Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (7.6 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 24dc98e2 Dimitris Aragiorgis
    def update_packages(self, os):
87 24dc98e2 Dimitris Aragiorgis
        for section in self.conf.files[os]:
88 24dc98e2 Dimitris Aragiorgis
          self.evaluate(os, section)
89 24dc98e2 Dimitris Aragiorgis
90 0ac84a9a Dimitris Aragiorgis
    def evaluate(self, filename, section):
91 0ac84a9a Dimitris Aragiorgis
        for k, v in self.conf.get_section(filename, section):
92 0ac84a9a Dimitris Aragiorgis
            setattr(self, k, v)
93 0ac84a9a Dimitris Aragiorgis
94 0ac84a9a Dimitris Aragiorgis
    def __init__(self, conf):
95 0ac84a9a Dimitris Aragiorgis
        self.conf = conf
96 0ac84a9a Dimitris Aragiorgis
        for f, sections in conf.files.iteritems():
97 0ac84a9a Dimitris Aragiorgis
            for s in sections:
98 0ac84a9a Dimitris Aragiorgis
                self.evaluate(f, s)
99 0ac84a9a Dimitris Aragiorgis
100 0ac84a9a Dimitris Aragiorgis
        self.node2hostname = dict(conf.get_section("nodes", "hostnames"))
101 0ac84a9a Dimitris Aragiorgis
        self.node2ip = dict(conf.get_section("nodes", "ips"))
102 0ac84a9a Dimitris Aragiorgis
        self.node2mac = dict(conf.get_section("nodes", "macs"))
103 f1b4fdfc Dimitris Aragiorgis
        self.node2os = dict(conf.get_section("nodes", "os"))
104 7d6fed3a Dionysis Grigoropoulos
        self.hostnames = [self.node2hostname[n]
105 7d6fed3a Dionysis Grigoropoulos
                          for n in self.nodes.split(",")]
106 7d6fed3a Dionysis Grigoropoulos
107 7d6fed3a Dionysis Grigoropoulos
        self.ips = [self.node2ip[n]
108 7d6fed3a Dionysis Grigoropoulos
                    for n in self.nodes.split(",")]
109 7d6fed3a Dionysis Grigoropoulos
110 7d6fed3a Dionysis Grigoropoulos
        self.cluster_hostnames = [self.node2hostname[n]
111 7d6fed3a Dionysis Grigoropoulos
                                  for n in self.cluster_nodes.split(",")]
112 7d6fed3a Dionysis Grigoropoulos
113 7d6fed3a Dionysis Grigoropoulos
        self.cluster_ips = [self.node2ip[n]
114 7d6fed3a Dionysis Grigoropoulos
                            for n in self.cluster_nodes.split(",")]
115 0ac84a9a Dimitris Aragiorgis
116 0ac84a9a Dimitris Aragiorgis
        self.net = ipaddr.IPNetwork(self.subnet)
117 0ac84a9a Dimitris Aragiorgis
118 0ac84a9a Dimitris Aragiorgis
        self.nodes_info = {}
119 0ac84a9a Dimitris Aragiorgis
        self.hosts_info = {}
120 0ac84a9a Dimitris Aragiorgis
        self.ips_info = {}
121 0ac84a9a Dimitris Aragiorgis
        for node in self.nodes.split(","):
122 7d6fed3a Dionysis Grigoropoulos
            host = Host(self.node2hostname[node],
123 7d6fed3a Dionysis Grigoropoulos
                        self.node2ip[node],
124 f1b4fdfc Dimitris Aragiorgis
                        self.node2mac[node], self.domain, self.node2os[node])
125 0ac84a9a Dimitris Aragiorgis
126 0ac84a9a Dimitris Aragiorgis
            self.nodes_info[node] = host
127 0ac84a9a Dimitris Aragiorgis
            self.hosts_info[host.hostname] = host
128 0ac84a9a Dimitris Aragiorgis
            self.ips_info[host.ip] = host
129 0ac84a9a Dimitris Aragiorgis
130 7d6fed3a Dionysis Grigoropoulos
        self.cluster = Host(self.cluster_name, self.cluster_ip, None,
131 9f93a6fb Dimitris Aragiorgis
                            self.domain, None)
132 0ac84a9a Dimitris Aragiorgis
        self.master = self.nodes_info[self.master_node]
133 0ac84a9a Dimitris Aragiorgis
134 0ac84a9a Dimitris Aragiorgis
        self.roles = {}
135 0ac84a9a Dimitris Aragiorgis
        for role, node in conf.get_section("synnefo", "roles"):
136 0ac84a9a Dimitris Aragiorgis
            self.roles[role] = Alias(self.nodes_info[node], role)
137 0ac84a9a Dimitris Aragiorgis
            setattr(self, role, self.roles[role])
138 0ac84a9a Dimitris Aragiorgis
139 7d6fed3a Dionysis Grigoropoulos
140 0ac84a9a Dimitris Aragiorgis
class Conf(object):
141 0ac84a9a Dimitris Aragiorgis
142 0ac84a9a Dimitris Aragiorgis
    files = {
143 7d6fed3a Dionysis Grigoropoulos
        "nodes": ["network", "info"],
144 bd9b6f21 Christos Stavrakakis
        "deploy": ["dirs", "packages", "keys", "options"],
145 9f93a6fb Dimitris Aragiorgis
        "vcluster": ["cluster", "image", "network"],
146 7d6fed3a Dionysis Grigoropoulos
        "synnefo": ["cred", "synnefo", "roles"],
147 24dc98e2 Dimitris Aragiorgis
        "squeeze": ["debian", "ganeti", "synnefo", "other"],
148 24dc98e2 Dimitris Aragiorgis
        "wheezy": ["debian", "ganeti", "synnefo", "other"],
149 7d6fed3a Dionysis Grigoropoulos
        "ganeti": [],
150 0ac84a9a Dimitris Aragiorgis
    }
151 0ac84a9a Dimitris Aragiorgis
152 0ac84a9a Dimitris Aragiorgis
    def __init__(self, confdir, cluster_name):
153 0ac84a9a Dimitris Aragiorgis
        self.confdir = confdir
154 0ac84a9a Dimitris Aragiorgis
        self.files["ganeti"] = [cluster_name]
155 0ac84a9a Dimitris Aragiorgis
        for f in self.files.keys():
156 0ac84a9a Dimitris Aragiorgis
            setattr(self, f, self.read_config(f))
157 0ac84a9a Dimitris Aragiorgis
158 0ac84a9a Dimitris Aragiorgis
    def read_config(self, f):
159 0ac84a9a Dimitris Aragiorgis
        config = ConfigParser.ConfigParser()
160 0ac84a9a Dimitris Aragiorgis
        config.optionxform = str
161 0ac84a9a Dimitris Aragiorgis
        filename = os.path.join(self.confdir, f) + ".conf"
162 0ac84a9a Dimitris Aragiorgis
        config.read(filename)
163 0ac84a9a Dimitris Aragiorgis
        return config
164 0ac84a9a Dimitris Aragiorgis
165 0ac84a9a Dimitris Aragiorgis
    def set(self, conf, section, option, value):
166 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
167 0ac84a9a Dimitris Aragiorgis
        c.set(section, option, value)
168 0ac84a9a Dimitris Aragiorgis
169 0ac84a9a Dimitris Aragiorgis
    def get(self, conf, section, option):
170 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
171 0ac84a9a Dimitris Aragiorgis
        return c.get(section, option, True)
172 0ac84a9a Dimitris Aragiorgis
173 0ac84a9a Dimitris Aragiorgis
    def get_section(self, conf, section):
174 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
175 0ac84a9a Dimitris Aragiorgis
        return c.items(section, True)
176 0ac84a9a Dimitris Aragiorgis
177 0ac84a9a Dimitris Aragiorgis
    def print_config(self):
178 0ac84a9a Dimitris Aragiorgis
        for f in self.files.keys():
179 0ac84a9a Dimitris Aragiorgis
            getattr(self, f).write(sys.stdout)
180 0ac84a9a Dimitris Aragiorgis
181 0ac84a9a Dimitris Aragiorgis
    def _configure(self, args):
182 0ac84a9a Dimitris Aragiorgis
        for f, sections in self.files.iteritems():
183 0ac84a9a Dimitris Aragiorgis
            for s in sections:
184 0ac84a9a Dimitris Aragiorgis
                for k, v in self.get_section(f, s):
185 0ac84a9a Dimitris Aragiorgis
                    if getattr(args, k, None):
186 0ac84a9a Dimitris Aragiorgis
                        self.set(f, s, k, getattr(args, k))
187 0ac84a9a Dimitris Aragiorgis
188 0ac84a9a Dimitris Aragiorgis
    @classmethod
189 0ac84a9a Dimitris Aragiorgis
    def configure(cls, confdir="/etc/snf-deploy",
190 0ac84a9a Dimitris Aragiorgis
                  cluster_name="ganeti1", args=None, autoconf=False):
191 0ac84a9a Dimitris Aragiorgis
192 0ac84a9a Dimitris Aragiorgis
        conf = cls(confdir, cluster_name)
193 0ac84a9a Dimitris Aragiorgis
        if args:
194 0ac84a9a Dimitris Aragiorgis
            conf._configure(args)
195 0ac84a9a Dimitris Aragiorgis
        if autoconf:
196 0ac84a9a Dimitris Aragiorgis
            conf.autoconf()
197 0ac84a9a Dimitris Aragiorgis
198 0ac84a9a Dimitris Aragiorgis
        return conf
199 0ac84a9a Dimitris Aragiorgis
200 0ac84a9a Dimitris Aragiorgis
    def autoconf(self):
201 0ac84a9a Dimitris Aragiorgis
        #domain = get_domain()
202 0ac84a9a Dimitris Aragiorgis
        #if domain:
203 0ac84a9a Dimitris Aragiorgis
        #    self.nodes.set("network", "domain", get_domain())
204 9f93a6fb Dimitris Aragiorgis
        # self.nodes.set("network", "subnet", "/".join(get_netinfo()))
205 9f93a6fb Dimitris Aragiorgis
        # self.nodes.set("network", "gateway", get_default_route()[0])
206 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("hostnames", "node1", get_hostname())
207 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("ips", "node1", get_netinfo()[0])
208 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("info", "nodes", "node1")
209 0ac84a9a Dimitris Aragiorgis
        self.nodes.set("info", "public_iface", get_default_route()[1])
210 0ac84a9a Dimitris Aragiorgis
211 0ac84a9a Dimitris Aragiorgis
212 24dc98e2 Dimitris Aragiorgis
213 0ac84a9a Dimitris Aragiorgis
def debug(host, msg):
214 0ac84a9a Dimitris Aragiorgis
215 1bc6d467 Dionysis Grigoropoulos
    print HEADER + host + \
216 7d6fed3a Dionysis Grigoropoulos
        OKBLUE + ": " + msg + ENDC
217 0ac84a9a Dimitris Aragiorgis
218 0ac84a9a Dimitris Aragiorgis
219 0ac84a9a Dimitris Aragiorgis
def check_pidfile(pidfile):
220 0ac84a9a Dimitris Aragiorgis
    print("Checking pidfile " + pidfile)
221 0ac84a9a Dimitris Aragiorgis
    try:
222 0ac84a9a Dimitris Aragiorgis
        f = open(pidfile, "r")
223 0ac84a9a Dimitris Aragiorgis
        pid = f.readline()
224 0ac84a9a Dimitris Aragiorgis
        os.kill(int(pid), signal.SIGKILL)
225 0ac84a9a Dimitris Aragiorgis
        f.close()
226 0ac84a9a Dimitris Aragiorgis
        os.remove(pidfile)
227 0ac84a9a Dimitris Aragiorgis
        time.sleep(5)
228 0ac84a9a Dimitris Aragiorgis
    except:
229 0ac84a9a Dimitris Aragiorgis
        pass
230 0ac84a9a Dimitris Aragiorgis
231 0ac84a9a Dimitris Aragiorgis
232 0ac84a9a Dimitris Aragiorgis
def randomMAC():
233 7d6fed3a Dionysis Grigoropoulos
    mac = [0x52, 0x54, 0x56,
234 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff),
235 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff),
236 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff)]
237 0ac84a9a Dimitris Aragiorgis
    return ':'.join(map(lambda x: "%02x" % x, mac))
238 0ac84a9a Dimitris Aragiorgis
239 0ac84a9a Dimitris Aragiorgis
240 0ac84a9a Dimitris Aragiorgis
def create_dir(d, clean=False):
241 0ac84a9a Dimitris Aragiorgis
    os.system("mkdir -p " + d)
242 0ac84a9a Dimitris Aragiorgis
    if clean:
243 0ac84a9a Dimitris Aragiorgis
        try:
244 0ac84a9a Dimitris Aragiorgis
            os.system("rm -f %s/*" % d)
245 0ac84a9a Dimitris Aragiorgis
        except:
246 0ac84a9a Dimitris Aragiorgis
            pass
247 0ac84a9a Dimitris Aragiorgis
248 0ac84a9a Dimitris Aragiorgis
249 0ac84a9a Dimitris Aragiorgis
def get_netinfo():
250 0ac84a9a Dimitris Aragiorgis
    _, pdev = get_default_route()
251 0ac84a9a Dimitris Aragiorgis
    r = re.compile(".*inet (\S+)/(\S+).*")
252 7d6fed3a Dionysis Grigoropoulos
    s = subprocess.Popen(['ip', 'addr', 'show', 'dev', pdev],
253 7d6fed3a Dionysis Grigoropoulos
                         stdout=subprocess.PIPE)
254 7d6fed3a Dionysis Grigoropoulos
255 0ac84a9a Dimitris Aragiorgis
    for line in s.stdout.readlines():
256 0ac84a9a Dimitris Aragiorgis
        match = r.search(line)
257 0ac84a9a Dimitris Aragiorgis
        if match:
258 0ac84a9a Dimitris Aragiorgis
            ip, size = match.groups()
259 0ac84a9a Dimitris Aragiorgis
            break
260 0ac84a9a Dimitris Aragiorgis
261 0ac84a9a Dimitris Aragiorgis
    return ip, size
262 0ac84a9a Dimitris Aragiorgis
263 0ac84a9a Dimitris Aragiorgis
264 0ac84a9a Dimitris Aragiorgis
def get_hostname():
265 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['hostname', '-s'], stdout=subprocess.PIPE)
266 0ac84a9a Dimitris Aragiorgis
    return s.stdout.readline().strip()
267 0ac84a9a Dimitris Aragiorgis
268 0ac84a9a Dimitris Aragiorgis
269 0ac84a9a Dimitris Aragiorgis
def get_domain():
270 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['hostname', '-d'], stdout=subprocess.PIPE)
271 0ac84a9a Dimitris Aragiorgis
    return s.stdout.readline().strip()
272 0ac84a9a Dimitris Aragiorgis
273 0ac84a9a Dimitris Aragiorgis
274 0ac84a9a Dimitris Aragiorgis
def get_default_route():
275 0ac84a9a Dimitris Aragiorgis
    r = re.compile("default via (\S+) dev (\S+)")
276 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['ip', 'route'], stdout=subprocess.PIPE)
277 0ac84a9a Dimitris Aragiorgis
    for line in s.stdout.readlines():
278 0ac84a9a Dimitris Aragiorgis
        match = r.search(line)
279 0ac84a9a Dimitris Aragiorgis
        if match:
280 0ac84a9a Dimitris Aragiorgis
            gw, dev = match.groups()
281 0ac84a9a Dimitris Aragiorgis
            break
282 0ac84a9a Dimitris Aragiorgis
283 0ac84a9a Dimitris Aragiorgis
    return (gw, dev)
284 0ac84a9a Dimitris Aragiorgis
285 0ac84a9a Dimitris Aragiorgis
286 0ac84a9a Dimitris Aragiorgis
def import_conf_file(filename, directory):
287 0ac84a9a Dimitris Aragiorgis
    return imp.load_module(filename, *imp.find_module(filename, [directory]))
288 0ac84a9a Dimitris Aragiorgis
289 0ac84a9a Dimitris Aragiorgis
290 0ac84a9a Dimitris Aragiorgis
def raddr(addr):
291 7d6fed3a Dionysis Grigoropoulos
    return list(reversed(addr.replace("/", "-").split(".")))