def rmdir(self, path): """Remove a directory.""" if not self.exists(path): raise exceptions.ArgusCLIError("Invalid Path.") if not self.is_file(path): raise exceptions.ArgusCLIError("The path is not a directory.") LOG.debug("Remove directory %s", path) cmd = "Remove-Item -Recurse -Path '{}'".format(path) self._client.run_command_with_retry(cmd, command_type=util.POWERSHELL)
def remove(self, path): """Remove a file.""" if not self.exists(path) or not self.is_file(path): raise exceptions.ArgusCLIError("Invalid Path '{}'.".format(path)) LOG.debug("Remove file %s", path) cmd = "Remove-Item -Force -Path '{path}'".format(path=path) self._client.run_command_with_retry(cmd, command_type=util.POWERSHELL)
def rmdir(self, path): """Remove a directory.""" if not self.exists(path) or not self.is_dir(path): raise exceptions.ArgusCLIError("Invalid Path '{}'.".format(path)) LOG.debug("Remove directory %s", path) cmd = ("IF EXIST '{path}' (RD /S /Q '{path}')".format(path=path)) self._client.run_command_with_retry(cmd, command_type=util.CMD)
def copy_file(self, path, new_file): """Copy a file to the destination""" if not self.exists(path): raise exceptions.ArgusCLIError("Invalid Path '{}'.".format(path)) LOG.debug("Copy file from %s to %s", path, new_file) cmd = ("Copy-Item -Force -Path '{path}' " "-Destination '{newname}'".format(path=path, newname=new_file)) self._client.run_command_with_retry(cmd, command_type=util.POWERSHELL)
def mkdir(self, path): """Create a directory in the instance if the path is valid. :param path: Remote path where the new directory should be created. """ if self.exists(path): raise exceptions.ArgusCLIError( "Cannot create directory {} . It already exists.".format(path)) else: self._new_item(path, self._DIRECTORY)
def run_command_until_condition(self, cmd, cond, retry_count=CONFIG.argus.retry_count, delay=CONFIG.argus.retry_delay, command_type=util.POWERSHELL, upper_timeout=CONFIG.argus.upper_timeout): """Run the given `cmd` until a condition `cond` occurs. :param cond: A callable which receives the standard output returned by executing the command. It should return a boolean value, which tells to this function to stop execution. :raises: `ArgusCLIError` if there is output found in the standard error. This method uses and behaves like `run_command_with_retry` but with an additional condition parameter. """ # countdown normalization if not retry_count or retry_count < 0: retry_count = 0 while True: try: stdout, stderr, exit_code = self.run_command( cmd, command_type=command_type, upper_timeout=upper_timeout) except Exception as exc: # pylint: disable=broad-except LOG.debug("Command failed with %r.", exc) else: if stderr and exit_code: raise exceptions.ArgusCLIError( ("Executing command {!r} failed with {!r}" " and exit code {}.") .format(cmd, stderr, exit_code)) elif cond(stdout): return else: LOG.debug("Condition not met, retrying...") if retry_count > 0: retry_count -= 1 LOG.debug("Retrying '%s'", cmd) time.sleep(delay) else: raise exceptions.ArgusTimeoutError( "Command {!r} failed too many times." .format(cmd))
def mkfile(self, path): """Create a file in the instance if the path is valid. :param path: Remote path where the new file should be created. """ if self.is_file(path): LOG.warning( "File '%s' already exists. LastWriteTime and" " LastAccessTime will be updated.", path) self._client.run_command_with_retry( "echo $null >> '{}'".format(path), command_type=util.POWERSHELL) elif self.is_dir(path): raise exceptions.ArgusCLIError("Path '{}' leads to a" " directory.".format(path)) self._new_item(path, self._FILE)
def git_clone(self, repo_url, location, count=util.RETRY_COUNT, delay=util.RETRY_DELAY): """Clone from a remote repository to a specified location. :param repo_url: The remote repository URL. :param location: The target location for where to clone the repository. :param count: The number of tries that should be attempted in case it fails. :param delay: The time delay before retrying. :returns: True if the clone was successful, False if not. :raises: ArgusCLIError if the path is not valid. :rtype: bool """ if self.exists(location): raise exceptions.ArgusCLIError("Destination path '{}' already " "exists.".format(location)) LOG.info("Cloning from %s to %s", repo_url, location) cmd = "git clone '{repo}' '{location}'".format(repo=repo_url, location=location) while count > 0: try: self._client.run_command(cmd) except exceptions.ArgusError as exc: LOG.debug("Cloning failed with %r.", exc) if self.exists(location): rem = self.rmdir if self.is_dir(location) else self.remove rem(location) count -= 1 if count: LOG.debug('Retrying...') time.sleep(delay) else: return True LOG.debug('Could not clone %s', repo_url) return False
def _run_cmd_until_condition(self, cmd, cond, retry_count=None, retry_count_interval=5): """Run the given `cmd` until a condition *cond* occurs. :param cmd: A string, representing a command which needs to be executed on the underlying remote client. :param cond: A callable which receives the stdout returned by executing the command. It should return a boolean value, which tells to this function to stop execution. :param retry_count: The number of retries which this function has. If the value is ``None``, then the function will run *forever*. :param retry_count_interval: The number of seconds to sleep when retrying a command. """ count = 0 while True: try: std_out, std_err = self._execute(cmd) except Exception: # pylint: disable=broad-except LOG.debug("Command %r failed while waiting for condition", cmd) count += 1 if retry_count and count >= retry_count: raise exceptions.ArgusTimeoutError( "Command {!r} failed too many times.".format(cmd)) time.sleep(retry_count_interval) else: if std_err: raise exceptions.ArgusCLIError( "Executing command {!r} failed with {!r}".format( cmd, std_err)) elif cond(std_out): break else: time.sleep(retry_count_interval)
def _unzip(self, zip_file, out_file, force=False): """Unzip the file. :param zip_file: Path to zip file. :param out_file: Path to output file from unzipping process. :param force: If we should override the output file or not. """ exists = self.exists(out_file) if exists and not force: raise exceptions.ArgusCLIError("Output file path already exists.") elif exists: (self.rmdir if self.is_dir(out_file) else self.remove)(out_file) cmd = ("If (Test-Path -Path '{path}') {{cmd /c RD /S /Q '{path}'}} " "Else {{ [System.IO.Compression.ZipFile]::ExtractToDirectory(" "'{zip_file}', '{path}') }}".format(zip_file=zip_file, path=out_file)) self._client.run_command_with_retry( cmd, command_type=util.POWERSHELL)