Exemplo n.º 1
0
 def __init__(self):
     object.__init__(self)
     self.cfg = PaellaConfig()
     self.conn = InstallerConnection()
     self.profile = os.environ['PAELLA_PROFILE']
     self.target = os.environ['PAELLA_TARGET']
     self.machine = None
     self.trait = None
     self.suite = get_suite(self.conn, self.profile)
     self.pr = Profile(self.conn)
     self.pr.set_profile(self.profile)
     self.traitlist = self.pr.make_traitlist()
     self.pe = ProfileEnvironment(self.conn, self.profile)
     self.tp = TraitParent(self.conn, self.suite)
     self.fm = Family(self.conn)
     self.tr = Trait(self.conn, self.suite)
     self.families = list(
         self.fm.get_related_families(self.pr.get_families()))
     self._envv = None
     self.default = DefaultEnvironment(self.conn)
     #self.installer = TraitInstaller(self.conn, self.suite)
     self.installer = ProfileInstaller(self.conn)
     self.installer.set_logfile()
     self.installer.set_profile(self.profile)
     self.installer.set_target(self.target)
     if os.environ.has_key('PAELLA_MACHINE'):
         self.machine = os.environ['PAELLA_MACHINE']
     if os.environ.has_key('PAELLA_TRAIT'):
         self.set_trait(os.environ['PAELLA_TRAIT'])
Exemplo n.º 2
0
 def set_profile(self, profile):
     self.profile = profile
     self._profile.set_profile(profile)
     os.environ['PAELLA_PROFILE'] = profile
     self.profiletrait.set_profile(profile)
     self.traits = self.profiletrait.trait_rows()
     self.env = ProfileEnvironment(self.conn, self.profile)
     self.familydata = self._profile.get_family_data()
     self.profiledata = self._profile.get_profile_data()
     self.suite = get_suite(self.conn, profile)
     self.installer = TraitInstaller(self.conn, self.suite, self.cfg)
     self.installer.log = self.log
     self.installer.familydata = self.familydata
     self.installer.profiledata = self.profiledata
     self.traitparent = TraitParent(self.conn, self.suite)
     self.log.info('profile set to %s' % profile)
Exemplo n.º 3
0
 def set_profile(self, profile):
     self.profile = profile
     self._profile.set_profile(profile)
     os.environ['PAELLA_PROFILE'] = profile
     self.profiletrait.set_profile(profile)
     self.traits = self.profiletrait.trait_rows()
     self.env = ProfileEnvironment(self.conn, self.profile)
     self.familydata = self._profile.get_family_data()
     self.profiledata = self._profile.get_profile_data()
     self.suite = get_suite(self.conn, profile)
     self.installer = TraitInstaller(self.conn, self.suite)
     self.installer.log = self.log
     self.installer.familydata = self.familydata
     self.installer.profiledata = self.profiledata
     self.installer.mtypedata = self.mtypedata
     self.traitparent = TraitParent(self.conn, self.suite)
     self.log.info('profile set to %s' % profile)
     traitlist = self.make_traitlist()
     self.setup_initial_paellainfo_env(traitlist)
Exemplo n.º 4
0
 def _init_attributes(self):
     self.traits = self.profiletrait.trait_rows()
     self.env = ProfileEnvironment(self.conn, self.profile)
     self.familydata = self._profile.get_family_data()
     self.profiledata = self._profile.get_profile_data()
     self.suite = get_suite(self.conn, self.profile)
Exemplo n.º 5
0
class ProfileInstaller(BaseInstaller):
    # here parent is the chroot installer
    # The target needs to be set in the parent before
    # this class is initialized.
    def __init__(self, parent):
        BaseInstaller.__init__(self, parent.conn)
        self._parent = parent
        self.target = parent.target
        # we need this paelladir attribute for now
        # but may replace/redo this later
        self.paelladir = self.target / 'root/paella'
        self.profile = None
        self.suite = None
        self.profiletrait = ProfileTrait(self.conn)
        self._profile = Profile(self.conn)
        if hasattr(parent, 'mainlog'):
            self.mainlog = parent.mainlog
            name = self.__class__.__name__
            self.mainlog.add_logger(name)
            self.log = self.mainlog.loggers[name]

        # make empty data dicts
        self.machine_data = {}
        self.familydata = {}
        self.profiledata = {}

    # this method is called within set_profile
    def _init_attributes(self):
        self.traits = self.profiletrait.trait_rows()
        self.env = ProfileEnvironment(self.conn, self.profile)
        self.familydata = self._profile.get_family_data()
        self.profiledata = self._profile.get_profile_data()
        self.suite = get_suite(self.conn, self.profile)

    # this method is called within set_profile
    # here is where the trait installer is setup
    # the data attributes need to be filled before this is called
    # this method needs to be fixed to use the new trait installer
    def _setup_installer(self, suite):
        self.installer = TraitInstaller(self)
        self.installer.familydata = self.familydata
        self.installer.profiledata = self.profiledata
        self.installer.machine_data = self.machine_data

    # here is where the processes are setup
    # every process is a trait and it maps to the same
    # function.  a "current_index" attribute keeps track
    # of which trait is being processed.
    def _setup_trait_processes(self, traitlist):
        self.setup_initial_paellainfo_env(traitlist)
        self._processes = traitlist
        self._process_map = {}.fromkeys(traitlist, self.process_trait)

    # setting the profile involves a lot of work
    # there are helper methods defined to help split
    # the code up into more manageable pieces.
    def set_profile(self, profile):
        self.profile = profile
        self._profile.set_profile(profile)
        os.environ['PAELLA_PROFILE'] = profile
        self.profiletrait.set_profile(profile)
        self._init_attributes()
        self._setup_installer(self.suite)
        self.traitparent = TraitParent(self.conn, self.suite)
        self.log.info('profile set to %s' % profile)
        traitlist = self.make_traitlist()
        self._setup_trait_processes(traitlist)

    # currently there is no script functionality
    # but there may be in the future.
    def make_script(self, procname):
        return None

    # this method needs to be checked
    def make_traitlist(self):
        listed = [x.trait for x in self.profiletrait.trait_rows()]
        log = None
        return self._profile.make_traitlist_with_traits(listed, log=log)

    def get_profile_data(self):
        return self.env.ProfileData()

    # this method needs to be checked
    # self.paelladir needs to be defined
    def setup_initial_paellainfo_files(self, traits):
        makepaths(self.paelladir)
        traitlist = file(join(self.paelladir, 'traitlist'), 'w')
        for trait in traits:
            traitlist.write('%s\n' % trait)
        traitlist.close()
        itraits = file(join(self.paelladir, 'installed_traits'), 'w')
        itraits.write('Installed Traits:\n')
        itraits.close()

    # initialize data in current_environment,
    # if PAELLA_MACHINE is set
    def setup_initial_paellainfo_env(self, traits):
        if os.environ.has_key('PAELLA_MACHINE'):
            machine = os.environ['PAELLA_MACHINE']
            curenv = CurrentEnvironment(self.conn, machine)
            curenv['current_profile'] = self.profile
            curenv['traitlist'] = ', '.join(traits)
            curenv['installed_traits'] = ''

    # this method has been rewritten to use
    # self.current_index
    # the UnbornError should never be raised
    def process_trait(self):
        trait = self._processes[self.current_index]
        self.traitparent.set_trait(trait)
        self.installer.set_trait(trait)
        parents = [r.parent for r in self.traitparent.parents()]
        for p in parents:
            if p not in self.processed:
                raise UnbornError
        self.log.info('processing trait %s' % trait)
        self.installer.run_all_processes()
        self.processed.append(trait)
        self.current_index += 1
        self.log.info('processed:  %s' % ', '.join(self.processed))
        self.append_installed_traits(trait)

    # this used to be called process
    def run_all_processes(self):
        traits = self.make_traitlist()
        self.setup_initial_paellainfo_files(traits)
        self.setup_initial_paellainfo_env(traits)
        self.processed = []
        self.current_index = 0
        BaseInstaller.run_all_processes(self)
        self.log.info('all traits processed for profile %s' % self.profile)
        self.log.info('------------------------------------')

    # this method needs to be checked
    def set_template_path(self, tpath):
        self.installer.set_template_path(tpath)

    # this method needs to be checked
    # target should be set upon init.
    # need to remove apt-get update command
    def set_target(self, target, update=False):
        Installer.set_target(self, target)
        self.installer.set_target(target)
        if update:
            os.system(self.command('apt-get update'))

    # this method needs to be checked
    # this method doesn't belong in the profile installer
    # this is a machine installer method
    def install_kernel(self, package):
        os.system(self.command('touch /boot/vmlinuz-fake'))
        os.system(self.command('ln -s boot/vmlinuz-fake vmlinuz'))
        os.system(self.command('apt-get -y install %s' % package))
        print 'kernel %s installed' % package

    # This helps reporting when when a trait is processed
    def append_installed_traits(self, trait):
        self._append_installed_traits_file(trait)
        self._append_installed_traits_db(trait)

    # this method needs to be checked
    # self.paelladir needs to be defined
    def _append_installed_traits_file(self, trait):
        itraits = file(join(self.paelladir, 'installed_traits'), 'a')
        itraits.write(trait + '\n')
        itraits.close()

    # this method needs to be checked
    def _append_installed_traits_db(self, trait):
        if os.environ.has_key('PAELLA_MACHINE'):
            machine = os.environ['PAELLA_MACHINE']
            curenv = CurrentEnvironment(self.conn, machine)
            line = curenv['installed_traits']
            traits = [t.strip() for t in line.split(',')]
            traits.append(trait)
            curenv['installed_traits'] = ', '.join(traits)
Exemplo n.º 6
0
 def select_profile(self, profile):
     self.variables = ProfileEnvironment(self.conn, profile)
     self.profiletrait.set_profile(profile)
     self.__set_pages(profile)
Exemplo n.º 7
0
class ProfileBrowser(ListNoteBook, HasDialogs):
    def __init__(self, conn, suites, name='ProfileBrowser'):
        self.menu = self.__make_mainmenu_(suites)
        ListNoteBook.__init__(self, name=name)
        self.conn = conn
        self.profiles = Profile(self.conn)
        self.profiletrait = ProfileTrait(self.conn)
        self.family = Family(self.conn)
        self.pfamily = StatementCursor(self.conn)
        self.pfamily.set_table('profile_family')
        self.trait_menu = make_menu(['drop', 'order'], self.trait_command)
        self.pdata_menu = make_menu(['edit', 'drop'], self.variable_command)
        self.family_menu = make_menu(['drop'], self.family_command)
        self.reset_rows()
        self.append_page(ScrollCList(rcmenu=self.trait_menu), 'traits')
        self.append_page(ScrollCList(rcmenu=self.pdata_menu), 'variables')
        self.append_page(ScrollCList(rcmenu=self.family_menu), 'families')
        self.dialogs = {}.fromkeys(['order'])

    def __make_mainmenu_(self, suites):
        suite_commands = ['change to %s' % suite for suite in suites]
        profile_commands = ['drop', 'set defaults', 'append defaults']
        commands = suite_commands + profile_commands
        return make_menu(commands, self.profile_command)

    def reset_rows(self):
        self.set_rows(
            self.profiles.select(fields=['profile', 'suite'], order='profile'))
        self.set_row_select(self.profile_selected)

    def profile_selected(self, listbox, row, column, event):
        row = listbox.get_selected_data()[0]
        self.current = row
        self.select_profile(self.current.profile)

    def select_profile(self, profile):
        self.variables = ProfileEnvironment(self.conn, profile)
        self.profiletrait.set_profile(profile)
        self.__set_pages(profile)

    def __set_pages(self, profile):
        pages = dict(self.pages)
        #set traits for profile
        pages['traits'].set_rows(self.profiletrait.trait_rows())
        pages['traits'].set_select_mode('multi')
        clause = Eq('profile', self.current.profile)
        cursor = self.variables.env.cursor
        pages['variables'].set_rows(cursor.select(clause=clause), ['trait'])
        pages['variables'].set_select_mode('multi')
        pfrows = self.pfamily.select(fields=['family'], clause=clause)
        pages['families'].set_rows(pfrows)
        pages['families'].set_select_mode('multi')
        self.__set_droptargets__(pages)

    def __set_droptargets__(self, pages):
        set_receive_targets(pages['traits'].listbox, self.drop_trait,
                            TARGETS.get('trait', self.current.suite))
        set_receive_targets(pages['families'].listbox, self.drop_families,
                            FTargets.get('family', 'flavor'))

    def trait_command(self, menuitem, action):
        traits = self._get_listbox('traits', 'trait')
        if action == 'drop':
            clause = In('trait', traits) & Eq('profile', self.current.profile)
            self.profiletrait.cmd.delete(clause=clause)
            self.__set_pages(self.current.profile)
        elif action == 'order':
            if not self.dialogs['order']:
                self.dialogs['order'] = dialogs.Entry('enter order',
                                                      name='order')
                self.dialogs['order'].set_ok(self.set_order)
                self.dialogs['order'].set_cancel(self.destroy_dialog)

    def variable_command(self, menuitem, action):
        rows = self.pages['variables'].get_selected_data()
        cursor = self.variables.env.cursor
        if action == 'drop':
            for row in rows:
                clause = Eq('profile', self.current.profile) & Eq(
                    'trait', row.trait)
                clause &= Eq('name', row.name)
                cursor.delete(clause=clause)
        elif action == 'edit':
            self.edit_profilevars()

    def family_command(self, menuitem, action):
        print action
        families = [x[0] for x in self.pages['families'].get_selected_data()]
        if action == 'drop':
            clause = Eq('profile', self.current.profile) & In(
                'family', families)
            self.pfamily.delete(clause=clause)

    def edit_profilevars(self):
        config = ProfileVariablesConfig(self.conn, self.current.profile)
        newconfig = config.edit()
        config.update(newconfig)
        self.select_profile(self.current.profile)

    def set_order(self, button):
        dialog = self.dialogs['order']
        ord = dialog.get()
        rows = self.pages['traits'].get_selected_data()
        pclause = Eq('profile', self.current.profile)
        for row in rows:
            clause = pclause & Eq('trait', row.trait)
            self.profiletrait.update(data=dict(ord=ord), clause=clause)

    def drop_trait(self, listbox, context, x, y, selection, targettype, time):
        traits = keysplitter(selection)
        self.profiletrait.insert_traits(traits)
        self.__set_pages(self.current.profile)

    def drop_families(self, listbox, context, x, y, selection, targettype,
                      time):
        families = keysplitter(selection)
        clause = Eq('profile', self.current.profile)
        data = dict(profile=self.current.profile)
        current = [x.family for x in self.pfamily.select(clause=clause)]
        for f in families:
            if f not in current:
                data['family'] = f
                self.pfamily.insert(data=data)
        self.__set_pages(self.current.profile)

    def _get_listbox(self, page, field):
        pages = dict(self.pages)
        return [row[field] for row in pages[page].listbox.get_selected_data()]

    def profile_command(self, menu, command):
        if command[:10] == 'change to ':
            self.change_suite(command[10:])
        elif command == 'drop':
            self.profiletrait.drop_profile(self.current.profile)
            self.profiles.drop_profile(self.current.profile)
            self.current = None
            self.reset_rows()
        elif command == 'set defaults':
            self.variables.set_defaults()
        elif command == 'append defaults':
            self.variables.append_defaults()
        else:
            raise Error, 'bad command %s' % command

    def change_suite(self, suite):
        clause = Eq('profile', self.current.profile)
        self.profiles.update(data={'suite': suite}, clause=clause)
        print 'changing suite to ', suite
        self.current_suite = suite
        self.reset_rows()
Exemplo n.º 8
0
 def select_profile(self, profile):
     self.variables = ProfileEnvironment(self.conn, profile)
     self.profiletrait.set_profile(profile)
     self.__set_pages(profile)
Exemplo n.º 9
0
class ProfileBrowser(ListNoteBook, HasDialogs):
    def __init__(self, conn, suites, name='ProfileBrowser'):
        self.menu = self.__make_mainmenu_(suites)
        ListNoteBook.__init__(self, name=name)
        self.conn = conn
        self.profiles = Profile(self.conn)
        self.profiletrait = ProfileTrait(self.conn)
        self.family = Family(self.conn)
        self.pfamily = StatementCursor(self.conn)
        self.pfamily.set_table('profile_family')
        self.trait_menu = make_menu(['drop', 'order'], self.trait_command)
        self.pdata_menu = make_menu(['edit', 'drop'], self.variable_command)
        self.family_menu = make_menu(['drop'], self.family_command)
        self.reset_rows()
        self.append_page(ScrollCList(rcmenu=self.trait_menu), 'traits')
        self.append_page(ScrollCList(rcmenu=self.pdata_menu), 'variables')
        self.append_page(ScrollCList(rcmenu=self.family_menu), 'families')
        self.dialogs = {}.fromkeys(['order'])
        
    def __make_mainmenu_(self, suites):
        suite_commands = ['change to %s' %suite for suite in suites]
        profile_commands = ['drop', 'set defaults', 'append defaults']
        commands = suite_commands + profile_commands
        return make_menu(commands, self.profile_command)

    def reset_rows(self):
        self.set_rows(self.profiles.select(fields=['profile', 'suite'], order='profile'))
        self.set_row_select(self.profile_selected)

    def profile_selected(self, listbox, row, column, event):
        row = listbox.get_selected_data()[0]
        self.current = row
        self.select_profile(self.current.profile)

    def select_profile(self, profile):
        self.variables = ProfileEnvironment(self.conn, profile)
        self.profiletrait.set_profile(profile)
        self.__set_pages(profile)

    def __set_pages(self, profile):
        pages = dict(self.pages)
        #set traits for profile
        pages['traits'].set_rows(self.profiletrait.trait_rows())
        pages['traits'].set_select_mode('multi')
        clause = Eq('profile', self.current.profile)
        cursor = self.variables.env.cursor
        pages['variables'].set_rows(cursor.select(clause=clause), ['trait'])
        pages['variables'].set_select_mode('multi')
        pfrows = self.pfamily.select(fields=['family'], clause=clause)
        pages['families'].set_rows(pfrows)
        pages['families'].set_select_mode('multi')
        self.__set_droptargets__(pages)
        
        
    def __set_droptargets__(self, pages):
        set_receive_targets(pages['traits'].listbox,
                            self.drop_trait, TARGETS.get('trait', self.current.suite))
        set_receive_targets(pages['families'].listbox,
                            self.drop_families, FTargets.get('family', 'flavor'))
        

    def trait_command(self, menuitem, action):
        traits = self._get_listbox('traits', 'trait')
        if action == 'drop':
            clause = In('trait', traits) & Eq('profile', self.current.profile)
            self.profiletrait.cmd.delete(clause=clause)
            self.__set_pages(self.current.profile)
        elif action == 'order':
            if not self.dialogs['order']:
                self.dialogs['order'] = dialogs.Entry('enter order', name='order')
                self.dialogs['order'].set_ok(self.set_order)
                self.dialogs['order'].set_cancel(self.destroy_dialog)


    def variable_command(self, menuitem, action):
        rows = self.pages['variables'].get_selected_data()
        cursor = self.variables.env.cursor
        if action == 'drop':
            for row in rows:
                clause = Eq('profile', self.current.profile) & Eq('trait', row.trait)
                clause &= Eq('name', row.name)
                cursor.delete(clause=clause)
        elif action == 'edit':
            self.edit_profilevars()

    def family_command(self, menuitem, action):
        print action
        families = [x[0] for x in self.pages['families'].get_selected_data()]
        if action == 'drop':
            clause = Eq('profile', self.current.profile) & In('family', families)
            self.pfamily.delete(clause=clause)

        
    def edit_profilevars(self):
        config = ProfileVariablesConfig(self.conn, self.current.profile)
        newconfig = config.edit()
        config.update(newconfig)
        self.select_profile(self.current.profile)
                            
    def set_order(self, button):
        dialog = self.dialogs['order']
        ord = dialog.get()
        rows = self.pages['traits'].get_selected_data()
        pclause = Eq('profile', self.current.profile)
        for row in rows:
            clause = pclause & Eq('trait', row.trait)
            self.profiletrait.update(data=dict(ord=ord), clause=clause)
        
    def drop_trait(self, listbox, context, x, y, selection,
                   targettype, time):
        traits = keysplitter(selection)
        self.profiletrait.insert_traits(traits)
        self.__set_pages(self.current.profile)

    def drop_families(self, listbox, context, x, y, selection,
                    targettype, time):
        families = keysplitter(selection)
        clause = Eq('profile', self.current.profile)
        data = dict(profile=self.current.profile)
        current = [x.family for x in self.pfamily.select(clause=clause)]
        for f in families:
            if f not in current:
                data['family'] = f
                self.pfamily.insert(data=data)
        self.__set_pages(self.current.profile)
            

    def _get_listbox(self, page, field):
        pages = dict(self.pages)
        return [row[field] for row in pages[page].listbox.get_selected_data()]

    def profile_command(self, menu, command):
        if command[:10] == 'change to ':
            self.change_suite(command[10:])
        elif command == 'drop':
            self.profiletrait.drop_profile(self.current.profile)
            self.profiles.drop_profile(self.current.profile)
            self.current = None
            self.reset_rows()
        elif command == 'set defaults':
            self.variables.set_defaults()
        elif command == 'append defaults':
            self.variables.append_defaults()
        else:
            raise Error, 'bad command %s' %command
            
    def change_suite(self, suite):
        clause = Eq('profile', self.current.profile)
        self.profiles.update(data={'suite' : suite}, clause=clause)        
        print 'changing suite to ', suite
        self.current_suite = suite
        self.reset_rows()
Exemplo n.º 10
0
class ProfileInstaller(Installer):
    def __init__(self, conn):
        os.environ['DEBIAN_FRONTEND'] = 'noninteractive'
        Installer.__init__(self, conn)
        self.profiletrait = ProfileTrait(self.conn)
        self.profile = None
        self.installer = None
        self._profile = Profile(self.conn)
        if hasattr(self, 'log'):
            self.log.info('profile installer initialized')
        self.mtypedata = {}

    def set_profile(self, profile):
        self.profile = profile
        self._profile.set_profile(profile)
        os.environ['PAELLA_PROFILE'] = profile
        self.profiletrait.set_profile(profile)
        self.traits = self.profiletrait.trait_rows()
        self.env = ProfileEnvironment(self.conn, self.profile)
        self.familydata = self._profile.get_family_data()
        self.profiledata = self._profile.get_profile_data()
        self.suite = get_suite(self.conn, profile)
        self.installer = TraitInstaller(self.conn, self.suite)
        self.installer.log = self.log
        self.installer.familydata = self.familydata
        self.installer.profiledata = self.profiledata
        self.installer.mtypedata = self.mtypedata
        self.traitparent = TraitParent(self.conn, self.suite)
        self.log.info('profile set to %s' % profile)

    def get_profile_data(self):
        return self.env.ProfileData()

    def set_logpath(self, logpath):
        Installer.set_logpath(self, logpath)
        if hasattr(self, 'installer'):
            self.installer.set_logpath(logpath)

    def make_traitlist(self):
        tp = TraitParent(self.conn, self.suite)
        listed = [x.trait for x in self.profiletrait.trait_rows()]
        all = list(self.traitparent.get_traitset(listed))
        setfun = tp.set_trait
        parfun = tp.parents
        log = self.log
        return make_deplist(listed, all, setfun, parfun, log)

    def setup_initial_paellainfo_files(self, traits):
        makepaths(self.paelladir)
        traitlist = file(join(self.paelladir, 'traitlist'), 'w')
        for trait in traits:
            traitlist.write('%s\n' % trait)
        traitlist.close()
        itraits = file(join(self.paelladir, 'installed_traits'), 'w')
        itraits.write('Installed Traits:\n')
        itraits.close()

    def setup_initial_paellainfo_env(self, traits):
        if os.environ.has_key('PAELLA_MACHINE'):
            machine = os.environ['PAELLA_MACHINE']
            curenv = CurrentEnvironment(self.conn, machine)
            curenv['current_profile'] = self.profile
            curenv['traitlist'] = ', '.join(traits)
            curenv['installed_traits'] = ''

    def process(self):
        traits = self.make_traitlist()
        self.setup_initial_paellainfo_files(traits)
        self.setup_initial_paellainfo_env(traits)
        self.processed = []
        for trait in traits:
            self.process_trait(trait)
            self.log.info('currently processed %s' % ','.join(self.processed))
        self.log.info('all traits processed for profile %s' % self.profile)
        self.log.info('------------------------------------')

    def _append_installed_traits_file(self, trait):
        itraits = file(join(self.paelladir, 'installed_traits'), 'a')
        itraits.write(trait + '\n')
        itraits.close()

    def _append_installed_traits_db(self, trait):
        if os.environ.has_key('PAELLA_MACHINE'):
            machine = os.environ['PAELLA_MACHINE']
            curenv = CurrentEnvironment(self.conn, machine)
            line = curenv['installed_traits']
            traits = [t.strip() for t in line.split(',')]
            traits.append(trait)
            curenv['installed_traits'] = ', '.join(traits)

    def process_trait(self, trait):
        self.traitparent.set_trait(trait)
        self.installer.set_trait(trait)
        parents = [r.parent for r in self.traitparent.parents()]
        for p in parents:
            if p not in self.processed:
                raise UnbornError
        self.log.info('processing trait %s' % trait)
        self.installer.process()
        self.processed.append(trait)
        self.log.info('processed:  %s' % ', '.join(self.processed))
        self.append_installed_traits(trait)

    def set_template_path(self, path):
        self.installer.set_template_path(path)

    def set_target(self, target, update=False):
        Installer.set_target(self, target)
        self.installer.set_target(target)
        if update:
            os.system(self.command('apt-get update'))

    def install_kernel(self, package):
        os.system(self.command('touch /boot/vmlinuz-fake'))
        os.system(self.command('ln -s boot/vmlinuz-fake vmlinuz'))
        os.system(self.command('apt-get -y install %s' % package))
        print 'kernel %s installed' % package

    def append_installed_traits(self, trait):
        self._append_installed_traits_file(trait)
        self._append_installed_traits_db(trait)