-
Notifications
You must be signed in to change notification settings - Fork 254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: within(directory){ execute(string) } should either 'just work' or 'boom' #306
Comments
just also noticing that the code absolute string bashes user input already: def sanitize_command!
command.to_s.strip!
if command.to_s.match("\n")
@command = String.new.tap do |cs|
command.to_s.lines.each do |line|
cs << line.strip
cs << '; ' unless line == command.to_s.lines.to_a.last
end
end
end
end
so extending this to 'do the right thing' is absolutely in line with the current design |
Alright, that's a problem. Here's the thing, we need a list of commands that people try and do this thing with, to have some concrete arguments. The issue, briefly explained is that the command mapping (prefixing, suffixing, wrapping in For the simplish cases of someone having a string such as |
What cases can you offer up as sane use-cases for strings in commands, and can we take those and see if we can make the whole API work reliably? |
there aren't sane use cases for either strings or arrays as *args as command arguments if you ask me - both are arbitrary. however, the code has a bunch of inconsistent string bashing in it already, eg an env with a " will 'just work' def environment_string
environment_hash.collect do |key,value|
key_string = key.is_a?(Symbol) ? key.to_s.upcase : key.to_s
escaped_value = value.to_s.gsub(/"/, '\"')
%{#{key_string}="#{escaped_value}"}
end.join(' ')
end but a directory with with a space in it will boom def within(&_block)
return yield unless options[:in]
sprintf("cd #{options[:in]} && %s", yield)
end so it seems like backing up to 10,000 feet makes sense - is the goal of the library to construct correct commands with a consistent api then within, as, and with all need handled. if the goal is, as you have suggested in some other threads, to let the user deal with that, then the meta apis that manage env, working directory, etc should be removed and the interface consist only of strings the user manages so handling things like directory = '/User Information'
execute "cd '#{ directory }'; echo 'it works'" is 100% transparent i'm just arguing for the goal to be 100% consistency and 100% either raw commands or managed_commands - but not sometimes one or the other such that the clients of the libraries know which to expect at all times |
for a sane use case, here are two from only the first cap3 deployment i've done sometimes you are going to run things that don't have a clean mapping from symbol to string fbomb = "./script/fbomb"
execute "cd #{ current_path } && #{ fbomb } daemon stop; true" a few things to note about this:
another example: execute 'yes | some_poorly_designed_script' which highlights your point about proper escaping ;-/ in any case the code to append the cwd onto within/as etc is, IMHO, just as complex and POLS as arbitrarily splitting strings with newlines and joining them on ';' - a hack, but one that is what the user wants 80/20 |
Alright, so thanks for those suggestions, better than I've come across, whilst I could shoot them all down with "you should be doing X" (and, maybe that's the resolution we come up iwht, and we improve the docs for this a LOT), let's see if we can make them work. For posterity:
I'm sure we can build up a list. I'd like to look into some realistic scenarios, something like, how they should/would look inside contrived, if still realistic setups :
I'm not 100% current on the implementation of Regarding the The idea was to give a Ruby DSL so that people could stop shell scripting, let's see if we can grow a list (community is included) to come up with a comprehensive list of things uncovered by the API, and we can work towards a solution. |
i'm going to pin this tab to i keep track of this and have to crank on some work now but i want to drop a few notes in here for myself: all commands have
i wonder if generating a script per command to be run would be better than |
Sounds like a rather large departure from what we've done to date, and what little uploading of scripts we have done has always run into problems with tempfiles, collisions of tempfile names, I actually looked a level deeper, which would be to send things like env vars (for example) on the ssh channel to setup the environment for the connection (they can be changed any time). Another option would be to have Net-SSH give us a shell in a directory with the correct user, before trying to wrap the user's command, it would complicate pooling ("I need a shell as this user in this directory with these env on this host" becomes the query, not just "I need a shell on this host") - but these could also be "channels" on the main "connection", so the channels (lightweight, very fast to setup/teardown) could be the instrument for changing directory, parameters, etc... I'd really have to look into how persistent those channel parameters are... but food for thought |
yeah i hear you. i'll look a bit but my thoughts would be to generate all scripts locally and send them over stdin on the channel... |
Man, this is the closest i've come to my bug.. For some weird reason I keep getting:
I am no ruby developer so I'm really working this with a lot of sample code and tutorials. But there is barely anything on the interwebs about writing customs tasks in rake files. This is my rake file:
Does anybody know what is going on? |
@ChristianVermeulen, I think the problem is that you need to tell it what host or what roles you want to run it on. Or to specify that you want it run locally with
Take a look at https://github.com/capistrano/sshkit/blob/master/EXAMPLES.md for more examples. |
@mkreyman That was indeed the problem. Can't believe it took me so long to find that out! |
docs aren't good enough to explain the design choice IMHO - just check
stackoverflow...
one solution is just to fix it - use shellwords to properly escape the command
otherwise raise an exception
the current behavior of doing
just isn't POLS - the point of a library like cap is to be able to re-use code
but, currently, each and every use must re-invent 'cd into a (properly escaped
directory) and run commands', including handling the fact that
a final solution would be to remove the 'within' API since it sometimes works,
and sometimes does not, issuing no exception nor warning
The text was updated successfully, but these errors were encountered: