patch by Thomas Dreibholz - ovs-vsctl and not ovs-ovsctl
[nodemanager.git] / conf_files.py
1 """configuration files"""
2
3 import grp
4 import os
5 import pwd
6 try:
7     from hashlib import sha1 as sha
8 except ImportError:
9     from sha import sha
10 import string
11
12 import curlwrapper
13 import logger
14 import tools
15 import xmlrpclib
16 from config import Config
17
18 # right after net
19 priority = 2
20
21 class conf_files:
22     def __init__(self, noscripts=False):
23         self.config = Config()
24         self.noscripts = noscripts
25         self.data = None
26
27     def checksum(self, path):
28         try:
29             f = open(path)
30             try: return sha(f.read()).digest()
31             finally: f.close()
32         except IOError: return None
33
34     def system(self, cmd):
35         if not self.noscripts and cmd:
36             logger.verbose('conf_files: running command %s' % cmd)
37             return tools.fork_as(None, os.system, cmd)
38         else: return 0
39
40     def update_conf_file(self, cf_rec):
41         if not cf_rec['enabled']: return
42         dest = cf_rec['dest']
43         err_cmd = cf_rec['error_cmd']
44         mode = string.atoi(cf_rec['file_permissions'], base=8)
45         try:
46             uid = pwd.getpwnam(cf_rec['file_owner'])[2]
47         except:
48             logger.log('conf_files: cannot find user %s -- %s not updated'%(cf_rec['file_owner'], dest))
49             return
50         try:
51             gid = grp.getgrnam(cf_rec['file_group'])[2]
52         except:
53             logger.log('conf_files: cannot find group %s -- %s not updated'%(cf_rec['file_group'], dest))
54             return
55         url = 'https://%s/%s' % (self.config.PLC_BOOT_HOST, cf_rec['source'])
56         # set node_id at the end of the request - hacky
57         if tools.node_id():
58             if url.find('?') >0: url += '&'
59             else:                url += '?'
60             url += "node_id=%d"%tools.node_id()
61         else:
62             logger.log('conf_files: %s -- WARNING, cannot add node_id to request'%dest)
63         try:
64             logger.verbose("conf_files: retrieving URL=%s"%url)
65             contents = curlwrapper.retrieve(url, self.config.cacert)
66         except xmlrpclib.ProtocolError as e:
67             logger.log('conf_files: failed to retrieve %s from %s, skipping' % (dest, url))
68             return
69         if not cf_rec['always_update'] and sha(contents).digest() == self.checksum(dest):
70             return
71         if self.system(cf_rec['preinstall_cmd']):
72             self.system(err_cmd)
73             if not cf_rec['ignore_cmd_errors']: return
74         logger.log('conf_files: installing file %s from %s' % (dest, url))
75         try: os.makedirs(os.path.dirname(dest))
76         except OSError: pass
77         tools.write_file(dest, lambda f: f.write(contents), mode=mode, uidgid=(uid, gid))
78         if self.system(cf_rec['postinstall_cmd']): self.system(err_cmd)
79
80     def run_once(self, data):
81         if data.has_key("conf_files"):
82             for f in data['conf_files']:
83                 try: self.update_conf_file(f)
84                 except: logger.log_exc("conf_files: failed to update conf_file")
85         else:
86             logger.log_missing_data("conf_files.run_once", 'conf_files')
87
88
89 def start(): pass
90
91 def GetSlivers(data, config = None, plc = None):
92     logger.log("conf_files: Running.")
93     cf = conf_files()
94     cf.run_once(data)
95     logger.log("conf_files: Done.")
96
97 if __name__ == '__main__':
98     import optparse
99     parser = optparse.OptionParser()
100     parser.add_option('-f', '--config', action='store', dest='config', default='/etc/planetlab/plc_config', help='PLC configuration file')
101     parser.add_option('-k', '--session', action='store', dest='session', default='/etc/planetlab/session', help='API session key (or file)')
102     parser.add_option('--noscripts', action='store_true', dest='noscripts', default=False, help='Do not run pre- or post-install scripts')
103     (options, args) = parser.parse_args()
104
105     # Load /etc/planetlab/plc_config
106     config = Config(options.config)
107
108     # Load /etc/planetlab/session
109     if os.path.exists(options.session):
110         with open(options.session) as f:
111             session = f.read().strip()
112     else:
113         session = options.session
114
115     # Initialize XML-RPC client
116     from plcapi import PLCAPI
117     plc = PLCAPI(config.plc_api_uri, config.cacert, auth = session)
118
119     main = conf_files(options.noscripts)
120     data = plc.GetSlivers()
121     main.run_once(data)