Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (7.4 kB)

1 0ac84a9a Dimitris Aragiorgis
#!/usr/bin/python
2 0ac84a9a Dimitris Aragiorgis
3 0ac84a9a Dimitris Aragiorgis
import time
4 0ac84a9a Dimitris Aragiorgis
import ipaddr
5 0ac84a9a Dimitris Aragiorgis
import os
6 0ac84a9a Dimitris Aragiorgis
import signal
7 0ac84a9a Dimitris Aragiorgis
import ConfigParser
8 0ac84a9a Dimitris Aragiorgis
import sys
9 0ac84a9a Dimitris Aragiorgis
import re
10 0ac84a9a Dimitris Aragiorgis
import random
11 0ac84a9a Dimitris Aragiorgis
import subprocess
12 0ac84a9a Dimitris Aragiorgis
import imp
13 0ac84a9a Dimitris Aragiorgis
14 0ac84a9a Dimitris Aragiorgis
15 1bc6d467 Dionysis Grigoropoulos
HEADER = '\033[95m'
16 1bc6d467 Dionysis Grigoropoulos
OKBLUE = '\033[94m'
17 1bc6d467 Dionysis Grigoropoulos
OKGREEN = '\033[92m'
18 1bc6d467 Dionysis Grigoropoulos
WARNING = '\033[93m'
19 1bc6d467 Dionysis Grigoropoulos
FAIL = '\033[91m'
20 1bc6d467 Dionysis Grigoropoulos
ENDC = '\033[0m'
21 1bc6d467 Dionysis Grigoropoulos
22 1bc6d467 Dionysis Grigoropoulos
23 1bc6d467 Dionysis Grigoropoulos
def disable_color():
24 eaae0a32 Erethon
    global HEADER
25 eaae0a32 Erethon
    global OKBLUE
26 eaae0a32 Erethon
    global OKGREEN
27 eaae0a32 Erethon
    global WARNING
28 eaae0a32 Erethon
    global FAIL
29 eaae0a32 Erethon
    global ENDC
30 eaae0a32 Erethon
31 1bc6d467 Dionysis Grigoropoulos
    HEADER = ''
32 1bc6d467 Dionysis Grigoropoulos
    OKBLUE = ''
33 1bc6d467 Dionysis Grigoropoulos
    OKGREEN = ''
34 1bc6d467 Dionysis Grigoropoulos
    WARNING = ''
35 1bc6d467 Dionysis Grigoropoulos
    FAIL = ''
36 1bc6d467 Dionysis Grigoropoulos
    ENDC = ''
37 1bc6d467 Dionysis Grigoropoulos
38 1bc6d467 Dionysis Grigoropoulos
39 1bc6d467 Dionysis Grigoropoulos
if not sys.stdout.isatty():
40 1bc6d467 Dionysis Grigoropoulos
    disable_color()
41 0ac84a9a Dimitris Aragiorgis
42 7d6fed3a Dionysis Grigoropoulos
43 0ac84a9a Dimitris Aragiorgis
class Host(object):
44 f1b4fdfc Dimitris Aragiorgis
    def __init__(self, hostname, ip, mac, domain, os):
45 0ac84a9a Dimitris Aragiorgis
        self.hostname = hostname
46 0ac84a9a Dimitris Aragiorgis
        self.ip = ip
47 0ac84a9a Dimitris Aragiorgis
        self.mac = mac
48 0ac84a9a Dimitris Aragiorgis
        self.domain = domain
49 f1b4fdfc Dimitris Aragiorgis
        self.os = os
50 0ac84a9a Dimitris Aragiorgis
51 0ac84a9a Dimitris Aragiorgis
    @property
52 0ac84a9a Dimitris Aragiorgis
    def fqdn(self):
53 0ac84a9a Dimitris Aragiorgis
        return self.hostname + "." + self.domain
54 0ac84a9a Dimitris Aragiorgis
55 0ac84a9a Dimitris Aragiorgis
    @property
56 0ac84a9a Dimitris Aragiorgis
    def arecord(self):
57 0ac84a9a Dimitris Aragiorgis
        return self.hostname + " IN A " + self.ip + "\n"
58 0ac84a9a Dimitris Aragiorgis
59 0ac84a9a Dimitris Aragiorgis
    @property
60 0ac84a9a Dimitris Aragiorgis
    def ptrrecord(self):
61 0ac84a9a Dimitris Aragiorgis
        return ".".join(raddr(self.ip)) + " IN PTR " + self.fqdn + ".\n"
62 0ac84a9a Dimitris Aragiorgis
63 0ac84a9a Dimitris Aragiorgis
64 0ac84a9a Dimitris Aragiorgis
class Alias(Host):
65 0ac84a9a Dimitris Aragiorgis
    def __init__(self, host, alias):
66 7d6fed3a Dionysis Grigoropoulos
        super(Alias, self).__init__(host.hostname, host.ip, host.mac,
67 f1b4fdfc Dimitris Aragiorgis
                                    host.domain, host.os)
68 0ac84a9a Dimitris Aragiorgis
        self.alias = alias
69 0ac84a9a Dimitris Aragiorgis
70 0ac84a9a Dimitris Aragiorgis
    @property
71 0ac84a9a Dimitris Aragiorgis
    def cnamerecord(self):
72 7d6fed3a Dionysis Grigoropoulos
        return (self.alias + " IN CNAME " + self.hostname + "." +
73 7d6fed3a Dionysis Grigoropoulos
                self.domain + ".\n")
74 0ac84a9a Dimitris Aragiorgis
75 0ac84a9a Dimitris Aragiorgis
    @property
76 0ac84a9a Dimitris Aragiorgis
    def fqdn(self):
77 0ac84a9a Dimitris Aragiorgis
        return self.alias + "." + self.domain
78 0ac84a9a Dimitris Aragiorgis
79 0ac84a9a Dimitris Aragiorgis
80 0ac84a9a Dimitris Aragiorgis
class Env(object):
81 0ac84a9a Dimitris Aragiorgis
82 24dc98e2 Dimitris Aragiorgis
    def update_packages(self, os):
83 24dc98e2 Dimitris Aragiorgis
        for section in self.conf.files[os]:
84 ca1de37b Ilias Tsitsimpis
            self.evaluate(os, section)
85 24dc98e2 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 9f93a6fb Dimitris Aragiorgis
                            self.domain, None)
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 9f93a6fb Dimitris Aragiorgis
        "vcluster": ["cluster", "image", "network"],
142 7d6fed3a Dionysis Grigoropoulos
        "synnefo": ["cred", "synnefo", "roles"],
143 24dc98e2 Dimitris Aragiorgis
        "squeeze": ["debian", "ganeti", "synnefo", "other"],
144 24dc98e2 Dimitris Aragiorgis
        "wheezy": ["debian", "ganeti", "synnefo", "other"],
145 0ac84a9a Dimitris Aragiorgis
    }
146 3bae85da Dimitris Aragiorgis
    confdir = "/etc/snf-deploy"
147 0ac84a9a Dimitris Aragiorgis
148 3bae85da Dimitris Aragiorgis
    def get_ganeti(self, cluster_name):
149 0ac84a9a Dimitris Aragiorgis
        self.files["ganeti"] = [cluster_name]
150 3bae85da Dimitris Aragiorgis
151 3bae85da Dimitris Aragiorgis
    def __init__(self, args):
152 3bae85da Dimitris Aragiorgis
        self.confdir = args.confdir
153 3bae85da Dimitris Aragiorgis
        self.get_ganeti(args.cluster_name)
154 0ac84a9a Dimitris Aragiorgis
        for f in self.files.keys():
155 0ac84a9a Dimitris Aragiorgis
            setattr(self, f, self.read_config(f))
156 3bae85da Dimitris Aragiorgis
        for f, sections in self.files.iteritems():
157 3bae85da Dimitris Aragiorgis
            for s in sections:
158 3bae85da Dimitris Aragiorgis
                for k, v in self.get_section(f, s):
159 3bae85da Dimitris Aragiorgis
                    if getattr(args, k, None):
160 3bae85da Dimitris Aragiorgis
                        self.set(f, s, k, getattr(args, k))
161 3bae85da Dimitris Aragiorgis
        if args.autoconf:
162 3bae85da Dimitris Aragiorgis
            self.autoconf()
163 3bae85da Dimitris Aragiorgis
164 3bae85da Dimitris Aragiorgis
    def autoconf(self):
165 3bae85da Dimitris Aragiorgis
        #domain = get_domain()
166 3bae85da Dimitris Aragiorgis
        #if domain:
167 3bae85da Dimitris Aragiorgis
        #    self.nodes.set("network", "domain", get_domain())
168 3bae85da Dimitris Aragiorgis
        # self.nodes.set("network", "subnet", "/".join(get_netinfo()))
169 3bae85da Dimitris Aragiorgis
        # self.nodes.set("network", "gateway", get_default_route()[0])
170 3bae85da Dimitris Aragiorgis
        self.nodes.set("hostnames", "node1", get_hostname())
171 3bae85da Dimitris Aragiorgis
        self.nodes.set("ips", "node1", get_netinfo()[0])
172 3bae85da Dimitris Aragiorgis
        self.nodes.set("info", "nodes", "node1")
173 3bae85da Dimitris Aragiorgis
        self.nodes.set("info", "public_iface", get_default_route()[1])
174 0ac84a9a Dimitris Aragiorgis
175 0ac84a9a Dimitris Aragiorgis
    def read_config(self, f):
176 0ac84a9a Dimitris Aragiorgis
        config = ConfigParser.ConfigParser()
177 0ac84a9a Dimitris Aragiorgis
        config.optionxform = str
178 0ac84a9a Dimitris Aragiorgis
        filename = os.path.join(self.confdir, f) + ".conf"
179 0ac84a9a Dimitris Aragiorgis
        config.read(filename)
180 0ac84a9a Dimitris Aragiorgis
        return config
181 0ac84a9a Dimitris Aragiorgis
182 0ac84a9a Dimitris Aragiorgis
    def set(self, conf, section, option, value):
183 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
184 0ac84a9a Dimitris Aragiorgis
        c.set(section, option, value)
185 0ac84a9a Dimitris Aragiorgis
186 0ac84a9a Dimitris Aragiorgis
    def get(self, conf, section, option):
187 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
188 0ac84a9a Dimitris Aragiorgis
        return c.get(section, option, True)
189 0ac84a9a Dimitris Aragiorgis
190 0ac84a9a Dimitris Aragiorgis
    def get_section(self, conf, section):
191 0ac84a9a Dimitris Aragiorgis
        c = getattr(self, conf)
192 0ac84a9a Dimitris Aragiorgis
        return c.items(section, True)
193 0ac84a9a Dimitris Aragiorgis
194 0ac84a9a Dimitris Aragiorgis
    def print_config(self):
195 0ac84a9a Dimitris Aragiorgis
        for f in self.files.keys():
196 0ac84a9a Dimitris Aragiorgis
            getattr(self, f).write(sys.stdout)
197 0ac84a9a Dimitris Aragiorgis
198 24dc98e2 Dimitris Aragiorgis
199 0ac84a9a Dimitris Aragiorgis
def debug(host, msg):
200 0ac84a9a Dimitris Aragiorgis
201 1bc6d467 Dionysis Grigoropoulos
    print HEADER + host + \
202 7d6fed3a Dionysis Grigoropoulos
        OKBLUE + ": " + msg + ENDC
203 0ac84a9a Dimitris Aragiorgis
204 0ac84a9a Dimitris Aragiorgis
205 0ac84a9a Dimitris Aragiorgis
def check_pidfile(pidfile):
206 0ac84a9a Dimitris Aragiorgis
    print("Checking pidfile " + pidfile)
207 0ac84a9a Dimitris Aragiorgis
    try:
208 0ac84a9a Dimitris Aragiorgis
        f = open(pidfile, "r")
209 0ac84a9a Dimitris Aragiorgis
        pid = f.readline()
210 0ac84a9a Dimitris Aragiorgis
        os.kill(int(pid), signal.SIGKILL)
211 0ac84a9a Dimitris Aragiorgis
        f.close()
212 0ac84a9a Dimitris Aragiorgis
        os.remove(pidfile)
213 0ac84a9a Dimitris Aragiorgis
        time.sleep(5)
214 0ac84a9a Dimitris Aragiorgis
    except:
215 0ac84a9a Dimitris Aragiorgis
        pass
216 0ac84a9a Dimitris Aragiorgis
217 0ac84a9a Dimitris Aragiorgis
218 ca1de37b Ilias Tsitsimpis
def random_mac():
219 7d6fed3a Dionysis Grigoropoulos
    mac = [0x52, 0x54, 0x56,
220 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff),
221 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff),
222 7d6fed3a Dionysis Grigoropoulos
           random.randint(0x00, 0xff)]
223 0ac84a9a Dimitris Aragiorgis
    return ':'.join(map(lambda x: "%02x" % x, mac))
224 0ac84a9a Dimitris Aragiorgis
225 0ac84a9a Dimitris Aragiorgis
226 0ac84a9a Dimitris Aragiorgis
def create_dir(d, clean=False):
227 0ac84a9a Dimitris Aragiorgis
    os.system("mkdir -p " + d)
228 0ac84a9a Dimitris Aragiorgis
    if clean:
229 0ac84a9a Dimitris Aragiorgis
        try:
230 0ac84a9a Dimitris Aragiorgis
            os.system("rm -f %s/*" % d)
231 0ac84a9a Dimitris Aragiorgis
        except:
232 0ac84a9a Dimitris Aragiorgis
            pass
233 0ac84a9a Dimitris Aragiorgis
234 0ac84a9a Dimitris Aragiorgis
235 0ac84a9a Dimitris Aragiorgis
def get_netinfo():
236 0ac84a9a Dimitris Aragiorgis
    _, pdev = get_default_route()
237 0ac84a9a Dimitris Aragiorgis
    r = re.compile(".*inet (\S+)/(\S+).*")
238 7d6fed3a Dionysis Grigoropoulos
    s = subprocess.Popen(['ip', 'addr', 'show', 'dev', pdev],
239 7d6fed3a Dionysis Grigoropoulos
                         stdout=subprocess.PIPE)
240 7d6fed3a Dionysis Grigoropoulos
241 0ac84a9a Dimitris Aragiorgis
    for line in s.stdout.readlines():
242 0ac84a9a Dimitris Aragiorgis
        match = r.search(line)
243 0ac84a9a Dimitris Aragiorgis
        if match:
244 0ac84a9a Dimitris Aragiorgis
            ip, size = match.groups()
245 0ac84a9a Dimitris Aragiorgis
            break
246 0ac84a9a Dimitris Aragiorgis
247 0ac84a9a Dimitris Aragiorgis
    return ip, size
248 0ac84a9a Dimitris Aragiorgis
249 0ac84a9a Dimitris Aragiorgis
250 0ac84a9a Dimitris Aragiorgis
def get_hostname():
251 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['hostname', '-s'], stdout=subprocess.PIPE)
252 0ac84a9a Dimitris Aragiorgis
    return s.stdout.readline().strip()
253 0ac84a9a Dimitris Aragiorgis
254 0ac84a9a Dimitris Aragiorgis
255 0ac84a9a Dimitris Aragiorgis
def get_domain():
256 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['hostname', '-d'], stdout=subprocess.PIPE)
257 0ac84a9a Dimitris Aragiorgis
    return s.stdout.readline().strip()
258 0ac84a9a Dimitris Aragiorgis
259 0ac84a9a Dimitris Aragiorgis
260 0ac84a9a Dimitris Aragiorgis
def get_default_route():
261 0ac84a9a Dimitris Aragiorgis
    r = re.compile("default via (\S+) dev (\S+)")
262 0ac84a9a Dimitris Aragiorgis
    s = subprocess.Popen(['ip', 'route'], stdout=subprocess.PIPE)
263 0ac84a9a Dimitris Aragiorgis
    for line in s.stdout.readlines():
264 0ac84a9a Dimitris Aragiorgis
        match = r.search(line)
265 0ac84a9a Dimitris Aragiorgis
        if match:
266 0ac84a9a Dimitris Aragiorgis
            gw, dev = match.groups()
267 0ac84a9a Dimitris Aragiorgis
            break
268 0ac84a9a Dimitris Aragiorgis
269 0ac84a9a Dimitris Aragiorgis
    return (gw, dev)
270 0ac84a9a Dimitris Aragiorgis
271 0ac84a9a Dimitris Aragiorgis
272 0ac84a9a Dimitris Aragiorgis
def import_conf_file(filename, directory):
273 0ac84a9a Dimitris Aragiorgis
    return imp.load_module(filename, *imp.find_module(filename, [directory]))
274 0ac84a9a Dimitris Aragiorgis
275 0ac84a9a Dimitris Aragiorgis
276 0ac84a9a Dimitris Aragiorgis
def raddr(addr):
277 7d6fed3a Dionysis Grigoropoulos
    return list(reversed(addr.replace("/", "-").split(".")))