Statistics
| Branch: | Tag: | Revision:

root / snf-deploy / snfdeploy / lib.py @ ad76b118

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

    
20
class Host(object):
21
    def __init__(self, hostname, ip, mac, domain):
22
        self.hostname = hostname
23
        self.ip = ip
24
        self.mac = mac
25
        self.domain = domain
26

    
27
    @property
28
    def fqdn(self):
29
        return self.hostname + "." + self.domain
30

    
31
    @property
32
    def arecord(self):
33
        return self.hostname + " IN A " + self.ip + "\n"
34

    
35
    @property
36
    def ptrrecord(self):
37
        return ".".join(raddr(self.ip)) + " IN PTR " + self.fqdn + ".\n"
38

    
39

    
40
class Alias(Host):
41
    def __init__(self, host, alias):
42
        super(Alias, self).__init__(host.hostname, host.ip, host.mac, host.domain)
43
        self.alias = alias
44

    
45
    @property
46
    def cnamerecord(self):
47
        return self.alias + " IN CNAME " + self.hostname + "." + self.domain + ".\n"
48

    
49
    @property
50
    def fqdn(self):
51
        return self.alias + "." + self.domain
52

    
53

    
54
class Env(object):
55

    
56
    def evaluate(self, filename, section):
57
        for k, v in self.conf.get_section(filename, section):
58
            setattr(self, k, v)
59

    
60
    def __init__(self, conf):
61
        self.conf = conf
62
        for f, sections in conf.files.iteritems():
63
            for s in sections:
64
                self.evaluate(f, s)
65

    
66
        self.node2hostname = dict(conf.get_section("nodes", "hostnames"))
67
        self.node2ip = dict(conf.get_section("nodes", "ips"))
68
        self.node2mac = dict(conf.get_section("nodes", "macs"))
69
        self.hostnames = [self.node2hostname[n] for n in self.nodes.split(",")]
70
        self.ips = [self.node2ip[n] for n in self.nodes.split(",")]
71
        self.cluster_hostnames = [self.node2hostname[n] for n in self.cluster_nodes.split(",")]
72
        self.cluster_ips = [self.node2ip[n] for n in self.cluster_nodes.split(",")]
73

    
74
        self.net = ipaddr.IPNetwork(self.subnet)
75

    
76
        self.nodes_info = {}
77
        self.hosts_info = {}
78
        self.ips_info = {}
79
        for node in self.nodes.split(","):
80
            host =  Host(self.node2hostname[node],
81
                         self.node2ip[node],
82
                         self.node2mac[node], self.domain)
83

    
84
            self.nodes_info[node] = host
85
            self.hosts_info[host.hostname] = host
86
            self.ips_info[host.ip] = host
87

    
88
        self.cluster = Host(self.cluster_name, self.cluster_ip, None, self.domain)
89
        self.master = self.nodes_info[self.master_node]
90

    
91
        self.roles = {}
92
        for role, node in conf.get_section("synnefo", "roles"):
93
            self.roles[role] = Alias(self.nodes_info[node], role)
94
            setattr(self, role, self.roles[role])
95

    
96
class Conf(object):
97

    
98
    files = {
99
      "nodes": ["network", "info"],
100
      "deploy": ["dirs", "packages"],
101
      "vcluster": ["cluster", "image"],
102
      "synnefo": ["cred", "synnefo", "roles"],
103
      "packages": ["debian", "ganeti", "synnefo", "other"],
104
      "ganeti": [],
105
    }
106

    
107
    def __init__(self, confdir, cluster_name):
108
        self.confdir = confdir
109
        self.files["ganeti"] = [cluster_name]
110
        for f in self.files.keys():
111
            setattr(self, f, self.read_config(f))
112

    
113
    def read_config(self, f):
114
        config = ConfigParser.ConfigParser()
115
        config.optionxform = str
116
        filename = os.path.join(self.confdir, f) + ".conf"
117
        config.read(filename)
118
        return config
119

    
120
    def set(self, conf, section, option, value):
121
        c = getattr(self, conf)
122
        c.set(section, option, value)
123

    
124
    def get(self, conf, section, option):
125
        c = getattr(self, conf)
126
        return c.get(section, option, True)
127

    
128
    def get_section(self, conf, section):
129
        c = getattr(self, conf)
130
        return c.items(section, True)
131

    
132
    def print_config(self):
133
        for f in self.files.keys():
134
            getattr(self, f).write(sys.stdout)
135

    
136
    def _configure(self, args):
137
        for f, sections in self.files.iteritems():
138
            for s in sections:
139
                for k, v in self.get_section(f, s):
140
                    if getattr(args, k, None):
141
                        self.set(f, s, k, getattr(args, k))
142

    
143
    @classmethod
144
    def configure(cls, confdir="/etc/snf-deploy",
145
                  cluster_name="ganeti1", args=None, autoconf=False):
146

    
147
        conf = cls(confdir, cluster_name)
148
        if args:
149
            conf._configure(args)
150
        if autoconf:
151
            conf.autoconf()
152

    
153
        return conf
154

    
155
    def autoconf(self):
156
        #domain = get_domain()
157
        #if domain:
158
        #    self.nodes.set("network", "domain", get_domain())
159
        self.nodes.set("network", "subnet", "/".join(get_netinfo()))
160
        self.nodes.set("network", "gateway", get_default_route()[0])
161
        self.nodes.set("hostnames", "node1", get_hostname())
162
        self.nodes.set("ips", "node1", get_netinfo()[0])
163
        self.nodes.set("info", "nodes", "node1")
164
        self.nodes.set("info", "public_iface", get_default_route()[1])
165

    
166

    
167
class bcolors:
168
    HEADER = '\033[95m'
169
    OKBLUE = '\033[94m'
170
    OKGREEN = '\033[92m'
171
    WARNING = '\033[93m'
172
    FAIL = '\033[91m'
173
    ENDC = '\033[0m'
174

    
175
    def disable(self):
176
        self.HEADER = ''
177
        self.OKBLUE = ''
178
        self.OKGREEN = ''
179
        self.WARNING = ''
180
        self.FAIL = ''
181
        self.ENDC = ''
182

    
183

    
184
def debug(host, msg):
185

    
186
    print bcolors.HEADER + host + \
187
          bcolors.OKBLUE + ": " + msg + bcolors.ENDC
188

    
189

    
190
def check_pidfile(pidfile):
191
    print("Checking pidfile " + pidfile)
192
    try:
193
        f = open(pidfile, "r")
194
        pid = f.readline()
195
        os.kill(int(pid), signal.SIGKILL)
196
        f.close()
197
        os.remove(pidfile)
198
        time.sleep(5)
199
    except:
200
        pass
201

    
202

    
203
def randomMAC():
204
    mac = [ 0x52, 0x54, 0x56,
205
        random.randint(0x00, 0xff),
206
        random.randint(0x00, 0xff),
207
        random.randint(0x00, 0xff) ]
208
    return ':'.join(map(lambda x: "%02x" % x, mac))
209

    
210

    
211
def create_dir(d, clean=False):
212
    os.system("mkdir -p " + d)
213
    if clean:
214
        try:
215
            os.system("rm -f %s/*" % d)
216
        except:
217
            pass
218

    
219

    
220
def get_netinfo():
221
    _, pdev = get_default_route()
222
    r = re.compile(".*inet (\S+)/(\S+).*")
223
    s = subprocess.Popen(['ip', 'addr', 'show', 'dev', pdev], stdout=subprocess.PIPE)
224
    for line in s.stdout.readlines():
225
        match = r.search(line)
226
        if match:
227
            ip, size = match.groups()
228
            break
229

    
230
    return ip, size
231

    
232

    
233
def get_hostname():
234
    s = subprocess.Popen(['hostname', '-s'], stdout=subprocess.PIPE)
235
    return s.stdout.readline().strip()
236

    
237

    
238
def get_domain():
239
    s = subprocess.Popen(['hostname', '-d'], stdout=subprocess.PIPE)
240
    return s.stdout.readline().strip()
241

    
242

    
243
def get_default_route():
244
    r = re.compile("default via (\S+) dev (\S+)")
245
    s = subprocess.Popen(['ip', 'route'], stdout=subprocess.PIPE)
246
    for line in s.stdout.readlines():
247
        match = r.search(line)
248
        if match:
249
            gw, dev = match.groups()
250
            break
251

    
252
    return (gw, dev)
253

    
254

    
255
def import_conf_file(filename, directory):
256
    return imp.load_module(filename, *imp.find_module(filename, [directory]))
257

    
258

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