def enable_as_master(self, service, master_config, for_failover=False): # For a server to be a master in postgres, we need to enable # replication user in pg_hba and ensure that WAL logging is # the appropriate level (use the same settings as backups) self._get_or_create_replication_user() hba_entry = "host replication replicator 0.0.0.0/0 md5 \n" tmp_hba = '/tmp/pg_hba' operating_system.copy(self.pgsql_hba_config, tmp_hba, force=True, as_root=True) operating_system.chmod(tmp_hba, FileMode.SET_ALL_RWX(), as_root=True) with open(tmp_hba, 'a+') as hba_file: hba_file.write(hba_entry) operating_system.copy(tmp_hba, self.pgsql_hba_config, force=True, as_root=True) operating_system.chmod(self.pgsql_hba_config, FileMode.SET_USR_RWX(), as_root=True) operating_system.remove(tmp_hba, as_root=True) pgutil.psql("SELECT pg_reload_conf()")
def enable_as_master(self, service, master_config, for_failover=False): """For a server to be a master in postgres, we need to enable the replication user in pg_hba and ensure that WAL logging is at the appropriate level (use the same settings as backups) """ LOG.debug("Enabling as master, with cfg: %s " % master_config) self._get_or_create_replication_user(service) hba_entry = "host replication replicator 0.0.0.0/0 md5 \n" # TODO(atomic77) Remove this hack after adding cfg manager for pg_hba tmp_hba = '/tmp/pg_hba' operating_system.copy(service.pgsql_hba_config, tmp_hba, force=True, as_root=True) operating_system.chmod(tmp_hba, FileMode.OCTAL_MODE("0777"), as_root=True) with open(tmp_hba, 'a+') as hba_file: hba_file.write(hba_entry) operating_system.copy(tmp_hba, service.pgsql_hba_config, force=True, as_root=True) operating_system.chmod(service.pgsql_hba_config, FileMode.OCTAL_MODE("0600"), as_root=True) operating_system.remove(tmp_hba, as_root=True) service.reload_configuration()
def enable_as_master(self, service, master_config): """Primary postgredql settings. For a server to be a master in postgres, we need to enable the replication user in pg_hba.conf """ self._get_or_create_replication_user(service) hba_entry = f"host replication {REPL_USER} 0.0.0.0/0 md5\n" tmp_hba = '/tmp/pg_hba' operating_system.copy(pg_service.HBA_CONFIG_FILE, tmp_hba, force=True, as_root=True) operating_system.chmod(tmp_hba, FileMode.SET_ALL_RWX(), as_root=True) with open(tmp_hba, 'a+') as hba_file: hba_file.write(hba_entry) operating_system.copy(tmp_hba, pg_service.HBA_CONFIG_FILE, force=True, as_root=True) operating_system.chown(pg_service.HBA_CONFIG_FILE, user=CONF.database_service_uid, group=CONF.database_service_uid, as_root=True) operating_system.chmod(pg_service.HBA_CONFIG_FILE, FileMode.SET_USR_RWX(), as_root=True) operating_system.remove(tmp_hba, as_root=True) LOG.debug(f"{pg_service.HBA_CONFIG_FILE} changed") service.restart()
def _create_replication_user(self, pwfile): """Create the replication user. Unfortunately, to be able to run pg_rewind, we need SUPERUSER, not just REPLICATION privilege """ pw = utils.generate_random_password() operating_system.write_file(pwfile, pw, as_root=True) operating_system.chown(pwfile, user=self.PGSQL_OWNER, group=self.PGSQL_OWNER, as_root=True) operating_system.chmod(pwfile, FileMode.OCTAL_MODE("0600"), as_root=True) # TODO(atomic77) Alter user is swallowing the replication # option for some reason -- enable this code when the # underlying issue is fixed # repl_user = models.PostgreSQLUser(name=REPL_USER, # password=REPL_PW) # self._create_user(context=None, user=repl_user) # self.alter_user(None, repl_user, 'REPLICATION', 'LOGIN') pgutil.psql("CREATE USER %s SUPERUSER ENCRYPTED " "password '%s';" % (REPL_USER, pw)) return pw
def __init__(self, status): self.state_change_wait_time = CONF.state_change_wait_time self.status = status revision_dir = \ guestagent_utils.build_file_path( os.path.join(MOUNT_POINT, os.path.dirname(system.VERTICA_ADMIN)), ConfigurationManager.DEFAULT_STRATEGY_OVERRIDES_SUB_DIR) if not operating_system.exists(FAKE_CFG): operating_system.write_file(FAKE_CFG, '', as_root=True) operating_system.chown(FAKE_CFG, system.VERTICA_ADMIN, system.VERTICA_ADMIN_GRP, as_root=True) operating_system.chmod(FAKE_CFG, FileMode.ADD_GRP_RX_OTH_RX(), as_root=True) self.configuration_manager = \ ConfigurationManager(FAKE_CFG, system.VERTICA_ADMIN, system.VERTICA_ADMIN_GRP, PropertiesCodec(delimiter='='), requires_root=True, override_strategy=ImportOverrideStrategy( revision_dir, "cnf"))
def _incremental_restore(self, location, checksum): metadata = self.storage.load_metadata(location, checksum) LOG.info(_("Metadata for inc backup: %s") % str(metadata)) if 'parent_location' in metadata: LOG.info("Found parent at %s", metadata['parent_location']) parent_location = metadata['parent_location'] parent_checksum = metadata['parent_checksum'] self._incremental_restore(parent_location, parent_checksum) cmd = self._incremental_restore_cmd(incr=True) self.content_length += self._unpack(location, checksum, cmd) else: # For the parent base backup, revert to the default restore cmd LOG.info("Recursed back to full backup ") super(PgBaseBackupIncremental, self).pre_restore() cmd = self._incremental_restore_cmd(incr=False) self.content_length += self._unpack(location, checksum, cmd) operating_system.chmod(self.PGSQL_DATA_DIR, FileMode.OCTAL_MODE("0700"), as_root=True, recursive=True, force=True)
def base_backup_metadata(self, f): """Parse the contents of the .backup file""" meta = {} operating_system.chmod(f, FileMode(add=[stat.S_IROTH]), as_root=True) start_re = re.compile("START WAL LOCATION: (.*) \(file (.*)\)") stop_re = re.compile("STOP WAL LOCATION: (.*) \(file (.*)\)") checkpt_re = re.compile("CHECKPOINT LOCATION: (.*)") label_re = re.compile("LABEL: (.*)") with open(f, 'r') as base_metadata: lines = "\n".join(base_metadata.readlines()) match = start_re.search(lines) if match: self.start_segment = meta['start-segment'] = match.group(1) self.start_wal_file = meta['start-wal-file'] = match.group(2) match = stop_re.search(lines) if match: self.stop_segment = meta['stop-segment'] = match.group(1) self.stop_wal_file = meta['stop-wal-file'] = match.group(2) match = checkpt_re.search(lines) if match: self.checkpoint_location \ = meta['checkpoint-location'] = match.group(1) match = label_re.search(lines) if match: self.label = meta['label'] = match.group(1) return meta
def _create_replication_user(self, pwfile): """Create the replication user. Unfortunately, to be able to run pg_rewind, we need SUPERUSER, not just REPLICATION privilege """ pw = utils.generate_random_password() operating_system.write_file(pwfile, pw, as_root=True) operating_system.chown(pwfile, user=self.PGSQL_OWNER, group=self.PGSQL_OWNER, as_root=True) operating_system.chmod(pwfile, FileMode.SET_USR_RWX(), as_root=True) pgutil.psql("CREATE USER %s SUPERUSER ENCRYPTED " "password '%s';" % (REPL_USER, pw)) return pw
def _create_replication_user(self, service, admin, pwfile): """Create the replication user. Unfortunately, to be able to run pg_rewind, we need SUPERUSER, not just REPLICATION privilege """ pw = utils.generate_random_password() operating_system.write_file(pwfile, pw, as_root=True) operating_system.chown(pwfile, user=service.pgsql_owner, group=service.pgsql_owner, as_root=True) operating_system.chmod(pwfile, FileMode.SET_USR_RWX(), as_root=True) repl_user = models.PostgreSQLUser(name=REPL_USER, password=pw) admin._create_user(context=None, user=repl_user) admin.alter_user(None, repl_user, True, 'REPLICATION', 'SUPERUSER', 'LOGIN') return pw
def _create_replication_user(self, service, adm_mgr, pwfile): """Create the replication user and password file. Unfortunately, to be able to run pg_rewind, we need SUPERUSER, not just REPLICATION privilege """ pw = utils.generate_random_password() operating_system.write_file(pwfile, pw, as_root=True) operating_system.chown(pwfile, user=CONF.database_service_uid, group=CONF.database_service_uid, as_root=True) operating_system.chmod(pwfile, FileMode.SET_USR_RWX(), as_root=True) LOG.debug(f"File {pwfile} created") LOG.debug(f"Creating replication user {REPL_USER}") repl_user = models.PostgreSQLUser(name=REPL_USER, password=pw) adm_mgr.create_user(repl_user, None, *('REPLICATION', 'SUPERUSER', 'LOGIN')) return pw
def _incremental_restore(self, location, checksum): metadata = self.storage.load_metadata(location, checksum) if 'parent_location' in metadata: LOG.info(_("Found parent at %s"), metadata['parent_location']) parent_location = metadata['parent_location'] parent_checksum = metadata['parent_checksum'] self._incremental_restore(parent_location, parent_checksum) cmd = self._incremental_restore_cmd(incr=True) self.content_length += self._unpack(location, checksum, cmd) else: # For the parent base backup, revert to the default restore cmd LOG.info(_("Recursed back to full backup.")) super(PgBaseBackupIncremental, self).pre_restore() cmd = self._incremental_restore_cmd(incr=False) self.content_length += self._unpack(location, checksum, cmd) operating_system.chmod(self.app.pgsql_data_dir, FileMode.SET_USR_RWX(), as_root=True, recursive=True, force=True)
def base_backup_metadata(self, metadata_file): """Parse the contents of the .backup file""" metadata = {} operating_system.chmod(metadata_file, FileMode(add=[stat.S_IROTH]), as_root=True) start_re = re.compile("START WAL LOCATION: (.*) \(file (.*)\)") stop_re = re.compile("STOP WAL LOCATION: (.*) \(file (.*)\)") checkpt_re = re.compile("CHECKPOINT LOCATION: (.*)") label_re = re.compile("LABEL: (.*)") metadata_contents = operating_system.read_file(metadata_file) match = start_re.search(metadata_contents) if match: self.start_segment = match.group(1) metadata['start-segment'] = self.start_segment self.start_wal_file = match.group(2) metadata['start-wal-file'] = self.start_wal_file match = stop_re.search(metadata_contents) if match: self.stop_segment = match.group(1) metadata['stop-segment'] = self.stop_segment self.stop_wal_file = match.group(2) metadata['stop-wal-file'] = self.stop_wal_file match = checkpt_re.search(metadata_contents) if match: self.checkpoint_location = match.group(1) metadata['checkpoint-location'] = self.checkpoint_location match = label_re.search(metadata_contents) if match: self.label = match.group(1) metadata['label'] = self.label return metadata
def post_restore(self): operating_system.chmod(self.app.pgsql_data_dir, FileMode.SET_USR_RWX(), as_root=True, recursive=True, force=True)
def test_chmod(self): self._assert_execute_call( [['chmod', '-R', '=064', 'path']], [{'run_as_root': True, 'root_helper': 'sudo'}], operating_system.chmod, None, 'path', FileMode.SET_GRP_RW_OTH_R, as_root=True) self._assert_execute_call( [['chmod', '-R', '+444', 'path']], [{'run_as_root': True, 'root_helper': 'sudo'}], operating_system.chmod, None, 'path', FileMode.ADD_READ_ALL, as_root=True) self._assert_execute_call( [['chmod', '-R', '+060', 'path']], [{'run_as_root': True, 'root_helper': 'sudo'}], operating_system.chmod, None, 'path', FileMode.ADD_GRP_RW, as_root=True) self._assert_execute_call( [['chmod', '-R', '=777', 'path']], [{'run_as_root': True, 'root_helper': 'sudo'}], operating_system.chmod, None, 'path', FileMode.SET_FULL, as_root=True) self._assert_execute_call( [['chmod', '-f', '=777', 'path']], [{'run_as_root': True, 'root_helper': 'sudo'}], operating_system.chmod, None, 'path', FileMode.SET_FULL, as_root=True, recursive=False, force=True) self._assert_execute_call( [['chmod', '-R', '=777', 'path']], [{'timeout': 100}], operating_system.chmod, None, 'path', FileMode.SET_FULL, timeout=100) self._assert_execute_call( [['chmod', '-R', '=777', 'path']], [{'run_as_root': True, 'root_helper': 'sudo', 'timeout': None}], operating_system.chmod, None, 'path', FileMode.SET_FULL, as_root=True, timeout=None) self._assert_execute_call( None, None, operating_system.chmod, ExpectedException(exception.UnprocessableEntity, "No file mode specified."), 'path', FileMode()) self._assert_execute_call( None, None, operating_system.chmod, ExpectedException(exception.UnprocessableEntity, "No file mode specified."), 'path', None) self._assert_execute_call( None, None, operating_system.chmod, ExpectedException(exception.UnprocessableEntity, "Cannot change mode of a blank file."), '', FileMode.SET_FULL) self._assert_execute_call( None, None, operating_system.chmod, ExpectedException(exception.UnprocessableEntity, "Cannot change mode of a blank file."), None, FileMode.SET_FULL) self._assert_execute_call( None, None, operating_system.chmod, ExpectedException(UnknownArgumentError, "Got unknown keyword args: {'_unknown_kw': 0}"), 'path', FileMode.SET_FULL, _unknown_kw=0)
def post_restore(self): operating_system.chmod(self.PGSQL_DATA_DIR, FileMode.OCTAL_MODE("0700"), as_root=True, recursive=True, force=True)
def post_restore(self): operating_system.chmod(self.pgsql_data_dir, FileMode.OCTAL_MODE("0700"), as_root=True, recursive=True, force=True)