I've recently learned how great expect is, now that I'm suddenly responsible for managing 150 VMs. I've been using it to distribute config files to remote servers, but there's got to be a better way than what I'm doing.

Mainly what I do is things like this:

set server [lindex $argv 0]
set timeout -1
spawn scp -i $::env(HOME)/.ssh/key.pem file $server:/tmp/
expect ">>"
spawn ssh -i $::env(HOME)/.ssh/key.pem $server
expect ">>"
send "sudo mv /tmp/file /etc/file && sudo service foo restart\r"
expect ">>"
puts "\r\r"

So basically, the script scp's the file over to the remote server, and then ssh's into the server and moves the file (using sudo, because it's a file owned by root in /etc, e.g. nscd.conf) to its destination. It seems like there must be a better way than this to manage distributing a new root-owned config file to a bunch of machines.

  • 4
    When operating 150+ servers it's time to look into proper configuration management systems (Puppet, Chef, Salt, Ansible, en.wikipedia.org/wiki/… ...). – faker Sep 23 '14 at 9:11
  • Yeah, that's a lot more time investment than I have time for at the moment, though. I was hoping there was some simple feature of expect (or Tcl) that would be a better way to do this than what I'm doing. This works, though. – dirtside Sep 23 '14 at 18:11

You can get something like chef or puppet up and running pretty quickly and it will save you a LOT of headache in the long run, but if you don't want to use real config management, a few suggestions for the way you're doing things now:

1) Put the key of the user you're connecting as into root's authorized_keys file so you don't have to do things as a non root user then log in to use sudo. Then you don't need expect at all. 2) Beware incomplete uploads when you're overwriting config files. You probably want some checksumming logic to make sure that you've copied the file and it's intact before you move it into place on the target host. 3) Use rsync over ssh if you're trying to make a whole directory or a bunch of files identical instead of scping them one at a time or doing scp -r. This will save you a bunch of time if the local and destination contents are already the same and will allow you to run things from cron to keep them in sync without fear of copying everything each time. 4) If you do run things from cron, make sure you have some sort of locking so that you don't get cron jobs piled on top of each other. Also make sure that you clean up the locking if your job fails, the system reboots, etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.