Statistics
| Branch: | Tag: | Revision:

root / snf-deploy / snfdeploy / lib.py @ 952a28c0

History | View | Annotate | Download (7.4 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

    
14

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

    
22

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

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

    
38

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

    
42

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

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

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

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

    
63

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

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

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

    
79

    
80
class Env(object):
81

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

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

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

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

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

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

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

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

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

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

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

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

    
135

    
136
class Conf(object):
137

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

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

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

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

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

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

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

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

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

    
198

    
199
def debug(host, msg):
200

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

    
204

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

    
217

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

    
225

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

    
234

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

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

    
247
    return ip, size
248

    
249

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

    
254

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

    
259

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

    
269
    return (gw, dev)
270

    
271

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

    
275

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