コード例 #1
0
ファイル: system.py プロジェクト: CyberReboot/vent
 def start(self):
     status = (True, None)
     # startup based on startup file
     if exists(self.startup_file):
         status = self._startup()
     else:
         tools = Tools()
         status = tools.new('core', None)
         if status[0]:
             status = tools.start(
                 'https://github.com/cyberreboot/vent', None)
     return status
コード例 #2
0
ファイル: choose_tools.py プロジェクト: swipswaps/vent
 def repo_tools(self, branch):
     """ Set the appropriate repo dir and get the tools available of it """
     tools = []
     m_helper = Tools()
     repo = self.parentApp.repo_value['repo']
     version = self.parentApp.repo_value['versions'][branch]
     status = m_helper.repo_tools(repo, branch, version)
     if status[0]:
         r_tools = status[1]
         for tool in r_tools:
             tools.append(tool[0])
     return tools
コード例 #3
0
ファイル: choose_tools.py プロジェクト: CyberReboot/vent
 def repo_tools(self, branch):
     """ Set the appropriate repo dir and get the tools available of it """
     tools = []
     m_helper = Tools()
     repo = self.parentApp.repo_value['repo']
     version = self.parentApp.repo_value['versions'][branch]
     status = m_helper.repo_tools(repo, branch, version)
     if status[0]:
         r_tools = status[1]
         for tool in r_tools:
             tools.append(tool[0])
     return tools
コード例 #4
0
ファイル: inventory_forms.py プロジェクト: swipswaps/vent
 def __init__(self, action_dict=None, action_name=None, *args, **keywords):
     api_action = Tools()
     action = {'api_action': api_action}
     if action_dict:
         action.update(action_dict)
     logger = Logger(action_name)
     InventoryForm.__init__(self, action, logger, *args, **keywords)
コード例 #5
0
ファイル: system.py プロジェクト: swipswaps/vent
    def start(self):
        status = (True, None)
        vent_bridge = None

        # create vent network bridge if it doesn't already exist
        try:
            vent_bridge = self.d_client.networks.create(
                'vent', check_duplicate=True, driver='bridge')
        except docker.errors.APIError as e:  # pragma: no cover
            if str(e) != '409 Client Error: Conflict ("network with name vent already exists")':
                self.logger.error(
                    'Unable to create network bridge because: {0}'.format(str(e)))
                status = (False, str(e))
            else:
                vent_bridge = self.d_client.networks.list('vent')[0]

        if status[0]:
            # add vent to the vent network bridge
            try:
                vent_bridge.connect(environ['HOSTNAME'])
            except Exception as e:  # pragma: no coverr
                self.logger.error(
                    'Unable to connect vent to the network bridge because: {0}'.format(str(e)))
                status = (False, str(e))

        if status[0]:
            # remove vent to the default network bridge
            try:
                default_bridge = self.d_client.networks.list('bridge')[0]
                default_bridge.disconnect(environ['HOSTNAME'])
            except Exception as e:  # pragma: no coverr
                self.logger.error(
                    'Unable to disconnect vent from the default network bridge because: {0}'.format(str(e)))
                status = (False, str(e))

        if status[0]:
            # startup based on startup file
            if exists(self.startup_file):
                status = self._startup()
            else:
                tools = Tools()
                status = tools.new('core', None)
                if status[0]:
                    status = tools.start(
                        'https://github.com/cyberreboot/vent', None)
        return status
コード例 #6
0
ファイル: choose_tools.py プロジェクト: swipswaps/vent
    def on_ok(self):
        """
        Take the tool selections and add them as plugins
        """
        def diff(first, second):
            """
            Get the elements that exist in the first list and not in the second
            """
            second = set(second)
            return [item for item in first if item not in second]

        def popup(original_tools, branch, thr, title):
            """
            Start the thread and display a popup of the tools being added until
            the thread is finished
            """
            thr.start()
            tool_str = 'Adding tools...'
            npyscreen.notify_wait(tool_str, title=title)
            while thr.is_alive():
                tools = diff(ManifestTools(), original_tools)
                if tools:
                    tool_str = ''
                for tool in tools:
                    pre_tool = 'Added: ' + branch + '/' + tool + '\n'
                    tool_str = pre_tool + tool_str
                npyscreen.notify_wait(tool_str, title=title)
                time.sleep(1)
            return

        original_tools = ManifestTools()
        for branch in self.tools_tc:
            tools = []
            for tool in self.tools_tc[branch]:
                if self.tools_tc[branch][tool].value:
                    # get rid of temporary show for multiple tools in same
                    # directory
                    if tool == '/':
                        tools.append(('.', ''))
                    else:
                        tools.append((tool, ''))
            repo = self.parentApp.repo_value['repo']
            version = self.parentApp.repo_value['versions'][branch]
            api_action = Tools(version=version, branch=branch)
            thr = threading.Thread(target=api_action.new,
                                   args=(),
                                   kwargs={
                                       'tool_type': 'repo',
                                       'uri': repo,
                                       'tools': tools
                                   })
            popup(original_tools, branch, thr,
                  'Please wait, adding tools for the ' + branch + ' branch...')
        npyscreen.notify_confirm('Done adding repository: ' +
                                 self.parentApp.repo_value['repo'],
                                 title='Added Repository')
        self.quit()
コード例 #7
0
ファイル: tools.py プロジェクト: swipswaps/vent
 def __init__(self, *args, **keywords):
     """ Initialize tool form objects """
     self.logger = Logger(__name__)
     self.api_action = System()
     self.tools_inst = Tools()
     action = {'api_action': self.tools_inst}
     self.tools_tc = {}
     self.repo_widgets = {}
     if keywords['action_dict']:
         action.update(keywords['action_dict'])
     if keywords['names']:
         i = 1
         for name in keywords['names']:
             try:
                 action['action_object' + str(i)] = getattr(
                     self.tools_inst, name)
             except AttributeError:
                 action['action_object' + str(i)] = getattr(
                     self.api_action, name)
             i += 1
     self.action = action
     # get list of all possible group views to display
     self.views = deque()
     possible_groups = set()
     manifest = Template(self.api_action.manifest)
     tools = self.tools_inst.inventory(choices=['tools'])[1]['tools']
     for tool in tools:
         groups = manifest.option(tool, 'groups')[1].split(',')
         for group in groups:
             # don't do core because that's the purpose of all in views
             if group != '' and group != 'core':
                 possible_groups.add(group)
     self.manifest = manifest
     self.views += possible_groups
     self.views.append('all groups')
     self.no_instance = ['remove']
     super(ToolForm, self).__init__(*args, **keywords)
コード例 #8
0
ファイル: add_options.py プロジェクト: CyberReboot/vent
 def repo_values(self):
     """
     Set the appropriate repo dir and get the branches and commits of it
     """
     branches = []
     commits = {}
     m_helper = Tools()
     status = m_helper.repo_branches(self.parentApp.repo_value['repo'])
     # branches and commits must both be retrieved successfully
     if status[0]:
         branches = status[1]
         status = m_helper.repo_commits(self.parentApp.repo_value['repo'])
         if status[0]:
             r_commits = status[1]
             for commit in r_commits:
                 commits[commit[0]] = commit[1]
         else:
             # if commits failed, return commit errors
             return status
     else:
         # if branch failed, return branch errors
         return status
     # if everything is good, return branches with commits
     return branches, commits
コード例 #9
0
 def repo_values(self):
     """
     Set the appropriate repo dir and get the branches and commits of it
     """
     branches = []
     commits = {}
     m_helper = Tools()
     status = m_helper.repo_branches(self.parentApp.repo_value['repo'])
     # branches and commits must both be retrieved successfully
     if status[0]:
         branches = status[1]
         status = m_helper.repo_commits(self.parentApp.repo_value['repo'])
         if status[0]:
             r_commits = status[1]
             for commit in r_commits:
                 commits[commit[0]] = commit[1]
         else:
             # if commits failed, return commit errors
             return status
     else:
         # if branch failed, return branch errors
         return status
     # if everything is good, return branches with commits
     return branches, commits
コード例 #10
0
ファイル: tools.py プロジェクト: CyberReboot/vent
 def __init__(self, *args, **keywords):
     """ Initialize tool form objects """
     self.logger = Logger(__name__)
     self.api_action = System()
     self.tools_inst = Tools()
     action = {'api_action': self.tools_inst}
     self.tools_tc = {}
     self.repo_widgets = {}
     if keywords['action_dict']:
         action.update(keywords['action_dict'])
     if keywords['names']:
         i = 1
         for name in keywords['names']:
             try:
                 action['action_object' +
                        str(i)] = getattr(self.tools_inst, name)
             except AttributeError:
                 action['action_object' +
                        str(i)] = getattr(self.api_action, name)
             i += 1
     self.action = action
     # get list of all possible group views to display
     self.views = deque()
     possible_groups = set()
     manifest = Template(self.api_action.manifest)
     tools = self.tools_inst.inventory(choices=['tools'])[1]['tools']
     for tool in tools:
         groups = manifest.option(tool, 'groups')[1].split(',')
         for group in groups:
             # don't do core because that's the purpose of all in views
             if group != '' and group != 'core':
                 possible_groups.add(group)
     self.manifest = manifest
     self.views += possible_groups
     self.views.append('all groups')
     self.no_instance = ['remove']
     super(ToolForm, self).__init__(*args, **keywords)
コード例 #11
0
ファイル: tools.py プロジェクト: CyberReboot/vent
class ToolForm(npyscreen.ActionForm):
    """ Tools form for the Vent CLI """

    def __init__(self, *args, **keywords):
        """ Initialize tool form objects """
        self.logger = Logger(__name__)
        self.api_action = System()
        self.tools_inst = Tools()
        action = {'api_action': self.tools_inst}
        self.tools_tc = {}
        self.repo_widgets = {}
        if keywords['action_dict']:
            action.update(keywords['action_dict'])
        if keywords['names']:
            i = 1
            for name in keywords['names']:
                try:
                    action['action_object' +
                           str(i)] = getattr(self.tools_inst, name)
                except AttributeError:
                    action['action_object' +
                           str(i)] = getattr(self.api_action, name)
                i += 1
        self.action = action
        # get list of all possible group views to display
        self.views = deque()
        possible_groups = set()
        manifest = Template(self.api_action.manifest)
        tools = self.tools_inst.inventory(choices=['tools'])[1]['tools']
        for tool in tools:
            groups = manifest.option(tool, 'groups')[1].split(',')
            for group in groups:
                # don't do core because that's the purpose of all in views
                if group != '' and group != 'core':
                    possible_groups.add(group)
        self.manifest = manifest
        self.views += possible_groups
        self.views.append('all groups')
        self.no_instance = ['remove']
        super(ToolForm, self).__init__(*args, **keywords)

    def quit(self, *args, **kwargs):
        """ Overridden to switch back to MAIN form """
        self.parentApp.switchForm('MAIN')

    def toggle_view(self, *args, **kwargs):
        """ Toggles the view between different groups """
        group_to_display = self.views.popleft()
        self.cur_view.value = group_to_display
        for repo in self.tools_tc:
            for tool in self.tools_tc[repo]:
                t_groups = self.manifest.option(tool, 'groups')[1]
                if group_to_display not in t_groups and \
                        group_to_display != 'all groups':
                    self.tools_tc[repo][tool].value = False
                    self.tools_tc[repo][tool].hidden = True
                else:
                    self.tools_tc[repo][tool].value = True
                    self.tools_tc[repo][tool].hidden = False
        # redraw elements
        self.display()
        # add view back to queue
        self.views.append(group_to_display)

    def create(self, group_view=False):
        """ Update with current tools """
        self.add_handlers({'^T': self.quit, '^Q': self.quit})
        self.add(npyscreen.TitleText,
                 name='Select which tools to ' + self.action['action'] + ':',
                 editable=False)
        togglable = ['remove']
        if self.action['action_name'] in togglable:
            self.cur_view = self.add(npyscreen.TitleText,
                                     name='Group view:',
                                     value='all groups', editable=False,
                                     rely=3)
            self.add_handlers({'^V': self.toggle_view})
            i = 5
        else:
            i = 4

        if self.action['action_name'] == 'start':
            response = self.tools_inst.inventory(choices=['repos',
                                                          'tools',
                                                          'built',
                                                          'running'])
        else:
            response = self.tools_inst.inventory(choices=['repos', 'tools'])
        if response[0]:
            inventory = response[1]

            repos = inventory['repos']

            # dict has repo as key and list of core/non-core tools as values
            has_core = {}
            has_non_core = {}

            # find all tools that are in this repo
            # and list them if they are core
            for repo in repos:
                core_list = []
                ncore_list = []

                # splice the repo names for processing
                if (repo.startswith('http')):
                    repo_name = repo.rsplit('/', 2)[1:]
                else:
                    repo_name = repo.split('/')

                for tool in inventory['tools']:
                    tool_repo_name = tool.split(':')

                    # cross reference repo names
                    if (repo_name[0] == tool_repo_name[0] and
                            repo_name[1] == tool_repo_name[1]):
                        # check to ensure tool not set to locally active = no
                        # in vent.cfg
                        externally_active = False
                        vent_cfg_file = self.api_action.vent_config
                        vent_cfg = Template(vent_cfg_file)
                        tool_pairs = vent_cfg.section('external-services')[1]
                        for ext_tool in tool_pairs:
                            if ext_tool[0].lower() == inventory['tools'][tool]:
                                try:
                                    ext_tool_options = json.loads(ext_tool[1])
                                    loc = 'locally_active'
                                    if (loc in ext_tool_options and
                                            ext_tool_options[loc] == 'no'):
                                        externally_active = True
                                except Exception as e:
                                    self.logger.error("Couldn't check ext"
                                                      ' because: ' + str(e))
                                    externally_active = False
                        manifest = Template(self.api_action.manifest)
                        if not externally_active:
                            instance_num = re.search(r'\d+$',
                                                     manifest.option(
                                                         tool, 'name')[1])
                            if not instance_num:
                                ncore_list.append(tool)
                            # multiple instances share same image
                            elif self.action['action_name'] not in self.no_instance:
                                ncore_list.append(tool)

                has_core[repo] = core_list
                has_non_core[repo] = ncore_list

            for repo in repos:
                self.tools_tc[repo] = {}

                if self.action['cores']:
                    # make sure only repos with core tools are displayed
                    if has_core.get(repo):
                        self.repo_widgets[repo] = self.add(npyscreen.TitleText,
                                                           name='Plugin: '+repo,
                                                           editable=False,
                                                           rely=i, relx=5)

                        for tool in has_core[repo]:
                            tool_name = tool.split(':', 2)[2].split('/')[-1]
                            if tool_name == '':
                                tool_name = '/'
                            self.tools_tc[repo][tool] = self.add(
                                npyscreen.CheckBox, name=tool_name,
                                value=True, relx=10)
                            i += 1
                        i += 3
                else:
                    # make sure only repos with non-core tools are displayed
                    if has_non_core.get(repo):
                        self.repo_widgets[repo] = self.add(npyscreen.TitleText,
                                                           name='Plugin: '+repo,
                                                           editable=False,
                                                           rely=i, relx=5)

                        for tool in has_non_core[repo]:
                            tool_name = tool.split(':', 2)[2].split('/')[-1]
                            if tool_name == '':
                                tool_name = '/'
                            self.tools_tc[repo][tool] = self.add(
                                npyscreen.CheckBox, name=tool_name,
                                value=True, relx=10)
                            i += 1
                        i += 3
        return

    def on_ok(self):
        """
        Take the tool selections and perform the provided action on them
        """
        def diff(first, second):
            """
            Get the elements that exist in the first list and not in the second
            """
            second = set(second)
            return [item for item in first if item not in second]

        def popup(original, orig_type, thr, title):
            """
            Start the thread and display a popup of info
            until the thread is finished
            """
            thr.start()
            info_str = ''
            while thr.is_alive():
                if orig_type == 'containers':
                    info = diff(Containers(), original)
                elif orig_type == 'images':
                    info = diff(Images(), original)
                if info:
                    info_str = ''
                for entry in info:
                    info_str = entry[0] + ': ' + entry[1] + '\n' + info_str
                if self.action['action_name'] != 'configure':
                    npyscreen.notify_wait(info_str, title=title)
                    time.sleep(1)

            thr.join()
            try:
                result = self.api_action.queue.get(False)
                if isinstance(result, tuple) and isinstance(result[1], tuple):
                    running, failed = result[1]
                    r_str = ''
                    for container in running:
                        r_str += container + ': successful\n'
                    for container in failed:
                        r_str += container + ': failed\n'
                    npyscreen.notify_confirm(r_str)
            except Exception as e:  # pragma: no cover
                pass
            return

        if self.action['type'] == 'images':
            originals = Images()
        else:
            originals = Containers()

        tool_d = {}
        if self.action['action_name'] in ['remove', 'stop', 'update']:
            reconfirmation_str = ''
            if self.action['cores']:
                reconfirmation_str = 'Are you sure you want to '
                reconfirmation_str += self.action['action_name']
                reconfirmation_str += ' core containers?'
            else:
                reconfirmation_str = 'Are you sure you want to '
                reconfirmation_str += self.action['action_name']
                reconfirmation_str += ' plugin containers?'

            perform = npyscreen.notify_ok_cancel(reconfirmation_str,
                                                 title='Confirm command')
            if not perform:
                return

        tools_to_configure = []
        for repo in self.tools_tc:
            for tool in self.tools_tc[repo]:
                if self.tools_tc[repo][tool].value:
                    t = tool.split(':', 2)[2].split('/')[-1]
                    if t.startswith('/:'):
                        t = ' '+t[1:]
                    t = t.split(':')
                    if self.action['action_name'] in ['start', 'stop']:
                        status = self.action['action_object1'](repo, t[0])
                    elif self.action['action_name'] == 'configure':
                        constraints = {'name': t[0],
                                       'branch': t[1],
                                       'version': t[2],
                                       'repo': repo}
                        options = ['type']
                        action = self.action['api_action']
                        tool = self.manifest.constrain_opts(constraints,
                                                            options)[0]
                        # only one tool should be returned
                        name = list(tool.keys())[0]
                        if tool[name]['type'] == 'registry':
                            registry_image = True
                        else:
                            registry_image = False
                        kargs = {'name': 'Configure ' + t[0],
                                 'tool_name': t[0],
                                 'branch': t[1],
                                 'version': t[2],
                                 'repo': repo,
                                 'next_tool': None,
                                 'get_configure': self.api_action.get_configure,
                                 'save_configure': self.api_action.save_configure,
                                 'restart_tools': self.api_action.restart_tools,
                                 'start_tools': action.start,
                                 'from_registry': registry_image}
                        if tools_to_configure:
                            kargs['next_tool'] = tools_to_configure[-1]
                        self.parentApp.addForm('EDITOR' + t[0], EditorForm,
                                               **kargs)
                        tools_to_configure.append('EDITOR' + t[0])
                    elif self.action['action_name'] == 'remove':
                        status = self.action['action_object1'](repo, t[0])
                    else:
                        kargs = {'name': t[0],
                                 'branch': t[1],
                                 'version': t[2]}
                        # add core recognition
                        if self.action['cores']:
                            kargs.update({'groups': 'core'})
                        # use latest version for update, not necessarily
                        # version in manifest
                        if self.action['action_name'] == 'update':
                            if t[2] != 'HEAD':
                                repo_commits = self.tools_inst.repo_commits(repo)[
                                    1]
                                for branch in repo_commits:
                                    if branch[0] == t[1]:
                                        kargs.update(
                                            {'new_version': branch[1][0]})
                            else:
                                kargs.update({'new_version': 'HEAD'})
                        thr = Thread(target=self.action['action_object1'],
                                     args=(),
                                     kwargs=kargs)
                        popup(originals, self.action['type'], thr,
                              'Please wait, ' + self.action['present_t'] +
                              '...')

        if self.action['action_name'] != 'configure':
            npyscreen.notify_confirm('Done ' + self.action['present_t'] + '.',
                                     title=self.action['past_t'])
            self.quit()
        else:
            if len(tools_to_configure) > 0:
                self.parentApp.change_form(tools_to_configure[-1])
            else:
                npyscreen.notify_confirm('No tools selected, returning to'
                                         ' main menu',
                                         title='No action taken')
                self.quit()

    def on_cancel(self):
        """ When user clicks cancel, will return to MAIN """
        self.quit()
コード例 #12
0
def test_new():
    """ Test the new function """
    tools = Tools()
    tools.new('image', 'redis')
    tools.new('core', '')
    tools.new('repo', 'https://github.com/cyberreboot/vent')
コード例 #13
0
ファイル: system.py プロジェクト: CyberReboot/vent
    def _startup(self):
        """
        Automatically detect if a startup file is specified and stand up a vent
        host with all necessary tools based on the specifications in that file
        """
        status = (True, None)
        try:
            s_dict = {}
            # rewrite the yml file to exclusively lowercase
            with open(self.startup_file, 'r') as sup:
                vent_startup = sup.read()
            with open(self.startup_file, 'w') as sup:
                for line in vent_startup:
                    sup.write(line.lower())
            with open(self.startup_file, 'r') as sup:
                s_dict = yaml.safe_load(sup.read())
            if 'vent.cfg' in s_dict:
                v_cfg = Template(self.vent_config)
                for section in s_dict['vent.cfg']:
                    for option in s_dict['vent.cfg'][section]:
                        val = ('no', 'yes')[
                            s_dict['vent.cfg'][section][option]]
                        v_status = v_cfg.add_option(section, option, value=val)
                        if not v_status[0]:
                            v_cfg.set_option(section, option, val)
                v_cfg.write_config()
                del s_dict['vent.cfg']
            tool_d = {}
            extra_options = ['info', 'service', 'settings', 'docker', 'gpu']
            s_dict_c = copy.deepcopy(s_dict)
            # TODO check for repo or image type
            for repo in s_dict_c:
                repository = Repository(System().manifest)
                repository.repo = repo
                repository._clone()
                repo_path, org, r_name = self.path_dirs.get_path(repo)
                get_tools = []
                for tool in s_dict_c[repo]:
                    t_branch = 'master'
                    t_version = 'HEAD'
                    if 'branch' in s_dict[repo][tool]:
                        t_branch = s_dict[repo][tool]['branch']
                    if 'version' in s_dict[repo][tool]:
                        t_version = s_dict[repo][tool]['version']
                    get_tools.append((tool, t_branch, t_version))

                available_tools = AvailableTools(repo_path, tools=get_tools)
                for tool in s_dict_c[repo]:
                    # if we can't find the tool in that repo, skip over this
                    # tool and notify in the logs
                    t_path, t_path_cased = PathDirs.rel_path(
                        tool, available_tools)
                    if t_path is None:
                        self.logger.error("Couldn't find tool " + tool + ' in'
                                          ' repo ' + repo)
                        continue
                    # ensure no NoneType iteration errors
                    if s_dict_c[repo][tool] is None:
                        s_dict[repo][tool] = {}
                    # check if we need to configure instances along the way
                    instances = 1
                    if 'settings' in s_dict[repo][tool]:
                        if 'instances' in s_dict[repo][tool]['settings']:
                            instances = int(s_dict[repo][tool]
                                            ['settings']['instances'])
                    # add the tool
                    t_branch = 'master'
                    t_version = 'HEAD'
                    t_image = None
                    add_tools = None
                    add_tools = [(t_path_cased, '')]
                    if 'branch' in s_dict[repo][tool]:
                        t_branch = s_dict[repo][tool]['branch']
                    if 'version' in s_dict[repo][tool]:
                        t_version = s_dict[repo][tool]['version']
                    if 'image' in s_dict[repo][tool]:
                        t_image = s_dict[repo][tool]['image']
                    repository.add(
                        repo, add_tools, branch=t_branch, version=t_version, image_name=t_image)
                    manifest = Template(self.manifest)
                    # update the manifest with extra defined runtime settings
                    base_section = ':'.join([org, r_name, t_path,
                                             t_branch, t_version])
                    for option in extra_options:
                        if option in s_dict[repo][tool]:
                            opt_dict = manifest.option(base_section, option)
                            # add new values defined into default options for
                            # that tool, don't overwrite them
                            if opt_dict[0]:
                                opt_dict = json.loads(opt_dict[1])
                            else:
                                opt_dict = {}
                            # stringify values for vent
                            for v in s_dict[repo][tool][option]:
                                pval = s_dict[repo][tool][option][v]
                                s_dict[repo][tool][option][v] = json.dumps(
                                    pval)
                            opt_dict.update(s_dict[repo][tool][option])
                            manifest.set_option(base_section, option,
                                                json.dumps(opt_dict))
                    # copy manifest info into new sections if necessary
                    if instances > 1:
                        for i in range(2, instances + 1):
                            i_section = base_section.rsplit(':', 2)
                            i_section[0] += str(i)
                            i_section = ':'.join(i_section)
                            manifest.add_section(i_section)
                            for opt_val in manifest.section(base_section)[1]:
                                if opt_val[0] == 'name':
                                    manifest.set_option(i_section, opt_val[0],
                                                        opt_val[1] + str(i))
                                else:
                                    manifest.set_option(i_section, opt_val[0],
                                                        opt_val[1])
                    manifest.write_config()

            tool_d = {}
            tools = Tools()
            # start tools, if necessary
            for repo in s_dict:
                for tool in s_dict[repo]:
                    if 'start' in s_dict[repo][tool]:
                        if s_dict[repo][tool]['start']:
                            local_instances = 1
                            if 'settings' in s_dict[repo][tool] and 'instances' in s_dict[repo][tool]['settings']:
                                local_instances = int(
                                    s_dict[repo][tool]['settings']['instances'])
                            t_branch = 'master'
                            t_version = 'HEAD'
                            if 'branch' in s_dict[repo][tool]:
                                t_branch = s_dict[repo][tool]['branch']
                            if 'version' in s_dict[repo][tool]:
                                t_version = s_dict[repo][tool]['version']
                            for i in range(1, local_instances + 1):
                                i_name = tool + str(i) if i != 1 else tool
                                i_name = i_name.replace('@', '')
                                tool_d.update(
                                    tools._prep_start(repo, i_name)[1])

            if tool_d:
                tools.start(tool_d, None, is_tool_d=True)
        except Exception as e:  # pragma: no cover
            self.logger.error('Startup failed because: {0}'.format(str(e)))
            status = (False, str(e))
        return status
コード例 #14
0
def test_remove():
    """ Test the remove function """
    tools = Tools()
    tools.remove('https://github.com/cyberreboot/vent', 'rabbitmq')
コード例 #15
0
ファイル: tools.py プロジェクト: swipswaps/vent
class ToolForm(npyscreen.ActionForm):
    """ Tools form for the Vent CLI """
    def __init__(self, *args, **keywords):
        """ Initialize tool form objects """
        self.logger = Logger(__name__)
        self.api_action = System()
        self.tools_inst = Tools()
        action = {'api_action': self.tools_inst}
        self.tools_tc = {}
        self.repo_widgets = {}
        if keywords['action_dict']:
            action.update(keywords['action_dict'])
        if keywords['names']:
            i = 1
            for name in keywords['names']:
                try:
                    action['action_object' + str(i)] = getattr(
                        self.tools_inst, name)
                except AttributeError:
                    action['action_object' + str(i)] = getattr(
                        self.api_action, name)
                i += 1
        self.action = action
        # get list of all possible group views to display
        self.views = deque()
        possible_groups = set()
        manifest = Template(self.api_action.manifest)
        tools = self.tools_inst.inventory(choices=['tools'])[1]['tools']
        for tool in tools:
            groups = manifest.option(tool, 'groups')[1].split(',')
            for group in groups:
                # don't do core because that's the purpose of all in views
                if group != '' and group != 'core':
                    possible_groups.add(group)
        self.manifest = manifest
        self.views += possible_groups
        self.views.append('all groups')
        self.no_instance = ['remove']
        super(ToolForm, self).__init__(*args, **keywords)

    def quit(self, *args, **kwargs):
        """ Overridden to switch back to MAIN form """
        self.parentApp.switchForm('MAIN')

    def toggle_view(self, *args, **kwargs):
        """ Toggles the view between different groups """
        group_to_display = self.views.popleft()
        self.cur_view.value = group_to_display
        for repo in self.tools_tc:
            for tool in self.tools_tc[repo]:
                t_groups = self.manifest.option(tool, 'groups')[1]
                if group_to_display not in t_groups and \
                        group_to_display != 'all groups':
                    self.tools_tc[repo][tool].value = False
                    self.tools_tc[repo][tool].hidden = True
                else:
                    self.tools_tc[repo][tool].value = True
                    self.tools_tc[repo][tool].hidden = False
        # redraw elements
        self.display()
        # add view back to queue
        self.views.append(group_to_display)

    def create(self, group_view=False):
        """ Update with current tools """
        self.add_handlers({'^T': self.quit, '^Q': self.quit})
        self.add(npyscreen.TitleText,
                 name='Select which tools to ' + self.action['action'] + ':',
                 editable=False)
        togglable = ['remove']
        if self.action['action_name'] in togglable:
            self.cur_view = self.add(npyscreen.TitleText,
                                     name='Group view:',
                                     value='all groups',
                                     editable=False,
                                     rely=3)
            self.add_handlers({'^V': self.toggle_view})
            i = 5
        else:
            i = 4

        if self.action['action_name'] == 'start':
            response = self.tools_inst.inventory(
                choices=['repos', 'tools', 'built', 'running'])
        else:
            response = self.tools_inst.inventory(choices=['repos', 'tools'])
        if response[0]:
            inventory = response[1]

            repos = inventory['repos']

            # dict has repo as key and list of core/non-core tools as values
            has_core = {}
            has_non_core = {}

            # find all tools that are in this repo
            # and list them if they are core
            for repo in repos:
                core_list = []
                ncore_list = []

                # splice the repo names for processing
                if (repo.startswith('http')):
                    repo_name = repo.rsplit('/', 2)[1:]
                else:
                    repo_name = repo.split('/')

                for tool in inventory['tools']:
                    tool_repo_name = tool.split(':')

                    # cross reference repo names
                    if (repo_name[0] == tool_repo_name[0]
                            and repo_name[1] == tool_repo_name[1]):
                        # check to ensure tool not set to locally active = no
                        # in vent.cfg
                        externally_active = False
                        vent_cfg_file = self.api_action.vent_config
                        vent_cfg = Template(vent_cfg_file)
                        tool_pairs = vent_cfg.section('external-services')[1]
                        for ext_tool in tool_pairs:
                            if ext_tool[0].lower() == inventory['tools'][tool]:
                                try:
                                    ext_tool_options = json.loads(ext_tool[1])
                                    loc = 'locally_active'
                                    if (loc in ext_tool_options
                                            and ext_tool_options[loc] == 'no'):
                                        externally_active = True
                                except Exception as e:
                                    self.logger.error("Couldn't check ext"
                                                      ' because: ' + str(e))
                                    externally_active = False
                        manifest = Template(self.api_action.manifest)
                        if not externally_active:
                            instance_num = re.search(
                                r'\d+$',
                                manifest.option(tool, 'name')[1])
                            if not instance_num:
                                ncore_list.append(tool)
                            # multiple instances share same image
                            elif self.action[
                                    'action_name'] not in self.no_instance:
                                ncore_list.append(tool)

                has_core[repo] = core_list
                has_non_core[repo] = ncore_list

            for repo in repos:
                self.tools_tc[repo] = {}

                if self.action['cores']:
                    # make sure only repos with core tools are displayed
                    if has_core.get(repo):
                        self.repo_widgets[repo] = self.add(npyscreen.TitleText,
                                                           name='Plugin: ' +
                                                           repo,
                                                           editable=False,
                                                           rely=i,
                                                           relx=5)

                        for tool in has_core[repo]:
                            tool_name = tool.split(':', 2)[2].split('/')[-1]
                            if tool_name == '':
                                tool_name = '/'
                            self.tools_tc[repo][tool] = self.add(
                                npyscreen.CheckBox,
                                name=tool_name,
                                value=True,
                                relx=10)
                            i += 1
                        i += 3
                else:
                    # make sure only repos with non-core tools are displayed
                    if has_non_core.get(repo):
                        self.repo_widgets[repo] = self.add(npyscreen.TitleText,
                                                           name='Plugin: ' +
                                                           repo,
                                                           editable=False,
                                                           rely=i,
                                                           relx=5)

                        for tool in has_non_core[repo]:
                            tool_name = tool.split(':', 2)[2].split('/')[-1]
                            if tool_name == '':
                                tool_name = '/'
                            self.tools_tc[repo][tool] = self.add(
                                npyscreen.CheckBox,
                                name=tool_name,
                                value=True,
                                relx=10)
                            i += 1
                        i += 3
        return

    def on_ok(self):
        """
        Take the tool selections and perform the provided action on them
        """
        def diff(first, second):
            """
            Get the elements that exist in the first list and not in the second
            """
            second = set(second)
            return [item for item in first if item not in second]

        def popup(original, orig_type, thr, title):
            """
            Start the thread and display a popup of info
            until the thread is finished
            """
            thr.start()
            info_str = ''
            while thr.is_alive():
                if orig_type == 'containers':
                    info = diff(Containers(), original)
                elif orig_type == 'images':
                    info = diff(Images(), original)
                if info:
                    info_str = ''
                for entry in info:
                    info_str = entry[0] + ': ' + entry[1] + '\n' + info_str
                if self.action['action_name'] != 'configure':
                    npyscreen.notify_wait(info_str, title=title)
                    time.sleep(1)

            thr.join()
            try:
                result = self.api_action.queue.get(False)
                if isinstance(result, tuple) and isinstance(result[1], tuple):
                    running, failed = result[1]
                    r_str = ''
                    for container in running:
                        r_str += container + ': successful\n'
                    for container in failed:
                        r_str += container + ': failed\n'
                    npyscreen.notify_confirm(r_str)
            except Exception as e:  # pragma: no cover
                pass
            return

        if self.action['type'] == 'images':
            originals = Images()
        else:
            originals = Containers()

        tool_d = {}
        if self.action['action_name'] in ['remove', 'stop', 'update']:
            reconfirmation_str = ''
            if self.action['cores']:
                reconfirmation_str = 'Are you sure you want to '
                reconfirmation_str += self.action['action_name']
                reconfirmation_str += ' core containers?'
            else:
                reconfirmation_str = 'Are you sure you want to '
                reconfirmation_str += self.action['action_name']
                reconfirmation_str += ' plugin containers?'

            perform = npyscreen.notify_ok_cancel(reconfirmation_str,
                                                 title='Confirm command')
            if not perform:
                return

        tools_to_configure = []
        for repo in self.tools_tc:
            for tool in self.tools_tc[repo]:
                if self.tools_tc[repo][tool].value:
                    t = tool.split(':', 2)[2].split('/')[-1]
                    if t.startswith('/:'):
                        t = ' ' + t[1:]
                    t = t.split(':')
                    if self.action['action_name'] in ['start', 'stop']:
                        status = self.action['action_object1'](repo, t[0])
                    elif self.action['action_name'] == 'configure':
                        constraints = {
                            'name': t[0],
                            'branch': t[1],
                            'version': t[2],
                            'repo': repo
                        }
                        options = ['type']
                        action = self.action['api_action']
                        tool = self.manifest.constrain_opts(
                            constraints, options)[0]
                        # only one tool should be returned
                        name = list(tool.keys())[0]
                        if tool[name]['type'] == 'registry':
                            registry_image = True
                        else:
                            registry_image = False
                        kargs = {
                            'name': 'Configure ' + t[0],
                            'tool_name': t[0],
                            'branch': t[1],
                            'version': t[2],
                            'repo': repo,
                            'next_tool': None,
                            'get_configure': self.api_action.get_configure,
                            'save_configure': self.api_action.save_configure,
                            'restart_tools': self.api_action.restart_tools,
                            'start_tools': action.start,
                            'from_registry': registry_image
                        }
                        if tools_to_configure:
                            kargs['next_tool'] = tools_to_configure[-1]
                        self.parentApp.addForm('EDITOR' + t[0], EditorForm,
                                               **kargs)
                        tools_to_configure.append('EDITOR' + t[0])
                    elif self.action['action_name'] == 'remove':
                        status = self.action['action_object1'](repo, t[0])
                    else:
                        kargs = {'name': t[0], 'branch': t[1], 'version': t[2]}
                        # add core recognition
                        if self.action['cores']:
                            kargs.update({'groups': 'core'})
                        # use latest version for update, not necessarily
                        # version in manifest
                        if self.action['action_name'] == 'update':
                            if t[2] != 'HEAD':
                                repo_commits = self.tools_inst.repo_commits(
                                    repo)[1]
                                for branch in repo_commits:
                                    if branch[0] == t[1]:
                                        kargs.update(
                                            {'new_version': branch[1][0]})
                            else:
                                kargs.update({'new_version': 'HEAD'})
                        thr = Thread(target=self.action['action_object1'],
                                     args=(),
                                     kwargs=kargs)
                        popup(
                            originals, self.action['type'], thr,
                            'Please wait, ' + self.action['present_t'] + '...')

        if self.action['action_name'] != 'configure':
            npyscreen.notify_confirm('Done ' + self.action['present_t'] + '.',
                                     title=self.action['past_t'])
            self.quit()
        else:
            if len(tools_to_configure) > 0:
                self.parentApp.change_form(tools_to_configure[-1])
            else:
                npyscreen.notify_confirm(
                    'No tools selected, returning to'
                    ' main menu',
                    title='No action taken')
                self.quit()

    def on_cancel(self):
        """ When user clicks cancel, will return to MAIN """
        self.quit()
コード例 #16
0
def test_inventory():
    """ Test the inventory function """
    tools = Tools()
    tools.inventory()
コード例 #17
0
ファイル: system.py プロジェクト: swipswaps/vent
 def restart_tools(self,
                   repo=None,
                   name=None,
                   groups=None,
                   branch='master',
                   version='HEAD',
                   main_cfg=False,
                   old_val='',
                   new_val=''):
     """
     Restart necessary tools based on changes that have been made either to
     vent.cfg or to vent.template. This includes tools that need to be
     restarted because they depend on other tools that were changed.
     """
     status = (True, None)
     if not main_cfg:
         try:
             t_identifier = {'name': name,
                             'branch': branch,
                             'version': version}
             result = Template(System().manifest).constrain_opts(t_identifier,
                                                                 ['running',
                                                                  'link_name'])
             tools = result[0]
             tool = list(tools.keys())[0]
             if ('running' in tools[tool] and
                     tools[tool]['running'] == 'yes'):
                 start_tools = [t_identifier]
                 dependent_tools = [tools[tool]['link_name']]
                 start_tools += Dependencies(dependent_tools)
                 # TODO
                 start_d = {}
                 for tool_identifier in start_tools:
                     self.clean(**tool_identifier)
                     start_d.update(self.prep_start(**tool_identifier)[1])
                 if start_d:
                     Tools().start(start_d, '', is_tool_d=True)
         except Exception as e:  # pragma: no cover
             self.logger.error('Trouble restarting tool ' + name +
                               ' because: ' + str(e))
             status = (False, str(e))
     else:
         try:
             # string manipulation to get tools into arrays
             ext_start = old_val.find('[external-services]')
             if ext_start >= 0:
                 ot_str = old_val[old_val.find('[external-services]') + 20:]
             else:
                 ot_str = ''
             old_tools = []
             for old_tool in ot_str.split('\n'):
                 if old_tool != '':
                     old_tools.append(old_tool.split('=')[0].strip())
             ext_start = new_val.find('[external-services]')
             if ext_start >= 0:
                 nt_str = new_val[new_val.find('[external-services]') + 20:]
             else:
                 nt_str = ''
             new_tools = []
             for new_tool in nt_str.split('\n'):
                 if new_tool != '':
                     new_tools.append(new_tool.split('=')[0].strip())
             # find tools changed
             tool_changes = []
             for old_tool in old_tools:
                 if old_tool not in new_tools:
                     tool_changes.append(old_tool)
             for new_tool in new_tools:
                 if new_tool not in old_tools:
                     tool_changes.append(new_tool)
                 else:
                     # tool name will be the same
                     oconf = old_val[old_val.find(new_tool):].split('\n')[0]
                     nconf = new_val[new_val.find(new_tool):].split('\n')[0]
                     if oconf != nconf:
                         tool_changes.append(new_tool)
             # put link names in a dictionary for finding dependencies
             dependent_tools = []
             for i, entry in enumerate(tool_changes):
                 dependent_tools.append(entry)
                 # change names to lowercase for use in clean, prep_start
                 tool_changes[i] = {'name': entry.lower().replace('-', '_')}
             dependencies = Dependencies(dependent_tools)
             # restart tools
             restart = tool_changes + dependencies
             tool_d = {}
             for tool in restart:
                 self.clean(**tool)
                 tool_d.update(self.prep_start(**tool)[1])
             if tool_d:
                 # TODO fix the arguments
                 Tools().start(tool_d)
         except Exception as e:  # pragma: no cover
             self.logger.error('Problem restarting tools: ' + str(e))
             status = (False, str(e))
     return status
コード例 #18
0
ファイル: system.py プロジェクト: swipswaps/vent
    def _startup(self):
        """
        Automatically detect if a startup file is specified and stand up a vent
        host with all necessary tools based on the specifications in that file
        """
        status = (True, None)
        try:
            s_dict = {}
            # rewrite the yml file to exclusively lowercase
            with open(self.startup_file, 'r') as sup:
                vent_startup = sup.read()
            with open(self.startup_file, 'w') as sup:
                for line in vent_startup:
                    sup.write(line.lower())
            with open(self.startup_file, 'r') as sup:
                s_dict = yaml.safe_load(sup.read())
            if 'vent.cfg' in s_dict:
                v_cfg = Template(self.vent_config)
                for section in s_dict['vent.cfg']:
                    for option in s_dict['vent.cfg'][section]:
                        val = ('no', 'yes')[
                            s_dict['vent.cfg'][section][option]]
                        v_status = v_cfg.add_option(section, option, value=val)
                        if not v_status[0]:
                            v_cfg.set_option(section, option, val)
                v_cfg.write_config()
                del s_dict['vent.cfg']
            tool_d = {}
            extra_options = ['info', 'service', 'settings', 'docker', 'gpu']
            s_dict_c = copy.deepcopy(s_dict)
            # TODO check for repo or image type
            for repo in s_dict_c:
                repository = Repository(System().manifest)
                repository.repo = repo
                repository._clone()
                repo_path, org, r_name = self.path_dirs.get_path(repo)
                get_tools = []
                for tool in s_dict_c[repo]:
                    t_branch = 'master'
                    t_version = 'HEAD'
                    if 'branch' in s_dict[repo][tool]:
                        t_branch = s_dict[repo][tool]['branch']
                    if 'version' in s_dict[repo][tool]:
                        t_version = s_dict[repo][tool]['version']
                    get_tools.append((tool, t_branch, t_version))

                available_tools = AvailableTools(repo_path, tools=get_tools)
                for tool in s_dict_c[repo]:
                    # if we can't find the tool in that repo, skip over this
                    # tool and notify in the logs
                    t_path, t_path_cased = PathDirs.rel_path(
                        tool, available_tools)
                    if t_path is None:
                        self.logger.error("Couldn't find tool " + tool + ' in'
                                          ' repo ' + repo)
                        continue
                    # ensure no NoneType iteration errors
                    if s_dict_c[repo][tool] is None:
                        s_dict[repo][tool] = {}
                    # check if we need to configure instances along the way
                    instances = 1
                    if 'settings' in s_dict[repo][tool]:
                        if 'instances' in s_dict[repo][tool]['settings']:
                            instances = int(s_dict[repo][tool]
                                            ['settings']['instances'])
                    # add the tool
                    t_branch = 'master'
                    t_version = 'HEAD'
                    t_image = None
                    add_tools = None
                    add_tools = [(t_path_cased, '')]
                    if 'branch' in s_dict[repo][tool]:
                        t_branch = s_dict[repo][tool]['branch']
                    if 'version' in s_dict[repo][tool]:
                        t_version = s_dict[repo][tool]['version']
                    if 'image' in s_dict[repo][tool]:
                        t_image = s_dict[repo][tool]['image']
                    repository.add(
                        repo, tools=add_tools, branch=t_branch, version=t_version, image_name=t_image)
                    manifest = Template(self.manifest)
                    # update the manifest with extra defined runtime settings
                    base_section = ':'.join([org, r_name, t_path,
                                             t_branch, t_version])
                    for option in extra_options:
                        if option in s_dict[repo][tool]:
                            opt_dict = manifest.option(base_section, option)
                            # add new values defined into default options for
                            # that tool, don't overwrite them
                            if opt_dict[0]:
                                opt_dict = json.loads(opt_dict[1])
                            else:
                                opt_dict = {}
                            # stringify values for vent
                            for v in s_dict[repo][tool][option]:
                                pval = s_dict[repo][tool][option][v]
                                s_dict[repo][tool][option][v] = json.dumps(
                                    pval)
                            opt_dict.update(s_dict[repo][tool][option])
                            manifest.set_option(base_section, option,
                                                json.dumps(opt_dict))
                    # copy manifest info into new sections if necessary
                    if instances > 1:
                        for i in range(2, instances + 1):
                            i_section = base_section.rsplit(':', 2)
                            i_section[0] += str(i)
                            i_section = ':'.join(i_section)
                            manifest.add_section(i_section)
                            for opt_val in manifest.section(base_section)[1]:
                                if opt_val[0] == 'name':
                                    manifest.set_option(i_section, opt_val[0],
                                                        opt_val[1] + str(i))
                                else:
                                    manifest.set_option(i_section, opt_val[0],
                                                        opt_val[1])
                    manifest.write_config()

            tool_d = {}
            tools = Tools()
            # start tools, if necessary
            for repo in s_dict:
                for tool in s_dict[repo]:
                    if 'start' in s_dict[repo][tool]:
                        if s_dict[repo][tool]['start']:
                            local_instances = 1
                            if 'settings' in s_dict[repo][tool] and 'instances' in s_dict[repo][tool]['settings']:
                                local_instances = int(
                                    s_dict[repo][tool]['settings']['instances'])
                            t_branch = 'master'
                            t_version = 'HEAD'
                            if 'branch' in s_dict[repo][tool]:
                                t_branch = s_dict[repo][tool]['branch']
                            if 'version' in s_dict[repo][tool]:
                                t_version = s_dict[repo][tool]['version']
                            for i in range(1, local_instances + 1):
                                i_name = tool + str(i) if i != 1 else tool
                                i_name = i_name.replace('@', '')
                                tool_d.update(
                                    tools._prep_start(repo, i_name)[1])

            if tool_d:
                tools.start(tool_d, None, is_tool_d=True)
        except Exception as e:  # pragma: no cover
            self.logger.error('Startup failed because: {0}'.format(str(e)))
            status = (False, str(e))
        return status
コード例 #19
0
ファイル: add.py プロジェクト: swipswaps/vent
    def on_ok(self):
        """ Add the repository """
        def popup(thr, add_type, title):
            """
            Start the thread and display a popup of the plugin being cloned
            until the thread is finished
            """
            thr.start()
            tool_str = 'Cloning repository...'
            if add_type == 'image':
                tool_str = 'Pulling image...'
            npyscreen.notify_wait(tool_str, title=title)
            while thr.is_alive():
                time.sleep(1)
            return

        if self.image.value and self.link_name.value:
            api_action = Tools()
            api_image = Image(System().manifest)
            api_system = System()
            thr = threading.Thread(target=api_image.add,
                                   args=(),
                                   kwargs={
                                       'image': self.image.value,
                                       'link_name': self.link_name.value,
                                       'tag': self.tag.value,
                                       'registry': self.registry.value,
                                       'groups': self.groups.value
                                   })
            popup(thr, 'image', 'Please wait, adding image...')
            npyscreen.notify_confirm('Done adding image.', title='Added image')
            editor_args = {
                'tool_name': self.image.value,
                'version': self.tag.value,
                'get_configure': api_system.get_configure,
                'save_configure': api_system.save_configure,
                'restart_tools': api_system.restart_tools,
                'start_tools': api_action.start,
                'from_registry': True,
                'just_downloaded': True,
                'link_name': self.link_name.value,
                'groups': self.groups.value
            }
            self.parentApp.addForm('CONFIGUREIMAGE',
                                   EditorForm,
                                   name='Specify vent.template settings for '
                                   'image pulled (optional)',
                                   **editor_args)
            self.parentApp.change_form('CONFIGUREIMAGE')
        elif self.image.value:
            npyscreen.notify_confirm(
                'A name needs to be supplied for '
                'the image being added!',
                title='Specify a name for the image',
                form_color='CAUTION')
        elif self.repo.value:
            self.parentApp.repo_value['repo'] = self.repo.value.lower()
            api_repo = Repository(System().manifest)
            api_repo.repo = self.repo.value.lower()
            thr = threading.Thread(target=api_repo._clone,
                                   args=(),
                                   kwargs={
                                       'user': self.user.value,
                                       'pw': self.pw.value
                                   })
            popup(thr, 'repository', 'Please wait, adding repository...')
            self.parentApp.addForm('ADDOPTIONS',
                                   AddOptionsForm,
                                   name='Set options for new plugin'
                                   '\t\t\t\t\t\t^Q to quit',
                                   color='CONTROL')
            self.parentApp.change_form('ADDOPTIONS')
        else:
            npyscreen.notify_confirm(
                'Either a repository or an image '
                'name must be specified!',
                title='Specify plugin to add',
                form_color='CAUTION')
        return
コード例 #20
0
def test_stop():
    """ Test the stop function """
    tools = Tools()
    tools.stop('https://github.com/cyberreboot/vent', 'rabbitmq')
コード例 #21
0
def test_configure():
    """ Test the configure function """
    tools = Tools()
    tools.configure('foo')