- create leading directories of conf files
[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         try: os.makedirs(os.path.dirname(dest))
54         except OSError: pass
55         tools.write_file(dest, lambda f: f.write(contents), mode=mode, uidgid=(uid,gid))
56         if self.system(cf_rec['postinstall_cmd']): self.system(err_cmd)
57
58     def run(self):
59         while True:
60             self.cond.acquire()
61             while self.data == None: self.cond.wait()
62             data = self.data
63             self.data = None
64             self.cond.release()
65             for d in data:
66                 for f in d['conf_files']:
67                     try: self.update_conf_file(f)
68                     except: logger.log_exc()
69
70     def callback(self, data):
71         if data != None:
72             self.cond.acquire()
73             self.data = data
74             self.cond.notify()
75             self.cond.release()
76
77 main = conf_files()
78
79 def GetSlivers_callback(data): main.callback(data)
80
81 def start(options): tools.as_daemon_thread(main.run)