def run_duplicity(self, options=[], current_time=None, fail=None, passphrase_input=[]): """ Run duplicity binary with given arguments and options """ # We run under setsid and take input from /dev/null (below) because # this way we force a failure if duplicity tries to read from the # console unexpectedly (like for gpg password or such). cmd_list = ["setsid", "duplicity"] cmd_list.extend(options) cmd_list.extend(["-v0"]) cmd_list.extend(["--no-print-statistics"]) cmd_list.extend(["--allow-source-mismatch"]) cmd_list.extend(["--archive-dir=testfiles/cache"]) if current_time: cmd_list.extend(["--current-time", current_time]) cmd_list.extend(self.class_args) if fail: cmd_list.extend(["--fail", str(fail)]) cmdline = " ".join(map(lambda x: '"%s"' % x, cmd_list)) if not passphrase_input: cmdline += " < /dev/null" child = pexpect.spawn('/bin/sh', ['-c', cmdline]) for passphrase in passphrase_input: child.expect('passphrase.*:') child.sendline(passphrase) child.wait() return_val = child.exitstatus #print "Ran duplicity command: ", cmdline, "\n with return_val: ", child.exitstatus if fail: self.assertEqual(30, child.exitstatus) elif return_val: raise CmdError(child.exitstatus)
def run_scp_command(self, commandline): """ Run an scp command, responding to password prompts """ for n in range(1, globals.num_retries+1): if n > 1: # sleep before retry time.sleep(self.retry_delay) log.Info("Running '%s' (attempt #%d)" % (commandline, n)) child = pexpect.spawn(commandline, timeout = None) if globals.ssh_askpass: state = "authorizing" else: state = "copying" while 1: if state == "authorizing": match = child.expect([pexpect.EOF, "(?i)timeout, server not responding", "(?i)pass(word|phrase .*):", "(?i)permission denied", "authenticity"]) log.Debug("State = %s, Before = '%s'" % (state, child.before.strip())) if match == 0: log.Warn("Failed to authenticate") break elif match == 1: log.Warn("Timeout waiting to authenticate") break elif match == 2: child.sendline(self.password) state = "copying" elif match == 3: log.Warn("Invalid SSH password") break elif match == 4: log.Warn("Remote host authentication failed (missing known_hosts entry?)") break elif state == "copying": match = child.expect([pexpect.EOF, "(?i)timeout, server not responding", "stalled", "authenticity", "ETA"]) log.Debug("State = %s, Before = '%s'" % (state, child.before.strip())) if match == 0: break elif match == 1: log.Warn("Timeout waiting for response") break elif match == 2: state = "stalled" elif match == 3: log.Warn("Remote host authentication failed (missing known_hosts entry?)") break elif state == "stalled": match = child.expect([pexpect.EOF, "(?i)timeout, server not responding", "ETA"]) log.Debug("State = %s, Before = '%s'" % (state, child.before.strip())) if match == 0: break elif match == 1: log.Warn("Stalled for too long, aborted copy") break elif match == 2: state = "copying" child.close(force = True) if child.exitstatus == 0: return log.Warn("Running '%s' failed (attempt #%d)" % (commandline, n)) log.Warn("Giving up trying to execute '%s' after %d attempts" % (commandline, globals.num_retries)) raise BackendException("Error running '%s'" % commandline)
def run_sftp_command(self, commandline, commands): """ Run an sftp command, responding to password prompts, passing commands from list """ maxread = 2000 # expected read buffer size responses = [pexpect.EOF, "(?i)timeout, server not responding", "sftp>", "(?i)pass(word|phrase .*):", "(?i)permission denied", "authenticity", "(?i)no such file or directory", "Couldn't delete file: No such file or directory", "Couldn't delete file", "open(.*): Failure"] max_response_len = max([len(p) for p in responses[1:]]) for n in range(1, globals.num_retries+1): if n > 1: # sleep before retry time.sleep(self.retry_delay) log.Info("Running '%s' (attempt #%d)" % (commandline, n)) child = pexpect.spawn(commandline, timeout = None, maxread=maxread) cmdloc = 0 passprompt = 0 while 1: msg = "" match = child.expect(responses, searchwindowsize=maxread+max_response_len) log.Debug("State = sftp, Before = '%s'" % (child.before.strip())) if match == 0: break elif match == 1: msg = "Timeout waiting for response" break if match == 2: if cmdloc < len(commands): command = commands[cmdloc] log.Info("sftp command: '%s'" % (command,)) child.sendline(command) cmdloc += 1 else: command = 'quit' child.sendline(command) res = child.before elif match == 3: passprompt += 1 child.sendline(self.password) if (passprompt>1): raise BackendException("Invalid SSH password.") elif match == 4: if not child.before.strip().startswith("mkdir"): msg = "Permission denied" break elif match == 5: msg = "Host key authenticity could not be verified (missing known_hosts entry?)" break elif match == 6: if not child.before.strip().startswith("rm"): msg = "Remote file or directory does not exist in command='%s'" % (commandline,) break elif match == 7: if not child.before.strip().startswith("Removing"): msg = "Could not delete file in command='%s'" % (commandline,) break; elif match == 8: msg = "Could not delete file in command='%s'" % (commandline,) break elif match == 9: msg = "Could not open file in command='%s'" % (commandline,) break child.close(force = True) if child.exitstatus == 0: return res log.Warn("Running '%s' with commands:\n %s\n failed (attempt #%d): %s" % (commandline, "\n ".join(commands), n, msg)) raise BackendException("Giving up trying to execute '%s' with commands:\n %s\n after %d attempts" % (commandline, "\n ".join(commands), globals.num_retries))
def run_scp_command(self, commandline): """ Run an scp command, responding to password prompts """ for n in range(1, globals.num_retries + 1): if n > 1: # sleep before retry time.sleep(self.retry_delay) log.Info("Running '%s' (attempt #%d)" % (commandline, n)) child = pexpect.spawn(commandline, timeout=None) if globals.ssh_askpass: state = "authorizing" else: state = "copying" while 1: if state == "authorizing": match = child.expect([ pexpect.EOF, "(?i)timeout, server not responding", "(?i)pass(word|phrase .*):", "(?i)permission denied", "authenticity" ]) log.Debug("State = %s, Before = '%s'" % (state, child.before.strip())) if match == 0: log.Warn("Failed to authenticate") break elif match == 1: log.Warn("Timeout waiting to authenticate") break elif match == 2: child.sendline(self.password) state = "copying" elif match == 3: log.Warn("Invalid SSH password") break elif match == 4: log.Warn( "Remote host authentication failed (missing known_hosts entry?)" ) break elif state == "copying": match = child.expect([ pexpect.EOF, "(?i)timeout, server not responding", "stalled", "authenticity", "ETA" ]) log.Debug("State = %s, Before = '%s'" % (state, child.before.strip())) if match == 0: break elif match == 1: log.Warn("Timeout waiting for response") break elif match == 2: state = "stalled" elif match == 3: log.Warn( "Remote host authentication failed (missing known_hosts entry?)" ) break elif state == "stalled": match = child.expect([ pexpect.EOF, "(?i)timeout, server not responding", "ETA" ]) log.Debug("State = %s, Before = '%s'" % (state, child.before.strip())) if match == 0: break elif match == 1: log.Warn("Stalled for too long, aborted copy") break elif match == 2: state = "copying" child.close(force=True) if child.exitstatus == 0: return log.Warn("Running '%s' failed (attempt #%d)" % (commandline, n)) log.Warn("Giving up trying to execute '%s' after %d attempts" % (commandline, globals.num_retries)) raise BackendException("Error running '%s'" % commandline)
def run_sftp_command(self, commandline, commands): """ Run an sftp command, responding to password prompts, passing commands from list """ maxread = 2000 # expected read buffer size responses = [ pexpect.EOF, "(?i)timeout, server not responding", "sftp>", "(?i)pass(word|phrase .*):", "(?i)permission denied", "authenticity", "(?i)no such file or directory", "Couldn't delete file: No such file or directory", "Couldn't delete file", "open(.*): Failure" ] max_response_len = max([len(p) for p in responses[1:]]) for n in range(1, globals.num_retries + 1): if n > 1: # sleep before retry time.sleep(self.retry_delay) log.Info("Running '%s' (attempt #%d)" % (commandline, n)) child = pexpect.spawn(commandline, timeout=None, maxread=maxread) cmdloc = 0 passprompt = 0 while 1: msg = "" match = child.expect(responses, searchwindowsize=maxread + max_response_len) log.Debug("State = sftp, Before = '%s'" % (child.before.strip())) if match == 0: break elif match == 1: msg = "Timeout waiting for response" break if match == 2: if cmdloc < len(commands): command = commands[cmdloc] log.Info("sftp command: '%s'" % (command, )) child.sendline(command) cmdloc += 1 else: command = 'quit' child.sendline(command) res = child.before elif match == 3: passprompt += 1 child.sendline(self.password) if (passprompt > 1): raise BackendException("Invalid SSH password.") elif match == 4: if not child.before.strip().startswith("mkdir"): msg = "Permission denied" break elif match == 5: msg = "Host key authenticity could not be verified (missing known_hosts entry?)" break elif match == 6: if not child.before.strip().startswith("rm"): msg = "Remote file or directory does not exist in command='%s'" % ( commandline, ) break elif match == 7: if not child.before.strip().startswith("Removing"): msg = "Could not delete file in command='%s'" % ( commandline, ) break elif match == 8: msg = "Could not delete file in command='%s'" % ( commandline, ) break elif match == 9: msg = "Could not open file in command='%s'" % ( commandline, ) break child.close(force=True) if child.exitstatus == 0: return res log.Warn( "Running '%s' with commands:\n %s\n failed (attempt #%d): %s" % (commandline, "\n ".join(commands), n, msg)) raise BackendException( "Giving up trying to execute '%s' with commands:\n %s\n after %d attempts" % (commandline, "\n ".join(commands), globals.num_retries))