bitkeeper revision 1.1108.35.1 (4108e070QU79vAGD5MxHmtf2vmIj5w)

Merge xenbk@gandalf:/var/bk/xeno-unstable.bk
into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk
This commit is contained in:
mjw@wray-m-3.hpl.hp.com committed 2004-07-29 11:33:04 +00:00
commit 08aa92db57
12 files changed
+423 -377

No files matched your search

+160 -133
View File
@@ -39,15 +39,23 @@ class XendDomain:
dbpath = "domain"
"""Table of domain info indexed by domain id."""
domain = {}
domain_by_id = {}
domain_by_name = {}
"""Table of domains to restart, indexed by domain id."""
restarts = {}
restarts_by_id = {}
restarts_by_name = {}
"""Table of delayed calls."""
schedule = {}
def __init__(self):
# Hack alert. Python does not support mutual imports, but XendDomainInfo
# needs access to the XendDomain instance to look up domains. Attempting
# to import XendDomain from XendDomainInfo causes unbounded recursion.
# So we stuff the XendDomain instance (self) into XendDomainInfo's
# namespace as 'xd'.
XendDomainInfo.xd = self
# Table of domain info indexed by domain id.
self.db = XendDB.XendDB(self.dbpath)
self.domain_db = self.db.fetchall("")
@@ -173,7 +181,8 @@ class XendDomain:
@return: deferred
"""
def cbok(dominfo):
self.domain[dominfo.id] = dominfo
self.domain_by_id[dominfo.id] = dominfo
self.domain_by_name[dominfo.name] = dominfo
if dominfo.restart_pending():
self.domain_restart_add(dominfo)
@@ -181,17 +190,17 @@ class XendDomain:
deferred.addCallback(cbok)
return deferred
def _add_domain(self, id, info, notify=1):
def _add_domain(self, info, notify=1):
"""Add a domain entry to the tables.
@param id: domain id
@param info: domain info object
@param notify: send a domain created event if true
"""
self.domain[id] = info
self.domain_db[id] = info.sxpr()
self.sync_domain(id)
if notify: eserver.inject('xend.domain.created', id)
self.domain_by_id[info.id] = info
self.domain_db[info.id] = info.sxpr()
self.domain_by_name[info.name] = info
self.sync_domain(info.id)
if notify: eserver.inject('xend.domain.created', info.name)
def _delete_domain(self, id, notify=1):
"""Remove a domain from the tables.
@@ -199,9 +208,12 @@ class XendDomain:
@param id: domain id
@param notify: send a domain died event if true
"""
if id in self.domain:
if notify: eserver.inject('xend.domain.died', id)
del self.domain[id]
if id in self.domain_by_id:
info = self.domain_by_id[id]
if notify: eserver.inject('xend.domain.died', info.name)
if info.name in self.domain_by_name:
del self.domain_by_name[info.name]
del self.domain_by_id[id]
if id in self.domain_db:
del self.domain_db[id]
self.db.delete(id)
@@ -229,7 +241,7 @@ class XendDomain:
if reason in ['poweroff', 'reboot']:
self.domain_restart_schedule(id, reason)
self.final_domain_destroy(id)
if len(self.restarts):
if self.domain_restarts_exist():
self.domain_restarts_schedule()
def refresh(self):
@@ -243,14 +255,14 @@ class XendDomain:
for d in domlist:
id = str(d['dom'])
doms[id] = d
if id not in self.domain:
if id not in self.domain_by_id:
savedinfo = None
deferred = XendDomainInfo.vm_recreate(savedinfo, d)
def cbok(dominfo):
self._add_domain(dominfo.id, dominfo)
self._add_domain(dominfo)
deferred.addCallback(cbok)
# Remove entries for domains that no longer exist.
for d in self.domain.values():
for d in self.domain_by_id.values():
info = doms.get(d.id)
if info:
d.update(info)
@@ -263,7 +275,7 @@ class XendDomain:
@param id: domain id
"""
dominfo = self.domain.get(id)
dominfo = self.domain_by_id.get(id)
if dominfo:
self.domain_db[id] = dominfo.sxpr()
self.sync_domain(id)
@@ -283,17 +295,25 @@ class XendDomain:
raise
pass
else:
d = self.domain.get(id)
d = self.domain_by_id.get(id)
if d:
d.update(dominfo[0])
def domain_ls(self):
"""Get list of domain ids.
"""Get list of domain names.
@return: domain ids
@return: domain names
"""
self.refresh()
return self.domain.keys()
return self.domain_by_name.keys()
def domain_ls_ids(self):
"""Get list of domain ids.
@return: domain names
"""
self.refresh()
return self.domain_by_id.keys()
def domains(self):
"""Get list of domain objects.
@@ -301,7 +321,7 @@ class XendDomain:
@return: domain objects
"""
self.refresh()
return self.domain.values()
return self.domain_by_id.values()
def domain_create(self, config):
"""Create a domain from a configuration.
@@ -310,7 +330,7 @@ class XendDomain:
@return: deferred
"""
def cbok(dominfo):
self._add_domain(dominfo.id, dominfo)
self._add_domain(dominfo)
return dominfo
deferred = XendDomainInfo.vm_create(config)
deferred.addCallback(cbok)
@@ -323,7 +343,7 @@ class XendDomain:
@return: deferred
"""
def cbok(dominfo):
self._add_domain(dominfo.id, dominfo)
self._add_domain(dominfo)
return dominfo
log.info("Restarting domain: id=%s name=%s", dominfo.id, dominfo.name)
deferred = dominfo.restart()
@@ -338,15 +358,14 @@ class XendDomain:
@param config: configuration
@return: deferred
"""
log.debug('domain_configure> id=%s config=%s', id, str(config))
dom = int(id)
dominfo = self.domain_get(dom)
dominfo = self.domain_get(id)
if not dominfo:
raise XendError("Invalid domain: " + str(id))
log.debug('domain_configure> id=%s config=%s', id, str(config))
if dominfo.config:
raise XendError("Domain already configured: " + str(id))
raise XendError("Domain already configured: " + dominfo.name)
def cbok(dominfo):
self._add_domain(dominfo.id, dominfo)
self._add_domain(dominfo)
return dominfo
deferred = dominfo.construct(config)
deferred.addCallback(cbok)
@@ -361,7 +380,7 @@ class XendDomain:
"""
def cbok(dominfo):
self._add_domain(dominfo.id, dominfo)
self._add_domain(dominfo)
return dominfo
deferred = XendDomainInfo.vm_restore(src, progress=progress)
deferred.addCallback(cbok)
@@ -375,25 +394,39 @@ class XendDomain:
"""
id = str(id)
self.refresh_domain(id)
return self.domain.get(id)
return self.domain_by_id.get(id)
def domain_lookup(self, name):
name = str(name)
dominfo = self.domain_by_name.get(name) or self.domain_by_id.get(name)
if dominfo:
return dominfo
raise XendError('invalid domain:' + name)
def domain_exists(self, name):
name = str(name)
if self.domain_by_name.get(name) or self.domain_by_id.get(name):
return 1
else:
return 0
def domain_unpause(self, id):
"""Unpause domain execution.
@param id: domain id
"""
dom = int(id)
eserver.inject('xend.domain.unpause', id)
return xc.domain_unpause(dom=dom)
dominfo = self.domain_lookup(id)
eserver.inject('xend.domain.unpause', dominfo.name)
return xc.domain_unpause(dom=dominfo.dom)
def domain_pause(self, id):
"""Pause domain execution.
@param id: domain id
"""
dom = int(id)
eserver.inject('xend.domain.pause', id)
return xc.domain_pause(dom=dom)
dominfo = self.domain_lookup(id)
eserver.inject('xend.domain.pause', dominfo.name)
return xc.domain_pause(dom=dominfo.dom)
def domain_shutdown(self, id, reason='poweroff'):
"""Shutdown domain (nicely).
@@ -406,18 +439,15 @@ class XendDomain:
@param id: domain id
@param reason: shutdown type: poweroff, reboot, suspend, halt
"""
dom = int(id)
id = str(id)
if dom <= 0:
return 0
dominfo = self.domain_lookup(id)
if reason == 'halt':
self.domain_restart_cancel(id)
self.domain_restart_cancel(dominfo.id)
else:
self.domain_restart_schedule(id, reason, force=1)
eserver.inject('xend.domain.shutdown', [id, reason])
self.domain_restart_schedule(dominfo.id, reason, force=1)
eserver.inject('xend.domain.shutdown', [dominfo.name, reason])
if reason == 'halt':
reason = 'poweroff'
val = xend.domain_shutdown(dom, reason)
val = xend.domain_shutdown(dominfo.id, reason)
self.refresh_schedule()
return val
@@ -428,10 +458,10 @@ class XendDomain:
@param reason: shutdown reason
"""
log.debug('domain_restart_schedule> %s %s %d', id, reason, force)
dominfo = self.domain.get(id)
dominfo = self.domain_lookup(id)
if not dominfo:
return
if id in self.restarts:
if dominfo.id in self.restarts_by_id:
return
restart = (force and reason == 'reboot') or dominfo.restart_needed(reason)
if restart:
@@ -439,8 +469,9 @@ class XendDomain:
self.domain_restart_add(dominfo)
def domain_restart_add(self, dominfo):
self.restarts[dominfo.id] = dominfo
log.info('Scheduling restart for domain: id=%s name=%s', dominfo.id, dominfo.name)
self.restarts_by_name[dominfo.name] = dominfo
self.restarts_by_id[dominfo.id] = dominfo
log.info('Scheduling restart for domain: name=%s id=%s', dominfo.name, dominfo.id)
self.domain_restarts_schedule()
def domain_restart_cancel(self, id):
@@ -448,53 +479,57 @@ class XendDomain:
@param id: domain id
"""
dominfo = self.restarts.get(id)
dominfo = self.restarts_by_id.get(id) or self.restarts_by_name.get(id)
if dominfo:
log.info('Cancelling restart for domain: id=%s name=%s', dominfo.id, dominfo.name)
log.info('Cancelling restart for domain: name=%s id=%s', dominfo.name, dominfo.id)
dominfo.restart_cancel()
del self.restarts[id]
del self.restarts_by_id[dominfo.id]
del self.restarts_by_name[dominfo.name]
def domain_restarts(self):
"""Execute any scheduled domain restarts for domains that have gone.
"""
self.domain_restarts_cancel()
for id in self.restarts.keys():
if id in self.domain:
for dominfo in self.restarts_by_id.values():
if dominfo.id in self.domain_by_id:
# Don't execute restart for domains still running.
continue
dominfo = self.restarts[id]
# Remove it from the restarts.
del self.restarts[id]
del self.restarts_by_id[dominfo.id]
del self.restarts_by_name[dominfo.name]
try:
def cbok(dominfo):
log.info('Restarted domain id=%s as %s', id, dominfo.id)
log.info('Restarted domain name=%s id=%s', dominfo.name, dominfo.id)
self.domain_unpause(dominfo.id)
def cberr(err):
log.exception("Delayed exception restarting domain: id=%s", id)
log.exception("Delayed exception restarting domain: name=%s id=%s",
dominfo.name, dominfo.id)
deferred = self.domain_restart(dominfo)
deferred.addCallback(cbok)
deferred.addErrback(cberr)
except:
log.exception("Exception restarting domain: id=%s", id)
if len(self.restarts):
log.exception("Exception restarting domain: name=%s id=%s",
dominfo.name, dominfo.id)
if self.domain_restarts_exist():
# Run again later if any restarts remain.
self.refresh_schedule(delay=5)
def domain_restarts_exist(self):
return len(self.restarts_by_id)
def final_domain_destroy(self, id):
"""Final destruction of a domain..
@param id: domain id
"""
dom = int(id)
if dom <= 0:
return 0
log.info('Destroying domain: id=%s', str(id))
eserver.inject('xend.domain.destroy', id)
dominfo = self.domain.get(id)
dominfo = self.domain_lookup(id)
log.info('Destroying domain: name=%s', dominfo.name)
eserver.inject('xend.domain.destroy', dominfo.name)
if dominfo:
val = dominfo.destroy()
else:
val = xc.domain_destroy(dom=dom)
#todo
val = xc.domain_destroy(dom=dominfo.dom)
return val
def domain_destroy(self, id, reason='halt'):
@@ -504,7 +539,6 @@ class XendDomain:
@param id: domain id
"""
id = str(id)
if reason == 'halt':
self.domain_restart_cancel(id)
elif reason == 'reboot':
@@ -522,9 +556,9 @@ class XendDomain:
# Need a cancel too?
# Don't forget to cancel restart for it.
print 'domain_migrate>', id, dst
dom = int(id)
dominfo = self.domain_lookup(id)
xmigrate = XendMigrate.instance()
val = xmigrate.migrate_begin(dom, dst)
val = xmigrate.migrate_begin(dominfo.id, dst)
print 'domain_migrate<', val
return val
@@ -536,9 +570,9 @@ class XendDomain:
@param progress: output progress if true
@return: deferred
"""
dom = int(id)
dominfo = self.domain_lookup(id)
xmigrate = XendMigrate.instance()
return xmigrate.save_begin(dom, dst)
return xmigrate.save_begin(dominfo.id, dst)
def domain_pincpu(self, dom, cpu):
"""Pin a domain to a cpu.
@@ -546,156 +580,149 @@ class XendDomain:
@param dom: domain
@param cpu: cpu number
"""
dom = int(dom)
return xc.domain_pincpu(dom, cpu)
dominfo = self.domain_lookup(id)
return xc.domain_pincpu(itn(dominfo.id), cpu)
def domain_cpu_bvt_set(self, dom, mcuadv, warp, warpl, warpu):
def domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu):
"""Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
dom = int(dom)
return xc.bvtsched_domain_set(dom=dom, mcuadv=mcuadv,
dominfo = self.domain_lookup(id)
return xc.bvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
warp=warp, warpl=warpl, warpu=warpu)
def domain_cpu_bvt_get(self, dom):
def domain_cpu_bvt_get(self, id):
"""Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
dom = int(dom)
return xc.bvtsched_domain_get(dom)
dominfo = self.domain_lookup(id)
return xc.bvtsched_domain_get(dominfo.dom)
def domain_cpu_fbvt_set(self, dom, mcuadv, warp, warpl, warpu):
def domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu):
"""Set FBVT (Fair Borrowed Virtual Time) scheduler parameters for a domain.
"""
dom = int(dom)
return xc.fbvtsched_domain_set(dom=dom, mcuadv=mcuadv,
dominfo = self.domain_lookup(id)
return xc.fbvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
warp=warp, warpl=warpl, warpu=warpu)
def domain_cpu_fbvt_get(self, dom):
def domain_cpu_fbvt_get(self, id):
"""Get FBVT (Fair Borrowed Virtual Time) scheduler parameters for a domain.
"""
dom = int(dom)
return xc.fbvtsched_domain_get(dom)
dominfo = self.domain_lookup(id)
return xc.fbvtsched_domain_get(dominfo.dom)
def domain_cpu_atropos_set(self, dom, period, slice, latency, xtratime):
def domain_cpu_atropos_set(self, id, period, slice, latency, xtratime):
"""Set Atropos scheduler parameters for a domain.
"""
dom = int(dom)
return xc.atropos_domain_set(dom, period, slice, latency, xtratime)
dominfo = self.domain_lookup(id)
return xc.atropos_domain_set(dominfo.dom, period, slice, latency, xtratime)
def domain_cpu_atropos_get(self, dom):
def domain_cpu_atropos_get(self, id):
"""Get Atropos scheduler parameters for a domain.
"""
dom = int(dom)
return xc.atropos_domain_get(dom)
dominfo = self.domain_lookup(id)
return xc.atropos_domain_get(dominfo.dom)
def domain_device_create(self, dom, devconfig):
def domain_device_create(self, id, devconfig):
"""Create a new device for a domain.
@param dom: domain id
@param id: domain id
@param devconfig: device configuration
@return: deferred
"""
dom = int(dom)
dominfo = self.domain_get(dom)
if not dominfo:
raise XendError("invalid domain:" + str(dom))
dominfo = self.domain_lookup(id)
self.refresh_schedule()
val = dominfo.device_create(devconfig)
self.update_domain(dominfo.id)
return val
def domain_device_destroy(self, dom, type, idx):
def domain_device_destroy(self, id, type, idx):
"""Destroy a device.
@param dom: domain id
@param id: domain id
@param type: device type
@param idx: device index
"""
dom = int(dom)
dominfo = self.domain_get(dom)
if not dominfo:
raise XendError("invalid domain:" + str(dom))
dominfo = self.domain_lookup(id)
self.refresh_schedule()
val = dominfo.device_destroy(type, idx)
self.update_domain(dominfo.id)
return val
def domain_devtype_ls(self, dom, type):
def domain_devtype_ls(self, id, type):
"""Get list of device indexes for a domain.
@param dom: domain
@param id: domain
@param type: device type
@return: device indexes
"""
dominfo = self.domain_get(dom)
if not dominfo: return None
dominfo = self.domain_lookup(id)
devs = dominfo.get_devices(type)
return range(0, len(devs))
#return range(0, len(devs))
return devs
def domain_devtype_get(self, dom, type, idx):
def domain_devtype_get(self, id, type, idx):
"""Get a device from a domain.
@param dom: domain
@param id: domain
@param type: device type
@param idx: device index
@return: device object (or None)
"""
dominfo = self.domain_get(dom)
if not dominfo: return None
dominfo = self.domain_lookup(id)
return dominfo.get_device_by_index(type, idx)
def domain_vif_ls(self, dom):
def domain_vif_ls(self, id):
"""Get list of virtual network interface (vif) indexes for a domain.
@param dom: domain
@param id: domain
@return: vif indexes
"""
return self.domain_devtype_ls(dom, 'vif')
return self.domain_devtype_ls(id, 'vif')
def domain_vif_get(self, dom, vif):
def domain_vif_get(self, id, vif):
"""Get a virtual network interface (vif) from a domain.
@param dom: domain
@param id: domain
@param vif: vif index
@return: vif device object (or None)
"""
return self.domain_devtype_get(dom, 'vif', vif)
return self.domain_devtype_get(id, 'vif', vif)
def domain_vbd_ls(self, dom):
def domain_vbd_ls(self, id):
"""Get list of virtual block device (vbd) indexes for a domain.
@param dom: domain
@param id: domain
@return: vbd indexes
"""
return self.domain_devtype_ls(dom, 'vbd')
return self.domain_devtype_ls(id, 'vbd')
def domain_vbd_get(self, dom, vbd):
def domain_vbd_get(self, id, vbd):
"""Get a virtual block device (vbd) from a domain.
@param dom: domain
@param id: domain
@param vbd: vbd index
@return: vbd device (or None)
"""
return self.domain_devtype_get(dom, 'vbd', vbd)
return self.domain_devtype_get(id, 'vbd', vbd)
def domain_shadow_control(self, dom, op):
def domain_shadow_control(self, id, op):
"""Shadow page control.
@param dom: domain
@param id: domain
@param op: operation
"""
dom = int(dom)
return xc.shadow_control(dom, op)
dominfo = self.domain_lookup(id)
return xc.shadow_control(dominfo.dom, op)
def domain_maxmem_set(self, dom, mem):
def domain_maxmem_set(self, id, mem):
"""Set the memory limit for a domain.
@param dom: domain
@param mem: memory limit (in MB)
@return: 0 on success, -1 on error
"""
dom = int(dom)
dominfo = self.domain_lookup(id)
maxmem = int(mem) * 1024
return xc.domain_setmaxmem(dom, maxmem_kb = maxmem)
return xc.domain_setmaxmem(dominfo.dom, maxmem_kb = maxmem)
def instance():
+170 -144
View File
@@ -193,8 +193,8 @@ config_handlers = {}
def add_config_handler(name, h):
"""Add a handler for a config field.
name field name
h handler: fn(vm, config, field, index)
@param name: field name
@param h: handler: fn(vm, config, field, index)
"""
config_handlers[name] = h
@@ -212,16 +212,15 @@ image_handlers = {}
def add_image_handler(name, h):
"""Add a handler for an image type
name image type
h handler: fn(config, name, memory, image)
@param name: image type
@param h: handler: fn(config, name, memory, image)
"""
image_handlers[name] = h
def get_image_handler(name):
"""Get the handler for an image type.
name image type
returns handler or None
@param name: image type
@return: handler or None
"""
return image_handlers.get(name)
@@ -233,17 +232,16 @@ device_handlers = {}
def add_device_handler(name, h):
"""Add a handler for a device type.
name device type
h handler: fn(vm, dev)
@param name: device type
@param h: handler: fn(vm, dev)
"""
device_handlers[name] = h
def get_device_handler(name):
"""Get the handler for a device type.
name device type
returns handler or None
@param name : device type
@return; handler or None
"""
return device_handlers.get(name)
@@ -252,10 +250,9 @@ def vm_create(config):
If a vm has been partially created and there is an error it
is destroyed.
config configuration
returns Deferred
raises VmError for invalid configuration
@param config configuration
@return: Deferred
@raise: VmError for invalid configuration
"""
vm = XendDomainInfo()
return vm.construct(config)
@@ -314,21 +311,27 @@ def vm_restore(src, progress=0):
return deferred
def dom_get(dom):
"""Get info from xen for an existing domain.
@param dom: domain id
@return: info or None
"""
domlist = xc.domain_getinfo(dom=dom)
if domlist and dom == domlist[0]['dom']:
return domlist[0]
return None
def append_deferred(dlist, v):
"""Append a value to a deferred list if it is a deferred.
@param dlist: list of deferreds
@param v: value to add
"""
if isinstance(v, defer.Deferred):
dlist.append(v)
def _vm_configure1(val, vm):
d = vm.create_devices()
def cbok(x):
return x
d.addCallback(cbok)
d.addCallback(_vm_configure2, vm)
return d
@@ -348,7 +351,7 @@ class XendDomainInfo:
"""Minimum time between domain restarts in seconds.
"""
MINIMUM_RESTART_TIME = 10
MINIMUM_RESTART_TIME = 20
def __init__(self):
self.recreate = 0
@@ -363,6 +366,7 @@ class XendDomainInfo:
self.cmdline = None
self.console = None
self.devices = {}
self.device_index = {}
self.configs = []
self.info = None
self.ipaddrs = []
@@ -378,9 +382,13 @@ class XendDomainInfo:
self.console_port = None
def setdom(self, dom):
"""Set the domain id.
@param dom: domain id
"""
self.dom = int(dom)
self.id = str(dom)
def update(self, info):
"""Update with info from xc.domain_getinfo().
"""
@@ -437,13 +445,39 @@ class XendDomainInfo:
sxpr.append(['config', self.config])
return sxpr
def check_name(self, name):
"""Check if a vm name is valid. Valid names start with a non-digit
and contain alphabetic characters, digits, or characters in '_-.'.
The same name cannot be used for more than one vm at the same time.
@param name: name
@raise: VMerror if invalid
"""
if name is None or name == '':
raise VmError('missing vm name')
if name[0] in string.digits:
raise VmError('invalid vm name')
for c in name:
if c in string.digits: continue
if c in '_-.': continue
if c in string.ascii_letters: continue
raise VmError('invalid vm name')
# See comment in XendDomain constructor about 'xd'.
if xd.domain_exists(name):
raise VmError('vm name clash: ' + name)
def construct(self, config):
"""Construct the vm instance from its configuration.
@param config: configuration
@return: deferred
@raise: VmError on error
"""
# todo - add support for scheduling params?
self.config = config
try:
self.name = sxp.child_value(config, 'name')
if self.name is None:
raise VmError('missing domain name')
self.check_name(self.name)
self.memory = int(sxp.child_value(config, 'memory'))
if self.memory is None:
raise VmError('missing memory size')
@@ -462,12 +496,9 @@ class XendDomainInfo:
raise VmError('unknown image type: ' + image_name)
image_handler(self, image)
deferred = self.configure()
def cbok(x):
return x
def cberr(err):
self.destroy()
return err
deferred.addCallback(cbok)
deferred.addErrback(cberr)
except StandardError, ex:
# Catch errors, cleanup and re-raise.
@@ -478,8 +509,10 @@ class XendDomainInfo:
def config_devices(self, name):
"""Get a list of the 'device' nodes of a given type from the config.
name device type
return list of device configs
@param name: device type
@type name: string
@return: device configs
@rtype: list
"""
devices = []
for d in sxp.children(self.config, 'device'):
@@ -490,31 +523,57 @@ class XendDomainInfo:
return devices
def config_device(self, type, idx):
"""Get a device config from the device nodes of a given type
from the config.
@param type: device type
@type type: string
@param idx: index
@type idx: int
@return config or None
"""
devs = self.config_devices(type)
if 0 <= idx < len(devs):
return devs[idx]
else:
return None
def next_device_index(self, type):
"""Get the next index for a given device type.
@param type: device type
@type type: string
@return device index
@rtype: int
"""
idx = self.device_index.get(type, 0)
self.device_index[type] = idx + 1
return idx
def add_device(self, type, dev):
"""Add a device to a virtual machine.
dev device to add
@param type: device type
@param dev: device to add
"""
dl = self.devices.get(type, [])
dl.append(dev)
self.devices[type] = dl
def get_devices(self, type):
"""Get a list of the devices of a given type.
@param type: device type
@return: devices
"""
val = self.devices.get(type, [])
return val
def get_device_by_id(self, type, id):
"""Get the device with the given id.
id device id
returns device or None
@param id: device id
@return: device or None
"""
dl = self.get_devices(type)
for d in dl:
@@ -525,20 +584,20 @@ class XendDomainInfo:
def get_device_by_index(self, type, idx):
"""Get the device with the given index.
idx device index
returns device or None
@param idx: device index
@return: device or None
"""
idx = str(idx)
dl = self.get_devices(type)
if 0 <= idx < len(dl):
return dl[idx]
else:
return None
for d in dl:
if d.getidx() == idx:
return d
return None
def add_config(self, val):
"""Add configuration data to a virtual machine.
val data to add
@param val: data to add
"""
self.configs.append(val)
@@ -661,11 +720,11 @@ class XendDomainInfo:
def create_domain(self, ostype, kernel, ramdisk, cmdline, vifs_n):
"""Create a domain. Builds the image but does not configure it.
ostype OS type
kernel kernel image
ramdisk kernel ramdisk
cmdline kernel commandline
vifs_n number of network interfaces
@param ostype: OS type
@param kernel: kernel image
@param ramdisk: kernel ramdisk
@param cmdline: kernel commandline
@param vifs_n: number of network interfaces
"""
if not self.recreate:
if not os.path.isfile(kernel):
@@ -685,8 +744,8 @@ class XendDomainInfo:
def create_devices(self):
"""Create the devices for a vm.
returns Deferred
raises VmError for invalid devices
@return: Deferred
@raise: VmError for invalid devices
"""
dlist = []
devices = sxp.children(self.config, 'device')
@@ -730,16 +789,17 @@ class XendDomainInfo:
"""
dev = self.get_device_by_index(type, idx)
if not dev:
raise VmError('invalid device: %s %d' % (type, idx))
raise VmError('invalid device: %s %s' % (type, idx))
devs = self.devices.get(type)
if 0 <= idx < len(devs):
del devs[idx]
dev_config = self.config_device(type, idx)
index = devs.index(dev)
dev_config = self.config_device(type, index)
if dev_config:
self.config.remove(['device', dev_config])
dev.destroy()
def configure_console(self):
"""Configure the vm console port.
"""
x = sxp.child_value(self.config, 'console')
if x:
try:
@@ -749,12 +809,20 @@ class XendDomainInfo:
self.console_port = port
def configure_restart(self):
"""Configure the vm restart mode.
"""
r = sxp.child_value(self.config, 'restart', RESTART_ONREBOOT)
if r not in restart_modes:
raise VmError('invalid restart mode: ' + str(r))
self.restart_mode = r;
def restart_needed(self, reason):
"""Determine if the vm needs to be restarted when shutdown
for the given reason.
@param reason: shutdown reason
@return 1 if needs restaert, 0 otherwise
"""
if self.restart_mode == RESTART_NEVER:
return 0
if self.restart_mode == RESTART_ALWAYS:
@@ -764,12 +832,18 @@ class XendDomainInfo:
return 0
def restart_cancel(self):
"""Cancel a vm restart.
"""
self.restart_state = None
def restarting(self):
"""Put the vm into restart mode.
"""
self.restart_state = STATE_RESTART_PENDING
def restart_pending(self):
"""Test if the vm has a pending restart.
"""
return self.restart_state == STATE_RESTART_PENDING
def restart_check(self):
@@ -781,7 +855,7 @@ class XendDomainInfo:
if self.restart_time is not None:
tdelta = tnow - self.restart_time
if tdelta < self.MINIMUM_RESTART_TIME:
msg = 'VM %d restarting too fast' % self.dom
msg = 'VM %s restarting too fast' % self.name
log.error(msg)
raise VmError(msg)
self.restart_time = tnow
@@ -830,17 +904,17 @@ class XendDomainInfo:
"""
if self.blkif_backend:
d = defer.Deferred()
d.callback(1)
d.callback(self)
else:
d = xend.blkif_create(self.dom, recreate=self.recreate)
d.addCallback(_vm_configure1, self)
return d
def dom_configure(self, dom):
"""Configure a domain.
"""Configure a vm for an existing domain.
dom domain id
returns deferred
@param dom: domain id
@return: deferred
"""
d = dom_get(dom)
if not d:
@@ -860,6 +934,8 @@ class XendDomainInfo:
return deferred
def configure_fields(self):
"""Process the vm configuration fields using the registered handlers.
"""
dlist = []
index = {}
for field in sxp.children(self.config):
@@ -880,11 +956,10 @@ class XendDomainInfo:
def vm_image_linux(vm, image):
"""Create a VM for a linux image.
name vm name
memory vm memory
image image config
returns vm
@param name: vm name
@param memory: vm memory
@param image: image config
@return: vm
"""
kernel = sxp.child_value(image, "kernel")
cmdline = ""
@@ -905,11 +980,10 @@ def vm_image_linux(vm, image):
def vm_image_netbsd(vm, image):
"""Create a VM for a bsd image.
name vm name
memory vm memory
image image config
returns vm
@param name: vm name
@param memory: vm memory
@param image: image config
@return: vm
"""
#todo: Same as for linux. Is that right? If so can unify them.
kernel = sxp.child_value(image, "kernel")
@@ -932,13 +1006,14 @@ def vm_image_netbsd(vm, image):
def vm_dev_vif(vm, val, index):
"""Create a virtual network interface (vif).
vm virtual machine
val vif config
index vif index
@param vm: virtual machine
@param val: vif config
@param index: vif index
@return: deferred
"""
if vm.netif_backend:
raise VmError('vif: vif in netif backend domain')
vif = index #todo
vif = vm.next_device_index('vif')
vmac = sxp.child_value(val, "mac")
xend.netif_create(vm.dom, recreate=vm.recreate)
log.debug("Creating vif dom=%d vif=%d mac=%s", vm.dom, vif, str(vmac))
@@ -954,13 +1029,14 @@ def vm_dev_vif(vm, val, index):
def vm_dev_vbd(vm, val, index):
"""Create a virtual block device (vbd).
vm virtual machine
val vbd config
index vbd index
@param vm: virtual machine
@param val: vbd config
@param index: vbd index
@return: deferred
"""
if vm.blkif_backend:
raise VmError('vbd: vbd in blkif backend domain')
vdev = index
vdev = vm.next_device_index('vif')
uname = sxp.child_value(val, 'uname')
if not uname:
raise VmError('vbd: Missing uname')
@@ -978,6 +1054,8 @@ def vm_dev_vbd(vm, val, index):
return defer
def parse_pci(val):
"""Parse a pci field.
"""
if isinstance(val, types.StringType):
radix = 10
if val.startswith('0x') or val.startswith('0X'):
@@ -988,6 +1066,13 @@ def parse_pci(val):
return v
def vm_dev_pci(vm, val, index):
"""Add a pci device.
@param vm: virtual machine
@param val: device configuration
@param index: device index
@return: 0 on success
"""
bus = sxp.child_value(val, 'bus')
if not bus:
raise VmError('pci: Missing bus')
@@ -1013,78 +1098,21 @@ def vm_dev_pci(vm, val, index):
return rc
def vm_field_vfr(vm, config, val, index):
"""Handle a vfr field in a config.
vm virtual machine
config vm config
val vfr field
"""
# Get the rules and add them.
# (vfr (vif (id foo) (ip x.x.x.x)) ... )
list = sxp.children(val, 'vif')
ipaddrs = []
for v in list:
id = sxp.child_value(v, 'id')
if id is None:
raise VmError('vfr: missing vif id')
id = int(id)
dev = vm.get_device_by_index('vif', id)
if not dev:
raise VmError('vfr: invalid vif id %d' % id)
vif = sxp.child_value(dev, 'vif')
ip = sxp.child_value(v, 'ip')
if not ip:
raise VmError('vfr: missing ip address')
ipaddrs.append(ip);
# todo: Configure the ipaddrs.
vm.ipaddrs = ipaddrs
def vnet_bridge(vnet, vmac, dom, idx):
"""Add the device for the vif to the bridge for its vnet.
"""
vif = "vif%d.%d" % (dom, idx)
try:
cmd = "(vif.conn (vif %s) (vnet %s) (vmac %s))" % (vif, vnet, vmac)
log.debug("vnet_bridge> %s", cmd)
out = file("/proc/vnet/policy", "wb")
out.write(cmd)
err = out.close()
log.debug("vnet_bridge> err=%d", err)
except IOError, ex:
log.exception("vnet_bridge>")
def vm_field_vnet(vm, config, val, index):
"""Handle a vnet field in a config.
vm virtual machine
config vm config
val vnet field
index index
"""
# Get the vif children. For each vif look up the vif device
# with the given id and configure its vnet.
# (vnet (vif (id foo) (vnet 2) (mac x:x:x:x:x:x)) ... )
vif_vnets = sxp.children(val, 'vif')
for v in vif_vnets:
id = sxp.child_value(v, 'id')
if id is None:
raise VmError('vnet: missing vif id')
dev = vm.get_device_by_id('vif', id)
#vnet = sxp.child_value(v, 'vnet', 1)
#mac = sxp.child_value(dev, 'mac')
#vif = sxp.child_value(dev, 'vif')
#vnet_bridge(vnet, mac, vm.dom, 0)
#vm.add_config([ 'vif.vnet', ['id', id], ['vnet', vnet], ['mac', mac]])
def vm_field_ignore(vm, config, val, index):
"""Dummy config field handler used for fields with built-in handling.
@param vm: virtual machine
@param config: vm config
@param val: vfr field
@param index: field index
"""
pass
# Register image handlers for linux and bsd.
# Register image handlers.
add_image_handler('linux', vm_image_linux)
add_image_handler('netbsd', vm_image_netbsd)
# Register device handlers for vifs and vbds.
# Register device handlers.
add_device_handler('vif', vm_dev_vif)
add_device_handler('vbd', vm_dev_vbd)
add_device_handler('pci', vm_dev_pci)
@@ -1098,6 +1126,4 @@ add_config_handler('image', vm_field_ignore)
add_config_handler('device', vm_field_ignore)
add_config_handler('backend', vm_field_ignore)
# Register config handlers for vfr and vnet.
add_config_handler('vfr', vm_field_vfr)
add_config_handler('vnet', vm_field_vnet)
# Register other config handlers.
+47 -61
View File
@@ -22,9 +22,9 @@ class SrvDomain(SrvDir):
def op_configure(self, op, req):
fn = FormFn(self.xd.domain_configure,
[['dom', 'int'],
[['dom', 'str'],
['config', 'sxpr']])
deferred = fn(req.args, {'dom': self.dom.id})
deferred = fn(req.args, {'dom': self.dom.name})
deferred.addErrback(self._op_configure_err, req)
return deferred
@@ -33,35 +33,35 @@ class SrvDomain(SrvDir):
return str(err)
def op_unpause(self, op, req):
val = self.xd.domain_unpause(self.dom.id)
val = self.xd.domain_unpause(self.dom.name)
return val
def op_pause(self, op, req):
val = self.xd.domain_pause(self.dom.id)
val = self.xd.domain_pause(self.dom.name)
return val
def op_shutdown(self, op, req):
fn = FormFn(self.xd.domain_shutdown,
[['dom', 'int'],
[['dom', 'str'],
['reason', 'str']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
req.setResponseCode(http.ACCEPTED)
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
def op_destroy(self, op, req):
fn = FormFn(self.xd.domain_destroy,
[['dom', 'int'],
[['dom', 'str'],
['reason', 'str']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
def op_save(self, op, req):
fn = FormFn(self.xd.domain_save,
[['dom', 'int'],
[['dom', 'str'],
['file', 'str']])
deferred = fn(req.args, {'dom': self.dom.id})
deferred = fn(req.args, {'dom': self.dom.name})
deferred.addCallback(self._op_save_cb, req)
deferred.addErrback(self._op_save_err, req)
return deferred
@@ -75,9 +75,9 @@ class SrvDomain(SrvDir):
def op_migrate(self, op, req):
fn = FormFn(self.xd.domain_migrate,
[['dom', 'int'],
[['dom', 'str'],
['destination', 'str']])
deferred = fn(req.args, {'dom': self.dom.id})
deferred = fn(req.args, {'dom': self.dom.name})
print 'op_migrate>', deferred
deferred.addCallback(self._op_migrate_cb, req)
deferred.addErrback(self._op_migrate_err, req)
@@ -99,99 +99,85 @@ class SrvDomain(SrvDir):
req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
return str(err)
def op_device_create(self, op, req):
fn = FormFn(self.xd.domain_device_create,
[['dom', 'int'],
['config', 'sxpr']])
d = fn(req.args, {'dom': self.dom.id})
return d
def op_device_destroy(self, op, req):
fn = FormFn(self.xd.domain_device_destroy,
[['dom', 'int'],
['type', 'str'],
['index', 'int']])
val = fn(req.args, {'dom': self.dom.id})
return val
def op_pincpu(self, op, req):
fn = FormFn(self.xd.domain_pincpu,
[['dom', 'int'],
[['dom', 'str'],
['cpu', 'int']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
return val
def op_cpu_bvt_set(self, op, req):
fn = FormFn(self.xd.domain_cpu_bvt_set,
[['dom', 'int'],
[['dom', 'str'],
['mcuadv', 'int'],
['warp', 'int'],
['warpl', 'int'],
['warpu', 'int']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
return val
def op_cpu_fbvt_set(self, op, req):
fn = FormFn(self.xd.domain_cpu_fbvt_set,
[['dom', 'int'],
[['dom', 'str'],
['mcuadv', 'int'],
['warp', 'int'],
['warpl', 'int'],
['warpu', 'int']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
return val
def op_cpu_atropos_set(self, op, req):
fn = FormFn(self.xd.domain_cpu_atropos_set,
[['dom', 'int'],
[['dom', 'str'],
['period', 'int'],
['slice', 'int'],
['latency', 'int'],
['xtratime', 'int']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
return val
def op_maxmem_set(self, op, req):
fn = FormFn(self.xd.domain_maxmem_set,
[['dom', 'int'],
[['dom', 'str'],
['memory', 'int']])
val = fn(req.args, {'dom': self.dom.id})
val = fn(req.args, {'dom': self.dom.name})
return val
def op_device_create(self, op, req):
fn = FormFn(self.xd.domain_device_create,
[['dom', 'str'],
['config', 'sxpr']])
d = fn(req.args, {'dom': self.dom.name})
return d
def op_device_destroy(self, op, req):
fn = FormFn(self.xd.domain_device_destroy,
[['dom', 'str'],
['type', 'str'],
['idx', 'str']])
val = fn(req.args, {'dom': self.dom.name})
return val
def op_vifs(self, op, req):
return self.xd.domain_vif_ls(self.dom.id)
devs = self.xd.domain_vif_ls(self.dom.name)
return [ dev.sxpr() for dev in devs ]
def op_vif(self, op, req):
fn = FormFn(self.xd.domain_vif_get,
[['dom', 'int'],
['vif', 'int']])
val = fn(req.args, {'dom': self.dom.id})
[['dom', 'str'],
['vif', 'str']])
val = fn(req.args, {'dom': self.dom.name})
return val
def op_vbds(self, op, req):
return self.xd.domain_vbd_ls(self.dom.id)
devs = self.xd.domain_vbd_ls(self.dom.name)
return [ dev.sxpr() for dev in devs ]
def op_vbd(self, op, req):
fn = FormFn(self.xd.domain_vbd_get,
[['dom', 'int'],
['vbd', 'int']])
val = fn(req.args, {'dom': self.dom.id})
return val
def op_vbd_add(self, op, req):
fn = FormFn(self.xd.domain_vbd_add,
[['dom', 'int'],
['uname', 'str'],
['dev', 'str'],
['mode', 'str']])
val = fn(req.args, {'dom': self.dom.id})
return val
def op_vbd_remove(self, op, req):
fn = FormFn(self.xd.domain_vbd_remove,
[['dom', 'int'],
['dev', 'str']])
val = fn(req.args, {'dom': self.dom.id})
[['dom', 'str'],
['vbd', 'str']])
val = fn(req.args, {'dom': self.dom.name})
return val
def render_POST(self, req):
+6 -6
View File
@@ -24,7 +24,7 @@ class SrvDomainDir(SrvDir):
def domain(self, x):
val = None
dom = self.xd.domain_get(x)
dom = self.xd.domain_lookup(x)
if not dom:
raise XendError('No such domain ' + str(x))
val = SrvDomain(dom)
@@ -74,7 +74,7 @@ class SrvDomainDir(SrvDir):
def _op_create_cb(self, dominfo, configstring, req):
"""Callback to handle deferred domain creation.
"""
dom = dominfo.id
dom = dominfo.name
domurl = "%s/%s" % (req.prePathURL(), dom)
req.setResponseCode(http.CREATED, "created")
req.setHeader("Location", domurl)
@@ -112,7 +112,7 @@ class SrvDomainDir(SrvDir):
return deferred
def _op_restore_cb(self, dominfo, req):
dom = dominfo.id
dom = dominfo.name
domurl = "%s/%s" % (req.prePathURL(), dom)
req.setResponseCode(http.CREATED)
req.setHeader("Location", domurl)
@@ -159,12 +159,12 @@ class SrvDomainDir(SrvDir):
sxp.show(domains, out=req)
else:
domains = self.xd.domains()
domains.sort(lambda x, y: cmp(x.id, y.id))
domains.sort(lambda x, y: cmp(x.name, y.name))
req.write('<ul>')
for d in domains:
req.write('<li><a href="%s%s"> Domain %s</a>'
% (url, d.id, d.id))
req.write('name=%s' % d.name)
% (url, d.name, d.name))
req.write('id=%s' % d.id)
req.write('memory=%d'% d.memory)
req.write('</li>')
req.write('</ul>')
+6 -2
View File
@@ -215,7 +215,7 @@ class BlkDev(controller.Dev):
"""
def __init__(self, ctrl, vdev, mode, segment):
controller.Dev.__init__(self, ctrl)
controller.Dev.__init__(self, segment['device'], ctrl)
self.vdev = vdev
self.mode = mode
self.device = segment['device']
@@ -227,7 +227,11 @@ class BlkDev(controller.Dev):
return 'w' not in self.mode
def sxpr(self):
val = ['blkdev', ['vdev', self.vdev], ['mode', self.mode] ]
val = ['blkdev',
['idx', self.idx],
['vdev', self.vdev],
['device', self.device],
['mode', self.mode]]
return val
def destroy(self):
+5 -1
View File
@@ -327,10 +327,14 @@ class Dev:
"""Abstract class for a device attached to a device controller.
"""
def __init__(self, controller):
def __init__(self, idx, controller):
self.idx = str(idx)
self.controller = controller
self.props = {}
def getidx(self):
return self.idx
def setprop(self, k, v):
self.props[k] = v
+5 -2
View File
@@ -112,7 +112,7 @@ class NetDev(controller.Dev):
"""
def __init__(self, ctrl, vif, config):
controller.Dev.__init__(self, ctrl)
controller.Dev.__init__(self, vif, ctrl)
self.vif = vif
self.evtchn = None
self.configure(config)
@@ -140,7 +140,10 @@ class NetDev(controller.Dev):
def sxpr(self):
vif = str(self.vif)
mac = self.get_mac()
val = ['vif', ['idx', vif], ['mac', mac]]
val = ['vif',
['idx', self.idx],
['vif', vif],
['mac', mac]]
if self.bridge:
val.append(['bridge', self.bridge])
if self.script:
+2 -1
View File
@@ -366,10 +366,11 @@ def show(sxpr, out=sys.stdout):
show(x, out)
i += 1
out.write(k_list_close)
elif isinstance(sxpr, (types.IntType, types.FloatType)):
out.write(str(sxpr))
elif isinstance(sxpr, types.StringType) and atomp(sxpr):
out.write(sxpr)
else:
#out.write("'" + str(sxpr) + "'")
out.write(repr(str(sxpr)))
def show_xml(sxpr, out=sys.stdout):
+3 -3
View File
@@ -402,7 +402,7 @@ def make_domain(opts, config):
except XendError, ex:
opts.err(str(ex))
dom = int(sxp.child_value(dominfo, 'id'))
dom = sxp.child_value(dominfo, 'name')
console_info = sxp.child(dominfo, 'console')
if console_info:
console_port = int(sxp.child_value(console_info, 'console_port'))
@@ -411,8 +411,8 @@ def make_domain(opts, config):
if server.xend_domain_unpause(dom) < 0:
server.xend_domain_destroy(dom)
opts.err("Failed to unpause domain %d" % dom)
opts.info("Started domain %d, console on port %d"
opts.err("Failed to unpause domain %s" % dom)
opts.info("Started domain %s, console on port %d"
% (dom, console_port))
return (dom, console_port)
+1 -5
View File
@@ -27,14 +27,10 @@ def main(argv):
return
if len(args) < 1: opts.err('Missing domain')
dom = args[0]
try:
domid = int(dom)
except:
opts.err('Invalid domain: ' + dom)
if opts.vals.reboot:
mode = 'reboot'
else:
mode = 'halt'
server.xend_domain_destroy(domid, mode)
server.xend_domain_destroy(dom, mode)
+11 -6
View File
@@ -246,10 +246,10 @@ class ProgList(Prog):
use_long = 1
if n == 0:
doms = map(int, server.xend_domains())
doms = server.xend_domains()
doms.sort()
else:
doms = map(int, params)
doms = params
if use_long:
self.long_list(doms)
@@ -257,22 +257,27 @@ class ProgList(Prog):
self.brief_list(doms)
def brief_list(self, doms):
print 'Dom Name Mem(MB) CPU State Time(s)'
print 'Name Id Mem(MB) CPU State Time(s) Console'
for dom in doms:
info = server.xend_domain(dom)
d = {}
d['dom'] = int(dom)
d['dom'] = int(sxp.child_value(info, 'id', '-1'))
d['name'] = sxp.child_value(info, 'name', '??')
d['mem'] = int(sxp.child_value(info, 'memory', '0'))
d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
d['state'] = sxp.child_value(info, 'state', '??')
d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
print ("%(dom)-4d %(name)-16s %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f" % d)
console = sxp.child(info, 'console')
if console:
d['port'] = sxp.child_value(console, 'console_port')
else:
d['port'] = ''
print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3d %(state)5s %(cpu_time)7.1f %(port)4s"
% d)
def long_list(self, doms):
for dom in doms:
info = server.xend_domain(dom)
print '\nDomain %d' % dom
PrettyPrint.prettyprint(info)
xm.prog(ProgList)
+7 -13
View File
@@ -9,6 +9,8 @@ import time
from xen.xend.XendClient import server
from xen.xm.opts import *
DOM0 = 'Domain-0'
gopts = Opts(use="""[options] [DOM]
Shutdown one or more domains gracefully.
@@ -35,11 +37,9 @@ gopts.opt('reboot', short='R',
use='Shutdown and reboot.')
def shutdown(opts, doms, mode, wait):
def domains():
return [ int(a) for a in server.xend_domains() ]
if doms == None: doms = domains()
if 0 in doms:
doms.remove(0)
if doms == None: doms = server.xend_domains()
if DOM0 in doms:
doms.remove(DOM0)
for d in doms:
server.xend_domain_shutdown(d, mode)
if wait:
@@ -50,7 +50,7 @@ def shutdown(opts, doms, mode, wait):
if d in alive: continue
dead.append(d)
for d in dead:
opts.info("Domain %d terminated" % d)
opts.info("Domain %s terminated" % d)
doms.remove(d)
time.sleep(1)
opts.info("All domains terminated")
@@ -76,13 +76,8 @@ def main_all(opts, args):
def main_dom(opts, args):
if len(args) < 1: opts.err('Missing domain')
dom = args[0]
try:
domid = int(dom)
except:
opts.err('Invalid domain: ' + dom)
mode = shutdown_mode(opts)
shutdown(opts, [ domid ], mode, opts.vals.wait)
shutdown(opts, [ dom ], mode, opts.vals.wait)
def main(argv):
opts = gopts
@@ -90,7 +85,6 @@ def main(argv):
if opts.vals.help:
opts.usage()
return
print 'shutdown.main>', len(args), args
if opts.vals.all:
main_all(opts, args)
else:
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.