Disallow multiple conf_files instances and have conf_files use curl with certificates.
[nodemanager.git] / conf_files.py
1 """configuration files"""
2
3 import grp
4 import os
5 import pwd
6 import sha
7 import string
8 import threading
9
10 import config
11 import curlwrapper
12 import logger
13 import tools
14
15
16 class conf_files:
17     def __init__(self):
18         self.cond = threading.Condition()
19         self.config = config.Config()
20         self.data = None
21
22     def checksum(self, path):
23         try:
24             f = open(path)
25             try: return sha.new(f.read()).digest()
26             finally: f.close()
27         except IOError: return None
28
29     def system(self, cmd):
30         if cmd:
31             logger.log('conf_files: running command %s' % cmd)
32             return os.system(cmd)
33         else: return 0
34
35     def update_conf_file(self, cf_rec):
36         if not cf_rec['enabled']: return
37         dest = cf_rec['dest']
38         logger.log('conf_files: considering file %s' % dest)
39         err_cmd = cf_rec['error_cmd']
40         mode = string.atoi(cf_rec['file_permissions'], base=8)
41         uid = pwd.getpwnam(cf_rec['file_owner'])[2]
42         gid = grp.getgrnam(cf_rec['file_group'])[2]
43         url = 'https://%s/%s' % (self.config.PLC_BOOT_HOST, cf_rec['source'])
44         contents = curlwrapper.retrieve(url)
45         logger.log('conf_files: retrieving url %s' % url)
46         if not cf_rec['always_update'] and sha.new(contents).digest() == self.checksum(dest):
47             logger.log('conf_files: skipping file %s, always_update is false and checksums are identical' % dest)
48             return
49         if self.system(cf_rec['preinstall_cmd']):
50             self.system(err_cmd)
51             if not cf_rec['ignore_cmd_errors']: return
52         logger.log('conf_files: installing file %s' % dest)
53         tools.write_file(dest, lambda f: f.write(contents), mode=mode, uidgid=(uid,gid))
54         if self.system(cf_rec['postinstall_cmd']): system(err_cmd)
55
56     def run(self):
57         while True:
58             self.cond.acquire()
59             while self.data == None: self.cond.wait()
60             data = self.data
61             self.data = None
62             self.cond.release()
63             for d in data:
64                 for f in d['conf_files']:
65                     try: self.update_conf_file(f)
66                     except: logger.log_exc()
67
68     def callback(self, data):
69         if data != None:
70             self.cond.acquire()
71             self.data = data
72             self.cond.notify()
73             self.cond.release()
74
75 main = conf_files()
76
77 def GetSlivers_callback(data): main.callback(data)
78
79 def start(options): tools.as_daemon_thread(main.run)