Creating a pseudoterminal to make sudo happy
- by larsks
I need to automate the provisioning of a cloud instance (running Fedora 17) for which the following initial facts are true:
I have ssh-key based access to a remote user (cloud)
That user has password-free root access via sudo.
Manual configuration is as simple as logging in and running sudo su - and having at it, but I would like to fully automate this process. The trick is that the system defaults to having the requiretty option enabled for sudo, which means that an attempt to do something like this:
ssh remotehost sudo yum -y install puppet
Will fail:
sudo: sorry, you must have a tty to run sudo
I am working around this right now by first pushing over a small Python script that will run a command on a pseudoterminal:
import os
import sys
import errno
import subprocess
pid, master_fd = os.forkpty()
if pid == 0:
# child process: now that we're attached to a
# pty, run the given command.
os.execvp(sys.argv[1], sys.argv[1:])
else:
while True:
try:
data = os.read(master_fd, 1024)
except OSError, detail:
if detail.errno == errno.EIO:
break
if not data:
break
sys.stdout.write(data)
os.wait()
Assuming that this is named pty, I can then run:
ssh remotehost ./pty sudo yum -y install puppet
This works fine, but I'm wondering if there are solutions already available that I haven't considered.
I would normally think about expect, but it's not installed by default on this system.
screen can do this in a pinch, but the best I came up with was:
screen -dmS sudo somecommand
...which does work but eats the output.
Are there any other tools available that will allocate a pseudoterminal for me that are going to be generally available?