deployment.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/env python
  2. import os, sys, re, json, base64
  3. from boto.ec2.connection import EC2Connection
  4. from subprocess import call
  5. from fabric import api
  6. from fabric.api import cd, run, put, sudo
  7. from os import environ as env
  8. from time import sleep
  9. # Remove SSH private key as it needs more processing
  10. CONFIG = json.loads(re.sub(r'("DOCKER_CI_KEY".+?"(.+?)",)','',
  11. env['CONFIG_JSON'], flags=re.DOTALL))
  12. # Populate environment variables
  13. for key in CONFIG:
  14. env[key] = CONFIG[key]
  15. # Load SSH private key
  16. env['DOCKER_CI_KEY'] = re.sub('^.+"DOCKER_CI_KEY".+?"(.+?)".+','\\1',
  17. env['CONFIG_JSON'],flags=re.DOTALL)
  18. AWS_TAG = env.get('AWS_TAG','docker-ci')
  19. AWS_KEY_NAME = 'dotcloud-dev' # Same as CONFIG_JSON['DOCKER_CI_PUB']
  20. AWS_AMI = 'ami-d582d6bc' # Ubuntu 13.04
  21. AWS_REGION = 'us-east-1'
  22. AWS_TYPE = 'm1.small'
  23. AWS_SEC_GROUPS = 'gateway'
  24. AWS_IMAGE_USER = 'ubuntu'
  25. DOCKER_PATH = '/go/src/github.com/dotcloud/docker'
  26. DOCKER_CI_PATH = '/docker-ci'
  27. CFG_PATH = '{}/buildbot'.format(DOCKER_CI_PATH)
  28. class AWS_EC2:
  29. '''Amazon EC2'''
  30. def __init__(self, access_key, secret_key):
  31. '''Set default API parameters'''
  32. self.handler = EC2Connection(access_key, secret_key)
  33. def create_instance(self, tag, instance_type):
  34. reservation = self.handler.run_instances(**instance_type)
  35. instance = reservation.instances[0]
  36. sleep(10)
  37. while instance.state != 'running':
  38. sleep(5)
  39. instance.update()
  40. print "Instance state: %s" % (instance.state)
  41. instance.add_tag("Name",tag)
  42. print "instance %s done!" % (instance.id)
  43. return instance.ip_address
  44. def get_instances(self):
  45. return self.handler.get_all_instances()
  46. def get_tags(self):
  47. return dict([(i.instances[0].id, i.instances[0].tags['Name'])
  48. for i in self.handler.get_all_instances() if i.instances[0].tags])
  49. def del_instance(self, instance_id):
  50. self.handler.terminate_instances(instance_ids=[instance_id])
  51. def json_fmt(data):
  52. '''Format json output'''
  53. return json.dumps(data, sort_keys = True, indent = 2)
  54. # Create EC2 API handler
  55. ec2 = AWS_EC2(env['AWS_ACCESS_KEY'], env['AWS_SECRET_KEY'])
  56. # Stop processing if AWS_TAG exists on EC2
  57. if AWS_TAG in ec2.get_tags().values():
  58. print ('Instance: {} already deployed. Not further processing.'
  59. .format(AWS_TAG))
  60. exit(1)
  61. ip = ec2.create_instance(AWS_TAG, {'image_id':AWS_AMI, 'instance_type':AWS_TYPE,
  62. 'security_groups':[AWS_SEC_GROUPS], 'key_name':AWS_KEY_NAME})
  63. # Wait 30 seconds for the machine to boot
  64. sleep(30)
  65. # Create docker-ci ssh private key so docker-ci docker container can communicate
  66. # with its EC2 instance
  67. os.makedirs('/root/.ssh')
  68. open('/root/.ssh/id_rsa','w').write(env['DOCKER_CI_KEY'])
  69. os.chmod('/root/.ssh/id_rsa',0600)
  70. open('/root/.ssh/config','w').write('StrictHostKeyChecking no\n')
  71. api.env.host_string = ip
  72. api.env.user = AWS_IMAGE_USER
  73. api.env.key_filename = '/root/.ssh/id_rsa'
  74. # Correct timezone
  75. sudo('echo "America/Los_Angeles" >/etc/timezone')
  76. sudo('dpkg-reconfigure --frontend noninteractive tzdata')
  77. # Load public docker-ci key
  78. sudo("echo '{}' >> /root/.ssh/authorized_keys".format(env['DOCKER_CI_PUB']))
  79. # Create docker nightly release credentials file
  80. credentials = {
  81. 'AWS_ACCESS_KEY': env['PKG_ACCESS_KEY'],
  82. 'AWS_SECRET_KEY': env['PKG_SECRET_KEY'],
  83. 'GPG_PASSPHRASE': env['PKG_GPG_PASSPHRASE'],
  84. 'INDEX_AUTH': env['INDEX_AUTH']}
  85. open(DOCKER_CI_PATH + '/nightlyrelease/release_credentials.json', 'w').write(
  86. base64.b64encode(json.dumps(credentials)))
  87. # Transfer docker
  88. sudo('mkdir -p ' + DOCKER_CI_PATH)
  89. sudo('chown {}.{} {}'.format(AWS_IMAGE_USER, AWS_IMAGE_USER, DOCKER_CI_PATH))
  90. call('/usr/bin/rsync -aH {} {}@{}:{}'.format(DOCKER_CI_PATH, AWS_IMAGE_USER, ip,
  91. os.path.dirname(DOCKER_CI_PATH)), shell=True)
  92. # Install Docker and Buildbot dependencies
  93. sudo('addgroup docker')
  94. sudo('usermod -a -G docker ubuntu')
  95. sudo('mkdir /mnt/docker; ln -s /mnt/docker /var/lib/docker')
  96. sudo('wget -q -O - https://get.docker.io/gpg | apt-key add -')
  97. sudo('echo deb https://get.docker.io/ubuntu docker main >'
  98. ' /etc/apt/sources.list.d/docker.list')
  99. sudo('echo -e "deb http://archive.ubuntu.com/ubuntu raring main universe\n'
  100. 'deb http://us.archive.ubuntu.com/ubuntu/ raring-security main universe\n"'
  101. ' > /etc/apt/sources.list; apt-get update')
  102. sudo('DEBIAN_FRONTEND=noninteractive apt-get install -q -y wget python-dev'
  103. ' python-pip supervisor git mercurial linux-image-extra-$(uname -r)'
  104. ' aufs-tools make libfontconfig libevent-dev')
  105. sudo('wget -O - https://go.googlecode.com/files/go1.1.2.linux-amd64.tar.gz | '
  106. 'tar -v -C /usr/local -xz; ln -s /usr/local/go/bin/go /usr/bin/go')
  107. sudo('GOPATH=/go go get -d github.com/dotcloud/docker')
  108. sudo('pip install -r {}/requirements.txt'.format(CFG_PATH))
  109. # Install docker and testing dependencies
  110. sudo('apt-get install -y -q lxc-docker')
  111. sudo('curl -s https://phantomjs.googlecode.com/files/'
  112. 'phantomjs-1.9.1-linux-x86_64.tar.bz2 | tar jx -C /usr/bin'
  113. ' --strip-components=2 phantomjs-1.9.1-linux-x86_64/bin/phantomjs')
  114. #### FIXME. Temporarily install docker with proper apparmor handling
  115. sudo('stop docker')
  116. sudo('wget -q -O /usr/bin/docker http://test.docker.io/test/docker')
  117. sudo('start docker')
  118. # Build docker-ci containers
  119. sudo('cd {}; docker build -t docker .'.format(DOCKER_PATH))
  120. sudo('cd {}/nightlyrelease; docker build -t dockerbuilder .'.format(
  121. DOCKER_CI_PATH))
  122. # Setup buildbot
  123. sudo('mkdir /data')
  124. sudo('{0}/setup.sh root {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}'
  125. ' {11} {12}'.format(CFG_PATH, DOCKER_PATH, env['BUILDBOT_PWD'],
  126. env['IRC_PWD'], env['IRC_CHANNEL'], env['SMTP_USER'],
  127. env['SMTP_PWD'], env['EMAIL_RCP'], env['REGISTRY_USER'],
  128. env['REGISTRY_PWD'], env['REGISTRY_BUCKET'], env['REGISTRY_ACCESS_KEY'],
  129. env['REGISTRY_SECRET_KEY']))