Beispiel #1
0
 def __init__(self, conn, suite, name='TraitDebconfBrowser'):
     self.menu = make_menu(dcmenu_cmds, self.modify_trait)
     ListNoteBook.__init__(self)
     self.conn = conn
     self.suite = suite
     self.dc = TraitDebconf(self.conn, self.suite)
     self.traits = Traits(self.conn, self.suite)
     self.reset_rows()
Beispiel #2
0
 def __init__(self, conn, suite, trait, name='DebconfEditor'):
     self.menu = make_menu(['update', 'insert'], self.main_command)
     _DebconfEditor.__init__(self, name=name)
     self.conn = conn
     self.suite = suite
     self.dc = TraitDebconf(self.conn, self.suite)
     self.dialogs = dict.fromkeys(['setconf', 'settemplate'])
     self.trait = trait
     self.dc.set_trait(trait)
Beispiel #3
0
 def __init__(self, conn, suite, name='DebconfBrowser'):
     CommandBoxWindow.__init__(self, name=name)
     self.tdcbox = TraitDebconfBrowser(conn, suite, name=name)
     self.vbox.add(self.tdcbox)
     self.conn = conn
     self.suite = suite
     self.dc = TraitDebconf(self.conn, self.suite)
     self.tbar.add_button('update', 'update', self.reset_rows)
     self.tbar.add_button('delete', 'delete', self.delete_row)
     self.reset_rows()
Beispiel #4
0
class DebconfBrowser(CommandBoxWindow):
    def __init__(self, conn, suite, name='DebconfBrowser'):
        CommandBoxWindow.__init__(self, name=name)
        self.tdcbox = TraitDebconfBrowser(conn, suite, name=name)
        self.vbox.add(self.tdcbox)
        self.conn = conn
        self.suite = suite
        self.dc = TraitDebconf(self.conn, self.suite)
        self.tbar.add_button('update', 'update', self.reset_rows)
        self.tbar.add_button('delete', 'delete', self.delete_row)
        self.reset_rows()

    def reset_rows(self, *args):
        self.dcbox.set_rows(self.dc.cmd.select())

    def delete_row(self, button, data):
        rows = self.dcbox.get_selected_data()
        if len(rows) != 1:
            dialogs.Message('need to select something')
        else:
            r = rows[0]
            self.dc.delete(r.name, r.trait)
Beispiel #5
0
class DebconfBrowser(CommandBoxWindow):
    def __init__(self, conn, suite, name='DebconfBrowser'):
        CommandBoxWindow.__init__(self, name=name)
        self.tdcbox = TraitDebconfBrowser(conn, suite, name=name)
        self.vbox.add(self.tdcbox)
        self.conn = conn
        self.suite = suite
        self.dc = TraitDebconf(self.conn, self.suite)
        self.tbar.add_button('update', 'update', self.reset_rows)
        self.tbar.add_button('delete', 'delete', self.delete_row)
        self.reset_rows()
        
    def reset_rows(self, *args):
        self.dcbox.set_rows(self.dc.cmd.select())


    def delete_row(self, button, data):
        rows = self.dcbox.get_selected_data()
        if len(rows) != 1:
            dialogs.Message('need to select something')
        else:
            r = rows[0]
            self.dc.delete(r.name, r.trait)
Beispiel #6
0
class DebconfEditor(_DebconfEditor):
    def __init__(self, conn, suite, trait, name='DebconfEditor'):
        self.menu = make_menu(['update', 'insert'], self.main_command)
        _DebconfEditor.__init__(self, name=name)
        self.conn = conn
        self.suite = suite
        self.dc = TraitDebconf(self.conn, self.suite)
        self.dialogs = dict.fromkeys(['setconf', 'settemplate'])
        self.trait = trait
        self.dc.set_trait(trait)
        
    def _get_debconf(self, data=True):
        rows = self.get_selected_data()
        if not len(rows):
            raise dialogs.Message('need to select something')
        name = rows[0].name
        if data:
            return self._get_debconf_data(name)
        else:
            return name

    def _get_debconf_data(self, name):
        data = {}.fromkeys(['name', 'template', 'owners', 'value'])
        for key in data:
            data[key] = self._debconf[name][key]
        return data
    
    def main_command(self, menuitem, command):
        if command == 'update':
            data = self._get_debconf()
            self.dc.update(data, self.trait)
        elif command == 'insert':
            data = self._get_debconf()
            self.dc.insert(data, self.trait)
                

    def filesel_ok(self, button, filesel):
        path = filesel.get_filename()
        action = filesel.get_data('action')
        if action == 'setconf':
            self.set_config(path)
        else:
            self.set_template(path)
        filesel.destroy()
Beispiel #7
0
class TraitDebconfBrowser(ListNoteBook):
    def __init__(self, conn, suite, name='TraitDebconfBrowser'):
        self.menu = make_menu(dcmenu_cmds, self.modify_trait)
        ListNoteBook.__init__(self)
        self.conn = conn
        self.suite = suite
        self.dc = TraitDebconf(self.conn, self.suite)
        self.traits = Traits(self.conn, self.suite)
        self.reset_rows()

    def reset_rows(self):
        rows = self.traits.select(fields=['trait'])
        self.set_rows(rows)
        self.set_row_select(self.trait_selected)

    def trait_selected(self, listbox, row, column, event):
        trait = listbox.get_selected_data()[0].trait
        self.select_trait(trait)
        
    def select_trait(self, trait):
        self.trait = trait
        self.dc.set_trait(trait)
        if trait not in self.pages:
            newpage = ScrollCList()
            self.append_page(newpage, trait)
        self.set_current_page(trait)
        self.pages[trait].set_rows(self.dc.cmd.select())

    def modify_trait(self, menuitem, action):
        try:
            trait = self.listbox.get_selected_data()[0].trait
        except IndexError:
            dialogs.Message('no trait selected')
            raise IndexError
        if action == 'getconfig':
            self.select_configdat(action='getconfig')
        elif action == 'getfromtar':
            self.select_configdat(action='getfromtar')
        elif action == 'update':
            print 'update'
        elif action == 'delete':
            print 'delete'
        

    def select_configdat(self, button=None, data=None, action='getconfig'):
        select_a_file(action, '/', self.filesel_ok)
        

    def pull_from_tar(self, button, fileselect):
        info, tfile = fileselect.extract_file()
        print tfile.name
        conffile, cfpath = tempfile.mkstemp('paella', 'debconf')
        conffile = file(cfpath, 'w')
        conffile.write(tfile.read())
        conffile.close()
        self.editor = DebconfEditorWin(self.conn, self.suite, self.trait)
        self.editor.set_config(cfpath)
        fileselect.destroy()
        os.remove(cfpath)
    
        
    def filesel_ok(self, button, filesel):
        path = filesel.get_filename()
        action = filesel.get_data('action')
        if action == 'getconfig':
            self.editor = DebconfEditorWin(self.conn, self.suite, self.trait)
            self.editor.set_config(path)
        elif action == 'getfromtar':
            select_from_tarfile('getfromtar', path, self.pull_from_tar)
        filesel.destroy()
Beispiel #8
0
 def __init__(self, conn, suite, cfg):
     Installer.__init__(self, conn, cfg=cfg)
     self.traitpackage = TraitPackage(conn, suite)
     self.traittemplate = TraitTemplate(conn, suite)
     self.traitdebconf = TraitDebconf(conn, suite)
     self.traitscripts = TraitScript(conn, suite)
Beispiel #9
0
class TraitInstaller(Installer):
    def __init__(self, conn, suite, cfg):
        Installer.__init__(self, conn, cfg=cfg)
        self.traitpackage = TraitPackage(conn, suite)
        self.traittemplate = TraitTemplate(conn, suite)
        self.traitdebconf = TraitDebconf(conn, suite)
        self.traitscripts = TraitScript(conn, suite)
        
    def set_trait(self, trait):
        self.traitpackage.set_trait(trait)
        self.traittemplate.set_trait(trait)
        self.traitdebconf.set_trait(trait)
        self.traitscripts.set_trait(trait)
        self._current_trait_ = trait
        self.log.info('trait set to %s' % self._current_trait_)

    def run(self, name, command, args='', proc=False, chroot=True,
            keeprunning=False):
        tname = 'trait-%s-%s' % (self._current_trait_, name)
        Installer.run(self, tname, command, args=args, proc=proc,
                      chroot=chroot,
                      keeprunning=keeprunning)
        

    def runscript(self, script, name, info, chroot=False):
        self.log.info(info['start'])
        self.run(name, script, chroot=chroot)
        os.remove(script)
        self.log.info(info['done'])
        
    def process(self):
        self.log.info('processing %s' % self._current_trait_)
        os.environ['PAELLA_TARGET'] = self.target
        os.environ['PAELLA_TRAIT'] = self._current_trait_
        packages = self.traitpackage.packages()
        templates = self.traittemplate.templates()

        #start pre script
        script = self._make_script('pre')
        if script is not None:
            info = dict(start='pre script started',
                        done='pre script done')
            self.runscript(script, 'pre-script', info)
            
        #remove packages
        script = self._make_script('remove')
        if script is None:
            remove = [p for p in packages if p.action == 'remove']
            if len(remove):
                self.remove(remove)
        else:
            info = dict(start='remove script started',
                        done='remove script done')
            self.runscript(script, 'remove-script', info)

        #install packages
        script = self._make_script('install')
        if script is None:
            install = [p for p in packages if p.action == 'install']
            if len(install):
                self.install(install, templates)
        else:
            info = dict(start='install script started',
                        done='install script done')
            self.runscript(script, 'install-script', info)
                        
        #configure packages
        script = self._make_script('config')
        if script is None:
            config = [p for p in packages if p.action in ['install', 'config']]
            if len(config):
                self.configure(config, templates)
        else:
            info = dict(start='config script started',
                        done='config script done')
            self.runscript(script, 'config-script', info)
            
        #reconfigure debconf
        script = self._make_script('reconfig')
        if script is None:
            self.reconfigure_debconf()
        else:
            info = dict(start='reconfig script started',
                        done='reconfig script done')
            self.runscript(script, 'reconfig-script', info)

        #start post script
        script = self._make_script('post')
        if script is not None:
            info = dict(start='post script started',
                        done='post script done')
            self.runscript(script, 'post-script', info)
                
    def remove(self, packages):
        packages = ' '.join([p.package for p in packages])
        command, args = 'apt-get -y remove', packages
        self.run('remove', command, args=args, proc=True)
                
    def install(self, packages, templates):
        package_args = ' '.join([p.package for p in packages])
        cmd = 'apt-get -y --force-yes install %s\n' % package_args
        cmd += 'rm /var/cache/apt/archives/*.deb -f'
        #os.system(self.with_proc(cmd))
        run = self.run('install', cmd, proc=True, keeprunning=True)
        if run:
            self.log.warn('PROBLEM installing %s' % self._current_trait_)
            self.log.warn('packages --> %s' % package_args)
            

    def configure(self, packages, templates):
        dpkg_rec = False
        for p in packages:
            for t in [t for t in templates if t.package == p.package]:
                if t.template == 'var/cache/debconf/config.dat':
                    dpkg_rec = True
                    self.log.info('Installing Debconf template ...')
                    self.install_debconf_template(t)
                else:
                    self.make_template(t)
        if dpkg_rec:
            self.log.info('Reconfiguring packages')
            for p in packages:
                cmd = 'dpkg-reconfigure -plow %s' % p.package
                run = self.run('dpkg-recfg', cmd, proc=True, keeprunning=True)
                if run:
                    self.log.info('reconfigure failed on %s' % p.package)
                else:
                    self.log.info('%s reconfigured' % p.package)
        script = self._make_script('chroot', execpath=True)
        if script is not None:
            #os.system(self.command(script))
            self.run('chroot-script', script)
            if script[0] == '/':
                script = script[1:]
            os.remove(join(self.target, script))
            
    def _make_script(self, name, execpath=False):
        script = self.traitscripts.get(name)
        if script is not None:
            exec_path = join('/tmp', name + '-script')
            target_path = join(self.target, 'tmp', name + '-script')
            sfile = file(target_path, 'w')
            sfile.write(script.read())
            sfile.close()
            os.system('chmod 755 %s' % target_path)
            if not execpath:
                return target_path
            else:
                return exec_path
        else:
            return None
        
    def make_template(self, template):
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(self.familydata)
        self.traittemplate.template.update(self.profiledata)
        self._make_template_common(template, tmpl)
        

    def make_template_with_data(self, template, data):
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(data)
        self._make_template_common(template, tmpl)
        
    def _make_template_common(self, template, tmpl):
        sub = self.traittemplate.template.sub()
        newpath = join(self.target, template.template)
        self.log.info('target template %s' % newpath)
        dir = dirname(newpath)
        if not isdir(dir):
            makepaths(dir)
        if tmpl != sub:
            self.log.info('%s %s subbed' % (template.package, template.template))
        newfile = file(newpath, 'w')
        newfile.write(sub)
        newfile.close()
        mode = template.mode
        if mode[0] == '0' and len(mode) <= 7 and mode.isdigit():
            mode = eval(mode)
        os.chmod(newpath, mode)
        own = ':'.join([template.owner, template.grp_owner])
        os.system(self.command('chown', '%s %s' %(own, join('/', template.template))))

    def install_debconf_template(self, template):
        self.log.info('Installing debconf for %s' % self._current_trait_)
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(self.profiledata)
        sub = self.traittemplate.template.sub()
        if tmpl == sub:
            self.log.info('static debconf, no substitutions')
            self.log.info('for trait %s ' % self._current_trait_)
        config_path = join(self.target, 'tmp/paella_debconf')
        if isfile(config_path):
            raise Error, '%s is not supposed to be there' % config_path
        debconf = file(config_path, 'w')
        debconf.write(sub + '\n')
        debconf.close()
        target_path = join(self.target, 'var/cache/debconf/config.dat')
        self.log.info('debconf config is %s %s' % (config_path, target_path))
        copy_configdb(config_path, target_path)
        os.remove(config_path)

    def set_template_path(self, path):
        self.traittemplate.template.set_path(path)

    def install_debconf(self):
        config = self.traitdebconf.get_config()
        config_path = join(self.target, 'tmp/paella_debconf')
        if isfile(config_path):
            raise Error, '%s is not supposed to be there' % config_path
        debconf = file(config_path, 'w')
        debconf.write(config + '\n')
        debconf.close()
        target_path = join(self.target, 'var/cache/debconf/config.dat')
        self.log.info('debconf config is %s %s' % (config_path, target_path))
        cmd = install_debconf(config_path, target_path)
        command = 'sh -c "%s"' % cmd
        self.log.info(cmd)
        os.system(cmd)
        os.remove(config_path)

    def reconfigure_debconf(self):
        owners = self.traitdebconf.all_owners()
        self.log.info('ALL OWNERS %s' % owners)
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        for owner in owners:
            self.log.info('RECONFIGURING %s' % owner)
            os.system(self.command('dpkg-reconfigure -plow %s' % owner))
Beispiel #10
0
from paella.gtk.utils import DownloadPoolBox as dpb
from paella.admin.management import Manager, SuiteManager
from paella.admin.debconf import DebconfEditorWin, DebconfBrowser

cfg = Configuration()

m = Manager()
m.set_usize(200, 300)
m.set_uposition(1050, 730)

#mirror = 'http://ftp.us.debian.org/debian/dists/'
mirror = 'http://paella/debian/dists.orig/'
m.dbconnect(cfg['dbname'])
#tm = TemplateManager(m.conn, 'woody')
#dc.debconf.set_config('/var/cache/debconf/config.dat')
#db = DebconfBrowser(m.conn, 'sid', 'default')

from paella.profile.trait import TraitDebconf
from paella.profile.profile import ProfileEnvironment
pe = ProfileEnvironment(m.conn, 'paella')
pe.set_trait('base')

td = TraitDebconf(m.conn, 'sid')

w = SuiteManager(m.conn, 'woody')
s = SuiteManager(m.conn, 'sid')

w.set_uposition(600, 20)
s.set_uposition(600, 60)
Beispiel #11
0
 def __init__(self, conn, suite, cfg):
     Installer.__init__(self, conn, cfg=cfg)
     self.traitpackage = TraitPackage(conn, suite)
     self.traittemplate = TraitTemplate(conn, suite)
     self.traitdebconf = TraitDebconf(conn, suite)
     self.traitscripts = TraitScript(conn, suite)
Beispiel #12
0
class TraitInstaller(Installer):
    def __init__(self, conn, suite, cfg):
        Installer.__init__(self, conn, cfg=cfg)
        self.traitpackage = TraitPackage(conn, suite)
        self.traittemplate = TraitTemplate(conn, suite)
        self.traitdebconf = TraitDebconf(conn, suite)
        self.traitscripts = TraitScript(conn, suite)
        
    def set_trait(self, trait):
        self.traitpackage.set_trait(trait)
        self.traittemplate.set_trait(trait)
        self.traitdebconf.set_trait(trait)
        self.traitscripts.set_trait(trait)
        self._current_trait_ = trait
        self.log.info('trait set to %s' % self._current_trait_)

    def run(self, name, command, args='', proc=False, chroot=True,
            keeprunning=False):
        tname = 'trait-%s-%s' % (self._current_trait_, name)
        Installer.run(self, tname, command, args=args, proc=proc,
                      chroot=chroot,
                      keeprunning=keeprunning)
        

    def runscript(self, script, name, info, chroot=False):
        self.log.info(info['start'])
        self.run(name, script, chroot=chroot)
        os.remove(script)
        self.log.info(info['done'])
        
    def process(self):
        self.log.info('processing %s' % self._current_trait_)
        os.environ['PAELLA_TARGET'] = self.target
        os.environ['PAELLA_TRAIT'] = self._current_trait_
        packages = self.traitpackage.packages()
        templates = self.traittemplate.templates()

        #start pre script
        script = self._make_script('pre')
        if script is not None:
            info = dict(start='pre script started',
                        done='pre script done')
            self.runscript(script, 'pre-script', info)
            
        #remove packages
        script = self._make_script('remove')
        if script is None:
            remove = [p for p in packages if p.action == 'remove']
            if len(remove):
                self.remove(remove)
        else:
            info = dict(start='remove script started',
                        done='remove script done')
            self.runscript(script, 'remove-script', info)

        #install packages
        script = self._make_script('install')
        if script is None:
            install = [p for p in packages if p.action == 'install']
            if len(install):
                self.install(install, templates)
        else:
            info = dict(start='install script started',
                        done='install script done')
            self.runscript(script, 'install-script', info)
                        
        #configure packages
        script = self._make_script('config')
        if script is None:
            config = [p for p in packages if p.action in ['install', 'config']]
            if len(config):
                self.configure(config, templates)
        else:
            info = dict(start='config script started',
                        done='config script done')
            self.runscript(script, 'config-script', info)
            
        #reconfigure debconf
        script = self._make_script('reconfig')
        if script is None:
            self.reconfigure_debconf()
        else:
            info = dict(start='reconfig script started',
                        done='reconfig script done')
            self.runscript(script, 'reconfig-script', info)

        #start post script
        script = self._make_script('post')
        if script is not None:
            info = dict(start='post script started',
                        done='post script done')
            self.runscript(script, 'post-script', info)
                
    def remove(self, packages):
        packages = ' '.join([p.package for p in packages])
        command, args = 'apt-get -y remove', packages
        self.run('remove', command, args=args, proc=True)
                
    def install(self, packages, templates):
        package_args = ' '.join([p.package for p in packages])
        cmd = 'apt-get -y --force-yes install %s\n' % package_args
        cmd += 'rm /var/cache/apt/archives/*.deb -f'
        #os.system(self.with_proc(cmd))
        run = self.run('install', cmd, proc=True, keeprunning=True)
        if run:
            self.log.warn('PROBLEM installing %s' % self._current_trait_)
            self.log.warn('packages --> %s' % package_args)
            

    def configure(self, packages, templates):
        dpkg_rec = False
        for p in packages:
            for t in [t for t in templates if t.package == p.package]:
                if t.template == 'var/cache/debconf/config.dat':
                    dpkg_rec = True
                    self.log.info('Installing Debconf template ...')
                    self.install_debconf_template(t)
                else:
                    self.make_template(t)
        if dpkg_rec:
            self.log.info('Reconfiguring packages')
            for p in packages:
                cmd = 'dpkg-reconfigure -plow %s' % p.package
                run = self.run('dpkg-recfg', cmd, proc=True, keeprunning=True)
                if run:
                    self.log.info('reconfigure failed on %s' % p.package)
                else:
                    self.log.info('%s reconfigured' % p.package)
        script = self._make_script('chroot', execpath=True)
        if script is not None:
            #os.system(self.command(script))
            self.run('chroot-script', script)
            if script[0] == '/':
                script = script[1:]
            os.remove(join(self.target, script))
            
    def _make_script(self, name, execpath=False):
        script = self.traitscripts.get(name)
        if script is not None:
            exec_path = join('/tmp', name + '-script')
            target_path = join(self.target, 'tmp', name + '-script')
            sfile = file(target_path, 'w')
            sfile.write(script.read())
            sfile.close()
            os.system('chmod 755 %s' % target_path)
            if not execpath:
                return target_path
            else:
                return exec_path
        else:
            return None
        
    def make_template(self, template):
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(self.familydata)
        self.traittemplate.template.update(self.profiledata)
        self._make_template_common(template, tmpl)
        

    def make_template_with_data(self, template, data):
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(data)
        self._make_template_common(template, tmpl)
        
    def _make_template_common(self, template, tmpl):
        sub = self.traittemplate.template.sub()
        newpath = join(self.target, template.template)
        self.log.info('target template %s' % newpath)
        dir = dirname(newpath)
        if not isdir(dir):
            makepaths(dir)
        if tmpl != sub:
            self.log.info('%s %s subbed' % (template.package, template.template))
        newfile = file(newpath, 'w')
        newfile.write(sub)
        newfile.close()
        mode = template.mode
        if mode[0] == '0' and len(mode) <= 7 and mode.isdigit():
            mode = eval(mode)
        os.chmod(newpath, mode)
        own = ':'.join([template.owner, template.grp_owner])
        os.system(self.command('chown', '%s %s' %(own, join('/', template.template))))

    def install_debconf_template(self, template):
        self.log.info('Installing debconf for %s' % self._current_trait_)
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(self.profiledata)
        sub = self.traittemplate.template.sub()
        if tmpl == sub:
            self.log.info('static debconf, no substitutions')
            self.log.info('for trait %s ' % self._current_trait_)
        config_path = join(self.target, 'tmp/paella_debconf')
        if isfile(config_path):
            raise Error, '%s is not supposed to be there' % config_path
        debconf = file(config_path, 'w')
        debconf.write(sub + '\n')
        debconf.close()
        target_path = join(self.target, 'var/cache/debconf/config.dat')
        self.log.info('debconf config is %s %s' % (config_path, target_path))
        copy_configdb(config_path, target_path)
        os.remove(config_path)

    def set_template_path(self, path):
        self.traittemplate.template.set_path(path)

    def install_debconf(self):
        config = self.traitdebconf.get_config()
        config_path = join(self.target, 'tmp/paella_debconf')
        if isfile(config_path):
            raise Error, '%s is not supposed to be there' % config_path
        debconf = file(config_path, 'w')
        debconf.write(config + '\n')
        debconf.close()
        target_path = join(self.target, 'var/cache/debconf/config.dat')
        self.log.info('debconf config is %s %s' % (config_path, target_path))
        cmd = install_debconf(config_path, target_path)
        command = 'sh -c "%s"' % cmd
        self.log.info(cmd)
        os.system(cmd)
        os.remove(config_path)

    def reconfigure_debconf(self):
        owners = self.traitdebconf.all_owners()
        self.log.info('ALL OWNERS %s' % owners)
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        for owner in owners:
            self.log.info('RECONFIGURING %s' % owner)
            os.system(self.command('dpkg-reconfigure -plow %s' % owner))
Beispiel #13
0
class TraitInstaller(Installer):
    def __init__(self, conn, suite, cfg):
        Installer.__init__(self, conn, cfg=cfg)
        self.traitpackage = TraitPackage(conn, suite)
        self.traittemplate = TraitTemplate(conn, suite)
        self.traitdebconf = TraitDebconf(conn, suite)
        self.traitscripts = TraitScript(conn, suite)

    def set_trait(self, trait):
        self.traitpackage.set_trait(trait)
        self.traittemplate.set_trait(trait)
        self.traitdebconf.set_trait(trait)
        self.traitscripts.set_trait(trait)
        self._current_trait_ = trait
        self.log.info("trait set to %s" % self._current_trait_)

    def run(self, name, command, args="", proc=False, chroot=True, keeprunning=False):
        tname = "trait-%s-%s" % (self._current_trait_, name)
        Installer.run(self, tname, command, args=args, proc=proc, chroot=chroot, keeprunning=keeprunning)

    def runscript(self, script, name, info, chroot=False):
        self.log.info(info["start"])
        self.run(name, script, chroot=chroot)
        os.remove(script)
        self.log.info(info["done"])

    def process(self):
        self.log.info("processing %s" % self._current_trait_)
        os.environ["PAELLA_TARGET"] = self.target
        os.environ["PAELLA_TRAIT"] = self._current_trait_
        packages = self.traitpackage.packages()
        templates = self.traittemplate.templates()

        # start pre script
        script = self._make_script("pre")
        if script is not None:
            info = dict(start="pre script started", done="pre script done")
            self.runscript(script, "pre-script", info)

        # remove packages
        script = self._make_script("remove")
        if script is None:
            remove = [p for p in packages if p.action == "remove"]
            if len(remove):
                self.remove(remove)
        else:
            info = dict(start="remove script started", done="remove script done")
            self.runscript(script, "remove-script", info)

        # install packages
        script = self._make_script("install")
        if script is None:
            install = [p for p in packages if p.action == "install"]
            if len(install):
                self.install(install, templates)
        else:
            info = dict(start="install script started", done="install script done")
            self.runscript(script, "install-script", info)

        # configure packages
        script = self._make_script("config")
        if script is None:
            config = [p for p in packages if p.action in ["install", "config"]]
            if len(config):
                self.configure(config, templates)
        else:
            info = dict(start="config script started", done="config script done")
            self.runscript(script, "config-script", info)

        # reconfigure debconf
        script = self._make_script("reconfig")
        if script is None:
            self.reconfigure_debconf()
        else:
            info = dict(start="reconfig script started", done="reconfig script done")
            self.runscript(script, "reconfig-script", info)

        # start post script
        script = self._make_script("post")
        if script is not None:
            info = dict(start="post script started", done="post script done")
            self.runscript(script, "post-script", info)

    def remove(self, packages):
        packages = " ".join([p.package for p in packages])
        command, args = "apt-get -y remove", packages
        self.run("remove", command, args=args, proc=True)

    def install(self, packages, templates):
        package_args = " ".join([p.package for p in packages])
        cmd = "apt-get -y --force-yes install %s\n" % package_args
        cmd += "rm /var/cache/apt/archives/*.deb -f"
        # os.system(self.with_proc(cmd))
        run = self.run("install", cmd, proc=True, keeprunning=True)
        if run:
            self.log.warn("PROBLEM installing %s" % self._current_trait_)
            self.log.warn("packages --> %s" % package_args)

    def configure(self, packages, templates):
        dpkg_rec = False
        for p in packages:
            for t in [t for t in templates if t.package == p.package]:
                if t.template == "var/cache/debconf/config.dat":
                    dpkg_rec = True
                    self.log.info("Installing Debconf template ...")
                    self.install_debconf_template(t)
                else:
                    self.make_template(t)
        if dpkg_rec:
            self.log.info("Reconfiguring packages")
            for p in packages:
                cmd = "dpkg-reconfigure -plow %s" % p.package
                run = self.run("dpkg-recfg", cmd, proc=True, keeprunning=True)
                if run:
                    self.log.info("reconfigure failed on %s" % p.package)
                else:
                    self.log.info("%s reconfigured" % p.package)
        script = self._make_script("chroot", execpath=True)
        if script is not None:
            # os.system(self.command(script))
            self.run("chroot-script", script)
            if script[0] == "/":
                script = script[1:]
            os.remove(join(self.target, script))

    def _make_script(self, name, execpath=False):
        script = self.traitscripts.get(name)
        if script is not None:
            exec_path = join("/tmp", name + "-script")
            target_path = join(self.target, "tmp", name + "-script")
            sfile = file(target_path, "w")
            sfile.write(script.read())
            sfile.close()
            os.system("chmod 755 %s" % target_path)
            if not execpath:
                return target_path
            else:
                return exec_path
        else:
            return None

    def make_template(self, template):
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(self.familydata)
        self.traittemplate.template.update(self.profiledata)
        self._make_template_common(template, tmpl)

    def make_template_with_data(self, template, data):
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(data)
        self._make_template_common(template, tmpl)

    def _make_template_common(self, template, tmpl):
        sub = self.traittemplate.template.sub()
        newpath = join(self.target, template.template)
        self.log.info("target template %s" % newpath)
        dir = dirname(newpath)
        if not isdir(dir):
            makepaths(dir)
        if tmpl != sub:
            self.log.info("%s %s subbed" % (template.package, template.template))
        newfile = file(newpath, "w")
        newfile.write(sub)
        newfile.close()
        mode = template.mode
        if mode[0] == "0" and len(mode) <= 7 and mode.isdigit():
            mode = eval(mode)
        os.chmod(newpath, mode)
        own = ":".join([template.owner, template.grp_owner])
        os.system(self.command("chown", "%s %s" % (own, join("/", template.template))))

    def install_debconf_template(self, template):
        self.log.info("Installing debconf for %s" % self._current_trait_)
        self.traittemplate.set_template(template.package, template.template)
        tmpl = self.traittemplate.template.template
        self.traittemplate.template.update(self.profiledata)
        sub = self.traittemplate.template.sub()
        if tmpl == sub:
            self.log.info("static debconf, no substitutions")
            self.log.info("for trait %s " % self._current_trait_)
        config_path = join(self.target, "tmp/paella_debconf")
        if isfile(config_path):
            raise Error, "%s is not supposed to be there" % config_path
        debconf = file(config_path, "w")
        debconf.write(sub + "\n")
        debconf.close()
        target_path = join(self.target, "var/cache/debconf/config.dat")
        self.log.info("debconf config is %s %s" % (config_path, target_path))
        copy_configdb(config_path, target_path)
        os.remove(config_path)

    def set_template_path(self, path):
        self.traittemplate.template.set_path(path)

    def install_debconf(self):
        config = self.traitdebconf.get_config()
        config_path = join(self.target, "tmp/paella_debconf")
        if isfile(config_path):
            raise Error, "%s is not supposed to be there" % config_path
        debconf = file(config_path, "w")
        debconf.write(config + "\n")
        debconf.close()
        target_path = join(self.target, "var/cache/debconf/config.dat")
        self.log.info("debconf config is %s %s" % (config_path, target_path))
        cmd = install_debconf(config_path, target_path)
        command = 'sh -c "%s"' % cmd
        self.log.info(cmd)
        os.system(cmd)
        os.remove(config_path)

    def reconfigure_debconf(self):
        owners = self.traitdebconf.all_owners()
        self.log.info("ALL OWNERS %s" % owners)
        os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        for owner in owners:
            self.log.info("RECONFIGURING %s" % owner)
            os.system(self.command("dpkg-reconfigure -plow %s" % owner))