diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/xenserver/xenapi/etc/xapi.d/plugins/glance | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance new file mode 100644 index 000000000..5e648b970 --- /dev/null +++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance @@ -0,0 +1,132 @@ +#!/usr/bin/env python + +# Copyright (c) 2010 Citrix Systems, Inc. +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# 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. + +# +# XenAPI plugin for putting images into glance +# + +import base64 +import errno +import hmac +import httplib +import os +import os.path +import pickle +import sha +import subprocess +import time +import urlparse + +import XenAPIPlugin + +#FIXME(sirp): should this use pluginlib from 5.6? +from pluginlib_nova import * +configure_logging('glance') + +CHUNK_SIZE = 8192 +FILE_SR_PATH = '/var/run/sr-mount' + +def put_vdis(session, args): + params = pickle.loads(exists(args, 'params')) + vdi_uuids = params["vdi_uuids"] + image_name = params["image_name"] + glance_host = params["glance_host"] + glance_port = params["glance_port"] + + sr_path = get_sr_path(session) + #FIXME(sirp): writing to a temp file until Glance supports chunked-PUTs + tmp_file = "%s.tar.gz" % os.path.join('/tmp', image_name) + tar_cmd = ['tar', '-zcf', tmp_file, '--directory=%s' % sr_path] + paths = [ "%s.vhd" % vdi_uuid for vdi_uuid in vdi_uuids ] + tar_cmd.extend(paths) + logging.debug("Bundling image with cmd: %s", tar_cmd) + subprocess.call(tar_cmd) + logging.debug("Writing to test file %s", tmp_file) + put_bundle_in_glance(tmp_file, image_name, glance_host, glance_port) + return "" # FIXME(sirp): return anything useful here? + + +def put_bundle_in_glance(tmp_file, image_name, glance_host, glance_port): + size = os.path.getsize(tmp_file) + basename = os.path.basename(tmp_file) + + bundle = open(tmp_file, 'r') + try: + headers = { + 'x-image-meta-store': 'file', + 'x-image-meta-is_public': 'True', + 'x-image-meta-type': 'raw', + 'x-image-meta-name': image_name, + 'x-image-meta-size': size, + 'content-length': size, + 'content-type': 'application/octet-stream', + } + conn = httplib.HTTPConnection(glance_host, glance_port) + #NOTE(sirp): httplib under python2.4 won't accept a file-like object + # to request + conn.putrequest('POST', '/images') + + for header, value in headers.iteritems(): + conn.putheader(header, value) + conn.endheaders() + + chunk = bundle.read(CHUNK_SIZE) + while chunk: + conn.send(chunk) + chunk = bundle.read(CHUNK_SIZE) + + + res = conn.getresponse() + #FIXME(sirp): should this be 201 Created? + if res.status != httplib.OK: + raise Exception("Unexpected response from Glance %i" % res.status) + finally: + bundle.close() + +def get_sr_path(session): + sr_ref = find_sr(session) + + if sr_ref is None: + raise Exception('Cannot find SR to read VDI from') + + sr_rec = session.xenapi.SR.get_record(sr_ref) + sr_uuid = sr_rec["uuid"] + sr_path = os.path.join(FILE_SR_PATH, sr_uuid) + return sr_path + + +#TODO(sirp): both objectstore and glance need this, should this be refactored +#into common lib +def find_sr(session): + host = get_this_host(session) + srs = session.xenapi.SR.get_all() + for sr in srs: + sr_rec = session.xenapi.SR.get_record(sr) + if not ('i18n-key' in sr_rec['other_config'] and + sr_rec['other_config']['i18n-key'] == 'local-storage'): + continue + for pbd in sr_rec['PBDs']: + pbd_rec = session.xenapi.PBD.get_record(pbd) + if pbd_rec['host'] == host: + return sr + return None + + +if __name__ == '__main__': + XenAPIPlugin.dispatch({'put_vdis': put_vdis}) |
