Example #1
0
def test_pkg_sort_by_deps_not_dict_should_fail():
    pass

    # TODO check not implemented
    with pytest.raises(TypeError):
        utils.pkg_sort_by_deps(None)

    # TODO empty dict should return empty list
    with pytest.raises(InstallationError):
        utils.pkg_sort_by_deps({})
Example #2
0
    def execute(self):
        """Execute command."""
        pkg_manifests = (self.config.inst_storage.get_pkgactive(
            PackageManifest.load))
        packages_bulk = {
            m.pkg_id.pkg_name: Package(manifest=m)
            for m in pkg_manifests
        }

        for package in cr_utl.pkg_sort_by_deps(packages_bulk):
            pkg_id = package.manifest.pkg_id
            mheading = f'{self.msg_src}: Execute: {pkg_id.pkg_name}'

            if package.svc_manager:
                svc_name = package.svc_manager.svc_name
                LOG.debug(f'{mheading}: Start service: {svc_name}: ...')

                try:
                    self.service_start(package.svc_manager)
                except (svcm_exc.ServiceError,
                        svcm_exc.ServiceManagerError) as e:
                    LOG.error(f'{mheading}: Start service:'
                              f' {type(e).__name__}: {e}')
                else:
                    LOG.debug(f'{mheading}: Start service: {svc_name}: OK')
            else:
                LOG.debug(f'{mheading}: Start service: NOP')
Example #3
0
def test_pkg_sort_order_should_be_correct():
    sorted = utils.pkg_sort_by_deps(packages={
        'vcredist': 'a',
        'nssm': 'b',
        'bootstrap': 'c'})

    assert sorted == ['a', 'b', 'c']
Example #4
0
    def execute(self):
        """Execute command."""
        # TODO: Implement DC/OS installation state detection here (alike how
        #       it's done in CmdSetup.execute() or CmdSetup.execute()) to
        #       allow attempts to start services only if
        #       istate == ISTATE.INSTALLED:

        pkg_manifests = (self.config.inst_storage.get_pkgactive(
            PackageManifest.load))
        packages_bulk = {
            m.pkg_id.pkg_name: Package(manifest=m)
            for m in pkg_manifests
        }

        for package in cr_utl.pkg_sort_by_deps(packages_bulk):
            pkg_id = package.manifest.pkg_id
            mheading = f'{self.msg_src}: Execute: {pkg_id.pkg_name}'

            # TODO: This part should be replaced with
            #       Package.handle_svc_start() method
            if package.svc_manager:
                svc_name = package.svc_manager.svc_name
                LOG.debug(f'{mheading}: Start service: {svc_name}: ...')

                try:
                    self.service_start(package.svc_manager)
                except (svcm_exc.ServiceError,
                        svcm_exc.ServiceManagerError) as e:
                    LOG.error(f'{mheading}: Start service:'
                              f' {type(e).__name__}: {e}')
                else:
                    LOG.debug(f'{mheading}: Start service: {svc_name}: OK')
            else:
                LOG.debug(f'{mheading}: Start service: NOP')
Example #5
0
    def execute(self):
        """Execute command."""
        msg_src = self.__class__.__name__
        LOG.debug(f'{msg_src}: Execute: Target:'
                  f' {self.cmd_opts.get(CLI_CMDOPT.CMD_TARGET)}')

        if self.cmd_opts.get(CLI_CMDOPT.CMD_TARGET) == CLI_CMDTARGET.STORAGE:
            # (Re)build/repair the installation storage structure.
            self.config.inst_storage.construct(
                clean=self.cmd_opts.get(CLI_CMDOPT.INST_CLEAN))
        elif self.cmd_opts.get(CLI_CMDOPT.CMD_TARGET) == CLI_CMDTARGET.PKGALL:
            dstor_root_url = self.config.cluster_conf.get(
                'distribution-storage', {}).get('rooturl', '')
            dstor_pkgrepo_path = self.config.cluster_conf.get(
                'distribution-storage', {}).get('pkgrepopath', '')

            # Add packages to the local package repository and initialize their
            # manager objects
            packages_bulk = []
            for item in self.config.ref_pkg_list:
                pkg_id = PackageId(pkg_id=item)

                try:
                    self.config.inst_storage.add_package(
                        pkg_id=pkg_id,
                        dstor_root_url=dstor_root_url,
                        dstor_pkgrepo_path=dstor_pkgrepo_path)
                except cr_exc.RCError as e:
                    err_msg = (f'{msg_src}: Execute: Add package to local'
                               f' repository: {pkg_id.pkg_id}: {e}')
                    raise cr_exc.SetupCommandError(err_msg) from e

                try:
                    package = Package(
                        pkg_id=pkg_id,
                        istor_nodes=self.config.inst_storage.istor_nodes,
                        cluster_conf=self.config.cluster_conf)
                except cr_exc.RCError as e:
                    err_msg = (f'{msg_src}: Execute: Initialize package:'
                               f' {pkg_id.pkg_id}: {e}')
                    raise cr_exc.SetupCommandError(err_msg) from e

                packages_bulk.append(package)

            # Finalize package setup procedures taking package mutual
            # dependencies into account.
            for package in cr_utl.pkg_sort_by_deps(packages_bulk):
                self._handle_pkg_inst_extras(package)
                self._handle_pkg_svc_setup(package)

                try:
                    package.manifest.save()
                except cr_exc.RCError as e:
                    err_msg = (f'{msg_src}: Execute: Register package:'
                               f' {package.manifest.pkg_id.pkg_id}: {e}')
                    raise cr_exc.SetupCommandError(err_msg)

                LOG.info(f'{msg_src}: Setup package:'
                         f' {package.manifest.pkg_id.pkg_id}: OK')
Example #6
0
    def execute(self):
        """Execute command."""
        msg_src = self.__class__.__name__

        pkg_manifests = (self.config.inst_storage.get_pkgactive(
            PackageManifest.load))
        packages_bulk = [Package(manifest=m) for m in pkg_manifests]

        for package in cr_utl.pkg_sort_by_deps(packages_bulk):
            pkg_id = package.manifest.pkg_id
            LOG.debug(f'{msg_src}: Execute: Package: {package.manifest.body}')

            if package.manifest.pkg_svccfg:
                try:
                    ret_code, stdout, stderr = package.svc_manager.status()
                except svcm_exc.ServiceManagerCommandError as e:
                    err_msg = (f'Execute: Get initial service status:'
                               f' {pkg_id.pkg_name}: {e}')
                    raise cr_exc.StartCommandError(err_msg) from e
                else:
                    LOG.debug(f'{msg_src}: Execute: Get initial service'
                              f' status: {pkg_id.pkg_name}: stdout[{stdout}]'
                              f' stderr[{stderr}]')
                    svc_status = str(stdout).strip().rstrip('\n')

                if svc_status == SVC_STATUS.STOPPED:
                    try:
                        package.svc_manager.start()
                    except svcm_exc.ServiceManagerCommandError as e:
                        err_msg = (f'Execute: Start service:'
                                   f' {pkg_id.pkg_name}: {e}')
                        raise cr_exc.StartCommandError(err_msg) from e

                    try:
                        ret_code, stdout, stderr = package.svc_manager.status()
                        LOG.debug(f'{msg_src}: Execute: Get final service'
                                  f' status: {pkg_id.pkg_name}:'
                                  f' stdout[{stdout}] stderr[{stderr}]')
                        svc_status = str(stdout).strip().rstrip('\n')

                        if svc_status != SVC_STATUS.RUNNING:
                            err_msg = (f'Execute: Service failed to start:'
                                       f' {pkg_id.pkg_name}: {svc_status}')
                            raise cr_exc.StartCommandError(err_msg)
                    except svcm_exc.ServiceManagerCommandError as e:
                        err_msg = (f'Execute: Get final service status:'
                                   f' {pkg_id.pkg_name}: {e}')
                        raise cr_exc.StartCommandError(err_msg) from e
                elif svc_status == SVC_STATUS.RUNNING:
                    LOG.warning(f'{msg_src}: Execute: Service is already'
                                f' running: {pkg_id.pkg_name}')
                else:
                    err_msg = (f'Execute: Invalid service status:'
                               f' {pkg_id.pkg_name}: {svc_status}')
                    raise cr_exc.StartCommandError(err_msg)
Example #7
0
    def execute(self):
        """Execute command."""
        state = self.state.get_state()
        if state is not None and state != STATE_NEEDS_START:
            raise cm_exc.InstallationError(
                f'Cannot start DC/OS: detected state {state}'
            )
        test_file = self.config.inst_storage.root_dpath / 'bin' / 'mesos-agent.exe'
        if not test_file.exists():
            raise cm_exc.InstallationError(
                f'Cannot start DC/OS: no file at {test_file}'
            )

        pkg_manifests = (
            self.config.inst_storage.get_pkgactive(PackageManifest.load)
        )
        packages_bulk = {
            m.pkg_id.pkg_name: Package(manifest=m) for m in pkg_manifests
        }

        for package in cr_utl.pkg_sort_by_deps(packages_bulk):
            pkg_id = package.manifest.pkg_id
            mheading = f'{self.msg_src}: Execute: {pkg_id.pkg_name}'

            # TODO: This part should be replaced with
            #       Package.handle_svc_start() method
            if package.svc_manager:
                svc_name = package.svc_manager.svc_name
                LOG.debug(f'{mheading}: Start service: {svc_name}: ...')

                try:
                    self.service_start(package.svc_manager)
                except (svcm_exc.ServiceError,
                        svcm_exc.ServiceManagerError) as e:
                    LOG.error(f'{mheading}: Start service:'
                              f' {type(e).__name__}: {e}')
                else:
                    LOG.debug(f'{mheading}: Start service: {svc_name}: OK')
            else:
                LOG.debug(f'{mheading}: Start service: NOP')

        self.state.unset_state()
Example #8
0
    def _handle_teardown(self):
        """Teardown the currently installed DC/OS."""
        mheading = f'{self.msg_src}: Execute'
        pkg_manifests = (
            self.config.inst_storage.get_pkgactive(PackageManifest.load)
        )
        packages_bulk = {
            m.pkg_id.pkg_name: Package(manifest=m) for m in pkg_manifests
        }

        iroot_dpath = self.config.inst_storage.root_dpath
        itmp_dpath = self.config.inst_storage.tmp_dpath
        pkgactive_old_dpath = itmp_dpath.joinpath(
            f'{storage.DCOS_PKGACTIVE_DPATH_DFT}.old'
        )
        sh_conf_dname = storage.DCOS_INST_CFG_DPATH_DFT
        sh_exec_dname = storage.DCOS_INST_BIN_DPATH_DFT
        sh_lib__dname = storage.DCOS_INST_LIB_DPATH_DFT

        # Teardown installed packages
        for package in cr_utl.pkg_sort_by_deps(packages_bulk):
            package.handle_svc_wipe(mheading)
            package.handle_uninst_extras(mheading)
            package.save_manifest(mheading, pkgactive_old_dpath)
            package.delete_manifest(mheading)

        # Remove/preserve shared directories
        for dname in sh_conf_dname, sh_exec_dname, sh_lib__dname:
            active_dpath = iroot_dpath.joinpath(dname)
            preserve_dpath = itmp_dpath.joinpath(f'{dname}.old')
            try:
                cm_utl.rmdir(str(preserve_dpath), recursive=True)
                active_dpath.rename(preserve_dpath)
            except (OSError, RuntimeError) as e:
                err_msg = (f'{mheading}: Preserve shared directory:'
                           f' {active_dpath}: {type(e).__name__}: {e}')
                raise cr_exc.RCError(err_msg) from e

            LOG.debug(f'{mheading}: Preserve shared directory: {active_dpath}:'
                      f' {preserve_dpath}')
Example #9
0
    def execute(self):
        """Execute command."""
        LOG.debug(f'{self.msg_src}: Execute: Target:'
                  f' {self.cmd_opts.get(CLI_CMDOPT.CMD_TARGET)}')

        if self.cmd_opts.get(CLI_CMDOPT.CMD_TARGET) == CLI_CMDTARGET.STORAGE:
            # (Re)build/repair the installation storage structure.
            self.config.inst_storage.construct(
                clean=self.cmd_opts.get(CLI_CMDOPT.INST_CLEAN))
        elif self.cmd_opts.get(CLI_CMDOPT.CMD_TARGET) == CLI_CMDTARGET.PKGALL:
            dstor_root_url = self.config.cluster_conf.get(
                'distribution-storage', {}).get('rooturl', '')
            dstor_pkgrepo_path = self.config.cluster_conf.get(
                'distribution-storage', {}).get('pkgrepopath', '')

            # Add packages to the local package repository and initialize their
            # manager objects
            packages_bulk = {}

            for item in self.config.ref_pkg_list:
                pkg_id = PackageId(pkg_id=item)

                try:
                    self.config.inst_storage.add_package(
                        pkg_id=pkg_id,
                        dstor_root_url=dstor_root_url,
                        dstor_pkgrepo_path=dstor_pkgrepo_path)
                except cr_exc.RCError as e:
                    err_msg = (f'{self.msg_src}: Execute: Add package to local'
                               f' repository: {pkg_id.pkg_id}: {e}')
                    raise cr_exc.SetupCommandError(err_msg) from e

                try:
                    package = Package(
                        pkg_id=pkg_id,
                        istor_nodes=self.config.inst_storage.istor_nodes,
                        cluster_conf=self.config.cluster_conf,
                        extra_context=self.config.dcos_conf.get('values'))
                except cr_exc.RCError as e:
                    err_msg = (f'{self.msg_src}: Execute: Initialize package:'
                               f' {pkg_id.pkg_id}: {e}')
                    raise cr_exc.SetupCommandError(err_msg) from e

                packages_bulk[pkg_id.pkg_name] = package

            # Finalize package setup procedures taking package mutual
            # dependencies into account.

            packages_sorted_by_deps = cr_utl.pkg_sort_by_deps(packages_bulk)

            # Prepare base per package configuration objects
            for package in packages_sorted_by_deps:
                self._handle_pkg_dir_setup(package)
                self._handle_pkg_cfg_setup(package)

            # Deploy DC/OS aggregated configuration object
            self._deploy_dcos_conf()

            # Run per package extra installation helpers, setup services and
            # save manifests
            for package in packages_sorted_by_deps:
                self._handle_pkg_inst_extras(package)
                self._handle_pkg_svc_setup(package)

                try:
                    package.manifest.save()
                except cr_exc.RCError as e:
                    err_msg = (f'{self.msg_src}: Execute: Register package:'
                               f' {package.manifest.pkg_id.pkg_id}: {e}')
                    raise cr_exc.SetupCommandError(err_msg)

                LOG.info(f'{self.msg_src}: Setup package:'
                         f' {package.manifest.pkg_id.pkg_id}: OK')
Example #10
0
    def _handle_clean_setup(self):
        """Perform all the steps on DC/OS installation remaining after the
        preparation stage is done (the CmdUpgrade._handle_upgrade_pre()).
        """
        # TODO: This code duplicates the CmdSetup._handle_cmdtarget_pkgall()
        #       stuff and so should be made standalone to be reused in both
        #       classes avoiding massive code duplication.
        dstor_root_url = self.config.cluster_conf.get('distribution-storage',
                                                      {}).get('rooturl', '')
        dstor_pkgrepo_path = self.config.cluster_conf.get(
            'distribution-storage', {}).get('pkgrepopath', '')

        # Deploy DC/OS aggregated configuration object
        self._deploy_dcos_conf()
        result = subprocess.run(
            ('powershell', '-executionpolicy', 'Bypass', '-File',
             'C:\\d2iq\\dcos\\bin\\detect_ip.ps1'),
            stdout=subprocess.PIPE,
            check=True)
        local_priv_ipaddr = result.stdout.decode('ascii').strip()

        self.config.dcos_conf['values']['privateipaddr'] = local_priv_ipaddr

        # Add packages to the local package repository and initialize their
        # manager objects
        packages_bulk = {}

        for item in self.config.ref_pkg_list:
            pkg_id = PackageId(pkg_id=item)

            try:
                self.config.inst_storage.add_package(
                    pkg_id=pkg_id,
                    dstor_root_url=dstor_root_url,
                    dstor_pkgrepo_path=dstor_pkgrepo_path)
            except cr_exc.RCError as e:
                err_msg = (f'{self.msg_src}: Execute: Add package to local'
                           f' repository: {pkg_id.pkg_id}: {e}')
                raise cr_exc.SetupCommandError(err_msg) from e

            try:
                package = Package(
                    pkg_id=pkg_id,
                    istor_nodes=self.config.inst_storage.istor_nodes,
                    cluster_conf=self.config.cluster_conf,
                    extra_context=self.config.dcos_conf.get('values'))
            except cr_exc.RCError as e:
                err_msg = (f'{self.msg_src}: Execute: Initialize package:'
                           f' {pkg_id.pkg_id}: {e}')
                raise cr_exc.SetupCommandError(err_msg) from e

            packages_bulk[pkg_id.pkg_name] = package

        # Finalize package setup procedures taking package mutual
        # dependencies into account.

        packages_sorted_by_deps = cr_utl.pkg_sort_by_deps(packages_bulk)

        # Prepare base per package configuration objects
        for package in packages_sorted_by_deps:
            # TODO: This method moves parts of individual packages which should
            #       be shared with other packages to DC/OS installation shared
            #       directories (<inst_root>\[bin|etc|lib]). It should be
            #       redesigned to deal with only required parts of packages and
            #       not populating shared DC/OS installation directories with
            #       unnecessary stuff.
            self._handle_pkg_dir_setup(package)
            # TODO: This should be replaced with Package.handle_config_setup()
            #       method to avoid code duplication in command manager classes
            #       CmdSetup and CmdUpgrade
            self._handle_pkg_cfg_setup(package)

        # Run per package extra installation helpers, setup services and
        # save manifests
        for package in packages_sorted_by_deps:
            # TODO: This should be replaced with Package.handle_inst_extras()
            #       method to avoid code duplication in command manager classes
            #       CmdSetup and CmdUpgrade
            self._handle_pkg_inst_extras(package)
            # TODO: This should be replaced with Package.handle_svc_setup()
            #       method to avoid code duplication in command manager classes
            #       CmdSetup and CmdUpgrade
            self._handle_pkg_svc_setup(package)

            # TODO: This part should be replaced with Package.save_manifest()
            #       method to avoid code duplication in command manager classes
            #       CmdSetup and CmdUpgrade
            try:
                package.manifest.save()
            except cr_exc.RCError as e:
                err_msg = (f'{self.msg_src}: Execute: Register package:'
                           f' {package.manifest.pkg_id.pkg_id}: {e}')
                raise cr_exc.SetupCommandError(err_msg)

            LOG.info(f'{self.msg_src}: Setup package:'
                     f' {package.manifest.pkg_id.pkg_id}: OK')