Merge with xen-unstable.hg.

Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
This commit is contained in:
Hollis Blanchard committed 2007-03-21 18:08:31 -05:00
commit 001e8c5cd8
236 files changed
+5564 -3043

No files matched your search

+1 -2
View File
@@ -39,14 +39,13 @@ vm_cfg = {
local_vdi_cfg = {
'name_label': 'gentoo.hvm',
'name_description': '',
'location': 'file:/root/gentoo.amd64.hvm.img',
'virtual_size': 0,
'sector_size': 0,
'type': 'system',
'parent': '',
'SR_name': 'Local',
'sharable': False,
'read_only': False,
'other_config': {'location': 'file:/root/gentoo.amd64.hvm.img'},
}
local_vbd_cfg = {
+2 -4
View File
@@ -39,8 +39,7 @@ vm_cfg = {
vdi_cfg = {
'name_label': 'API_VDI',
'name_description': '',
'virtual_size': 100 * 1024 * 1024,
'sector_size': 1024,
'virtual_size': 100 * 1024 * 1024 * 1024,
'type': 'system',
'parent': '',
'SR_name': 'QCoW',
@@ -60,14 +59,13 @@ vbd_cfg = {
local_vdi_cfg = {
'name_label': 'gentoo.amd64.img',
'name_description': '',
'location': 'file:/root/gentoo.amd64.img',
'virtual_size': 0,
'sector_size': 0,
'type': 'system',
'parent': '',
'SR_name': 'Local',
'sharable': False,
'read_only': False,
'other_config': {'location': 'file:/root/gentoo.amd64.img'},
}
local_vbd_cfg = {
+3 -8
View File
@@ -40,8 +40,7 @@ VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(VCPUs_number)-5s'\
' %(power_state)-10s %(uuid)-36s'
SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \
'%(type)-10s'
VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
'%(sector_size)-8s'
VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s'
VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
@@ -96,12 +95,9 @@ OPTIONS = {
'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}),
(('--name-description',), {'help': 'Description for VDI'}),
(('--sector-size',), {'type': 'int',
'help': 'Sector size',
'default': 0}),
(('--virtual-size',), {'type': 'int',
'default': 0,
'help': 'Size of VDI in sectors'}),
'help': 'Size of VDI in bytes'}),
(('--type',), {'choices': ['system', 'user', 'ephemeral'],
'default': 'system',
'help': 'VDI type'}),
@@ -569,8 +565,7 @@ def xapi_vdi_list(args, async = False):
if not is_long:
print VDI_LIST_FORMAT % {'name_label': 'VDI Label',
'uuid' : 'UUID',
'virtual_size': 'Bytes',
'sector_size': 'Sector Size'}
'virtual_size': 'Bytes'}
for vdi in vdis:
vdi_struct = execute(server, 'VDI.get_record', (session, vdi))
+1 -2
View File
@@ -1,7 +1,6 @@
name_label = 'VDI 1'
name_description = ''
virtual_size = 10 * 1024 * 1024
sector_size = 1024
virtual_size = 10 * 1024 * 1024 * 1024
type = 'system'
sharable = False
read_only = False
+65 -29
View File
@@ -47,20 +47,24 @@ static PyObject *dom_op(XcObject *self, PyObject *args,
static PyObject *pyxc_error_to_exception(void)
{
PyObject *pyerr;
const xc_error const *err = xc_get_last_error();
const xc_error *err = xc_get_last_error();
const char *desc = xc_error_code_to_desc(err->code);
if (err->code == XC_ERROR_NONE)
if ( err->code == XC_ERROR_NONE )
return PyErr_SetFromErrno(xc_error_obj);
if (err->message[0] != '\0')
if ( err->message[0] != '\0' )
pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
else
pyerr = Py_BuildValue("(is)", err->code, desc);
xc_clear_last_error();
PyErr_SetObject(xc_error_obj, pyerr);
if ( pyerr != NULL )
{
PyErr_SetObject(xc_error_obj, pyerr);
Py_DECREF(pyerr);
}
return NULL;
}
@@ -70,13 +74,13 @@ static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
uint32_t dom;
char *corefile;
if (!PyArg_ParseTuple(args, "is", &dom, &corefile))
if ( !PyArg_ParseTuple(args, "is", &dom, &corefile) )
return NULL;
if ( (corefile == NULL) || (corefile[0] == '\0') )
return NULL;
if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
return pyxc_error_to_exception();
Py_INCREF(zero);
@@ -168,10 +172,10 @@ static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
{
uint32_t dom, reason;
if (!PyArg_ParseTuple(args, "ii", &dom, &reason))
if ( !PyArg_ParseTuple(args, "ii", &dom, &reason) )
return NULL;
if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0)
if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
return pyxc_error_to_exception();
Py_INCREF(zero);
@@ -183,10 +187,10 @@ static PyObject *pyxc_domain_resume(XcObject *self, PyObject *args)
uint32_t dom;
int fast;
if (!PyArg_ParseTuple(args, "ii", &dom, &fast))
if ( !PyArg_ParseTuple(args, "ii", &dom, &fast) )
return NULL;
if (xc_domain_resume(self->xc_handle, dom, fast) != 0)
if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
return pyxc_error_to_exception();
Py_INCREF(zero);
@@ -282,7 +286,7 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
PyObject *args,
PyObject *kwds)
{
PyObject *list, *info_dict;
PyObject *list, *info_dict, *pyhandle;
uint32_t first_dom = 0;
int max_doms = 1024, nr_doms, i, j;
@@ -308,26 +312,34 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
list = PyList_New(nr_doms);
for ( i = 0 ; i < nr_doms; i++ )
{
PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t));
info_dict = Py_BuildValue(
"{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
",s:L,s:L,s:L,s:i,s:i}",
"domid", (int)info[i].domid,
"online_vcpus", info[i].nr_online_vcpus,
"max_vcpu_id", info[i].max_vcpu_id,
"hvm", info[i].hvm,
"dying", info[i].dying,
"crashed", info[i].crashed,
"shutdown", info[i].shutdown,
"paused", info[i].paused,
"blocked", info[i].blocked,
"running", info[i].running,
"mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024),
"cpu_time", (long long)info[i].cpu_time,
"maxmem_kb", (long long)info[i].max_memkb,
"ssidref", (int)info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason);
pyhandle = PyList_New(sizeof(xen_domain_handle_t));
if ( (pyhandle == NULL) || (info_dict == NULL) )
{
Py_DECREF(list);
if ( pyhandle != NULL ) { Py_DECREF(pyhandle); }
if ( info_dict != NULL ) { Py_DECREF(info_dict); }
return NULL;
}
for ( j = 0; j < sizeof(xen_domain_handle_t); j++ )
PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j]));
info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
",s:l,s:L,s:l,s:i,s:i}",
"domid", info[i].domid,
"online_vcpus", info[i].nr_online_vcpus,
"max_vcpu_id", info[i].max_vcpu_id,
"hvm", info[i].hvm,
"dying", info[i].dying,
"crashed", info[i].crashed,
"shutdown", info[i].shutdown,
"paused", info[i].paused,
"blocked", info[i].blocked,
"running", info[i].running,
"mem_kb", info[i].nr_pages*(XC_PAGE_SIZE/1024),
"cpu_time", info[i].cpu_time,
"maxmem_kb", info[i].max_memkb,
"ssidref", info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason);
PyDict_SetItemString(info_dict, "handle", pyhandle);
Py_DECREF(pyhandle);
PyList_SetItem(list, i, info_dict);
@@ -1007,6 +1019,24 @@ static PyObject *pyxc_domain_send_trigger(XcObject *self,
return zero;
}
static PyObject *pyxc_send_debug_keys(XcObject *self,
PyObject *args,
PyObject *kwds)
{
char *keys;
static char *kwd_list[] = { "keys", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) )
return NULL;
if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
}
static PyObject *dom_op(XcObject *self, PyObject *args,
int (*fn)(int, uint32_t))
{
@@ -1380,6 +1410,12 @@ static PyMethodDef pyxc_methods[] = {
" vcpu [int]: VCPU to be sent trigger.\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "send_debug_keys",
(PyCFunction)pyxc_send_debug_keys,
METH_VARARGS | METH_KEYWORDS, "\n"
"Inject debug keys into Xen.\n"
" keys [str]: String of keys to inject.\n" },
#ifdef __powerpc__
{ "arch_alloc_real_mode_area",
(PyCFunction)pyxc_alloc_real_mode_area,
+12 -5
View File
@@ -66,16 +66,23 @@ def blkdev_segment(name):
'type' : 'Disk' }
return val
def blkdev_uname_to_file(uname):
"""Take a blkdev uname and return the corresponding filename."""
fn = None
def _parse_uname(uname):
fn = taptype = None
if uname.find(":") != -1:
(typ, fn) = uname.split(":", 1)
if typ == "phy" and not fn.startswith("/"):
fn = "/dev/%s" %(fn,)
if typ == "tap":
(typ, fn) = fn.split(":", 1)
return fn
(taptype, fn) = fn.split(":", 1)
return (fn, taptype)
def blkdev_uname_to_file(uname):
"""Take a blkdev uname and return the corresponding filename."""
return _parse_uname(uname)[0]
def blkdev_uname_to_taptype(uname):
"""Take a blkdev uname and return the blktap type."""
return _parse_uname(uname)[1]
def mount_mode(name):
mode = None
+35 -17
View File
@@ -200,6 +200,18 @@ class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
else:
response = self._dispatch(method, params)
if self.xenapi and \
(response is None or
not isinstance(response, dict) or
'Status' not in response):
log.exception('Internal error handling %s: Invalid result %s',
method, response)
response = { "Status": "Failure",
"ErrorDescription":
['INTERNAL_ERROR',
'Invalid result %s handling %s' %
(response, method)]}
# With either Unicode or normal strings, we can only transmit
# \t, \n, \r, \u0020-\ud7ff, \ue000-\ufffd, and \u10000-\u10ffff
# in an XML document. xmlrpclib does not escape these values
@@ -215,24 +227,30 @@ class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
response = xmlrpclib.dumps(response,
methodresponse=1,
allow_none=1)
except xmlrpclib.Fault, fault:
response = xmlrpclib.dumps(fault)
except Exception, exn:
if self.xenapi:
if _is_not_supported(exn):
errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
try:
if self.xenapi:
if _is_not_supported(exn):
errdesc = ['MESSAGE_METHOD_UNKNOWN', method]
else:
log.exception('Internal error handling %s', method)
errdesc = ['INTERNAL_ERROR', str(exn)]
response = xmlrpclib.dumps(
({ "Status": "Failure",
"ErrorDescription": errdesc },),
methodresponse = 1)
else:
log.exception('Internal error handling %s', method)
errdesc = ['INTERNAL_ERROR', str(exn)]
response = xmlrpclib.dumps(
({ "Status": "Failure",
"ErrorDescription": errdesc },),
methodresponse = 1)
else:
log.exception('Internal error handling %s', method)
import xen.xend.XendClient
response = xmlrpclib.dumps(
xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
import xen.xend.XendClient
if isinstance(exn, xmlrpclib.Fault):
response = xmlrpclib.dumps(exn)
else:
log.exception('Internal error handling %s', method)
response = xmlrpclib.dumps(
xmlrpclib.Fault(xen.xend.XendClient.ERROR_INTERNAL, str(exn)))
except:
log.exception('Internal error handling error')
return response
@@ -241,7 +259,7 @@ def _is_not_supported(exn):
try:
m = notSupportedRE.search(exn[0])
return m is not None
except TypeError, e:
except:
return False
+275 -149
View File
@@ -31,10 +31,14 @@ from xen.xend.XendError import *
from xen.xend.XendClient import ERROR_INVALID_DOMAIN
from xen.xend.XendLogging import log
from xen.xend.XendTask import XendTask
from xen.xend.XendVMMetrics import XendVMMetrics
from xen.xend.XendAPIConstants import *
from xen.util.xmlrpclib2 import stringify
from xen.util.blkif import blkdev_name_to_number
AUTH_NONE = 'none'
AUTH_PAM = 'pam'
@@ -192,6 +196,16 @@ def valid_vm(func):
_check_ref(XendDomain.instance().is_valid_vm,
'VM', func, *args, **kwargs)
def valid_vm_metrics(func):
"""Decorator to verify if vm_metrics_ref is valid before calling method.
@param func: function with params: (self, session, vm_metrics_ref, ...)
@rtype: callable object
"""
return lambda *args, **kwargs: \
_check_ref(XendVMMetrics.is_valid_vm_metrics,
'VM_metrics', func, *args, **kwargs)
def valid_network(func):
"""Decorator to verify if network_ref is valid before calling method.
@@ -400,6 +414,7 @@ class XendAPI(object):
'host_metrics' : valid_host_metrics,
'network' : valid_network,
'VM' : valid_vm,
'VM_metrics' : valid_vm_metrics,
'VBD' : valid_vbd,
'VBD_metrics' : valid_vbd_metrics,
'VIF' : valid_vif,
@@ -629,6 +644,7 @@ class XendAPI(object):
host_attr_ro = ['software_version',
'resident_VMs',
'host_CPUs',
'cpu_configuration',
'metrics',
'capabilities',
'supported_bootloaders',
@@ -638,6 +654,7 @@ class XendAPI(object):
'API_version_vendor_implementation']
host_attr_rw = ['name_label',
'sched_policy',
'name_description',
'other_config']
@@ -647,7 +664,9 @@ class XendAPI(object):
('shutdown', None),
('add_to_other_config', None),
('remove_from_other_config', None),
('dmesg', 'String')]
('dmesg', 'String'),
('get_log', 'String'),
('send_debug_keys', None)]
host_funcs = [('get_by_name_label', 'Set(host)')]
@@ -676,8 +695,9 @@ class XendAPI(object):
return xen_api_success_void()
def host_remove_from_other_config(self, session, host_ref, key):
node = XendNode.instance()
del node.other_config[key]
node.save()
if key in node.other_config:
del node.other_config[key]
node.save()
return xen_api_success_void()
def host_get_API_version_major(self, _, ref):
return xen_api_success(XEN_API_VERSION_MAJOR)
@@ -699,7 +719,13 @@ class XendAPI(object):
return xen_api_success(XendNode.instance().get_capabilities())
def host_get_supported_bootloaders(self, session, host_ref):
return xen_api_success(['pygrub'])
def host_get_sched_policy(self, _, host_ref):
return xen_api_success(XendNode.instance().get_vcpus_policy())
def host_set_sched_policy(self, _, host_ref, policy):
return xen_api_todo()
def host_get_cpu_configuration(self, _, host_ref):
return xen_api_success(XendNode.instance().get_cpu_configuration())
# object methods
def host_disable(self, session, host_ref):
XendDomain.instance().set_allow_new_domains(False)
@@ -716,8 +742,21 @@ class XendAPI(object):
return xen_api_error(XEND_ERROR_HOST_RUNNING)
return xen_api_error(XEND_ERROR_UNSUPPORTED)
def host_dmesg(self, session, host_ref):
return xen_api_success(XendDmesg.instance().info())
def host_dmesg(self, session, host_ref, clear):
if clear:
return xen_api_success(XendDmesg.instance().clear())
else:
return xen_api_success(XendDmesg.instance().info())
def host_get_log(self, session, host_ref):
log_file = open(XendLogging.getLogFilename())
log_buffer = log_file.read()
return xen_api_success(log_buffer)
def host_send_debug_keys(self, _, host_ref, keys):
node = XendNode.instance()
node.send_debug_keys(keys)
return xen_api_success_void()
def host_get_record(self, session, host_ref):
node = XendNode.instance()
@@ -734,9 +773,11 @@ class XendAPI(object):
'other_config': node.other_config,
'resident_VMs': dom.get_domain_refs(),
'host_CPUs': node.get_host_cpu_refs(),
'cpu_configuration': node.get_cpu_configuration(),
'metrics': node.host_metrics_uuid,
'capabilities': node.get_capabilities(),
'supported_bootloaders': 'pygrub'}
'supported_bootloaders': 'pygrub',
'sched_policy': node.get_vcpus_policy()}
return xen_api_success(record)
# class methods
@@ -758,7 +799,8 @@ class XendAPI(object):
'modelname',
'stepping',
'flags',
'utilisation']
'utilisation',
'features']
# attributes
def _host_cpu_get(self, ref, field):
@@ -767,6 +809,8 @@ class XendAPI(object):
def host_cpu_get_host(self, _, ref):
return xen_api_success(XendNode.instance().uuid)
def host_cpu_get_features(self, _, ref):
return self._host_cpu_get(ref, 'features')
def host_cpu_get_number(self, _, ref):
return self._host_cpu_get(ref, 'number')
def host_cpu_get_vendor(self, _, ref):
@@ -989,19 +1033,17 @@ class XendAPI(object):
VM_attr_ro = ['power_state',
'resident_on',
'memory_actual',
'memory_static_max',
'memory_static_min',
'VCPUs_number',
'VCPUs_utilisation',
'consoles',
'VIFs',
'VBDs',
'VTPMs',
'PCI_bus',
'tools_version',
'domid',
'is_control_domain',
'metrics'
]
VM_attr_rw = ['name_label',
@@ -1011,7 +1053,6 @@ class XendAPI(object):
'auto_power_on',
'memory_dynamic_max',
'memory_dynamic_min',
'VCPUs_policy',
'VCPUs_params',
'actions_after_shutdown',
'actions_after_reboot',
@@ -1024,12 +1065,8 @@ class XendAPI(object):
'PV_bootloader_args',
'HVM_boot_policy',
'HVM_boot_params',
'platform_std_VGA',
'platform_serial',
'platform_localtime',
'platform_clock_offset',
'platform_enable_audio',
'platform_keymap',
'platform',
'PCI_bus',
'other_config']
VM_methods = [('clone', 'VM'),
@@ -1042,8 +1079,16 @@ class XendAPI(object):
('hard_reboot', None),
('suspend', None),
('resume', None),
('send_sysrq', None),
('add_to_HVM_boot_params', None),
('remove_from_HVM_boot_params', None),
('add_to_VCPUs_params', None),
('remove_from_VCPUs_params', None),
('add_to_platform', None),
('remove_from_platform', None),
('add_to_other_config', None),
('remove_from_other_config', None)]
('remove_from_other_config', None),
('send_trigger', None)]
VM_funcs = [('create', 'VM'),
('get_by_name_label', 'Set(VM)')]
@@ -1058,7 +1103,6 @@ class XendAPI(object):
'memory_dynamic_max',
'memory_dynamic_min',
'memory_static_min',
'VCPUs_policy',
'VCPUs_params',
'actions_after_shutdown',
'actions_after_reboot',
@@ -1071,13 +1115,7 @@ class XendAPI(object):
'PV_bootloader_args',
'HVM_boot_policy',
'HVM_boot_params',
'platform_std_VGA',
'platform_serial',
'platform_localtime',
'platform_clock_offset',
'platform_enable_audio',
'platform_keymap',
'grub_cmdline',
'platform',
'PCI_bus',
'other_config']
@@ -1089,7 +1127,10 @@ class XendAPI(object):
xd = XendDomain.instance()
dominfo = xd.get_vm_by_uuid(vm_ref)
dominfo.info[name] = value
xd.managed_config_save(dominfo)
return self._VM_save(dominfo)
def _VM_save(self, dominfo):
XendDomain.instance().managed_config_save(dominfo)
return xen_api_success_void()
# attributes (ro)
@@ -1099,11 +1140,7 @@ class XendAPI(object):
def VM_get_resident_on(self, session, vm_ref):
return xen_api_success(XendNode.instance().uuid)
def VM_get_memory_actual(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # unsupported by xc
def VM_get_memory_static_max(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_memory_static_max())
@@ -1116,10 +1153,6 @@ class XendAPI(object):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.getVCpuCount())
def VM_get_VCPUs_utilisation(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vcpus_util())
def VM_get_VIFs(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vifs())
@@ -1136,14 +1169,14 @@ class XendAPI(object):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_consoles())
def VM_get_PCI_bus(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return dom.get_pci_bus()
def VM_get_tools_version(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return dom.get_tools_version()
def VM_get_metrics(self, _, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_metrics())
# attributes (rw)
def VM_get_name_label(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1167,11 +1200,7 @@ class XendAPI(object):
def VM_get_memory_dynamic_min(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_memory_dynamic_min())
def VM_get_VCPUs_policy(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vcpus_policy())
return xen_api_success(dom.get_memory_dynamic_min())
def VM_get_VCPUs_params(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1214,29 +1243,16 @@ class XendAPI(object):
def VM_get_HVM_boot_params(self, session, vm_ref):
return self.VM_get('HVM_boot_params', session, vm_ref)
def VM_get_platform_std_VGA(self, session, vm_ref):
def VM_get_platform(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_platform_std_vga())
return xen_api_success(dom.get_platform())
def VM_get_platform_serial(self, session, vm_ref):
def VM_get_PCI_bus(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_platform_serial())
return dom.get_pci_bus()
def VM_get_platform_localtime(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_platform_localtime())
def VM_get_platform_clock_offset(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_platform_clock_offset())
def VM_get_platform_enable_audio(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_platform_enable_audio())
def VM_get_platform_keymap(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_platform_keymap())
def VM_set_PCI_bus(self, session, vm_ref, val):
return self.VM_set('PCI_bus', session, vm_ref, val)
def VM_get_other_config(self, session, vm_ref):
return self.VM_get('other_config', session, vm_ref)
@@ -1253,7 +1269,7 @@ class XendAPI(object):
def VM_set_name_label(self, session, vm_ref, label):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
dom.setName(label)
return xen_api_success_void()
return self._VM_save(dom)
def VM_set_name_description(self, session, vm_ref, desc):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1275,21 +1291,32 @@ class XendAPI(object):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo()
def VM_set_VCPUs_policy(self, session, vm_ref, policy):
def VM_set_VCPUs_params(self, session, vm_ref, value):
return self.VM_set('vcpus_params', session, vm_ref, value)
def VM_add_to_VCPUs_params(self, session, vm_ref, key, value):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo()
def VM_set_VCPUs_params(self, session, vm_ref, params):
if 'vcpus_params' not in dom.info:
dom.info['vcpus_params'] = {}
dom.info['vcpus_params'][key] = value
return self._VM_save(dom)
def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo()
if 'vcpus_params' in dom.info \
and key in dom.info['vcpus_params']:
del dom.info['vcpus_params'][key]
return self._VM_save(dom)
else:
return xen_api_success_void()
def VM_set_actions_after_shutdown(self, session, vm_ref, action):
if action not in XEN_API_ON_NORMAL_EXIST:
if action not in XEN_API_ON_NORMAL_EXIT:
return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
return self.VM_set('actions_after_shutdown', session, vm_ref, action)
def VM_set_actions_after_reboot(self, session, vm_ref, action):
if action not in XEN_API_ON_NORMAL_EXIST:
if action not in XEN_API_ON_NORMAL_EXIT:
return xen_api_error(['VM_ON_NORMAL_EXIT_INVALID', vm_ref])
return self.VM_set('actions_after_reboot', session, vm_ref, action)
@@ -1319,14 +1346,16 @@ class XendAPI(object):
if 'HVM_boot_params' not in dom.info:
dom.info['HVM_boot_params'] = {}
dom.info['HVM_boot_params'][key] = value
return xen_api_success_void()
return self._VM_save(dom)
def VM_remove_from_HVM_boot_params(self, session, vm_ref, key):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
if 'HVM_boot_params' in dom.info \
and key in dom.info['HVM_boot_params']:
del dom.info['HVM_boot_params'][key]
return xen_api_success_void()
return self._VM_save(dom)
else:
return xen_api_success_void()
def VM_set_PV_bootloader(self, session, vm_ref, value):
return self.VM_set('PV_bootloader', session, vm_ref, value)
@@ -1343,40 +1372,42 @@ class XendAPI(object):
def VM_set_PV_bootloader_args(self, session, vm_ref, value):
return self.VM_set('PV_bootloader_args', session, vm_ref, value)
def VM_set_platform_std_VGA(self, session, vm_ref, value):
return self.VM_set('platform_std_vga', session, vm_ref, value)
def VM_set_platform(self, session, vm_ref, value):
return self.VM_set('platform', session, vm_ref, value)
def VM_set_platform_serial(self, session, vm_ref, value):
return self.VM_set('platform_serial', session, vm_ref, value)
def VM_add_to_platform(self, session, vm_ref, key, value):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
plat = dom.get_platform()
plat[key] = value
return self.VM_set_platform(session, vm_ref, plat)
def VM_remove_from_platform(self, session, vm_ref, key):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
plat = dom.get_platform()
if key in plat:
del plat[key]
return self.VM_set_platform(session, vm_ref, plat)
else:
return xen_api_success_void()
def VM_set_platform_keymap(self, session, vm_ref, value):
return self.VM_set('platform_keymap', session, vm_ref, value)
def VM_set_platform_localtime(self, session, vm_ref, value):
return self.VM_set('platform_localtime', session, vm_ref, value)
def VM_set_platform_clock_offset(self, session, vm_ref, value):
return self.VM_set('platform_clock_offset', session, vm_ref, value)
def VM_set_platform_enable_audio(self, session, vm_ref, value):
return self.VM_set('platform_enable_audio', session, vm_ref, value)
def VM_set_other_config(self, session, vm_ref, value):
return self.VM_set('otherconfig', session, vm_ref, value)
return self.VM_set('other_config', session, vm_ref, value)
def VM_add_to_other_config(self, session, vm_ref, key, value):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
if dom and 'otherconfig' in dom.info:
dom.info['otherconfig'][key] = value
return xen_api_success_void()
if dom and 'other_config' in dom.info:
dom.info['other_config'][key] = value
return self._VM_save(dom)
def VM_remove_from_other_config(self, session, vm_ref, key):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
if dom and 'otherconfig' in dom.info \
and key in dom.info['otherconfig']:
del dom.info['otherconfig'][key]
return xen_api_success_void()
if dom and 'other_config' in dom.info \
and key in dom.info['other_config']:
del dom.info['other_config'][key]
return self._VM_save(dom)
else:
return xen_api_success_void()
# class methods
def VM_get_all(self, session):
refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
@@ -1417,11 +1448,8 @@ class XendAPI(object):
'memory_static_max': xeninfo.get_memory_static_max(),
'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
'memory_actual': xeninfo.get_memory_static_min(),
'VCPUs_policy': xeninfo.get_vcpus_policy(),
'VCPUs_params': xeninfo.get_vcpus_params(),
'VCPUs_number': xeninfo.getVCpuCount(),
'VCPUs_utilisation': xeninfo.get_vcpus_util(),
'actions_after_shutdown': xeninfo.get_on_shutdown(),
'actions_after_reboot': xeninfo.get_on_reboot(),
'actions_after_suspend': xeninfo.get_on_suspend(),
@@ -1437,12 +1465,7 @@ class XendAPI(object):
'PV_bootloader_args': xeninfo.info.get('PV_bootloader_args'),
'HVM_boot_policy': xeninfo.info.get('HVM_boot_policy'),
'HVM_boot_params': xeninfo.info.get('HVM_boot_params'),
'platform_std_VGA': xeninfo.get_platform_std_vga(),
'platform_serial': xeninfo.get_platform_serial(),
'platform_localtime': xeninfo.get_platform_localtime(),
'platform_clock_offset': xeninfo.get_platform_clock_offset(),
'platform_enable_audio': xeninfo.get_platform_enable_audio(),
'platform_keymap': xeninfo.get_platform_keymap(),
'platform': xeninfo.get_platform(),
'PCI_bus': xeninfo.get_pci_bus(),
'tools_version': xeninfo.get_tools_version(),
'other_config': xeninfo.info.get('other_config', {}),
@@ -1486,10 +1509,13 @@ class XendAPI(object):
start_paused = start_paused)
def VM_start(self, session, vm_ref, start_paused):
return XendTask.log_progress(0, 100, do_vm_func,
"domain_start", vm_ref,
start_paused = start_paused)
try:
return XendTask.log_progress(0, 100, do_vm_func,
"domain_start", vm_ref,
start_paused = start_paused)
except HVMRequired, exn:
return xen_api_error(['VM_HVM_REQUIRED', vm_ref])
def VM_suspend(self, session, vm_ref):
return XendTask.log_progress(0, 100, do_vm_func,
"domain_suspend", vm_ref)
@@ -1498,10 +1524,56 @@ class XendAPI(object):
return XendTask.log_progress(0, 100, do_vm_func,
"domain_unpause", vm_ref)
def VM_send_sysrq(self, _, vm_ref, req):
xeninfo = XendDomain.instance().get_vm_by_uuid(vm_ref)
if xeninfo.state != XEN_API_VM_POWER_STATE_RUNNING:
return xen_api_error(
['VM_BAD_POWER_STATE', vm_ref,
XendDomain.POWER_STATE_NAMES[XEN_API_VM_POWER_STATE_RUNNING],
XendDomain.POWER_STATE_NAMES[xeninfo.state]])
xeninfo.send_sysrq(req)
return xen_api_success_void()
def VM_send_trigger(self, _, vm_ref, trigger, vcpu):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
return xen_api_success_void()
# Xen API: Class VM_metrics
# ----------------------------------------------------------------
VM_metrics_attr_ro = ['memory_actual',
'vcpus_number',
'vcpus_utilisation']
VM_metrics_attr_rw = []
VM_metrics_methods = []
def _VM_metrics_get(self, ref):
return XendVMMetrics.get_by_uuid(ref)
def VM_metrics_get_all(self, _):
return xen_api_success(XendVMMetrics.get_all())
def VM_metrics_get_record(self, _, ref):
return xen_api_success(self._VM_metrics_get(ref).get_record())
def VM_metrics_get_memory_actual(self, _, ref):
return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
def VM_metrics_get_vcpus_number(self, _, ref):
return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
def VM_metrics_get_vcpus_utilisation(self, _, ref):
return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
# Xen API: Class VBD
# ----------------------------------------------------------------
VBD_attr_ro = ['metrics']
VBD_attr_ro = ['metrics',
'runtime_properties']
VBD_attr_rw = ['VM',
'VDI',
'device',
@@ -1542,23 +1614,28 @@ class XendAPI(object):
# class methods
def VBD_create(self, session, vbd_struct):
xendom = XendDomain.instance()
xennode = XendNode.instance()
if not xendom.is_valid_vm(vbd_struct['VM']):
return xen_api_error(['HANDLE_INVALID', 'VM', vbd_struct['VM']])
dom = xendom.get_vm_by_uuid(vbd_struct['VM'])
vbd_ref = ''
vdi = xennode.get_vdi_by_uuid(vbd_struct['VDI'])
if not vdi:
return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
# new VBD via VDI/SR
vdi_image = vdi.get_location()
try:
# new VBD via VDI/SR
vdi_ref = vbd_struct.get('VDI')
vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
if not vdi:
return xen_api_error(['HANDLE_INVALID', 'VDI', vdi_ref])
vdi_image = vdi.get_location()
vbd_ref = XendTask.log_progress(0, 100,
dom.create_vbd,
vbd_struct, vdi_image)
except XendError:
return xen_api_todo()
except XendError, e:
log.exception("Error in VBD_create")
return xen_api_error(['INTERNAL_ERROR', str(e)])
vdi.addVBD(vbd_ref)
xendom.managed_config_save(dom)
return xen_api_success(vbd_ref)
@@ -1570,7 +1647,14 @@ class XendAPI(object):
if not vm:
return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
vdi_ref = XendDomain.instance()\
.get_dev_property_by_uuid('vbd', vbd_ref, "VDI")
vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
XendTask.log_progress(0, 100, vm.destroy_vbd, vbd_ref)
vdi.removeVBD(vbd_ref)
return xen_api_success_void()
def _VBD_get(self, vbd_ref, prop):
@@ -1582,6 +1666,24 @@ class XendAPI(object):
def VBD_get_metrics(self, _, vbd_ref):
return xen_api_success(vbd_ref)
def VBD_get_runtime_properties(self, _, vbd_ref):
xendom = XendDomain.instance()
dominfo = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
device = dominfo.get_dev_config_by_uuid('vbd', vbd_ref)
try:
devid = int(device['id'])
device_sxps = dominfo.getDeviceSxprs('vbd')
device_dicts = [dict(device_sxp[1][1:]) for device_sxp in device_sxps]
device_dict = [device_dict
for device_dict in device_dicts
if int(device_dict['virtual-device']) == devid][0]
return xen_api_success(device_dict)
except Exception, exn:
log.exception(exn)
return xen_api_success({})
# attributes (rw)
def VBD_get_VM(self, session, vbd_ref):
return self._VBD_get(vbd_ref, 'VM')
@@ -1642,7 +1744,8 @@ class XendAPI(object):
# Xen API: Class VIF
# ----------------------------------------------------------------
VIF_attr_ro = ['metrics']
VIF_attr_ro = ['metrics',
'runtime_properties']
VIF_attr_rw = ['device',
'network',
'VM',
@@ -1679,18 +1782,17 @@ class XendAPI(object):
# class methods
def VIF_create(self, session, vif_struct):
xendom = XendDomain.instance()
if xendom.is_valid_vm(vif_struct['VM']):
dom = xendom.get_vm_by_uuid(vif_struct['VM'])
try:
vif_ref = dom.create_vif(vif_struct)
xendom.managed_config_save(dom)
return xen_api_success(vif_ref)
except XendError:
return xen_api_error(XEND_ERROR_TODO)
else:
if not xendom.is_valid_vm(vif_struct['VM']):
return xen_api_error(['HANDLE_INVALID', 'VM', vif_struct['VM']])
dom = xendom.get_vm_by_uuid(vif_struct['VM'])
try:
vif_ref = dom.create_vif(vif_struct)
xendom.managed_config_save(dom)
return xen_api_success(vif_ref)
except XendError:
return xen_api_error(XEND_ERROR_TODO)
def VIF_destroy(self, session, vif_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
@@ -1728,6 +1830,27 @@ class XendAPI(object):
vifs = reduce(lambda x, y: x + y, vifs)
return xen_api_success(vifs)
def VIF_get_runtime_properties(self, _, vif_ref):
xendom = XendDomain.instance()
dominfo = xendom.get_vm_with_dev_uuid('vif', vif_ref)
device = dominfo.get_dev_config_by_uuid('vif', vif_ref)
try:
devid = int(device['id'])
device_sxps = dominfo.getDeviceSxprs('vif')
device_dicts = [dict(device_sxp[1][1:])
for device_sxp in device_sxps]
device_dict = [device_dict
for device_dict in device_dicts
if int(device_dict['handle']) == devid][0]
return xen_api_success(device_dict)
except Exception, exn:
log.exception(exn)
return xen_api_success({})
# Xen API: Class VIF_metrics
# ----------------------------------------------------------------
@@ -1754,16 +1877,16 @@ class XendAPI(object):
# Xen API: Class VDI
# ----------------------------------------------------------------
VDI_attr_ro = ['VBDs',
VDI_attr_ro = ['SR',
'VBDs',
'physical_utilisation',
'sector_size',
'type']
VDI_attr_rw = ['name_label',
'name_description',
'SR',
'virtual_size',
'sharable',
'read_only']
'read_only',
'other_config']
VDI_attr_inst = VDI_attr_ro + VDI_attr_rw
VDI_methods = [('snapshot', 'VDI')]
@@ -1774,14 +1897,12 @@ class XendAPI(object):
return XendNode.instance().get_vdi_by_uuid(ref)
def VDI_get_VBDs(self, session, vdi_ref):
return xen_api_todo()
vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
return xen_api_success(vdi.getVBDs())
def VDI_get_physical_utilisation(self, session, vdi_ref):
return xen_api_success(self._get_VDI(vdi_ref).
get_physical_utilisation())
def VDI_get_sector_size(self, session, vdi_ref):
return xen_api_success(self._get_VDI(vdi_ref).sector_size)
get_physical_utilisation())
def VDI_get_type(self, session, vdi_ref):
return xen_api_success(self._get_VDI(vdi_ref).type)
@@ -1812,9 +1933,6 @@ class XendAPI(object):
self._get_VDI(vdi_ref).name_description = value
return xen_api_success_void()
def VDI_set_SR(self, session, vdi_ref, value):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
def VDI_set_virtual_size(self, session, vdi_ref, value):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
@@ -1826,6 +1944,14 @@ class XendAPI(object):
self._get_VDI(vdi_ref).read_only = bool(value)
return xen_api_success_void()
def VDI_get_other_config(self, session, vdi_ref):
return xen_api_success(
self._get_VDI(vdi_ref).other_config)
def VDI_set_other_config(self, session, vdi_ref, other_config):
self._get_VDI(vdi_ref).other_config = other_config
return xen_api_success_void()
# Object Methods
def VDI_snapshot(self, session, vdi_ref):
return xen_api_todo()
@@ -1842,13 +1968,13 @@ class XendAPI(object):
'name_label': image.name_label,
'name_description': image.name_description,
'SR': image.sr_uuid,
'VBDs': [], # TODO
'VBDs': image.getVBDs(),
'virtual_size': image.virtual_size,
'physical_utilisation': image.physical_utilisation,
'sector_size': image.sector_size,
'type': image.type,
'sharable': image.sharable,
'read_only': image.read_only,
'other_config': image.other_config
})
# Class Functions
@@ -1929,7 +2055,7 @@ class XendAPI(object):
XendDomain.POWER_STATE_NAMES[dom.state]])
from xen.xend.server import tpmif
tpmif.destroy_vtpmstate(dom.getName())
return xen_api_success(True)
return xen_api_success_void()
else:
return xen_api_error(['HANDLE_INVALID', 'VM', vtpm_struct['VM']])
+21 -5
View File
@@ -9,6 +9,7 @@ import os
import re
import string
import threading
import fcntl
from struct import pack, unpack, calcsize
from xen.util.xpopen import xPopen3
@@ -73,10 +74,15 @@ def save(fd, dominfo, network, live, dst, checkpoint=False):
write_exact(fd, config, "could not write guest state file: config")
image_cfg = dominfo.info.get('image', {})
hvm = image_cfg.has_key('hvm')
hvm = dominfo.info.is_hvm()
stdvga = 0
if hvm:
log.info("save hvm domain")
if dominfo.info['platform'].has_key('stdvga'):
if dominfo.info['platform']['stdvga'] == 1:
stdvga = 1
# xc_save takes three customization parameters: maxit, max_f, and
# flags the last controls whether or not save is 'live', while the
# first two further customize behaviour when 'live' save is
@@ -84,7 +90,8 @@ def save(fd, dominfo, network, live, dst, checkpoint=False):
# libxenguest; see the comments and/or code in xc_linux_save() for
# more information.
cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ]
str(dominfo.getDomid()), "0", "0",
str(int(live) | (int(hvm) << 2) | (int(stdvga) << 3)) ]
log.debug("[xc_save]: %s", string.join(cmd))
def saveInputHandler(line, tochild):
@@ -183,11 +190,11 @@ def restore(xd, fd, dominfo = None, paused = False):
# if hvm, pass mem size to calculate the store_mfn
image_cfg = dominfo.info.get('image', {})
is_hvm = image_cfg.has_key('hvm')
is_hvm = dominfo.info.is_hvm()
if is_hvm:
hvm = dominfo.info['memory_static_min']
apic = dominfo.info['image']['hvm'].get('apic', 0)
pae = dominfo.info['image']['hvm'].get('pae', 0)
apic = int(dominfo.info['platform'].get('apic', 0))
pae = int(dominfo.info['platform'].get('pae', 0))
log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
dominfo.domid, hvm, apic, pae)
else:
@@ -224,6 +231,15 @@ def restore(xd, fd, dominfo = None, paused = False):
forkHelper(cmd, fd, handler.handler, True)
# We don't want to pass this fd to any other children -- we
# might need to recover ths disk space that backs it.
try:
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(fd, fcntl.F_SETFD, flags)
except:
pass
if handler.store_mfn is None:
raise XendError('Could not read store MFN')
+149 -227
View File
@@ -12,7 +12,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006 XenSource Ltd
# Copyright (C) 2006-2007 XenSource Ltd
#============================================================================
import logging
@@ -28,7 +28,7 @@ from xen.xend.PrettyPrint import prettyprintstring
from xen.xend.XendConstants import DOM_STATE_HALTED
log = logging.getLogger("xend.XendConfig")
log.setLevel(logging.DEBUG)
log.setLevel(logging.WARN)
"""
@@ -105,28 +105,23 @@ XENAPI_CFG_TO_LEGACY_CFG = {
'uuid': 'uuid',
'vcpus_number': 'vcpus',
'cpus': 'cpus',
'memory_static_min': 'memory',
'memory_static_max': 'maxmem',
'name_label': 'name',
'actions_after_shutdown': 'on_poweroff',
'actions_after_reboot': 'on_reboot',
'actions_after_crash': 'on_crash',
'platform_localtime': 'localtime',
'PV_bootloader': 'bootloader',
'PV_bootloader_args': 'bootloader_args',
}
LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG)
# Mapping from XendConfig configuration keys to the old
# legacy configuration keys that are found in the 'image'
# SXP object.
XENAPI_HVM_CFG = {
'platform_std_vga': 'stdvga',
'platform_serial' : 'serial',
'platform_localtime': 'localtime',
'platform_keymap' : 'keymap'
}
# Platform configuration keys.
XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'boot', 'device_model', 'display',
'fda', 'fdb', 'keymap', 'isa', 'localtime',
'nographic', 'pae', 'serial', 'sdl',
'soundhw','stdvga', 'usb', 'usbdevice', 'vnc',
'vncconsole', 'vncdisplay', 'vnclisten',
'vncpasswd', 'vncunused', 'xauthority']
# List of XendConfig configuration keys that have no direct equivalent
# in the old world.
@@ -139,11 +134,10 @@ XENAPI_CFG_TYPES = {
'user_version': str,
'is_a_template': bool0,
'resident_on': str,
'memory_static_min': int,
'memory_static_min': int, # note these are stored in bytes, not KB!
'memory_static_max': int,
'memory_dynamic_min': int,
'memory_dynamic_max': int,
'memory_actual': int,
'cpus': list,
'vcpus_policy': str,
'vcpus_params': dict,
@@ -151,7 +145,6 @@ XENAPI_CFG_TYPES = {
'actions_after_shutdown': str,
'actions_after_reboot': str,
'actions_after_crash': str,
'tpm_backend': int,
'PV_bootloader': str,
'PV_kernel': str,
'PV_ramdisk': str,
@@ -159,15 +152,10 @@ XENAPI_CFG_TYPES = {
'PV_bootloader_args': str,
'HVM_boot_policy': str,
'HVM_boot_params': dict,
'platform_std_vga': bool0,
'platform_serial': str,
'platform_localtime': bool0,
'platform_clock_offset': bool0,
'platform_enable_audio': bool0,
'platform_keymap': str,
'pci_bus': str,
'PCI_bus': str,
'platform': dict,
'tools_version': dict,
'otherconfig': dict,
'other_config': dict,
}
# List of legacy configuration keys that have no equivalent in the
@@ -237,44 +225,7 @@ LEGACY_XENSTORE_VM_PARAMS = [
'on_xend_stop',
]
LEGACY_IMAGE_CFG = [
('root', str),
('ip', str),
('nographic', int),
('vnc', int),
('sdl', int),
('vncdisplay', int),
('vncunused', int),
('vncpasswd', str),
('vnclisten', str),
]
LEGACY_IMAGE_HVM_CFG = [
('device_model', str),
('display', str),
('xauthority', str),
('vncconsole', int),
('pae', int),
('apic', int),
]
LEGACY_IMAGE_HVM_DEVICES_CFG = [
('acpi', int),
('boot', str),
('fda', str),
('fdb', str),
('isa', int),
('keymap', str),
('localtime', int),
('serial', str),
('stdvga', int),
('soundhw', str),
('usb', int),
('usbdevice', str),
('vcpus', int),
]
LEGACY_DM = '/usr/lib/xen/bin/qemu-dm'
DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm'
##
## Config Choices
@@ -316,7 +267,6 @@ class XendConfig(dict):
self._sxp_to_xapi_unsupported(sxp_obj)
elif xapi:
self.update_with_xenapi_config(xapi)
self._add_xapi_unsupported(xapi)
elif dominfo:
# output from xc.domain_getinfo
self._dominfo_to_xapi(dominfo)
@@ -361,9 +311,7 @@ class XendConfig(dict):
'shadow_memory': 0,
'memory_static_max': 0,
'memory_dynamic_max': 0,
'memory_actual': 0,
'devices': {},
'image': {},
'security': None,
'on_xend_start': 'ignore',
'on_xend_stop': 'ignore',
@@ -377,24 +325,44 @@ class XendConfig(dict):
'vbd_refs': [],
'vtpm_refs': [],
'other_config': {},
'platform': {}
}
return defaults
#
# Here we assume these values exist in the dict.
# If they don't we have a bigger problem, lets not
# try and 'fix it up' but acutually fix the cause ;-)
#
def _memory_sanity_check(self):
if self['memory_static_min'] == 0:
self['memory_static_min'] = self['memory_dynamic_min']
# If the static max is not set, let's set it to dynamic max.
# If the static max is smaller than static min, then fix it!
self['memory_static_max'] = max(self['memory_static_max'],
self['memory_dynamic_max'],
self['memory_static_min'])
for mem_type in ('memory_static_min', 'memory_static_max'):
if self[mem_type] <= 0:
raise XendConfigError('Memory value too low for %s: %d' %
(mem_type, self[mem_type]))
log.debug("_memory_sanity_check memory_static_min: %s, "
"memory_static_max: %i, "
"memory_dynamic_min: %i, "
"memory_dynamic_max: %i",
self["memory_static_min"],
self["memory_static_max"],
self["memory_dynamic_min"],
self["memory_dynamic_max"])
if not self["memory_static_min"] <= self["memory_static_max"]:
raise XendConfigError("memory_static_min must be less " \
"than or equal to memory_static_max")
if not self["memory_dynamic_min"] <= self["memory_dynamic_max"]:
raise XendConfigError("memory_dynamic_min must be less " \
"than or equal to memory_dynamic_max")
if not self["memory_static_min"] <= self["memory_dynamic_min"]:
raise XendConfigError("memory_static_min must be less " \
"than or equal to memory_dynamic_min")
if not self["memory_dynamic_max"] <= self["memory_static_max"]:
raise XendConfigError("memory_dynamic_max must be less " \
"than or equal to memory_static_max")
if not self["memory_dynamic_max"] > 0:
raise XendConfigError("memory_dynamic_max must be greater " \
"than zero")
if not self["memory_static_max"] > 0:
raise XendConfigError("memory_static_max must be greater " \
"than zero")
def _actions_sanity_check(self):
for event in ['shutdown', 'reboot', 'crash']:
@@ -417,19 +385,34 @@ class XendConfig(dict):
if 'name_label' not in self:
self['name_label'] = 'Domain-' + self['uuid']
def _platform_sanity_check(self):
if self.is_hvm():
if 'device_model' not in self['platform']:
self['platform']['device_model'] = DEFAULT_DM
# Compatibility hack, can go away soon.
if 'soundhw' not in self['platform'] and \
self['platform'].get('enable_audio'):
self['platform']['soundhw'] = 'sb16'
def validate(self):
self._uuid_sanity_check()
self._name_sanity_check()
self._memory_sanity_check()
self._actions_sanity_check()
self._vcpus_sanity_check()
self._platform_sanity_check()
def _dominfo_to_xapi(self, dominfo):
self['domid'] = dominfo['domid']
self['online_vcpus'] = dominfo['online_vcpus']
self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
self['memory_static_min'] = 0
self['memory_static_max'] = dominfo['maxmem_kb'] * 1024
self['cpu_time'] = dominfo['cpu_time']/1e9
# TODO: i don't know what the security stuff expects here
if dominfo.get('ssidref'):
@@ -483,6 +466,13 @@ class XendConfig(dict):
log.warn('Ignoring unrecognised value for deprecated option:'
'restart = \'%s\'', restart)
# Handle memory, passed in as MiB
if sxp.child_value(sxp_cfg, "memory") != None:
cfg["memory"] = int(sxp.child_value(sxp_cfg, "memory"))
if sxp.child_value(sxp_cfg, "maxmem") != None:
cfg["maxmem"] = int(sxp.child_value(sxp_cfg, "maxmem"))
# Only extract options we know about.
extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
@@ -498,6 +488,18 @@ class XendConfig(dict):
log.warn("Unable to parse key %s: %s: %s" %
(key, str(val), e))
if 'platform' not in cfg:
cfg['platform'] = {}
localtime = sxp.child_value(sxp_cfg, 'localtime')
if localtime is not None:
cfg['platform']['localtime'] = localtime
# Compatibility hack -- can go soon.
for key in XENAPI_PLATFORM_CFG:
val = sxp.child_value(sxp_cfg, "platform_" + key, None)
if val is not None:
self['platform'][key] = val
# Compatibility hack -- can go soon.
boot_order = sxp.child_value(sxp_cfg, 'HVM_boot')
if boot_order:
@@ -640,6 +642,21 @@ class XendConfig(dict):
except KeyError:
pass
# Lets try and handle memory correctly
MiB = 1024 * 1024
if "memory" in cfg:
self["memory_static_min"] = 0
self["memory_static_max"] = int(cfg["memory"]) * MiB
self["memory_dynamic_min"] = int(cfg["memory"]) * MiB
self["memory_dynamic_max"] = int(cfg["memory"]) * MiB
if "maxmem" in cfg:
self["memory_static_max"] = int(cfg["maxmem"]) * MiB
self._memory_sanity_check()
def update_with(n, o):
if not self.get(n):
self[n] = cfg.get(o, '')
@@ -652,17 +669,9 @@ class XendConfig(dict):
self.update_with_image_sxp(image_sxp)
# Convert Legacy HVM parameters to Xen API configuration
self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
self['platform_serial'] = str(cfg.get('serial', ''))
self['platform_localtime'] = bool0(cfg.get('localtime', 0))
self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
# make sure a sane maximum is set
if self['memory_static_max'] <= 0:
self['memory_static_max'] = self['memory_static_min']
self['memory_dynamic_max'] = self['memory_static_max']
self['memory_dynamic_min'] = self['memory_static_min']
for key in XENAPI_PLATFORM_CFG:
if key in cfg:
self['platform'][key] = cfg[key]
# set device references in the configuration
self['devices'] = cfg.get('devices', {})
@@ -672,7 +681,7 @@ class XendConfig(dict):
self['vtpm_refs'] = cfg.get('vtpm_refs', [])
# coalesce hvm vnc frame buffer with vfb config
if self['image']['type'] == 'hvm' and self['image'].get('vnc', 0):
if self.is_hvm() and self['platform'].get('vnc', 0):
# add vfb device if it isn't there already
has_rfb = False
for console_uuid in self['console_refs']:
@@ -685,11 +694,11 @@ class XendConfig(dict):
if not has_rfb:
dev_config = ['vfb']
# copy VNC related params from image config to vfb dev conf
# copy VNC related params from platform config to vfb dev conf
for key in ['vncpasswd', 'vncunused', 'vncdisplay',
'vnclisten']:
if key in self['image']:
dev_config.append([key, self['image'][key]])
if key in self['platform']:
dev_config.append([key, self['platform'][key]])
self.device_add('vfb', cfg_sxp = dev_config)
@@ -706,39 +715,19 @@ class XendConfig(dict):
# the image (as well as HVM images)
image_sxp = sxp.child_value(sxp_cfg, 'image', [])
if image_sxp:
image = {}
image['type'] = sxp.name(image_sxp)
for arg, conv in LEGACY_IMAGE_CFG:
val = sxp.child_value(image_sxp, arg, None)
if val != None:
image[arg] = conv(val)
image_hvm = {}
for arg, conv in LEGACY_IMAGE_HVM_CFG:
val = sxp.child_value(image_sxp, arg, None)
if val != None:
image_hvm[arg] = conv(val)
image_hvm_devices = {}
for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
val = sxp.child_value(image_sxp, arg, None)
if val != None:
image_hvm_devices[arg] = conv(val)
if image_hvm or image_hvm_devices:
image['hvm'] = image_hvm
image['hvm']['devices'] = image_hvm_devices
image_type = sxp.name(image_sxp)
if image_type != 'hvm' and image_type != 'linux':
self['platform']['image_type'] = image_type
for key in XENAPI_PLATFORM_CFG:
val = sxp.child_value(image_sxp, key, None)
if val is not None:
self['platform'][key] = val
notes = sxp.children(image_sxp, 'notes')
if notes:
image['notes'] = self.notes_from_sxp(notes[0])
self['notes'] = self.notes_from_sxp(notes[0])
self['image'] = image
for apikey, imgkey in XENAPI_HVM_CFG.items():
val = sxp.child_value(image_sxp, imgkey, None)
if val != None:
self[apikey] = val
self._hvm_boot_params_from_sxp(image_sxp)
# extract backend value
@@ -774,33 +763,6 @@ class XendConfig(dict):
_set_cfg_if_exists('up_time')
_set_cfg_if_exists('status') # TODO, deprecated
def _add_xapi_unsupported(self, xapi_dict):
"""Updates the configuration object with entries that are not
officially supported by the Xen API but is required for
the rest of Xend to function.
"""
# populate image
if 'image' in xapi_dict:
self['image'].update(xapi_dict['image'])
else:
hvm = self['HVM_boot_policy'] != ''
self['image']['type'] = hvm and 'hvm' or 'linux'
if hvm:
self['image']['hvm'] = {'devices': {}}
for xapi, cfgapi in XENAPI_HVM_CFG.items():
if xapi in self:
self['image']['hvm']['devices'][cfgapi] = self[xapi]
# currently unsupported options
self['image']['hvm']['device_model'] = LEGACY_DM
self['image']['vnc'] = 0
self['image']['hvm']['pae'] = 1
if self['platform_enable_audio']:
self['image']['hvm']['devices']['soundhw'] = 'sb16'
def _get_old_state_string(self):
"""Returns the old xm state string.
@rtype: string
@@ -884,18 +846,29 @@ class XendConfig(dict):
else:
sxpr.append([legacy, self[xenapi]])
MiB = 1024*1024
sxpr.append(["maxmem", int(self["memory_static_max"])/MiB])
sxpr.append(["memory", int(self["memory_dynamic_max"])/MiB])
if not legacy_only:
sxpr.append(['memory_dynamic_min',
int(self.get('memory_dynamic_min'))])
sxpr.append(['memory_dynamic_max',
int(self.get('memory_dynamic_max'))])
sxpr.append(['memory_static_max',
int(self.get('memory_static_max'))])
sxpr.append(['memory_static_min',
int(self.get('memory_static_min'))])
for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
if legacy in ('domid', 'uuid'): # skip these
continue
if self.has_key(legacy) and self[legacy] not in (None, []):
sxpr.append([legacy, self[legacy]])
if 'image' in self and self['image']:
sxpr.append(['image', self.image_sxpr()])
sxpr.append(['image', self.image_sxpr()])
sxpr.append(['status', domain.state])
sxpr.append(['memory_dynamic_min', self.get('memory_dynamic_min')])
sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max')])
if domain.getDomid() is not None:
sxpr.append(['state', self._get_old_state_string()])
@@ -1339,7 +1312,7 @@ class XendConfig(dict):
def image_sxpr(self):
"""Returns a backwards compatible image SXP expression that is
used in xenstore's /vm/<uuid>/image value and xm list."""
image = [self['image'].get('type', 'linux')]
image = [self.image_type()]
if self.has_key('PV_kernel'):
image.append(['kernel', self['PV_kernel']])
if self.has_key('PV_ramdisk') and self['PV_ramdisk']:
@@ -1347,28 +1320,12 @@ class XendConfig(dict):
if self.has_key('PV_args') and self['PV_args']:
image.append(['args', self['PV_args']])
for arg, conv in LEGACY_IMAGE_CFG:
if self['image'].has_key(arg):
image.append([arg, self['image'][arg]])
for key in XENAPI_PLATFORM_CFG:
if key in self['platform']:
image.append([key, self['platform'][key]])
if 'hvm' in self['image']:
for arg, conv in LEGACY_IMAGE_HVM_CFG:
if self['image']['hvm'].get(arg):
image.append([arg, conv(self['image']['hvm'][arg])])
if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
val = self['image']['hvm']['devices'].get(arg)
if val != None:
try:
if conv: val = conv(val)
except (ValueError, TypeError):
if type(val) == bool: val = int(val)
image.append([arg, val])
if 'notes' in self['image']:
image.append(self.notes_sxp(self['image']['notes']))
if 'notes' in self:
image.append(self.notes_sxp(self['notes']))
return image
@@ -1399,57 +1356,24 @@ class XendConfig(dict):
self['PV_ramdisk'] = sxp.child_value(image_sxp, 'ramdisk','')
self['PV_args'] = kernel_args
# Store image SXP in python dictionary format
image = {}
image['type'] = sxp.name(image_sxp)
for arg, conv in LEGACY_IMAGE_CFG:
val = sxp.child_value(image_sxp, arg, None)
if val != None:
image[arg] = conv(val)
image_hvm = {}
for arg, conv in LEGACY_IMAGE_HVM_CFG:
val = sxp.child_value(image_sxp, arg, None)
if val != None:
image_hvm[arg] = conv(val)
image_hvm_devices = {}
for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
val = sxp.child_value(image_sxp, arg, None)
if val != None:
try:
image_hvm_devices[arg] = conv(val)
except (ValueError, TypeError):
image_hvm_devices[arg] = val
if image_hvm or image_hvm_devices:
image['hvm'] = image_hvm
image['hvm']['devices'] = image_hvm_devices
for key in XENAPI_PLATFORM_CFG:
val = sxp.child_value(image_sxp, key, None)
if val is not None:
self['platform'][key] = val
notes = sxp.children(image_sxp, 'notes')
if notes:
image['notes'] = self.notes_from_sxp(notes[0])
self['notes'] = self.notes_from_sxp(notes[0])
self['image'] = image
for apikey, imgkey in XENAPI_HVM_CFG.items():
val = sxp.child_value(image_sxp, imgkey, None)
if val != None:
type_conv = XENAPI_CFG_TYPES[apikey]
if callable(type_conv):
self[apikey] = type_conv(val)
else:
self[apikey] = val
self._hvm_boot_params_from_sxp(image_sxp)
def set_notes(self, notes):
'Add parsed elfnotes to image'
self['image']['notes'] = notes
self['notes'] = notes
def get_notes(self):
try:
return self['image']['notes'] or {}
return self['notes'] or {}
except KeyError:
return {}
@@ -1471,11 +1395,9 @@ class XendConfig(dict):
self['HVM_boot_policy'] = 'BIOS order'
self['HVM_boot_params'] = { 'order' : boot }
def is_hvm(self):
return self['HVM_boot_policy'] != ''
#
# debugging
#
if __name__ == "__main__":
pass
def image_type(self):
stored_type = self['platform'].get('image_type')
return stored_type or (self.is_hvm() and 'hvm' or 'linux')
+2 -2
View File
@@ -495,7 +495,7 @@ class XendDomain:
self._refresh(refresh_shutdown = False)
dom = self.domain_lookup_nr(domid)
if not dom:
raise XendInvalidDomain("No domain named '%s'." % str(domid))
raise XendInvalidDomain(str(domid))
return dom
finally:
self.domains_lock.release()
@@ -674,7 +674,7 @@ class XendDomain:
else:
return domid
raise XendInvalidDomain("Domain does not exist")
raise XendInvalidDomain(vm_uuid)
finally:
self.domains_lock.release()
+113 -86
View File
@@ -13,7 +13,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005, 2006 XenSource Ltd
# Copyright (C) 2005-2007 XenSource Ltd
#============================================================================
"""Representation of a single domain.
@@ -34,7 +34,7 @@ from types import StringTypes
import xen.lowlevel.xc
from xen.util import asserts
from xen.util.blkif import blkdev_uname_to_file
from xen.util.blkif import blkdev_uname_to_file, blkdev_uname_to_taptype
from xen.util import security
from xen.xend import balloon, sxp, uuid, image, arch, osdep
@@ -51,6 +51,8 @@ from xen.xend.xenstore.xswatch import xswatch
from xen.xend.XendConstants import *
from xen.xend.XendAPIConstants import *
from xen.xend.XendVMMetrics import XendVMMetrics
MIGRATE_TIMEOUT = 30.0
BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
@@ -176,14 +178,8 @@ def recreate(info, priv):
vm._storeVmDetails()
vm._storeDomDetails()
if vm.info['image']: # Only dom0 should be without an image entry when
# recreating, but we cope with missing ones
# elsewhere just in case.
vm.image = image.create(vm,
vm.info,
vm.info['image'],
vm.info['devices'])
vm.image.recreate()
vm.image = image.create(vm, vm.info)
vm.image.recreate()
vm._registerWatches()
vm.refreshShutdown(xeninfo)
@@ -375,6 +371,8 @@ class XendDomainInfo:
self._augmentInfo(priv)
self._checkName(self.info['name_label'])
self.metrics = XendVMMetrics(uuid.createString(), self)
#
@@ -448,9 +446,7 @@ class XendDomainInfo:
self.storeDom("control/shutdown", reason)
## shutdown hypercall for hvm domain desides xenstore write
image_cfg = self.info.get('image', {})
hvm = image_cfg.has_key('hvm')
if hvm:
if self.info.is_hvm():
for code in DOMAIN_SHUTDOWN_REASONS.keys():
if DOMAIN_SHUTDOWN_REASONS[code] == reason:
break
@@ -580,12 +576,14 @@ class XendDomainInfo:
if target <= 0:
raise XendError('Invalid memory size')
self.info['memory_static_min'] = target
MiB = 1024 * 1024
self.info['memory_dynamic_min'] = target * MiB
self.info['memory_dynamic_max'] = target * MiB
if self.domid >= 0:
self.storeVm("memory", target)
self.storeDom("memory/target", target << 10)
else:
self.info['memory_dynamic_min'] = target
xen.xend.XendDomain.instance().managed_config_save(self)
def setMemoryMaximum(self, limit):
@@ -635,6 +633,10 @@ class XendDomainInfo:
except RuntimeError, exn:
raise XendError(str(exn))
def getDomInfo(self):
return dom_get(self.domid)
#
# internal functions ... TODO: re-categorised
#
@@ -664,6 +666,10 @@ class XendDomainInfo:
if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
self.info[xapiarg] = val
elif arg == "memory":
self.info["static_memory_min"] = val
elif arg == "maxmem":
self.info["static_memory_max"] = val
else:
self.info[arg] = val
@@ -780,7 +786,7 @@ class XendDomainInfo:
'vm': self.vmpath,
'name': self.info['name_label'],
'console/limit': str(xoptions.get_console_limit() * 1024),
'memory/target': str(self.info['memory_static_min'] * 1024),
'memory/target': str(self.info['memory_dynamic_max'] / 1024),
}
def f(n, v):
@@ -864,7 +870,15 @@ class XendDomainInfo:
xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
if val != None and val != self.info[xapiarg]:
self.info[xapiarg] = val
changed= True
changed = True
elif arg == "memory":
if val != None and val != self.info["static_memory_min"]:
self.info["static_memory_min"] = val
changed = True
elif arg == "maxmem":
if val != None and val != self.info["static_memory_max"]:
self.info["static_memory_max"] = val
changed = True
# Check whether image definition has been updated
image_sxp = self._readVm('image')
@@ -969,11 +983,12 @@ class XendDomainInfo:
def getMemoryTarget(self):
"""Get this domain's target memory size, in KB."""
return self.info['memory_static_min'] * 1024
return self.info['memory_dynamic_max'] / 1024
def getMemoryMaximum(self):
"""Get this domain's maximum memory size, in KB."""
return self.info['memory_static_max'] * 1024
# remember, info now stores memory in bytes
return self.info['memory_static_max'] / 1024
def getResume(self):
return str(self._resume)
@@ -1389,9 +1404,7 @@ class XendDomainInfo:
self.shutdownStartTime = None
image_cfg = self.info.get('image', {})
hvm = image_cfg.has_key('hvm')
hvm = self.info.is_hvm()
if hvm:
info = xc.xeninfo()
if 'hvm' not in info['xen_caps']:
@@ -1438,14 +1451,8 @@ class XendDomainInfo:
self._configureBootloader()
if not self._infoIsSet('image'):
raise VmError('Missing image in configuration')
try:
self.image = image.create(self,
self.info,
self.info['image'],
self.info['devices'])
self.image = image.create(self, self.info)
localtime = self.info.get('platform_localtime', False)
if localtime:
@@ -1463,13 +1470,14 @@ class XendDomainInfo:
# Use architecture- and image-specific calculations to determine
# the various headrooms necessary, given the raw configured
# values. maxmem, memory, and shadow are all in KiB.
# but memory_static_max etc are all stored in bytes now.
memory = self.image.getRequiredAvailableMemory(
self.info['memory_static_min'] * 1024)
self.info['memory_dynamic_max'] / 1024)
maxmem = self.image.getRequiredAvailableMemory(
self.info['memory_static_max'] * 1024)
self.info['memory_static_max'] / 1024)
shadow = self.image.getRequiredShadowMemory(
self.info['shadow_memory'] * 1024,
self.info['memory_static_max'] * 1024)
self.info['shadow_memory'] / 1024,
self.info['memory_static_max'] / 1024)
log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],)
# Round shadow up to a multiple of a MiB, as shadow_mem_control
@@ -1505,9 +1513,15 @@ class XendDomainInfo:
self.info['start_time'] = time.time()
self._stateSet(DOM_STATE_RUNNING)
except (RuntimeError, VmError), exn:
except VmError, exn:
log.exception("XendDomainInfo.initDomain: exception occurred")
self.image.cleanupBootloading()
if self.image:
self.image.cleanupBootloading()
raise exn
except RuntimeError, exn:
log.exception("XendDomainInfo.initDomain: exception occurred")
if self.image:
self.image.cleanupBootloading()
raise VmError(str(exn))
@@ -1574,13 +1588,8 @@ class XendDomainInfo:
self.console_mfn = console_mfn
self._introduceDomain()
image_cfg = self.info.get('image', {})
hvm = image_cfg.has_key('hvm')
if hvm:
self.image = image.create(self,
self.info,
self.info['image'],
self.info['devices'])
if self.info.is_hvm():
self.image = image.create(self, self.info)
if self.image:
self.image.createDeviceModel(True)
self.image.register_shutdown_watch()
@@ -1657,7 +1666,18 @@ class XendDomainInfo:
log.exception("XendDomainInfo.destroy: xc.domain_destroy failed.")
from xen.xend import XendDomain
XendDomain.instance().remove_domain(self)
if "transient" in self.info["other_config"]\
and bool(self.info["other_config"]["transient"]):
xendDomainInstance = XendDomain.instance()
xendDomainInstance.domains_lock.acquire()
xendDomainInstance._refresh(refresh_shutdown = False)
xendDomainInstance.domains_lock.release()
xendDomainInstance.domain_delete(self.info["name_label"])
else:
XendDomain.instance().remove_domain(self)
self.cleanupDomain()
self._cleanup_phantom_devs(paths)
@@ -1742,11 +1762,7 @@ class XendDomainInfo:
if boot:
# HVM booting.
self.info['image']['type'] = 'hvm'
if not 'devices' in self.info['image']:
self.info['image']['devices'] = {}
self.info['image']['devices']['boot'] = \
self.info['HVM_boot_params'].get('order', 'dc')
pass
elif not blexec and kernel:
# Boot from dom0. Nothing left to do -- the kernel and ramdisk
# will be picked up by image.py.
@@ -1770,7 +1786,8 @@ class XendDomainInfo:
disk = devinfo[1]['uname']
fn = blkdev_uname_to_file(disk)
mounted = devtype == 'tap' and not os.stat(fn).st_rdev
taptype = blkdev_uname_to_taptype(disk)
mounted = devtype == 'tap' and taptype != 'aio' and taptype != 'sync' and not os.stat(fn).st_rdev
if mounted:
# This is a file, not a device. pygrub can cope with a
# file if it's raw, but if it's QCOW or other such formats
@@ -1786,7 +1803,7 @@ class XendDomainInfo:
from xen.xend import XendDomain
dom0 = XendDomain.instance().privilegedDomain()
dom0._waitForDeviceUUID(dom0.create_vbd(vbd, fn))
dom0._waitForDeviceUUID(dom0.create_vbd(vbd, disk))
fn = BOOTLOADER_LOOPBACK_DEVICE
try:
@@ -1844,7 +1861,7 @@ class XendDomainInfo:
# 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
# the minimum that Xen would allocate if no value were given.
overhead_kb = self.info['vcpus_number'] * 1024 + \
self.info['memory_static_max'] * 4
(self.info['memory_static_max'] / 1024 / 1024) * 4
overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
# The domain might already have some shadow memory
overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
@@ -1910,10 +1927,14 @@ class XendDomainInfo:
if self._infoIsSet(info_key):
to_store[key] = str(self.info[info_key])
if self.info.get('image'):
image_sxpr = self.info.image_sxpr()
if image_sxpr:
to_store['image'] = sxp.to_string(image_sxpr)
if self._infoIsSet("static_memory_min"):
to_store["memory"] = str(self.info["static_memory_min"])
if self._infoIsSet("static_memory_max"):
to_store["maxmem"] = str(self.info["static_memory_max"])
image_sxpr = self.info.image_sxpr()
if image_sxpr:
to_store['image'] = sxp.to_string(image_sxpr)
if self._infoIsSet('security'):
secinfo = self.info['security']
@@ -2000,7 +2021,11 @@ class XendDomainInfo:
info = dom_get(self.domid)
if not info:
return
if info["maxmem_kb"] < 0:
info["maxmem_kb"] = XendNode.instance() \
.physinfo_dict()['total_memory'] * 1024
#manually update ssidref / security fields
if security.on() and info.has_key('ssidref'):
if (info['ssidref'] != 0) and self.info.has_key('security'):
@@ -2057,15 +2082,6 @@ class XendDomainInfo:
return self.info.get('memory_dynamic_max', 0)
def get_memory_dynamic_min(self):
return self.info.get('memory_dynamic_min', 0)
def get_vcpus_policy(self):
sched_id = xc.sched_id_get()
if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
return 'sedf'
elif sched_id == xen.lowlevel.xc.XEN_SCHEDULER_CREDIT:
return 'credit'
else:
return 'unknown'
def get_vcpus_params(self):
if self.getDomid() is None:
return self.info['vcpus_params']
@@ -2074,22 +2090,14 @@ class XendDomainInfo:
return retval
def get_power_state(self):
return XEN_API_VM_POWER_STATE[self.state]
def get_platform_std_vga(self):
return self.info.get('platform_std_vga', False)
def get_platform_serial(self):
return self.info.get('platform_serial', '')
def get_platform_localtime(self):
return self.info.get('platform_localtime', False)
def get_platform_clock_offset(self):
return self.info.get('platform_clock_offset', False)
def get_platform_enable_audio(self):
return self.info.get('platform_enable_audio', False)
def get_platform_keymap(self):
return self.info.get('platform_keymap', '')
def get_platform(self):
return self.info.get('platform', {})
def get_pci_bus(self):
return self.info.get('pci_bus', '')
def get_tools_version(self):
return self.info.get('tools_version', {})
def get_metrics(self):
return self.metrics.get_uuid();
def get_on_shutdown(self):
after_shutdown = self.info.get('actions_after_shutdown')
@@ -2278,8 +2286,6 @@ class XendDomainInfo:
@return: uuid of the device
"""
xenapi_vbd['image'] = vdi_image_path
log.debug('create_vbd: %s' % xenapi_vbd)
dev_uuid = ''
if vdi_image_path.startswith('tap'):
dev_uuid = self.info.device_add('tap', cfg_xenapi = xenapi_vbd)
else:
@@ -2289,16 +2295,25 @@ class XendDomainInfo:
raise XendError('Failed to create device')
if self.state == XEN_API_VM_POWER_STATE_RUNNING:
_, config = self.info['devices'][dev_uuid]
dev_control = None
if vdi_image_path.startswith('tap'):
dev_control = self.getDeviceController('tap')
dev_control = self.getDeviceController('tap')
else:
dev_control = self.getDeviceController('vbd')
config['devid'] = dev_control.createDevice(config)
try:
devid = dev_control.createDevice(config)
dev_control.waitForDevice(devid)
self.info.device_update(dev_uuid,
cfg_xenapi = {'devid': devid})
except Exception, exn:
log.exception(exn)
del self.info['devices'][dev_uuid]
self.info['vbd_refs'].remove(dev_uuid)
raise
return dev_uuid
def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
@@ -2332,9 +2347,21 @@ class XendDomainInfo:
raise XendError('Failed to create device')
if self.state == XEN_API_VM_POWER_STATE_RUNNING:
_, config = self.info['devices'][dev_uuid]
config['devid'] = self.getDeviceController('vif').createDevice(config)
_, config = self.info['devices'][dev_uuid]
dev_control = self.getDeviceController('vif')
try:
devid = dev_control.createDevice(config)
dev_control.waitForDevice(devid)
self.info.device_update(dev_uuid,
cfg_xenapi = {'devid': devid})
except Exception, exn:
log.exception(exn)
del self.info['devices'][dev_uuid]
self.info['vif_refs'].remove(dev_uuid)
raise
return dev_uuid
def create_vtpm(self, xenapi_vtpm):
@@ -2401,7 +2428,7 @@ class XendDomainInfo:
def __str__(self):
return '<domain id=%s name=%s memory=%s state=%s>' % \
(str(self.domid), self.info['name_label'],
str(self.info['memory_static_min']), DOM_STATES[self.state])
str(self.info['memory_dynamic_max']), DOM_STATES[self.state])
__repr__ = __str__
+7
View File
@@ -13,6 +13,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (c) 2006, 2007 XenSource Inc.
#============================================================================
from xmlrpclib import Fault
@@ -55,6 +56,12 @@ class VmError(XendError):
"""Vm construction error."""
pass
class HVMRequired(VmError):
def __init__(self):
XendError.__init__(self,
'HVM guest support is unavailable: is VT/AMD-V '
'supported by your CPU and enabled in your BIOS?')
XEND_ERROR_AUTHENTICATION_FAILED = ('ELUSER', 'Authentication Failed')
XEND_ERROR_SESSION_INVALID = ('EPERMDENIED', 'Session Invalid')
+12
View File
@@ -59,6 +59,18 @@ if 'TRACE' not in logging.__dict__:
return filename, frame[2]
logging.Logger.findCaller = findCaller
# Work around a bug in Python's inspect module: findsource is supposed to
# raise IOError if it fails, with other functions in that module coping
# with that, but some people are seeing IndexError raised from there.
if hasattr(inspect, 'findsource'):
real_findsource = getattr(inspect, 'findsource')
def findsource(*args, **kwargs):
try:
return real_findsource(*args, **kwargs)
except IndexError, exn:
raise IOError(exn)
inspect.findsource = findsource
log = logging.getLogger("xend")
+59 -6
View File
@@ -75,6 +75,11 @@ class XendNode:
self.other_config = {}
self.cpus = {}
self.host_metrics_uuid = uuid.createString()
# put some arbitrary params in other_config as this
# is directly exposed via XenAPI
self.other_config["xen_pagesize"] = self.xeninfo_dict()["xen_pagesize"]
self.other_config["platform_params"] = self.xeninfo_dict()["platform_params"]
# load CPU UUIDs
saved_cpus = self.state_store.load_state('cpu')
@@ -95,15 +100,12 @@ class XendNode:
self.cpus[u] = {'uuid': u, 'number': i }
for u in self.cpus.keys():
log.error(self.cpus[u])
number = self.cpus[u]['number']
# We can run off the end of the cpuinfo list if domain0 does not
# have #vcpus == #pcpus. In that case we just replicate one that's
# in the hash table.
if not cpuinfo.has_key(number):
number = cpuinfo.keys()[0]
log.error(number)
log.error(cpuinfo)
if arch.type == "x86":
self.cpus[u].update(
{ 'host' : self.uuid,
@@ -356,14 +358,37 @@ class XendNode:
def xen_version(self):
info = self.xc.xeninfo()
try:
from xen import VERSION
return {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
'Xend': VERSION}
except (ImportError, AttributeError):
return {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
info = {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
'Xend': '3.0.3'}
# Add xend_config_format
info.update(self.xendinfo_dict())
# Add version info about machine
info.update(self.nodeinfo_dict())
# Add specific xen version info
xeninfo_dict = self.xeninfo_dict()
info.update({
"xen_major": xeninfo_dict["xen_major"],
"xen_minor": xeninfo_dict["xen_minor"],
"xen_extra": xeninfo_dict["xen_extra"],
"cc_compiler": xeninfo_dict["cc_compiler"],
"cc_compile_by": xeninfo_dict["cc_compile_by"],
"cc_compile_domain": xeninfo_dict["cc_compile_domain"],
"cc_compile_date": xeninfo_dict["cc_compile_date"],
"xen_changeset": xeninfo_dict["xen_changeset"]
})
return info
def get_name(self):
return self.name
@@ -418,6 +443,27 @@ class XendNode:
return 0.0
def get_vcpus_policy(self):
sched_id = self.xc.sched_id_get()
if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
return 'sedf'
elif sched_id == xen.lowlevel.xc.XEN_SCHEDULER_CREDIT:
return 'credit'
else:
return 'unknown'
def get_cpu_configuration(self):
phys_info = self.physinfo_dict()
cpu_info = {
"nr_nodes": phys_info["nr_nodes"],
"sockets_per_node": phys_info["sockets_per_node"],
"cores_per_socket": phys_info["cores_per_socket"],
"threads_per_core": phys_info["threads_per_core"]
}
return cpu_info
#
# Network Functions
#
@@ -453,6 +499,12 @@ class XendNode:
return pif.network
raise Exception('Bridge %s is not connected to a network' % bridge)
#
# Debug keys.
#
def send_debug_keys(self, keys):
return self.xc.send_debug_keys(keys)
#
# Getting host information.
@@ -478,7 +530,8 @@ class XendNode:
info['cores_per_socket'] *
info['threads_per_core'])
info['cpu_mhz'] = info['cpu_khz'] / 1000
# physinfo is in KiB
# physinfo is in KiB, need it in MiB
info['total_memory'] = info['total_memory'] / 1024
info['free_memory'] = info['free_memory'] / 1024
+16 -11
View File
@@ -54,7 +54,6 @@ class XendVDI(AutoSaveObject):
SAVED_CFG = ['name_label',
'name_description',
'sector_size',
'virtual_size',
'physical_utilisation',
'sharable',
@@ -67,13 +66,22 @@ class XendVDI(AutoSaveObject):
self.sr_uuid = sr_uuid
self.name_label = ""
self.name_description = ""
self.sector_size = 1024
self.virtual_size = 0
self.physical_utilisation = 0
self.sharable = False
self.read_only = False
self.type = "system"
self.location = ''
self.other_config = {}
self.vbds = []
def addVBD(self, vbd_ref):
self.vbds.append(vbd_ref)
def removeVBD(self, vbd_ref):
self.vbds.remove(vbd_ref)
def getVBDs(self):
return self.vbds
def load_config_dict(self, cfg):
"""Loads configuration into the object from a dict.
@@ -144,11 +152,10 @@ class XendVDI(AutoSaveObject):
'name_description': self.name_description,
'virtual_size': self.virtual_size,
'physical_utilisation': self.physical_utilisation,
'sector_size': self.sector_size,
'sharable': False,
'readonly': False,
'SR': self.sr_uuid,
'location': self.get_location(),
'other_config': self.other_config,
'VBDs': []}
def get_location(self):
@@ -163,12 +170,11 @@ class XendQCoWVDI(XendVDI):
self.cfg_path = cfg_path
self.physical_utilisation = psize
self.virtual_size = vsize
self.sector_size = 512
self.auto_save = True
self.location = 'tap:qcow:%s' % self.qcow_path
self.other_config['location'] = 'tap:qcow:%s' % self.qcow_path
def get_location(self):
return self.location
return self.other_config['location']
class XendLocalVDI(XendVDI):
def __init__(self, vdi_struct):
@@ -182,11 +188,10 @@ class XendLocalVDI(XendVDI):
self.name_description = vdi_struct.get('name_description', '')
self.physical_utilisation = 0
self.virtual_size = 0
self.sector_size = 0
self.type = vdi_struct.get('type', '')
self.sharable = vdi_struct.get('sharable', False)
self.read_only = vdi_struct.get('read_only', False)
self.location = vdi_struct.get('location', 'file:/dev/null')
self.other_config = vdi_struct.get('other_config', {})
def get_location(self):
return self.location
return self.other_config['location']
+70
View File
@@ -0,0 +1,70 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (c) 2006-2007 Xensource Inc.
#============================================================================
from xen.xend.XendLogging import log
instances = {}
class XendVMMetrics:
"""VM Metrics."""
def get_by_uuid(_, uuid):
return instances[uuid]
get_by_uuid = classmethod(get_by_uuid)
def is_valid_vm_metrics(_, uuid):
return uuid in instances
is_valid_vm_metrics = classmethod(is_valid_vm_metrics)
def get_all(_):
return instances.keys()
get_all = classmethod(get_all)
def __init__(self, uuid, xend_domain_instance):
self.uuid = uuid
self.xend_domain_instance = xend_domain_instance
instances[uuid] = self
def get_uuid(self):
return self.uuid
def get_memory_actual(self):
return self.get_record()["memory_actual"]
def get_vcpus_number(self):
return self.get_record()["vcpus_number"]
def get_vcpus_utilisation(self):
return self.xend_domain_instance.get_vcpus_util()
def get_record(self):
domInfo = self.xend_domain_instance.getDomInfo()
if domInfo:
return { 'uuid' : self.uuid,
'memory_actual' : domInfo["mem_kb"] * 1024,
'vcpus_number' : domInfo["online_vcpus"],
'vcpus_utilisation' : self.get_vcpus_utilisation()
}
else:
return { 'uuid' : self.uuid,
'memory_actual' : 0,
'vcpus_number' : 0,
'vcpus_utilisation' : {}
}
+26 -31
View File
@@ -13,7 +13,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
# Copyright (C) 2005-2007 XenSource Ltd
#============================================================================
@@ -24,7 +24,7 @@ import signal
import xen.lowlevel.xc
from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
from xen.xend.XendError import VmError, XendError
from xen.xend.XendError import VmError, XendError, HVMRequired
from xen.xend.XendLogging import log
from xen.xend.XendOptions import instance as xenopts
from xen.xend.server.netif import randomMAC
@@ -36,13 +36,12 @@ xc = xen.lowlevel.xc.xc()
MAX_GUEST_CMDLINE = 1024
def create(vm, vmConfig, imageConfig, deviceConfig):
def create(vm, vmConfig):
"""Create an image handler for a vm.
@return ImageHandler instance
"""
return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig,
deviceConfig)
return findImageHandlerClass(vmConfig)(vm, vmConfig)
class ImageHandler:
@@ -65,7 +64,7 @@ class ImageHandler:
ostype = None
def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
def __init__(self, vm, vmConfig):
self.vm = vm
self.bootloader = False
@@ -73,9 +72,9 @@ class ImageHandler:
self.ramdisk = None
self.cmdline = None
self.configure(vmConfig, imageConfig, deviceConfig)
self.configure(vmConfig)
def configure(self, vmConfig, imageConfig, _):
def configure(self, vmConfig):
"""Config actions common to all unix-like domains."""
if '_temp_using_bootloader' in vmConfig:
self.bootloader = True
@@ -233,30 +232,29 @@ class HVMImageHandler(ImageHandler):
ostype = "hvm"
def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig)
def __init__(self, vm, vmConfig):
ImageHandler.__init__(self, vm, vmConfig)
self.shutdownWatch = None
self.rebootFeatureWatch = None
def configure(self, vmConfig, imageConfig, deviceConfig):
ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
def configure(self, vmConfig):
ImageHandler.configure(self, vmConfig)
if not self.kernel:
self.kernel = '/usr/lib/xen/boot/hvmloader'
info = xc.xeninfo()
if 'hvm' not in info['xen_caps']:
raise VmError("HVM guest support is unavailable: is VT/AMD-V "
"supported by your CPU and enabled in your BIOS?")
raise HVMRequired()
self.dmargs = self.parseDeviceModelArgs(vmConfig)
self.device_model = imageConfig['hvm'].get('device_model')
self.device_model = vmConfig['platform'].get('device_model')
if not self.device_model:
raise VmError("hvm: missing device model")
self.display = imageConfig['hvm'].get('display')
self.xauthority = imageConfig['hvm'].get('xauthority')
self.vncconsole = imageConfig['hvm'].get('vncconsole')
self.display = vmConfig['platform'].get('display')
self.xauthority = vmConfig['platform'].get('xauthority')
self.vncconsole = vmConfig['platform'].get('vncconsole')
self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
("image/device-model", self.device_model),
@@ -264,9 +262,9 @@ class HVMImageHandler(ImageHandler):
self.pid = None
self.pae = imageConfig['hvm'].get('pae', 0)
self.apic = imageConfig['hvm'].get('apic', 0)
self.acpi = imageConfig['hvm']['devices'].get('acpi', 0)
self.pae = int(vmConfig['platform'].get('pae', 0))
self.apic = int(vmConfig['platform'].get('apic', 0))
self.acpi = int(vmConfig['platform'].get('acpi', 0))
def buildDomain(self):
@@ -302,11 +300,10 @@ class HVMImageHandler(ImageHandler):
'localtime', 'serial', 'stdvga', 'isa',
'acpi', 'usb', 'usbdevice', 'keymap' ]
hvmDeviceConfig = vmConfig['image']['hvm']['devices']
ret = ['-vcpus', str(self.vm.getVCpuCount())]
for a in dmargs:
v = hvmDeviceConfig.get(a)
v = vmConfig['platform'].get(a)
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
@@ -366,14 +363,14 @@ class HVMImageHandler(ImageHandler):
# Find RFB console device, and if it exists, make QEMU enable
# the VNC console.
#
if vmConfig['image'].get('nographic'):
if int(vmConfig['platform'].get('nographic', 0)) != 0:
# skip vnc init if nographic is set
ret.append('-nographic')
return ret
vnc_config = {}
has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0
has_sdl = int(vmConfig['image'].get('sdl', 0)) != 0
has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
for dev_uuid in vmConfig['console_refs']:
dev_type, dev_info = vmConfig['devices'][dev_uuid]
if dev_type == 'vfb':
@@ -385,8 +382,8 @@ class HVMImageHandler(ImageHandler):
if not vnc_config:
for key in ('vncunused', 'vnclisten', 'vncdisplay',
'vncpasswd'):
if key in vmConfig['image']:
vnc_config[key] = vmConfig['image'][key]
if key in vmConfig['platform']:
vnc_config[key] = vmConfig['platform'][key]
if not vnc_config.get('vncunused', 0) and \
vnc_config.get('vncdisplay', 0):
@@ -604,9 +601,7 @@ def findImageHandlerClass(image):
@param image config
@return ImageHandler subclass or None
"""
image_type = image['type']
if image_type is None:
raise VmError('missing image type')
image_type = image.image_type()
try:
return _handlers[arch.type][image_type]
except KeyError:
+6 -3
View File
@@ -276,9 +276,12 @@ class Daemon:
if not m:
return None
modulename = m.group(1)
if re.search('sxp.py', modulename):
return None
if re.search('SrvServer.py', modulename):
if modulename.endswith('.pyc'):
modulename = modulename[:-1]
if modulename == 'sxp.py' or \
modulename == 'XendLogging.py' or \
modulename == 'XendMonitor.py' or \
modulename == 'server/SrvServer.py':
return None
self.traceindent += 1
self.print_trace("> %s:%s\n"
+1 -1
View File
@@ -157,7 +157,7 @@ class XMLRPCServer:
self.server.register_function(fn, "xend.domain.%s" % name[7:])
# Functions in XendNode and XendDmesg
for type, lst, n in [(XendNode, ['info'], 'node'),
for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'),
(XendDmesg, ['info', 'clear'], 'node.dmesg')]:
inst = type.instance()
for name in lst:
+1 -1
View File
@@ -46,7 +46,7 @@ class VfbifController(DevController):
def createDevice(self, config):
DevController.createDevice(self, config)
if self.vm.info.get('HVM_boot_policy'):
if self.vm.info.is_hvm():
# is HVM, so qemu-dm will handle the vfb.
return
+1 -1
View File
@@ -155,7 +155,7 @@ class Session(xen.util.xmlrpclib2.ServerProxy):
def _parse_result(result):
if type(result) != dict or 'Status' not in result:
raise xmlrpclib.Fault(500, 'Missing Status in response from server')
raise xmlrpclib.Fault(500, 'Missing Status in response from server: ' + str(result))
if result['Status'] == 'Success':
if 'Value' in result:
return result['Value']
+1 -1
View File
@@ -17,7 +17,7 @@
# Author: Bryan D. Payne <bdpayne@us.ibm.com>
#============================================================================
"""Labeling a domain configuration file or a resoruce.
"""Labeling a domain configuration file or a resource.
"""
import os
import sys
+118
View File
@@ -0,0 +1,118 @@
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin 1 for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
%HTMLlat1;
<!ENTITY % HTMLsymbol PUBLIC
"-//W3C//ENTITIES Symbols for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
%HTMLsymbol;
<!ENTITY % HTMLspecial PUBLIC
"-//W3C//ENTITIES Special for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
%HTMLspecial;
<!-- a Uniform Resource Identifier, see [RFC2396] -->
<!ENTITY % URI "CDATA">
<!ENTITY % NAMEID "name ID #REQUIRED">
<!ENTITY % CRASH_BEHAVIOUR "( destroy
| coredump_and_destroy
| restart
| coredump_and_restart
| preserve
| rename_restart )">
<!ENTITY % NORMAL_EXIT "( destroy | restart )">
<!ENTITY % VDI_TYPE "( system
| user
| ephemeral
| suspend
| crashdump )">
<!ELEMENT xm (vm*,
vdi*)>
<!ELEMENT version (#PCDATA)>
<!ELEMENT vm (name,
version,
(pv|hvm),
memory,
vbd*,
vif*,
vcpu_param*,
other_config*)>
<!ATTLIST vm is_a_template CDATA #REQUIRED
auto_power_on CDATA #REQUIRED
vcpus_max CDATA #REQUIRED
vcpus_at_startup CDATA #REQUIRED
actions_after_shutdown %NORMAL_EXIT; #REQUIRED
actions_after_reboot %NORMAL_EXIT; #REQUIRED
actions_after_crash %CRASH_BEHAVIOUR; #REQUIRED
platform_std_VGA CDATA #REQUIRED
platform_serial CDATA #REQUIRED
platform_localtime CDATA #REQUIRED
platform_clock_offet CDATA #REQUIRED
platform_enable_audio CDATA #REQUIRED
PCI_bus CDATA #REQUIRED>
<!ELEMENT memory EMPTY>
<!ATTLIST memory static_min CDATA #REQUIRED
static_max CDATA #REQUIRED
dynamic_min CDATA #REQUIRED
dynamic_max CDATA #REQUIRED>
<!ELEMENT vbd (qos_algorithm_param*)>
<!ATTLIST vbd %NAMEID;
mode (RO | RW) #REQUIRED
vdi IDREF #REQUIRED
device CDATA #REQUIRED
bootable CDATA #REQUIRED
type (CD | disk) #REQUIRED
qos_algorithm_type CDATA #REQUIRED>
<!ELEMENT vif (qos_algorithm_param*)>
<!ATTLIST vif %NAMEID;
mac CDATA #REQUIRED
mtu CDATA #REQUIRED
device CDATA #REQUIRED
qos_algorithm_type CDATA #REQUIRED
bridge CDATA #IMPLIED
network CDATA #IMPLIED>
<!ELEMENT pv EMPTY>
<!ATTLIST pv kernel CDATA #REQUIRED
bootloader CDATA #REQUIRED
ramdisk CDATA #REQUIRED
args CDATA #REQUIRED
bootloader_args CDATA #REQUIRED>
<!ELEMENT hvm (boot_param*)>
<!ATTLIST hvm boot_policy CDATA #REQUIRED>
<!ELEMENT boot_param EMPTY>
<!ATTLIST boot_param key CDATA #REQUIRED
value CDATA #REQUIRED>
<!ELEMENT vdi (name)>
<!ATTLIST vdi %NAMEID;
src %URI; #REQUIRED
type %VDI_TYPE; #REQUIRED
size CDATA #REQUIRED
shareable CDATA #REQUIRED
read_only CDATA #REQUIRED>
<!ELEMENT name (label,
description)>
<!ELEMENT label (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT vcpu_param EMPTY>
<!ATTLIST vcpu_param key CDATA #REQUIRED
value CDATA #REQUIRED>
<!ELEMENT other_config EMPTY>
<!ATTLIST other_config key CDATA #REQUIRED
value CDATA #REQUIRED>
<!ELEMENT qos_algorithm_param EMPTY>
<!ATTLIST qos_algorithm_param key CDATA #REQUIRED
value CDATA #REQUIRED>
+57 -26
View File
@@ -28,12 +28,13 @@ import time
import xmlrpclib
from xen.xend import sxp
from xen.xend import PrettyPrint
from xen.xend import PrettyPrint as SXPPrettyPrint
from xen.xend import osdep
import xen.xend.XendClient
from xen.xend.XendBootloader import bootloader
from xen.util import blkif
from xen.util import security
from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
from xen.xm.opts import *
@@ -98,6 +99,11 @@ gopts.opt('dryrun', short='n',
use="Dry run - prints the resulting configuration in SXP but "
"does not create the domain.")
gopts.opt('xmldryrun', short='x',
fn=set_true, default=0,
use="XML dry run - prints the resulting configuration in XML but "
"does not create the domain.")
gopts.opt('paused', short='p',
fn=set_true, default=0,
use='Leave the domain paused after it is created.')
@@ -1241,34 +1247,59 @@ def main(argv):
except IOError, exn:
raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
if serverType == SERVER_XEN_API:
from xen.xm.xenapi_create import sxp2xml
sxp2xml_inst = sxp2xml()
doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
if opts.vals.dryrun:
PrettyPrint.prettyprint(config)
SXPPrettyPrint.prettyprint(config)
if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
from xml.dom.ext import PrettyPrint as XMLPrettyPrint
XMLPrettyPrint(doc)
if opts.vals.dryrun or opts.vals.xmldryrun:
return
if opts.vals.console_autoconnect:
do_console(sxp.child_value(config, 'name', -1))
if serverType == SERVER_XEN_API:
from xen.xm.xenapi_create import xenapi_create
xenapi_create_inst = xenapi_create()
vm_refs = xenapi_create_inst.create(document = doc)
map(lambda vm_ref: server.xenapi.VM.start(vm_ref, 0), vm_refs)
else:
if not create_security_check(config):
raise security.ACMError('Security Configuration prevents domain from starting')
else:
if opts.vals.console_autoconnect:
cpid = os.fork()
if cpid != 0:
for i in range(10):
# Catch failure of the create process
time.sleep(1)
(p, rv) = os.waitpid(cpid, os.WNOHANG)
if os.WIFEXITED(rv):
if os.WEXITSTATUS(rv) != 0:
sys.exit(os.WEXITSTATUS(rv))
try:
# Acquire the console of the created dom
name = sxp.child_value(config, 'name', -1)
dom = server.xend.domain(name)
domid = int(sxp.child_value(dom, 'domid', '-1'))
console.execConsole(domid)
except:
pass
print("Could not start console\n");
sys.exit(0)
dom = make_domain(opts, config)
raise security.ACMError(
'Security Configuration prevents domain from starting')
dom = make_domain(opts, config)
def do_console(domain_name):
cpid = os.fork()
if cpid != 0:
for i in range(10):
# Catch failure of the create process
time.sleep(1)
(p, rv) = os.waitpid(cpid, os.WNOHANG)
if os.WIFEXITED(rv):
if os.WEXITSTATUS(rv) != 0:
sys.exit(os.WEXITSTATUS(rv))
try:
# Acquire the console of the created dom
if serverType == SERVER_XEN_API:
domid = server.xenapi.VM.get_domid(
get_single_vm(domain_name))
else:
dom = server.xend.domain(domain_name)
domid = int(sxp.child_value(dom, 'domid', '-1'))
console.execConsole(domid)
except:
pass
print("Could not start console\n");
sys.exit(0)
if __name__ == '__main__':
main(sys.argv)
+437 -102
View File
@@ -25,6 +25,7 @@ import atexit
import cmd
import os
import pprint
import readline
import shlex
import sys
import re
@@ -32,11 +33,11 @@ import getopt
import socket
import traceback
import xmlrpclib
import traceback
import time
import datetime
from select import select
import xml.dom.minidom
from xen.util.blkif import blkdev_name_to_number
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)
@@ -48,18 +49,19 @@ from xen.xend.XendConstants import *
from xen.xm.opts import OptionError, Opts, wrap, set_true
from xen.xm import console
from xen.util import security
from xen.util.xmlrpclib2 import ServerProxy
import XenAPI
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
# may only be specified before positional arguments.
if not hasattr(getopt, 'gnu_getopt'):
getopt.gnu_getopt = getopt.getopt
XM_CONFIG_FILE = '/etc/xen/xm-config.xml'
XM_CONFIG_FILE_ENVVAR = 'XM_CONFIG_FILE'
XM_CONFIG_FILE_DEFAULT = '/etc/xen/xm-config.xml'
# Supported types of server
SERVER_LEGACY_XMLRPC = 'LegacyXMLRPC'
@@ -133,11 +135,12 @@ SUBCOMMAND_HELP = {
'sched-credit': ('[-d <Domain> [-w[=WEIGHT]|-c[=CAP]]]',
'Get/set credit scheduler parameters.'),
'sysrq' : ('<Domain> <letter>', 'Send a sysrq to a domain.'),
'debug-keys' : ('<Keys>', 'Send debug keys to Xen.'),
'trigger' : ('<Domain> <nmi|reset|init> [<VCPU>]',
'Send a trigger to a domain.'),
'vcpu-list' : ('[<Domain>]',
'List the VCPUs for a domain or all domains.'),
'vcpu-pin' : ('<Domain> <VCPU> <CPUs>',
'vcpu-pin' : ('<Domain> <VCPU> <CPUs|all>',
'Set which CPUs a VCPU can use.'),
'vcpu-set' : ('<Domain> <vCPUs>',
'Set the number of active VCPUs for allowed for the'
@@ -260,7 +263,6 @@ common_commands = [
"shutdown",
"start",
"suspend",
"trigger",
"top",
"unpause",
"uptime",
@@ -300,6 +302,7 @@ domain_commands = [
]
host_commands = [
"debug-keys",
"dmesg",
"info",
"log",
@@ -349,13 +352,14 @@ all_commands = (domain_commands + host_commands + scheduler_commands +
# Configuration File Parsing
##
xmConfigFile = os.getenv(XM_CONFIG_FILE_ENVVAR, XM_CONFIG_FILE_DEFAULT)
config = None
if os.path.isfile(XM_CONFIG_FILE):
if os.path.isfile(xmConfigFile):
try:
config = xml.dom.minidom.parse(XM_CONFIG_FILE)
config = xml.dom.minidom.parse(xmConfigFile)
except:
print >>sys.stderr, ('Ignoring invalid configuration file %s.' %
XM_CONFIG_FILE)
xmConfigFile)
def parseServer():
if config:
@@ -489,6 +493,18 @@ def usage(cmd = None):
#
####################################################################
def get_default_SR():
return [sr_ref
for sr_ref in server.xenapi.SR.get_all()
if server.xenapi.SR.get_type(sr_ref) == "local"][0]
def get_default_Network():
return [network_ref
for network_ref in server.xenapi.network.get_all()][0]
def map2sxp(m):
return [[k, m[k]] for k in m.keys()]
def arg_check(args, name, lo, hi = -1):
n = len([i for i in args if i != '--'])
@@ -555,7 +571,11 @@ class Shell(cmd.Cmd):
if serverType == SERVER_XEN_API:
res = server.xenapi._UNSUPPORTED_list_all_methods()
for f in res:
setattr(Shell, 'do_' + f, self.default)
setattr(Shell, 'do_' + f + ' ', self.default)
def preloop(self):
cmd.Cmd.preloop(self)
readline.set_completer_delims(' ')
def default(self, line):
words = shlex.split(line)
@@ -576,9 +596,9 @@ class Shell(cmd.Cmd):
return False
def completedefault(self, text, line, begidx, endidx):
cmd = line.split(' ')[0]
clas, func = cmd.split('.')
if begidx != len(cmd) + 1 or \
words = shlex.split(line[:begidx])
clas, func = words[0].split('.')
if len(words) > 1 or \
func.startswith('get_by_') or \
func == 'get_all':
return []
@@ -667,10 +687,41 @@ def xm_restore(args):
def getDomains(domain_names, state, full = 0):
if domain_names:
return [server.xend.domain(dom, full) for dom in domain_names]
if serverType == SERVER_XEN_API:
doms_sxp = []
doms_dict = []
dom_refs = server.xenapi.VM.get_all()
for dom_ref in dom_refs:
dom_rec = server.xenapi.VM.get_record(dom_ref)
dom_metrics_ref = server.xenapi.VM.get_metrics(dom_ref)
dom_metrics = server.xenapi.VM_metrics.get_record(dom_metrics_ref)
dom_rec.update({'name': dom_rec['name_label'],
'memory_actual': int(dom_metrics['memory_actual'])/1024,
'vcpus': dom_metrics['vcpus_number'],
'state': '-----',
'cpu_time': dom_metrics['vcpus_utilisation']})
doms_sxp.append(['domain'] + map2sxp(dom_rec))
doms_dict.append(dom_rec)
if domain_names:
doms = [['domain'] + map2sxp(dom) for dom in doms_dict
if dom["name"] in domain_names]
if len(doms) > 0:
return doms
else:
print "Error: no domain%s named %s" % \
(len(domain_names) > 1 and 's' or '',
', '.join(domain_names))
sys.exit(-1)
else:
return doms_sxp
else:
return server.xend.domains_with_state(True, state, full)
if domain_names:
return [server.xend.domain(dom, full) for dom in domain_names]
else:
return server.xend.domains_with_state(True, state, full)
def xm_list(args):
@@ -729,26 +780,48 @@ def parse_doms_info(info):
else:
up_time = time.time() - start_time
return {
parsed_info = {
'domid' : get_info('domid', str, ''),
'name' : get_info('name', str, '??'),
'mem' : get_info('memory_dynamic_min', int, 0),
'state' : get_info('state', str, ''),
'cpu_time' : get_info('cpu_time', float, 0.0),
# VCPUs is the number online when the VM is up, or the number
# configured otherwise.
'vcpus' : get_info('online_vcpus', int,
get_info('vcpus', int, 0)),
'up_time' : up_time,
'seclabel' : security.get_security_printlabel(info),
'up_time' : up_time
}
# We're not supporting security stuff just yet via XenAPI
if serverType != SERVER_XEN_API:
from xen.util import security
parsed_info['seclabel'] = security.get_security_printlabel(info)
else:
parsed_info['seclabel'] = ""
if serverType == SERVER_XEN_API:
parsed_info['mem'] = get_info('memory_actual', int, 0) / 1024
cpu_times = get_info('cpu_time', lambda x : (x), 0.0)
if sum(cpu_times.values()) > 0:
parsed_info['cpu_time'] = sum(cpu_times.values()) / float(len(cpu_times.values()))
else:
parsed_info['cpu_time'] = 0
else:
parsed_info['mem'] = get_info('memory', int,0)
parsed_info['cpu_time'] = get_info('cpu_time', float, 0.0)
return parsed_info
def check_sched_type(sched):
current = 'unknown'
for x in server.xend.node.info()[1:]:
if len(x) > 1 and x[0] == 'xen_scheduler':
current = x[1]
break
if serverType == SERVER_XEN_API:
current = server.xenapi.host.get_sched_policy(server.xenapi.session.get_this_host())
else:
current = 'unknown'
for x in server.xend.node.info()[1:]:
if len(x) > 1 and x[0] == 'xen_scheduler':
current = x[1]
break
if sched != current:
err("Xen is running with the %s scheduler" % current)
sys.exit(1)
@@ -788,17 +861,22 @@ def xm_label_list(doms):
output = []
format = '%(name)-32s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
'%(cpu_time)8.1f %(seclabel)9s'
for dom in doms:
d = parse_doms_info(dom)
if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
if not d['seclabel']:
d['seclabel'] = 'ERROR'
elif security.active_policy in ['DEFAULT']:
d['seclabel'] = 'DEFAULT'
else:
d['seclabel'] = 'INACTIVE'
output.append((format % d, d['seclabel']))
if serverType != SERVER_XEN_API:
from xen.util import security
for dom in doms:
d = parse_doms_info(dom)
if security.active_policy not in ['INACTIVE', 'NULL', 'DEFAULT']:
if not d['seclabel']:
d['seclabel'] = 'ERROR'
elif security.active_policy in ['DEFAULT']:
d['seclabel'] = 'DEFAULT'
else:
d['seclabel'] = 'INACTIVE'
output.append((format % d, d['seclabel']))
#sort by labels
output.sort(lambda x,y: cmp( x[1].lower(), y[1].lower()))
@@ -807,7 +885,6 @@ def xm_label_list(doms):
def xm_vcpu_list(args):
if args:
dominfo = map(server.xend.domain.getVCPUInfo, args)
else:
@@ -1078,7 +1155,10 @@ def xm_vcpu_pin(args):
dom = args[0]
vcpu = args[1]
cpumap = cpu_make_map(args[2])
if args[2] == 'all':
cpumap = cpu_make_map('0-63')
else:
cpumap = cpu_make_map(args[2])
server.xend.domain.pincpu(dom, vcpu, cpumap)
@@ -1086,49 +1166,69 @@ def xm_mem_max(args):
arg_check(args, "mem-max", 2)
dom = args[0]
mem = int_unit(args[1], 'm')
server.xend.domain.maxmem_set(dom, mem)
if serverType == SERVER_XEN_API:
mem = int_unit(args[1], 'k') * 1024
server.xenapi.VM.set_memory_static_max(get_single_vm(dom), mem)
else:
mem = int_unit(args[1], 'm')
server.xend.domain.maxmem_set(dom, mem)
def xm_mem_set(args):
arg_check(args, "mem-set", 2)
dom = args[0]
mem_target = int_unit(args[1], 'm')
server.xend.domain.setMemoryTarget(dom, mem_target)
if serverType == SERVER_XEN_API:
mem_target = int_unit(args[1], 'm') * 1024 * 1024
server.xenapi.VM.set_memory_dynamic_max(get_single_vm(dom), mem_target)
server.xenapi.VM.set_memory_dynamic_min(get_single_vm(dom), mem_target)
else:
mem_target = int_unit(args[1], 'm')
server.xend.domain.setMemoryTarget(dom, mem_target)
def xm_vcpu_set(args):
arg_check(args, "vcpu-set", 2)
server.xend.domain.setVCpuCount(args[0], int(args[1]))
dom = args[0]
vcpus = int(args[1])
if serverType == SERVER_XEN_API:
server.xenapi.VM.set_vcpus_live(get_single_vm(dom), vcpus)
else:
server.xend.domain.setVCpuCount(dom, vcpus)
def xm_destroy(args):
arg_check(args, "destroy", 1)
dom = args[0]
if serverType == SERVER_XEN_API:
server.xenapi.VM.hard_shutdown(get_single_vm(dom))
else:
server.xend.domain.destroy(dom)
def xm_domid(args):
arg_check(args, "domid", 1)
name = args[0]
dom = server.xend.domain(name)
print sxp.child_value(dom, 'domid')
if serverType == SERVER_XEN_API:
print server.xenapi.VM.get_domid(get_single_vm(name))
else:
dom = server.xend.domain(name)
print sxp.child_value(dom, 'domid')
def xm_domname(args):
arg_check(args, "domname", 1)
name = args[0]
dom = server.xend.domain(name)
print sxp.child_value(dom, 'name')
if serverType == SERVER_XEN_API:
print server.xenapi.VM.get_name_label(get_single_vm(name))
else:
dom = server.xend.domain(name)
print sxp.child_value(dom, 'name')
def xm_sched_sedf(args):
def ns_to_ms(val):
@@ -1276,13 +1376,59 @@ def xm_sched_credit(args):
def xm_info(args):
arg_check(args, "info", 0)
info = server.xend.node.info()
for x in info[1:]:
if len(x) < 2:
print "%-23s: (none)" % x[0]
else:
print "%-23s:" % x[0], x[1]
if serverType == SERVER_XEN_API:
# Need to fake out old style xm info as people rely on parsing it
host_record = server.xenapi.host.get_record(
server.xenapi.session.get_this_host())
host_cpu_records = map(server.xenapi.host_cpu.get_record, host_record["host_CPUs"])
host_metrics_record = server.xenapi.host_metrics.get_record(host_record["metrics"])
info = {
"host": host_record["name_label"],
"release": host_record["software_version"]["release"],
"version": host_record["software_version"]["version"],
"machine": host_record["software_version"]["machine"],
"nr_cpus": len(host_record["host_CPUs"]),
"nr_nodes": host_record["cpu_configuration"]["nr_nodes"],
"sockets_per_node": host_record["cpu_configuration"]["sockets_per_node"],
"cores_per_socket": host_record["cpu_configuration"]["cores_per_socket"],
"threads_per_core": host_record["cpu_configuration"]["threads_per_core"],
"cpu_mhz": sum([int(host_cpu_record["speed"]) for host_cpu_record in host_cpu_records])
/ len(host_cpu_records),
"hw_caps": host_cpu_records[0]["features"],
"total_memory": int(host_metrics_record["memory_total"])/1024/1024,
"free_memory": int(host_metrics_record["memory_free"])/1024/1024,
"xen_major": host_record["software_version"]["xen_major"],
"xen_minor": host_record["software_version"]["xen_minor"],
"xen_extra": host_record["software_version"]["xen_extra"],
"xen_caps": " ".join(host_record["capabilities"]),
"xen_scheduler": host_record["sched_policy"],
"xen_pagesize": host_record["other_config"]["xen_pagesize"],
"platform_params": host_record["other_config"]["platform_params"],
"xen_changeset": host_record["software_version"]["xen_changeset"],
"cc_compiler": host_record["software_version"]["cc_compiler"],
"cc_compile_by": host_record["software_version"]["cc_compile_by"],
"cc_compile_domain": host_record["software_version"]["cc_compile_domain"],
"cc_compile_date": host_record["software_version"]["cc_compile_date"],
"xend_config_format":host_record["software_version"]["xend_config_format"]
}
sorted = info.items()
sorted.sort(lambda (x1,y1), (x2,y2): -cmp(x1,x2))
for (k, v) in sorted:
print "%-23s:" % k, v
else:
info = server.xend.node.info()
for x in info[1:]:
if len(x) < 2:
print "%-23s: (none)" % x[0]
else:
print "%-23s:" % x[0], x[1]
def xm_console(args):
arg_check(args, "console", 1, 2)
@@ -1308,13 +1454,17 @@ def xm_console(args):
dom = params[0]
try:
info = server.xend.domain(dom)
if serverType == SERVER_XEN_API:
domid = int(server.xenapi.VM.get_domid(get_single_vm(dom)))
else:
info = server.xend.domain(dom)
domid = int(sxp.child_value(info, 'domid', '-1'))
except:
if quiet:
sys.exit(1)
else:
raise
domid = int(sxp.child_value(info, 'domid', '-1'))
if domid == -1:
if quiet:
sys.exit(1)
@@ -1382,7 +1532,10 @@ def xm_sysrq(args):
arg_check(args, "sysrq", 2)
dom = args[0]
req = args[1]
server.xend.domain.send_sysrq(dom, req)
if serverType == SERVER_XEN_API:
server.xenapi.VM.send_sysrq(get_single_vm(dom), req)
else:
server.xend.domain.send_sysrq(dom, req)
def xm_trigger(args):
vcpu = 0
@@ -1392,8 +1545,23 @@ def xm_trigger(args):
trigger = args[1]
if len(args) == 3:
vcpu = int(args[2])
if serverType == SERVER_XEN_API:
server.xenapi.VM.send_trigger(get_single_vm(dom), trigger, vcpu)
else:
server.xend.domain.send_trigger(dom, trigger, vcpu)
def xm_debug_keys(args):
arg_check(args, "debug-keys", 1)
keys = str(args[0])
server.xend.domain.send_trigger(dom, trigger, vcpu)
if serverType == SERVER_XEN_API:
server.xenapi.host.send_debug_keys(
server.xenapi.session.get_this_host(),
keys)
else:
server.xend.node.send_debug_keys(keys)
def xm_top(args):
arg_check(args, "top", 0)
@@ -1418,17 +1586,33 @@ def xm_dmesg(args):
err("No parameter required")
usage('dmesg')
if not use_clear:
print server.xend.node.dmesg.info()
if serverType == SERVER_XEN_API:
if not use_clear:
print server.xenapi.host.dmesg(
server.xenapi.session.get_this_host(),0)
else:
server.xenapi.host.dmesg(
server.xenapi.session.get_this_host(),1)
else:
server.xend.node.dmesg.clear()
if not use_clear:
print server.xend.node.dmesg.info()
else:
server.xend.node.dmesg.clear()
def xm_log(args):
arg_check(args, "log", 0)
print server.xend.node.log()
if serverType == SERVER_XEN_API:
print server.xenapi.host.get_log(
server.xenapi.session.get_this_host())
else:
print server.xend.node.log()
def xm_serve(args):
if serverType == SERVER_XEN_API:
print "Not supported with XenAPI"
sys.exit(-1)
arg_check(args, "serve", 0)
from fcntl import fcntl, F_SETFL
@@ -1503,12 +1687,21 @@ def xm_network_list(args):
(use_long, params) = arg_check_for_resource_list(args, "network-list")
dom = params[0]
if use_long:
if serverType == SERVER_XEN_API:
vif_refs = server.xenapi.VM.get_VIFs(get_single_vm(dom))
vif_properties = \
map(server.xenapi.VIF.get_runtime_properties, vif_refs)
devs = map(lambda (handle, properties): [handle, map2sxp(properties)],
zip(range(len(vif_properties)), vif_properties))
else:
devs = server.xend.domain.getDeviceSxprs(dom, 'vif')
if use_long:
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
for x in server.xend.domain.getDeviceSxprs(dom, 'vif'):
for x in devs:
if hdr == 0:
print 'Idx BE MAC Addr. handle state evt-ch tx-/rx-ring-ref BE-path'
hdr = 1
@@ -1528,12 +1721,25 @@ def xm_block_list(args):
(use_long, params) = arg_check_for_resource_list(args, "block-list")
dom = params[0]
if use_long:
if serverType == SERVER_XEN_API:
vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
vbd_properties = \
map(server.xenapi.VBD.get_runtime_properties, vbd_refs)
vbd_devs = \
map(server.xenapi.VBD.get_device, vbd_refs)
vbd_devids = \
map(blkdev_name_to_number, vbd_devs)
devs = map(lambda (devid, prop): [devid, map2sxp(prop)],
zip(vbd_devids, vbd_properties))
else:
devs = server.xend.domain.getDeviceSxprs(dom, 'vbd')
if use_long:
map(PrettyPrint.prettyprint, devs)
else:
hdr = 0
for x in server.xend.domain.getDeviceSxprs(dom, 'vbd'):
for x in devs:
if hdr == 0:
print 'Vdev BE handle state evt-ch ring-ref BE-path'
hdr = 1
@@ -1588,13 +1794,17 @@ def parse_block_configuration(args):
if len(args) == 5:
vbd.append(['backend', args[4]])
# verify that policy permits attaching this resource
if security.on():
dominfo = server.xend.domain(dom)
label = security.get_security_printlabel(dominfo)
else:
label = None
security.res_security_check(args[1], label)
if serverType != SERVER_XEN_API:
# verify that policy permits attaching this resource
from xen.util import security
if security.on():
dominfo = server.xend.domain(dom)
label = security.get_security_printlabel(dominfo)
else:
label = None
security.res_security_check(args[1], label)
return (dom, vbd)
@@ -1602,8 +1812,45 @@ def parse_block_configuration(args):
def xm_block_attach(args):
arg_check(args, 'block-attach', 4, 5)
(dom, vbd) = parse_block_configuration(args)
server.xend.domain.device_create(dom, vbd)
if serverType == SERVER_XEN_API:
dom = args[0]
uname = args[1]
dev = args[2]
mode = args[3]
# First create new VDI
vdi_record = {
"name_label": "vdi" + str(uname.__hash__()),
"name_description": "",
"SR": get_default_SR(),
"virtual_size": 0,
"sector_size": 512,
"type": "system",
"sharable": False,
"read_only": mode!="w",
"other_config": {"location": uname}
}
vdi_ref = server.xenapi.VDI.create(vdi_record)
# Now create new VBD
vbd_record = {
"VM": get_single_vm(dom),
"VDI": vdi_ref,
"device": dev,
"bootable": True,
"mode": mode=="w" and "RW" or "RO",
"type": "Disk",
"qos_algorithm_type": "",
"qos_algorithm_params": {}
}
server.xenapi.VBD.create(vbd_record)
else:
(dom, vbd) = parse_block_configuration(args)
server.xend.domain.device_create(dom, vbd)
def xm_block_configure(args):
@@ -1621,15 +1868,65 @@ def xm_network_attach(args):
vif_params = ['type', 'mac', 'bridge', 'ip', 'script', \
'backend', 'vifname', 'rate', 'model']
for a in args[1:]:
vif_param = a.split("=")
if len(vif_param) != 2 or vif_param[1] == '' or \
vif_param[0] not in vif_params:
err("Invalid argument: %s" % a)
usage('network-attach')
vif.append(vif_param)
if serverType == SERVER_XEN_API:
vif_record = {
"device": "eth0",
"network": get_default_Network(),
"VM": get_single_vm(dom),
"MAC": "",
"MTU": "",
"qos_algorithm_type": "",
"qos_algorithm_params": {},
"other_config": {}
}
server.xend.domain.device_create(dom, vif)
def set(keys, val):
record = vif_record
for key in keys[:-1]:
record = record[key]
record[keys[-1]] = val
vif_conv = {
'type':
lambda x: None,
'mac':
lambda x: set(['MAC'], x),
'bridge':
lambda x: set(['network'], get_net_from_bridge(x)),
'ip':
lambda x: set(['other_config', 'ip'], x),
'script':
lambda x: set(['other_config', 'script'], x),
'backend':
lambda x: set(['other_config', 'backend'], x),
'vifname':
lambda x: set(['device'], x),
'rate':
lambda x: set(['qos_algorithm_params', 'rate'], x),
'model':
lambda x: None
}
for a in args[1:]:
vif_param = a.split("=")
if len(vif_param) != 2 or vif_param[1] == '' or \
vif_param[0] not in vif_params:
err("Invalid argument: %s" % a)
usage('network-attach')
else:
vif_conv[vif_param[0]](vif_param[1])
print str(vif_record)
server.xenapi.VIF.create(vif_record)
else:
for a in args[1:]:
vif_param = a.split("=")
if len(vif_param) != 2 or vif_param[1] == '' or \
vif_param[0] not in vif_params:
err("Invalid argument: %s" % a)
usage('network-attach')
vif.append(vif_param)
server.xend.domain.device_create(dom, vif)
def detach(args, command, deviceClass):
@@ -1649,16 +1946,49 @@ def detach(args, command, deviceClass):
def xm_block_detach(args):
try:
detach(args, 'block-detach', 'vbd')
return
except:
pass
detach(args, 'block-detach', 'tap')
if serverType == SERVER_XEN_API:
arg_check(args, "xm_block_detach", 2, 3)
dom = args[0]
dev = args[1]
vbd_refs = server.xenapi.VM.get_VBDs(get_single_vm(dom))
vbd_refs = [vbd_ref for vbd_ref in vbd_refs
if server.xenapi.VBD.get_device(vbd_ref) == dev]
if len(vbd_refs) > 0:
vbd_ref = vbd_refs[0]
vdi_ref = server.xenapi.VBD.get_VDI(vbd_ref)
server.xenapi.VBD.destroy(vbd_ref)
if len(server.xenapi.VDI.get_VBDs(vdi_ref)) <= 0:
server.xenapi.VDI.destroy(vdi_ref)
else:
raise OptionError("Cannot find device '%s' in domain '%s'"
% (dev,dom))
else:
try:
detach(args, 'block-detach', 'vbd')
return
except:
pass
detach(args, 'block-detach', 'tap')
def xm_network_detach(args):
detach(args, 'network-detach', 'vif')
if serverType == SERVER_XEN_API:
arg_check(args, "xm_block_detach", 2, 3)
dom = args[0]
devid = args[1]
vif_refs = server.xenapi.VM.get_VIFs(get_single_vm(dom))
vif_refs = [vif_ref for vif_ref in vif_refs
if server.xenapi.VIF.\
get_runtime_properties(vif_ref)["handle"] == devid]
if len(vif_refs) > 0:
vif_ref = vif_refs[0]
server.xenapi.VIF.destroy(vif_ref)
else:
print "Cannot find device '%s' in domain '%s'" % (devid,dom)
else:
detach(args, 'network-detach', 'vif')
def xm_vnet_list(args):
@@ -1738,6 +2068,7 @@ commands = {
"pause": xm_pause,
"unpause": xm_unpause,
# host commands
"debug-keys": xm_debug_keys,
"dmesg": xm_dmesg,
"info": xm_info,
"log": xm_log,
@@ -1881,7 +2212,7 @@ def _run_cmd(cmd, cmd_name, args):
err("Domain '%s' does not exist." % ex.faultString)
else:
err(ex.faultString)
_usage(cmd_name)
_usage(cmd_name)
except xmlrpclib.ProtocolError, ex:
if ex.errcode == -1:
print >>sys.stderr, (
@@ -1898,13 +2229,17 @@ def _run_cmd(cmd, cmd_name, args):
err(str(e))
_usage(cmd_name)
print e.usage
except security.ACMError, e:
err(str(e))
except:
print "Unexpected error:", sys.exc_info()[0]
print
print "Please report to xen-devel@lists.xensource.com"
raise
except Exception, e:
if serverType != SERVER_XEN_API:
from xen.util import security
if isinstance(e, security.ACMError):
err(str(e))
return False, 1
else:
print "Unexpected error:", sys.exc_info()[0]
print
print "Please report to xen-devel@lists.xensource.com"
raise
return False, 1
+4 -1
View File
@@ -19,7 +19,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Xen-xm 3.0\n"
"PO-Revision-Date: 2007-02-20 15:22+0000\n"
"PO-Revision-Date: 2007-03-10 23:17+0000\n"
"Last-Translator: Ewan Mellor <ewan@xensource.com>\n"
"Language-Team: xen-devel <xen-devel@lists.xensource.com>\n"
"MIME-Version: 1.0\n"
@@ -61,3 +61,6 @@ msgstr "The VLAN tag you gave (%(1)s) is invalid -- it must be between 0 and 409
msgid "VM_BAD_POWER_STATE"
msgstr "The VM must be %(2)s to perform the requested operation (it is currently %(3)s)."
msgid "VM_HVM_REQUIRED"
msgstr "HVM guest support is unavailable: is VT/AMD-V supported by your CPU and enabled in your BIOS?"
+12 -1
View File
@@ -22,6 +22,9 @@ from xen.xend import PrettyPrint
from xen.xend import sxp
from xen.xend import XendClient
from xen.xm.main import serverType, SERVER_XEN_API
from xen.xm.xenapi_create import *
from opts import *
from create import *
@@ -65,7 +68,15 @@ def main(argv):
if opts.vals.dryrun:
PrettyPrint.prettyprint(config)
else:
return
if serverType == SERVER_XEN_API:
sxp2xml_inst = sxp2xml()
doc = sxp2xml_inst.convert_sxp_to_xml(config)
xenapi_create_inst = xenapi_create()
vm_refs = xenapi_create_inst.create(document = doc)
else:
make_unstarted_domain(opts, config)
if __name__ == '__main__':
+30 -7
View File
@@ -21,7 +21,8 @@ import time
from xen.xend import sxp
from opts import *
from main import server
from main import server, serverType, SERVER_XEN_API, get_single_vm
from xen.xend.XendAPIConstants import *
gopts = Opts(use="""[options] [DOM]
@@ -49,6 +50,9 @@ gopts.opt('reboot', short='R',
use='Shutdown and reboot.')
def wait_reboot(opts, doms, rcs):
if serverType == SERVER_XEN_API:
opts.err("Cannot wait for reboot w/ XenAPI (yet)")
while doms:
alive = server.xend.domains(0)
reboot = []
@@ -68,7 +72,12 @@ def wait_reboot(opts, doms, rcs):
def wait_shutdown(opts, doms):
while doms:
alive = server.xend.domains(0)
if serverType == SERVER_XEN_API:
alive = [dom for dom in server.xenapi.VM.get_all()
if server.xenapi.VM.get_power_state(dom) ==
XEN_API_VM_POWER_STATE[XEN_API_VM_POWER_STATE_RUNNING]]
else:
alive = server.xend.domains(0)
dead = []
for d in doms:
if d in alive: continue
@@ -82,8 +91,16 @@ def wait_shutdown(opts, doms):
def shutdown(opts, doms, mode, wait):
rcs = {}
for d in doms:
rcs[d] = server.xend.domain.getRestartCount(d)
server.xend.domain.shutdown(d, mode)
if serverType == SERVER_XEN_API:
if mode == 'halt':
server.xenapi.VM.clean_shutdown(d)
if mode == 'reboot':
server.xenapi.VM.clean_reboot(d)
if mode == 'poweroff':
server.xenapi.VM.clean_shutdown(d)
else:
rcs[d] = server.xend.domain.getRestartCount(d)
server.xend.domain.shutdown(d, mode)
if wait:
if mode == 'reboot':
@@ -103,9 +120,13 @@ def shutdown_mode(opts):
return 'poweroff'
def main_all(opts, args):
doms = server.xend.domains(0)
dom0_name = sxp.child_value(server.xend.domain(0), 'name')
doms.remove(dom0_name)
if serverType == SERVER_XEN_API:
doms = [dom for dom in server.xenapi.VM.get_all()
if not server.xenapi.VM.get_is_control_domain(dom)]
else:
doms = server.xend.domains(0)
dom0_name = sxp.child_value(server.xend.domain(0), 'name')
doms.remove(dom0_name)
mode = shutdown_mode(opts)
shutdown(opts, doms, mode, opts.vals.wait)
@@ -113,6 +134,8 @@ def main_dom(opts, args):
if len(args) == 0: opts.err('No domain parameter given')
if len(args) > 1: opts.err('No multiple domain parameters allowed')
dom = args[0]
if serverType == SERVER_XEN_API:
dom = get_single_vm(dom)
mode = shutdown_mode(opts)
shutdown(opts, [ dom ], mode, opts.vals.wait)
+636
View File
@@ -0,0 +1,636 @@
#!/usr/bin/python
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2007 Tom Wilkie <tom.wilkie@gmail.com>
#============================================================================
"""Domain creation using new XenAPI
"""
from xen.xm.main import server, get_default_SR
from xml.dom.minidom import parse, getDOMImplementation
from xml.dom.ext import PrettyPrint
from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
from xen.xend import sxp
from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
XEN_API_ON_CRASH_BEHAVIOUR
import sys
import os
import traceback
def log(_, msg):
#print "> " + msg
pass
DEBUG = 0
def get_name_label(node):
name_node = node.getElementsByTagName("name")[0]
label_node = name_node.getElementsByTagName("label")[0]
return " ".join([child.nodeValue for child in label_node.childNodes])
def get_name_description(node):
name_node = node.getElementsByTagName("name")[0]
description_node = name_node.getElementsByTagName("description")[0]
return " ".join([child.nodeValue for child in description_node.childNodes])
def get_text_in_child_node(node, child):
tag_node = node.getElementsByTagName(child)[0]
return tag_node.nodeValue
def get_child_node_attribute(node, child, attribute):
tag_node = node.getElementsByTagName(child)[0]
return tag_node.attributes[attribute].value
def get_child_nodes_as_dict(node, child_name,
key_attribute_name,
value_attribute_name):
return dict([(child.attributes[key_attribute_name].value,
child.attributes[value_attribute_name].value)
for child in node.getElementsByTagName(child_name)])
def try_quietly(fn, *args):
try:
return fn(*args)
except:
return None
class xenapi_create:
def __init__(self):
self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
self.dtd = "/usr/lib/python/xen/xm/create.dtd"
def create(self, filename=None, document=None):
"""
Create a domain from an XML file or DOM tree
"""
if filename is not None:
self.check_dtd(file)
document = parse(file)
elif document is not None:
self.check_dom_against_dtd(document)
self.check_doc(document)
vdis = document.getElementsByTagName("vdi")
vdi_refs_dict = self.create_vdis(vdis)
try:
vms = document.getElementsByTagName("vm")
return self.create_vms(vms, vdi_refs_dict)
except Exception, exn:
try_quietly(self.cleanup_vdis(vdi_refs_dict))
raise exn
# Methods to check xml file
# try to use dtd to check where possible
def check_dtd(self, file):
"""
Check file against DTD.
Use this if possible as it gives nice
error messages
"""
dtd = xmldtd.load_dtd(self.dtd)
parser = xmlproc.XMLProcessor()
parser.set_application(xmlval.ValidatingApp(dtd, parser))
parser.dtd = dtd
parser.ent = dtd
parser.parse_resource(file)
def check_dom_against_dtd(self, dom):
"""
Check DOM again DTD.
Doesn't give as nice error messages.
(no location info)
"""
dtd = xmldtd.load_dtd(self.dtd)
app = xmlval.ValidatingApp(dtd, self)
app.set_locator(self)
self.dom2sax(dom, app)
# Get errors back from ValidatingApp
def report_error(self, number, args=None):
self.errors = xmlproc.errors.english
try:
msg = self.errors[number]
if args != None:
msg = msg % args
except KeyError:
msg = self.errors[4002] % number # Unknown err msg :-)
print msg
sys.exit(-1)
# Here for compatibility with ValidatingApp
def get_line(self):
return -1
def get_column(self):
return -1
def dom2sax(self, dom, app):
"""
Take a dom tree and tarverse it,
issuing SAX calls to app.
"""
for child in dom.childNodes:
if child.nodeType == child.TEXT_NODE:
data = child.nodeValue
app.handle_data(data, 0, len(data))
else:
app.handle_start_tag(
child.nodeName,
self.attrs_to_dict(child.attributes))
self.dom2sax(child, app)
app.handle_end_tag(child.nodeName)
def attrs_to_dict(self, attrs):
return dict(attrs.items())
#
# Checks which cannot be done with dtd
#
def check_doc(self, doc):
vms = doc.getElementsByTagName("vm")
self.check_vms(vms)
def check_vms(self, vms):
map(self.check_vm, vms)
def check_vm(self, vm):
vifs = vm.getElementsByTagName("vif")
self.check_vifs(vifs)
def check_vifs(self, vifs):
map(self.check_vif, vifs)
def check_vif(self, vif):
"""
Check that the vif has
either a bridge or network
name but not both
"""
if "bridge" in vif.attributes.keys() \
and "network" in vif.attributes.keys():
raise "You cannot specify both a bridge and\
a network name."
# Cleanup methods here
def cleanup_vdis(self, vdi_refs_dict):
map(self.cleanup_vdi, vdi_refs_dict.values())
def cleanup_vdi(self, vdi_ref):
server.xenapi.VDI.destroy(vdi_ref)
def cleanup_vms(self, vm_refs):
map(self.cleanup_vm, vm_refs)
def cleanup_vm(self, vm_ref):
server.xenapi.VM.destroy(vm_ref)
# Create methods here
def create_vdis(self, vdis):
log(DEBUG, "create_vdis")
return dict(map(self.create_vdi, vdis))
def create_vdi(self, vdi):
log(DEBUG, "create_vdi")
vdi_record = {
"name_label": get_name_label(vdi),
"name_description": get_name_description(vdi),
"SR": self.DEFAULT_STORAGE_REPOSITORY,
"virtual_size": vdi.attributes["size"].value,
"type": vdi.attributes["type"].value,
"shareable": vdi.attributes["shareable"].value,
"read_only": vdi.attributes["read_only"].value,
"other_config": {"location":
vdi.attributes["src"].value}
}
key = vdi.attributes["name"].value
value = server.xenapi.VDI.create(vdi_record)
return (key, value)
def create_vms(self, vms, vdis):
log(DEBUG, "create_vms")
return map(lambda vm: self.create_vm(vm, vdis), vms)
def create_vm(self, vm, vdis):
log(DEBUG, "create_vm")
vm_record = {
"name_label":
get_name_label(vm),
"name_description":
get_name_description(vm),
"user_version":
get_text_in_child_node(vm, "version"),
"is_a_template":
vm.attributes["is_a_template"].value,
"auto_power_on":
vm.attributes["auto_power_on"].value,
"memory_static_max":
get_child_node_attribute(vm, "memory", "static_max"),
"memory_static_min":
get_child_node_attribute(vm, "memory", "static_min"),
"memory_dynamic_max":
get_child_node_attribute(vm, "memory", "dynamic_max"),
"memory_dynamic_min":
get_child_node_attribute(vm, "memory", "dynamic_min"),
"vcpus_params":
get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
"vcpus_max":
vm.attributes["vcpus_max"].value,
"vcpus_at_startup":
vm.attributes["vcpus_at_startup"].value,
"actions_after_shutdown":
vm.attributes["actions_after_shutdown"].value,
"actions_after_reboot":
vm.attributes["actions_after_reboot"].value,
"actions_after_crash":
vm.attributes["actions_after_crash"].value,
"platform_std_VGA":
vm.attributes["platform_std_VGA"].value,
"platform_serial":
vm.attributes["platform_serial"].value,
"platform_localtime":
vm.attributes["platform_localtime"].value,
"platform_clock_offet":
vm.attributes["platform_clock_offet"].value,
"platform_enable_audio":
vm.attributes["platform_enable_audio"].value,
"PCI_bus":
vm.attributes["platform_enable_audio"].value,
"other_config":
get_child_nodes_as_dict(vm, "other_config", "key", "value")
}
if len(vm.getElementsByTagName("pv")) > 0:
vm_record.update({
"PV_bootloader":
get_child_node_attribute(vm, "pv", "bootloader"),
"PV_kernel":
get_child_node_attribute(vm, "pv", "kernel"),
"PV_ramdisk":
get_child_node_attribute(vm, "pv", "ramdisk"),
"PV_args":
get_child_node_attribute(vm, "pv", "args"),
"PV_bootloader_args":
get_child_node_attribute(vm, "pv", "bootloader_args")
})
else:
hvm = vm.getElementsByTagName("hvm")[0]
vm_record.update({
"HVM_boot_policy":
get_child_node_attribute(vm, "hvm", "boot_policy"),
"HVM_boot_params":
get_child_nodes_as_dict(hvm, "boot_params", "key", "value")
})
try:
vm_ref = server.xenapi.VM.create(vm_record)
except:
traceback.print_exc()
sys.exit(-1)
# Now create vbds
vbds = vm.getElementsByTagName("vbd")
self.create_vbds(vm_ref, vbds, vdis)
# Now create vifs
vifs = vm.getElementsByTagName("vif")
self.create_vifs(vm_ref, vifs)
return vm_ref
def create_vbds(self, vm_ref, vbds, vdis):
log(DEBUG, "create_vbds")
return map(lambda vbd: self.create_vbd(vm_ref, vbd, vdis), vbds)
def create_vbd(self, vm_ref, vbd, vdis):
log(DEBUG, "create_vbd")
vbd_record = {
"VM":
vm_ref,
"VDI":
vdis[vbd.attributes["vdi"].value],
"device":
vbd.attributes["device"].value,
"bootable":
vbd.attributes["bootable"].value,
"mode":
vbd.attributes["mode"].value,
"type":
vbd.attributes["type"].value,
"qos_algorithm_type":
vbd.attributes["qos_algorithm_type"].value,
"qos_algorithm_params":
get_child_nodes_as_dict(vbd,
"qos_algorithm_param", "key", "value")
}
return server.xenapi.VBD.create(vbd_record)
def create_vifs(self, vm_ref, vifs):
log(DEBUG, "create_vifs")
return map(lambda vif: self.create_vif(vm_ref, vif), vifs)
def create_vif(self, vm_ref, vif):
log(DEBUG, "create_vif")
if "bridge" in vif.attributes.keys():
raise "Not allowed to add by bridge just yet"
elif "network" in vif.attributes.keys():
network = [network_ref
for network_ref in server.xenapi.network.get_all()
if server.xenapi.network.get_name_label(network_ref)
== vif.attributes["network"].value][0]
else:
network = self._get_network_ref()
vif_record = {
"device":
vif.attributes["device"].value,
"network":
network,
"VM":
vm_ref,
"MAC":
vif.attributes["mac"].value,
"MTU":
vif.attributes["mtu"].value,
"qos_algorithm_type":
vif.attributes["qos_algorithm_type"].value,
"qos_algorithm_params":
get_child_nodes_as_dict(vif,
"qos_algorithm_param", "key", "value")
}
return server.xenapi.VIF.create(vif_record)
_network_refs = []
def _get_network_ref(self):
try:
return self._network_refs.pop(0)
except IndexError:
self._network_refs = server.xenapi.network.get_all()
return self._network_refs.pop(0)
def get_child_by_name(exp, childname, default = None):
try:
return [child for child in sxp.children(exp)
if child[0] == childname][0][1]
except:
return default
# Convert old sxp into new xml
class sxp2xml:
def convert_sxp_to_xml(self, config, transient=False):
devices = [child for child in sxp.children(config)
if len(child) > 0 and child[0] == "device"]
vbds_sxp = map(lambda x: x[1], [device for device in devices
if device[1][0] == "vbd"])
vifs_sxp = map(lambda x: x[1], [device for device in devices
if device[1][0] == "vif"])
# Create XML Document
impl = getDOMImplementation()
document = impl.createDocument(None, "xm", None)
# Lets make the VM tag..
vm = document.createElement("vm")
# Some string compatibility
actions_after_shutdown \
= get_child_by_name(config, "on_poweroff", "destroy")
actions_after_reboot \
= get_child_by_name(config, "on_reboot", "restart")
actions_after_crash \
= get_child_by_name(config, "on_crash", "restart")
def conv_chk(val, vals):
val.replace("-", "_")
if val not in vals:
raise "Invalid value: " + val
else:
return val
actions_after_shutdown = conv_chk(actions_after_shutdown,\
XEN_API_ON_NORMAL_EXIT)
actions_after_reboot = conv_chk(actions_after_reboot, \
XEN_API_ON_NORMAL_EXIT)
actions_after_crash = conv_chk(actions_after_crash, \
XEN_API_ON_CRASH_BEHAVIOUR)
# Flesh out tag attributes
vm.attributes["is_a_template"] = "false"
vm.attributes["auto_power_on"] = "false"
vm.attributes["actions_after_shutdown"] \
= actions_after_shutdown
vm.attributes["actions_after_reboot"] \
= actions_after_reboot
vm.attributes["actions_after_crash"] \
= actions_after_crash
vm.attributes["platform_std_VGA"] = "false"
vm.attributes["platform_serial"] = ""
vm.attributes["platform_localtime"] = ""
vm.attributes["platform_clock_offet"] = ""
vm.attributes["platform_enable_audio"] = ""
vm.attributes["PCI_bus"] = ""
vm.attributes["vcpus_max"] \
= str(get_child_by_name(config, "vcpus", 1))
vm.attributes["vcpus_at_startup"] \
= str(get_child_by_name(config, "vcpus", 1))
# Make the name tag
vm.appendChild(self.make_name_tag(
get_child_by_name(config, "name"), document))
# Make version tag
version = document.createElement("version")
version.appendChild(document.createTextNode("1.0"))
vm.appendChild(version)
# Make pv or hvm tag
image = get_child_by_name(config, "image")
if image[0] == "linux":
pv = document.createElement("pv")
pv.attributes["kernel"] \
= get_child_by_name(image, "kernel", "")
pv.attributes["bootloader"] = ""
pv.attributes["ramdisk"] \
= get_child_by_name(image, "ramdisk", "")
pv.attributes["args"] \
= "root=" + get_child_by_name(image, "root", "") \
+ " " + get_child_by_name(image, "args", "")
pv.attributes["bootloader_args"] = ""
vm.appendChild(pv)
elif image[0] == "hvm":
hvm = document.createElement("hvm")
hvm.attributes["boot_policy"] = ""
vm.appendChild(hvm)
# Make memory tag
memory = document.createElement("memory")
memory_str = str(int(
get_child_by_name(config, "memory"))*1024*1024)
memory.attributes["static_min"] = str(0)
memory.attributes["static_max"] = memory_str
memory.attributes["dynamic_min"] = memory_str
memory.attributes["dynamic_max"] = memory_str
if get_child_by_name(config, "maxmem"):
memory.attributes["static_max"] = \
str(int(get_child_by_name(config, "maxmem")*1024*1024))
vm.appendChild(memory)
# And now the vbds
vbds = map(lambda vbd: self.extract_vbd(vbd, document), vbds_sxp)
map(vm.appendChild, vbds)
# And now the vifs
vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
map(vm.appendChild, vifs)
# transient?
if transient:
other_config = document.createElement("other_config")
other_config.attributes["key"] = "transient"
other_config.attributes["value"] = "True"
vm.appendChild(other_config)
# Add it to doc_root
document.documentElement.appendChild(vm)
# We want to pull out vdis
vdis = map(lambda vdb: self.extract_vdi(vdb, document), vbds_sxp)
map(document.documentElement.appendChild, vdis)
return document
def make_name_tag(self, label_text, document):
name = document.createElement("name")
label = document.createElement("label")
label.appendChild(document.createTextNode(str(label_text)))
name.appendChild(label)
description = document.createElement("description")
description.appendChild(document.createTextNode(" "))
name.appendChild(description)
return name
def extract_vbd(self, vbd_sxp, document):
src = get_child_by_name(vbd_sxp, "uname")
name = str(src.__hash__())
vbd = document.createElement("vbd")
vbd.attributes["name"] = "vdb" + name
vbd.attributes["vdi"] = "vdi" + name
vbd.attributes["mode"] \
= get_child_by_name(vbd_sxp, "mode") != "w" \
and "RO" or "RW"
vbd.attributes["device"] \
= get_child_by_name(vbd_sxp, "dev")
vbd.attributes["bootable"] = "1"
vbd.attributes["type"] = "disk"
vbd.attributes["qos_algorithm_type"] = ""
return vbd
def extract_vdi(self, vbd_sxp, document):
src = get_child_by_name(vbd_sxp, "uname")
name = "vdi" + str(src.__hash__())
path = src[src.find(":")+1:]
vdi = document.createElement("vdi")
vdi.attributes["src"] = src
vdi.attributes["read_only"] \
= (get_child_by_name(vbd_sxp, "mode") != "w") \
and "true" or "false"
vdi.attributes["size"] \
= str(os.path.getsize(path))
vdi.attributes["type"] = "system"
vdi.attributes["shareable"] = "false"
vdi.attributes["name"] = name
vdi.appendChild(self.make_name_tag(name, document))
return vdi
def extract_vif(self, vif_sxp, document):
vif = document.createElement("vif")
dev = get_child_by_name(vif_sxp, "vifname", "eth0")
vif.attributes["name"] \
= "vif" + str(dev.__hash__())
vif.attributes["mac"] \
= get_child_by_name(vif_sxp, "mac", "")
vif.attributes["mtu"] \
= get_child_by_name(vif_sxp, "mtu", "")
vif.attributes["device"] = dev
vif.attributes["qos_algorithm_type"] = ""
if get_child_by_name(vif_sxp, "bridge") is not None:
vif.attributes["bridge"] \
= get_child_by_name(vif_sxp, "bridge")
return vif
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.