Skip to content

Instantly share code, notes, and snippets.

@stfp
Created January 8, 2011 11:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stfp/770767 to your computer and use it in GitHub Desktop.
Save stfp/770767 to your computer and use it in GitHub Desktop.
installs an open nebula image from the repository to a new lvm volume in each host
#!/usr/bin/python
import os, sys
import logging
import hashlib
from xmlrpclib import ServerProxy
import xml2obj
ONE_SERVER="http://localhost:2633/RPC2"
ONE_USER="oneadmin"
ONE_PASSWORD="onepassword"
SSH_KEY_FILE="/srv/cloud/one/.ssh/id_rsa"
SSH_USERNAME="oneadmin"
VG_NAME="vg1"
class OneServer(ServerProxy):
def __init__(self, url, username, password):
ServerProxy.__init__(self, url)
self.session = "%s:%s" % (username, hashlib.sha1(password).hexdigest())
def call(self, method, *args):
result = getattr(self, method)(self.session, *args)
if result[0]:
return xml2obj.xml2obj(result[1])
else:
raise Exception("OneServer call exception")
def list_images(server):
pool = server.call("one.imagepool.info", -2)
print "Images in open nebula:"
print "----------------------"
for img in pool.image:
print img.id, img.template.description
def get_hostname_list(server):
pool = server.call("one.hostpool.info", -2)
res = []
for host in pool.host:
res.append(host.template.hostname)
return res
def run_on_host(hostname, cmd, prefix=""):
logging.info("[%s]: %s %s", hostname, prefix, cmd)
os.system('%s ssh -i %s %s@%s "%s"' % (prefix, SSH_KEY_FILE, SSH_USERNAME, hostname, cmd))
def run_on_hosts(hosts, cmd, prefix=""):
for hn in hosts:
run_on_host(hn, cmd, prefix)
def main():
server = OneServer(ONE_SERVER, ONE_USER, ONE_PASSWORD)
if len(sys.argv) != 2:
print "Usage: %s img-ig" % (sys.argv[0])
print "Creates a lvm volume and copies the specified image into it, on all the hosts declared in opennebula"
print ""
list_images(server)
print ""
sys.exit(0)
imgid = int(sys.argv[1])
imginfo = server.call("one.image.info", imgid)
imgsize = os.stat(imginfo["source"]).st_size
logging.info("image id: %s name: %s source: %s size: %d" % (imginfo["id"], imginfo["name"], imginfo["source"], imgsize))
hosts = get_hostname_list(server)
run_on_hosts(hosts, "sudo /sbin/lvcreate -n one-img-%d -L %dB %s" % (imgid, imgsize, VG_NAME))
run_on_hosts(hosts, "sudo dd of=/dev/%s/one-img-%d" % (VG_NAME, imgid), prefix="cat %s |" % (imginfo["source"]))
if __name__ == "__main__":
main()
import re
import xml.sax.handler
def xml2obj(src):
"""
A simple function to converts XML data into native Python object.
"""
non_id_char = re.compile('[^_0-9a-zA-Z]')
def _name_mangle(name):
return non_id_char.sub('_', name).lower()
class DataNode(object):
def __init__(self):
self._attrs = {} # XML attributes and child elements
self.data = None # child text data
def __len__(self):
# treat single element as a list of 1
return 1
def __getitem__(self, key):
if isinstance(key, basestring):
return self._attrs.get(key,None)
else:
return [self][key]
def __contains__(self, name):
return self._attrs.has_key(name)
def __nonzero__(self):
return bool(self._attrs or self.data)
def __getattr__(self, name):
if name.startswith('__'):
# need to do this for Python special methods???
raise AttributeError(name)
return self._attrs.get(name,None)
def _add_xml_attr(self, name, value):
if name in self._attrs:
# multiple attribute of the same name are represented by a list
children = self._attrs[name]
if not isinstance(children, list):
children = [children]
self._attrs[name] = children
children.append(value)
else:
self._attrs[name] = value
def __str__(self):
return self.data or ''
def __repr__(self):
items = sorted(self._attrs.items())
if self.data:
items.append(('data', self.data))
return u'{%s}' % ', '.join([u'%s:%s' % (k,repr(v)) for k,v in items])
class TreeBuilder(xml.sax.handler.ContentHandler):
def __init__(self):
self.stack = []
self.root = DataNode()
self.current = self.root
self.text_parts = []
def startElement(self, name, attrs):
self.stack.append((self.current, self.text_parts))
self.current = DataNode()
self.text_parts = []
# xml attributes --> python attributes
for k, v in attrs.items():
self.current._add_xml_attr(_name_mangle(k), v)
def endElement(self, name):
text = ''.join(self.text_parts).strip()
if text:
self.current.data = text
if self.current._attrs:
obj = self.current
else:
# a text only node is simply represented by the string
obj = text or ''
self.current, self.text_parts = self.stack.pop()
self.current._add_xml_attr(_name_mangle(name), obj)
def characters(self, content):
self.text_parts.append(content)
builder = TreeBuilder()
if isinstance(src,basestring):
xml.sax.parseString(src, builder)
else:
xml.sax.parse(src, builder)
return builder.root._attrs.values()[0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment