Statistics
| Branch: | Tag: | Revision:

root / snf-deploy / snfdeploy / lib.py @ 8f5ea521

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