7. SSH Protocol

7.1. paramiko

import paramiko

client = paramiko.SSHClient()

client.connect('example.com', username='tester')
# Traceback (most recent call last):
#   ...
# paramiko.ssh_exception.SSHException: Server 'example.com' not found in known_hosts
import paramiko

client = paramiko.SSHClient()

client.load_system_host_keys()
client.load_host_keys('/home/brandon/.ssh/known_hosts')
client.connect('example.com', username='test')

7.1.1. Password Auth

client.connect('example.com', username='brandon', password=mypass)
client.connect('my.example.com')

7.1.2. Public/Private Key Auth

client.connect('my.example.com', key_filename='/home/brandon/.ssh/id_sysadmin')

7.1.3. Running commands

import paramiko, sys, getpass

hostname = sys.argv[1]
username = sys.argv[2]
password = getpass.getpass()


client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
client.connect(hostname, username=username, password=password)
    for command in 'echo "Hello, world!"', 'uname', 'uptime':
        stdin, stdout, stderr = client.exec_command(command)
        stdin.close()
        print(repr(stdout.read()))
        stdout.close()
        stderr.close()
client.close

7.2. fabric

7.2.1. Local

from fabric.api import local

def prepare_deploy():
    local("./manage.py test my_app")
    local("git add -p && git commit")
    local("git push")
$ fab prepare_deploy
[localhost] run: ./manage.py test my_app
Creating test database...
Creating tables
Creating indexes
..........................................
----------------------------------------------------------------------
Ran 42 tests in 9.138s

OK
Destroying test database...

[localhost] run: git add -p && git commit

<interactive Git add / git commit edit message session>

[localhost] run: git push

<git push session, possibly merging conflicts interactively>

Done.

7.2.2. Organization

from fabric.api import local

def test():
    local("./manage.py test my_app")

def commit():
    local("git add -p && git commit")

def push():
    local("git push")

def prepare_deploy():
    test()
    commit()
    push()

7.2.3. Failure handling

from fabric.api import local, settings, abort
from fabric.contrib.console import confirm

def test():
    with settings(warn_only=True):
        result = local('./manage.py test my_app', capture=True)

    if result.failed and not confirm("Tests failed. Continue anyway?"):
        abort("Aborting at user request.")

7.2.4. Executing on remote host

from fabric.api import *
from fabric.contrib.console import confirm

env.hosts = ['my_server']

def test():
    with settings(warn_only=True):
        result = local('./manage.py test my_app', capture=True)

    if result.failed and not confirm("Tests failed. Continue anyway?"):
        abort("Aborting at user request.")

def commit():
    local("git add -p && git commit")

def push():
    local("git push")

def prepare_deploy():
    test()
    commit()
    push()

def deploy():
    code_dir = '/srv/django/myproject'

    with settings(warn_only=True):
        if run("test -d %s" % code_dir).failed:
            run("git clone [email protected]:/path/to/repo/.git %s" % code_dir)

    with cd(code_dir):
        run("git pull")
        run("touch app.wsgi")
from fabric.api import *

def deploy():
    sudo("~/install_script.py")
    sudo("mkdir /var/www/new_docroot", user="www-data")
    sudo("ls /home/jdoe", user=1001)
    result = sudo("ls /tmp/")

    with settings(sudo_user='mysql'):
        sudo("whoami")
        # 'mysql'

7.2.5. Host

from fabric.api import hosts

@hosts(['127.0.0.1', 'localhost'])
def whoami():
    sudo('whoami')

7.3. pssh

../_images/ssh-pssh-1.jpg
../_images/ssh-pssh-2.jpg
../_images/ssh-pssh-3.png