1
#!/usr/bin/env python2.7
2
# Copyright 2012 Canonical Ltd. This software is licensed under the
3
# GNU Affero General Public License version 3 (see the file LICENSE).
5
"""Setup a Virtual Data-center Environment."""
7
from __future__ import (
21
from Cheetah.Template import Template
26
NODES_RANGE = range(1,4)
28
def yaml_loadf(fname):
35
def __init__(self, syscfg, ident, basedir=None):
36
self.ip_pre = syscfg['network']['ip_pre']
38
basedir = os.path.abspath(os.curdir)
39
self.basedir = basedir
40
self._setcfg(syscfg,ident)
41
self.network = syscfg['network']['name']
44
return("== %s ==\n ip: %s\n mac: %s\n template: %s\n" %
45
(self.name, self.ipaddr, self.mac, self.template))
49
return("%s.%s" % (self.ip_pre, self.ipnum))
53
return("%s/%s-disk0.img" % (self.basedir, self.name))
57
# have to add the getters
58
for prop in ( "ipaddr", "disk0" ):
59
ret[prop] = getattr(self,prop)
62
def toLibVirtXml(self):
63
template = Template(file=self.template, searchList=[self.dictInfo()])
64
return template.respond()
67
def _setcfg(self, cfg, num):
69
self.name = "%s%02i" % (cfg['prefix'],num)
70
self.mac = "%s:%02x" % (cfg['mac_pre'],num)
71
self.ipnum = num + 100
72
self.template = cfg['template']
73
self.mem = cfg['mem'] * 1024
77
def _setcfg(self, cfg, ident):
78
cfg = cfg['systems'][ident]
81
self.ipnum = cfg['ip']
82
self.template = cfg['template']
83
self.mem = cfg['mem'] * 1024
85
def renderSysDom(config, syscfg, stype="node"):
86
template = Template(file=syscfg['template'], searchList=[config, syscfg])
87
return template.respond()
90
# ip: 2 # ip address must be in dhcp range
91
# mac: 00:16:3e:3e:a9:1a
92
# template: libvirt-system.tmpl
97
# mac_pre: 00:16:3e:3e:aa
100
def writeDomXmlFile(dom, outpre=""):
101
fname="%s%s.xml" % (outpre, dom.name)
102
output = open(fname,"w")
103
output.write(dom.toLibVirtXml())
107
def libvirt_setup(config):
108
conn = libvirt.open("qemu:///system")
109
netname = config['network']['name']
110
if netname in conn.listDefinedNetworks() or netname in conn.listNetworks():
111
net = conn.networkLookupByName(netname)
117
for system in config['systems']:
118
d = System(config, system)
119
allsys[d.name]=d.dictInfo()
120
for num in NODES_RANGE:
121
d = Node(config, num)
122
allsys[d.name]=d.dictInfo()
124
conn.networkDefineXML(Template(file=config['network']['template'],
125
searchList=[config['network'],
126
{'all_systems': allsys }]).respond())
128
print("defined network %s " % netname)
130
cob = System(config, "zimmer")
133
for node in NODES_RANGE:
134
systems.append(Node(config, node))
136
qcow_create = "qemu-img create -f qcow2 %s 2G"
137
defined_systems = conn.listDefinedDomains()
138
for system in systems:
139
if system.name in defined_systems:
140
dom = conn.lookupByName(system.name)
144
conn.defineXML(system.toLibVirtXml())
145
if isinstance(system,Node):
146
subprocess.check_call(qcow_create % system.disk0, shell=True)
147
print("defined domain %s" % system.name)
149
def cobbler_addsystem(server, token, system, profile, hostip):
151
"macaddress-eth0" : system.mac,
152
"ipaddress-eth0" : system.ipaddr,
153
"static-eth0" : False,
157
'hostname': system.name,
158
'power_address': "qemu+tcp://%s:65001" % hostip,
159
'power_id': system.name,
160
'power_type': "virsh",
162
'netboot_enabled': True,
163
'modify_interface': eth0,
166
if len(server.find_system({"name": system.name})):
167
server.remove_system(system.name,token)
169
print("removed existing %s" % system.name)
171
sid = server.new_system(token)
172
for key, val in items.iteritems():
173
ret = server.modify_system(sid, key, val, token)
175
raise Exception("failed for %s [%s]: %s, %s" %
176
(system.name, ret, key, val))
177
ret = server.save_system(sid,token)
179
raise Exception("failed to save %s" % system.name)
180
print("added %s" % system.name)
183
def get_profile_arch():
184
"""Get the system architecture for use in the cobbler setup profile."""
185
# This should, for any given system, match what the zimmer-build
186
# script does to determine the right architecture.
187
arch_text = subprocess.check_output(['/bin/uname', '-m']).strip()
188
if re.match('i.86', arch_text):
194
def cobbler_setup(config):
195
hostip = "%s.1" % config['network']['ip_pre']
196
arch = get_profile_arch()
197
profile = "maas-precise-%s" % arch
199
cob = System(config, "zimmer")
200
cobbler_url = "http://%s/cobbler_api" % cob.ipaddr
201
print("Connecting to %s." % cobbler_url)
202
server = xmlrpclib.Server(cobbler_url)
203
token = server.login("cobbler","xcobbler")
205
systems = [Node(config, node) for node in NODES_RANGE]
207
for system in systems:
208
cobbler_addsystem(server, token, system, profile, hostip)
211
outpre = "libvirt-cobbler-"
212
cfg_file = "settings.cfg"
214
if len(sys.argv) == 1:
216
"Usage: setup.py action\n"
217
"action one of: libvirt-setup, cobbler-setup")
220
config = yaml_loadf(cfg_file)
222
if sys.argv[1] == "libvirt-setup":
223
libvirt_setup(config)
224
elif sys.argv[1] == "cobbler-setup":
225
cobbler_setup(config)
227
if __name__ == '__main__':