mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
merge with xen-unstable.hg
This commit is contained in:
commit
0741834153
91 files changed
+4911
-1694
No files matched your search
@@ -29,7 +29,7 @@
|
||||
#define PKG "xen.lowlevel.xc"
|
||||
#define CLS "xc"
|
||||
|
||||
static PyObject *xc_error, *zero;
|
||||
static PyObject *xc_error_obj, *zero;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD;
|
||||
@@ -40,6 +40,26 @@ typedef struct {
|
||||
static PyObject *dom_op(XcObject *self, PyObject *args,
|
||||
int (*fn)(int, uint32_t));
|
||||
|
||||
static PyObject *pyxc_error_to_exception(void)
|
||||
{
|
||||
PyObject *pyerr;
|
||||
const xc_error const *err = xc_get_last_error();
|
||||
const char *desc = xc_error_code_to_desc(err->code);
|
||||
|
||||
if (err->code == XC_ERROR_NONE)
|
||||
return PyErr_SetFromErrno(xc_error_obj);
|
||||
|
||||
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);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
|
||||
{
|
||||
@@ -53,7 +73,7 @@ static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -101,13 +121,13 @@ static PyObject *pyxc_domain_create(XcObject *self,
|
||||
|
||||
if ( (ret = xc_domain_create(self->xc_handle, ssidref,
|
||||
handle, flags, &dom)) < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
return PyInt_FromLong(dom);
|
||||
|
||||
out_exception:
|
||||
errno = EINVAL;
|
||||
PyErr_SetFromErrno(xc_error);
|
||||
PyErr_SetFromErrno(xc_error_obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -119,7 +139,7 @@ static PyObject *pyxc_domain_max_vcpus(XcObject *self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -164,7 +184,7 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
|
||||
}
|
||||
|
||||
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -184,7 +204,7 @@ static PyObject *pyxc_domain_setcpuweight(XcObject *self,
|
||||
return NULL;
|
||||
|
||||
if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -215,14 +235,13 @@ static PyObject *pyxc_domain_sethandle(XcObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
|
||||
out_exception:
|
||||
errno = EINVAL;
|
||||
PyErr_SetFromErrno(xc_error);
|
||||
PyErr_SetFromErrno(xc_error_obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -251,7 +270,7 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
|
||||
if (nr_doms < 0)
|
||||
{
|
||||
free(info);
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
}
|
||||
|
||||
list = PyList_New(nr_doms);
|
||||
@@ -306,10 +325,10 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self,
|
||||
|
||||
rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
|
||||
if ( rc < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
|
||||
if ( rc < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
|
||||
"online", info.online,
|
||||
@@ -360,9 +379,7 @@ static PyObject *pyxc_linux_build(XcObject *self,
|
||||
ramdisk, cmdline, features, flags,
|
||||
store_evtchn, &store_mfn,
|
||||
console_evtchn, &console_mfn) != 0 ) {
|
||||
if (!errno)
|
||||
errno = EINVAL;
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
}
|
||||
return Py_BuildValue("{s:i,s:i}",
|
||||
"store_mfn", store_mfn,
|
||||
@@ -396,7 +413,7 @@ static PyObject *pyxc_hvm_build(XcObject *self,
|
||||
xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_VCPUS, vcpus);
|
||||
#endif
|
||||
if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
#if !defined(__ia64__)
|
||||
/* Set up the HVM info table. */
|
||||
@@ -404,7 +421,7 @@ static PyObject *pyxc_hvm_build(XcObject *self,
|
||||
PROT_READ | PROT_WRITE,
|
||||
HVM_INFO_PFN);
|
||||
if ( va_map == NULL )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return PyErr_SetFromErrno(xc_error_obj);
|
||||
va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
|
||||
memset(va_hvm, 0, sizeof(*va_hvm));
|
||||
strncpy(va_hvm->signature, "HVM INFO", 8);
|
||||
@@ -442,7 +459,7 @@ static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
|
||||
return NULL;
|
||||
|
||||
if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
return PyInt_FromLong(port);
|
||||
}
|
||||
@@ -463,7 +480,7 @@ static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
|
||||
ret = xc_physdev_pci_access_modify(
|
||||
self->xc_handle, dom, bus, dev, func, enable);
|
||||
if ( ret != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -485,7 +502,7 @@ static PyObject *pyxc_readconsolering(XcObject *self,
|
||||
|
||||
ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
|
||||
if ( ret < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
return PyString_FromStringAndSize(str, count);
|
||||
}
|
||||
@@ -515,7 +532,7 @@ static PyObject *pyxc_physinfo(XcObject *self)
|
||||
int i;
|
||||
|
||||
if ( xc_physinfo(self->xc_handle, &info) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
*q=0;
|
||||
for(i=0;i<sizeof(info.hw_cap)/4;i++)
|
||||
@@ -553,25 +570,25 @@ static PyObject *pyxc_xeninfo(XcObject *self)
|
||||
xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
|
||||
|
||||
if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
|
||||
|
||||
xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
|
||||
if (xen_pagesize < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
|
||||
"xen_major", xen_version >> 16,
|
||||
@@ -604,7 +621,7 @@ static PyObject *pyxc_sedf_domain_set(XcObject *self,
|
||||
return NULL;
|
||||
if ( xc_sedf_domain_set(self->xc_handle, domid, period,
|
||||
slice, latency, extratime,weight) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -621,7 +638,7 @@ static PyObject *pyxc_sedf_domain_get(XcObject *self, PyObject *args)
|
||||
|
||||
if (xc_sedf_domain_get(self->xc_handle, domid, &period,
|
||||
&slice,&latency,&extratime,&weight))
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
|
||||
"domid", domid,
|
||||
@@ -649,7 +666,7 @@ static PyObject *pyxc_shadow_control(PyObject *self,
|
||||
|
||||
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
|
||||
< 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -679,7 +696,7 @@ static PyObject *pyxc_shadow_mem_control(PyObject *self,
|
||||
op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
|
||||
}
|
||||
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
mbarg = mb;
|
||||
return Py_BuildValue("i", mbarg);
|
||||
@@ -689,7 +706,7 @@ static PyObject *pyxc_sched_id_get(XcObject *self) {
|
||||
|
||||
int sched_id;
|
||||
if (xc_sched_id(self->xc_handle, &sched_id) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return PyErr_SetFromErrno(xc_error_obj);
|
||||
|
||||
return Py_BuildValue("i", sched_id);
|
||||
}
|
||||
@@ -715,7 +732,7 @@ static PyObject *pyxc_sched_credit_domain_set(XcObject *self,
|
||||
sdom.cap = cap;
|
||||
|
||||
if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -730,7 +747,7 @@ static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
return Py_BuildValue("{s:H,s:H}",
|
||||
"weight", sdom.weight,
|
||||
@@ -746,7 +763,22 @@ static PyObject *pyxc_domain_setmaxmem(XcObject *self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_domain_set_memmap_limit(XcObject *self, PyObject *args)
|
||||
{
|
||||
uint32_t dom;
|
||||
unsigned int maplimit_kb;
|
||||
|
||||
if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -773,7 +805,7 @@ static PyObject *pyxc_domain_memory_increase_reservation(XcObject *self,
|
||||
if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
|
||||
nr_extents, extent_order,
|
||||
address_bits, NULL) )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -795,7 +827,7 @@ static PyObject *pyxc_domain_ioport_permission(XcObject *self,
|
||||
ret = xc_domain_ioport_permission(
|
||||
self->xc_handle, dom, first_port, nr_ports, allow_access);
|
||||
if ( ret != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -818,7 +850,7 @@ static PyObject *pyxc_domain_irq_permission(PyObject *self,
|
||||
ret = xc_domain_irq_permission(
|
||||
xc->xc_handle, dom, pirq, allow_access);
|
||||
if ( ret != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -841,7 +873,7 @@ static PyObject *pyxc_domain_iomem_permission(PyObject *self,
|
||||
ret = xc_domain_iomem_permission(
|
||||
xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
|
||||
if ( ret != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -881,7 +913,7 @@ static PyObject *dom_op(XcObject *self, PyObject *args,
|
||||
return NULL;
|
||||
|
||||
if (fn(self->xc_handle, dom) != 0)
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
return pyxc_error_to_exception();
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
@@ -1135,6 +1167,14 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" maxmem_kb [int]: .\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "domain_set_memmap_limit",
|
||||
(PyCFunction)pyxc_domain_set_memmap_limit,
|
||||
METH_VARARGS, "\n"
|
||||
"Set a domain's physical memory mappping limit\n"
|
||||
" dom [int]: Identifier of domain.\n"
|
||||
" map_limitkb [int]: .\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "domain_memory_increase_reservation",
|
||||
(PyCFunction)pyxc_domain_memory_increase_reservation,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
@@ -1210,7 +1250,7 @@ static int
|
||||
PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
if ((self->xc_handle = xc_interface_open()) == -1) {
|
||||
PyErr_SetFromErrno(xc_error);
|
||||
pyxc_error_to_exception();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1283,7 +1323,7 @@ PyMODINIT_FUNC initxc(void)
|
||||
if (m == NULL)
|
||||
return;
|
||||
|
||||
xc_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
|
||||
xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
|
||||
zero = PyInt_FromLong(0);
|
||||
|
||||
/* KAF: This ensures that we get debug output in a timely manner. */
|
||||
@@ -1293,8 +1333,8 @@ PyMODINIT_FUNC initxc(void)
|
||||
Py_INCREF(&PyXcType);
|
||||
PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
|
||||
|
||||
Py_INCREF(xc_error);
|
||||
PyModule_AddObject(m, "Error", xc_error);
|
||||
Py_INCREF(xc_error_obj);
|
||||
PyModule_AddObject(m, "Error", xc_error_obj);
|
||||
|
||||
/* Expose some libxc constants to Python */
|
||||
PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);
|
||||
|
||||
@@ -264,7 +264,32 @@ class HttpServerRequest(http.HttpRequest):
|
||||
s += x + "/"
|
||||
self.write(' <a href="%s">%s</a>/' % (s, x))
|
||||
self.write("</h1>")
|
||||
|
||||
|
||||
class HttpServerClient:
|
||||
|
||||
def __init__(self, server, sock, addr):
|
||||
self.server = server
|
||||
self.sock = sock
|
||||
self.addr = addr
|
||||
|
||||
def process(self):
|
||||
thread = threading.Thread(target=self.doProcess)
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
|
||||
def doProcess(self):
|
||||
try:
|
||||
rp = RequestProcessor(self.server, self.sock, self.addr)
|
||||
rp.process()
|
||||
except SystemExit:
|
||||
raise
|
||||
except Exception, ex:
|
||||
print 'HttpServer>processRequest> exception: ', ex
|
||||
try:
|
||||
self.sock.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
class HttpServer:
|
||||
|
||||
backlog = 5
|
||||
@@ -286,8 +311,8 @@ class HttpServer:
|
||||
|
||||
while not self.closed:
|
||||
(sock, addr) = self.accept()
|
||||
self.processRequest(sock, addr)
|
||||
|
||||
cl = HttpServerClient(self, sock, addr)
|
||||
cl.process()
|
||||
|
||||
def stop(self):
|
||||
self.close()
|
||||
@@ -314,19 +339,6 @@ class HttpServer:
|
||||
except:
|
||||
pass
|
||||
|
||||
def processRequest(self, sock, addr):
|
||||
try:
|
||||
rp = RequestProcessor(self, sock, addr)
|
||||
rp.process()
|
||||
except SystemExit:
|
||||
raise
|
||||
except Exception, ex:
|
||||
print 'HttpServer>processRequest> exception: ', ex
|
||||
try:
|
||||
sock.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
def getServerAddr(self):
|
||||
return (socket.gethostname(), self.port)
|
||||
|
||||
|
||||
@@ -821,8 +821,9 @@ class XendAPI:
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_todo()
|
||||
|
||||
def VM_set_name_label(self, session, vm_ref):
|
||||
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()
|
||||
|
||||
def VM_set_name_description(self, session, vm_ref):
|
||||
@@ -1035,8 +1036,8 @@ class XendAPI:
|
||||
# regular xm created VBDs
|
||||
|
||||
VBD_attr_ro = ['image',
|
||||
'IO_bandwidth_incoming_kbs',
|
||||
'IO_bandwidth_outgoing_kbs']
|
||||
'io_read_kbs',
|
||||
'io_write_kbs']
|
||||
VBD_attr_rw = ['VM',
|
||||
'VDI',
|
||||
'device',
|
||||
@@ -1056,7 +1057,16 @@ class XendAPI:
|
||||
cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
|
||||
if not cfg:
|
||||
return xen_api_error(XEND_ERROR_VBD_INVALID)
|
||||
return xen_api_success(cfg)
|
||||
|
||||
valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
|
||||
self.Base_attr_ro + self.Base_attr_rw
|
||||
|
||||
return_cfg = {}
|
||||
for k in cfg.keys():
|
||||
if k in valid_vbd_keys:
|
||||
return_cfg[k] = cfg[k]
|
||||
|
||||
return xen_api_success(return_cfg)
|
||||
|
||||
def VBD_media_change(self, session, vbd_ref, vdi_ref):
|
||||
return xen_api_error(XEND_ERROR_UNSUPPORTED)
|
||||
@@ -1112,10 +1122,8 @@ class XendAPI:
|
||||
# Xen API: Class VIF
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
VIF_attr_ro = ['network_read_kbs',
|
||||
'network_write_kbs',
|
||||
'IO_bandwidth_incoming_kbs',
|
||||
'IO_bandwidth_outgoing_kbs']
|
||||
VIF_attr_ro = ['io_read_kbs',
|
||||
'io_write_kbs']
|
||||
VIF_attr_rw = ['name',
|
||||
'type',
|
||||
'device',
|
||||
@@ -1135,13 +1143,16 @@ class XendAPI:
|
||||
cfg = vm.get_dev_xenapi_config('vif', vif_ref)
|
||||
if not cfg:
|
||||
return xen_api_error(XEND_ERROR_VIF_INVALID)
|
||||
|
||||
valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
|
||||
self.Base_attr_ro + self.Base_attr_rw
|
||||
|
||||
return_cfg = {}
|
||||
for k in cfg.keys():
|
||||
if k not in valid_vif_keys:
|
||||
del cfg[k]
|
||||
if k in valid_vif_keys:
|
||||
return_cfg[k] = cfg[k]
|
||||
|
||||
return xen_api_success(cfg)
|
||||
return xen_api_success(return_cfg)
|
||||
|
||||
# class methods
|
||||
def VIF_create(self, session, vif_struct):
|
||||
|
||||
@@ -137,7 +137,6 @@ def restore(xd, fd, dominfo = None, paused = False):
|
||||
vmconfig = p.get_val()
|
||||
|
||||
if dominfo:
|
||||
dominfo.update(XendConfig(sxp_obj = vmconfig), refresh = False)
|
||||
dominfo.resume()
|
||||
else:
|
||||
dominfo = xd.restore_(vmconfig)
|
||||
|
||||
@@ -42,6 +42,39 @@ def reverse_dict(adict):
|
||||
def bool0(v):
|
||||
return v != '0' and bool(v)
|
||||
|
||||
# Recursively copy a data struct, scrubbing out VNC passwords.
|
||||
# Will scrub any dict entry with a key of 'vncpasswd' or any
|
||||
# 2-element list whose first member is 'vncpasswd'. It will
|
||||
# also scrub a string matching '(vncpasswd XYZ)'. Everything
|
||||
# else is no-op passthrough
|
||||
def scrub_password(data):
|
||||
if type(data) == dict or type(data) == XendConfig:
|
||||
scrubbed = {}
|
||||
for key in data.keys():
|
||||
if key == "vncpasswd":
|
||||
scrubbed[key] = "XXXXXXXX"
|
||||
else:
|
||||
scrubbed[key] = scrub_password(data[key])
|
||||
return scrubbed
|
||||
elif type(data) == list:
|
||||
if len(data) == 2 and type(data[0]) == str and data[0] == 'vncpasswd':
|
||||
return ['vncpasswd', 'XXXXXXXX']
|
||||
else:
|
||||
scrubbed = []
|
||||
for entry in data:
|
||||
scrubbed.append(scrub_password(entry))
|
||||
return scrubbed
|
||||
elif type(data) == tuple:
|
||||
scrubbed = []
|
||||
for entry in data:
|
||||
scrubbed.append(scrub_password(entry))
|
||||
return tuple(scrubbed)
|
||||
elif type(data) == str:
|
||||
return re.sub(r'\(vncpasswd\s+[^\)]+\)','(vncpasswd XXXXXX)', data)
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
# Mapping from XendConfig configuration keys to the old
|
||||
# legacy configuration keys that map directly.
|
||||
|
||||
@@ -269,7 +302,7 @@ class XendConfig(dict):
|
||||
# output from xc.domain_getinfo
|
||||
self._dominfo_to_xapi(dominfo)
|
||||
|
||||
log.debug('XendConfig.init: %s' % self)
|
||||
log.debug('XendConfig.init: %s' % scrub_password(self))
|
||||
|
||||
# validators go here
|
||||
self.validate()
|
||||
@@ -353,10 +386,15 @@ class XendConfig(dict):
|
||||
if self['builder'] not in ('hvm', 'linux'):
|
||||
raise XendConfigError('Invalid builder configuration')
|
||||
|
||||
def _vcpus_sanity_check(self):
|
||||
if self.get('vcpus_number') != None:
|
||||
self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
|
||||
|
||||
def validate(self):
|
||||
self._memory_sanity_check()
|
||||
self._actions_sanity_check()
|
||||
self._builder_sanity_check()
|
||||
self._vcpus_sanity_check()
|
||||
|
||||
def _dominfo_to_xapi(self, dominfo):
|
||||
self['domid'] = dominfo['domid']
|
||||
@@ -471,14 +509,8 @@ class XendConfig(dict):
|
||||
|
||||
log.debug("XendConfig: reading device: %s" % pci_devs)
|
||||
else:
|
||||
for opt, val in config[1:]:
|
||||
dev_info[opt] = val
|
||||
log.debug("XendConfig: reading device: %s" % dev_info)
|
||||
# create uuid if it doesn't
|
||||
dev_uuid = dev_info.get('uuid', uuid.createString())
|
||||
dev_info['uuid'] = dev_uuid
|
||||
cfg['devices'][dev_uuid] = (dev_type, dev_info)
|
||||
|
||||
self.device_add(dev_type, cfg_sxp = config, target = cfg)
|
||||
log.debug("XendConfig: reading device: %s" % scrub_password(dev_info))
|
||||
|
||||
# Extract missing data from configuration entries
|
||||
image_sxp = sxp.child_value(sxp_cfg, 'image', [])
|
||||
@@ -600,6 +632,9 @@ class XendConfig(dict):
|
||||
self['memory_dynamic_max'] = self['memory_static_max']
|
||||
self['memory_dynamic_min'] = self['memory_static_min']
|
||||
|
||||
# make sure max_vcpu_id is set correctly
|
||||
self['max_vcpu_id'] = self['vcpus_number'] - 1
|
||||
|
||||
# set device references in the configuration
|
||||
self['devices'] = cfg.get('devices', {})
|
||||
|
||||
@@ -675,13 +710,14 @@ class XendConfig(dict):
|
||||
else:
|
||||
self[sxp_arg] = val
|
||||
|
||||
_set_cfg_if_exists('bootloader')
|
||||
_set_cfg_if_exists('shadow_memory')
|
||||
_set_cfg_if_exists('security')
|
||||
_set_cfg_if_exists('features')
|
||||
_set_cfg_if_exists('on_xend_stop')
|
||||
_set_cfg_if_exists('on_xend_start')
|
||||
_set_cfg_if_exists('vcpu_avail')
|
||||
_set_cfg_if_exists('max_vcpu_id') # TODO, deprecated?
|
||||
_set_cfg_if_exists('max_vcpu_id') # needed for vcpuDomDetails
|
||||
|
||||
# Parse and store runtime configuration
|
||||
_set_cfg_if_exists('start_time')
|
||||
@@ -828,7 +864,8 @@ class XendConfig(dict):
|
||||
|
||||
return sxpr
|
||||
|
||||
def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
|
||||
def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None,
|
||||
target = None):
|
||||
"""Add a device configuration in SXP format or XenAPI struct format.
|
||||
|
||||
For SXP, it could be either:
|
||||
@@ -843,9 +880,14 @@ class XendConfig(dict):
|
||||
@param cfg_sxp: SXP configuration object
|
||||
@type cfg_xenapi: dict
|
||||
@param cfg_xenapi: A device configuration from Xen API (eg. vbd,vif)
|
||||
@param target: write device information to
|
||||
@type target: None or a dictionary
|
||||
@rtype: string
|
||||
@return: Assigned UUID of the device.
|
||||
"""
|
||||
if target == None:
|
||||
target = self
|
||||
|
||||
if dev_type not in XendDevices.valid_devices() and \
|
||||
dev_type not in XendDevices.pseudo_devices():
|
||||
raise XendConfigError("XendConfig: %s not a valid device type" %
|
||||
@@ -875,10 +917,12 @@ class XendConfig(dict):
|
||||
except ValueError:
|
||||
pass # SXP has no options for this device
|
||||
|
||||
|
||||
def _get_config_ipaddr(config):
|
||||
|
||||
# Special handling for certain device parameters.
|
||||
|
||||
def _get_config_ipaddr(cfg):
|
||||
val = []
|
||||
for ipaddr in sxp.children(config, elt='ip'):
|
||||
for ipaddr in sxp.children(cfg, elt='ip'):
|
||||
val.append(sxp.child0(ipaddr))
|
||||
return val
|
||||
|
||||
@@ -897,11 +941,18 @@ class XendConfig(dict):
|
||||
dev_info['uuid'] = dev_uuid
|
||||
|
||||
# store dev references by uuid for certain device types
|
||||
self['devices'][dev_uuid] = (dev_type, dev_info)
|
||||
target['devices'][dev_uuid] = (dev_type, dev_info)
|
||||
if dev_type in ('vif', 'vbd', 'vtpm'):
|
||||
self['%s_refs' % dev_type].append(dev_uuid)
|
||||
param = '%s_refs' % dev_type
|
||||
if param not in target:
|
||||
target[param] = []
|
||||
if dev_uuid not in target[param]:
|
||||
target[param].append(dev_uuid)
|
||||
elif dev_type in ('tap',):
|
||||
self['vbd_refs'].append(dev_uuid)
|
||||
if 'vbd_refs' not in target:
|
||||
target['vbd_refs'] = []
|
||||
if dev_uuid not in target['vbd_refs']:
|
||||
target['vbd_refs'].append(dev_uuid)
|
||||
|
||||
return dev_uuid
|
||||
|
||||
|
||||
@@ -641,17 +641,22 @@ class XendDomain:
|
||||
return (self.get_vm_with_dev_uuid(klass, dev_uuid) != None)
|
||||
|
||||
def do_legacy_api_with_uuid(self, fn, vm_uuid, *args, **kwargs):
|
||||
dom = self.uuid_to_dom(vm_uuid)
|
||||
fn(dom, *args, **kwargs)
|
||||
|
||||
def uuid_to_dom(self, vm_uuid):
|
||||
self.domains_lock.acquire()
|
||||
try:
|
||||
for domid, dom in self.domains.items():
|
||||
if dom.get_uuid == vm_uuid:
|
||||
return fn(domid, *args, **kwargs)
|
||||
if dom.get_uuid() == vm_uuid:
|
||||
return domid
|
||||
|
||||
if vm_uuid in self.managed_domains:
|
||||
domid = self.managed_domains[vm_uuid].getDomid()
|
||||
if domid == None:
|
||||
domid = self.managed_domains[vm_uuid].getName()
|
||||
return fn(domid, *args, **kwargs)
|
||||
if domid is None:
|
||||
return self.managed_domains[vm_uuid].getName()
|
||||
else:
|
||||
return domid
|
||||
|
||||
raise XendInvalidDomain("Domain does not exist")
|
||||
finally:
|
||||
@@ -808,7 +813,7 @@ class XendDomain:
|
||||
raise XendError("Cannot save privileged domain %s" % domname)
|
||||
|
||||
if dominfo.state != DOM_STATE_HALTED:
|
||||
raise XendError("Cannot suspend domain that is not running.")
|
||||
raise XendError("Cannot resume domain that is not halted.")
|
||||
|
||||
dom_uuid = dominfo.get_uuid()
|
||||
chkpath = self._managed_check_point_path(dom_uuid)
|
||||
|
||||
@@ -40,6 +40,7 @@ from xen.util import security
|
||||
from xen.xend import balloon, sxp, uuid, image, arch
|
||||
from xen.xend import XendRoot, XendNode, XendConfig
|
||||
|
||||
from xen.xend.XendConfig import scrub_password
|
||||
from xen.xend.XendBootloader import bootloader
|
||||
from xen.xend.XendError import XendError, VmError
|
||||
from xen.xend.XendDevices import XendDevices
|
||||
@@ -148,7 +149,7 @@ def create(config):
|
||||
@raise VmError: Invalid configuration or failure to start.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.create(%s)", config)
|
||||
log.debug("XendDomainInfo.create(%s)", scrub_password(config))
|
||||
vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
|
||||
try:
|
||||
vm.start()
|
||||
@@ -175,7 +176,7 @@ def recreate(info, priv):
|
||||
@raise XendError: Errors with configuration.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.recreate(%s)", info)
|
||||
log.debug("XendDomainInfo.recreate(%s)", scrub_password(info))
|
||||
|
||||
assert not info['dying']
|
||||
|
||||
@@ -257,7 +258,7 @@ def restore(config):
|
||||
@raise XendError: Errors with configuration.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.restore(%s)", config)
|
||||
log.debug("XendDomainInfo.restore(%s)", scrub_password(config))
|
||||
vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
|
||||
resume = True)
|
||||
try:
|
||||
@@ -280,7 +281,7 @@ def createDormant(domconfig):
|
||||
@raise XendError: Errors with configuration.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.createDormant(%s)", domconfig)
|
||||
log.debug("XendDomainInfo.createDormant(%s)", scrub_password(domconfig))
|
||||
|
||||
# domid does not make sense for non-running domains.
|
||||
domconfig.pop('domid', None)
|
||||
@@ -520,11 +521,11 @@ class XendDomainInfo:
|
||||
@param dev_config: device configuration
|
||||
@type dev_config: SXP object (parsed config)
|
||||
"""
|
||||
log.debug("XendDomainInfo.device_create: %s" % dev_config)
|
||||
log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config))
|
||||
dev_type = sxp.name(dev_config)
|
||||
dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
|
||||
dev_config_dict = self.info['devices'][dev_uuid][1]
|
||||
log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
|
||||
log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config_dict))
|
||||
devid = self._createDevice(dev_type, dev_config_dict)
|
||||
self._waitForDevice(dev_type, devid)
|
||||
return self.getDeviceController(dev_type).sxpr(devid)
|
||||
@@ -746,7 +747,7 @@ class XendDomainInfo:
|
||||
|
||||
to_store.update(self._vcpuDomDetails())
|
||||
|
||||
log.debug("Storing domain details: %s", to_store)
|
||||
log.debug("Storing domain details: %s", scrub_password(to_store))
|
||||
|
||||
self._writeDom(to_store)
|
||||
|
||||
@@ -875,10 +876,18 @@ class XendDomainInfo:
|
||||
|
||||
def setVCpuCount(self, vcpus):
|
||||
self.info['vcpu_avail'] = (1 << vcpus) - 1
|
||||
self.info['vcpus_number'] = vcpus
|
||||
self.storeVm('vcpu_avail', self.info['vcpu_avail'])
|
||||
self.storeVm('vcpus', self.info['vcpus_number'])
|
||||
self._writeDom(self._vcpuDomDetails())
|
||||
# update dom differently depending on whether we are adjusting
|
||||
# vcpu number up or down, otherwise _vcpuDomDetails does not
|
||||
# disable the vcpus
|
||||
if self.info['vcpus_number'] > vcpus:
|
||||
# decreasing
|
||||
self._writeDom(self._vcpuDomDetails())
|
||||
self.info['vcpus_number'] = vcpus
|
||||
else:
|
||||
# same or increasing
|
||||
self.info['vcpus_number'] = vcpus
|
||||
self._writeDom(self._vcpuDomDetails())
|
||||
|
||||
def getLabel(self):
|
||||
return security.get_security_info(self.info, 'label')
|
||||
@@ -1188,7 +1197,7 @@ class XendDomainInfo:
|
||||
"""
|
||||
for (devclass, config) in self.info.get('devices', {}).values():
|
||||
if devclass in XendDevices.valid_devices():
|
||||
log.info("createDevice: %s : %s" % (devclass, config))
|
||||
log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
|
||||
self._createDevice(devclass, config)
|
||||
|
||||
if self.image:
|
||||
@@ -1326,7 +1335,7 @@ class XendDomainInfo:
|
||||
|
||||
# if we have a boot loader but no image, then we need to set things
|
||||
# up by running the boot loader non-interactively
|
||||
if self.info.get('bootloader') and self.info.get('image'):
|
||||
if self.info.get('bootloader'):
|
||||
self._configureBootloader()
|
||||
|
||||
if not self._infoIsSet('image'):
|
||||
@@ -1532,11 +1541,17 @@ class XendDomainInfo:
|
||||
if not self.info.get('bootloader'):
|
||||
return
|
||||
blcfg = None
|
||||
|
||||
# FIXME: this assumes that we want to use the first disk device
|
||||
for devuuid, (devtype, devinfo) in self.info.all_devices_sxpr():
|
||||
for (devtype, devinfo) in self.info.all_devices_sxpr():
|
||||
if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
|
||||
continue
|
||||
disk = devinfo.get('uname')
|
||||
disk = None
|
||||
for param in devinfo:
|
||||
if param[0] == 'uname':
|
||||
disk = param[1]
|
||||
break
|
||||
|
||||
if disk is None:
|
||||
continue
|
||||
fn = blkdev_uname_to_file(disk)
|
||||
@@ -1661,7 +1676,7 @@ class XendDomainInfo:
|
||||
if not self._readVm('xend/restart_count'):
|
||||
to_store['xend/restart_count'] = str(0)
|
||||
|
||||
log.debug("Storing VM details: %s", to_store)
|
||||
log.debug("Storing VM details: %s", scrub_password(to_store))
|
||||
|
||||
self._writeVm(to_store)
|
||||
self._setVmPermissions()
|
||||
@@ -1773,13 +1788,13 @@ class XendDomainInfo:
|
||||
return dom_uuid
|
||||
|
||||
def get_memory_static_max(self):
|
||||
return self.info.get('memory_static_max')
|
||||
return self.info.get('memory_static_max', 0)
|
||||
def get_memory_static_min(self):
|
||||
return self.info.get('memory_static_min')
|
||||
return self.info.get('memory_static_min', 0)
|
||||
def get_memory_dynamic_max(self):
|
||||
return self.info.get('memory_dynamic_min')
|
||||
return self.info.get('memory_dynamic_max', 0)
|
||||
def get_memory_dynamic_min(self):
|
||||
return self.info.get('memory_dynamic_max')
|
||||
return self.info.get('memory_dynamic_min', 0)
|
||||
|
||||
|
||||
def get_vcpus_policy(self):
|
||||
@@ -1813,7 +1828,7 @@ class XendDomainInfo:
|
||||
def get_builder(self):
|
||||
return self.info.get('builder', 0)
|
||||
def get_boot_method(self):
|
||||
return self.info.get('boot_method', '')
|
||||
return self.info.get('boot_method', XEN_API_BOOT_TYPE[2])
|
||||
def get_kernel_image(self):
|
||||
return self.info.get('kernel_kernel', '')
|
||||
def get_kernel_initrd(self):
|
||||
@@ -1823,7 +1838,7 @@ class XendDomainInfo:
|
||||
def get_grub_cmdline(self):
|
||||
return '' # TODO
|
||||
def get_pci_bus(self):
|
||||
return 0 # TODO
|
||||
return '' # TODO
|
||||
def get_tools_version(self):
|
||||
return {} # TODO
|
||||
def get_other_config(self):
|
||||
@@ -1918,18 +1933,16 @@ class XendDomainInfo:
|
||||
|
||||
config['network'] = '' # Invalid for Xend
|
||||
config['MTU'] = 1500 # TODO
|
||||
config['network_read_kbs'] = 0.0
|
||||
config['network_write_kbs'] = 0.0
|
||||
config['IO_bandwidth_incoming_kbs'] = 0.0
|
||||
config['IO_bandwidth_outgoing_kbs'] = 0.0
|
||||
config['io_read_kbs'] = 0.0
|
||||
config['io_write_kbs'] = 0.0
|
||||
|
||||
if dev_class == 'vbd':
|
||||
config['VDI'] = '' # TODO
|
||||
config['VDI'] = config.get('VDI', '')
|
||||
config['device'] = config.get('dev', '')
|
||||
config['driver'] = 'paravirtualised' # TODO
|
||||
config['image'] = config.get('uname', '')
|
||||
config['IO_bandwidth_incoming_kbs'] = 0.0
|
||||
config['IO_bandwidth_outgoing_kbs'] = 0.0
|
||||
config['io_read_kbs'] = 0.0
|
||||
config['io_write_kbs'] = 0.0
|
||||
if config['mode'] == 'r':
|
||||
config['mode'] = 'RO'
|
||||
else:
|
||||
@@ -2043,27 +2056,7 @@ class XendDomainInfo:
|
||||
return dev_uuid
|
||||
|
||||
def has_device(self, dev_class, dev_uuid):
|
||||
return (dev_uuid in self.info['%s_refs' % dev_class])
|
||||
|
||||
"""
|
||||
def stateChar(name):
|
||||
if name in self.info:
|
||||
if self.info[name]:
|
||||
return name[0]
|
||||
else:
|
||||
return '-'
|
||||
else:
|
||||
return '?'
|
||||
|
||||
state = reduce(lambda x, y: x + y, map(stateChar, DOM_STATES_OLD))
|
||||
|
||||
sxpr.append(['state', state])
|
||||
|
||||
if self.store_mfn:
|
||||
sxpr.append(['store_mfn', self.store_mfn])
|
||||
if self.console_mfn:
|
||||
sxpr.append(['console_mfn', self.console_mfn])
|
||||
"""
|
||||
return (dev_uuid in self.info['%s_refs' % dev_class.lower()])
|
||||
|
||||
def __str__(self):
|
||||
return '<domain id=%s name=%s memory=%s state=%s>' % \
|
||||
|
||||
@@ -338,7 +338,7 @@ class HVMImageHandler(ImageHandler):
|
||||
|
||||
for devuuid, (devtype, devinfo) in deviceConfig.items():
|
||||
if devtype == 'vbd':
|
||||
uname = devinfo['uname']
|
||||
uname = devinfo.get('uname')
|
||||
if uname is not None and 'file:' in uname:
|
||||
(_, vbdparam) = string.split(uname, ':', 1)
|
||||
if not os.path.isfile(vbdparam):
|
||||
@@ -548,6 +548,14 @@ class X86_HVM_ImageHandler(HVMImageHandler):
|
||||
return max(4 * (256 * self.vm.getVCpuCount() + 2 * (maxmem_kb / 1024)),
|
||||
shadow_mem_kb)
|
||||
|
||||
class X86_Linux_ImageHandler(LinuxImageHandler):
|
||||
|
||||
def buildDomain(self):
|
||||
# set physical mapping limit
|
||||
# add an 8MB slack to balance backend allocations.
|
||||
mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
|
||||
xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
|
||||
return LinuxImageHandler.buildDomain(self)
|
||||
|
||||
_handlers = {
|
||||
"powerpc": {
|
||||
@@ -558,7 +566,7 @@ _handlers = {
|
||||
"hvm": IA64_HVM_ImageHandler,
|
||||
},
|
||||
"x86": {
|
||||
"linux": LinuxImageHandler,
|
||||
"linux": X86_Linux_ImageHandler,
|
||||
"hvm": X86_HVM_ImageHandler,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -226,9 +226,11 @@ class DevController:
|
||||
for key, val in configDict.items():
|
||||
if isinstance(val, (types.ListType, types.TupleType)):
|
||||
for v in val:
|
||||
sxpr.append([key, v])
|
||||
if v != None:
|
||||
sxpr.append([key, v])
|
||||
else:
|
||||
sxpr.append([key, val])
|
||||
if val != None:
|
||||
sxpr.append([key, val])
|
||||
return sxpr
|
||||
|
||||
def sxprs(self):
|
||||
|
||||
@@ -278,6 +278,8 @@ class Daemon:
|
||||
modulename = m.group(1)
|
||||
if re.search('sxp.py', modulename):
|
||||
return None
|
||||
if re.search('SrvServer.py', modulename):
|
||||
return None
|
||||
self.traceindent += 1
|
||||
self.print_trace("> %s:%s\n"
|
||||
% (modulename, code.co_name))
|
||||
|
||||
@@ -21,6 +21,7 @@ from xen.web import http
|
||||
from xen.xend import sxp
|
||||
from xen.xend import XendDomain
|
||||
from xen.xend.Args import FormFn
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
from xen.web.SrvDir import SrvDir
|
||||
|
||||
@@ -63,6 +64,18 @@ class SrvDomain(SrvDir):
|
||||
self.acceptCommand(req)
|
||||
return self.dom.shutdown(req.args['reason'][0])
|
||||
|
||||
def op_delete(self, _, req):
|
||||
self.acceptCommand(req)
|
||||
return self.xd.domain_delete(self.dom.getName())
|
||||
|
||||
def op_start(self, _, req):
|
||||
self.acceptCommand(req)
|
||||
paused = False
|
||||
if 'paused' in req.args and req.args['paused'] == [1]:
|
||||
paused = True
|
||||
log.debug("Starting domain " + self.dom.getName() + " " + str(paused))
|
||||
return self.xd.domain_start(self.dom.getName(), paused)
|
||||
|
||||
def op_sysrq(self, _, req):
|
||||
self.acceptCommand(req)
|
||||
return self.dom.send_sysrq(int(req.args['key'][0]))
|
||||
|
||||
@@ -25,6 +25,8 @@ from xen.xend import XendDomain
|
||||
from xen.xend.XendDomainInfo import XendDomainInfo
|
||||
from xen.xend.Args import FormFn
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendConstants import DOM_STATE_RUNNING
|
||||
|
||||
from xen.web.SrvDir import SrvDir
|
||||
from SrvDomain import SrvDomain
|
||||
@@ -101,6 +103,35 @@ class SrvDomainDir(SrvDir):
|
||||
out.close()
|
||||
return val
|
||||
|
||||
def op_new(self, _, req):
|
||||
"""Define a new domain.
|
||||
Expects the domain config in request parameter 'config' in SXP format.
|
||||
"""
|
||||
ok = 0
|
||||
errmsg = ''
|
||||
try:
|
||||
configstring = req.args.get('config')[0]
|
||||
#print 'op_create>', 'config:', configstring
|
||||
pin = sxp.Parser()
|
||||
pin.input(configstring)
|
||||
pin.input_eof()
|
||||
config = pin.get_val()
|
||||
ok = 1
|
||||
except sxp.ParseError, ex:
|
||||
errmsg = 'Invalid configuration ' + str(ex)
|
||||
except Exception, ex:
|
||||
print 'op_create> Exception in config', ex
|
||||
traceback.print_exc()
|
||||
errmsg = 'Configuration error ' + str(ex)
|
||||
if not ok:
|
||||
raise XendError(errmsg)
|
||||
try:
|
||||
self.xd.domain_new(config)
|
||||
except Exception, ex:
|
||||
print 'op_create> Exception creating domain:'
|
||||
traceback.print_exc()
|
||||
raise XendError("Error creating domain: " + str(ex))
|
||||
|
||||
def op_restore(self, op, req):
|
||||
"""Restore a domain from file.
|
||||
|
||||
@@ -159,16 +190,19 @@ class SrvDomainDir(SrvDir):
|
||||
if detail:
|
||||
sxp.show(map(XendDomainInfo.sxpr, self.xd.list()), out=req)
|
||||
else:
|
||||
sxp.show(self.xd.list_names(), out=req)
|
||||
state = DOM_STATE_RUNNING
|
||||
if 'state' in req.args and len(req.args['state']) > 0:
|
||||
state = req.args['state'][0]
|
||||
log.debug("Listing domains in state " + str(state))
|
||||
sxp.show(self.xd.list_names(state), out=req)
|
||||
else:
|
||||
domains = self.xd.list_sorted()
|
||||
req.write('<ul>')
|
||||
for d in domains:
|
||||
req.write(
|
||||
'<li><a href="%s%s">Domain %s</a>: id = %s, memory = %d, '
|
||||
'ssidref = %d.'
|
||||
'<li><a href="%s%s">Domain %s</a>: id = %s, memory = %d'
|
||||
% (url, d.getName(), d.getName(), d.getDomid(),
|
||||
d.getMemoryTarget(), d.getSsidref()))
|
||||
d.getMemoryTarget()))
|
||||
req.write('</li>')
|
||||
req.write('</ul>')
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@ xroot = XendRoot.instance()
|
||||
|
||||
class XendServers:
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, root):
|
||||
self.servers = []
|
||||
self.root = root
|
||||
self.cleaningUp = False
|
||||
self.reloadingConfig = False
|
||||
|
||||
@@ -101,6 +102,9 @@ class XendServers:
|
||||
while True:
|
||||
threads = []
|
||||
for server in self.servers:
|
||||
if server.ready:
|
||||
continue
|
||||
|
||||
thread = Thread(target=server.run, name=server.__class__.__name__)
|
||||
if isinstance(server, HttpServer):
|
||||
thread.setDaemon(True)
|
||||
@@ -156,21 +160,23 @@ class XendServers:
|
||||
pass
|
||||
|
||||
if self.reloadingConfig:
|
||||
log.info("Restarting all servers...")
|
||||
log.info("Restarting all XML-RPC and Xen-API servers...")
|
||||
self.cleaningUp = False
|
||||
self.reloadingConfig = False
|
||||
xroot.set_config()
|
||||
self.servers = []
|
||||
_loadConfig(self)
|
||||
new_servers = [x for x in self.servers
|
||||
if isinstance(x, HttpServer)]
|
||||
self.servers = new_servers
|
||||
_loadConfig(self, self.root, True)
|
||||
else:
|
||||
break
|
||||
|
||||
def _loadConfig(servers):
|
||||
if xroot.get_xend_http_server():
|
||||
def _loadConfig(servers, root, reload):
|
||||
if not reload and xroot.get_xend_http_server():
|
||||
servers.add(HttpServer(root,
|
||||
xroot.get_xend_address(),
|
||||
xroot.get_xend_port()))
|
||||
if xroot.get_xend_unix_server():
|
||||
if not reload and xroot.get_xend_unix_server():
|
||||
path = xroot.get_xend_unix_path()
|
||||
log.info('unix path=' + path)
|
||||
servers.add(UnixHttpServer(root, path))
|
||||
@@ -218,6 +224,6 @@ def _loadConfig(servers):
|
||||
def create():
|
||||
root = SrvDir()
|
||||
root.putChild('xend', SrvRoot())
|
||||
servers = XendServers()
|
||||
_loadConfig(servers)
|
||||
servers = XendServers(root)
|
||||
_loadConfig(servers, root, False)
|
||||
return servers
|
||||
@@ -124,6 +124,8 @@ class BlkifController(DevController):
|
||||
config['dev'] = dev
|
||||
if typ and params:
|
||||
config['uname'] = typ +':' + params
|
||||
else:
|
||||
config['uname'] = None
|
||||
if mode:
|
||||
config['mode'] = mode
|
||||
if uuid:
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
#============================================================================
|
||||
# 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 XenSource Inc.
|
||||
#============================================================================
|
||||
#
|
||||
# Parts of this file are based upon xmlrpclib.py, the XML-RPC client
|
||||
# interface included in the Python distribution.
|
||||
#
|
||||
# Copyright (c) 1999-2002 by Secret Labs AB
|
||||
# Copyright (c) 1999-2002 by Fredrik Lundh
|
||||
#
|
||||
# By obtaining, using, and/or copying this software and/or its
|
||||
# associated documentation, you agree that you have read, understood,
|
||||
# and will comply with the following terms and conditions:
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and
|
||||
# its associated documentation for any purpose and without fee is
|
||||
# hereby granted, provided that the above copyright notice appears in
|
||||
# all copies, and that both that copyright notice and this permission
|
||||
# notice appear in supporting documentation, and that the name of
|
||||
# Secret Labs AB or the author not be used in advertising or publicity
|
||||
# pertaining to distribution of the software without specific, written
|
||||
# prior permission.
|
||||
#
|
||||
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
|
||||
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
|
||||
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
|
||||
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
||||
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
# OF THIS SOFTWARE.
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
import xmlrpclib
|
||||
|
||||
import xen.util.xmlrpclib2
|
||||
|
||||
|
||||
class Failure(Exception):
|
||||
def __init__(self, details):
|
||||
self.details = details
|
||||
|
||||
def __str__(self):
|
||||
return "Xen-API failure: %s" % str(self.details)
|
||||
|
||||
|
||||
class Session(xen.util.xmlrpclib2.ServerProxy):
|
||||
"""A server proxy and session manager for communicating with Xend using
|
||||
the Xen-API.
|
||||
|
||||
Example:
|
||||
|
||||
session = Session('http://localhost:9363/')
|
||||
session.login_with_password('me', 'mypassword')
|
||||
session.xenapi.VM.start(vm_uuid)
|
||||
session.xenapi.session.logout()
|
||||
|
||||
For now, this class also supports the legacy XML-RPC API, using
|
||||
session.xend.domain('Domain-0') and similar. This support will disappear
|
||||
once there is a working Xen-API replacement for every call in the legacy
|
||||
API.
|
||||
"""
|
||||
|
||||
def __init__(self, uri, transport=None, encoding=None, verbose=0,
|
||||
allow_none=1):
|
||||
xen.util.xmlrpclib2.ServerProxy.__init__(self, uri, transport,
|
||||
encoding, verbose,
|
||||
allow_none)
|
||||
self._session = None
|
||||
|
||||
|
||||
def _xen_request(self, methodname, params):
|
||||
full_params = (self._session,) + params
|
||||
return _parse_result(getattr(self, methodname)(*full_params))
|
||||
|
||||
|
||||
def _login(self, method, username, password):
|
||||
self._session = _parse_result(
|
||||
getattr(self, 'session.%s' % method)(username, password))
|
||||
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'xenapi':
|
||||
return _Dispatcher(self._xen_request, None)
|
||||
elif name.startswith('login'):
|
||||
return lambda u, p: self._login(name, u, p)
|
||||
else:
|
||||
return xen.util.xmlrpclib2.ServerProxy.__getattr__(self, name)
|
||||
|
||||
|
||||
def _parse_result(result):
|
||||
if 'Status' not in result:
|
||||
raise xmlrpclib.Fault(500, 'Missing Status in response from server')
|
||||
if result['Status'] == 'Success':
|
||||
if 'Value' in result:
|
||||
return result['Value']
|
||||
else:
|
||||
raise xmlrpclib.Fault(500,
|
||||
'Missing Value in response from server')
|
||||
else:
|
||||
if 'ErrorDescription' in result:
|
||||
raise Failure(result['ErrorDescription'])
|
||||
else:
|
||||
raise xmlrpclib.Fault(
|
||||
500, 'Missing ErrorDescription in response from server')
|
||||
|
||||
|
||||
# Based upon _Method from xmlrpclib.
|
||||
class _Dispatcher:
|
||||
def __init__(self, send, name):
|
||||
self.__send = send
|
||||
self.__name = name
|
||||
def __getattr__(self, name):
|
||||
if self.__name is None:
|
||||
return _Dispatcher(self.__send, name)
|
||||
else:
|
||||
return _Dispatcher(self.__send, "%s.%s" % (self.__name, name))
|
||||
def __call__(self, *args):
|
||||
return self.__send(self.__name, args)
|
||||
@@ -29,13 +29,13 @@ import xmlrpclib
|
||||
from xen.xend import sxp
|
||||
from xen.xend import PrettyPrint
|
||||
import xen.xend.XendClient
|
||||
from xen.xend.XendClient import server
|
||||
from xen.xend.XendBootloader import bootloader
|
||||
from xen.util import blkif
|
||||
from xen.util import security
|
||||
|
||||
from xen.xm.opts import *
|
||||
|
||||
from main import server
|
||||
import console
|
||||
|
||||
|
||||
@@ -704,8 +704,10 @@ def configure_hvm(config_image, vals):
|
||||
config_image.append(['vncpasswd', vals.vncpasswd])
|
||||
|
||||
def run_bootloader(vals, config_image):
|
||||
if not os.access(vals.bootloader, os.F_OK):
|
||||
err("Bootloader '%s' does not exist" % vals.bootloader)
|
||||
if not os.access(vals.bootloader, os.X_OK):
|
||||
err("Bootloader isn't executable")
|
||||
err("Bootloader '%s' isn't executable" % vals.bootloader)
|
||||
if len(vals.disk) < 1:
|
||||
err("No disks configured and boot loader requested")
|
||||
(uname, dev, mode, backend) = vals.disk[0]
|
||||
|
||||
+120
-15
@@ -21,6 +21,7 @@
|
||||
|
||||
"""Grand unified management application for Xen.
|
||||
"""
|
||||
import atexit
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
@@ -29,8 +30,10 @@ import socket
|
||||
import traceback
|
||||
import xmlrpclib
|
||||
import traceback
|
||||
import time
|
||||
import datetime
|
||||
from select import select
|
||||
import xml.dom.minidom
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings('ignore', category=FutureWarning)
|
||||
@@ -38,12 +41,14 @@ warnings.filterwarnings('ignore', category=FutureWarning)
|
||||
from xen.xend import PrettyPrint
|
||||
from xen.xend import sxp
|
||||
from xen.xend import XendClient
|
||||
from xen.xend.XendClient import server
|
||||
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
|
||||
@@ -51,6 +56,12 @@ from xen.util import security
|
||||
if not hasattr(getopt, 'gnu_getopt'):
|
||||
getopt.gnu_getopt = getopt.getopt
|
||||
|
||||
XM_CONFIG_FILE = '/etc/xen/xm-config.xml'
|
||||
|
||||
# Supported types of server
|
||||
SERVER_LEGACY_XMLRPC = 'LegacyXMLRPC'
|
||||
SERVER_XEN_API = 'Xen-API'
|
||||
|
||||
# General help message
|
||||
|
||||
USAGE_HELP = "Usage: xm <subcommand> [args]\n\n" \
|
||||
@@ -319,6 +330,40 @@ acm_commands = [
|
||||
all_commands = (domain_commands + host_commands + scheduler_commands +
|
||||
device_commands + vnet_commands + acm_commands)
|
||||
|
||||
|
||||
##
|
||||
# Configuration File Parsing
|
||||
##
|
||||
|
||||
config = None
|
||||
if os.path.isfile(XM_CONFIG_FILE):
|
||||
try:
|
||||
config = xml.dom.minidom.parse(XM_CONFIG_FILE)
|
||||
except:
|
||||
print >>sys.stderr, ('Ignoring invalid configuration file %s.' %
|
||||
XM_CONFIG_FILE)
|
||||
|
||||
def parseServer():
|
||||
if config:
|
||||
server = config.getElementsByTagName('server')
|
||||
if server:
|
||||
st = server[0].getAttribute('type')
|
||||
if st != SERVER_XEN_API and st != SERVER_LEGACY_XMLRPC:
|
||||
print >>sys.stderr, ('Invalid server type %s; using %s.' %
|
||||
(st, SERVER_LEGACY_XMLRPC))
|
||||
st = SERVER_LEGACY_XMLRPC
|
||||
return (st, server[0].getAttribute('uri'))
|
||||
|
||||
return SERVER_LEGACY_XMLRPC, XendClient.uri
|
||||
|
||||
def parseAuthentication():
|
||||
server = config.getElementsByTagName('server')[0]
|
||||
return (server.getAttribute('username'),
|
||||
server.getAttribute('password'))
|
||||
|
||||
serverType, serverURI = parseServer()
|
||||
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# Help/usage printing functions
|
||||
@@ -469,6 +514,16 @@ def err(msg):
|
||||
print >>sys.stderr, "Error:", msg
|
||||
|
||||
|
||||
def get_single_vm(dom):
|
||||
uuids = server.xenapi.VM.get_by_name_label(dom)
|
||||
n = len(uuids)
|
||||
if n == 1:
|
||||
return uuids[0]
|
||||
else:
|
||||
dominfo = server.xend.domain(dom, False)
|
||||
return dominfo['uuid']
|
||||
|
||||
|
||||
#########################################################################
|
||||
#
|
||||
# Main xm functions
|
||||
@@ -577,15 +632,21 @@ def parse_doms_info(info):
|
||||
|
||||
def get_status(n, t, d):
|
||||
return DOM_STATES[t(sxp.child_value(info, n, d))]
|
||||
|
||||
|
||||
start_time = get_info('start_time', float, -1)
|
||||
if start_time == -1:
|
||||
up_time = float(-1)
|
||||
else:
|
||||
up_time = time.time() - start_time
|
||||
|
||||
return {
|
||||
'domid' : get_info('domid', str, ''),
|
||||
'name' : get_info('name', str, '??'),
|
||||
'mem' : get_info('memory_dynamic_min', int, 0),
|
||||
'vcpus' : get_info('vcpus', int, 0),
|
||||
'vcpus' : get_info('online_vcpus', int, 0),
|
||||
'state' : get_info('state', str, ''),
|
||||
'cpu_time' : get_info('cpu_time', float, 0),
|
||||
'up_time' : get_info('up_time', float, -1),
|
||||
'up_time' : up_time,
|
||||
'seclabel' : security.get_security_printlabel(info),
|
||||
}
|
||||
|
||||
@@ -767,17 +828,26 @@ def xm_start(args):
|
||||
sys.exit(1)
|
||||
|
||||
dom = params[0]
|
||||
server.xend.domain.start(dom, paused)
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.start(get_single_vm(dom), paused)
|
||||
else:
|
||||
server.xend.domain.start(dom, paused)
|
||||
|
||||
def xm_delete(args):
|
||||
arg_check(args, "delete", 1)
|
||||
dom = args[0]
|
||||
server.xend.domain.delete(dom)
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.destroy(get_single_vm(dom))
|
||||
else:
|
||||
server.xend.domain.delete(dom)
|
||||
|
||||
def xm_suspend(args):
|
||||
arg_check(args, "suspend", 1)
|
||||
dom = args[0]
|
||||
server.xend.domain.suspend(dom)
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.suspend(get_single_vm(dom))
|
||||
else:
|
||||
server.xend.domain.suspend(dom)
|
||||
|
||||
def xm_resume(args):
|
||||
arg_check(args, "resume", 1, 2)
|
||||
@@ -799,7 +869,10 @@ def xm_resume(args):
|
||||
sys.exit(1)
|
||||
|
||||
dom = params[0]
|
||||
server.xend.domain.resume(dom, paused)
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.resume(get_single_vm(dom), paused)
|
||||
else:
|
||||
server.xend.domain.resume(dom, paused)
|
||||
|
||||
def xm_reboot(args):
|
||||
arg_check(args, "reboot", 1, 3)
|
||||
@@ -815,13 +888,19 @@ def xm_pause(args):
|
||||
arg_check(args, "pause", 1)
|
||||
dom = args[0]
|
||||
|
||||
server.xend.domain.pause(dom)
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.pause(get_single_vm(dom))
|
||||
else:
|
||||
server.xend.domain.pause(dom)
|
||||
|
||||
def xm_unpause(args):
|
||||
arg_check(args, "unpause", 1)
|
||||
dom = args[0]
|
||||
|
||||
server.xend.domain.unpause(dom)
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.unpause(get_single_vm(dom))
|
||||
else:
|
||||
server.xend.domain.unpause(dom)
|
||||
|
||||
def xm_dump_core(args):
|
||||
live = False
|
||||
@@ -862,7 +941,10 @@ def xm_dump_core(args):
|
||||
def xm_rename(args):
|
||||
arg_check(args, "rename", 2)
|
||||
|
||||
server.xend.domain.setName(args[0], args[1])
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.set_name_label(get_single_vm(args[0]), args[1])
|
||||
else:
|
||||
server.xend.domain.setName(args[0], args[1])
|
||||
|
||||
def xm_importcommand(command, args):
|
||||
cmd = __import__(command, globals(), locals(), 'xen.xm')
|
||||
@@ -920,7 +1002,12 @@ def xm_vcpu_set(args):
|
||||
|
||||
def xm_destroy(args):
|
||||
arg_check(args, "destroy", 1)
|
||||
server.xend.domain.destroy(args[0])
|
||||
|
||||
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):
|
||||
@@ -1134,7 +1221,7 @@ def xm_uptime(args):
|
||||
|
||||
for dom in doms:
|
||||
d = parse_doms_info(dom)
|
||||
if d['domid'] > 0:
|
||||
if int(d['domid']) > 0:
|
||||
uptime = int(round(d['up_time']))
|
||||
else:
|
||||
f=open('/proc/uptime', 'r')
|
||||
@@ -1161,10 +1248,10 @@ def xm_uptime(args):
|
||||
if short_mode:
|
||||
now = datetime.datetime.now()
|
||||
upstring = now.strftime(" %H:%M:%S") + " up " + upstring
|
||||
upstring += ", " + d['name'] + " (" + str(d['domid']) + ")"
|
||||
upstring += ", " + d['name'] + " (" + d['domid'] + ")"
|
||||
else:
|
||||
upstring += ':%(seconds)02d' % vars()
|
||||
upstring = ("%(name)-32s %(domid)3d " % d) + upstring
|
||||
upstring = ("%(name)-32s %(domid)3s " % d) + upstring
|
||||
|
||||
print upstring
|
||||
|
||||
@@ -1577,6 +1664,8 @@ def deprecated(old,new):
|
||||
"Command %s is deprecated. Please use xm %s instead." % (old, new))
|
||||
|
||||
def main(argv=sys.argv):
|
||||
global server
|
||||
|
||||
if len(argv) < 2:
|
||||
usage()
|
||||
|
||||
@@ -1595,6 +1684,19 @@ def main(argv=sys.argv):
|
||||
args = argv[2:]
|
||||
if cmd:
|
||||
try:
|
||||
if serverType == SERVER_XEN_API:
|
||||
server = XenAPI.Session(serverURI)
|
||||
username, password = parseAuthentication()
|
||||
server.login_with_password(username, password)
|
||||
def logout():
|
||||
try:
|
||||
server.xenapi.session.logout()
|
||||
except:
|
||||
pass
|
||||
atexit.register(logout)
|
||||
else:
|
||||
server = ServerProxy(serverURI)
|
||||
|
||||
rc = cmd(args)
|
||||
if rc:
|
||||
usage()
|
||||
@@ -1615,6 +1717,9 @@ def main(argv=sys.argv):
|
||||
sys.exit(1)
|
||||
except SystemExit:
|
||||
sys.exit(1)
|
||||
except XenAPI.Failure, exn:
|
||||
err(str(exn))
|
||||
sys.exit(1)
|
||||
except xmlrpclib.Fault, ex:
|
||||
if ex.faultCode == XendClient.ERROR_INVALID_DOMAIN:
|
||||
err("Domain '%s' does not exist." % ex.faultString)
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
|
||||
import sys
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
from xen.xm.opts import *
|
||||
|
||||
from main import server
|
||||
|
||||
gopts = Opts(use="""[options] DOM HOST
|
||||
|
||||
Migrate domain DOM to host HOST.
|
||||
|
||||
@@ -21,10 +21,9 @@ import xmlrpclib
|
||||
from xen.xend import PrettyPrint
|
||||
from xen.xend import sxp
|
||||
from xen.xend import XendClient
|
||||
from xen.xend.XendClient import server
|
||||
|
||||
from xen.xm.opts import *
|
||||
from xen.xm.create import *
|
||||
from opts import *
|
||||
from create import *
|
||||
|
||||
def make_unstarted_domain(opts, config):
|
||||
"""Create an unstarted domain.
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
"""
|
||||
import time
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
from xen.xend import sxp
|
||||
from xen.xm.opts import *
|
||||
from opts import *
|
||||
from main import server
|
||||
|
||||
gopts = Opts(use="""[options] [DOM]
|
||||
|
||||
|
||||