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.