Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (7.5 kB)

1 0ac84a9a Dimitris Aragiorgis
#!/usr/bin/python
2 0ac84a9a Dimitris Aragiorgis
3 0ac84a9a Dimitris Aragiorgis
import json
4 0ac84a9a Dimitris Aragiorgis
import time
5 0ac84a9a Dimitris Aragiorgis
import ipaddr
6 0ac84a9a Dimitris Aragiorgis
import os
7 0ac84a9a Dimitris Aragiorgis
import signal
8 0ac84a9a Dimitris Aragiorgis
import ConfigParser
9 0ac84a9a Dimitris Aragiorgis
import sys
10 0ac84a9a Dimitris Aragiorgis
import re
11 0ac84a9a Dimitris Aragiorgis
import random
12 0ac84a9a Dimitris Aragiorgis
import subprocess
13 0ac84a9a Dimitris Aragiorgis
import shutil
14 0ac84a9a Dimitris Aragiorgis
import imp
15 0ac84a9a Dimitris Aragiorgis
import tempfile
16 0ac84a9a Dimitris Aragiorgis
from snfdeploy import massedit
17 0ac84a9a Dimitris Aragiorgis
18 0ac84a9a Dimitris Aragiorgis
19 1bc6d467 Dionysis Grigoropoulos
HEADER = '\033[95m'
20 1bc6d467 Dionysis Grigoropoulos
OKBLUE = '\033[94m'
21 1bc6d467 Dionysis Grigoropoulos
OKGREEN = '\033[92m'
22 1bc6d467 Dionysis Grigoropoulos
WARNING = '\033[93m'
23 1bc6d467 Dionysis Grigoropoulos
FAIL = '\033[91m'
24 1bc6d467 Dionysis Grigoropoulos
ENDC = '\033[0m'
25 1bc6d467 Dionysis Grigoropoulos
26 1bc6d467 Dionysis Grigoropoulos
27 1bc6d467 Dionysis Grigoropoulos
def disable_color():
28 eaae0a32 Erethon
    global HEADER
29 eaae0a32 Erethon
    global OKBLUE
30 eaae0a32 Erethon
    global OKGREEN
31 eaae0a32 Erethon
    global WARNING
32 eaae0a32 Erethon
    global FAIL
33 eaae0a32 Erethon
    global ENDC
34 eaae0a32 Erethon
35 1bc6d467 Dionysis Grigoropoulos
    HEADER = ''
36 1bc6d467 Dionysis Grigoropoulos
    OKBLUE = ''
37 1bc6d467 Dionysis Grigoropoulos
    OKGREEN = ''
38 1bc6d467 Dionysis Grigoropoulos
    WARNING = ''
39 1bc6d467 Dionysis Grigoropoulos
    FAIL = ''
40 1bc6d467 Dionysis Grigoropoulos
    ENDC = ''
41 1bc6d467 Dionysis Grigoropoulos
42 1bc6d467 Dionysis Grigoropoulos
43 1bc6d467 Dionysis Grigoropoulos
if not sys.stdout.isatty():
44 1bc6d467 Dionysis Grigoropoulos
    disable_color()
45 0ac84a9a Dimitris Aragiorgis
46 7d6fed3a Dionysis Grigoropoulos
47 0ac84a9a Dimitris Aragiorgis
class Host(object):
48 f1b4fdfc Dimitris Aragiorgis
    def __init__(self, hostname, ip, mac, domain, os):
49 0ac84a9a Dimitris Aragiorgis
        self.hostname = hostname
50 0ac84a9a Dimitris Aragiorgis
        self.ip = ip
51 0ac84a9a Dimitris Aragiorgis
        self.mac = mac
52 0ac84a9a Dimitris Aragiorgis
        self.domain = domain
53 f1b4fdfc Dimitris Aragiorgis
        self.os = os
54 0ac84a9a Dimitris Aragiorgis
55 0ac84a9a Dimitris Aragiorgis
    @property
56 0ac84a9a Dimitris Aragiorgis
    def fqdn(self):
57 0ac84a9a Dimitris Aragiorgis
        return self.hostname + "." + self.domain
58 0ac84a9a Dimitris Aragiorgis
59 0ac84a9a Dimitris Aragiorgis
    @property
60 0ac84a9a Dimitris Aragiorgis
    def arecord(self):
61 0ac84a9a Dimitris Aragiorgis
        return self.hostname + " IN A " + self.ip + "\n"
62 0ac84a9a Dimitris Aragiorgis
63 0ac84a9a Dimitris Aragiorgis
    @property
64 0ac84a9a Dimitris Aragiorgis
    def ptrrecord(self):
65 0ac84a9a Dimitris Aragiorgis
        return ".".join(raddr(self.ip)) + " IN PTR " + self.fqdn + ".\n"
66 0ac84a9a Dimitris Aragiorgis
67 0ac84a9a Dimitris Aragiorgis
68 0ac84a9a Dimitris Aragiorgis
class Alias(Host):
69 0ac84a9a Dimitris Aragiorgis
    def __init__(self, host, alias):
70 7d6fed3a Dionysis Grigoropoulos
        super(Alias, self).__init__(host.hostname, host.ip, host.mac,
71 f1b4fdfc Dimitris Aragiorgis
                                    host.domain, host.os)
72 0ac84a9a Dimitris Aragiorgis
        self.alias = alias
73 0ac84a9a Dimitris Aragiorgis
74 0ac84a9a Dimitris Aragiorgis
    @property
75 0ac84a9a Dimitris Aragiorgis
    def cnamerecord(self):
76 7d6fed3a Dionysis Grigoropoulos
        return (self.alias + " IN CNAME " + self.hostname + "." +
77 7d6fed3a Dionysis Grigoropoulos
                self.domain + ".\n")
78 0ac84a9a Dimitris Aragiorgis
79 0ac84a9a Dimitris Aragiorgis
    @property
80 0ac84a9a Dimitris Aragiorgis
    def fqdn(self):
81 0ac84a9a Dimitris Aragiorgis
        return self.alias + "." + self.domain
82 0ac84a9a Dimitris Aragiorgis
83 0ac84a9a Dimitris Aragiorgis
84 0ac84a9a Dimitris Aragiorgis
class Env(object):
85 0ac84a9a Dimitris Aragiorgis
86 0ac84a9a Dimitris Aragiorgis
    def evaluate(self, filename, section):
87 0ac84a9a Dimitris Aragiorgis
        for k, v in self.conf.get_section(filename, section):
88 0ac84a9a Dimitris Aragiorgis
            setattr(self, k, v)
89 0ac84a9a Dimitris Aragiorgis
90 0ac84a9a Dimitris Aragiorgis
    def __init__(self, conf):
91 0ac84a9a Dimitris Aragiorgis
        self.conf = conf
92 0ac84a9a Dimitris Aragiorgis
        for f, sections in conf.files.iteritems():
93 0ac84a9a Dimitris Aragiorgis
            for s in sections:
94 0ac84a9a Dimitris Aragiorgis
                self.evaluate(f, s)
95 0ac84a9a Dimitris Aragiorgis
96 0ac84a9a Dimitris Aragiorgis
        self.node2hostname = dict(conf.get_section("nodes", "hostnames"))
97 0ac84a9a Dimitris Aragiorgis
        self.node2ip = dict(conf.get_section("nodes", "ips"))
98 0ac84a9a Dimitris Aragiorgis
        self.node2mac = dict(conf.get_section("nodes", "macs"))
99 f1b4fdfc Dimitris Aragiorgis
        self.node2os = dict(conf.get_section("nodes", "os"))
100 7d6fed3a Dionysis Grigoropoulos
        self.hostnames = [self.node2hostname[n]
101 7d6fed3a Dionysis Grigoropoulos
                          for n in self.nodes.split(",")]
102 7d6fed3a Dionysis Grigoropoulos
103 7d6fed3a Dionysis Grigoropoulos
        self.ips = [self.node2ip[n]
104 7d6fed3a Dionysis Grigoropoulos
                    for n in self.nodes.split(",")]
105 7d6fed3a Dionysis Grigoropoulos
106 7d6fed3a Dionysis Grigoropoulos
        self.cluster_hostnames = [self.node2hostname[n]
107 7d6fed3a Dionysis Grigoropoulos
                                  for n in self.cluster_nodes.split(",")]
108 7d6fed3a Dionysis Grigoropoulos
109 7d6fed3a Dionysis Grigoropoulos
        self.cluster_ips = [self.node2ip[n]
110 7d6fed3a Dionysis Grigoropoulos
                            for n in self.cluster_nodes.split(",")]
111 0ac84a9a Dimitris Aragiorgis
112 0ac84a9a Dimitris Aragiorgis
        self.net = ipaddr.IPNetwork(self.subnet)
113 0ac84a9a Dimitris Aragiorgis
114 0ac84a9a Dimitris Aragiorgis
        self.nodes_info = {}
115 0ac84a9a Dimitris Aragiorgis
        self.hosts_info = {}
116 0ac84a9a Dimitris Aragiorgis
        self.ips_info = {}
117 0ac84a9a Dimitris Aragiorgis
        for node in self.nodes.split(","):
118 7d6fed3a Dionysis Grigoropoulos
            host = Host(self.node2hostname[node],
119 7d6fed3a Dionysis Grigoropoulos
                        self.node2ip[node],
120 f1b4fdfc Dimitris Aragiorgis
                        self.node2mac[node], self.domain, self.node2os[node])
121 0ac84a9a Dimitris Aragiorgis
122 0ac84a9a Dimitris Aragiorgis
            self.nodes_info[node] = host
123 0ac84a9a Dimitris Aragiorgis
            self.hosts_info[host.hostname] = host
124 0ac84a9a Dimitris Aragiorgis
            self.ips_info[host.ip] = host
125 0ac84a9a Dimitris Aragiorgis
126 7d6fed3a Dionysis Grigoropoulos
        self.cluster = Host(self.cluster_name, self.cluster_ip, None,
127 7d6fed3a Dionysis Grigoropoulos
                            self.domain)
128 0ac84a9a Dimitris Aragiorgis
        self.master = self.nodes_info[self.master_node]
129 0ac84a9a Dimitris Aragiorgis
130 0ac84a9a Dimitris Aragiorgis
        self.roles = {}
131 0ac84a9a Dimitris Aragiorgis
        for role, node in conf.get_section("synnefo", "roles"):
132 0ac84a9a Dimitris Aragiorgis
            self.roles[role] = Alias(self.nodes_info[node], role)
133 0ac84a9a Dimitris Aragiorgis
            setattr(self, role, self.roles[role])
134 0ac84a9a Dimitris Aragiorgis
135 7d6fed3a Dionysis Grigoropoulos
136 0ac84a9a Dimitris Aragiorgis
class Conf(object):
137 0ac84a9a Dimitris Aragiorgis
138 0ac84a9a Dimitris Aragiorgis
    files = {
139 7d6fed3a Dionysis Grigoropoulos
        "nodes": ["network", "info"],
140 bd9b6f21 Christos Stavrakakis
        "deploy": ["dirs", "packages", "keys", "options"],
141 7d6fed3a Dionysis Grigoropoulos
        "vcluster": ["cluster", "image"],
142 7d6fed3a Dionysis Grigoropoulos
        "synnefo": ["cred", "synnefo", "roles"],
143 7d6fed3a Dionysis Grigoropoulos
        "packages": ["debian", "ganeti", "synnefo", "other"],
144 7d6fed3a Dionysis Grigoropoulos
        "ganeti": [],
145 0ac84a9a Dimitris Aragiorgis
    }
146 0ac84a9a Dimitris Aragiorgis
147 0ac84a9a Dimitris Aragiorgis
    def __init__(self, confdir, cluster_name):
148 0ac84a9a Dimitris Aragiorgis
        self.confdir = confdir
149 0ac84a9a Dimitris Aragiorgis
        self.files["ganeti"] = [cluster_name]
150 0ac84a9a Dimitris Aragiorgis
        for f in self.files.keys():
151 0ac84a9a Dimitris Aragiorgis
            setattr(self, f, self.read_config(f))
152 0ac84a9a Dimitris Aragiorgis
153 0ac84a9a Dimitris Aragiorgis
    def read_config(self, f):
154 0ac84a9a Dimitris Aragiorgis
        config = ConfigParser.ConfigParser()
155 0ac84a9a Dimitris Aragiorgis
        config.optionxform = str
156 0ac84a9a Dimitris Aragiorgis
        filename = os.path.join(self.confdir, f) + ".conf"
157 0ac84a9a Dimitris Aragiorgis
        config.read(filename)
158 0ac84a9a Dimitris Aragiorgis
        return config
159 0ac84a9a Dimitris Aragiorgis
160 0ac84a9a Dimitris Aragiorgis
    def set(self, conf, section, option, value):
161 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
162 0ac84a9a Dimitris Aragiorgis
        c.set(section, option, value)
163 0ac84a9a Dimitris Aragiorgis
164 0ac84a9a Dimitris Aragiorgis
    def get(self, conf, section, option):
165 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
166 0ac84a9a Dimitris Aragiorgis
        return c.get(section, option, True)
167 0ac84a9a Dimitris Aragiorgis
168 0ac84a9a Dimitris Aragiorgis
    def get_section(self, conf, section):
169 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
170 0ac84a9a Dimitris Aragiorgis
        return c.items(section, True)
171 0ac84a9a Dimitris Aragiorgis
172 0ac84a9a Dimitris Aragiorgis
    def print_config(self):
173 0ac84a9a Dimitris Aragiorgis
        for f in self.files.keys():
174 0ac84a9a Dimitris Aragiorgis
            getattr(self, f).write(sys.stdout)
175 0ac84a9a Dimitris Aragiorgis
176 0ac84a9a Dimitris Aragiorgis
    def _configure(self, args):
177 0ac84a9a Dimitris Aragiorgis
        for f, sections in self.files.iteritems():
178 0ac84a9a Dimitris Aragiorgis
            for s in sections:
179 0ac84a9a Dimitris Aragiorgis
                for k, v in self.get_section(f, s):
180 0ac84a9a Dimitris Aragiorgis
                    if getattr(args, k, None):
181 0ac84a9a Dimitris Aragiorgis
                        self.set(f, s, k, getattr(args, k))
182 0ac84a9a Dimitris Aragiorgis
183 0ac84a9a Dimitris Aragiorgis
    @classmethod
184 0ac84a9a Dimitris Aragiorgis
    def configure(cls, confdir="/etc/snf-deploy",
185 0ac84a9a Dimitris Aragiorgis
                  cluster_name="ganeti1", args=None, autoconf=False):
186 0ac84a9a Dimitris Aragiorgis
187 0ac84a9a Dimitris Aragiorgis
        conf = cls(confdir, cluster_name)
188 0ac84a9a Dimitris Aragiorgis
        if args:
189 0ac84a9a Dimitris Aragiorgis
            conf._configure(args)
190 0ac84a9a Dimitris Aragiorgis
        if autoconf:
191 0ac84a9a Dimitris Aragiorgis
            conf.autoconf()
192 0ac84a9a Dimitris Aragiorgis
193 0ac84a9a Dimitris Aragiorgis
        return conf
194 0ac84a9a Dimitris Aragiorgis
195 0ac84a9a Dimitris Aragiorgis
    def autoconf(self):
196 0ac84a9a Dimitris Aragiorgis
        #domain = get_domain()
197 0ac84a9a Dimitris Aragiorgis
        #if domain:
198 0ac84a9a Dimitris Aragiorgis
        #    self.nodes.set("network", "domain", get_domain())
199 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("network", "subnet", "/".join(get_netinfo()))
200 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("network", "gateway", get_default_route()[0])
201 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("hostnames", "node1", get_hostname())
202 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("ips", "node1", get_netinfo()[0])
203 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("info", "nodes", "node1")
204 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("info", "public_iface", get_default_route()[1])
205 0ac84a9a Dimitris Aragiorgis
206 0ac84a9a Dimitris Aragiorgis
207 0ac84a9a Dimitris Aragiorgis
def debug(host, msg):
208 0ac84a9a Dimitris Aragiorgis
209 1bc6d467 Dionysis Grigoropoulos
    print HEADER + host + \
210 7d6fed3a Dionysis Grigoropoulos
        OKBLUE + ": " + msg + ENDC
211 0ac84a9a Dimitris Aragiorgis
212 0ac84a9a Dimitris Aragiorgis
213 0ac84a9a Dimitris Aragiorgis
def check_pidfile(pidfile):
214 0ac84a9a Dimitris Aragiorgis
    print("Checking pidfile " + pidfile)
215 0ac84a9a Dimitris Aragiorgis
    try:
216 0ac84a9a Dimitris Aragiorgis
        f = open(pidfile, "r")
217 0ac84a9a Dimitris Aragiorgis
        pid = f.readline()
218 0ac84a9a Dimitris Aragiorgis
        os.kill(int(pid), signal.SIGKILL)
219 0ac84a9a Dimitris Aragiorgis
        f.close()
220 0ac84a9a Dimitris Aragiorgis
        os.remove(pidfile)
221 0ac84a9a Dimitris Aragiorgis
        time.sleep(5)
222 0ac84a9a Dimitris Aragiorgis
    except:
223 0ac84a9a Dimitris Aragiorgis
        pass
224 0ac84a9a Dimitris Aragiorgis
225 0ac84a9a Dimitris Aragiorgis
226 0ac84a9a Dimitris Aragiorgis
def randomMAC():
227 7d6fed3a Dionysis Grigoropoulos
    mac = [0x52, 0x54, 0x56,
228 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff),
229 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff),
230 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff)]
231 0ac84a9a Dimitris Aragiorgis
    return ':'.join(map(lambda x: "%02x" % x, mac))
232 0ac84a9a Dimitris Aragiorgis
233 0ac84a9a Dimitris Aragiorgis
234 0ac84a9a Dimitris Aragiorgis
def create_dir(d, clean=False):
235 0ac84a9a Dimitris Aragiorgis
    os.system("mkdir -p " + d)
236 0ac84a9a Dimitris Aragiorgis
    if clean:
237 0ac84a9a Dimitris Aragiorgis
        try:
238 0ac84a9a Dimitris Aragiorgis
            os.system("rm -f %s/*" % d)
239 0ac84a9a Dimitris Aragiorgis
        except:
240 0ac84a9a Dimitris Aragiorgis
            pass
241 0ac84a9a Dimitris Aragiorgis
242 0ac84a9a Dimitris Aragiorgis
243 0ac84a9a Dimitris Aragiorgis
def get_netinfo():
244 0ac84a9a Dimitris Aragiorgis
    _, pdev = get_default_route()
245 0ac84a9a Dimitris Aragiorgis
    r = re.compile(".*inet (\S+)/(\S+).*")
246 7d6fed3a Dionysis Grigoropoulos
    s = subprocess.Popen(['ip', 'addr', 'show', 'dev', pdev],
247 7d6fed3a Dionysis Grigoropoulos
                         stdout=subprocess.PIPE)
248 7d6fed3a Dionysis Grigoropoulos
249 0ac84a9a Dimitris Aragiorgis
    for line in s.stdout.readlines():
250 0ac84a9a Dimitris Aragiorgis
        match = r.search(line)
251 0ac84a9a Dimitris Aragiorgis
        if match:
252 0ac84a9a Dimitris Aragiorgis
            ip, size = match.groups()
253 0ac84a9a Dimitris Aragiorgis
            break
254 0ac84a9a Dimitris Aragiorgis
255 0ac84a9a Dimitris Aragiorgis
    return ip, size
256 0ac84a9a Dimitris Aragiorgis
257 0ac84a9a Dimitris Aragiorgis
258 0ac84a9a Dimitris Aragiorgis
def get_hostname():
259 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['hostname', '-s'], stdout=subprocess.PIPE)
260 0ac84a9a Dimitris Aragiorgis
    return s.stdout.readline().strip()
261 0ac84a9a Dimitris Aragiorgis
262 0ac84a9a Dimitris Aragiorgis
263 0ac84a9a Dimitris Aragiorgis
def get_domain():
264 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['hostname', '-d'], stdout=subprocess.PIPE)
265 0ac84a9a Dimitris Aragiorgis
    return s.stdout.readline().strip()
266 0ac84a9a Dimitris Aragiorgis
267 0ac84a9a Dimitris Aragiorgis
268 0ac84a9a Dimitris Aragiorgis
def get_default_route():
269 0ac84a9a Dimitris Aragiorgis
    r = re.compile("default via (\S+) dev (\S+)")
270 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['ip', 'route'], stdout=subprocess.PIPE)
271 0ac84a9a Dimitris Aragiorgis
    for line in s.stdout.readlines():
272 0ac84a9a Dimitris Aragiorgis
        match = r.search(line)
273 0ac84a9a Dimitris Aragiorgis
        if match:
274 0ac84a9a Dimitris Aragiorgis
            gw, dev = match.groups()
275 0ac84a9a Dimitris Aragiorgis
            break
276 0ac84a9a Dimitris Aragiorgis
277 0ac84a9a Dimitris Aragiorgis
    return (gw, dev)
278 0ac84a9a Dimitris Aragiorgis
279 0ac84a9a Dimitris Aragiorgis
280 0ac84a9a Dimitris Aragiorgis
def import_conf_file(filename, directory):
281 0ac84a9a Dimitris Aragiorgis
    return imp.load_module(filename, *imp.find_module(filename, [directory]))
282 0ac84a9a Dimitris Aragiorgis
283 0ac84a9a Dimitris Aragiorgis
284 0ac84a9a Dimitris Aragiorgis
def raddr(addr):
285 7d6fed3a Dionysis Grigoropoulos
    return list(reversed(addr.replace("/", "-").split(".")))