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')
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')
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')
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)
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()
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}')
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')
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')
def test_manifest_should_not_be_changed_in_init(self, *args): """Check Package constructor manifest processing.""" manifest = mock.Mock(spec=PackageManifest) manifest.pkg_svccfg = {} pack = Package(PackageId(), manifest=manifest) assert pack.manifest == manifest