예제 #1
0
    def __init__(self, config, initial_env, run_type='install'):
        self.__config = config
        self.__env = Env(initial_env=initial_env,
                         env_prefix=self.__config['app']['env_prefix'])
        self.__current_running = set()

        self.__run_type = run_type
        if run_type == 'runtime':
            self.__config_package_name = 'package_runtime'
        else:
            self.__config_package_name = 'package_install'
예제 #2
0
    def __init__(self, config_user, config_version, config_release, step_info):
        self.__config_user = config_user
        self.__config_version = config_version
        self.__config_release = config_release
        self.__step_info = step_info

        # Create independent env for installation
        self.__env = Env()
        self.__env.clean()

        self.__pkg_mgr = PackageManager(config_version, config_release)
예제 #3
0
    def execute(self, config_version, shell):
        shell.clear_script()

        env = Env()
        env.clean()
        set_env, unset_env = env.env_change()

        for e in unset_env:
            shell.unset_env(e)
        for k, v in set_env.items():
            shell.set_env(k, v)

        click.echo(shell.script, nl=False)
예제 #4
0
    def __init__(self, config_entry={}, initial_env=None):
        if initial_env is None:
            initial_env = os.environ

        self.__config_entry_input = config_entry
        self.__config_entry = copy.deepcopy(self.__config_entry_input)
        self.__config = Config(self.__config_entry, initial_env)

        add_stream_logger(self.__config['output']['verbose'],
                          self.__config['output']['quiet'])

        self.__env = Env(initial_env=initial_env,
                         env_prefix=self.__config['app']['env_prefix'])

        self.__operation = Operation(self.__config, self.__env)
예제 #5
0
    def default_version(self, shell=None):
        try:
            info = Info()
            default_version = info.default_version
            if default_version:
                config_version = ConfigVersion(config_user, default_version)
                config_release = ConfigRelease(config_version)

                obj = BsmUse(config_user, config_version, config_release)
                set_env, unset_env = obj.run()
            else:
                env = Env()
                env.clean()
                set_env, unset_env = env.env_change()

            for e in unset_env:
                shell.unset_env(e)
            for k, v in set_env.items():
                shell.set_env(k, v)
        except Exception as e:
            _logger.warn('Cat not load default version: {0}'.format(e))
예제 #6
0
    def reload(self, **kwargs):
        if 'config_entry' in kwargs:
            self.__config_entry = kwargs['config_entry']

        if 'initial_env' in kwargs:
            if kwargs['initial_env'] is None:
                initial_env = os.environ
            else:
                initial_env = kwargs['initial_env']
        else:
            initial_env = self.__env.env_final()

        self.__config = Config(self.__config_entry, initial_env)

        create_stream_logger(self.__config['output']['verbose'],
                             self.__config['output']['quiet'])

        self.__env = Env(initial_env=initial_env,
                         env_prefix=self.__config['app']['env_prefix'])
        self.__env.load_app(self.__config['app'])

        self.__operation = Operation(self.__config, self.__env)
예제 #7
0
    def run(self):
        sorted_pkgs = dag_run(self.__dag)

        software_root = self.__config_version.config['software_root']
        release_version = self.__config_version.config['version']

        env = Env()
        env.clean()
        env.set_release(software_root, release_version)

        global_env = self.__config_release.get('setting',
                                               {}).get('global_env', {})
        new_global_env = {}
        for k, v in global_env.items():
            new_global_env[k] = v.format(**self.__config_version.config)
        env.set_global(new_global_env)

        path_def = self.__config_release.get('setting', {}).get('path_def', {})
        for pkg in sorted_pkgs:
            pkg_info = self.__pkg_mgr.package_info(pkg)
            env.set_package(path_def, pkg_info)

        env_change = env.env_change()

        _logger.info('From software root: {0}'.format(software_root))
        _logger.info('Using version: {0}'.format(release_version))

        return env_change
예제 #8
0
    def __dag_run(self):
        # Get clean environment
        env = Env(initial_env=self._env.env_final(),
                  env_prefix=self._config['app']['env_prefix'])
        env.unload_packages()
        env.unload_release()
        env.unload_app()
        env.load_app(self._config['app'])
        env.load_release(self._config['scenario'], self._config['option'],
                         self._config['release'])

        selector = InstallSelector(self._config)
        processor = MultiThreadProcessor()
        executor = InstallExecutor(self._config, env.env_final())

        start_time = datetime.datetime.utcnow()

        with Handler(self._config['release_path']['handler_python_dir']):
            dag_run(self.__dag,
                    selector=selector,
                    processor=processor,
                    executor=executor)

        end_time = datetime.datetime.utcnow()

        self._config['release_status']['install'] = {}
        self._config['release_status']['install']['start'] = start_time
        self._config['release_status']['install']['end'] = end_time
        self._config['release_status']['install']['finished'] = True
        self._config['release_status']['option'] = {}
        for opt in self._config['release_install']['options_to_save']:
            if opt in self._config['option']:
                self._config['release_status']['option'][opt] = self._config[
                    'option'][opt]

        safe_mkdir(self._config['release_path']['status_dir'])
        self._config['release_status'].save_to_file(
            self._config['release_path']['status_file'])
예제 #9
0
    def execute(self, check_type):
        env = Env(initial_env=self._env.env_final(),
                  env_prefix=self._config['app']['env_prefix'])
        env.unload_packages()
        env.unload_release()
        env.unload_app()
        env.load_app(self._config['app'])
        env.load_release(self._config['scenario'], self._config['option'],
                         self._config['release'])

        missing = {}

        with Handler(self._config['release_path']['handler_python_dir']) as h:
            for category in self._config['package_check']:
                for package, value in self._config['package_check'][
                        category].items():
                    if not self.__check_package(h, env.env_final(),
                                                value['config'], check_type):
                        missing.setdefault(package, [])
                        missing[package].append(category)

            self.__check_summary(h, missing, check_type)

        return missing
예제 #10
0
class Executor(object):
    def __init__(self, config, initial_env, run_type='install'):
        self.__config = config
        self.__env = Env(initial_env=initial_env,
                         env_prefix=self.__config['app']['env_prefix'])
        self.__current_running = set()

        self.__run_type = run_type
        if run_type == 'runtime':
            self.__config_package_name = 'package_runtime'
        else:
            self.__config_package_name = 'package_install'

    def param(self, vertex):
        ctg, subdir, pkg, version, step, sub_step = vertex

        par = {}

        par['category'] = ctg
        par['subdir'] = subdir
        par['package'] = pkg
        par['version'] = version
        par['step'] = step
        par['sub_step'] = sub_step

        pkg_cfg = self.__config[self.__config_package_name].package_config(
            ctg, subdir, pkg, version)

        step_info = pkg_cfg['step'][step][sub_step]
        par['action'] = step_info.get('handler')
        par['action_param'] = step_info.get('param')
        par['action_install'] = step_info.get('install', False)

        pkg_path = pkg_cfg['package_path']
        par['package_path'] = copy.deepcopy(pkg_path)
        par['log_file'] = os.path.join(
            pkg_path['log_dir'], '{0}_{1}_{2}.log'.format(pkg, step, sub_step))
        par['env'] = copy.deepcopy(self.__env.env_final())

        par['config_package'] = copy.deepcopy(pkg_cfg['config'])
        par['config_app'] = self.__config['app'].data_copy()
        par['config_output'] = self.__config['output'].data_copy()
        par['config_scenario'] = self.__config['scenario'].data_copy()
        par['config_option'] = self.__config['option'].data_copy()
        par['config_release_path'] = self.__config['release_path'].data_copy()
        par['config_attribute'] = self.__config['attribute'].data_copy()
        par['config_release'] = self.__config['release'].data_copy()
        par['config_category'] = self.__config['category'].data_copy()
        par['config_category_priority'] = self.__config[
            'category_priority'].data_copy()
        par['config_package_all'] = self.__config[
            self.__config_package_name].data_copy()
        par['config_package_all_path'] = self.__config[
            self.__config_package_name + '_path'].data_copy()

        return par

    # This method must be thread safe
    # Do NOT access or modify any variables outside this function (global and member variables)
    # All parameters are passed by "param" argument
    def execute(self, param):
        pkg = param['package']
        step = param['step']
        sub_step = param['sub_step']

        if sub_step == 0:
            step_full_name = '{0} - {1}'.format(pkg, step)
        else:
            step_full_name = '{0} - {1} - {2}'.format(pkg, step, sub_step)

        if not param['action_install']:
            _logger.debug('Skip step: {0}'.format(step_full_name))
            return {'success': True, 'skip': True}

        result = {}

        result['start'] = datetime.datetime.utcnow()

        safe_mkdir(os.path.dirname(param['log_file']))

        try:
            with Handler() as h:
                result_action = h.run('install', param)
        except HandlerNotFoundError as e:
            _logger.error('Install handler "{0}" not found for "{1}"'.format(
                param['action'], step_full_name))
            raise
        except Exception as e:
            _logger.error('Install handler "{0}" error for {1}: {2}'.format(
                param['action'], step_full_name, e))
            if param['config_output']['verbose']:
                _logger.error('\n{0}'.format(traceback.format_exc()))
            raise

        if isinstance(result_action, bool):
            result['success'] = result_action
        elif isinstance(result_action, dict):
            result['success'] = result_action.get('success', False)
        else:
            result['success'] = False

        if not result['success']:
            if isinstance(result_action, dict) and 'message' in result_action:
                _logger.error('"{0}" execution error: {1}'.format(
                    step_full_name, result_action['message']))
            _logger.error('"{0}" execution error. Find log in "{1}"'.format(
                step_full_name, param['log_file']))
            raise InstallExecutorError(
                '"{0}" execution error'.format(step_full_name))

        result['action'] = result_action
        result['end'] = datetime.datetime.utcnow()

        return result

    def report_start(self, vertice):
        pass

    def report_finish(self, vertice_result):
        steps = self.__config['release_install']['steps']
        atomic_start = self.__config['release_install']['atomic_start']
        atomic_end = self.__config['release_install']['atomic_end']

        for vertex, result in vertice_result:
            ctg, subdir, pkg, version, step, sub_step = vertex

            pkg_cfg = self.__config[self.__config_package_name].package_config(
                ctg, subdir, pkg, version)

            if step == atomic_end and sub_step == (len(pkg_cfg['step'][step]) -
                                                   1):
                _logger.debug('Load package env for {0}'.format(pkg))
                self.__env.load_package(pkg_cfg['config'])

            if result['success']:
                if not result.get('skip'):
                    _logger.info(' > {0} {1} {2} finished'.format(
                        pkg, step, sub_step))
                    if sub_step == (len(pkg_cfg['step'][step]) - 1):
                        _logger.debug(
                            'Save install status for {0} - {1}'.format(
                                pkg, step))
                        pkg_cfg['install_status'].setdefault('steps', {})
                        pkg_cfg['install_status']['steps'][step] = {}
                        pkg_cfg['install_status']['steps'][step][
                            'finished'] = True
                        pkg_cfg['install_status']['steps'][step][
                            'start'] = result['start']
                        pkg_cfg['install_status']['steps'][step][
                            'end'] = result['end']
                        self.__config[
                            self.__config_package_name].save_install_status(
                                ctg, subdir, pkg, version)
                if step == steps[-1] and sub_step == (
                        len(pkg_cfg['step'][step]) - 1):
                    if not pkg_cfg['install_status'].get('finished'):
                        pkg_cfg['install_status']['finished'] = True
                        self.__config[
                            self.__config_package_name].save_install_status(
                                ctg, subdir, pkg, version)
                        if self.__run_type == 'install':
                            _logger.debug(
                                'Save package config for {0}'.format(pkg))
                            self.__config[
                                self.
                                __config_package_name].save_package_config(
                                    ctg, subdir, pkg, version)

    def report_running(self, vertice):
        if not vertice:
            return

        new_running = set()
        for v in vertice:
            ctg, subdir, pkg, version, step, sub_step = v
            pkg_cfg = self.__config[self.__config_package_name].package_config(
                ctg, subdir, pkg, version)
            if not pkg_cfg['step'][step][sub_step].get('install'):
                continue
            new_running.add(v)

        if new_running == self.__current_running or not new_running:
            return

        self.__current_running = new_running

        running_vertice = []
        for v in self.__current_running:
            ctg, subdir, pkg, version, step, sub_step = v
            if sub_step == 0:
                step_full_name = '{2}({4})'
            else:
                step_full_name = '{2}({4}.{5})'
            running_vertice.append(step_full_name.format(*v))
        _logger.info('Running: ' + ', '.join(running_vertice))

    def deliver(self, vertex, result):
        pass

    def abort(self, vertice):
        pass
예제 #11
0
class Bsm(object):
    def __init__(self, config_entry={}, initial_env=None):
        if initial_env is None:
            initial_env = os.environ

        self.__config_entry_input = config_entry
        self.__config_entry = copy.deepcopy(self.__config_entry_input)
        self.__config = Config(self.__config_entry, initial_env)

        add_stream_logger(self.__config['output']['verbose'],
                          self.__config['output']['quiet'])

        self.__env = Env(initial_env=initial_env,
                         env_prefix=self.__config['app']['env_prefix'])

        self.__operation = Operation(self.__config, self.__env)

    def version(self):
        return BSM_VERSION

    def home(self):
        return BSM_HOME

    def __auto_reload(method):
        def inner(self, *args, **kargs):
            self.__watch_config()
            return method(self, *args, **kargs)

        return inner

    def __watch_config(self):
        if self.__config_entry == self.__config_entry_input:
            return
        self.reload_config()

    def reload_config(self):
        self.__config_entry = copy.deepcopy(self.__config_entry_input)
        self.__config.reset(self.__config_entry)

    @property
    def entry(self):
        return self.__config_entry_input

    def switch(self, scenario):
        self.__config_entry_input['scenario'] = scenario

    @__auto_reload
    def app(self):
        return self.__config['app']['id']

    @__auto_reload
    def config_all(self):
        return self.__config.data

    @__auto_reload
    def config(self, config_type):
        return self.__config.config(config_type)

    @__auto_reload
    def option(self):
        return self.__operation.execute('option')

    @__auto_reload
    def ls_remote(self, list_all=False):
        return self.__operation.execute('ls_remote', list_all)

    @__auto_reload
    def check_build(self):
        return self.__operation.execute('check', 'build')

    @__auto_reload
    def check_runtime(self):
        return self.__operation.execute('check', 'runtime')

    @__auto_reload
    def install_release(self):
        return self.__operation.execute('install-release')

    @__auto_reload
    def install_package(self, category=None, subdir=None, version=None):
        return self.__operation.execute('install-package', category, subdir,
                                        version)

    @__auto_reload
    def install_software(self):
        return self.__operation.execute('install-software')

    @__auto_reload
    def ls(self):
        return self.__operation.execute('ls')

    @__auto_reload
    def use(self):
        self.__operation.execute('use')

    @__auto_reload
    def ls_package(self):
        pass

    @__auto_reload
    def run_release_command(self, command, args):
        # run customized commands defined in release
        # like bsm run pack (only in current version)
        pass

    def apply_env_changes(self):
        return self.__env.apply_changes()

    def env_final(self):
        return self.__env.env_final()

    def default_version(self, shell=None):
        try:
            info = Info()
            default_version = info.default_version
            if default_version:
                config_version = ConfigVersion(config_user, default_version)
                config_release = ConfigRelease(config_version)

                obj = BsmUse(config_user, config_version, config_release)
                set_env, unset_env = obj.run()
            else:
                env = Env()
                env.clean()
                set_env, unset_env = env.env_change()

            for e in unset_env:
                shell.unset_env(e)
            for k, v in set_env.items():
                shell.set_env(k, v)
        except Exception as e:
            _logger.warn('Cat not load default version: {0}'.format(e))
예제 #12
0
class Bsm(object):
    def __init__(self, config_entry={}, initial_env=None):
        self.reload(config_entry=config_entry, initial_env=initial_env)

    def reload(self, **kwargs):
        if 'config_entry' in kwargs:
            self.__config_entry = kwargs['config_entry']

        if 'initial_env' in kwargs:
            if kwargs['initial_env'] is None:
                initial_env = os.environ
            else:
                initial_env = kwargs['initial_env']
        else:
            initial_env = self.__env.env_final()

        self.__config = Config(self.__config_entry, initial_env)

        create_stream_logger(self.__config['output']['verbose'],
                             self.__config['output']['quiet'])

        self.__env = Env(initial_env=initial_env,
                         env_prefix=self.__config['app']['env_prefix'])
        self.__env.load_app(self.__config['app'])

        self.__operation = Operation(self.__config, self.__env)

    def version(self):
        return BSM_VERSION

    def home(self):
        return BSM_HOME

    def app(self):
        return self.__config['app']['id']

    def config_all(self):
        return self.__config.data()

    def config(self, config_type):
        return self.__config.config(config_type)

    def apply_env_changes(self):
        return self.__env.apply_changes()

    def env_final(self):
        return self.__env.env_final()

    def default(self):
        return self.__config['info'].get('default', {})

    def ls_remote(self, list_all=False):
        return self.__operation.execute('ls-remote', list_all)

    def check_missing_install(self):
        return self.__operation.execute('check-missing', 'install')

    def check_missing_runtime(self):
        return self.__operation.execute('check-missing', 'runtime')

    def install_release(self):
        return self.__operation.execute('install-release')

    def install_release_packages(self):
        return self.__operation.execute('install-release-packages')

    def ls_release_version(self):
        return self.__operation.execute('ls-release-version')

    def load_release(self):
        return self.__operation.execute('load-release')

    def load_release_packages(self):
        return self.__operation.execute('load-release-packages')

    def clean(self):
        return self.__operation.execute('clean')

    def exit(self):
        return self.__operation.execute('exit')

    def save_as_default(self):
        return self.__operation.execute('save-as-default')

    def current(self):
        return self.__env.current_release()

    def detect_category(self, directory):
        return self.__operation.execute('detect-category', directory)

    def run_release_command(self, command):
        return self.__operation.execute('run-release-command', command)

    def find_package(self,
                     package,
                     category=None,
                     subdir=None,
                     version=None,
                     from_install=False):
        return self.__operation.execute('find-package', package, category,
                                        subdir, version, from_install)

    def match_install_package(self,
                              package,
                              category=None,
                              subdir=None,
                              version=None,
                              category_origin=None,
                              subdir_origin=None,
                              version_origin=None):
        return self.__operation.execute('match-install-package', package,
                                        category, subdir, version,
                                        category_origin, subdir_origin,
                                        version_origin)

    def package_path(self, package, category, subdir, version):
        return self.__operation.execute('package-path', package, category,
                                        subdir, version)

    def package_config(self, package, category, subdir, version):
        return self.__operation.execute('package-config', package, category,
                                        subdir, version)

    def package_exist(self, package, category, subdir, version):
        return self.__operation.execute('package-exist', package, category,
                                        subdir, version)

    def install_package_config(self,
                               package,
                               category,
                               subdir,
                               version,
                               category_origin,
                               subdir_origin,
                               version_origin,
                               from_install=False):
        return self.__operation.execute('install-package-config', package,
                                        category, subdir, version,
                                        category_origin, subdir_origin,
                                        version_origin, from_install)

    def install_package(self, package, category, subdir, version):
        return self.__operation.execute('install-package', package, category,
                                        subdir, version)

    def remove_package(self, package, category, subdir, version):
        return self.__operation.execute('remove-package', package, category,
                                        subdir, version)

    def detect_package_param(self, package_dir):
        return self.__operation.execute('detect-package-param', package_dir)

    def detect_package(self, directory):
        return self.__operation.execute('detect-package', directory)

    def check_conflict_package(self, directory):
        return self.__operation.execute('check-conflict-package', directory)

    def create_package_config(self, package, category, subdir, version):
        return self.__operation.execute('create-package-config', package,
                                        category, subdir, version)

    def build_package(self, package, category, subdir, version, rebuild=False):
        return self.__operation.execute('build-package', package, category,
                                        subdir, version, rebuild)

    def clean_package(self, package):
        return self.__operation.execute('clean-package', package)

    def load_package(self, package, category, subdir, version):
        return self.__operation.execute('load-package', package, category,
                                        subdir, version)

    def ls_all_package(self):
        return self.__operation.execute('ls-all-package')

    def ls_active_package(self):
        return self.__operation.execute('ls-active-package')
예제 #13
0
파일: env.py 프로젝트: bsmsoft/bsm
    def __init__(self, initial_env, env_prefix):
        super(Env, self).__init__()

        env = BsmEnv(initial_env, env_prefix)
        self.update(env.current_release())
예제 #14
0
    def execute(self, config, config_version):
        env = Env()

        for name, info in env.package_info.items():
            click.echo('{name} @ {version} : {category} - {path}'.format(
                name=name, **info))
예제 #15
0
class Executor(object):
    def __init__(self, config_user, config_version, config_release, step_info):
        self.__config_user = config_user
        self.__config_version = config_version
        self.__config_release = config_release
        self.__step_info = step_info

        # Create independent env for installation
        self.__env = Env()
        self.__env.clean()

        self.__pkg_mgr = PackageManager(config_version, config_release)

    def param(self, vertex):
        pkg, action, sub_action = vertex

        par = {}

        par['package'] = pkg
        par['action'] = action
        par['sub_action'] = sub_action

        step = self.__step_info.package_step(pkg, action, sub_action)
        par['action_name'] = step.get('action')
        par['action_param'] = step.get('param')

        par['log_file'] = os.path.join(
            self.__pkg_mgr.package_info(pkg)['dir']['log'],
            '{0}_{1}_{2}.log'.format(pkg, action, sub_action))
        par['env'] = copy.deepcopy(self.__env.env_final())

        par['config_user'] = copy.deepcopy(self.__config_user)
        par['def_dir'] = self.__config_version.def_dir
        par['pkg_info'] = copy.deepcopy(self.__pkg_mgr.package_info(pkg))
        par['pkg_dir_list'] = copy.deepcopy(self.__pkg_mgr.package_dir_list())

        return par

    # Do NOT access or modify any variables outside this function (global and member variables)
    def execute(self, param):
        pkg = param['package']
        action = param['action']
        sub_action = param['sub_action']

        if sub_action == 0:
            action_full_name = '{0} - {1}'.format(pkg, action)
        else:
            action_full_name = '{0} - {1} - {2}'.format(
                pkg, action, sub_action)

        result = {}

        result['start'] = datetime.datetime.utcnow()

        safe_mkdir(param['pkg_info']['dir']['log'])

        try:
            result_action = run_handler('', 'install', param['action_name'],
                                        param)
        except Exception as e:
            _logger.critical('"{0}" install handler error: {1}'.format(
                action_full_name, e))
            if param['config_user']['verbose']:
                _logger.critical('\n{0}'.format(traceback.format_exc()))
            raise

        result['success'] = False
        if isinstance(result_action, bool) and result_action:
            result['success'] = True
        if isinstance(
                result_action, dict
        ) and 'success' in result_action and result_action['success']:
            result['success'] = True

        if not result['success']:
            if isinstance(result_action, dict) and 'message' in result_action:
                _logger.error('"{0}" execution error: {1}'.format(
                    action_full_name, result_action['message']))
            _logger.critical('"{0}" execution error. Find log in "{1}"'.format(
                action_full_name, param['log_file']))
            raise InstallExecutorError(
                '"{0}" execution error'.format(action_full_name))

        result['action'] = result_action
        result['end'] = datetime.datetime.utcnow()

        return result

    def report_start(self, vertice):
        pass

    def report_finish(self, vertice_result):
        for vertex, result in vertice_result:
            pkg, action, sub_action = vertex

            if isinstance(result['action'], dict) and 'env_package' in result[
                    'action'] and result['action']['env_package']:
                path_def = self.__config_release.config['setting'].get(
                    'path_def', {})
                pkg_info = self.__pkg_mgr.package_info(pkg)
                self.__env.set_package(path_def, pkg_info)

            if isinstance(
                    result['action'],
                    dict) and 'save_release_status' in result[
                        'action'] and result['action']['save_release_status']:
                self.__pkg_mgr.save_release_status(pkg, result['end'])

            if result['success']:
                _logger.info(' > {0} {1} {2} finished'.format(
                    pkg, action, sub_action))
                if self.__step_info.is_last_sub_action(pkg, action,
                                                       sub_action):
                    self.__pkg_mgr.save_action_status(pkg, action,
                                                      result['start'],
                                                      result['end'])

    def report_running(self, vertice):
        if not vertice:
            return

        running_vertice = []
        for v in vertice:
            if v[2] == 0:
                action_full_name = '{0}({1})'
            else:
                action_full_name = '{0}({1}.{2})'
            running_vertice.append(action_full_name.format(*v))
        _logger.info('Running: ' + ', '.join(running_vertice))

    def deliver(self, vertex, result):
        pass

    def abort(self, vertice):
        pass