Statistics
| Branch: | Tag: | Revision:

root / snf-deploy / snfdeploy / lib.py @ 09a75177

History | View | Annotate | Download (7.5 kB)

1
#!/usr/bin/python
2

    
3
import time
4
import ipaddr
5
import os
6
import signal
7
import ConfigParser
8
import sys
9
import re
10
import random
11
import subprocess
12
import imp
13
import binascii
14

    
15

    
16
HEADER = '\033[95m'
17
OKBLUE = '\033[94m'
18
OKGREEN = '\033[92m'
19
WARNING = '\033[93m'
20
FAIL = '\033[91m'
21
ENDC = '\033[0m'
22

    
23

    
24
def disable_color():
25
    global HEADER
26
    global OKBLUE
27
    global OKGREEN
28
    global WARNING
29
    global FAIL
30
    global ENDC
31

    
32
    HEADER = ''
33
    OKBLUE = ''
34
    OKGREEN = ''
35
    WARNING = ''
36
    FAIL = ''
37
    ENDC = ''
38

    
39

    
40
if not sys.stdout.isatty():
41
    disable_color()
42

    
43

    
44
class Host(object):
45
    def __init__(self, hostname, ip, mac, domain, os):
46
        self.hostname = hostname
47
        self.ip = ip
48
        self.mac = mac
49
        self.domain = domain
50
        self.os = os
51

    
52
    @property
53
    def fqdn(self):
54
        return self.hostname + "." + self.domain
55

    
56
    @property
57
    def arecord(self):
58
        return self.hostname + " IN A " + self.ip + "\n"
59

    
60
    @property
61
    def ptrrecord(self):
62
        return ".".join(raddr(self.ip)) + " IN PTR " + self.fqdn + ".\n"
63

    
64

    
65
class Alias(Host):
66
    def __init__(self, host, alias):
67
        super(Alias, self).__init__(host.hostname, host.ip, host.mac,
68
                                    host.domain, host.os)
69
        self.alias = alias
70

    
71
    @property
72
    def cnamerecord(self):
73
        return (self.alias + " IN CNAME " + self.hostname + "." +
74
                self.domain + ".\n")
75

    
76
    @property
77
    def fqdn(self):
78
        return self.alias + "." + self.domain
79

    
80

    
81
class Env(object):
82

    
83
    def update_packages(self, os):
84
        for section in self.conf.files[os]:
85
            self.evaluate(os, section)
86

    
87
    def evaluate(self, filename, section):
88
        for k, v in self.conf.get_section(filename, section):
89
            setattr(self, k, v)
90

    
91
    def __init__(self, conf):
92
        self.conf = conf
93
        for f, sections in conf.files.iteritems():
94
            for s in sections:
95
                self.evaluate(f, s)
96

    
97
        self.node2hostname = dict(conf.get_section("nodes", "hostnames"))
98
        self.node2ip = dict(conf.get_section("nodes", "ips"))
99
        self.node2mac = dict(conf.get_section("nodes", "macs"))
100
        self.node2os = dict(conf.get_section("nodes", "os"))
101
        self.hostnames = [self.node2hostname[n]
102
                          for n in self.nodes.split(",")]
103

    
104
        self.ips = [self.node2ip[n]
105
                    for n in self.nodes.split(",")]
106

    
107
        self.cluster_hostnames = [self.node2hostname[n]
108
                                  for n in self.cluster_nodes.split(",")]
109

    
110
        self.cluster_ips = [self.node2ip[n]
111
                            for n in self.cluster_nodes.split(",")]
112

    
113
        self.net = ipaddr.IPNetwork(self.subnet)
114

    
115
        self.nodes_info = {}
116
        self.hosts_info = {}
117
        self.ips_info = {}
118
        for node in self.nodes.split(","):
119
            host = Host(self.node2hostname[node],
120
                        self.node2ip[node],
121
                        self.node2mac[node], self.domain, self.node2os[node])
122

    
123
            self.nodes_info[node] = host
124
            self.hosts_info[host.hostname] = host
125
            self.ips_info[host.ip] = host
126

    
127
        self.cluster = Host(self.cluster_name, self.cluster_ip, None,
128
                            self.domain, None)
129
        self.master = self.nodes_info[self.master_node]
130

    
131
        self.roles = {}
132
        for role, node in conf.get_section("synnefo", "roles"):
133
            self.roles[role] = Alias(self.nodes_info[node], role)
134
            setattr(self, role, self.roles[role])
135

    
136

    
137
class Conf(object):
138

    
139
    files = {
140
        "nodes": ["network", "info"],
141
        "deploy": ["dirs", "packages", "keys", "options"],
142
        "vcluster": ["cluster", "image", "network"],
143
        "synnefo": ["cred", "synnefo", "roles"],
144
        "squeeze": ["debian", "ganeti", "synnefo", "other"],
145
        "wheezy": ["debian", "ganeti", "synnefo", "other"],
146
    }
147
    confdir = "/etc/snf-deploy"
148

    
149
    def get_ganeti(self, cluster_name):
150
        self.files["ganeti"] = [cluster_name]
151

    
152
    def __init__(self, args):
153
        self.confdir = args.confdir
154
        self.get_ganeti(args.cluster_name)
155
        for f in self.files.keys():
156
            setattr(self, f, self.read_config(f))
157
        for f, sections in self.files.iteritems():
158
            for s in sections:
159
                for k, v in self.get_section(f, s):
160
                    if getattr(args, k, None):
161
                        self.set(f, s, k, getattr(args, k))
162
        if args.autoconf:
163
            self.autoconf()
164

    
165
    def autoconf(self):
166
        #domain = get_domain()
167
        #if domain:
168
        #    self.nodes.set("network", "domain", get_domain())
169
        # self.nodes.set("network", "subnet", "/".join(get_netinfo()))
170
        # self.nodes.set("network", "gateway", get_default_route()[0])
171
        self.nodes.set("hostnames", "node1", get_hostname())
172
        self.nodes.set("ips", "node1", get_netinfo()[0])
173
        self.nodes.set("info", "nodes", "node1")
174
        self.nodes.set("info", "public_iface", get_default_route()[1])
175

    
176
    def read_config(self, f):
177
        config = ConfigParser.ConfigParser()
178
        config.optionxform = str
179
        filename = os.path.join(self.confdir, f) + ".conf"
180
        config.read(filename)
181
        return config
182

    
183
    def set(self, conf, section, option, value):
184
        c = getattr(self, conf)
185
        c.set(section, option, value)
186

    
187
    def get(self, conf, section, option):
188
        c = getattr(self, conf)
189
        return c.get(section, option, True)
190

    
191
    def get_section(self, conf, section):
192
        c = getattr(self, conf)
193
        return c.items(section, True)
194

    
195
    def print_config(self):
196
        for f in self.files.keys():
197
            getattr(self, f).write(sys.stdout)
198

    
199

    
200
def debug(host, msg):
201

    
202
    print HEADER + host + \
203
        OKBLUE + ": " + msg + ENDC
204

    
205

    
206
def check_pidfile(pidfile):
207
    print("Checking pidfile " + pidfile)
208
    try:
209
        f = open(pidfile, "r")
210
        pid = f.readline()
211
        os.kill(int(pid), signal.SIGKILL)
212
        f.close()
213
        os.remove(pidfile)
214
        time.sleep(5)
215
    except:
216
        pass
217

    
218

    
219
def random_mac():
220
    mac = [0x52, 0x54, 0x56,
221
           random.randint(0x00, 0xff),
222
           random.randint(0x00, 0xff),
223
           random.randint(0x00, 0xff)]
224
    return ':'.join(map(lambda x: "%02x" % x, mac))
225

    
226

    
227
def create_dir(d, clean=False):
228
    os.system("mkdir -p " + d)
229
    if clean:
230
        try:
231
            os.system("rm -f %s/*" % d)
232
        except:
233
            pass
234

    
235

    
236
def get_netinfo():
237
    _, pdev = get_default_route()
238
    r = re.compile(".*inet (\S+)/(\S+).*")
239
    s = subprocess.Popen(['ip', 'addr', 'show', 'dev', pdev],
240
                         stdout=subprocess.PIPE)
241

    
242
    for line in s.stdout.readlines():
243
        match = r.search(line)
244
        if match:
245
            ip, size = match.groups()
246
            break
247

    
248
    return ip, size
249

    
250

    
251
def get_hostname():
252
    s = subprocess.Popen(['hostname', '-s'], stdout=subprocess.PIPE)
253
    return s.stdout.readline().strip()
254

    
255

    
256
def get_domain():
257
    s = subprocess.Popen(['hostname', '-d'], stdout=subprocess.PIPE)
258
    return s.stdout.readline().strip()
259

    
260

    
261
def get_default_route():
262
    r = re.compile("default via (\S+) dev (\S+)")
263
    s = subprocess.Popen(['ip', 'route'], stdout=subprocess.PIPE)
264
    for line in s.stdout.readlines():
265
        match = r.search(line)
266
        if match:
267
            gw, dev = match.groups()
268
            break
269

    
270
    return (gw, dev)
271

    
272

    
273
def import_conf_file(filename, directory):
274
    return imp.load_module(filename, *imp.find_module(filename, [directory]))
275

    
276

    
277
def raddr(addr):
278
    return list(reversed(addr.replace("/", "-").split(".")))
279

    
280

    
281
def random_secret():
282
    return binascii.b2a_hex(os.urandom(15))