quick pass at small xen code cleanup and usage of double quotes
This commit is contained in:
parent
bc1a24e880
commit
1f9a8879c1
2 changed files with 223 additions and 203 deletions
|
@ -54,8 +54,7 @@ UDEVADM_PATH = "/sbin/udevadm"
|
||||||
|
|
||||||
|
|
||||||
class XenVEth(PyCoreNetIf):
|
class XenVEth(PyCoreNetIf):
|
||||||
def __init__(self, node, name, localname, mtu=1500, net=None,
|
def __init__(self, node, name, localname, mtu=1500, net=None, start=True, hwaddr=None):
|
||||||
start=True, hwaddr=None):
|
|
||||||
# note that net arg is ignored
|
# note that net arg is ignored
|
||||||
PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu)
|
PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu)
|
||||||
self.localname = localname
|
self.localname = localname
|
||||||
|
@ -65,10 +64,9 @@ class XenVEth(PyCoreNetIf):
|
||||||
self.startup()
|
self.startup()
|
||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
cmd = [XM_PATH, 'network-attach', self.node.vmname,
|
cmd = [XM_PATH, "network-attach", self.node.vmname, "vifname=%s" % self.localname, "script=vif-core"]
|
||||||
'vifname=%s' % self.localname, 'script=vif-core']
|
|
||||||
if self.hwaddr is not None:
|
if self.hwaddr is not None:
|
||||||
cmd.append('mac=%s' % self.hwaddr)
|
cmd.append("mac=%s" % self.hwaddr)
|
||||||
subprocess.check_call(cmd)
|
subprocess.check_call(cmd)
|
||||||
subprocess.check_call([constants.IP_BIN, "link", "set", self.localname, "up"])
|
subprocess.check_call([constants.IP_BIN, "link", "set", self.localname, "up"])
|
||||||
self.up = True
|
self.up = True
|
||||||
|
@ -79,8 +77,8 @@ class XenVEth(PyCoreNetIf):
|
||||||
if self.localname:
|
if self.localname:
|
||||||
if self.hwaddr is not None:
|
if self.hwaddr is not None:
|
||||||
pass
|
pass
|
||||||
# this should be doable, but some argument isn't a string
|
# this should be doable, but some argument isn"t a string
|
||||||
# check_call([XM_PATH, 'network-detach', self.node.vmname,
|
# check_call([XM_PATH, "network-detach", self.node.vmname,
|
||||||
# self.hwaddr])
|
# self.hwaddr])
|
||||||
self.up = False
|
self.up = False
|
||||||
|
|
||||||
|
@ -88,51 +86,50 @@ class XenVEth(PyCoreNetIf):
|
||||||
class XenNode(PyCoreNode):
|
class XenNode(PyCoreNode):
|
||||||
apitype = NodeTypes.XEN.value
|
apitype = NodeTypes.XEN.value
|
||||||
|
|
||||||
FilesToIgnore = frozenset([
|
files_to_ignore = frozenset([
|
||||||
# 'ipforward.sh',
|
# "ipforward.sh",
|
||||||
'quaggaboot.sh',
|
"quaggaboot.sh",
|
||||||
])
|
])
|
||||||
|
|
||||||
FilesRedirection = {
|
files_redirection = {
|
||||||
'ipforward.sh': '/core-tmp/ipforward.sh',
|
"ipforward.sh": "/core-tmp/ipforward.sh",
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdsToIgnore = frozenset([
|
cmds_to_ignore = frozenset([
|
||||||
# 'sh ipforward.sh',
|
# "sh ipforward.sh",
|
||||||
# 'sh quaggaboot.sh zebra',
|
# "sh quaggaboot.sh zebra",
|
||||||
# 'sh quaggaboot.sh ospfd',
|
# "sh quaggaboot.sh ospfd",
|
||||||
# 'sh quaggaboot.sh ospf6d',
|
# "sh quaggaboot.sh ospf6d",
|
||||||
'killall zebra',
|
"killall zebra",
|
||||||
'killall ospfd',
|
"killall ospfd",
|
||||||
'killall ospf6d',
|
"killall ospf6d",
|
||||||
'pidof zebra', 'pidof ospfd', 'pidof ospf6d',
|
"pidof zebra", "pidof ospfd", "pidof ospf6d",
|
||||||
])
|
])
|
||||||
|
|
||||||
def RedirCmd_ipforward(self):
|
def redir_cmd_ipforward(self):
|
||||||
sysctlFile = open(os.path.join(self.mountdir, self.etcdir, 'sysctl.conf'), 'a')
|
sysctl_file = open(os.path.join(self.mountdir, self.etcdir, "sysctl.conf"), "a")
|
||||||
p1 = subprocess.Popen([AWK_PATH, '/^\/sbin\/sysctl -w/ {print $NF}',
|
p1 = subprocess.Popen([AWK_PATH, "/^\/sbin\/sysctl -w/ {print $NF}",
|
||||||
os.path.join(self.nodedir, 'core-tmp/ipforward.sh')], stdout=sysctlFile)
|
os.path.join(self.nodedir, "core-tmp/ipforward.sh")], stdout=sysctl_file)
|
||||||
p1.wait()
|
p1.wait()
|
||||||
sysctlFile.close()
|
sysctl_file.close()
|
||||||
|
|
||||||
def RedirCmd_zebra(self):
|
def redir_cmd_zebra(self):
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e', 's/^zebra=no/zebra=yes/',
|
subprocess.check_call([SED_PATH, "-i", "-e", "s/^zebra=no/zebra=yes/",
|
||||||
os.path.join(self.mountdir, self.etcdir, 'quagga/daemons')])
|
os.path.join(self.mountdir, self.etcdir, "quagga/daemons")])
|
||||||
|
|
||||||
def RedirCmd_ospfd(self):
|
def redir_cmd_ospfd(self):
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e', 's/^ospfd=no/ospfd=yes/',
|
subprocess.check_call([SED_PATH, "-i", "-e", "s/^ospfd=no/ospfd=yes/",
|
||||||
os.path.join(self.mountdir, self.etcdir, 'quagga/daemons')])
|
os.path.join(self.mountdir, self.etcdir, "quagga/daemons")])
|
||||||
|
|
||||||
def RedirCmd_ospf6d(self):
|
def redir_cmd_ospf6d(self):
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e',
|
subprocess.check_call([SED_PATH, "-i", "-e", "s/^ospf6d=no/ospf6d=yes/",
|
||||||
's/^ospf6d=no/ospf6d=yes/',
|
os.path.join(self.mountdir, self.etcdir, "quagga/daemons")])
|
||||||
os.path.join(self.mountdir, self.etcdir, 'quagga/daemons')])
|
|
||||||
|
|
||||||
CmdsRedirection = {
|
cmds_redirection = {
|
||||||
'sh ipforward.sh': RedirCmd_ipforward,
|
"sh ipforward.sh": redir_cmd_ipforward,
|
||||||
'sh quaggaboot.sh zebra': RedirCmd_zebra,
|
"sh quaggaboot.sh zebra": redir_cmd_zebra,
|
||||||
'sh quaggaboot.sh ospfd': RedirCmd_ospfd,
|
"sh quaggaboot.sh ospfd": redir_cmd_ospfd,
|
||||||
'sh quaggaboot.sh ospf6d': RedirCmd_ospf6d,
|
"sh quaggaboot.sh ospf6d": redir_cmd_ospf6d,
|
||||||
}
|
}
|
||||||
|
|
||||||
# CoreNode: no __init__, take from LxcNode & SimpleLxcNode
|
# CoreNode: no __init__, take from LxcNode & SimpleLxcNode
|
||||||
|
@ -154,34 +151,32 @@ class XenNode(PyCoreNode):
|
||||||
# domU name
|
# domU name
|
||||||
self.vmname = "c" + str(session.session_id) + "-" + name
|
self.vmname = "c" + str(session.session_id) + "-" + name
|
||||||
# LVM volume group name
|
# LVM volume group name
|
||||||
self.vgname = self.getconfigitem('vg_name', vgname)
|
self.vgname = self.getconfigitem("vg_name", vgname)
|
||||||
# LVM logical volume name
|
# LVM logical volume name
|
||||||
self.lvname = self.vmname + '-'
|
self.lvname = self.vmname + "-"
|
||||||
# LVM logical volume device path name
|
# LVM logical volume device path name
|
||||||
self.lvpath = os.path.join('/dev', self.vgname, self.lvname)
|
self.lvpath = os.path.join("/dev", self.vgname, self.lvname)
|
||||||
self.disksize = self.getconfigitem('disk_size', disksize)
|
self.disksize = self.getconfigitem("disk_size", disksize)
|
||||||
self.ramsize = int(self.getconfigitem('ram_size', ramsize))
|
self.ramsize = int(self.getconfigitem("ram_size", ramsize))
|
||||||
self.isofile = self.getconfigitem('iso_file', isofile)
|
self.isofile = self.getconfigitem("iso_file", isofile)
|
||||||
# temporary mount point for paused VM persistent filesystem
|
# temporary mount point for paused VM persistent filesystem
|
||||||
self.mountdir = None
|
self.mountdir = None
|
||||||
self.etcdir = self.getconfigitem('etc_path')
|
self.etcdir = self.getconfigitem("etc_path")
|
||||||
|
|
||||||
# TODO: remove this temporary hack
|
# TODO: remove this temporary hack
|
||||||
self.FilesRedirection['/usr/local/etc/quagga/Quagga.conf'] = \
|
self.files_redirection["/usr/local/etc/quagga/Quagga.conf"] = os.path.join(
|
||||||
os.path.join(self.getconfigitem('mount_path'), self.etcdir,
|
self.getconfigitem("mount_path"), self.etcdir, "quagga/Quagga.conf")
|
||||||
'quagga/Quagga.conf')
|
|
||||||
|
|
||||||
# LxcNode initialization
|
# LxcNode initialization
|
||||||
# self.makenodedir()
|
# self.makenodedir()
|
||||||
if self.nodedir is None:
|
if self.nodedir is None:
|
||||||
self.nodedir = os.path.join(session.session_dir, self.name + ".conf")
|
self.nodedir = os.path.join(session.session_dir, self.name + ".conf")
|
||||||
self.mountdir = self.nodedir + self.getconfigitem('mount_path')
|
self.mountdir = self.nodedir + self.getconfigitem("mount_path")
|
||||||
if not os.path.isdir(self.mountdir):
|
if not os.path.isdir(self.mountdir):
|
||||||
os.makedirs(self.mountdir)
|
os.makedirs(self.mountdir)
|
||||||
self.tmpnodedir = True
|
self.tmpnodedir = True
|
||||||
else:
|
else:
|
||||||
raise Exception("Xen PVM node requires a temporary nodedir")
|
raise Exception("Xen PVM node requires a temporary nodedir")
|
||||||
self.tmpnodedir = False
|
|
||||||
self.bootsh = bootsh
|
self.bootsh = bootsh
|
||||||
if start:
|
if start:
|
||||||
self.startup()
|
self.startup()
|
||||||
|
@ -197,7 +192,7 @@ class XenNode(PyCoreNode):
|
||||||
|
|
||||||
# from class LxcNode (also SimpleLxcNode)
|
# from class LxcNode (also SimpleLxcNode)
|
||||||
def startup(self):
|
def startup(self):
|
||||||
logger.warn("XEN PVM startup() called: preparing disk for %s" % self.name)
|
logger.warn("XEN PVM startup() called: preparing disk for %s", self.name)
|
||||||
self.lock.acquire()
|
self.lock.acquire()
|
||||||
try:
|
try:
|
||||||
if self.up:
|
if self.up:
|
||||||
|
@ -205,12 +200,12 @@ class XenNode(PyCoreNode):
|
||||||
self.createlogicalvolume()
|
self.createlogicalvolume()
|
||||||
self.createpartitions()
|
self.createpartitions()
|
||||||
persistdev = self.createfilesystems()
|
persistdev = self.createfilesystems()
|
||||||
subprocess.check_call([constants.MOUNT_BIN, '-t', 'ext4', persistdev, self.mountdir])
|
subprocess.check_call([constants.MOUNT_BIN, "-t", "ext4", persistdev, self.mountdir])
|
||||||
self.untarpersistent(tarname=self.getconfigitem('persist_tar_iso'),
|
self.untarpersistent(tarname=self.getconfigitem("persist_tar_iso"),
|
||||||
iso=True)
|
iso=True)
|
||||||
self.setrootpassword(pw=self.getconfigitem('root_password'))
|
self.setrootpassword(pw=self.getconfigitem("root_password"))
|
||||||
self.sethostname(old='UBASE', new=self.name)
|
self.sethostname(old="UBASE", new=self.name)
|
||||||
self.setupssh(keypath=self.getconfigitem('ssh_key_path'))
|
self.setupssh(keypath=self.getconfigitem("ssh_key_path"))
|
||||||
self.createvm()
|
self.createvm()
|
||||||
self.up = True
|
self.up = True
|
||||||
finally:
|
finally:
|
||||||
|
@ -229,22 +224,22 @@ class XenNode(PyCoreNode):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.session.services.bootnodeservices(self)
|
self.session.services.bootnodeservices(self)
|
||||||
tarname = self.getconfigitem('persist_tar')
|
tarname = self.getconfigitem("persist_tar")
|
||||||
if tarname:
|
if tarname:
|
||||||
self.untarpersistent(tarname=tarname, iso=False)
|
self.untarpersistent(tarname=tarname, iso=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([constants.UMOUNT_BIN, self.mountdir])
|
subprocess.check_call([constants.UMOUNT_BIN, self.mountdir])
|
||||||
self.unmount_all(self.mountdir)
|
self.unmount_all(self.mountdir)
|
||||||
subprocess.check_call([UDEVADM_PATH, 'settle'])
|
subprocess.check_call([UDEVADM_PATH, "settle"])
|
||||||
subprocess.check_call([KPARTX_PATH, '-d', self.lvpath])
|
subprocess.check_call([KPARTX_PATH, "-d", self.lvpath])
|
||||||
|
|
||||||
# time.sleep(5)
|
# time.sleep(5)
|
||||||
# time.sleep(1)
|
# time.sleep(1)
|
||||||
|
|
||||||
# unpause VM
|
# unpause VM
|
||||||
logger.warn("XEN PVM boot() unpause domU %s" % self.vmname)
|
logger.warn("XEN PVM boot() unpause domU %s", self.vmname)
|
||||||
utils.mutecheck_call([XM_PATH, 'unpause', self.vmname])
|
utils.mutecheck_call([XM_PATH, "unpause", self.vmname])
|
||||||
|
|
||||||
self.booted = True
|
self.booted = True
|
||||||
finally:
|
finally:
|
||||||
|
@ -268,25 +263,25 @@ class XenNode(PyCoreNode):
|
||||||
try:
|
try:
|
||||||
# RJE XXX what to do here
|
# RJE XXX what to do here
|
||||||
if self.booted:
|
if self.booted:
|
||||||
utils.mutecheck_call([XM_PATH, 'destroy', self.vmname])
|
utils.mutecheck_call([XM_PATH, "destroy", self.vmname])
|
||||||
self.booted = False
|
self.booted = False
|
||||||
except (OSError, subprocess.CalledProcessError):
|
except (OSError, subprocess.CalledProcessError):
|
||||||
# ignore this error too, the VM may have exited already
|
# ignore this error too, the VM may have exited already
|
||||||
logger.exception("error during shutdown")
|
logger.exception("error during shutdown")
|
||||||
|
|
||||||
# discard LVM volume
|
# discard LVM volume
|
||||||
lvmRemoveCount = 0
|
lvm_remove_count = 0
|
||||||
while os.path.exists(self.lvpath):
|
while os.path.exists(self.lvpath):
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([UDEVADM_PATH, 'settle'])
|
subprocess.check_call([UDEVADM_PATH, "settle"])
|
||||||
utils.mutecall([LVCHANGE_PATH, '-an', self.lvpath])
|
utils.mutecall([LVCHANGE_PATH, "-an", self.lvpath])
|
||||||
lvmRemoveCount += 1
|
lvm_remove_count += 1
|
||||||
utils.mutecall([LVREMOVE_PATH, '-f', self.lvpath])
|
utils.mutecall([LVREMOVE_PATH, "-f", self.lvpath])
|
||||||
except OSError:
|
except OSError:
|
||||||
logger.exception("error during shutdown")
|
logger.exception("error during shutdown")
|
||||||
|
|
||||||
if lvmRemoveCount > 1:
|
if lvm_remove_count > 1:
|
||||||
logger.warn("XEN PVM shutdown() required %d lvremove executions." % lvmRemoveCount)
|
logger.warn("XEN PVM shutdown() required %d lvremove executions.", lvm_remove_count)
|
||||||
|
|
||||||
self._netif.clear()
|
self._netif.clear()
|
||||||
del self.session
|
del self.session
|
||||||
|
@ -303,8 +298,8 @@ class XenNode(PyCoreNode):
|
||||||
"""
|
"""
|
||||||
if os.path.exists(self.lvpath):
|
if os.path.exists(self.lvpath):
|
||||||
raise Exception, "LVM volume already exists"
|
raise Exception, "LVM volume already exists"
|
||||||
utils.mutecheck_call([LVCREATE_PATH, '--size', self.disksize,
|
utils.mutecheck_call([LVCREATE_PATH, "--size", self.disksize,
|
||||||
'--name', self.lvname, self.vgname])
|
"--name", self.lvname, self.vgname])
|
||||||
|
|
||||||
def createpartitions(self):
|
def createpartitions(self):
|
||||||
"""
|
"""
|
||||||
|
@ -313,7 +308,7 @@ class XenNode(PyCoreNode):
|
||||||
"""
|
"""
|
||||||
dev = parted.Device(path=self.lvpath)
|
dev = parted.Device(path=self.lvpath)
|
||||||
dev.removeFromCache()
|
dev.removeFromCache()
|
||||||
disk = parted.freshDisk(dev, 'msdos')
|
disk = parted.freshDisk(dev, "msdos")
|
||||||
constraint = parted.Constraint(device=dev)
|
constraint = parted.Constraint(device=dev)
|
||||||
persist_size = int(0.75 * constraint.maxSize)
|
persist_size = int(0.75 * constraint.maxSize)
|
||||||
self.createpartition(device=dev, disk=disk, start=1,
|
self.createpartition(device=dev, disk=disk, start=1,
|
||||||
|
@ -338,14 +333,14 @@ class XenNode(PyCoreNode):
|
||||||
Make an ext4 filesystem and swap space. Return the device name for
|
Make an ext4 filesystem and swap space. Return the device name for
|
||||||
the persistent partition so we can mount it.
|
the persistent partition so we can mount it.
|
||||||
"""
|
"""
|
||||||
output = subprocess.Popen([KPARTX_PATH, '-l', self.lvpath],
|
output = subprocess.Popen([KPARTX_PATH, "-l", self.lvpath],
|
||||||
stdout=subprocess.PIPE).communicate()[0]
|
stdout=subprocess.PIPE).communicate()[0]
|
||||||
lines = output.splitlines()
|
lines = output.splitlines()
|
||||||
persistdev = '/dev/mapper/' + lines[0].strip().split(' ')[0].strip()
|
persistdev = "/dev/mapper/" + lines[0].strip().split(" ")[0].strip()
|
||||||
swapdev = '/dev/mapper/' + lines[1].strip().split(' ')[0].strip()
|
swapdev = "/dev/mapper/" + lines[1].strip().split(" ")[0].strip()
|
||||||
subprocess.check_call([KPARTX_PATH, '-a', self.lvpath])
|
subprocess.check_call([KPARTX_PATH, "-a", self.lvpath])
|
||||||
utils.mutecheck_call([MKFSEXT4_PATH, '-L', 'persist', persistdev])
|
utils.mutecheck_call([MKFSEXT4_PATH, "-L", "persist", persistdev])
|
||||||
utils.mutecheck_call([MKSWAP_PATH, '-f', '-L', 'swap', swapdev])
|
utils.mutecheck_call([MKSWAP_PATH, "-f", "-L", "swap", swapdev])
|
||||||
return persistdev
|
return persistdev
|
||||||
|
|
||||||
def untarpersistent(self, tarname, iso):
|
def untarpersistent(self, tarname, iso):
|
||||||
|
@ -353,7 +348,8 @@ class XenNode(PyCoreNode):
|
||||||
Unpack a persistent template tar file to the mounted mount dir.
|
Unpack a persistent template tar file to the mounted mount dir.
|
||||||
Uses fsimage library to read from an ISO file.
|
Uses fsimage library to read from an ISO file.
|
||||||
"""
|
"""
|
||||||
tarname = tarname.replace('%h', self.name) # filename may use hostname
|
# filename may use hostname
|
||||||
|
tarname = tarname.replace("%h", self.name)
|
||||||
if iso:
|
if iso:
|
||||||
try:
|
try:
|
||||||
fs = fsimage.open(self.isofile, 0)
|
fs = fsimage.open(self.isofile, 0)
|
||||||
|
@ -375,8 +371,8 @@ class XenNode(PyCoreNode):
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.exception("Failed to open tar file: %s", tarname)
|
logger.exception("Failed to open tar file: %s", tarname)
|
||||||
return
|
return
|
||||||
p = subprocess.Popen([TAR_PATH, '-C', self.mountdir, '--numeric-owner',
|
p = subprocess.Popen([TAR_PATH, "-C", self.mountdir, "--numeric-owner",
|
||||||
'-xf', '-'], stdin=subprocess.PIPE)
|
"-xf", "-"], stdin=subprocess.PIPE)
|
||||||
p.communicate(input=tardata)
|
p.communicate(input=tardata)
|
||||||
p.wait()
|
p.wait()
|
||||||
|
|
||||||
|
@ -385,39 +381,38 @@ class XenNode(PyCoreNode):
|
||||||
Set the root password by updating the shadow password file that
|
Set the root password by updating the shadow password file that
|
||||||
is on the filesystem mounted in the temporary area.
|
is on the filesystem mounted in the temporary area.
|
||||||
"""
|
"""
|
||||||
saltedpw = crypt.crypt(pw, '$6$' + base64.b64encode(os.urandom(12)))
|
saltedpw = crypt.crypt(pw, "$6$" + base64.b64encode(os.urandom(12)))
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e',
|
subprocess.check_call([SED_PATH, "-i", "-e",
|
||||||
'/^root:/s_^root:\([^:]*\):_root:' + saltedpw + ':_',
|
"/^root:/s_^root:\([^:]*\):_root:" + saltedpw + ":_",
|
||||||
os.path.join(self.mountdir, self.etcdir, 'shadow')])
|
os.path.join(self.mountdir, self.etcdir, "shadow")])
|
||||||
|
|
||||||
def sethostname(self, old, new):
|
def sethostname(self, old, new):
|
||||||
"""
|
"""
|
||||||
Set the hostname by updating the hostname and hosts files that
|
Set the hostname by updating the hostname and hosts files that
|
||||||
reside on the filesystem mounted in the temporary area.
|
reside on the filesystem mounted in the temporary area.
|
||||||
"""
|
"""
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e', 's/%s/%s/' % (old, new),
|
subprocess.check_call([SED_PATH, "-i", "-e", "s/%s/%s/" % (old, new),
|
||||||
os.path.join(self.mountdir, self.etcdir, 'hostname')])
|
os.path.join(self.mountdir, self.etcdir, "hostname")])
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e', 's/%s/%s/' % (old, new),
|
subprocess.check_call([SED_PATH, "-i", "-e", "s/%s/%s/" % (old, new),
|
||||||
os.path.join(self.mountdir, self.etcdir, 'hosts')])
|
os.path.join(self.mountdir, self.etcdir, "hosts")])
|
||||||
|
|
||||||
def setupssh(self, keypath):
|
def setupssh(self, keypath):
|
||||||
"""
|
"""
|
||||||
Configure SSH access by installing host keys and a system-wide
|
Configure SSH access by installing host keys and a system-wide
|
||||||
authorized_keys file.
|
authorized_keys file.
|
||||||
"""
|
"""
|
||||||
sshdcfg = os.path.join(self.mountdir, self.etcdir, 'ssh/sshd_config')
|
sshdcfg = os.path.join(self.mountdir, self.etcdir, "ssh/sshd_config")
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e',
|
subprocess.check_call([SED_PATH, "-i", "-e", "s/PermitRootLogin no/PermitRootLogin yes/", sshdcfg])
|
||||||
's/PermitRootLogin no/PermitRootLogin yes/', sshdcfg])
|
sshdir = os.path.join(self.getconfigitem("mount_path"), self.etcdir, "ssh")
|
||||||
sshdir = os.path.join(self.getconfigitem('mount_path'), self.etcdir,
|
# backslash slashes for use in sed
|
||||||
'ssh')
|
sshdir = sshdir.replace("/", "\\/")
|
||||||
sshdir = sshdir.replace('/', '\\/') # backslash slashes for use in sed
|
subprocess.check_call([SED_PATH, "-i", "-e",
|
||||||
subprocess.check_call([SED_PATH, '-i', '-e',
|
"s/#AuthorizedKeysFile %h\/.ssh\/authorized_keys/" + \
|
||||||
's/#AuthorizedKeysFile %h\/.ssh\/authorized_keys/' + \
|
"AuthorizedKeysFile " + sshdir + "\/authorized_keys/",
|
||||||
'AuthorizedKeysFile ' + sshdir + '\/authorized_keys/',
|
|
||||||
sshdcfg])
|
sshdcfg])
|
||||||
for f in 'ssh_host_rsa_key', 'ssh_host_rsa_key.pub', 'authorized_keys':
|
for f in "ssh_host_rsa_key", "ssh_host_rsa_key.pub", "authorized_keys":
|
||||||
src = os.path.join(keypath, f)
|
src = os.path.join(keypath, f)
|
||||||
dst = os.path.join(self.mountdir, self.etcdir, 'ssh', f)
|
dst = os.path.join(self.mountdir, self.etcdir, "ssh", f)
|
||||||
shutil.copy(src, dst)
|
shutil.copy(src, dst)
|
||||||
if f[-3:] != "pub":
|
if f[-3:] != "pub":
|
||||||
os.chmod(dst, 0600)
|
os.chmod(dst, 0600)
|
||||||
|
@ -428,16 +423,16 @@ class XenNode(PyCoreNode):
|
||||||
Instantiate it now, so we can add network interfaces,
|
Instantiate it now, so we can add network interfaces,
|
||||||
pause it so we can have the filesystem open for configuration.
|
pause it so we can have the filesystem open for configuration.
|
||||||
"""
|
"""
|
||||||
args = [XM_PATH, 'create', os.devnull, '--paused']
|
args = [XM_PATH, "create", os.devnull, "--paused"]
|
||||||
args.extend(['name=' + self.vmname, 'memory=' + str(self.ramsize)])
|
args.extend(["name=" + self.vmname, "memory=" + str(self.ramsize)])
|
||||||
args.append('disk=tap:aio:' + self.isofile + ',hda,r')
|
args.append("disk=tap:aio:" + self.isofile + ",hda,r")
|
||||||
args.append('disk=phy:' + self.lvpath + ',hdb,w')
|
args.append("disk=phy:" + self.lvpath + ",hdb,w")
|
||||||
args.append('bootloader=pygrub')
|
args.append("bootloader=pygrub")
|
||||||
bootargs = '--kernel=/isolinux/vmlinuz --ramdisk=/isolinux/initrd'
|
bootargs = "--kernel=/isolinux/vmlinuz --ramdisk=/isolinux/initrd"
|
||||||
args.append('bootargs=' + bootargs)
|
args.append("bootargs=" + bootargs)
|
||||||
for action in ('poweroff', 'reboot', 'suspend', 'crash', 'halt'):
|
for action in ("poweroff", "reboot", "suspend", "crash", "halt"):
|
||||||
args.append('on_%s=destroy' % action)
|
args.append("on_%s=destroy" % action)
|
||||||
args.append('extra=' + self.getconfigitem('xm_create_extra'))
|
args.append("extra=" + self.getconfigitem("xm_create_extra"))
|
||||||
utils.mutecheck_call(args)
|
utils.mutecheck_call(args)
|
||||||
|
|
||||||
# from class LxcNode
|
# from class LxcNode
|
||||||
|
@ -456,7 +451,7 @@ class XenNode(PyCoreNode):
|
||||||
def openpausednodefile(self, filename, mode="w"):
|
def openpausednodefile(self, filename, mode="w"):
|
||||||
dirname, basename = os.path.split(filename)
|
dirname, basename = os.path.split(filename)
|
||||||
if not basename:
|
if not basename:
|
||||||
raise ValueError, "no basename for filename: " + filename
|
raise ValueError("no basename for filename: %s" % filename)
|
||||||
if dirname and dirname[0] == "/":
|
if dirname and dirname[0] == "/":
|
||||||
dirname = dirname[1:]
|
dirname = dirname[1:]
|
||||||
# dirname = dirname.replace("/", ".")
|
# dirname = dirname.replace("/", ".")
|
||||||
|
@ -468,16 +463,16 @@ class XenNode(PyCoreNode):
|
||||||
|
|
||||||
# from class LxcNode
|
# from class LxcNode
|
||||||
def nodefile(self, filename, contents, mode=0644):
|
def nodefile(self, filename, contents, mode=0644):
|
||||||
if filename in self.FilesToIgnore:
|
if filename in self.files_to_ignore:
|
||||||
# self.warn("XEN PVM nodefile(filename=%s) ignored" % [filename])
|
# self.warn("XEN PVM nodefile(filename=%s) ignored" % [filename])
|
||||||
return
|
return
|
||||||
|
|
||||||
if filename in self.FilesRedirection:
|
if filename in self.files_redirection:
|
||||||
redirFilename = self.FilesRedirection[filename]
|
redirection_filename = self.files_redirection[filename]
|
||||||
logger.warn("XEN PVM nodefile(filename=%s) redirected to %s" % (filename, redirFilename))
|
logger.warn("XEN PVM nodefile(filename=%s) redirected to %s", filename, redirection_filename)
|
||||||
filename = redirFilename
|
filename = redirection_filename
|
||||||
|
|
||||||
logger.warn("XEN PVM nodefile(filename=%s) called" % [filename])
|
logger.warn("XEN PVM nodefile(filename=%s) called", filename)
|
||||||
self.lock.acquire()
|
self.lock.acquire()
|
||||||
if not self.up:
|
if not self.up:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
@ -492,7 +487,7 @@ class XenNode(PyCoreNode):
|
||||||
f.write(contents)
|
f.write(contents)
|
||||||
os.chmod(f.name, mode)
|
os.chmod(f.name, mode)
|
||||||
f.close()
|
f.close()
|
||||||
logger.info("created nodefile: '%s'; mode: 0%o" % (f.name, mode))
|
logger.info("created nodefile: %s; mode: 0%o", f.name, mode)
|
||||||
finally:
|
finally:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
|
@ -502,33 +497,33 @@ class XenNode(PyCoreNode):
|
||||||
return False # XXX
|
return False # XXX
|
||||||
|
|
||||||
def cmd(self, args, wait=True):
|
def cmd(self, args, wait=True):
|
||||||
cmdAsString = string.join(args, ' ')
|
cmd_string = string.join(args, " ")
|
||||||
if cmdAsString in self.CmdsToIgnore:
|
if cmd_string in self.cmds_to_ignore:
|
||||||
# self.warn("XEN PVM cmd(args=[%s]) called and ignored" % cmdAsString)
|
# self.warn("XEN PVM cmd(args=[%s]) called and ignored" % cmdAsString)
|
||||||
return 0
|
return 0
|
||||||
if cmdAsString in self.CmdsRedirection:
|
if cmd_string in self.cmds_redirection:
|
||||||
self.CmdsRedirection[cmdAsString](self)
|
self.cmds_redirection[cmd_string](self)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
logger("XEN PVM cmd(args=[%s]) called, but not yet implemented" % cmdAsString)
|
logger("XEN PVM cmd(args=[%s]) called, but not yet implemented", cmd_string)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def cmdresult(self, args):
|
def cmdresult(self, args):
|
||||||
cmdAsString = string.join(args, ' ')
|
cmd_string = string.join(args, " ")
|
||||||
if cmdAsString in self.CmdsToIgnore:
|
if cmd_string in self.cmds_to_ignore:
|
||||||
# self.warn("XEN PVM cmd(args=[%s]) called and ignored" % cmdAsString)
|
# self.warn("XEN PVM cmd(args=[%s]) called and ignored" % cmdAsString)
|
||||||
return 0, ""
|
return 0, ""
|
||||||
logger.warn("XEN PVM cmdresult(args=[%s]) called, but not yet implemented" % cmdAsString)
|
logger.warn("XEN PVM cmdresult(args=[%s]) called, but not yet implemented", cmd_string)
|
||||||
return 0, ""
|
return 0, ""
|
||||||
|
|
||||||
def popen(self, args):
|
def popen(self, args):
|
||||||
cmdAsString = string.join(args, ' ')
|
cmd_string = string.join(args, " ")
|
||||||
logger.warn("XEN PVM popen(args=[%s]) called, but not yet implemented" % cmdAsString)
|
logger.warn("XEN PVM popen(args=[%s]) called, but not yet implemented", cmd_string)
|
||||||
return
|
return
|
||||||
|
|
||||||
def icmd(self, args):
|
def icmd(self, args):
|
||||||
cmdAsString = string.join(args, ' ')
|
cmd_string = string.join(args, " ")
|
||||||
logger.warn("XEN PVM icmd(args=[%s]) called, but not yet implemented" % cmdAsString)
|
logger.warn("XEN PVM icmd(args=[%s]) called, but not yet implemented", cmd_string)
|
||||||
return
|
return
|
||||||
|
|
||||||
def term(self, sh="/bin/sh"):
|
def term(self, sh="/bin/sh"):
|
||||||
|
@ -537,30 +532,30 @@ class XenNode(PyCoreNode):
|
||||||
|
|
||||||
def termcmdstring(self, sh="/bin/sh"):
|
def termcmdstring(self, sh="/bin/sh"):
|
||||||
"""
|
"""
|
||||||
We may add 'sudo' to the command string because the GUI runs as a
|
We may add "sudo" to the command string because the GUI runs as a
|
||||||
normal user. Use SSH if control interface is available, otherwise
|
normal user. Use SSH if control interface is available, otherwise
|
||||||
use Xen console with a keymapping for easy login.
|
use Xen console with a keymapping for easy login.
|
||||||
"""
|
"""
|
||||||
controlifc = None
|
controlifc = None
|
||||||
for ifc in self.netifs():
|
for ifc in self.netifs():
|
||||||
if hasattr(ifc, 'control') and ifc.control == True:
|
if hasattr(ifc, "control") and ifc.control is True:
|
||||||
controlifc = ifc
|
controlifc = ifc
|
||||||
break
|
break
|
||||||
cmd = "xterm "
|
cmd = "xterm "
|
||||||
# use SSH if control interface is available
|
# use SSH if control interface is available
|
||||||
if controlifc:
|
if controlifc:
|
||||||
controlip = controlifc.addrlist[0].split('/')[0]
|
controlip = controlifc.addrlist[0].split("/")[0]
|
||||||
cmd += "-e ssh root@%s" % controlip
|
cmd += "-e ssh root@%s" % controlip
|
||||||
return cmd
|
return cmd
|
||||||
# otherwise use 'xm console'
|
# otherwise use "xm console"
|
||||||
# pw = self.getconfigitem('root_password')
|
# pw = self.getconfigitem("root_password")
|
||||||
# cmd += "-xrm 'XTerm*VT100.translations: #override <Key>F1: "
|
# cmd += "-xrm "XTerm*VT100.translations: #override <Key>F1: "
|
||||||
# cmd += "string(\"root\\n\") \\n <Key>F2: string(\"%s\\n\")' " % pw
|
# cmd += "string(\"root\\n\") \\n <Key>F2: string(\"%s\\n\")" " % pw
|
||||||
cmd += "-e sudo %s console %s" % (XM_PATH, self.vmname)
|
cmd += "-e sudo %s console %s" % (XM_PATH, self.vmname)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def shcmd(self, cmdstr, sh="/bin/sh"):
|
def shcmd(self, cmdstr, sh="/bin/sh"):
|
||||||
logger("XEN PVM shcmd(args=[%s]) called, but not yet implemented" % cmdstr)
|
logger("XEN PVM shcmd(args=[%s]) called, but not yet implemented", cmdstr)
|
||||||
return
|
return
|
||||||
|
|
||||||
def mount(self, source, target):
|
def mount(self, source, target):
|
||||||
|
@ -595,8 +590,7 @@ class XenNode(PyCoreNode):
|
||||||
PyCoreNode.delnetif(self, ifindex)
|
PyCoreNode.delnetif(self, ifindex)
|
||||||
|
|
||||||
def newveth(self, ifindex=None, ifname=None, net=None, hwaddr=None):
|
def newveth(self, ifindex=None, ifname=None, net=None, hwaddr=None):
|
||||||
logger.warn("XEN PVM newveth(ifindex=%s, ifname=%s) called" %
|
logger.warn("XEN PVM newveth(ifindex=%s, ifname=%s) called", ifindex, ifname)
|
||||||
(ifindex, ifname))
|
|
||||||
|
|
||||||
self.lock.acquire()
|
self.lock.acquire()
|
||||||
try:
|
try:
|
||||||
|
@ -656,8 +650,7 @@ class XenNode(PyCoreNode):
|
||||||
addr = self.getaddr(self.ifname(ifindex), rescan=True)
|
addr = self.getaddr(self.ifname(ifindex), rescan=True)
|
||||||
for t in addrtypes:
|
for t in addrtypes:
|
||||||
if t not in self.valid_deladdrtype:
|
if t not in self.valid_deladdrtype:
|
||||||
raise ValueError, "addr type must be in: " + \
|
raise ValueError("addr type must be in: " + " ".join(self.valid_deladdrtype))
|
||||||
" ".join(self.valid_deladdrtype)
|
|
||||||
for a in addr[t]:
|
for a in addr[t]:
|
||||||
self.deladdr(ifindex, a)
|
self.deladdr(ifindex, a)
|
||||||
# update cached information
|
# update cached information
|
||||||
|
@ -668,10 +661,8 @@ class XenNode(PyCoreNode):
|
||||||
# if self.up:
|
# if self.up:
|
||||||
# self.cmd([IP_BIN, "link", "set", self.ifname(ifindex), "up"])
|
# self.cmd([IP_BIN, "link", "set", self.ifname(ifindex), "up"])
|
||||||
|
|
||||||
def newnetif(self, net=None, addrlist=[], hwaddr=None,
|
def newnetif(self, net=None, addrlist=[], hwaddr=None, ifindex=None, ifname=None):
|
||||||
ifindex=None, ifname=None):
|
logger.warn("XEN PVM newnetif(ifindex=%s, ifname=%s) called", ifindex, ifname)
|
||||||
logger.warn("XEN PVM newnetif(ifindex=%s, ifname=%s) called" %
|
|
||||||
(ifindex, ifname))
|
|
||||||
|
|
||||||
self.lock.acquire()
|
self.lock.acquire()
|
||||||
|
|
||||||
|
@ -705,18 +696,18 @@ class XenNode(PyCoreNode):
|
||||||
if net is not None:
|
if net is not None:
|
||||||
self.attachnet(ifindex, net)
|
self.attachnet(ifindex, net)
|
||||||
|
|
||||||
rulefile = os.path.join(self.getconfigitem('mount_path'),
|
rulefile = os.path.join(self.getconfigitem("mount_path"),
|
||||||
self.etcdir,
|
self.etcdir,
|
||||||
'udev/rules.d/70-persistent-net.rules')
|
"udev/rules.d/70-persistent-net.rules")
|
||||||
f = self.openpausednodefile(rulefile, "a")
|
f = self.openpausednodefile(rulefile, "a")
|
||||||
f.write(
|
f.write(
|
||||||
'\n# Xen PVM virtual interface #%s %s with MAC address %s\n' % (ifindex, self.ifname(ifindex), hwaddr))
|
"\n# Xen PVM virtual interface #%s %s with MAC address %s\n" % (ifindex, self.ifname(ifindex), hwaddr))
|
||||||
# Using MAC address as we're now loading PVM net driver "early"
|
# Using MAC address as we"re now loading PVM net driver "early"
|
||||||
# OLD: Would like to use MAC address, but udev isn't working with paravirtualized NICs. Perhaps the "set hw address" isn't triggering a rescan.
|
# OLD: Would like to use MAC address, but udev isn"t working with paravirtualized NICs. Perhaps the "set hw address" isn"t triggering a rescan.
|
||||||
f.write(
|
f.write(
|
||||||
'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", KERNEL=="eth*", NAME="%s"\n' % (
|
'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", KERNEL=="eth*", NAME="%s"\n' % (
|
||||||
hwaddr, self.ifname(ifindex)))
|
hwaddr, self.ifname(ifindex)))
|
||||||
# f.write('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", DEVPATH=="/devices/vif-%s/?*", KERNEL=="eth*", NAME="%s"\n' % (ifindex, self.ifname(ifindex)))
|
# f.write("SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", DEVPATH=="/devices/vif-%s/?*", KERNEL=="eth*", NAME="%s"\n" % (ifindex, self.ifname(ifindex)))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
if hwaddr:
|
if hwaddr:
|
||||||
|
@ -748,7 +739,7 @@ class XenNode(PyCoreNode):
|
||||||
# othernode.addnetif(PyCoreNetIf(othernode, otherifname),
|
# othernode.addnetif(PyCoreNetIf(othernode, otherifname),
|
||||||
# othernode.newifindex())
|
# othernode.newifindex())
|
||||||
|
|
||||||
def addfile(self, srcname, filename):
|
def addfile(self, srcname, filename, mode=0644):
|
||||||
self.lock.acquire()
|
self.lock.acquire()
|
||||||
if not self.up:
|
if not self.up:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
@ -758,14 +749,14 @@ class XenNode(PyCoreNode):
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
raise Exception("Can't access VM file as VM is already running")
|
raise Exception("Can't access VM file as VM is already running")
|
||||||
|
|
||||||
if filename in self.FilesToIgnore:
|
if filename in self.files_to_ignore:
|
||||||
# self.warn("XEN PVM addfile(filename=%s) ignored" % [filename])
|
# self.warn("XEN PVM addfile(filename=%s) ignored" % [filename])
|
||||||
return
|
return
|
||||||
|
|
||||||
if filename in self.FilesRedirection:
|
if filename in self.files_redirection:
|
||||||
redirFilename = self.FilesRedirection[filename]
|
redirection_filename = self.files_redirection[filename]
|
||||||
logger.warn("XEN PVM addfile(filename=%s) redirected to %s" % (filename, redirFilename))
|
logger.warn("XEN PVM addfile(filename=%s) redirected to %s", filename, redirection_filename)
|
||||||
filename = redirFilename
|
filename = redirection_filename
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fin = open(srcname, "r")
|
fin = open(srcname, "r")
|
||||||
|
@ -776,13 +767,13 @@ class XenNode(PyCoreNode):
|
||||||
fout.write(contents)
|
fout.write(contents)
|
||||||
os.chmod(fout.name, mode)
|
os.chmod(fout.name, mode)
|
||||||
fout.close()
|
fout.close()
|
||||||
logger.info("created nodefile: '%s'; mode: 0%o" % (fout.name, mode))
|
logger.info("created nodefile: %s; mode: 0%o", fout.name, mode)
|
||||||
finally:
|
finally:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
logger.warn("XEN PVM addfile(filename=%s) called" % [filename])
|
logger.warn("XEN PVM addfile(filename=%s) called", filename)
|
||||||
|
|
||||||
# shcmd = "mkdir -p $(dirname '%s') && mv '%s' '%s' && sync" % \
|
# shcmd = "mkdir -p $(dirname "%s") && mv "%s" "%s" && sync" % \
|
||||||
# (filename, srcname, filename)
|
# (filename, srcname, filename)
|
||||||
# self.shcmd(shcmd)
|
# self.shcmd(shcmd)
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ xenconfig.py: Implementation of the XenConfigManager class for managing
|
||||||
configurable items for XenNodes.
|
configurable items for XenNodes.
|
||||||
|
|
||||||
Configuration for a XenNode is available at these three levels:
|
Configuration for a XenNode is available at these three levels:
|
||||||
Global config: XenConfigManager.configs[0] = (type='xen', values)
|
Global config: XenConfigManager.configs[0] = (type="xen", values)
|
||||||
Nodes of this machine type have this config. These are the default values.
|
Nodes of this machine type have this config. These are the default values.
|
||||||
XenConfigManager.default_config comes from defaults + xen.conf
|
XenConfigManager.default_config comes from defaults + xen.conf
|
||||||
Node type config: XenConfigManager.configs[0] = (type='mytype', values)
|
Node type config: XenConfigManager.configs[0] = (type="mytype", values)
|
||||||
All nodes of this type have this config.
|
All nodes of this type have this config.
|
||||||
Node-specific config: XenConfigManager.configs[nodenumber] = (type, values)
|
Node-specific config: XenConfigManager.configs[nodenumber] = (type, values)
|
||||||
The node having this specific number has this config.
|
The node having this specific number has this config.
|
||||||
|
@ -50,27 +50,43 @@ class XenConfigManager(ConfigurableManager):
|
||||||
|
|
||||||
def setconfig(self, nodenum, conftype, values):
|
def setconfig(self, nodenum, conftype, values):
|
||||||
"""
|
"""
|
||||||
add configuration values for a node to a dictionary; values are
|
Add configuration values for a node to a dictionary; values are
|
||||||
usually received from a Configuration Message, and may refer to a
|
usually received from a Configuration Message, and may refer to a
|
||||||
node for which no object exists yet
|
node for which no object exists yet
|
||||||
|
|
||||||
|
:param int nodenum: node id to configure
|
||||||
|
:param str conftype: configuration type
|
||||||
|
:param tuple values: values to configure
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
# used for storing the global default config
|
||||||
if nodenum is None:
|
if nodenum is None:
|
||||||
nodenum = 0 # used for storing the global default config
|
nodenum = 0
|
||||||
return ConfigurableManager.setconfig(self, nodenum, conftype, values)
|
return ConfigurableManager.setconfig(self, nodenum, conftype, values)
|
||||||
|
|
||||||
def getconfig(self, nodenum, conftype, defaultvalues):
|
def getconfig(self, nodenum, conftype, defaultvalues):
|
||||||
"""
|
"""
|
||||||
get configuration values for a node; if the values don't exist in
|
Get configuration values for a node; if the values don"t exist in
|
||||||
our dictionary then return the default values supplied; if conftype
|
our dictionary then return the default values supplied; if conftype
|
||||||
is None then we return a match on any conftype.
|
is None then we return a match on any conftype.
|
||||||
|
|
||||||
|
:param int nodenum: node id to configure
|
||||||
|
:param str conftype: configuration type
|
||||||
|
:param tuple defaultvalues: default values to return
|
||||||
|
:return: configuration for node and config type
|
||||||
|
:rtype: tuple
|
||||||
"""
|
"""
|
||||||
|
# used for storing the global default config
|
||||||
if nodenum is None:
|
if nodenum is None:
|
||||||
nodenum = 0 # used for storing the global default config
|
nodenum = 0
|
||||||
return ConfigurableManager.getconfig(self, nodenum, conftype, defaultvalues)
|
return ConfigurableManager.getconfig(self, nodenum, conftype, defaultvalues)
|
||||||
|
|
||||||
def clearconfig(self, nodenum):
|
def clearconfig(self, nodenum):
|
||||||
"""
|
"""
|
||||||
remove configuration values for a node
|
Remove configuration values for a node
|
||||||
|
|
||||||
|
:param int nodenum: node id to clear config
|
||||||
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
ConfigurableManager.clearconfig(self, nodenum)
|
ConfigurableManager.clearconfig(self, nodenum)
|
||||||
if 0 in self.configs:
|
if 0 in self.configs:
|
||||||
|
@ -87,16 +103,19 @@ class XenConfigManager(ConfigurableManager):
|
||||||
def loadconfigfile(self, filename=None):
|
def loadconfigfile(self, filename=None):
|
||||||
"""
|
"""
|
||||||
Load defaults from the /etc/core/xen.conf file into dict object.
|
Load defaults from the /etc/core/xen.conf file into dict object.
|
||||||
|
|
||||||
|
:param str filename: file name of configuration to load
|
||||||
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
if filename is None:
|
if filename is None:
|
||||||
filename = os.path.join(constants.CORE_CONF_DIR, 'xen.conf')
|
filename = os.path.join(constants.CORE_CONF_DIR, "xen.conf")
|
||||||
cfg = ConfigParser.SafeConfigParser()
|
cfg = ConfigParser.SafeConfigParser()
|
||||||
if filename not in cfg.read(filename):
|
if filename not in cfg.read(filename):
|
||||||
logger.warn("unable to read Xen config file: %s" % filename)
|
logger.warn("unable to read Xen config file: %s", filename)
|
||||||
return
|
return
|
||||||
section = "xen"
|
section = "xen"
|
||||||
if not cfg.has_section(section):
|
if not cfg.has_section(section):
|
||||||
logger.warn("%s is missing a xen section!" % filename)
|
logger.warn("%s is missing a xen section!", filename)
|
||||||
return
|
return
|
||||||
self.configfile = dict(cfg.items(section))
|
self.configfile = dict(cfg.items(section))
|
||||||
# populate default config items from config file entries
|
# populate default config items from config file entries
|
||||||
|
@ -105,7 +124,7 @@ class XenConfigManager(ConfigurableManager):
|
||||||
for i in range(len(names)):
|
for i in range(len(names)):
|
||||||
if names[i] in self.configfile:
|
if names[i] in self.configfile:
|
||||||
vals[i] = self.configfile[names[i]]
|
vals[i] = self.configfile[names[i]]
|
||||||
# this sets XenConfigManager.configs[0] = (type='xen', vals)
|
# this sets XenConfigManager.configs[0] = (type="xen", vals)
|
||||||
self.setconfig(None, self.default_config.name, vals)
|
self.setconfig(None, self.default_config.name, vals)
|
||||||
|
|
||||||
def getconfigitem(self, name, model=None, node=None, value=None):
|
def getconfigitem(self, name, model=None, node=None, value=None):
|
||||||
|
@ -113,6 +132,12 @@ class XenConfigManager(ConfigurableManager):
|
||||||
Get a config item of the given name, first looking for node-specific
|
Get a config item of the given name, first looking for node-specific
|
||||||
configuration, then model specific, and finally global defaults.
|
configuration, then model specific, and finally global defaults.
|
||||||
If a value is supplied, it will override any stored config.
|
If a value is supplied, it will override any stored config.
|
||||||
|
|
||||||
|
:param str name: name of config item to get
|
||||||
|
:param model: model config to get
|
||||||
|
:param node: node config to get
|
||||||
|
:param value: value to override stored config, if provided
|
||||||
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
if value is not None:
|
if value is not None:
|
||||||
return value
|
return value
|
||||||
|
@ -122,13 +147,10 @@ class XenConfigManager(ConfigurableManager):
|
||||||
(t, v) = self.getconfig(nodenum=n, conftype=model, defaultvalues=None)
|
(t, v) = self.getconfig(nodenum=n, conftype=model, defaultvalues=None)
|
||||||
if n is not None and v is None:
|
if n is not None and v is None:
|
||||||
# get item from default config for the node type
|
# get item from default config for the node type
|
||||||
(t, v) = self.getconfig(nodenum=None, conftype=model,
|
(t, v) = self.getconfig(nodenum=None, conftype=model, defaultvalues=None)
|
||||||
defaultvalues=None)
|
|
||||||
if v is None:
|
if v is None:
|
||||||
# get item from default config for the machine type
|
# get item from default config for the machine type
|
||||||
(t, v) = self.getconfig(nodenum=None,
|
(t, v) = self.getconfig(nodenum=None, conftype=self.default_config.name, defaultvalues=None)
|
||||||
conftype=self.default_config.name,
|
|
||||||
defaultvalues=None)
|
|
||||||
|
|
||||||
confignames = self.default_config.getnames()
|
confignames = self.default_config.getnames()
|
||||||
if v and name in confignames:
|
if v and name in confignames:
|
||||||
|
@ -139,7 +161,7 @@ class XenConfigManager(ConfigurableManager):
|
||||||
if name in self.configfile:
|
if name in self.configfile:
|
||||||
return self.configfile[name]
|
return self.configfile[name]
|
||||||
else:
|
else:
|
||||||
# logger.warn("missing config item '%s'" % name)
|
# logger.warn("missing config item "%s"" % name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,7 +189,7 @@ class XenConfig(Configurable):
|
||||||
|
|
||||||
nodetype = object_name
|
nodetype = object_name
|
||||||
if opaque is not None:
|
if opaque is not None:
|
||||||
opaque_items = opaque.split(':')
|
opaque_items = opaque.split(":")
|
||||||
if len(opaque_items) != 2:
|
if len(opaque_items) != 2:
|
||||||
logger.warn("xen config: invalid opaque data in conf message")
|
logger.warn("xen config: invalid opaque data in conf message")
|
||||||
return None
|
return None
|
||||||
|
@ -211,7 +233,7 @@ class XenConfig(Configurable):
|
||||||
values = xen.getconfig(node_id, cls.name, defaults)[1]
|
values = xen.getconfig(node_id, cls.name, defaults)[1]
|
||||||
else:
|
else:
|
||||||
# use new values supplied from the conf message
|
# use new values supplied from the conf message
|
||||||
values = values_str.split('|')
|
values = values_str.split("|")
|
||||||
xen.setconfig(node_id, nodetype, values)
|
xen.setconfig(node_id, nodetype, values)
|
||||||
|
|
||||||
return reply
|
return reply
|
||||||
|
@ -222,8 +244,15 @@ class XenConfig(Configurable):
|
||||||
Convert this class to a Config API message. Some TLVs are defined
|
Convert this class to a Config API message. Some TLVs are defined
|
||||||
by the class, but node number, conf type flags, and values must
|
by the class, but node number, conf type flags, and values must
|
||||||
be passed in.
|
be passed in.
|
||||||
|
|
||||||
|
:param int flags: configuration flags
|
||||||
|
:param int node_id: node id
|
||||||
|
:param int type_flags: type flags
|
||||||
|
:param int nodetype: node type
|
||||||
|
:param tuple values: values
|
||||||
|
:return: configuration message
|
||||||
"""
|
"""
|
||||||
values_str = string.join(values, '|')
|
values_str = string.join(values, "|")
|
||||||
tlvdata = ""
|
tlvdata = ""
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.NODE.value, node_id)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.NODE.value, node_id)
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.OBJECT.value, cls.name)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.OBJECT.value, cls.name)
|
||||||
|
@ -231,9 +260,9 @@ class XenConfig(Configurable):
|
||||||
datatypes = tuple(map(lambda x: x[1], cls.config_matrix))
|
datatypes = tuple(map(lambda x: x[1], cls.config_matrix))
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.DATA_TYPES.value, datatypes)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.DATA_TYPES.value, datatypes)
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.VALUES.value, values_str)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.VALUES.value, values_str)
|
||||||
captions = reduce(lambda a, b: a + '|' + b, map(lambda x: x[4], cls.config_matrix))
|
captions = reduce(lambda a, b: a + "|" + b, map(lambda x: x[4], cls.config_matrix))
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.CAPTIONS, captions)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.CAPTIONS, captions)
|
||||||
possiblevals = reduce(lambda a, b: a + '|' + b, map(lambda x: x[3], cls.config_matrix))
|
possiblevals = reduce(lambda a, b: a + "|" + b, map(lambda x: x[3], cls.config_matrix))
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.POSSIBLE_VALUES.value, possiblevals)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.POSSIBLE_VALUES.value, possiblevals)
|
||||||
if cls.bitmap is not None:
|
if cls.bitmap is not None:
|
||||||
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.BITMAP.value, cls.bitmap)
|
tlvdata += coreapi.CoreConfigTlv.pack(ConfigTlvs.BITMAP.value, cls.bitmap)
|
||||||
|
@ -251,24 +280,24 @@ class XenDefaultConfig(XenConfig):
|
||||||
"""
|
"""
|
||||||
name = "xen"
|
name = "xen"
|
||||||
# Configuration items:
|
# Configuration items:
|
||||||
# ('name', 'type', 'default', 'possible-value-list', 'caption')
|
# ("name", "type", "default", "possible-value-list", "caption")
|
||||||
config_matrix = [
|
config_matrix = [
|
||||||
('ram_size', ConfigDataTypes.STRING.value, '256', '',
|
("ram_size", ConfigDataTypes.STRING.value, "256", "",
|
||||||
'ram size (MB)'),
|
"ram size (MB)"),
|
||||||
('disk_size', ConfigDataTypes.STRING.value, '256M', '',
|
("disk_size", ConfigDataTypes.STRING.value, "256M", "",
|
||||||
'disk size (use K/M/G suffix)'),
|
"disk size (use K/M/G suffix)"),
|
||||||
('iso_file', ConfigDataTypes.STRING.value, '', '',
|
("iso_file", ConfigDataTypes.STRING.value, "", "",
|
||||||
'iso file'),
|
"iso file"),
|
||||||
('mount_path', ConfigDataTypes.STRING.value, '', '',
|
("mount_path", ConfigDataTypes.STRING.value, "", "",
|
||||||
'mount path'),
|
"mount path"),
|
||||||
('etc_path', ConfigDataTypes.STRING.value, '', '',
|
("etc_path", ConfigDataTypes.STRING.value, "", "",
|
||||||
'etc path'),
|
"etc path"),
|
||||||
('persist_tar_iso', ConfigDataTypes.STRING.value, '', '',
|
("persist_tar_iso", ConfigDataTypes.STRING.value, "", "",
|
||||||
'iso persist tar file'),
|
"iso persist tar file"),
|
||||||
('persist_tar', ConfigDataTypes.STRING.value, '', '',
|
("persist_tar", ConfigDataTypes.STRING.value, "", "",
|
||||||
'persist tar file'),
|
"persist tar file"),
|
||||||
('root_password', ConfigDataTypes.STRING.value, 'password', '',
|
("root_password", ConfigDataTypes.STRING.value, "password", "",
|
||||||
'root password'),
|
"root password"),
|
||||||
]
|
]
|
||||||
|
|
||||||
config_groups = "domU properties:1-%d" % len(config_matrix)
|
config_groups = "domU properties:1-%d" % len(config_matrix)
|
||||||
|
|
Loading…
Reference in a new issue