Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 210 lines (187 sloc) 6.9 kb
#!/usr/bin/env python
# Common functions for managing statically-attached (ie onboot, without xapi) VDIs
import sys, os, subprocess
import XenAPI, inventory, xmlrpclib
main_dir = "@ETCDIR@/static-vdis"
def read_whole_file(filename):
f = open(filename)
try:
return reduce(lambda x, y: x + y, f.readlines(), "").strip()
finally:
f.close()
def write_whole_file(filename, contents):
f = open(filename, "w")
try:
f.write(contents)
finally:
f.close()
def load(name):
"""Return a dictionary describing a single static VDI"""
d = { "id": name }
for key in [ "vdi-uuid", "config", "reason" ]:
d[key] = read_whole_file("%s/%s/%s" % (main_dir, name, key))
try:
disk = "%s/%s/disk" % (main_dir, name)
os.stat(disk) # throws an error if missing
d["disk"] = os.readlink(disk)
except:
pass
dnb = "False"
try:
os.stat("%s/%s/delete-next-boot" % (main_dir, name))
dnb = "True"
except:
pass
d["delete-next-boot"] = dnb
return d
def list():
all = []
try:
all = os.listdir(main_dir)
except:
pass
return map(load, all)
def fresh_name():
all = []
try:
all = os.listdir(main_dir)
for i in range(0, len(all) + 1): # guarantees to find a unique number
i = str(i)
if not(i in all):
return i
except:
# Directory doesn't exist
os.mkdir(main_dir)
return "0"
def to_string_list(d):
keys = [ "vdi-uuid", "reason", "currently-attached", "delete-next-boot" "path" ]
m = 0
for key in keys:
if len(key) > m:
m = m + len(key)
def left(key, value):
return key + (" " * (m - len(key))) + ": " + value
def right(key, value):
return (" " * (m - len(key))) + key + ": " + value
l = [ left("vdi-uuid", d["vdi-uuid"]), right("reason", d["reason"]) ]
l.append(right("delete-next-boot", d["delete-next-boot"]))
if d.has_key("disk"):
l.append(right("currently-attached", "True"))
l.append(right("path", d['disk']))
else:
l.append(right("currently-attached", "False"))
return l
def add(session, vdi_uuid, reason):
for existing in list():
if existing['vdi-uuid'] == vdi_uuid:
if existing['delete-next-boot'] == "True":
# Undo the 'delete-next-boot' flag to reinstitute
path = main_dir + "/" + existing['id']
os.unlink(path + "/delete-next-boot")
os.unlink(path + "/reason")
write_whole_file(path + "/reason", reason)
# Assume config is still valid
return
raise "Static configuration for VDI already exists"
vdi = session.xenapi.VDI.get_by_uuid(vdi_uuid)
host = session.xenapi.host.get_by_uuid(inventory.get_localhost_uuid ())
config = None
try:
config = session.xenapi.VDI.generate_config(host, vdi)
except XenAPI.Failure, e:
raise "Failed generating static config file: %s" % (str(e))
sr = session.xenapi.VDI.get_SR(vdi)
ty = session.xenapi.SR.get_type(sr)
filename = None
all_sm = session.xenapi.SM.get_all_records()
for sm_ref in all_sm.keys():
if all_sm[sm_ref]['type'] == ty:
filename = session.xenapi.SM.get_driver_filename(sm_ref)
if filename == None:
raise "Unable to discover SM plugin driver filename"
# Make a fresh directory in main_dir to store the configuration. Note
# there is no locking so please run this script serially.
fresh = fresh_name()
path = main_dir + "/" + fresh
os.mkdir(path)
write_whole_file(path + "/vdi-uuid", vdi_uuid)
write_whole_file(path + "/config", config)
write_whole_file(path + "/reason", reason)
os.symlink(filename, path + "/driver")
def delete(vdi_uuid):
found = False
for existing in list():
if existing['vdi-uuid'] == vdi_uuid:
found = True
path = main_dir + "/" + existing['id']
f = open(path + "/delete-next-boot", "w")
f.close()
# If not currently attached then zap the whole tree
if not(existing.has_key("disk")):
os.system("/bin/rm -rf %s" % path)
if not found:
raise "Disk configuration not found"
# Copied by util.py
def doexec(args, inputtext=None):
"""Execute a subprocess, then return its return code, stdout and stderr"""
proc = subprocess.Popen(args,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
(stdout,stderr) = proc.communicate(inputtext)
rc = proc.returncode
return (rc,stdout,stderr)
def call_backend_attach(driver, config):
xml = doexec([ driver, config ])
if xml[0] <> 0:
raise "SM_BACKEND_FAILURE(%d, %s, %s)" % xml
xmlrpc = xmlrpclib.loads(xml[1])
try:
path = xmlrpc[0][0]['params']
except:
path = xmlrpc[0][0]
return path
def attach(vdi_uuid):
found = False
for existing in list():
if existing['vdi-uuid'] == vdi_uuid:
found = True
if not(existing.has_key('path')):
d = main_dir + "/" + existing['id']
# Delete any old symlink
try:
os.unlink(d + "/disk")
except:
pass
config = read_whole_file(d + "/config")
path = call_backend_attach(d + "/driver", config)
os.symlink(path, d + "/disk")
return d + "/disk"
if not found:
raise "Disk configuration not found"
def usage():
print "Usage:"
print " %s list -- print a list of VDIs which will be attached on host boot" % sys.argv[0]
print " %s add <uuid> <reason> -- make the VDI <uuid> available on host boot" % sys.argv[0]
print " %s del <uuid> -- cease making the VDI <uuid> available on host boot" % sys.argv[0]
print " %s attach <uuid> -- attach the VDI immediately" % sys.argv[0]
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) < 2:
usage()
if sys.argv[1] == "list" and len(sys.argv) == 2:
for i in list ():
for line in to_string_list(i):
print line
print
elif sys.argv[1] == "add" and len(sys.argv) == 4:
session = XenAPI.xapi_local()
session.xenapi.login_with_password("root", "")
try:
add(session, sys.argv[2], sys.argv[3])
finally:
session.xenapi.logout()
elif sys.argv[1] == "del" and len(sys.argv) == 3:
delete(sys.argv[2])
elif sys.argv[1] == "attach" and len(sys.argv) == 3:
path = attach(sys.argv[2])
print path
else:
usage()
Jump to Line
Something went wrong with that request. Please try again.