"""configuration files"""

import grp
import os
import pwd
import sha
import string
import threading

import config
import curlwrapper
import logger
import tools


class conf_files:
    def __init__(self):
        self.cond = threading.Condition()
        self.config = config.Config()
        self.data = None

    def checksum(self, path):
        try:
            f = open(path)
            try: return sha.new(f.read()).digest()
            finally: f.close()
        except IOError: return None

    def system(self, cmd):
        if cmd:
            logger.log('conf_files: running command %s' % cmd)
            return os.system(cmd)
        else: return 0

    def update_conf_file(self, cf_rec):
        if not cf_rec['enabled']: return
        dest = cf_rec['dest']
        logger.log('conf_files: considering file %s' % dest)
        err_cmd = cf_rec['error_cmd']
        mode = string.atoi(cf_rec['file_permissions'], base=8)
        uid = pwd.getpwnam(cf_rec['file_owner'])[2]
        gid = grp.getgrnam(cf_rec['file_group'])[2]
        url = 'https://%s/%s' % (self.config.PLC_BOOT_HOST, cf_rec['source'])
        contents = curlwrapper.retrieve(url)
        logger.log('conf_files: retrieving url %s' % url)
        if not cf_rec['always_update'] and sha.new(contents).digest() == self.checksum(dest):
            logger.log('conf_files: skipping file %s, always_update is false and checksums are identical' % dest)
            return
        if self.system(cf_rec['preinstall_cmd']):
            self.system(err_cmd)
            if not cf_rec['ignore_cmd_errors']: return
        logger.log('conf_files: installing file %s' % dest)
        try: os.makedirs(os.path.dirname(dest))
        except OSError: pass
        tools.write_file(dest, lambda f: f.write(contents), mode=mode, uidgid=(uid,gid))
        if self.system(cf_rec['postinstall_cmd']): self.system(err_cmd)

    def run(self):
        while True:
            self.cond.acquire()
            while self.data == None: self.cond.wait()
            data = self.data
            self.data = None
            self.cond.release()
            for d in data:
                for f in d['conf_files']:
                    try: self.update_conf_file(f)
                    except: logger.log_exc()

    def callback(self, data):
        if data != None:
            self.cond.acquire()
            self.data = data
            self.cond.notify()
            self.cond.release()

main = conf_files()

def GetSlivers_callback(data): main.callback(data)

def start(options): tools.as_daemon_thread(main.run)

@@ -99,22 +99,8 @@
 ng%0A%0A
-import config%0A
 impo
@@ -114,16 +114,16 @@
 wrapper%0A
+
 import l
@@ -178,26 +178,63 @@
 _init__(self
-):
+, config):%0A        self.config = config
 %0A        sel
@@ -268,46 +268,8 @@
 n()%0A
-        self.config = config.Config()%0A
     
@@ -1141,16 +1141,36 @@
 ieve(url
+, self.config.cacert
 )%0A      
@@ -1885,16 +1885,195 @@
 r_cmd)%0A%0A
+    def run_once(self, data):%0A        for d in data:%0A            for f in d%5B'conf_files'%5D:%0A                try: self.update_conf_file(f)%0A                except: logger.log_exc()%0A%0A
     def 
@@ -2295,158 +2295,26 @@
     
-for d in data:%0A                for f in d%5B'conf_files'%5D:%0A                    try: self.update_conf_file(f)%0A                    except: logger.log_exc(
+self.run_once(data
 )%0A%0A 
@@ -2503,20 +2503,12 @@
 n = 
-conf_files()
+None
 %0A%0Ade
@@ -2578,40 +2578,981 @@
 ions
-): tools.as_daemon_thread(main.run
+, config):%0A    main = conf_files(config)%0A    tools.as_daemon_thread(main.run)%0A%0Aif __name__ == '__main__':%0A    import optparse%0A    parser = optparse.OptionParser()%0A    parser.add_option('-f', '--config', action='store', dest='config', default='/etc/planetlab/plc_config', help='PLC configuration file')%0A    parser.add_option('-k', '--session', action='store', dest='session', default='/etc/planetlab/session', help='API session key (or file)')%0A    (options, args) = parser.parse_args()%0A%0A    # Load /etc/planetlab/plc_config%0A    from config import Config%0A    config = Config(options.config)%0A%0A    # Load /etc/planetlab/session%0A    if os.path.exists(options.session):%0A        session = file(options.session).read().strip()%0A    else:%0A        session = options.session%0A%0A    # Initialize XML-RPC client%0A    from plcapi import PLCAPI%0A    plc = PLCAPI(config.plc_api_uri, config.cacert, auth = session)%0A%0A    main = conf_files(config)%0A    data = plc.GetSlivers()%0A    main.run_once(data
 )%0A

support one-shot run