xm:
1. Add the following commands: grp-create, grp-shutdown, grp-destroy,
grp-join, grp-pause, grp-unpause, grp-reboot, grp-save, grp-restore,
grp-migrate, grp-list
2. Add example group configuration file and parsing mechanism.
diff -r ecb6cd61a9cf tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/python/xen/xm/create.py Tue Feb 20 12:59:11 2007 -0500
@@ -489,6 +489,11 @@ gopts.var('on_xend_stop', val='continue|
- shutdown: Domain is shutdown;
- suspend: Domain is suspended;
""")
+
+gopts.var('dgid', val='NUM',
+ fn=set_int, default=32767,
+ use='Default domain group to join.')
+
def err(msg):
"""Print an error to stderr and exit.
@@ -749,6 +754,8 @@ def make_config(vals):
config.append(['backend', ['tpmif']])
if vals.localtime:
config.append(['localtime', vals.localtime])
+ if vals.dgid is not None:
+ config.append(['dgid', vals.dgid])
config_image = configure_image(vals)
if vals.bootloader:
@@ -1268,6 +1275,7 @@ def main(argv):
print("Could not start console\n");
sys.exit(0)
dom = make_domain(opts, config)
+ return dom
if __name__ == '__main__':
diff -r ecb6cd61a9cf tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Tue Feb 20 12:27:03 2007 +0000
+++ b/tools/python/xen/xm/main.py Tue Feb 20 12:59:11 2007 -0500
@@ -50,6 +50,7 @@ from xen.xm import console
from xen.xm import console
from xen.util import security
from xen.util.xmlrpclib2 import ServerProxy
+from xen.xm import group
import XenAPI
@@ -184,6 +185,25 @@ SUBCOMMAND_HELP = {
'labels' : ('[policy] [type=dom|res|any]',
'List <type> labels for (active) policy.'),
'serve' : ('', 'Proxy Xend XMLRPC over stdio.'),
+
+ # domain groups
+
+ 'grp-create' : ('<config> [--managed | -m]','Create a domain group'),
+ 'grp-shutdown' : ('<grp> [--keep| -k]','Shutdown all domains in group'),
+ 'grp-destroy' : ('<grp> [--force | -f]','Destroy group'),
+ 'grp-reboot' : ('<grp>','Reboot all domains in group'),
+ 'grp-pause' : ('<grp>','Pause all domains in group'),
+ 'grp-unpause' : ('<grp>','Unpause all domains in group'),
+ 'grp-save' : ('<grp> <prefix>','Save all domains in group to '
+ 'files with the specified prefix'),
+ 'grp-restore' : ('<CheckpointFile> [CheckpointFile ...]',
+ 'Restore all domains in group from file(s)'),
+ 'grp-suspend' : ('<grp>','Suspend all domains in group'),
+ 'grp-resume' : ('<grp>','Resume all domains in group'),
+ 'grp-migrate' : ('<grp> <host> [--live | -l]',
+ 'Migrate all domains in group to host'),
+ 'grp-join' : ('<dom> <grp>','Add domain to group'),
+ 'grp-list' : ('','List groups and their members'),
}
SUBCOMMAND_OPTIONS = {
@@ -292,6 +312,20 @@ domain_commands = [
"vcpu-set",
]
+group_commands = [
+ "grp-create",
+ "grp-shutdown",
+ "grp-destroy",
+ "grp-reboot",
+ "grp-pause",
+ "grp-unpause",
+ "grp-suspend",
+ "grp-resume",
+ "grp-migrate",
+ "grp-join",
+ "grp-list",
+]
+
host_commands = [
"dmesg",
"info",
@@ -335,7 +369,8 @@ acm_commands = [
]
all_commands = (domain_commands + host_commands + scheduler_commands +
- device_commands + vnet_commands + acm_commands + ['shell'])
+ device_commands + vnet_commands + acm_commands + ['shell'] +
+ group_commands )
##
@@ -482,12 +517,17 @@ def usage(cmd = None):
#
####################################################################
-def arg_check(args, name, lo, hi = -1):
+def arg_check(args, name, lo, hi = None):
n = len([i for i in args if i != '--'])
- if hi == -1:
+ if hi == None:
if n != lo:
err("'xm %s' requires %d argument%s.\n" % (name, lo,
+ lo == 1 and '' or 's'))
+ usage(name)
+ elif hi == -1:
+ if n < lo:
+ err("'xm %s' requires at least %d argument%s.\n" % (name, lo,
lo == 1 and '' or 's'))
usage(name)
else:
@@ -694,6 +734,7 @@ def parse_doms_info(info):
return {
'domid' : get_info('domid', str, ''),
+ 'dgid' : get_info('dgid', int, -1),
'name' : get_info('name', str, '??'),
'mem' : get_info('memory_dynamic_min', int, 0),
'state' : get_info('state', str, ''),
@@ -733,6 +774,7 @@ def domid_match(domid, info):
return domid is None or domid == info['name'] or \
domid == str(info['domid'])
+
def xm_brief_list(doms):
print '%-40s %3s %5s %5s %10s %9s' % \
('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)')
@@ -744,13 +786,14 @@ def xm_brief_list(doms):
d = parse_doms_info(dom)
print format % d
+
def xm_label_list(doms):
- print '%-32s %3s %5s %5s %5s %9s %-8s' % \
+ print '%-32s %3s %5s %5s %5s %9s %-8s %7s' % \
('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
output = []
format = '%(name)-32s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
- '%(cpu_time)8.1f %(seclabel)9s'
+ '%(cpu_time)8.1f %(seclabel)9s %(dgid)7d'
for dom in doms:
d = parse_doms_info(dom)
@@ -1647,6 +1690,100 @@ def xm_vnet_delete(args):
arg_check(args, "vnet-delete", 1)
vnet = args[0]
server.xend_vnet_delete(vnet)
+
+def xm_grp_create(args):
+ arg_check(args, "grp-create", 1)
+
+ CONFIG_ROOT = '/etc/xen/'
+ config_path = args[0]
+
+ if ( os.path.exists( config_path ) ):
+ verified_config_path = config_path
+ elif ( os.path.exists(CONFIG_ROOT + config_path ) ):
+ verified_config_path = CONFIG_ROOT + config_path
+ else:
+ err( "configuration file [%s] not found" % config_path )
+ return 1
+
+ return group.grp_create( verified_config_path )
+
+def xm_grp_destroy(args):
+ force = False
+ arg_check(args, "grp-destroy", 1, 2)
+ dgid = args[0]
+ for clflag in ['--force', '-f']:
+ if clflag in args:
+ force = True
+ return group.grp_destroy(dgid, force)
+
+def xm_grp_shutdown(args):
+ keep = False
+ arg_check(args, "grp-shutdown", 1, 2)
+ dgid = args[0]
+ for clflag in ['--keep', '-k']:
+ if clflag in args:
+ keep = True
+ return group.grp_shutdown(dgid, "poweroff", keep)
+
+def xm_grp_reboot(args):
+ arg_check(args, "grp-reboot", 1)
+ dgid = args[0]
+ return group.grp_shutdown(dgid, "reboot", True)
+
+def xm_grp_pause(args):
+ arg_check(args, "grp-pause", 1)
+ dgid = args[0]
+ return group.grp_pause(dgid)
+
+def xm_grp_unpause(args):
+ arg_check(args, "grp-unpause", 1)
+ dgid = args[0]
+ return group.grp_unpause(dgid)
+
+def xm_grp_save(args):
+ arg_check(args, "grp-save", 2)
+ dgid = args[0]
+ prefix = args[1]
+ return group.grp_save(dgid, prefix)
+
+def xm_grp_restore(args):
+ arg_check(args, "grp-restore", 1, -1)
+ return group.grp_restore(args)
+
+def xm_grp_suspend(args):
+ print "Not yet implemented"
+ #arg_check(args, "grp-suspend", 1)
+ #dgid = args[0]
+ #return group.grp_suspend(dgid)
+
+def xm_grp_resume(args):
+ print "Not yet implemented"
+ #arg_check(args, "grp-resume", 1)
+ #dgid = args[0]
+ #return group.grp_resume(dgid)
+
+def xm_grp_migrate(args):
+ live = False
+ arg_check(args, "grp-migrate", 2, 3)
+ dgid = args[0]
+ dst = args[1]
+ for clflag in ['--live', '-l']:
+ if clflag in args:
+ live = True
+ # hardcode these options for now
+ resource = 0
+ port = 0
+ return group.grp_migrate(dgid,dst,live,resource,port)
+
+def xm_grp_join(args):
+ arg_check(args, "grp-join", 2)
+ domid = args[0]
+ dgid = args[1]
+ return group.grp_join(domid, dgid)
+
+def xm_grp_list(args):
+ arg_check(args, "grp-list", 0)
+ return group.grp_list()
commands = {
"shell": xm_shell,
@@ -1704,6 +1841,20 @@ commands = {
"vnet-delete": xm_vnet_delete,
# vtpm
"vtpm-list": xm_vtpm_list,
+ # group
+ "grp-create": xm_grp_create,
+ "grp-shutdown": xm_grp_shutdown,
+ "grp-destroy": xm_grp_destroy,
+ "grp-reboot": xm_grp_reboot,
+ "grp-pause": xm_grp_pause,
+ "grp-unpause": xm_grp_unpause,
+ "grp-save": xm_grp_save,
+ "grp-restore": xm_grp_restore,
+ "grp-suspend": xm_grp_suspend,
+ "grp-resume": xm_grp_resume,
+ "grp-migrate": xm_grp_migrate,
+ "grp-join": xm_grp_join,
+ "grp-list": xm_grp_list,
}
## The commands supported by a separate argument parser in xend.xm.
diff -r ecb6cd61a9cf tools/python/xen/xm/group.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xm/group.py Tue Feb 20 12:59:11 2007 -0500
@@ -0,0 +1,274 @@
+#============================================================================
+# 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
+#============================================================================
+# Author: Chris Bookholt <hap10@xxxxxxxxxxxxxx>
+#============================================================================
+import os.path
+import sys
+import xmlrpclib
+import time
+from xen.xm.opts import Opts
+from xen.xend import sxp
+from xen.xend.XendClient import server
+from sets import Set
+
+opts = Opts()
+
+# print an error to stderr and exit.
+def err(msg):
+ print >>sys.stderr, "Error:", msg
+ sys.exit(1)
+
+
+def get_grp(dgid):
+ grpinfo = server.xend.group(dgid)
+ if not grpinfo:
+ err("group %s does not exist" % dgid)
+ return grpinfo
+
+
+def idCheck(dgid, op):
+ dgid = int(dgid)
+ if (dgid == 0 or dgid == 32767):
+ err("cannot %s group %d" % (op,dgid))
+
+
+def wait_create(domname, timeout):
+ counter = 0
+ while counter < timeout:
+ domains = server.xend.domains(0)
+ if domname in domains:
+ return
+ counter += 1
+ time.sleep(1)
+ err("timeout reached; problem starting group member dom: %s" % domname)
+
+
+# read and parse sxp config from file
+def make_config(config_file_path):
+ try:
+ fin = file(config_file_path, 'rb')
+ try:
+ config = sxp.parse(fin)
+ finally:
+ fin.close()
+ if config is None:
+ config = ['grp_config']
+ else:
+ config.insert(0, 'grp_config')
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+ return config
+
+
+# create a domain group
+def make_domain_group(config):
+ try:
+ grpinfo = server.xend.group.create(config)
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+ return grpinfo
+
+
+# start the group members
+def populate_group(grpinfo, managed):
+ if managed:
+ from xen.xm import new
+ else:
+ from xen.xm import create
+
+ for domdata in grpinfo['member_list']:
+ domdata_list = domdata.split(":")
+ domname = domdata_list[0]
+ dom_config_path = domdata_list[1]
+ if managed:
+ #print "creating managed domain %s from file: %s" %
(domname,dom_config_path)
+ new.main([None,dom_config_path])
+ #print "starting managed domain %s" % domname
+ server.xend.domain.start(domname, False)
+ domid = sxp.child_value(server.xend.domain(domname), 'domid')
+ else:
+ domid = create.main([None,dom_config_path])
+ wait_create(domname, 10)
+ dgid = grpinfo['dgid']
+ grp_join(domid, dgid)
+ #grp_unpause(grp.dgid)
+
+
+def grp_create(config_file_path, managed = False):
+ config = make_config(config_file_path)
+ grpinfo = make_domain_group(config)
+ populate_group(grpinfo, managed)
+
+
+# shutdown or reboot a group of domains
+def grp_shutdown(dgid, reason, keep):
+ grpinfo = get_grp(dgid)
+ idCheck(grpinfo['dgid'],"shutdown or reboot")
+ try:
+ server.xend.group.shutdown(dgid, reason)
+ if reason == "poweroff" and not keep:
+ print "waiting for group members to shutdown..."
+ from xen.xm.shutdown import wait_shutdown
+ wait_shutdown(opts, grpinfo['members'])
+ grp_destroy(dgid, force = False)
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# destroy a domain group
+def grp_destroy(dgid, force = False):
+ grpinfo = get_grp(dgid)
+ idCheck(grpinfo['dgid'],"destroy")
+ try:
+ if force:
+ grp_pause(dgid)
+ for domid in grpinfo['members']:
+ server.xend.domain.destroy(domid)
+ print "waiting for group members to be destroyed..."
+ from xen.xm.shutdown import wait_shutdown
+ wait_shutdown(opts, grpinfo['members'])
+ server.xend.group.destroy(grpinfo['dgid'])
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+ return
+
+
+# save a group of running domains
+def grp_save(dgid, prefix):
+ grpinfo = get_grp(dgid)
+ idCheck(grpinfo['dgid'],"save")
+ try:
+ server.xend.group.save(dgid, prefix)
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# retore a group of running domains
+def grp_restore(srcs):
+ try:
+ server.xend.group.restore(srcs)
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# suspend a group of running, managed domains
+#def grp_suspend(dgid):
+# grpinfo = get_grp(dgid)
+# idCheck(grpinfo['dgid'],"suspend")
+# try:
+# server.xend.group.suspend(dgid)
+# except xmlrpclib.Fault, ex:
+# err(str(ex))
+# except Exception, ex:
+# print("Error: %s" % str(ex))
+# raise Exception
+
+
+# resume a suspended domain group
+#def grp_resume(dgid):
+# try:
+# server.xend.group.resume(dgid)
+# except xmlrpclib.Fault, ex:
+# err(str(ex))
+# except Exception, ex:
+# print("Error: %s" % str(ex))
+# raise Exception
+
+
+# pause a domain group
+def grp_pause(dgid):
+ grpinfo = get_grp(dgid)
+ idCheck(grpinfo['dgid'],"pause")
+ try:
+ server.xend.group.pause(grpinfo['dgid'])
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# unpause a domain group
+def grp_unpause(dgid):
+ grpinfo = get_grp(dgid)
+ idCheck(grpinfo['dgid'],"unpause")
+ try:
+ server.xend.group.unpause(grpinfo['dgid'])
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# migrate a domain group
+def grp_migrate(dgid, dst, live, resource, port):
+ grpinfo = get_grp(dgid)
+ idCheck(grpinfo['dgid'],"unpause")
+ try:
+ server.xend.group.migrate(grpinfo['dgid'], dst, live, resource, port)
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# cause a domain to join a group
+def grp_join( dom, dgid ):
+ grpinfo = get_grp(dgid)
+ domid = sxp.child_value(server.xend.domain(dom), 'domid')
+ try:
+ server.xend.group.join(domid, grpinfo['dgid'])
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
+
+
+# print list of domain group stats
+def grp_list():
+ try:
+ domgrps = server.xend.group.list()
+ format = "%-20s %-6s %-5s %-46s"
+ print format % ('Name', 'ID', 'Size', 'Members')
+ for grpinfo in domgrps:
+ name = grpinfo['grp_name']
+ dgid = grpinfo['dgid']
+ size = grpinfo['size']
+ members = ", ".join(grpinfo['members'])
+ print format % (name, dgid, size, members)
+ except xmlrpclib.Fault, ex:
+ err(str(ex))
+ except Exception, ex:
+ print("Error: %s" % str(ex))
+ raise Exception
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|