
This commit changes all deploy start upgrade scripts to python, improve them by removing duplicated/needless code and add more logging. The summary of the changes are: - All shell scripts were converted to python code - Some scripts were renamed to follow a naming convention and as a symlink with the old name was added to them for backwards compatibility - Improved error logging and exception try/except blocks - Removed from deploy start script the unnecessary initial step to initialize a temporary ostree_repo, changing it to checkout the ostree_repo directly from the feed Test Plan: PASS: AIO-SX stx-10 to stx-11 e2e upgrade PASS: AIO-DX stx-10 to stx-11 e2e upgrade Story: 2011357 Task: 51892 Change-Id: I63c324b169883c6e9007bc99fd67b5f5b2880668 Signed-off-by: Heitor Matsui <heitorvieira.matsui@windriver.com>
146 lines
5.1 KiB
Python
146 lines
5.1 KiB
Python
#!/usr/bin/python3
|
|
#
|
|
# Copyright (c) 2023-2025 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
#
|
|
# This script is used create a 2nd instance of postgres
|
|
# on deploy start step of an upgrade. It needs a port
|
|
# number as parameter that should be different from the
|
|
# default postgres port value.
|
|
#
|
|
|
|
import configparser
|
|
import grp
|
|
import logging as LOG
|
|
import os
|
|
import pwd
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
import upgrade_utils
|
|
|
|
|
|
class PostgresDatabase:
|
|
DEFAULT_POSTGRESQL_PORT = 5432
|
|
POSTGRESQL_PATH = "/var/lib/postgresql"
|
|
POSTGRESQL_RUNTIME = "/var/run/postgresql"
|
|
BUILD_INFO_FILE = "/etc/build.info"
|
|
|
|
def __init__(self, port):
|
|
# get postgres uid and gid
|
|
self._uid = pwd.getpwnam("postgres").pw_uid
|
|
self._gid = grp.getgrnam("postgres").gr_gid
|
|
|
|
# set database port
|
|
if port == self.DEFAULT_POSTGRESQL_PORT:
|
|
LOG.error(f"Port number should be different from the "
|
|
f"default {self.DEFAULT_POSTGRESQL_PORT}")
|
|
raise
|
|
self._port = port
|
|
|
|
# set postgres bin dir
|
|
try:
|
|
process = subprocess.run(["pg_config", "--bindir"], check=True,
|
|
text=True, capture_output=True)
|
|
self._postgres_bin_dir = process.stdout.strip()
|
|
except subprocess.CalledProcessError as e:
|
|
LOG.error(f"Error getting postgres bindir: {str(e)}")
|
|
raise
|
|
|
|
# get sw_version
|
|
try:
|
|
cp = configparser.ConfigParser()
|
|
default_section = configparser.DEFAULTSECT
|
|
with open(self.BUILD_INFO_FILE, "r") as fp:
|
|
cp.read_string(f"[{default_section}]\n" + fp.read())
|
|
self._sw_version = cp.get(default_section, "SW_VERSION").strip('"')
|
|
except Exception as e:
|
|
LOG.error(f"Error getting SW_VERSION: {str(e)}")
|
|
raise
|
|
|
|
# set postgres data dir
|
|
self._postgres_data_dir = os.path.join(self.POSTGRESQL_PATH, self._sw_version)
|
|
|
|
def run(self):
|
|
# create postgres data directory
|
|
try:
|
|
shutil.rmtree(self._postgres_data_dir, ignore_errors=True)
|
|
os.makedirs(self._postgres_data_dir, mode=0o700, exist_ok=True)
|
|
os.chown(self._postgres_data_dir, uid=self._uid, gid=self._gid)
|
|
except Exception as e:
|
|
LOG.error(f"Error setting up postgres data directory: {str(e)}")
|
|
return 1
|
|
LOG.info(f"Created postgres data directory {self._postgres_data_dir}")
|
|
|
|
# initialize postgres instance
|
|
try:
|
|
cmd = ["sudo", "-u", "postgres", os.path.join(self._postgres_bin_dir, "initdb"),
|
|
"-D", self._postgres_data_dir]
|
|
subprocess.run(cmd, check=True, text=True, capture_output=True)
|
|
except subprocess.CalledProcessError as e:
|
|
LOG.error(f"Failed to initialize the postgres database: {str(e.stderr)}")
|
|
return 1
|
|
LOG.info("Initialized new postgres database instance")
|
|
|
|
# set password encryption
|
|
try:
|
|
cmd = ["sed", "-i", "s/^#\?password_encryption.*/password_encryption = 'scram-sha-256'/",
|
|
os.path.join(self._postgres_data_dir, "postgresql.conf")]
|
|
subprocess.run(cmd, check=True, text=True, capture_output=True)
|
|
except subprocess.CalledProcessError as e:
|
|
LOG.error(f"Failed to set password encryption method: {str(e.stderr)}")
|
|
return 1
|
|
LOG.info("Database password encryption changed")
|
|
|
|
# create postgres runtime directory
|
|
try:
|
|
os.makedirs(self.POSTGRESQL_RUNTIME, exist_ok=True)
|
|
os.chown(self.POSTGRESQL_RUNTIME, uid=self._uid, gid=self._gid)
|
|
except Exception as e:
|
|
LOG.error(f"Error setting up postgres runtime directory: {str(e)}")
|
|
return 1
|
|
LOG.info(f"Created postgres runtime directory {self.POSTGRESQL_RUNTIME}")
|
|
|
|
# start postgres instance
|
|
try:
|
|
cmd = ["sudo", "-u", "postgres", os.path.join(self._postgres_bin_dir, "pg_ctl"), "-D",
|
|
self._postgres_data_dir, "-o", f"-F -p {self._port}", "start"]
|
|
subprocess.run(cmd, check=True) # somehow capture_output hangs up the command
|
|
except subprocess.CalledProcessError as e:
|
|
LOG.error(f"Failed to start postgres database: {str(e)}")
|
|
return 1
|
|
LOG.info(f"Started new postgres database instance on port {self._port}")
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
upgrade_utils.configure_logging("/var/log/software.log", log_level=LOG.INFO)
|
|
|
|
port = None
|
|
error = False
|
|
for arg in range(1, len(sys.argv)):
|
|
if arg == 1:
|
|
try:
|
|
port = int(sys.argv[arg])
|
|
except ValueError:
|
|
error = True
|
|
|
|
if port is None:
|
|
usage_msg = f"usage: {sys.argv[0]} <port>"
|
|
print(usage_msg)
|
|
LOG.error(usage_msg)
|
|
sys.exit(1)
|
|
|
|
if error:
|
|
error_msg = f"Invalid port: {port}"
|
|
print(error_msg)
|
|
LOG.error(error_msg)
|
|
sys.exit(1)
|
|
|
|
postgres_database = PostgresDatabase(port)
|
|
sys.exit(postgres_database.run())
|