Permalink
Browse files

fixes, makes rackspace cloud duplicity containers work again

  • Loading branch information...
1 parent e9ef5a1 commit 5ce9c2d4957f84b34e865f61b261ba3f542e1eaa @mig5 committed Mar 6, 2011
Showing with 15 additions and 107 deletions.
  1. +1 −1 README
  2. +0 −2 TODO
  3. +1 −1 config/felicity.ini
  4. +10 −102 felicity
  5. +3 −1 scripts/backup_restore
View
2 README
@@ -18,7 +18,7 @@ Tonnes of ugly hacks at this stage, working on things from the TODO.
Dependencies:
- * libcloud, python, python-paramiko
+ * libcloud, python, fabric
Usage:
View
2 TODO
@@ -4,8 +4,6 @@ Things to do
Definitely
----------
- * There is no error checking right now
-
* make things more configurable in .ini
* Improve the efficiency of scripts, not sure if we really need to use `at` but it seemed to solve the issue of duplicity simply not running?
View
@@ -1,7 +1,7 @@
[Felicity]
email=you@example.com
vpsprovider=Rackspace
-backupprovider=Amazon
+backupprovider=Rackspace
passphrase=secret_gpg_passphrase
[Rackspace]
View
112 felicity
@@ -3,18 +3,10 @@
from libcloud.types import Provider
from libcloud.providers import get_driver
from libcloud.deployment import MultiStepDeployment, ScriptDeployment, SSHKeyDeployment
-from libcloud.ssh import SSHClient, ParamikoSSHClient
from random import choice
-import paramiko
-from paramiko.rsakey import RSAKey
-import os
-import random
-import sys
-import ConfigParser
+import os, random, sys, ConfigParser
from email import Parser
-
-ssh = 0
# Fetch some values from the config file
config = ConfigParser.RawConfigParser()
config.read(os.path.expanduser('~/felicity/config/felicity.ini'))
@@ -38,13 +30,6 @@ config_size = config.get(vpsprovider, 'size')
# Where should we send the report to?
email = config.get('Felicity', 'email')
-
-# Where are the backups?
-backupprovider = config.get('Felicity', 'backupprovider')
-
-# The Duplicity passphrase, for decrypting during restore
-passphrase = config.get('Felicity', 'passphrase')
-
server = 0
# Let's test to see if the request has come in via email or from CLI
@@ -66,69 +51,11 @@ def dependency_check():
try:
open(os.path.expanduser('~/felicity/config/authorized_keys')).read()
except IOError:
- print "You need an authorized_keys file in the config directory."
- sys.exit(1)
+ raise SystemExit("You need an authorized_keys file in the config directory.")
try:
- import paramiko
+ import fabric
except ImportError:
- print "You need the Paramiko SSH module for Python installed (apt-get install python-paramiko)"
- sys.exit(1)
-
-def ssh_connect(remote_host):
- # Make a connection to the server
- rsa_key = os.path.expanduser('~/.ssh/id_rsa')
- mykey = paramiko.RSAKey.from_private_key_file(rsa_key)
- global ssh
- ssh = paramiko.SSHClient()
- ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- ssh.load_system_host_keys()
- ssh.connect(remote_host, username='root', pkey=mykey)
-
-def ssh_close():
- # Close the ssh connection
- ssh.close()
-
-def deploy_customisations():
- # Setting self-destruct for 48 hours
- ssh.exec_command('echo "halt" | at now + 2 days')
-
- # Disabling password authentication in SSH
- ssh.exec_command('sed -i -r -e "s/^[ #]*(PasswordAuthentication).*/\1 no/" /etc/ssh/sshd_config')
- ssh.exec_command('/etc/init.d/ssh restart')
-
- # Setting a firewall
- ssh.exec_command('/usr/local/bin/firewall start')
-
-def deploy_script():
- # Open an SFTP connection for transferring files
- ftp = ssh.open_sftp()
-
- scripts = ['backup_list_buckets', 'backup_list_bucket_keys', 'backup_restore_wrapper', 'backup_restore', 'firewall']
- for script in scripts:
- ftp.put(os.path.expanduser('~/felicity/scripts/' + script), '/usr/local/bin/' + script)
- script_file = ftp.open('/usr/local/bin/' + script, 'r')
- script_file.chmod(0755)
- script_file.close()
-
- # Save a file containing credentials for Duplicity.
- # This will be sourced by the backup_restore script
- file = ftp.open('/usr/local/etc/backup_restore_creds', 'w')
-
- if backupprovider == "Amazon":
- file.write('export AWS_ACCESS_KEY_ID=%s\n' % config.get('Amazon', 'user'))
- file.write('export AWS_SECRET_ACCESS_KEY=%s\n' % config.get('Amazon', 'key'))
- if backupprovider == "Rackspace":
- file.write('export CLOUDFILES_USERNAME=%s\n' % config.get('Rackspace', 'user'))
- file.write('export CLOUDFILES_APIKEY=%s\n' % config.get('Rackspace','key'))
- file.write('export PASSPHRASE=%s' % passphrase)
- file.close()
-
- # Close the SFTP connection
- ftp.close()
-
-def run_script():
- # Preparing restore script to run
- ssh.exec_command('echo "/usr/local/bin/backup_restore_wrapper %s %s %s" | at now + 1 minute' % tuple([ server, email, backupprovider]))
+ raise SystemExit("You need the Fabric Python library (apt-get install fabric)")
def main():
# Run some tests
@@ -154,43 +81,24 @@ def main():
SSHKeyDeployment(open(os.path.expanduser('~/felicity/config/authorized_keys')).read()),
ScriptDeployment("echo 'deb http://www.backports.org/debian lenny-backports main contrib non-free' >> /etc/apt/sources.list"),
ScriptDeployment("apt-get update"),
+ ScriptDeployment("apt-get -y install debian-archive-keyring"),
+ ScriptDeployment("apt-get update"),
ScriptDeployment("apt-get -y -t lenny-backports install duplicity"),
ScriptDeployment("echo 'postfix postfix/main_mailer_type select Internet Site' | debconf-set-selections"),
ScriptDeployment("echo 'postfix postfix/mailname string $HOSTNAME' | debconf-set-selections"),
ScriptDeployment("echo 'postfix postfix/destinations string localhost.localdomain, localhost' | debconf-set-selections"),
- ScriptDeployment("apt-get -y install postfix mailx python-boto at")
+ ScriptDeployment("apt-get -y install postfix mailx python-boto at git-core python-setuptools")
]
msd = MultiStepDeployment(dispatch)
# Create and deploy a new server now, and run the deployment steps defined above
print "Provisioning server and running deployment processes"
# Hostname of the new VPS
- hostname = 'backup-restore-"%s"%d' % tuple([server, random.randrange(0, 101, 2)])
+ hostname = 'backup-restore-"%s"%d' % (server, random.randrange(0, 101, 2))
node = conn.deploy_node(name=hostname, image=preferred_image[0], size=preferred_size[0], deploy=msd)
- # This is the public IP of the new server that will be used for further steps
- remote_host = node.public_ip[0]
-
- # Connect to the new server
- print "Connecting to %s" % remote_host
- ssh_connect(remote_host)
-
- # Deploy our scripts
- print "Deploying scripts"
- deploy_script()
-
- # Make some customisations to the server
- print "Securing SSH, setting a firewall and self-destruct for 48 hours"
- deploy_customisations()
-
- # Run the backup restore script
- print "Priming the server to run the backup restore script"
- run_script()
-
- # End the SSH session
- print "Closing SSH session"
- ssh_close()
-
+ print "Deploying scripts"
+ os.system('fab -H %s -u root deploy:server=%s' % (node.public_ip[0], server))
if __name__ == "__main__":
main()
View
@@ -39,6 +39,8 @@ s3_restore() {
# Doesn't work yet. CF doesn't support 'folders' inside containers
cf_restore() {
+# Find a list of buckets based on the server name provided.
+BUCKETS=`python /usr/local/bin/backup_list_containers $SERVER`
# Loop over the backup directories and do a restore of each one to
# a subdirectory of $RESTORE_DIR
for bucket in ${BUCKETS[*]}; do
@@ -47,7 +49,7 @@ for bucket in ${BUCKETS[*]}; do
echo "Restoring $SERVER bucket $bucket to $RESTORE_DIR/$bucket"
duplicity restore cf+http://$bucket $RESTORE_DIR/$bucket
echo "Now running a collection-status report of your backups in $bucket"
- duplicity collection-status s3+http://$bucket
+ duplicity collection-status cf+http://$bucket
echo "----------------------------------------------------------------------------"
done
}

0 comments on commit 5ce9c2d

Please sign in to comment.