Files
devstack-gate/slave_scripts/devstack-vm-update-image.py
James E. Blair 6253f48907 Cache a copy of all images on the template VM.
This is part 1 of a 2 part change that will get the images
pre-populated in the devstack directory on the vm so that
they aren't downloaded via the Internet each time.

This needs to be merged first so that the directory with the
images is available on the vm.  The next change, to the
gate-host script, will expect it to be there.

Change-Id: I230e3d3032a9d605b2e1192e1f1df6d5da75d01e
2011-12-14 13:49:59 -08:00

113 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python
# Update the base image that is used for devstack VMs.
# Copyright (C) 2011 OpenStack LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
#
# See the License for the specific language governing permissions and
# limitations under the License.
from libcloud.base import NodeImage, NodeSize, NodeLocation
from libcloud.types import Provider
from libcloud.providers import get_driver
from libcloud.deployment import MultiStepDeployment, ScriptDeployment, SSHKeyDeployment
from libcloud.dns.types import Provider as DnsProvider
from libcloud.dns.types import RecordType
from libcloud.dns.providers import get_driver as dns_get_driver
import libcloud
import sys
import os
import commands
import time
import paramiko
CLOUD_SERVERS_DRIVER = os.environ.get('CLOUD_SERVERS_DRIVER','rackspace')
CLOUD_SERVERS_USERNAME = os.environ['CLOUD_SERVERS_USERNAME']
CLOUD_SERVERS_API_KEY = os.environ['CLOUD_SERVERS_API_KEY']
SERVER_NAME = 'devstack-oneiric.template.openstack.org'
IMAGE_NAME = 'devstack-oneiric'
debs = ' '.join(open(sys.argv[1]).read().split('\n'))
pips = ' '.join(open(sys.argv[2]).read().split('\n'))
filedir = sys.argv[3]
if CLOUD_SERVERS_DRIVER == 'rackspace':
Driver = get_driver(Provider.RACKSPACE)
conn = Driver(CLOUD_SERVERS_USERNAME, CLOUD_SERVERS_API_KEY)
print "Searching for %s server" % SERVER_NAME
node = [n for n in conn.list_nodes() if n.name==SERVER_NAME][0]
print "Searching for %s image" % IMAGE_NAME
images = [img for img in conn.list_images()
if img.name.startswith(IMAGE_NAME)]
else:
raise Exception ("Driver not supported")
ip = node.public_ip[0]
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
client.connect(ip)
def run(action, x):
stdin, stdout, stderr = client.exec_command(x)
print x
ret = stdout.channel.recv_exit_status()
print stdout.read()
print stderr.read()
if ret:
raise Exception("Unable to %s" % action)
def scp(source, dest):
print 'copy', source, dest
ftp = client.open_sftp()
ftp.put(source, dest)
ftp.close()
run('make file cache directory', 'mkdir -p files')
for fn in os.listdir(filedir):
source = os.path.join(filedir, fn)
scp(source, 'files/%s'%fn)
run('update package list', 'sudo apt-get update')
run('install packages', 'sudo DEBIAN_FRONTEND=noninteractive apt-get --option "Dpkg::Options::=--force-confold" --assume-yes install %s' % debs)
run('install pips', 'sudo pip install %s' % pips)
run('upgrade server', 'sudo apt-get -y dist-upgrade')
run('run puppet', 'sudo bash -c "cd /root/openstack-ci-puppet && /usr/bin/git pull -q && /var/lib/gems/1.8/bin/puppet apply -l /tmp/manifest.log --modulepath=/root/openstack-ci-puppet/modules manifests/site.pp"')
run('stop mysql', 'sudo /etc/init.d/mysql stop')
run('stop rabbitmq', 'sudo /etc/init.d/rabbitmq-server stop')
for image in images:
print 'Deleting image', image
try:
conn.ex_delete_image(image)
except Exception, e:
print e
IMAGE_NAME = IMAGE_NAME+'-'+str(int(time.time()))
image = conn.ex_save_image(node=node, name=IMAGE_NAME)
last_extra = None
while True:
image = [img for img in conn.list_images(ex_only_active=False)
if img.name==IMAGE_NAME][0]
if image.extra != last_extra:
print image.extra['status'], image.extra['progress']
if image.extra['status'] == 'ACTIVE':
break
last_extra = image.extra
time.sleep(2)