Refactoring code to kernel Dom0 plugin.

The kernel and ramdisk VDI manipulation code really has nothing to do
with Glance so it doesn't make a lot of sense for it to exist in the
Glance Dom0 plugin.

This patch refactors the code out to its own plugin and then applies a
few misc cleanups.

Change-Id: I363d54ea3c2d51aa6a6c1635b4fb59ebb9ce1fc0
This commit is contained in:
Rick Harris 2012-06-29 21:26:42 +00:00
parent 019d953ef5
commit 1dea34fa1a
6 changed files with 146 additions and 104 deletions

View File

@ -498,13 +498,13 @@ class SessionBase(object):
return as_json(returncode='0', message='success')
elif (plugin, method) == ('agent', 'resetnetwork'):
return as_json(returncode='0', message='success')
elif (plugin, method) == ('glance', 'copy_kernel_vdi'):
return ''
elif (plugin, method) == ('glance', 'upload_vhd'):
return ''
elif (plugin, method) == ('glance', 'create_kernel_ramdisk'):
elif (plugin, method) == ('kernel', 'copy_vdi'):
return ''
elif (plugin, method) == ('glance', 'remove_kernel_ramdisk'):
elif (plugin, method) == ('kernel', 'create_kernel_ramdisk'):
return ''
elif (plugin, method) == ('kernel', 'remove_kernel_ramdisk'):
return ''
elif (plugin, method) == ('migration', 'move_vhds_into_sr'):
return ''

View File

@ -600,8 +600,8 @@ def create_kernel_image(context, session, instance, image_id, user_id,
args = {}
args['cached-image'] = image_id
args['new-image-uuid'] = str(uuid.uuid4())
filename = session.call_plugin('glance', 'create_kernel_ramdisk',
args)
filename = session.call_plugin(
'kernel', 'create_kernel_ramdisk', args)
if filename == "":
return _fetch_image(context, session, instance, image_id, image_type)
@ -610,6 +610,15 @@ def create_kernel_image(context, session, instance, image_id, user_id,
return {vdi_type: dict(uuid=None, file=filename)}
def destroy_kernel_ramdisk(session, kernel, ramdisk):
args = {}
if kernel:
args['kernel-file'] = kernel
if ramdisk:
args['ramdisk-file'] = ramdisk
session.call_plugin('kernel', 'remove_kernel_ramdisk', args)
def _create_cached_image(context, session, instance, image_id, image_type):
sr_ref = safe_find_sr(session)
sr_type = session.call_xenapi('SR.get_record', sr_ref)["type"]
@ -904,7 +913,7 @@ def _fetch_disk_image(context, session, instance, image_id, image_type):
# content of the VDI into the proper path.
LOG.debug(_("Copying VDI %s to /boot/guest on dom0"),
vdi_ref, instance=instance)
fn = "copy_kernel_vdi"
args = {}
args['vdi-ref'] = vdi_ref
@ -912,7 +921,7 @@ def _fetch_disk_image(context, session, instance, image_id, image_type):
args['image-size'] = str(vdi_size)
if FLAGS.cache_images:
args['cached-image'] = image_id
filename = session.call_plugin('glance', fn, args)
filename = session.call_plugin('kernel', 'copy_vdi', args)
# Remove the VDI as it is not needed anymore.
destroy_vdi(session, vdi_ref)

View File

@ -292,8 +292,9 @@ class VMOps(object):
if kernel_file or ramdisk_file:
LOG.debug(_("Removing kernel/ramdisk files from dom0"),
instance=instance)
self._destroy_kernel_ramdisk_plugin_call(kernel_file,
ramdisk_file)
vm_utils.destroy_kernel_ramdisk(
self._session, kernel_file, ramdisk_file)
undo_mgr.undo_with(undo_create_kernel_ramdisk)
return kernel_file, ramdisk_file
@ -1001,14 +1002,6 @@ class VMOps(object):
except volume_utils.StorageError as exc:
LOG.error(exc)
def _destroy_kernel_ramdisk_plugin_call(self, kernel, ramdisk):
args = {}
if kernel:
args['kernel-file'] = kernel
if ramdisk:
args['ramdisk-file'] = ramdisk
self._session.call_plugin('glance', 'remove_kernel_ramdisk', args)
def _destroy_kernel_ramdisk(self, instance, vm_ref):
"""Three situations can occur:
@ -1038,7 +1031,7 @@ class VMOps(object):
(kernel, ramdisk) = vm_utils.lookup_kernel_ramdisk(self._session,
vm_ref)
self._destroy_kernel_ramdisk_plugin_call(kernel, ramdisk)
vm_utils.destroy_kernel_ramdisk(self._session, kernel, ramdisk)
LOG.debug(_("kernel/ramdisk files removed"), instance=instance)
def _destroy_vm(self, instance, vm_ref):

View File

@ -30,6 +30,7 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root,-)
/etc/xapi.d/plugins/agent
/etc/xapi.d/plugins/glance
/etc/xapi.d/plugins/kernel
/etc/xapi.d/plugins/migration
/etc/xapi.d/plugins/pluginlib_nova.py
/etc/xapi.d/plugins/xenhost

View File

@ -28,7 +28,6 @@ except ImportError:
import simplejson as json
import md5
import os
import os.path
import shutil
import urllib2
@ -40,47 +39,11 @@ import utils
from pluginlib_nova import *
configure_logging('glance')
KERNEL_DIR = '/boot/guest'
class RetryableError(Exception):
pass
def _copy_kernel_vdi(dest, copy_args):
vdi_uuid = copy_args['vdi_uuid']
vdi_size = copy_args['vdi_size']
cached_image = copy_args['cached-image']
logging.debug("copying kernel/ramdisk file from %s to /boot/guest/%s",
dest, vdi_uuid)
filename = KERNEL_DIR + '/' + vdi_uuid
#make sure KERNEL_DIR exists, otherwise create it
if not os.path.isdir(KERNEL_DIR):
logging.debug("Creating directory %s", KERNEL_DIR)
os.makedirs(KERNEL_DIR)
#read data from /dev/ and write into a file on /boot/guest
of = open(filename, 'wb')
f = open(dest, 'rb')
#copy only vdi_size bytes
data = f.read(vdi_size)
of.write(data)
if cached_image:
#create a cache file. If caching is enabled, kernel images do not have
#to be fetched from glance.
cached_image = KERNEL_DIR + '/' + cached_image
logging.debug("copying kernel/ramdisk file from %s to /boot/guest/%s",
dest, cached_image)
cache_file = open(cached_image, 'wb')
cache_file.write(data)
cache_file.close()
logging.debug("Done. Filename: %s", cached_image)
f.close()
of.close()
logging.debug("Done. Filename: %s", filename)
return filename
def _download_tarball_and_verify(request, staging_path):
try:
response = urllib2.urlopen(request)
@ -225,24 +188,6 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
conn.close()
def create_kernel_ramdisk(session, args):
"""Creates a copy of the kernel/ramdisk image if it is present in the
cache. If the image is not present in the cache, it does nothing.
"""
cached_image = exists(args, 'cached-image')
image_uuid = exists(args, 'new-image-uuid')
cached_image_filename = KERNEL_DIR + '/' + cached_image
filename = KERNEL_DIR + '/' + image_uuid
if os.path.isfile(cached_image_filename):
shutil.copyfile(cached_image_filename, filename)
logging.debug("Done. Filename: %s", filename)
else:
filename = ""
logging.debug("Cached kernel/ramdisk image not found")
return filename
def download_vhd(session, args):
"""Download an image from Glance, unbundle it, and then deposit the VHDs
into the storage repository
@ -295,35 +240,6 @@ def upload_vhd(session, args):
return "" # Nothing useful to return on an upload
def copy_kernel_vdi(session, args):
vdi = exists(args, 'vdi-ref')
size = exists(args, 'image-size')
cached_image = optional(args, 'cached-image')
#Use the uuid as a filename
vdi_uuid = session.xenapi.VDI.get_uuid(vdi)
copy_args = {'vdi_uuid': vdi_uuid,
'vdi_size': int(size),
'cached-image': cached_image}
filename = with_vdi_in_dom0(session, vdi, False,
lambda dev:
_copy_kernel_vdi('/dev/%s' % dev, copy_args))
return filename
def remove_kernel_ramdisk(session, args):
"""Removes kernel and/or ramdisk from dom0's file system"""
kernel_file = optional(args, 'kernel-file')
ramdisk_file = optional(args, 'ramdisk-file')
if kernel_file:
os.remove(kernel_file)
if ramdisk_file:
os.remove(ramdisk_file)
return "ok"
if __name__ == '__main__':
XenAPIPlugin.dispatch({'upload_vhd': upload_vhd,
'download_vhd': download_vhd,
'copy_kernel_vdi': copy_kernel_vdi,
'create_kernel_ramdisk': create_kernel_ramdisk,
'remove_kernel_ramdisk': remove_kernel_ramdisk})
'download_vhd': download_vhd})

View File

@ -0,0 +1,123 @@
#!/usr/bin/env python
# Copyright (c) 2012 Openstack, LLC
# 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.
"""Handle the manipulation of kernel images."""
import os
import shutil
import XenAPIPlugin
#FIXME(sirp): should this use pluginlib from 5.6?
from pluginlib_nova import *
configure_logging('kernel')
KERNEL_DIR = '/boot/guest'
def _copy_vdi(dest, copy_args):
vdi_uuid = copy_args['vdi_uuid']
vdi_size = copy_args['vdi_size']
cached_image = copy_args['cached-image']
logging.debug("copying kernel/ramdisk file from %s to /boot/guest/%s",
dest, vdi_uuid)
filename = KERNEL_DIR + '/' + vdi_uuid
# Make sure KERNEL_DIR exists, otherwise create it
if not os.path.isdir(KERNEL_DIR):
logging.debug("Creating directory %s", KERNEL_DIR)
os.makedirs(KERNEL_DIR)
# Read data from /dev/ and write into a file on /boot/guest
of = open(filename, 'wb')
f = open(dest, 'rb')
# Copy only vdi_size bytes
data = f.read(vdi_size)
of.write(data)
if cached_image:
# Create a cache file. If caching is enabled, kernel images do not have
# to be fetched from glance.
cached_image = KERNEL_DIR + '/' + cached_image
logging.debug("copying kernel/ramdisk file from %s to /boot/guest/%s",
dest, cached_image)
cache_file = open(cached_image, 'wb')
cache_file.write(data)
cache_file.close()
logging.debug("Done. Filename: %s", cached_image)
f.close()
of.close()
logging.debug("Done. Filename: %s", filename)
return filename
def copy_vdi(session, args):
vdi = exists(args, 'vdi-ref')
size = exists(args, 'image-size')
cached_image = optional(args, 'cached-image')
# Use the uuid as a filename
vdi_uuid = session.xenapi.VDI.get_uuid(vdi)
copy_args = {'vdi_uuid': vdi_uuid,
'vdi_size': int(size),
'cached-image': cached_image}
filename = with_vdi_in_dom0(session, vdi, False,
lambda dev:
_copy_vdi('/dev/%s' % dev, copy_args))
return filename
def create_kernel_ramdisk(session, args):
"""Creates a copy of the kernel/ramdisk image if it is present in the
cache. If the image is not present in the cache, it does nothing.
"""
cached_image = exists(args, 'cached-image')
image_uuid = exists(args, 'new-image-uuid')
cached_image_filename = KERNEL_DIR + '/' + cached_image
filename = KERNEL_DIR + '/' + image_uuid
if os.path.isfile(cached_image_filename):
shutil.copyfile(cached_image_filename, filename)
logging.debug("Done. Filename: %s", filename)
else:
filename = ""
logging.debug("Cached kernel/ramdisk image not found")
return filename
def remove_kernel_ramdisk(session, args):
"""Removes kernel and/or ramdisk from dom0's file system"""
kernel_file = optional(args, 'kernel-file')
ramdisk_file = optional(args, 'ramdisk-file')
if kernel_file:
os.remove(kernel_file)
if ramdisk_file:
os.remove(ramdisk_file)
return "ok"
if __name__ == '__main__':
XenAPIPlugin.dispatch({'copy_vdi': copy_vdi,
'create_kernel_ramdisk': create_kernel_ramdisk,
'remove_kernel_ramdisk': remove_kernel_ramdisk})