Add meta option for passing meta-data
Add a meta option for passing through metadata key/value pairs. For snapshot images, this ends up getting passed through to novaclient.server.create_image(metadata=...). For uploaded images, the values are used as custom properties for glanceclient.images.create() The 255 character limits are taken from the API documentation in [1]. This is initially intended to be used for setting xenapi and vm_mode settings for disk-image-builder based Rackspace images, as described in [2]. [1] http://docs.openstack.org/developer/python-novaclient/ref/v1_1/servers.html [2] https://developer.rackspace.com/blog/custom-images-via-boot-dot-rackspace-dot-com-training-wheels-included/ Change-Id: Ic2f044f44f06830b5b84438d838013d409e642b4
This commit is contained in:
parent
f206a1b722
commit
34335b5fbf
|
@ -220,6 +220,9 @@ same name. Example::
|
|||
reset: reset_node.sh
|
||||
username: jenkins
|
||||
private-key: /var/lib/jenkins/.ssh/id_rsa
|
||||
meta:
|
||||
key: value
|
||||
key2: value
|
||||
- name: quantal
|
||||
base-image: 'Quantal'
|
||||
min-ram: 8192
|
||||
|
@ -276,6 +279,11 @@ of availability zones being used. If you need more control of the
|
|||
distribution you can use multiple logical providers each providing a
|
||||
different list of availabiltiy zones.
|
||||
|
||||
The `meta` section is optional. It is a dict of arbitrary key/value
|
||||
metadata to store for this server using the nova metadata service. A
|
||||
maximum of five entries is allowed, and both keys and values must be
|
||||
255 characters or less.
|
||||
|
||||
targets
|
||||
-------
|
||||
|
||||
|
|
|
@ -81,7 +81,8 @@ class FakeList(object):
|
|||
t.start()
|
||||
return s
|
||||
|
||||
def create_image(self, server, image_name):
|
||||
def create_image(self, server, image_name, metadata):
|
||||
# XXX : validate metadata?
|
||||
x = self.api.images.create(name=image_name)
|
||||
return x.id
|
||||
|
||||
|
|
|
@ -876,7 +876,7 @@ class DiskImageUpdater(ImageUpdater):
|
|||
stripped_filename = self.filename.replace(".qcow2", "")
|
||||
image_path = os.path.join(self.imagesdir, stripped_filename)
|
||||
image_id = self.manager.uploadImage(image_name, image_path,
|
||||
'qcow2', 'bare')
|
||||
'qcow2', 'bare', self.image.meta)
|
||||
self.snap_image.external_id = image_id
|
||||
session.commit()
|
||||
self.log.debug("Image id: %s building image %s" %
|
||||
|
@ -969,7 +969,8 @@ class SnapshotImageUpdater(ImageUpdater):
|
|||
|
||||
self.bootstrapServer(server, key, use_password=use_password)
|
||||
|
||||
image_id = self.manager.createImage(server_id, hostname)
|
||||
image_id = self.manager.createImage(server_id, hostname,
|
||||
self.image.meta)
|
||||
self.snap_image.external_id = image_id
|
||||
session.commit()
|
||||
self.log.debug("Image id: %s building image %s" %
|
||||
|
@ -1250,6 +1251,23 @@ class NodePool(threading.Thread):
|
|||
i.private_key = image.get('private-key',
|
||||
'/var/lib/jenkins/.ssh/id_rsa')
|
||||
|
||||
# note this does "double-duty" -- for
|
||||
# SnapshotImageUpdater the meta-data dict is passed to
|
||||
# nova when the snapshot image is created. For
|
||||
# DiskImageUpdater, this dict is expanded and used as
|
||||
# custom properties when the image is uploaded.
|
||||
i.meta = image.get('meta', {})
|
||||
# 5 elements, and no key or value can be > 255 chars
|
||||
# per novaclient.servers.create() rules
|
||||
if i.meta:
|
||||
if len(i.meta) > 5 or \
|
||||
any([len(k) > 255 or len(v) > 255
|
||||
for k, v in i.meta.iteritems()]):
|
||||
# soft-fail
|
||||
self.log.error("Invalid metadata for %s; ignored"
|
||||
% i.name)
|
||||
i.meta = {}
|
||||
|
||||
for target in config['targets']:
|
||||
t = Target()
|
||||
t.name = target['name']
|
||||
|
@ -1316,7 +1334,8 @@ class NodePool(threading.Thread):
|
|||
new_images[k].setup != old_images[k].setup or
|
||||
new_images[k].reset != old_images[k].reset or
|
||||
new_images[k].username != old_images[k].username or
|
||||
new_images[k].private_key != old_images[k].private_key):
|
||||
new_images[k].private_key != old_images[k].private_key or
|
||||
new_images[k].meta != old_images[k].meta):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
@ -207,12 +207,14 @@ class UploadImageTask(Task):
|
|||
image = fakeprovider.FakeGlanceClient()
|
||||
image.update(data='fake')
|
||||
else:
|
||||
# configure glance and upload image
|
||||
# configure glance and upload image. Note the meta flags
|
||||
# are provided as custom glance properties
|
||||
glanceclient = self.get_glance_client(self.args['provider'])
|
||||
image = glanceclient.images.create(
|
||||
name=self.args['image_name'], is_public=False,
|
||||
disk_format=self.args['disk_format'],
|
||||
container_format=self.args['container_format'])
|
||||
container_format=self.args['container_format'],
|
||||
**self.args['meta'])
|
||||
image.update(data=open(self.args['filename'], 'rb'))
|
||||
glanceclient = None
|
||||
|
||||
|
@ -489,18 +491,20 @@ class ProviderManager(TaskManager):
|
|||
if newip['instance_id'] == server_id:
|
||||
return newip['ip']
|
||||
|
||||
def createImage(self, server_id, image_name):
|
||||
def createImage(self, server_id, image_name, meta):
|
||||
return self.submitTask(CreateImageTask(server=server_id,
|
||||
image_name=image_name))
|
||||
image_name=image_name,
|
||||
metadata=meta))
|
||||
|
||||
def getImage(self, image_id):
|
||||
return self.submitTask(GetImageTask(image=image_id))
|
||||
|
||||
def uploadImage(self, image_name, filename, disk_format, container_format):
|
||||
def uploadImage(self, image_name, filename, disk_format, container_format,
|
||||
meta):
|
||||
return self.submitTask(UploadImageTask(
|
||||
image_name=image_name, filename='%s.%s' % (filename, disk_format),
|
||||
disk_format=disk_format, container_format=container_format,
|
||||
provider=self.provider))
|
||||
provider=self.provider, meta=meta))
|
||||
|
||||
def listExtensions(self):
|
||||
return self.submitTask(ListExtensionsTask())
|
||||
|
|
|
@ -36,6 +36,9 @@ providers:
|
|||
base-image: 'Fake Precise'
|
||||
min-ram: 8192
|
||||
name-filter: 'Fake'
|
||||
meta:
|
||||
key: value
|
||||
key2: value
|
||||
setup: prepare_node_devstack.sh
|
||||
|
||||
targets:
|
||||
|
|
Loading…
Reference in New Issue