Statistics
| Branch: | Tag: | Revision:

root / snf-deploy / snfdeploy / lib.py @ 24dc98e2

History | View | Annotate | Download (7.7 kB)

1
#!/usr/bin/python
2

    
3
import json
4
import time
5
import ipaddr
6
import os
7
import signal
8
import ConfigParser
9
import sys
10
import re
11
import random
12
import subprocess
13
import shutil
14
import imp
15
import tempfile
16
from snfdeploy import massedit
17

    
18

    
19
HEADER = '\033[95m'
20
OKBLUE = '\033[94m'
21
OKGREEN = '\033[92m'
22
WARNING = '\033[93m'
23
FAIL = '\033[91m'
24
ENDC = '\033[0m'
25

    
26

    
27
def disable_color():
28
    global HEADER
29
    global OKBLUE
30
    global OKGREEN
31
    global WARNING
32
    global FAIL
33
    global ENDC
34

    
35
    HEADER = ''
36
    OKBLUE = ''
37
    OKGREEN = ''
38
    WARNING = ''
39
    FAIL = ''
40
    ENDC = ''
41

    
42

    
43
if not sys.stdout.isatty():
44
    disable_color()
45

    
46

    
47
class Host(object):
48
    def __init__(self, hostname, ip, mac, domain, os):
49
        self.hostname = hostname
50
        self.ip = ip
51
        self.mac = mac
52
        self.domain = domain
53
        self.os = os
54

    
55
    @property
56
    def fqdn(self):
57
        return self.hostname + "." + self.domain
58

    
59
    @property
60
    def arecord(self):
61
        return self.hostname + " IN A " + self.ip + "\n"
62

    
63
    @property
64
    def ptrrecord(self):
65
        return ".".join(raddr(self.ip)) + " IN PTR " + self.fqdn + ".\n"
66

    
67

    
68
class Alias(Host):
69
    def __init__(self, host, alias):
70
        super(Alias, self).__init__(host.hostname, host.ip, host.mac,
71
                                    host.domain, host.os)
72
        self.alias = alias
73

    
74
    @property
75
    def cnamerecord(self):
76
        return (self.alias + " IN CNAME " + self.hostname + "." +
77
                self.domain + ".\n")
78

    
79
    @property
80
    def fqdn(self):
81
        return self.alias + "." + self.domain
82

    
83

    
84
class Env(object):
85

    
86
    def update_packages(self, os):
87
        for section in self.conf.files[os]:
88
          self.evaluate(os, section)
89

    
90
    def evaluate(self, filename, section):
91
        for k, v in self.conf.get_section(filename, section):
92
            setattr(self, k, v)
93

    
94
    def __init__(self, conf):
95
        self.conf = conf
96
        for f, sections in conf.files.iteritems():
97
            for s in sections:
98
                self.evaluate(f, s)
99

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

    
107
        self.ips = [self.node2ip[n]
108
                    for n in self.nodes.split(",")]
109

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

    
113
        self.cluster_ips = [self.node2ip[n]
114
                            for n in self.cluster_nodes.split(",")]
115

    
116
        self.net = ipaddr.IPNetwork(self.subnet)
117

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

    
126
            self.nodes_info[node] = host
127
            self.hosts_info[host.hostname] = host
128
            self.ips_info[host.ip] = host
129

    
130
        self.cluster = Host(self.cluster_name, self.cluster_ip, None,
131
                            self.domain, None)
132
        self.master = self.nodes_info[self.master_node]
133

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

    
139

    
140
class Conf(object):
141

    
142
    files = {
143
        "nodes": ["network", "info"],
144
        "deploy": ["dirs", "packages", "keys", "options"],
145
        "vcluster": ["cluster", "image", "network"],
146
        "synnefo": ["cred", "synnefo", "roles"],
147
        "packages": ["debian", "ganeti", "synnefo", "other"],
148
        "squeeze": ["debian", "ganeti", "synnefo", "other"],
149
        "wheezy": ["debian", "ganeti", "synnefo", "other"],
150
        "ganeti": [],
151
    }
152

    
153
    def __init__(self, confdir, cluster_name):
154
        self.confdir = confdir
155
        self.files["ganeti"] = [cluster_name]
156
        for f in self.files.keys():
157
            setattr(self, f, self.read_config(f))
158

    
159
    def read_config(self, f):
160
        config = ConfigParser.ConfigParser()
161
        config.optionxform = str
162
        filename = os.path.join(self.confdir, f) + ".conf"
163
        config.read(filename)
164
        return config
165

    
166
    def set(self, conf, section, option, value):
167
        c = getattr(self, conf)
168
        c.set(section, option, value)
169

    
170
    def get(self, conf, section, option):
171
        c = getattr(self, conf)
172
        return c.get(section, option, True)
173

    
174
    def get_section(self, conf, section):
175
        c = getattr(self, conf)
176
        return c.items(section, True)
177

    
178
    def print_config(self):
179
        for f in self.files.keys():
180
            getattr(self, f).write(sys.stdout)
181

    
182
    def _configure(self, args):
183
        for f, sections in self.files.iteritems():
184
            for s in sections:
185
                for k, v in self.get_section(f, s):
186
                    if getattr(args, k, None):
187
                        self.set(f, s, k, getattr(args, k))
188

    
189
    @classmethod
190
    def configure(cls, confdir="/etc/snf-deploy",
191
                  cluster_name="ganeti1", args=None, autoconf=False):
192

    
193
        conf = cls(confdir, cluster_name)
194
        if args:
195
            conf._configure(args)
196
        if autoconf:
197
            conf.autoconf()
198

    
199
        return conf
200

    
201
    def autoconf(self):
202
        #domain = get_domain()
203
        #if domain:
204
        #    self.nodes.set("network", "domain", get_domain())
205
        # self.nodes.set("network", "subnet", "/".join(get_netinfo()))
206
        # self.nodes.set("network", "gateway", get_default_route()[0])
207
        self.nodes.set("hostnames", "node1", get_hostname())
208
        self.nodes.set("ips", "node1", get_netinfo()[0])
209
        self.nodes.set("info", "nodes", "node1")
210
        self.nodes.set("info", "public_iface", get_default_route()[1])
211

    
212

    
213

    
214
def debug(host, msg):
215

    
216
    print HEADER + host + \
217
        OKBLUE + ": " + msg + ENDC
218

    
219

    
220
def check_pidfile(pidfile):
221
    print("Checking pidfile " + pidfile)
222
    try:
223
        f = open(pidfile, "r")
224
        pid = f.readline()
225
        os.kill(int(pid), signal.SIGKILL)
226
        f.close()
227
        os.remove(pidfile)
228
        time.sleep(5)
229
    except:
230
        pass
231

    
232

    
233
def randomMAC():
234
    mac = [0x52, 0x54, 0x56,
235
           random.randint(0x00, 0xff),
236
           random.randint(0x00, 0xff),
237
           random.randint(0x00, 0xff)]
238
    return ':'.join(map(lambda x: "%02x" % x, mac))
239

    
240

    
241
def create_dir(d, clean=False):
242
    os.system("mkdir -p " + d)
243
    if clean:
244
        try:
245
            os.system("rm -f %s/*" % d)
246
        except:
247
            pass
248

    
249

    
250
def get_netinfo():
251
    _, pdev = get_default_route()
252
    r = re.compile(".*inet (\S+)/(\S+).*")
253
    s = subprocess.Popen(['ip', 'addr', 'show', 'dev', pdev],
254
                         stdout=subprocess.PIPE)
255

    
256
    for line in s.stdout.readlines():
257
        match = r.search(line)
258
        if match:
259
            ip, size = match.groups()
260
            break
261

    
262
    return ip, size
263

    
264

    
265
def get_hostname():
266
    s = subprocess.Popen(['hostname', '-s'], stdout=subprocess.PIPE)
267
    return s.stdout.readline().strip()
268

    
269

    
270
def get_domain():
271
    s = subprocess.Popen(['hostname', '-d'], stdout=subprocess.PIPE)
272
    return s.stdout.readline().strip()
273

    
274

    
275
def get_default_route():
276
    r = re.compile("default via (\S+) dev (\S+)")
277
    s = subprocess.Popen(['ip', 'route'], stdout=subprocess.PIPE)
278
    for line in s.stdout.readlines():
279
        match = r.search(line)
280
        if match:
281
            gw, dev = match.groups()
282
            break
283

    
284
    return (gw, dev)
285

    
286

    
287
def import_conf_file(filename, directory):
288
    return imp.load_module(filename, *imp.find_module(filename, [directory]))
289

    
290

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