def fake_utils_execute(*cmd, **kwargs): if 'if=/dev/zero' in cmd and 'iflag=direct' in cmd: raise processutils.ProcessExecutionError() if 'of=/dev/null' in cmd and 'oflag=direct' in cmd: raise processutils.ProcessExecutionError() if 'iflag=direct' in cmd and 'oflag=direct' in cmd: raise exception.InvalidInput(message='iflag/oflag error')
def exec_cmd(self, cmd): """Simulates the execution of dsmc, rm, and ln commands.""" if cmd[0] == 'dsmc': out, err, ret = self._exec_dsmc_cmd(cmd) elif cmd[0] == 'ln': dest = cmd[2] out = '' if dest in self._hardlinks: err = ('ln: failed to create hard link `%s\': ' 'File exists' % dest) ret = 1 else: self._hardlinks.append(dest) err = '' ret = 0 elif cmd[0] == 'rm': dest = cmd[2] out = '' if dest not in self._hardlinks: err = ('rm: cannot remove `%s\': No such file or ' 'directory' % dest) ret = 1 else: index = self._hardlinks.index(dest) del self._hardlinks[index] err = '' ret = 0 else: raise putils.ProcessExecutionError(exit_code=1, stdout='', stderr='Unsupported command', cmd=' '.join(cmd)) return (out, err, ret)
def test_mount_quobyte_should_reraise_already_mounted_error(self): """Same as test_mount_quobyte_should_suppress_and_log_already_mounted_error but with ensure=False. """ with contextlib.nested( mock.patch.object(self._driver, '_execute'), mock.patch('cinder.volume.drivers.quobyte.QuobyteDriver' '.read_proc_mount')) as (mock_execute, mock_open): mock_open.return_value = StringIO.StringIO() mock_execute.side_effect = [ None, # mkdir putils.ProcessExecutionError( # mount stderr='is busy or already mounted') ] self.assertRaises(putils.ProcessExecutionError, self._driver._mount_quobyte, self.TEST_QUOBYTE_VOLUME, self.TEST_MNT_POINT, ensure=False) mkdir_call = mock.call('mkdir', '-p', self.TEST_MNT_POINT) mount_call = mock.call('mount.quobyte', self.TEST_QUOBYTE_VOLUME, self.TEST_MNT_POINT, run_as_root=False) mock_execute.assert_has_calls([mkdir_call, mount_call], any_order=False)
def _ssh_execute(self, ssh, command, *arg, **kwargs): transport = ssh.get_transport() chan = transport.open_session() completed = False try: chan.invoke_shell() LOG.debug("Reading CLI MOTD") self._get_output(chan) cmd = 'stty columns 255' LOG.debug("Setting CLI terminal width: '%s'", cmd) chan.send(cmd + '\r') out = self._get_output(chan) LOG.debug("Sending CLI command: '%s'", command) chan.send(command + '\r') out = self._get_output(chan) completed = True if any(ln.startswith(('% Error', 'Error:')) for ln in out): desc = _("Error executing EQL command") cmdout = '\n'.join(out) LOG.error(cmdout) raise processutils.ProcessExecutionError(stdout=cmdout, cmd=command, description=desc) return out finally: if not completed: LOG.debug("Timed out executing command: '%s'", command) chan.close()
def _xvp_encrypt(self, password, is_pool_password=False): """Call xvp to obfuscate passwords for config file. Args: - password: the password to encode, max 8 char for vm passwords, and 16 chars for pool passwords. passwords will be trimmed to max len before encoding. - is_pool_password: True if this is the XenServer api password False if it's a VM console password (xvp uses different keys and max lengths for pool passwords) Note that xvp's obfuscation should not be considered 'real' encryption. It simply DES encrypts the passwords with static keys plainly viewable in the xvp source code. """ maxlen = 8 flag = '-e' if is_pool_password: maxlen = 16 flag = '-x' # xvp will blow up on passwords that are too long (mdragon) password = password[:maxlen] out, err = utils.execute('xvp', flag, process_input=password) if err: raise processutils.ProcessExecutionError(_("Failed to run xvp.")) return out.strip()
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): utils.check_ssh_injection(cmd_list) command = ' '.join(cmd_list) if not self.sshpool: password = self.configuration.san_password privatekey = self.configuration.san_private_key min_size = self.configuration.ssh_min_pool_conn max_size = self.configuration.ssh_max_pool_conn self.sshpool = ssh_utils.SSHPool( self.configuration.san_ip, self.configuration.san_ssh_port, self.configuration.ssh_conn_timeout, self.configuration.san_login, password=password, privatekey=privatekey, min_size=min_size, max_size=max_size) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(e) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Error running SSH command: %s") % command)
def test_stop_shellinabox_console_fail_nokill(self, mock_stop): mock_stop.side_effect = processutils.ProcessExecutionError() self.assertRaises(exception.ConsoleError, console_utils.stop_shellinabox_console, self.info['uuid']) mock_stop.assert_called_once_with(self.info['uuid'])
def fake_execute(self, *cmd, **kwargs): self.cmds.append(string.join(cmd)) # Tests that if tgtadm --op show fails with 'target already exists', # we handle it gracefully and continue. if 'tgtadm' in cmd and '--op' in cmd and 'show' in cmd: raise processutils.ProcessExecutionError( stderr='tgtadm: this target already exists') else: return "", None
def test_delete_absent_volume(self): self.driver._eql_execute = self.mox.\ CreateMock(self.driver._eql_execute) volume = {'name': self.volume_name, 'size': 1, 'id': self.volid} self.driver._eql_execute('volume', 'select', volume['name'], 'show').\ AndRaise(processutils.ProcessExecutionError( stdout='% Error ..... does not exist.\n')) self.mox.ReplayAll() self.driver.delete_volume(volume)
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): command = ' '.join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: msg = _("Exception: %s") % six.text_type(e) LOG.error(msg) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Error running SSH command: %s") % command)
def _run_ssh(self, cmd_list, check_exit_code=True, attempts=1): # TODO(skolathur): Need to implement ssh_injection check # currently, the check will fail for zonecreate command # as zone members are separated by ';'which is a danger char command = ' '.join(cmd_list) if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: return processutils.ssh_execute( ssh, command, check_exit_code=check_exit_code) except Exception as e: LOG.error(e) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Error running SSH command: %s") % command)
def fake_exec(*cmd, **kwargs): # Support only bool check_exit_code = kwargs.pop('check_exit_code', True) global SIM out, err, ret = SIM.exec_cmd(cmd) if ret and check_exit_code: raise putils.ProcessExecutionError(exit_code=-1, stdout=out, stderr=err, cmd=' '.join(cmd)) return (out, err)
def _execute_shell_cmd(self, cmd): """Run command over shell for older firmware versions. We invoke shell and issue the command and return the output. This is primarily used for issuing read commands when we are not sure if the firmware supports exec_command. """ utils.check_ssh_injection(cmd) command = ' '.join(cmd) stdout, stderr = None, None if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) with self.sshpool.item() as ssh: LOG.debug('Running cmd (SSH): %s' % command) channel = ssh.invoke_shell() stdin_stream = channel.makefile('wb') stdout_stream = channel.makefile('rb') stderr_stream = channel.makefile('rb') stdin_stream.write('''%s exit ''' % command) stdin_stream.flush() stdout = stdout_stream.readlines() stderr = stderr_stream.readlines() stdin_stream.close() stdout_stream.close() stderr_stream.close() exit_status = channel.recv_exit_status() # exit_status == -1 if no exit code was returned if exit_status != -1: LOG.debug('Result was %s' % exit_status) if exit_status != 0: msg = "command %s failed" % command LOG.debug(msg) raise processutils.ProcessExecutionError( exit_code=exit_status, stdout=stdout, stderr=stderr, cmd=command) try: channel.close() except Exception as e: LOG.exception(e) LOG.debug("_execute_cmd: stderr to return:%s" % stderr) return (stdout, stderr)
def test__stop_console_nokill(self, mock_pid, mock_execute, mock_unlink): pid_file = console_utils._get_console_pid_file(self.info['uuid']) mock_pid.return_value = '12345' mock_execute.side_effect = processutils.ProcessExecutionError() self.assertRaises(processutils.ProcessExecutionError, console_utils._stop_console, self.info['uuid']) mock_pid.assert_called_once_with(self.info['uuid']) mock_execute.assert_called_once_with('kill', mock_pid.return_value, check_exit_code=[0, 99]) mock_unlink.assert_called_once_with(pid_file)
def _exec_dsmc_cmd(self, cmd): """Simulates the execution of the dsmc command.""" cmd_switch = { 'backup': self._cmd_backup, 'restore': self._cmd_restore, 'delete': self._cmd_delete } kwargs = self._cmd_to_dict(cmd) if kwargs['cmd'] != 'dsmc' or kwargs['type'] not in cmd_switch: raise putils.ProcessExecutionError(exit_code=1, stdout='', stderr='Not dsmc command', cmd=' '.join(cmd)) out, err, ret = cmd_switch[kwargs['type']](**kwargs) return (out, err, ret)
def execute_command(self, cmd, check_exit_code=True): try: kwargs = self._cmd_to_dict(cmd) except exception.InvalidInput: return self._errors['CMMVC50000'] command = kwargs['cmd'] del kwargs['cmd'] func = getattr(self, '_cmd_' + command) out, err = func(**kwargs) if (check_exit_code) and (len(err) != 0): raise processutils.ProcessExecutionError(exit_code=1, stdout=out, stderr=err, cmd=command) return (out, err)
def test_with_stdout(self): stdout = """ Lo, praise of the prowess of people-kings of spear-armed Danes, in days long sped, we have heard, and what honot the athelings won! Oft Scyld the Scefing from squadroned foes, from many a tribe, the mead-bench tore, awing the earls. Since erse he lay friendless, a foundling, fate repaid him: for he waxed under welkin, in wealth he trove, till before him the folk, both far and near, who house by the whale-path, heard his mandate, gabe him gits: a good king he! To him an heir was afterward born, a son in his halls, whom heaven sent to favor the fol, feeling their woe that erst they had lacked an earl for leader so long a while; the Lord endowed him, the Wielder of Wonder, with world's renown. """.strip() err = processutils.ProcessExecutionError(stdout=stdout) print(six.text_type(err)) self.assertTrue('people-kings' in six.text_type(err))
def test_mount_quobyte_should_suppress_and_log_already_mounted_error(self): """Based on /proc/mount, the file system is not mounted yet. However, mount.quobyte returns with an 'already mounted' error. This is a last-resort safe-guard in case /proc/mount parsing was not successful. Because _mount_quobyte gets called with ensure=True, the error will be suppressed and logged instead. """ with contextlib.nested( mock.patch.object(self._driver, '_execute'), mock.patch('cinder.volume.drivers.quobyte.QuobyteDriver' '.read_proc_mount'), mock.patch('cinder.volume.drivers.quobyte.LOG')) as ( mock_execute, mock_open, mock_LOG): # Content of /proc/mount (empty). mock_open.return_value = StringIO.StringIO() mock_execute.side_effect = [ None, putils.ProcessExecutionError( stderr='is busy or already mounted') ] self._driver._mount_quobyte(self.TEST_QUOBYTE_VOLUME, self.TEST_MNT_POINT, ensure=True) mkdir_call = mock.call('mkdir', '-p', self.TEST_MNT_POINT) mount_call = mock.call('mount.quobyte', self.TEST_QUOBYTE_VOLUME, self.TEST_MNT_POINT, run_as_root=False) mock_execute.assert_has_calls([mkdir_call, mount_call], any_order=False) mock_LOG.warn.assert_called_once_with('%s is already mounted', self.TEST_QUOBYTE_VOLUME)
def test_reraise_false(self): with srb.handle_process_execution_error( message='', info_message='', reraise=False): raise processutils.ProcessExecutionError(description='Oops')
def test_with_cmd(self): cmd = 'telinit' err = processutils.ProcessExecutionError(cmd=cmd) self.assertTrue(cmd in six.text_type(err))
def test_with_exit_code(self): exit_code = 0 err = processutils.ProcessExecutionError(exit_code=exit_code) self.assertTrue(str(exit_code) in six.text_type(err))
def test_with_description(self): description = 'The Narwhal Bacons at Midnight' err = processutils.ProcessExecutionError(description=description) self.assertTrue(description in six.text_type(err))
def test_defaults(self): err = processutils.ProcessExecutionError() self.assertTrue('None\n' in six.text_type(err)) self.assertTrue('code: -\n' in six.text_type(err))
def fake_execute_raises(*cmd, **kwargs): raise processutils.ProcessExecutionError(exit_code=42, stdout='stdout', stderr='stderr', cmd=['this', 'is', 'a', 'command'])
def test_with_stderr(self): stderr = 'Cottonian library' err = processutils.ProcessExecutionError(stderr=stderr) self.assertTrue(stderr in six.text_type(err))
def __init__(self, ipaddress, username, password, port, vsan): if not GlobalVars._is_normal_test: raise processutils.ProcessExecutionError( "Unable to connect to fabric")
def _ssh_execute(self, cmd_list, check_exit_code=True, attempts=1): """Execute cli with status update. Executes CLI commands where status return is expected. cmd_list is a list of commands, where each command is itself a list of parameters. We use utils.check_ssh_injection to check each command, but then join then with " ; " to form a single command. """ # Check that each command is secure for cmd in cmd_list: utils.check_ssh_injection(cmd) # Combine into a single command. command = ' ; '.join(map(lambda x: ' '.join(x), cmd_list)) if not self.sshpool: self.sshpool = ssh_utils.SSHPool(self.switch_ip, self.switch_port, None, self.switch_user, self.switch_pwd, min_size=1, max_size=5) stdin, stdout, stderr = None, None, None LOG.debug("Executing command via ssh: %s" % command) last_exception = None try: with self.sshpool.item() as ssh: while attempts > 0: attempts -= 1 try: stdin, stdout, stderr = ssh.exec_command(command) greenthread.sleep(random.randint(20, 500) / 100.0) channel = stdout.channel exit_status = channel.recv_exit_status() LOG.debug("Exit Status from ssh:%s", exit_status) # exit_status == -1 if no exit code was returned if exit_status != -1: LOG.debug('Result was %s' % exit_status) if check_exit_code and exit_status != 0: raise processutils.ProcessExecutionError( exit_code=exit_status, stdout=stdout, stderr=stderr, cmd=command) else: return True else: return True except Exception as e: msg = _("Exception: %s") % six.text_type(e) LOG.error(msg) last_exception = e greenthread.sleep(random.randint(20, 500) / 100.0) LOG.debug("Handling error case after SSH:%s", last_exception) try: raise processutils.ProcessExecutionError( exit_code=last_exception.exit_code, stdout=last_exception.stdout, stderr=last_exception.stderr, cmd=last_exception.cmd) except AttributeError: raise processutils.ProcessExecutionError( exit_code=-1, stdout="", stderr="Error running SSH command", cmd=command) except Exception as e: with excutils.save_and_reraise_exception(): msg = (_("Error executing command via ssh: %s") % six.text_type(e)) LOG.error(msg) finally: if stdin: stdin.flush() stdin.close() if stdout: stdout.close() if stderr: stderr.close()
def initiator_no_file(*args, **kwargs): raise putils.ProcessExecutionError('No file')
def _try_failing(self): self.attempts = self.attempts + 1 raise processutils.ProcessExecutionError("Fail everytime") return True
def f(): with srb.handle_process_execution_error( message='', info_message='', reraise=True): raise processutils.ProcessExecutionError(description='Oops')