Add UID/GID configurations for each datastore
When trove prepares a container, it grants permissions for folders with the default user/group "database" (ID 1001). However, some Docker images require a different user for provisioning the database. Therefore, we need to make it flexible so that the database container can run with the required user and group, regardless of the default settings. Story: #2010827 Task: #48386 Change-Id: Ie0268951db7a9e711089714cecf7fbf311eecec8
This commit is contained in:
parent
be9bd3f3a0
commit
27778a90d0
@ -303,6 +303,25 @@ Some config options specifically for trove guest agent:
|
||||
docker_image = your-registry/your-repo/mysql
|
||||
backup_docker_image = your-registry/your-repo/db-backup-mysql
|
||||
|
||||
* Setting username, uid, gid for each datastore
|
||||
|
||||
Currently, when a database container is running, it is owned by user:
|
||||
database (UID: 1001) and group: database (GID: 1001).
|
||||
|
||||
In some cases, you may need to set the owner of files,
|
||||
directories or container to adapt to your own datastore image.
|
||||
|
||||
To achieve this, you can configure the option
|
||||
database_service_uname, database_service_uid, database_service_gid
|
||||
in trove-guestagent.conf with following:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[<datastore_manage>]
|
||||
database_service_uid = 1001
|
||||
database_service_gid = 0
|
||||
database_service_uname = postgres
|
||||
|
||||
Make Trove work with multiple versions for each datastore
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
When Trove do a backup/restore actions, The Trove guest agent pulls container
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add support of setting owner,uid,gid for each datastore instances
|
||||
by configuring database_service_uname,
|
||||
database_service_uid and database_service_gid
|
||||
Story 2010827 <https://storyboard.openstack.org/#!/story/2010827>
|
@ -83,8 +83,11 @@ def main():
|
||||
|
||||
# Create user and group for running docker container.
|
||||
LOG.info('Creating user and group for database service')
|
||||
uid = cfg.get_configuration_property('database_service_uid')
|
||||
operating_system.create_user('database', uid)
|
||||
uid = CONF.get(CONF.datastore_manager
|
||||
).database_service_uid or CONF.database_service_uid
|
||||
gid = CONF.get(CONF.datastore_manager).database_service_gid or uid
|
||||
uname = CONF.get(CONF.datastore_manager).database_service_uname
|
||||
operating_system.create_user(uname, user_id=uid, group_id=gid)
|
||||
|
||||
# Mount device if needed.
|
||||
# When doing rebuild, the device should be already formatted but not
|
||||
@ -97,9 +100,8 @@ def main():
|
||||
device_path, mount_point)
|
||||
device.format()
|
||||
device.mount(mount_point)
|
||||
operating_system.chown(mount_point, CONF.database_service_uid,
|
||||
CONF.database_service_uid,
|
||||
recursive=True, as_root=True)
|
||||
operating_system.chown(
|
||||
mount_point, uid, gid, recursive=True, as_root=True)
|
||||
|
||||
# rpc module must be loaded after decision about thread monkeypatching
|
||||
# because if thread module is not monkeypatched we can't use eventlet
|
||||
|
@ -544,6 +544,12 @@ mysql_group = cfg.OptGroup(
|
||||
'mysql', title='MySQL options',
|
||||
help="Oslo option group designed for MySQL datastore")
|
||||
mysql_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -621,6 +627,12 @@ percona_group = cfg.OptGroup(
|
||||
'percona', title='Percona options',
|
||||
help="Oslo option group designed for Percona datastore")
|
||||
percona_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -690,6 +702,12 @@ pxc_group = cfg.OptGroup(
|
||||
'pxc', title='Percona XtraDB Cluster options',
|
||||
help="Oslo option group designed for Percona XtraDB Cluster datastore")
|
||||
pxc_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -771,6 +789,12 @@ redis_group = cfg.OptGroup(
|
||||
'redis', title='Redis options',
|
||||
help="Oslo option group designed for Redis datastore")
|
||||
redis_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -830,6 +854,12 @@ cassandra_group = cfg.OptGroup(
|
||||
'cassandra', title='Cassandra options',
|
||||
help="Oslo option group designed for Cassandra datastore")
|
||||
cassandra_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -914,6 +944,12 @@ couchbase_group = cfg.OptGroup(
|
||||
'couchbase', title='Couchbase options',
|
||||
help="Oslo option group designed for Couchbase datastore")
|
||||
couchbase_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -959,6 +995,12 @@ mongodb_group = cfg.OptGroup(
|
||||
'mongodb', title='MongoDB options',
|
||||
help="Oslo option group designed for MongoDB datastore")
|
||||
mongodb_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -1038,6 +1080,12 @@ postgresql_group = cfg.OptGroup(
|
||||
'postgresql', title='PostgreSQL options',
|
||||
help="Oslo option group for the PostgreSQL datastore.")
|
||||
postgresql_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt(
|
||||
'enable_clean_wal_archives',
|
||||
default=True,
|
||||
@ -1123,6 +1171,12 @@ couchdb_group = cfg.OptGroup(
|
||||
'couchdb', title='CouchDB options',
|
||||
help="Oslo option group designed for CouchDB datastore")
|
||||
couchdb_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -1174,6 +1228,12 @@ vertica_group = cfg.OptGroup(
|
||||
'vertica', title='Vertica options',
|
||||
help="Oslo option group designed for Vertica datastore")
|
||||
vertica_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -1241,6 +1301,12 @@ db2_group = cfg.OptGroup(
|
||||
'db2', title='DB2 options',
|
||||
help="Oslo option group designed for DB2 datastore")
|
||||
db2_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
@ -1284,6 +1350,12 @@ mariadb_group = cfg.OptGroup(
|
||||
'mariadb', title='MariaDB options',
|
||||
help="Oslo option group designed for MariaDB datastore")
|
||||
mariadb_opts = [
|
||||
cfg.StrOpt('database_service_uname', default='database',
|
||||
help='The name of database service user.'),
|
||||
cfg.StrOpt('database_service_uid',
|
||||
help='The UID of database service user.'),
|
||||
cfg.StrOpt('database_service_gid',
|
||||
help='The GID of database service user.'),
|
||||
cfg.BoolOpt('icmp', default=False,
|
||||
help='Whether to permit ICMP.',
|
||||
deprecated_for_removal=True),
|
||||
|
@ -71,9 +71,10 @@ class MySqlManager(manager.Manager):
|
||||
"""This is called from prepare in the base class."""
|
||||
data_dir = mount_point + '/data'
|
||||
self.app.stop_db()
|
||||
operating_system.ensure_directory(data_dir,
|
||||
user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid,
|
||||
operating_system.ensure_directory(
|
||||
data_dir,
|
||||
user=self.app.database_service_uid,
|
||||
group=self.app.database_service_gid,
|
||||
as_root=True)
|
||||
# This makes sure the include dir is created.
|
||||
self.app.set_data_dir(data_dir)
|
||||
@ -223,9 +224,11 @@ class MySqlManager(manager.Manager):
|
||||
# Allow database service user to access the temporary files.
|
||||
try:
|
||||
for file in [init_file.name, err_file.name]:
|
||||
operating_system.chown(file, CONF.database_service_uid,
|
||||
CONF.database_service_uid, force=True,
|
||||
as_root=True)
|
||||
operating_system.chown(
|
||||
file,
|
||||
self.app.database_service_uid,
|
||||
self.app.database_service_gid,
|
||||
force=True, as_root=True)
|
||||
except Exception as err:
|
||||
LOG.error('Failed to change file owner, error: %s', str(err))
|
||||
for file in [init_file.name, err_file.name]:
|
||||
@ -338,8 +341,8 @@ class MySqlManager(manager.Manager):
|
||||
mount_point = CONF.get(CONF.datastore_manager).mount_point
|
||||
data_dir = mount_point + '/data'
|
||||
operating_system.ensure_directory(data_dir,
|
||||
user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid,
|
||||
user=self.app.database_service_uid,
|
||||
group=self.app.database_service_gid,
|
||||
as_root=True)
|
||||
# This makes sure the include dir is created.
|
||||
self.app.set_data_dir(data_dir)
|
||||
|
@ -445,7 +445,7 @@ class BaseMySqlApp(service.BaseDbApp):
|
||||
return self._configuration_manager
|
||||
|
||||
self._configuration_manager = ConfigurationManager(
|
||||
MYSQL_CONFIG, CONF.database_service_uid, CONF.database_service_uid,
|
||||
MYSQL_CONFIG, self.database_service_uid, self.database_service_gid,
|
||||
service.BaseDbApp.CFG_CODEC, requires_root=True,
|
||||
override_strategy=ImportOverrideStrategy(CNF_INCLUDE_DIR, CNF_EXT)
|
||||
)
|
||||
@ -591,14 +591,14 @@ class BaseMySqlApp(service.BaseDbApp):
|
||||
root_pass = utils.generate_random_password()
|
||||
|
||||
# Get uid and gid
|
||||
user = "%s:%s" % (CONF.database_service_uid, CONF.database_service_uid)
|
||||
user = "%s:%s" % (self.database_service_uid, self.database_service_gid)
|
||||
|
||||
# Create folders for mysql on localhost
|
||||
for folder in ['/etc/mysql', constants.MYSQL_HOST_SOCKET_PATH,
|
||||
'/etc/mysql/mysql.conf.d']:
|
||||
operating_system.ensure_directory(
|
||||
folder, user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid, force=True,
|
||||
folder, user=self.database_service_uid,
|
||||
group=self.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
|
||||
volumes = {
|
||||
@ -678,8 +678,8 @@ class BaseMySqlApp(service.BaseDbApp):
|
||||
for folder in ['/etc/mysql', constants.MYSQL_HOST_SOCKET_PATH,
|
||||
'/etc/mysql/mysql.conf.d']:
|
||||
operating_system.ensure_directory(
|
||||
folder, user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid, force=True,
|
||||
folder, user=self.database_service_uid,
|
||||
group=self.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
|
||||
try:
|
||||
@ -742,8 +742,8 @@ class BaseMySqlApp(service.BaseDbApp):
|
||||
|
||||
LOG.debug('Deleting ib_logfile files after restore from backup %s',
|
||||
backup_id)
|
||||
operating_system.chown(restore_location, CONF.database_service_uid,
|
||||
CONF.database_service_uid, force=True,
|
||||
operating_system.chown(restore_location, self.database_service_uid,
|
||||
self.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
self.wipe_ib_logfiles()
|
||||
|
||||
|
@ -123,13 +123,11 @@ class PostgresManager(manager.Manager):
|
||||
device_path, mount_point, backup_info,
|
||||
config_contents, root_password, overrides,
|
||||
cluster_config, snapshot, ds_version=None):
|
||||
operating_system.ensure_directory(self.app.datadir,
|
||||
user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid,
|
||||
as_root=True)
|
||||
operating_system.ensure_directory(service.WAL_ARCHIVE_DIR,
|
||||
user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid,
|
||||
for datadir in [self.app.datadir, service.WAL_ARCHIVE_DIR]:
|
||||
operating_system.ensure_directory(
|
||||
datadir,
|
||||
user=self.app.database_service_uid,
|
||||
group=self.app.database_service_gid,
|
||||
as_root=True)
|
||||
|
||||
LOG.info('Preparing database config files')
|
||||
@ -149,9 +147,11 @@ class PostgresManager(manager.Manager):
|
||||
signal_file = f"{self.app.datadir}/recovery.signal"
|
||||
operating_system.execute_shell_cmd(
|
||||
f"touch {signal_file}", [], shell=True, as_root=True)
|
||||
operating_system.chown(signal_file, CONF.database_service_uid,
|
||||
CONF.database_service_uid, force=True,
|
||||
as_root=True)
|
||||
operating_system.chown(
|
||||
signal_file,
|
||||
user=self.app.database_service_uid,
|
||||
group=self.app.database_service_gid,
|
||||
force=True, as_root=True)
|
||||
|
||||
if snapshot:
|
||||
# This instance is a replica
|
||||
@ -198,7 +198,8 @@ class PostgresManager(manager.Manager):
|
||||
}
|
||||
|
||||
def is_log_enabled(self, logname):
|
||||
return self.configuration_manager.get_value('logging_collector', False)
|
||||
return self.configuration_manager.get_value(
|
||||
'logging_collector', default=False)
|
||||
|
||||
def create_backup(self, context, backup_info):
|
||||
"""Create backup for the database.
|
||||
|
@ -85,8 +85,8 @@ class PgSqlApp(service.BaseDbApp):
|
||||
|
||||
self._configuration_manager = configuration.ConfigurationManager(
|
||||
CONFIG_FILE,
|
||||
CONF.database_service_uid,
|
||||
CONF.database_service_uid,
|
||||
self.database_service_uid,
|
||||
self.database_service_gid,
|
||||
stream_codecs.KeyValueCodec(
|
||||
value_quoting=True,
|
||||
bool_case=stream_codecs.KeyValueCodec.BOOL_LOWER,
|
||||
@ -143,8 +143,8 @@ class PgSqlApp(service.BaseDbApp):
|
||||
stream_codecs.PropertiesCodec(string_mappings={'\t': None}),
|
||||
as_root=True)
|
||||
operating_system.chown(HBA_CONFIG_FILE,
|
||||
CONF.database_service_uid,
|
||||
CONF.database_service_uid,
|
||||
self.database_service_uid,
|
||||
self.database_service_gid,
|
||||
as_root=True)
|
||||
operating_system.chmod(HBA_CONFIG_FILE,
|
||||
operating_system.FileMode.SET_USR_RO,
|
||||
@ -174,14 +174,14 @@ class PgSqlApp(service.BaseDbApp):
|
||||
postgres_pass = utils.generate_random_password()
|
||||
|
||||
# Get uid and gid
|
||||
user = "%s:%s" % (CONF.database_service_uid, CONF.database_service_uid)
|
||||
user = "%s:%s" % (self.database_service_uid, self.database_service_gid)
|
||||
|
||||
# Create folders for postgres on localhost
|
||||
for folder in ['/etc/postgresql',
|
||||
constants.POSTGRESQL_HOST_SOCKET_PATH]:
|
||||
operating_system.ensure_directory(
|
||||
folder, user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid, force=True,
|
||||
folder, user=self.database_service_uid,
|
||||
group=self.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
|
||||
volumes = {
|
||||
@ -244,8 +244,8 @@ class PgSqlApp(service.BaseDbApp):
|
||||
for folder in ['/etc/postgresql',
|
||||
constants.POSTGRESQL_HOST_SOCKET_PATH]:
|
||||
operating_system.ensure_directory(
|
||||
folder, user=CONF.database_service_uid,
|
||||
group=CONF.database_service_uid, force=True,
|
||||
folder, user=self.database_service_uid,
|
||||
group=self.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
|
||||
try:
|
||||
@ -311,8 +311,8 @@ class PgSqlApp(service.BaseDbApp):
|
||||
raise Exception(msg)
|
||||
|
||||
for dir in [WAL_ARCHIVE_DIR, self.datadir]:
|
||||
operating_system.chown(dir, CONF.database_service_uid,
|
||||
CONF.database_service_uid, force=True,
|
||||
operating_system.chown(dir, self.database_service_uid,
|
||||
self.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
|
||||
def is_replica(self):
|
||||
@ -341,7 +341,7 @@ class PgSqlApp(service.BaseDbApp):
|
||||
def pg_rewind(self, conn_info):
|
||||
docker_image = CONF.get(CONF.datastore_manager).docker_image
|
||||
image = f'{docker_image}:{CONF.datastore_version}'
|
||||
user = "%s:%s" % (CONF.database_service_uid, CONF.database_service_uid)
|
||||
user = "%s:%s" % (self.database_service_uid, self.database_service_gid)
|
||||
volumes = {
|
||||
constants.POSTGRESQL_HOST_SOCKET_PATH:
|
||||
{"bind": "/var/run/postgresql", "mode": "rw"},
|
||||
|
@ -562,3 +562,13 @@ class BaseDbApp(object):
|
||||
sent=timeutils.utcnow_ts(microsecond=True),
|
||||
**backup_state)
|
||||
LOG.debug("Updated state for %s to %s.", backup_id, backup_state)
|
||||
|
||||
@property
|
||||
def database_service_uid(self):
|
||||
return cfg.get_configuration_property(
|
||||
'database_service_uid') or CONF.database_service_uid
|
||||
|
||||
@property
|
||||
def database_service_gid(self):
|
||||
return cfg.get_configuration_property(
|
||||
'database_service_gid') or self.database_service_uid
|
||||
|
@ -41,8 +41,9 @@ class PostgresqlReplicationStreaming(base.Replication):
|
||||
"""
|
||||
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.chown(pwfile, user=service.database_service_uid,
|
||||
group=service.database_service_gid,
|
||||
as_root=True)
|
||||
operating_system.chmod(pwfile, FileMode.SET_USR_RWX(),
|
||||
as_root=True)
|
||||
LOG.debug(f"File {pwfile} created")
|
||||
@ -108,8 +109,9 @@ class PostgresqlReplicationStreaming(base.Replication):
|
||||
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)
|
||||
user=service.database_service_uid,
|
||||
group=service.database_service_gid,
|
||||
as_root=True)
|
||||
operating_system.chmod(pg_service.HBA_CONFIG_FILE,
|
||||
FileMode.SET_USR_RWX(),
|
||||
as_root=True)
|
||||
@ -166,8 +168,8 @@ class PostgresqlReplicationStreaming(base.Replication):
|
||||
signal_file = f"{service.datadir}/standby.signal"
|
||||
operating_system.execute_shell_cmd(
|
||||
f"touch {signal_file}", [], shell=True, as_root=True)
|
||||
operating_system.chown(signal_file, CONF.database_service_uid,
|
||||
CONF.database_service_uid, force=True,
|
||||
operating_system.chown(signal_file, service.database_service_uid,
|
||||
service.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
LOG.debug("Standby signal file created")
|
||||
|
||||
@ -217,8 +219,8 @@ class PostgresqlReplicationStreaming(base.Replication):
|
||||
signal_file = f"{service.datadir}/standby.signal"
|
||||
operating_system.execute_shell_cmd(
|
||||
f"touch {signal_file}", [], shell=True, as_root=True)
|
||||
operating_system.chown(signal_file, CONF.database_service_uid,
|
||||
CONF.database_service_uid, force=True,
|
||||
operating_system.chown(signal_file, service.database_service_uid,
|
||||
service.database_service_gid, force=True,
|
||||
as_root=True)
|
||||
LOG.debug("Standby signal file created")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user