Skip to content

Instantly share code, notes, and snippets.

@mbbx6spp
Last active September 29, 2019 18:37
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mbbx6spp/6181003 to your computer and use it in GitHub Desktop.
Save mbbx6spp/6181003 to your computer and use it in GitHub Desktop.
Example usage of the dancer shell (dsh). Used as partial material for the DevOps Tech Talk Topic meetup on 8/8/2013.

Distributed or Dancer Shell

Similar to ansible command but allows you to use any command that will work in your shell. Not tied to specific configuration management tooling, just SSH and your default shell on remote systems. Just works. I <3 it :)

What does it do?

Runs commands across potentially many machines. Allows you to organize your servers/VMs/instances into groups very easily.

Getting Started

Most OSes just have a package for it in their package management system. Doesn't rely on Python or Ruby or whatever. e.g.

sudo apt-get install dsh

OR

sudo yum install dsh

OR for the wannabees

brew install dsh

(That isn't a dig at homebrew which is a great package manager for OSX. That was a dig at OSX itself.)

Ok, now what?

So there is usually a directory where you can define your host groups in plain text files. It's that simple. On most *NIX systems it is /etc/dsh. *NIX conventions FTW. Nothing fancy again.

$ tree /etc/dsh/ | head -15     
/etc/dsh/                       
├── dsh.conf                    
├── group
│   ├── all -> ../machines.list 
│   ├── prod.admin
│   ├── prod.api
│   ├── prod.cache
│   ├── prod.proxy
│   ├── prod.webapp
│   ├── prod.webcache
...
│   ├── profiling.admin
│   ├── profiling.api
│   ├── profiling.cache
│   ├── profiling.proxy
│   ├── profiling.webapp
│   ├── profiling.webcache
...
│   ├── staging.admin
│   ├── staging.api
│   ├── staging.cache
│   ├── staging.proxy
│   ├── staging.webapp
│   ├── staging.webcache
...
│   └── api.all
│   └── cache.all
│   └── proxy.all
│   └── webcache.all
│   └── webapp.all
└── machines.list  

What does a group file look like?

$ cat /etc/dsh/group/prod.webapp  
webapp001.appname.com
webapp002.appname.com
webapp003.appname.com
webapp004.appname.com
webapp005.appname.com
webapp006.appname.com
webapp007.appname.com
...
webapp123.appname.com

So now what?

Let's do something.

dsh -M -g webcache.all 'sudo service varnish restart'
dsh -cM -F 4 -g webapp.prod 'pgrep -f my_awesome_app'
dsh -m webapp001.appname.com -m webcache003.appname.com -m proxy005.appname.com 'sudo reboot'
dsh -g staging.webapp -g staging.admin 'sudo service nginx reload'
dsh -cF 5 -g all 'ss | awk '{ print $4 }' | sort | uniq'

Configuration Options

This is an example of the global dsh.conf file.

$ cat /etc/dsh/dsh.conf 
verbose = 0             
remoteshell = ssh       
showmachinenames = 0    
waitshell = 1           
remoteshellopt=-q       

Pretty simple. Check the man pages for more information.

@adiktofsugar
Copy link

Really helpful, thanks.

With brew on Mac, you should put /etc/dsh into ~/.dsh unless you want to change however it's installed by default on brew.

@chrisribe
Copy link

Thanks for the details.

But how do you handle identity_file option (-i) and user name ex: myuser@ ?
I am trying to use this on AWS EC2 machines but ssh requires rsa keys.

There is not much in the documentation about login access and how to setup.
Any tips?

Chris

@mbbx6spp
Copy link
Author

@chrisribe I didn't see this message until now, sorry for the delay. I personally use my own user's ${HOME}/.ssh/config file to set that up. Something like this:

Host *.sub.mydomain.tld
  IdentityFile ~/.some/private/dir/key
  # if username needs to change do the following
  User myusername
  # if port needs to change do the following too
  Port 22022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment