Created
January 8, 2011 11:27
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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