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:
parent
019d953ef5
commit
1dea34fa1a
@ -498,13 +498,13 @@ class SessionBase(object):
|
|||||||
return as_json(returncode='0', message='success')
|
return as_json(returncode='0', message='success')
|
||||||
elif (plugin, method) == ('agent', 'resetnetwork'):
|
elif (plugin, method) == ('agent', 'resetnetwork'):
|
||||||
return as_json(returncode='0', message='success')
|
return as_json(returncode='0', message='success')
|
||||||
elif (plugin, method) == ('glance', 'copy_kernel_vdi'):
|
|
||||||
return ''
|
|
||||||
elif (plugin, method) == ('glance', 'upload_vhd'):
|
elif (plugin, method) == ('glance', 'upload_vhd'):
|
||||||
return ''
|
return ''
|
||||||
elif (plugin, method) == ('glance', 'create_kernel_ramdisk'):
|
elif (plugin, method) == ('kernel', 'copy_vdi'):
|
||||||
return ''
|
return ''
|
||||||
elif (plugin, method) == ('glance', 'remove_kernel_ramdisk'):
|
elif (plugin, method) == ('kernel', 'create_kernel_ramdisk'):
|
||||||
|
return ''
|
||||||
|
elif (plugin, method) == ('kernel', 'remove_kernel_ramdisk'):
|
||||||
return ''
|
return ''
|
||||||
elif (plugin, method) == ('migration', 'move_vhds_into_sr'):
|
elif (plugin, method) == ('migration', 'move_vhds_into_sr'):
|
||||||
return ''
|
return ''
|
||||||
|
@ -600,8 +600,8 @@ def create_kernel_image(context, session, instance, image_id, user_id,
|
|||||||
args = {}
|
args = {}
|
||||||
args['cached-image'] = image_id
|
args['cached-image'] = image_id
|
||||||
args['new-image-uuid'] = str(uuid.uuid4())
|
args['new-image-uuid'] = str(uuid.uuid4())
|
||||||
filename = session.call_plugin('glance', 'create_kernel_ramdisk',
|
filename = session.call_plugin(
|
||||||
args)
|
'kernel', 'create_kernel_ramdisk', args)
|
||||||
|
|
||||||
if filename == "":
|
if filename == "":
|
||||||
return _fetch_image(context, session, instance, image_id, image_type)
|
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)}
|
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):
|
def _create_cached_image(context, session, instance, image_id, image_type):
|
||||||
sr_ref = safe_find_sr(session)
|
sr_ref = safe_find_sr(session)
|
||||||
sr_type = session.call_xenapi('SR.get_record', sr_ref)["type"]
|
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.
|
# content of the VDI into the proper path.
|
||||||
LOG.debug(_("Copying VDI %s to /boot/guest on dom0"),
|
LOG.debug(_("Copying VDI %s to /boot/guest on dom0"),
|
||||||
vdi_ref, instance=instance)
|
vdi_ref, instance=instance)
|
||||||
fn = "copy_kernel_vdi"
|
|
||||||
args = {}
|
args = {}
|
||||||
args['vdi-ref'] = vdi_ref
|
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)
|
args['image-size'] = str(vdi_size)
|
||||||
if FLAGS.cache_images:
|
if FLAGS.cache_images:
|
||||||
args['cached-image'] = image_id
|
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.
|
# Remove the VDI as it is not needed anymore.
|
||||||
destroy_vdi(session, vdi_ref)
|
destroy_vdi(session, vdi_ref)
|
||||||
|
@ -292,8 +292,9 @@ class VMOps(object):
|
|||||||
if kernel_file or ramdisk_file:
|
if kernel_file or ramdisk_file:
|
||||||
LOG.debug(_("Removing kernel/ramdisk files from dom0"),
|
LOG.debug(_("Removing kernel/ramdisk files from dom0"),
|
||||||
instance=instance)
|
instance=instance)
|
||||||
self._destroy_kernel_ramdisk_plugin_call(kernel_file,
|
vm_utils.destroy_kernel_ramdisk(
|
||||||
ramdisk_file)
|
self._session, kernel_file, ramdisk_file)
|
||||||
|
|
||||||
undo_mgr.undo_with(undo_create_kernel_ramdisk)
|
undo_mgr.undo_with(undo_create_kernel_ramdisk)
|
||||||
return kernel_file, ramdisk_file
|
return kernel_file, ramdisk_file
|
||||||
|
|
||||||
@ -1001,14 +1002,6 @@ class VMOps(object):
|
|||||||
except volume_utils.StorageError as exc:
|
except volume_utils.StorageError as exc:
|
||||||
LOG.error(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):
|
def _destroy_kernel_ramdisk(self, instance, vm_ref):
|
||||||
"""Three situations can occur:
|
"""Three situations can occur:
|
||||||
|
|
||||||
@ -1038,7 +1031,7 @@ class VMOps(object):
|
|||||||
(kernel, ramdisk) = vm_utils.lookup_kernel_ramdisk(self._session,
|
(kernel, ramdisk) = vm_utils.lookup_kernel_ramdisk(self._session,
|
||||||
vm_ref)
|
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)
|
LOG.debug(_("kernel/ramdisk files removed"), instance=instance)
|
||||||
|
|
||||||
def _destroy_vm(self, instance, vm_ref):
|
def _destroy_vm(self, instance, vm_ref):
|
||||||
|
@ -30,6 +30,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
/etc/xapi.d/plugins/agent
|
/etc/xapi.d/plugins/agent
|
||||||
/etc/xapi.d/plugins/glance
|
/etc/xapi.d/plugins/glance
|
||||||
|
/etc/xapi.d/plugins/kernel
|
||||||
/etc/xapi.d/plugins/migration
|
/etc/xapi.d/plugins/migration
|
||||||
/etc/xapi.d/plugins/pluginlib_nova.py
|
/etc/xapi.d/plugins/pluginlib_nova.py
|
||||||
/etc/xapi.d/plugins/xenhost
|
/etc/xapi.d/plugins/xenhost
|
||||||
|
@ -28,7 +28,6 @@ except ImportError:
|
|||||||
import simplejson as json
|
import simplejson as json
|
||||||
import md5
|
import md5
|
||||||
import os
|
import os
|
||||||
import os.path
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
import urllib2
|
import urllib2
|
||||||
@ -40,47 +39,11 @@ import utils
|
|||||||
from pluginlib_nova import *
|
from pluginlib_nova import *
|
||||||
configure_logging('glance')
|
configure_logging('glance')
|
||||||
|
|
||||||
KERNEL_DIR = '/boot/guest'
|
|
||||||
|
|
||||||
|
|
||||||
class RetryableError(Exception):
|
class RetryableError(Exception):
|
||||||
pass
|
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):
|
def _download_tarball_and_verify(request, staging_path):
|
||||||
try:
|
try:
|
||||||
response = urllib2.urlopen(request)
|
response = urllib2.urlopen(request)
|
||||||
@ -225,24 +188,6 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
|
|||||||
conn.close()
|
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):
|
def download_vhd(session, args):
|
||||||
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
||||||
into the storage repository
|
into the storage repository
|
||||||
@ -295,35 +240,6 @@ def upload_vhd(session, args):
|
|||||||
return "" # Nothing useful to return on an upload
|
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__':
|
if __name__ == '__main__':
|
||||||
XenAPIPlugin.dispatch({'upload_vhd': upload_vhd,
|
XenAPIPlugin.dispatch({'upload_vhd': upload_vhd,
|
||||||
'download_vhd': download_vhd,
|
'download_vhd': download_vhd})
|
||||||
'copy_kernel_vdi': copy_kernel_vdi,
|
|
||||||
'create_kernel_ramdisk': create_kernel_ramdisk,
|
|
||||||
'remove_kernel_ramdisk': remove_kernel_ramdisk})
|
|
||||||
|
123
plugins/xenserver/xenapi/etc/xapi.d/plugins/kernel
Executable file
123
plugins/xenserver/xenapi/etc/xapi.d/plugins/kernel
Executable 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})
|
Loading…
Reference in New Issue
Block a user