~rvb/maas/component-bug-1307415-1.5

« back to all changes in this revision

Viewing changes to vdenv/setup.py

  • Committer: Gavin Panella
  • Date: 2013-06-05 10:44:25 UTC
  • mto: This revision was merged to the branch mainline in revision 1514.
  • Revision ID: gavin.panella@canonical.com-20130605104425-153uddpy8c1wg2yz
Drop vdenv as unused.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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).
4
 
 
5
 
"""Setup a Virtual Data-center Environment."""
6
 
 
7
 
from __future__ import (
8
 
    absolute_import,
9
 
    print_function,
10
 
    unicode_literals,
11
 
    )
12
 
 
13
 
__metaclass__ = type
14
 
 
15
 
import os
16
 
import re
17
 
import subprocess
18
 
import sys
19
 
import xmlrpclib
20
 
 
21
 
from Cheetah.Template import Template
22
 
import libvirt
23
 
import yaml
24
 
 
25
 
 
26
 
NODES_RANGE = range(1,4)
27
 
 
28
 
def yaml_loadf(fname):
29
 
    fp = open(fname)
30
 
    ret = yaml.load(fp)
31
 
    fp.close()
32
 
    return(ret)
33
 
 
34
 
class Domain:
35
 
    def __init__(self, syscfg, ident, basedir=None):
36
 
        self.ip_pre = syscfg['network']['ip_pre']
37
 
        if basedir == None:
38
 
            basedir = os.path.abspath(os.curdir)
39
 
        self.basedir = basedir
40
 
        self._setcfg(syscfg,ident)
41
 
        self.network = syscfg['network']['name']
42
 
 
43
 
    def __repr__(self):
44
 
        return("== %s ==\n ip: %s\n mac: %s\n template: %s\n" %
45
 
               (self.name, self.ipaddr, self.mac, self.template))
46
 
 
47
 
    @property
48
 
    def ipaddr(self):
49
 
        return("%s.%s" % (self.ip_pre, self.ipnum))
50
 
 
51
 
    @property
52
 
    def disk0(self):
53
 
        return("%s/%s-disk0.img" % (self.basedir, self.name))
54
 
 
55
 
    def dictInfo(self):
56
 
        ret = vars(self)
57
 
        # have to add the getters
58
 
        for prop in ( "ipaddr", "disk0" ):
59
 
            ret[prop] = getattr(self,prop)
60
 
        return ret
61
 
 
62
 
    def toLibVirtXml(self):
63
 
        template = Template(file=self.template, searchList=[self.dictInfo()])
64
 
        return template.respond()
65
 
 
66
 
class Node(Domain):
67
 
    def _setcfg(self, cfg, num):
68
 
        cfg = cfg['nodes']
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
74
 
        return
75
 
 
76
 
class System(Domain):
77
 
    def _setcfg(self, cfg, ident):
78
 
        cfg = cfg['systems'][ident]
79
 
        self.name = ident
80
 
        self.mac = cfg['mac']
81
 
        self.ipnum = cfg['ip']
82
 
        self.template = cfg['template']
83
 
        self.mem = cfg['mem'] * 1024
84
 
 
85
 
def renderSysDom(config, syscfg, stype="node"):
86
 
    template = Template(file=syscfg['template'], searchList=[config, syscfg])
87
 
    return template.respond()
88
 
 
89
 
# cobbler:
90
 
#  ip: 2 # ip address must be in dhcp range
91
 
#  mac: 00:16:3e:3e:a9:1a
92
 
#  template: libvirt-system.tmpl
93
 
#  mem: 524288
94
 
#
95
 
#nodes:
96
 
# prefix: node
97
 
# mac_pre: 00:16:3e:3e:aa
98
 
# mam: 256
99
 
 
100
 
def writeDomXmlFile(dom, outpre=""):
101
 
    fname="%s%s.xml" % (outpre, dom.name)
102
 
    output = open(fname,"w")
103
 
    output.write(dom.toLibVirtXml())
104
 
    output.close()
105
 
    return fname
106
 
 
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)
112
 
        if net.isActive():
113
 
            net.destroy()
114
 
        net.undefine()
115
 
 
116
 
    allsys = {}
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()
123
 
 
124
 
    conn.networkDefineXML(Template(file=config['network']['template'],
125
 
                          searchList=[config['network'],
126
 
                                      {'all_systems': allsys }]).respond())
127
 
 
128
 
    print("defined network %s " % netname)
129
 
 
130
 
    cob = System(config, "zimmer")
131
 
    systems = [ cob ]
132
 
 
133
 
    for node in NODES_RANGE:
134
 
        systems.append(Node(config, node))
135
 
 
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)
141
 
            if dom.isActive():
142
 
                dom.destroy()
143
 
            dom.undefine()
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)
148
 
 
149
 
def cobbler_addsystem(server, token, system, profile, hostip):
150
 
    eth0 = {
151
 
        "macaddress-eth0" : system.mac,
152
 
        "ipaddress-eth0" : system.ipaddr,
153
 
        "static-eth0" : False,
154
 
    }
155
 
    items = {
156
 
        'name': system.name,
157
 
        'hostname': system.name,
158
 
        'power_address': "qemu+tcp://%s:65001" % hostip,
159
 
        'power_id': system.name,
160
 
        'power_type': "virsh",
161
 
        'profile': profile,
162
 
        'netboot_enabled': True,
163
 
        'modify_interface': eth0,
164
 
    }
165
 
 
166
 
    if len(server.find_system({"name": system.name})):
167
 
        server.remove_system(system.name,token)
168
 
        server.update()
169
 
        print("removed existing %s" % system.name)
170
 
 
171
 
    sid = server.new_system(token)
172
 
    for key, val in items.iteritems():
173
 
        ret = server.modify_system(sid, key, val, token)
174
 
        if not ret:
175
 
            raise Exception("failed for %s [%s]: %s, %s" %
176
 
                            (system.name, ret, key, val))
177
 
    ret = server.save_system(sid,token)
178
 
    if not ret:
179
 
        raise Exception("failed to save %s" % system.name)
180
 
    print("added %s" % system.name)
181
 
 
182
 
 
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):
189
 
        return 'i386'
190
 
    else:
191
 
        return arch_text
192
 
 
193
 
 
194
 
def cobbler_setup(config):
195
 
    hostip = "%s.1" % config['network']['ip_pre']
196
 
    arch = get_profile_arch()
197
 
    profile = "maas-precise-%s" % arch
198
 
 
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")
204
 
 
205
 
    systems = [Node(config, node) for node in NODES_RANGE]
206
 
 
207
 
    for system in systems:
208
 
        cobbler_addsystem(server, token, system, profile, hostip)
209
 
 
210
 
def main():
211
 
    outpre = "libvirt-cobbler-"
212
 
    cfg_file = "settings.cfg"
213
 
 
214
 
    if len(sys.argv) == 1:
215
 
        print(
216
 
            "Usage: setup.py action\n"
217
 
            "action one of: libvirt-setup, cobbler-setup")
218
 
        sys.exit(1)
219
 
 
220
 
    config = yaml_loadf(cfg_file)
221
 
 
222
 
    if sys.argv[1] == "libvirt-setup":
223
 
        libvirt_setup(config)
224
 
    elif sys.argv[1] == "cobbler-setup":
225
 
        cobbler_setup(config)
226
 
 
227
 
if __name__ == '__main__':
228
 
    main()