def __init__(self, config, remove_origin=False, debug=False): self.remove_origin = remove_origin if remove_origin: command = 'compress(){ bzip2 -c > "$2" < "$1" && rm -f "$1";}; compress' else: command = 'compress(){ bzip2 -c > "$2" < "$1";}; compress' Command.__init__(self, command, shell=True, check=True, debug=debug)
def get_remote_status(self): """Get the status of the remote server""" pg_settings = ("archive_mode", "archive_command", "data_directory") pg_query_keys = ("server_txt_version", "current_xlog") result = dict.fromkeys(pg_settings + pg_query_keys, None) try: with self.pg_connect() as conn: for name in pg_settings: result[name] = self.get_pg_setting(name) try: cur = conn.cursor() cur.execute("SELECT version()") result["server_txt_version"] = cur.fetchone()[0].split()[1] except: result["server_txt_version"] = None try: cur = conn.cursor() cur.execute("SELECT pg_xlogfile_name(pg_current_xlog_location())") result["current_xlog"] = cur.fetchone()[0] except: result["current_xlog"] = None except: pass cmd = Command(self.ssh_command, self.ssh_options) result["last_shipped_wal"] = None if result["data_directory"] and result["archive_command"]: archive_dir = os.path.join(result["data_directory"], "pg_xlog", "archive_status") out = cmd.getoutput(None, "ls", "-tr", archive_dir)[0] for line in out.splitlines(): if line.endswith(".done"): name = line[:-5] if xlog.is_wal_file(name): result["last_shipped_wal"] = line[:-5] return result
def get_remote_status(self): '''Get the status of the remote server''' pg_settings = ('archive_mode', 'archive_command', 'data_directory') pg_query_keys = ('server_txt_version', 'current_xlog') result = dict.fromkeys(pg_settings + pg_query_keys, None) try: with self.pg_connect() as conn: for name in pg_settings: result[name] = self.get_pg_setting(name) try: cur = conn.cursor() cur.execute("SELECT version()") result['server_txt_version'] = cur.fetchone()[0].split()[1] except: result['server_txt_version'] = None try: cur = conn.cursor() cur.execute('SELECT pg_xlogfile_name(pg_current_xlog_location())') result['current_xlog'] = cur.fetchone()[0]; except: result['current_xlog'] = None except: pass cmd = Command(self.ssh_command, self.ssh_options) result['last_shipped_wal'] = None if result['data_directory'] and result['archive_command']: archive_dir = os.path.join(result['data_directory'], 'pg_xlog', 'archive_status') out = cmd.getoutput(None, 'ls', '-tr', archive_dir)[0] for line in out.splitlines(): if line.endswith('.done'): name = line[:-5] if xlog.is_wal_file(name): result['last_shipped_wal'] = line[:-5] return result
def get_remote_status(self): """ Retrieve the last archived WAL using a ssh connection on the remote server and executing an ls command. :rtype: dict """ remote_status = {} with self.server.pg_connect(): if self.server.server_version < 90400: remote_status['last_archived_wal'] = None if self.server.get_pg_setting('data_directory') and \ self.server.get_pg_setting('archive_command'): # TODO: replace with RemoteUnixCommand cmd = Command(self.ssh_command, self.ssh_options) archive_dir = os.path.join( self.server.get_pg_setting('data_directory'), 'pg_xlog', 'archive_status') out = str(cmd.getoutput('ls', '-tr', archive_dir)[0]) for line in out.splitlines(): if line.endswith('.done'): name = line[:-5] if xlog.is_any_xlog_file(name): remote_status['last_archived_wal'] = name break return remote_status
def get_remote_status(self): """ Get remote information on PostgreSQL using Ssh, such as last archived WAL file :rtype: dict(str,str|None) """ remote_status = {} # Retrieve the last archived WAL using a Ssh connection on # the remote server and executing an 'ls' command. Only # for pre-9.4 versions of PostgreSQL. if self.server.postgres.server_version < 90400: remote_status['last_archived_wal'] = None if self.server.postgres.get_setting('data_directory') and \ self.server.postgres.get_setting('archive_command'): # TODO: replace with RemoteUnixCommand cmd = Command(self.ssh_command, self.ssh_options, path=self.server.path) archive_dir = os.path.join( self.server.postgres.get_setting('data_directory'), 'pg_xlog', 'archive_status') out = str(cmd.getoutput('ls', '-tr', archive_dir)[0]) for line in out.splitlines(): if line.endswith('.done'): name = line[:-5] if xlog.is_any_xlog_file(name): remote_status['last_archived_wal'] = name break return remote_status
def __init__(self, config, remove_origin=False, debug=False): if not config.custom_decompression_filter: raise CompressionIncompatibility("custom_decompression_filter") self.remove_origin = remove_origin if remove_origin: template = 'decompress(){ %s > "$2" < "$1" && rm -f "$1";}; decompress' else: template = 'decompress(){ %s > "$2" < "$1";}; decompress' Command.__init__(self, template % config.custom_decompression_filter, shell=True, check=True, debug=debug)
def ssh(server, args): warn = args.warning crit = args.critical from barman.backup_executor import _parse_ssh_command from barman.command_wrappers import Command ssh_command, ssh_options = _parse_ssh_command(server.config.ssh_command) cmd = Command(ssh_command, ssh_options) (retval, duration) = timed(cmd, 'true') milliseconds = get_milliseconds(duration) perfdata_key = "milliseconds" if retval == 0: exit_check(milliseconds, warn, crit, "SSH command ran in %sms" % (milliseconds), perfdata_key=perfdata_key, perfdata_min=0) else: critical( "Impossible to run a SSH command.", get_perfdata_str(perfdata_key, milliseconds, warn, crit, 0, None))
def run(self): """ Run a a hook script if configured. This method must never throw any exception """ # noinspection PyBroadException try: if self.script: _logger.debug("Attempt to run %s: %s", self.name, self.script) cmd = Command(self.script, env_append=self.environment, path=self.backup_manager.server.path, shell=True, check=False) self.exit_status = cmd() if self.exit_status != 0: details = "%s returned %d\n" \ "Output details:\n" \ % (self.script, self.exit_status) details += cmd.out details += cmd.err _logger.warning(details) else: _logger.debug("%s returned %d", self.script, self.exit_status) return self.exit_status except Exception as e: _logger.exception('Exception running %s', self.name) self.exception = e return None
def __init__(self, ssh_command, ssh_options=None, path=None): """ Uses the same commands as the UnixLocalCommand but the constructor is overridden and a remote shell is initialized using the ssh_command provided by the user :param str ssh_command: the ssh command provided by the user :param list[str] ssh_options: the options to be passed to SSH :param str path: the path to be used if provided, otherwise the PATH environment variable will be used """ # Ensure that ssh_option is iterable if ssh_options is None: ssh_options = [] if ssh_command is None: raise FsOperationFailed('No ssh command provided') self.cmd = Command(ssh_command, ssh_options, path=path, shell=True) try: ret = self.cmd("true") except OSError: raise FsOperationFailed("Unable to execute %s" % ssh_command) if ret != 0: raise FsOperationFailed( "Connection failed using '%s %s' return code %s" % ( ssh_command, ' '.join(ssh_options), ret))
def check_ssh(self): '''Checks SSH connection''' cmd = Command(self.ssh_command, self.ssh_options) ret = cmd("true") if ret == 0: yield ("\tssh: OK", True) else: yield ("\tssh: FAILED (return code: %s)" % (ret, ), False)
def _build_command(self, pipe_command): """ Build the command string and create the actual Command object :param pipe_command: the command used to compress/decompress :rtype: Command """ command = "barman_command(){ " command += pipe_command command += ' > "$2" < "$1"' command += ";}; barman_command" return Command(command, shell=True, check=True, path=self.path)
def fetch_remote_status(self): """ Get remote information on PostgreSQL using Ssh, such as last archived WAL file This method does not raise any exception in case of errors, but set the missing values to None in the resulting dictionary. :rtype: dict[str, None|str] """ remote_status = {} # Retrieve the last archived WAL using a Ssh connection on # the remote server and executing an 'ls' command. Only # for pre-9.4 versions of PostgreSQL. try: if self.server.postgres and \ self.server.postgres.server_version < 90400: remote_status['last_archived_wal'] = None if self.server.postgres.get_setting('data_directory') and \ self.server.postgres.get_setting('archive_command'): # TODO: replace with RemoteUnixCommand # The Command can raise OSError # if self.ssh_command does not exist. cmd = Command(self.ssh_command, self.ssh_options, path=self.server.path) archive_dir = os.path.join( self.server.postgres.get_setting('data_directory'), 'pg_xlog', 'archive_status') out = str(cmd.getoutput('ls', '-t', archive_dir)[0]) for line in out.splitlines(): if line.endswith('.done'): name = line[:-5] if xlog.is_any_xlog_file(name): remote_status['last_archived_wal'] = name break except (PostgresConnectionError, OSError) as e: _logger.warn("Error retrieving PostgreSQL status: %s", e) return remote_status
def get_remote_status(self): '''Get the status of the remote server''' pg_settings = ('archive_mode', 'archive_command', 'data_directory') pg_query_keys = ('server_txt_version', 'current_xlog') result = dict.fromkeys(pg_settings + pg_query_keys, None) try: with self.pg_connect() as conn: for name in pg_settings: result[name] = self.get_pg_setting(name) try: cur = conn.cursor() cur.execute("SELECT version()") result['server_txt_version'] = cur.fetchone()[0].split()[1] except: result['server_txt_version'] = None try: cur = conn.cursor() cur.execute( 'SELECT pg_xlogfile_name(pg_current_xlog_location())') result['current_xlog'] = cur.fetchone()[0] except: result['current_xlog'] = None except: pass cmd = Command(self.ssh_command, self.ssh_options) result['last_shipped_wal'] = None if result['data_directory'] and result['archive_command']: archive_dir = os.path.join(result['data_directory'], 'pg_xlog', 'archive_status') out = cmd.getoutput(None, 'ls', '-tr', archive_dir)[0] for line in out.splitlines(): if line.endswith('.done'): name = line[:-5] if xlog.is_wal_file(name): result['last_shipped_wal'] = line[:-5] return result
def run_post_backup_script(self, backup_info): ''' Run the post_backup_script if configured. This method must never throw any exception ''' try: script = self.config.post_backup_script if script: _logger.info("Attempt to run post_backup_script: %s", script) cmd = Command( script, env_append=self.build_script_env(backup_info, 'post'), shell=True, check=False) ret = cmd() _logger.info("post_backup_script returned %d", ret) except Exception: _logger.exception('Exception running post_backup_script')
def __init__(self, path=None): # initialize a shell self.internal_cmd = Command(cmd='sh', args=['-c'], path=path)
def __init__(self, path=None): # initialize a shell self.internal_cmd = Command(cmd="sh", args=["-c"], path=path)
def fetch_remote_status(self): """ Execute checks for replication-based wal archiving This method does not raise any exception in case of errors, but set the missing values to None in the resulting dictionary. :rtype: dict[str, None|str] """ result = dict.fromkeys( ('pg_receivexlog_compatible', 'pg_receivexlog_installed', 'pg_receivexlog_path', 'pg_receivexlog_version'), None) # Detect a pg_receivexlog executable pg_receivexlog = utils.which("pg_receivexlog", self.backup_manager.server.path) # Test pg_receivexlog existence if pg_receivexlog: result["pg_receivexlog_installed"] = True result["pg_receivexlog_path"] = pg_receivexlog else: result["pg_receivexlog_installed"] = False return result receivexlog = Command(pg_receivexlog, check=True) # Obtain the `pg_receivexlog` version try: receivexlog("--version") splitter_version = receivexlog.out.strip().split() result["pg_receivexlog_version"] = splitter_version[-1] receivexlog_version = Version( utils.simplify_version(result["pg_receivexlog_version"])) except CommandFailedException as e: receivexlog_version = None _logger.debug("Error invoking pg_receivexlog: %s", e) # Retrieve the PostgreSQL versionn pg_version = None if self.server.streaming is not None: pg_version = self.server.streaming.server_major_version # If one of the version is unknown we cannot compare them if receivexlog_version is None or pg_version is None: return result # pg_version is not None so transform into a Version object # for easier comparison between versions pg_version = Version(pg_version) # pg_receivexlog 9.2 is compatible only with PostgreSQL 9.2. if "9.2" == pg_version == receivexlog_version: result["pg_receivexlog_compatible"] = True # other versions are compatible with lesser versions of PostgreSQL # WARNING: The development versions of `pg_receivexlog` are considered # higher than the stable versions here, but this is not an issue # because it accepts everything that is less than # the `pg_receivexlog` version(e.g. '9.6' is less than '9.6devel') elif "9.2" < pg_version <= receivexlog_version: result["pg_receivexlog_compatible"] = True else: result["pg_receivexlog_compatible"] = False return result
def __init__(self, path=None): # initialize a shell self.cmd = Command(cmd='sh -c', shell=True, path=path)