Creating a pseudoterminal to make sudo happy
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?
You want the -t
option to ssh:
-t Force pseudo-tty allocation. This can be used to execute
arbitrary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
You may need to use -tt
if the script is going to be run non-interactively.