def abort_upgrade(con_ssh=None, timeout=60, fail_ok=False): """ Aborts upgrade Args: con_ssh (SSHClient): timeout (int) fail_ok (bool): Returns (tuple): (0, dict/list) (1, <stderr>) # cli returns stderr, applicable if fail_ok is true """ if con_ssh is None: con_ssh = ControllerClient.get_active_controller() cmd = "source /etc/nova/openrc; system upgrade-abort" con_ssh.send(cmd) end_time = time.time() + timeout rc = 1 while time.time() < end_time: index = con_ssh.expect([con_ssh.prompt, Prompt.YES_N_PROMPT], timeout=timeout) if index == 1: con_ssh.send('yes') index = con_ssh.expect([con_ssh.prompt, Prompt.CONFIRM_PROMPT], timeout=timeout) if index == 1: con_ssh.send('abort') index = con_ssh.expect([con_ssh.prompt, Prompt.CONFIRM_PROMPT], timeout=timeout) if index == 0: rc = con_ssh.exec_cmd("echo $?")[0] con_ssh.flush() break if rc != 0: err_msg = "CLI system upgrade-abort rejected" LOG.warning(err_msg) if fail_ok: return 1, err_msg else: raise exceptions.CLIRejected(err_msg) table_ = system_upgrade_show()[1] state = table_parser.get_value_two_col_table(table_, "state") if "aborting" in state: return 0, "Upgrade aborting" else: err_msg = "Upgrade abort failed" if fail_ok: LOG.warn(err_msg) return 1, err_msg else: raise exceptions.CLIRejected(err_msg)
def simplex_host_upgrade(con_ssh=None, fail_ok=False): """ Simplex host_upgrade is to handle simplex host-upgrade cli. Args: con_ssh (SSHClient): fail_ok (bool): Returns (tuple): (0, dict/list) (1, <stderr>) # cli returns stderr, applicable if fail_ok is true """ if con_ssh is None: con_ssh = ControllerClient.get_active_controller() cmd = "source /etc/nova/openrc; system host-upgrade controller-0" con_ssh.send(cmd) index = con_ssh.expect([con_ssh.prompt, Prompt.YES_N_PROMPT]) con_ssh.send('yes') if index == 0: err_msg = "CLI system host upgrade rejected" LOG.warning(err_msg) if fail_ok: return 1, err_msg else: raise exceptions.CLIRejected(err_msg) else: return 0, "host upgrade success"
def get_swift_containers(con_ssh=None, fail_ok=False, auth_info=Tenant.get('admin')): rc, out = cli.swift('list', ssh_client=con_ssh, fail_ok=True, auth_info=auth_info) if rc == 0: if out: return 0, out.split('\n'), None else: return 0, [], None else: msg = "Fail to list swift containers: {} ".format(out) if fail_ok: return rc, [], msg raise exceptions.CLIRejected(msg)
def system_upgrade_start(con_ssh=None, force=False, fail_ok=False): """ Starts upgrade Args: con_ssh: force: fail_ok: Returns (tuple): (0, output) (1, <stderr>) : "if fail_ok is true # cli returns stderr. (2, <stderr>) : "applicable only if fail_ok is true. upgrade-start rejected: An upgrade is already in progress." """ if force: rc, output = cli.system("upgrade-start", positional_args='--force', ssh_client=con_ssh, fail_ok=True) else: rc, output = cli.system("upgrade-start", ssh_client=con_ssh, fail_ok=True) if rc == 0: LOG.info("system upgrade-start ran successfully.") return 0, output else: if "An upgrade is already in progress" in output: # upgrade already in progress LOG.warning("Upgrade is already in progress. No need to start") if fail_ok: return 2, output else: raise exceptions.CLIRejected(output) else: err_msg = "CLI system command failed: {}".format(output) LOG.warning(err_msg) if fail_ok: return 1, output else: raise exceptions.CLIRejected(err_msg)
def import_load(load_path, timeout=120, con_ssh=None, fail_ok=False, upgrade_ver=None): # TODO: Need to support remote_cli. i.e., no hardcoded load_path, etc home_dir = HostLinuxUser.get_home() if upgrade_ver >= '17.07': load_path = '{}/bootimage.sig'.format(HostLinuxUser.get_home()) rc, output = cli.system('load-import {}/bootimage.iso'.format(home_dir), load_path, ssh_client=con_ssh, fail_ok=True) else: rc, output = cli.system('load-import', load_path, ssh_client=con_ssh, fail_ok=True) if rc == 0: table_ = table_parser.table(output) id_ = (table_parser.get_values(table_, "Value", Property='id')).pop() soft_ver = (table_parser.get_values(table_, "Value", Property='software_version')).pop() LOG.info('Waiting to finish importing load id {} version {}'.format( id_, soft_ver)) end_time = time.time() + timeout while time.time() < end_time: state = get_imported_load_state(id_, load_version=soft_ver, con_ssh=con_ssh) LOG.info("Import state {}".format(state)) if "imported" in state: LOG.info("Importing load {} is completed".format(soft_ver)) return [rc, id_, soft_ver] time.sleep(3) err_msg = "Timeout waiting to complete importing load {}".format(soft_ver) LOG.warning(err_msg) if fail_ok: return [1, err_msg] else: raise exceptions.TimeoutException(err_msg) else: err_msg = "CLI command rejected: {}".format(output) if fail_ok: return [1, err_msg] else: raise exceptions.CLIRejected(err_msg)
def activate_upgrade(con_ssh=None, fail_ok=False): """ Activates upgrade Args: con_ssh (SSHClient): fail_ok (bool): Returns (tuple): (0, dict/list) - success (1, <stderr>) # cli returns stderr, applicable if fail_ok is true """ rc, output = cli.system('upgrade-activate', ssh_client=con_ssh, fail_ok=True) if rc != 0: err_msg = "CLI system upgrade-activate failed: {}".format(output) LOG.warning(err_msg) if fail_ok: return rc, output else: raise exceptions.CLIRejected(err_msg) if not system_helper.wait_for_alarm_gone("250.001", con_ssh=con_ssh, timeout=900, check_interval=60, fail_ok=True): alarms = system_helper.get_alarms(alarm_id="250.001") err_msg = "After activating upgrade alarms are not cleared : {}".format(alarms) LOG.warning(err_msg) if fail_ok: return 1, err_msg else: raise exceptions.HostError(err_msg) if not wait_for_upgrade_activate_complete(fail_ok=True): err_msg = "Upgrade activate failed" LOG.warning(err_msg) if fail_ok: return 1, err_msg else: raise exceptions.HostError(err_msg) LOG.info("Upgrade activation complete") return 0, None
def complete_upgrade(con_ssh=None, fail_ok=False): """ Completes upgrade Args: con_ssh (SSHClient): fail_ok (bool): Returns (tuple): (0, dict/list) (1, <stderr>) # cli returns stderr, applicable if fail_ok is true """ rc, output = cli.system('upgrade-complete', ssh_client=con_ssh, fail_ok=True) if rc != 0: err_msg = "CLI system upgrade-complete rejected: {}".format(output) LOG.warning(err_msg) if fail_ok: return 1, output else: raise exceptions.CLIRejected(err_msg) return 0, "Upgrade complete"
def exec_cli(cmd, sub_cmd, positional_args='', client=None, flags='', fail_ok=False, cli_dir='', auth_info=None, source_openrc=None, timeout=CLI_TIMEOUT): """ Args: cmd: such as 'neutron' sub_cmd: such as 'net-show' client: SSHClient, TelnetClient or LocalHostClient positional_args: string or list. Single arg examples: 'arg0' or ['arg0'] Multiple args string example: 'arg1 arg2' Multiple args list example: ['arg1','arg2'] flags: string or list. Single arg examples: 'arg0 value0' or ['arg0 value'] Multiple args string example: 'arg1 value1 arg2 value2 arg3' Multiple args list example: ['arg1 value1','arg2 value2', 'arg3'] auth_info: (dict) authorization information to run cli commands. source_openrc (None|bool): In general this should NOT be set unless necessary. fail_ok: cli_dir: timeout: Returns: if command executed successfully: return command_output if command failed to execute such as authentication failure: if fail_ok: return exit_code, command_output if not fail_ok: raise exception """ use_telnet = True if isinstance(client, TelnetClient) else False # Determine region and auth_url raw_cmd = cmd.strip().split()[0] is_dc = ProjVar.get_var('IS_DC') platform_cmds = ('system', 'fm') if auth_info is None: auth_info = Tenant.get_primary() platform = True if auth_info.get('platform') else False if not platform and ProjVar.get_var('OPENSTACK_DEPLOYED') is False: skip('stx-openstack application is not applied.') region = auth_info.get('region') dc_region = region if region and is_dc else None default_region_and_url = Tenant.get_region_and_url(platform=platform, dc_region=dc_region) region = region if region else default_region_and_url['region'] auth_url = auth_info.get('auth_url', default_region_and_url['auth_url']) if is_dc: # Set proper region when cmd is against DC central cloud. This is # needed due to the same auth_info may be # passed to different keywords that require different region if region in ('RegionOne', 'SystemController'): region = 'RegionOne' if raw_cmd in platform_cmds else \ 'SystemController' # # Reset auth_url if cmd is against DC central cloud RegionOne # containerized services. This is needed due to # # the default auth_url for central controller RegionOne is platform # auth_url # if region == 'RegionOne' and not platform: # auth_url = default_region_and_url['auth_url'] positional_args = __convert_args(positional_args) flags = __convert_args(flags) if not use_telnet and not client: if is_dc: # This may not exist if cli cmd used before DC vars are initialized client = ControllerClient.get_active_controller(name=region, fail_ok=True) if not client: client = ControllerClient.get_active_controller() if source_openrc is None: source_openrc = ProjVar.get_var('SOURCE_OPENRC') if source_openrc: source_file = _get_rc_path(user=auth_info['user'], platform=platform) if use_telnet: cmd = 'source {}; {}'.format(source_file, cmd) else: source_openrc_file(ssh_client=client, auth_info=auth_info, rc_file=source_file, fail_ok=fail_ok) flags = '' elif auth_info: # auth params auth_args = ( "--os-username '{}' --os-password '{}' --os-project-name {} " "--os-auth-url {} " "--os-user-domain-name Default --os-project-domain-name Default". format(auth_info['user'], auth_info['password'], auth_info['tenant'], auth_url)) flags = '{} {}'.format(auth_args.strip(), flags.strip()) # internal URL handling if raw_cmd in ('openstack', 'sw-manager'): flags += ' --os-interface internal' else: flags += ' --os-endpoint-type internalURL' # region handling if raw_cmd != 'dcmanager': if raw_cmd == 'cinder': flags += ' --os_region_name {}'.format(region) else: flags += ' --os-region-name {}'.format(region) complete_cmd = ' '.join( [os.path.join(cli_dir, cmd), flags.strip(), sub_cmd, positional_args]).strip() # workaround for dcmanager cmd not supporting --os-project-name if complete_cmd.startswith('dcmanager'): complete_cmd = complete_cmd.replace('--os-project-name', '--os-tenant-name') kwargs = {'searchwindowsize': 100} if not use_telnet else {} exit_code, cmd_output = client.exec_cmd(complete_cmd, expect_timeout=timeout, **kwargs) if exit_code == 0: return 0, cmd_output if fail_ok and exit_code in [1, 2]: return 1, cmd_output raise exceptions.CLIRejected( "CLI '{}' failed to execute. Output: {}".format( complete_cmd, cmd_output))