sprinkle-tool / sprinkle

Sprinkle is a software provisioning tool you can use to build remote servers with. eg. to install a Rails, or Sinatra stack on a brand new slice directly after its been created
https://github.com/sprinkle-tool/sprinkle
MIT License
1.15k stars 138 forks source link

push_text installer problem #42

Closed pibako closed 11 years ago

pibako commented 13 years ago

I'm trying to prepare automatic setup for debian squeeze box and having the following problem: when I try to: push_text 'some text', '/etc/init.d/nginx' this is what I get (simply telling me I have no rights to access the file):

nginx install sequence: /bin/echo -e 'some text' |tee -a /etc/init.d/nginx for roles: web_stack
--> Installing nginx for roles: web_stack
** [out :: deb-vb] tee: /etc/init.d/nginx: Permission denied
** [out :: deb-vb] 
** [out :: deb-vb] some text
/Users/piotrkowalski/.rvm/gems/ruby-1.9.2-p290@servers/gems/capistrano-2.8.0/lib/capistrano/command.rb:176:in `process!': failed: "sh -c 'sudo -p '\\''sudo password: '\\'' /bin/echo -e '\\''some text'\\'' |tee -a /etc/init.d/nginx'" on deb-vb (Capistrano::CommandError)

On the other hand when I use sudo like this: push_text 'some text', '/etc/init.d/nginx', :sudo => true do the installation hangs waiting for sudo password:

nginx install sequence: /bin/echo -e 'some text' |sudo tee -a /etc/init.d/nginx for roles: web_stack
--> Installing nginx for roles: web_stack
** [out :: deb-vb] [sudo] password for pkow:

Source documentation for Installer says there is no need to use sudo since 'All commands by default are sudo'd'.

in my deploy.rb I have: default_run_options[:pty] = true

I am using sprinkle 0.4.1 and capistrano 2.8.0.

Any ideas?

BTW How to execute arbitrary shell command as a sudo user?

joshgoebel commented 13 years ago

All commands aren't sudoed by default unless you told Capistrano to do that... where in the docs do you see that? So adding sudo is right... you may need to setup the sudo prompt thing within Cap? I'm not 100% since I think the whole sudo password thing is dumb and always setup my boxes to use ssh keys to avoid it entirely.

joshgoebel commented 13 years ago

Arbitrary commands?

runner "sudo blah"

joshgoebel commented 13 years ago

But I'm not sure if that would hook into Capistranos special sudo prompting support or not, which is a whole separate thing... again as I don't use passwords for sudo... can someone else weigh in here?

pibako commented 13 years ago

In installer.rb: https://github.com/crafterm/sprinkle/blob/master/lib/sprinkle/installers/installer.rb

All commands by default are sudo'd so there is no need to include "sudo" in the command itself.

Maybe I misunderstand it since it is about post/pre methods.

pibako commented 13 years ago

On the other hand Capistrano handbook https://github.com/capistrano/capistrano/wiki/2.x-From-The-Beginning says it defaults to sudo for certain operations unless you specify :use_sudo:

set :use_sudo, false. By default, Capistrano will try to use sudo to do certain operations (setting up your servers, restarting your application, etc.). If you are on a shared host, sudo might be unavailable to you, or maybe you just want to avoid using sudo.

and runner "sudo blah" doesn't hook into Capistranos special sudo prompting support although i set in deploy.rb: default_run_options[:pty] = true

joshgoebel commented 13 years ago

That's not correct, I'll change it. That would only be the case if you setup Cap to run all commands via sudo.

pibako commented 13 years ago

What do you mean by this?

always setup my boxes to use ssh keys to avoid it entirely

Does it mean you set up your box as a root user? And if yes how does it relates to ssh key? Now I feel lost ;(

joshgoebel commented 13 years ago

if you put

set :use_sudo, true

In your cap deploy.rb file then that should turn on sudo by default.

joshgoebel commented 13 years ago

"always setup my boxes to use ssh keys to avoid it entirely"

My bad I was getting different things confused. I setup sudo to NOT require a password... and I use SSH keys so that ssh does not require a password. So no password prompts are needed.

joshgoebel commented 13 years ago

Try the use_sudo code I pasted above and see if that makes any difference.

joshgoebel commented 13 years ago

"On the other hand Capistrano handbook https://github.com/capistrano/capistrano/wiki/2.x-From-The-Beginning says it defaults to sudo for certain operations unless you specify :use_sudo:"

Oh, hmmm... I didn't know that was the default... I guess I've always user user_sudo, false in my cap setups.

pibako commented 13 years ago

I've just tested your solution but Capistrano should defaults to use_sudo => true anyway. It is still hangs on:

Installing nginx for roles: web_stack
** [out :: deb-vb] [sudo] password for pkow:
** [out :: deb-vb] 

but I have noticed something weird because this actually creates empty file :/

joshgoebel commented 13 years ago

Ok... default seems to be use sudo... and use_sudo, false turns it off... so if you're using the default or use_sudo, true then you shouldn't need to specify ":sudo" in your sprinkle stuff, as it should already be happening inside Capistrano... AND Capistrano should be handling the prompts and passwords.

The issue you'd run into was using use_sudo, false and then something like you're doing or runner "sudo blah"... in which case there would be no way to fill in the password as everything Sprinkle does is non-interactive.

joshgoebel commented 13 years ago

Your output is weird. This is what cap does:

sh -c 'sudo -p '\\''sudo password: '\\'' rm /etc/motd'

It tells sudo to change the sudo password prompt to a KNOWN prompt so it can detect it and answer... but you're output says "password for pkow:" which is likely why Capistrano isn't working.

joshgoebel commented 13 years ago

Off the top of my head I'm not sure the issue is with the Sprinkle stack (other than that the docs need to be cleared up a bit to explain that's only true with the Capistrno actor)

pibako commented 13 years ago

The issue you'd run into was using use_sudo, false and then something like you're doing or runner "sudo blah"... in which case there would be no way to fill in the password as everything Sprinkle does is non-interactive.

Not really, I haven't used :use_sudo in my deploy.rb at all so I defaulted to using sudo.

This is the full output of this operation:

nginx install sequence: /bin/echo -e 'nginx_text' |sudo tee -a /etc/init.d/nginx; ch mod +x /etc/init.d/nginx; /usr/sbin/update-> rc.d -f nginx defaults; /etc/init.d/nginx start for roles: web_stack --> Installing nginx for roles: web_stack * [out :: deb-vb] * [out :: deb-vb] [sudo] password for pkow:

joshgoebel commented 13 years ago

"sudo tee' would not be in the output unless you were using :sudo. If you're using capistranos defaults then you should not use :sudo in your installer settings.

pibako commented 13 years ago

Sorry I messed up things.

This, is the output when I use set :use_sudo, true in deploy.rb and push_text 'nginx_text', '/etc/init.d/nginx' operation without sudo:

nginx install sequence: /bin/echo -e 'some text' |tee -a /etc/init.d/nginx for roles: web_stack
--> Installing nginx for roles: web_stack
** [out :: deb-vb] tee: /etc/init.d/nginx: Permission denied
** [out :: deb-vb] 
** [out :: deb-vb] some text
/Users/piotrkowalski/.rvm/gems/ruby-1.9.2-p290@servers/gems/capistrano-2.8.0/lib/capistrano/command.rb:176:in `process!': failed: "sh -c 'sudo -p '\\''sudo password: '\\'' /bin/echo -e '\\''some text'\\'' |tee -a /etc/init.d/nginx'" on deb-vb (Capistrano::CommandError)
joshgoebel commented 13 years ago

The issue seems to be that echo is run sudo, but not "tee", so the file cannot be written to. Have to think about that.

joshgoebel commented 13 years ago

Try something simpler:

runner "echo -e 'your test' > /etc/initd.ngnix'"

And see if that would work.

joshgoebel commented 13 years ago

Although that would add it each time. But I'm curious if that would work for you... since I'm wondering why we're choosing to use tee in the first place now.

pibako commented 13 years ago

nice try... but i have tested it before. Here is the output:

nginx install sequence: echo -e 'your test' > /etc/initd.ngnix for roles: web_stack
--> Installing nginx for roles: web_stack
** [out :: deb-vb] sh: cannot create /etc/initd.ngnix: Permission denied
/Users/piotrkowalski/.rvm/gems/ruby-1.9.2-p290@servers/gems/capistrano-2.8.0/lib/capistrano/command.rb:176:in `process!': failed: "sh -c 'sudo -p '\\''sudo password: '\\'' echo -e '\\''your test'\\'' > /etc/initd.ngnix'" on deb-vb (Capistrano::CommandError)

BTW Can you reproduce the problem?

pibako commented 13 years ago

It is so weird. I wonder why nobody else reports the problem since there are tons of passenger-stack's forks.

I have tested several different configurations to name a few and none of them works for me:

Maybe it is something with Debian Squeeze... I am loosing my mind.

Off the topic: You say you use sudo to NOT require a password therefore why to use sudo at all?

joshgoebel commented 13 years ago

"BTW Can you reproduce the problem?"

I don't think I need to I understand it... and I think I remember trying to use > with sudo before and not being able to write the filesystem unless I first sudo -s (and got a shell)... so sudo doesn't apply to the output... since I'd guess it's the SHELL (running as an unprivileged user) that is doing the actual output, not the sudoed command... and that's probably an answer to why we're using tee with a :sudo option.

"You say you use sudo to NOT require a password therefore why to use sudo at all?"

The user account is still unprivileged in everyday use. Processes running as that user are still unprivileged processes. I suppose it would make rooting the box easier, but I know large hosting companies recommending exactly this setup, so I don't think it's quite as bad as it sounds. If someone gets shell access or your app lets people execute arbitrary shell commands then really your box is close to toast anyways.

joshgoebel commented 13 years ago

Can you jump in a free node channel so I could help you? I have an idea.

joshgoebel commented 13 years ago

freenode (IRC)

pibako commented 13 years ago

Hmmm... I see emacs has support for IRC, but I am not experienced with that. My nickname is pibako. What channel to join?

pibako commented 13 years ago

The simple workaround to the problem is to create or move a file into /tmp/ directory, edit it there then mv it back. You can follow the example below:

  push_text nginx_text, '/tmp/nginx' do
    post :install, "chmod +x /tmp/nginx"
  end
  runner 'mv /tmp/nginx /etc/init.d/nginx'

One thing is that you must use cap set :use_sudo, true (it defaults to it) and you don't use sprinkle :sudo option for push_text method.

Many thanks to yyyc514 (Josh Goebel) for his help.

joshgoebel commented 13 years ago

Note if you're editing an existing file you'd need also:

pre :install, 'command to copy file to /tmp'

I'm going to re-open this issue until Sprinkle itself is fixed so this workaround is not needed.

joshgoebel commented 11 years ago

Anyone want to volunteer to rewrite push_text to use sed or something that can modify the file in place while running under sudo to just avoid this problem entirely?

joshgoebel commented 11 years ago

Discussion continued in #104.

joshgoebel commented 11 years ago

Closing as this is continued (and left open) in #104 and is slated to be fixed in 0.6.