StarlingX Installation/Update/Patching/Backup/Restore
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
10 KiB

# Copyright (c) 2022 Wind River Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
Debian Build Test Patches:
PATCH A) Reboot required - all nodes
Update package - logmgmt
rebuild the pkg
build-image to generate a new commit in the build ostree_repo
build a patch
PATCH B) In Service patch
Update the metadata
Uses the example-restart script
Uses the same ostree commit as PATCH A so they can't be applied together
build a patch
PATCH C) Patch with dependency (reboot required, depends on PATCH A)
build PATCH A
update package - logmgmt
build-image to generate a new commit in the build ostree_repo
build Patch C (requires A)
debchange (devscripts) - Tool for maintenance of the debian/changelog file in a source package
Steps to run:
# Setup debian build env
# For more information about how to setup the environment:
export PROJECT="stx-debian-build"
export STX_BUILD_HOME="/localdisk/designer/${USER}/${PROJECT}"
# Initialize the build containers
stx control start
./ --help
import argparse
import logging
import os
import shutil
import subprocess
import sys
from requests import patch
sys.path.insert(0, "../cgcs-patch")
from cgcs_make_patch.make_patch import PatchBuilder # noqa: E402 pylint: disable=wrong-import-position
from cgcs_make_patch.make_patch import PatchRecipeData # noqa: E402 pylint: disable=wrong-import-position
format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
log = logging.getLogger('build_test_patches')
def run_cmd(cmd):
Run a cmd and return
param command: string representing the command to be executed
log.debug("Running: %s", cmd)
class TestPatchInitException(Exception):
"""TestPatch initialization error"""
class TestPatchCreationException(Exception):
"""Patch creation error"""
class TestPatchBuilder():
Build test patches
def __init__(self, sw_version):
self.project = os.environ.get("PROJECT")
self.build_home = os.environ.get("STX_BUILD_HOME")
self.repo = os.path.join(self.build_home, "repo")
self.repo_root = os.path.join(self.repo, "cgcs-root")
self.patch_repo_base = os.path.join(self.repo_root, "stx/update")
self.sw_version = sw_version
self.restart_script = os.path.join(self.patch_repo_base, "patch-scripts/EXAMPLE_0001/scripts/example-restart")
except TestPatchInitException:
log.exception("TestPatchBuilder initialization failure")
def __upversion_pkg(self, pkg_dir):
Updates changelog version in pkg_dir/debian/deb_folder
""""Upversioning package %s", pkg_dir)
# cd pkg_dir/debian/deb_folder; dch -q "PATCH TEST" --changelog changelog
pwd = os.getcwd()
# Increase the change log version
cmd = "dch -q 'PATCH TEST' --changelog debian/deb_folder/changelog"
ret = run_cmd(cmd)
if ret.returncode != 0:
raise Exception("Error while changing the package version")
def __delete_dir(self, dir_path):
Deletes a directory - called when cleaning up the cloned ostree
param dir_path: Path to the directory
if os.path.isdir(dir_path):"removing %s", dir_path)
def build_pkg(self, pkg_name):
Build package
os.chdir(os.path.join(self.repo, "stx-tools"))
cmd = f'''
source import-stx
stx shell -c "build-pkgs -c -p {pkg_name}"
ret = run_cmd(cmd)"Build pkgs return code %s", ret.returncode)
if ret.returncode != 0:
raise Exception("Failed to build packages")
def build_image(self):
Build image - generates new ostree commit
cmd = '''
source import-stx
stx shell -c "build-image"
ret = run_cmd(cmd)"Build image return code %s", ret.returncode)
if ret.returncode != 0:
raise Exception("Failed to build image")
def update_pkg(self, pname):
Make a change on the logmgmt package and upversions it
param pname: patch name that is added to the script and can be used as patch validation
pkg_name = "logmgmt""Updating package %s", pkg_name)
pkg_dir = os.path.join(self.repo_root, "stx/utilities/utilities", pkg_name)
pkg_script = os.path.join(pkg_dir, "scripts/init.d/logmgmt")
# Insert a message into /etc/init.d/$(basename $SCRIPT)
cmd = "sed -i 's|start).*|start) logger -t \\$(basename \\$0) \"" + pname + " patch is applied\"|' " + pkg_script
# build the pkg to apply the change
def create_test_patches(self, pname, requires=False, inservice=False, formal=False):
Creates test patches:
RR, INSVC and RR_Requires
param pname: Patch ID and file name
param requires: If set it will build the 2nd patch
param inservice: If set it will build the insvc patch
param formal: Signs the patch with formal key
ostree_clone_name = "ostree_repo_patch"
patch_builder = PatchBuilder()
# Generating ostree_repo clone
# Update pkg
self.update_pkg(pname)"Generating RR patch for all nodes")
# build image to trigger a new ostree commit
patch_data = PatchRecipeData()
patch_data.patch_id = pname + "_RR_ALL_NODES"
patch_data.sw_version = self.sw_version
patch_data.metadata = {
"DESCRIPTION": "Test patch",
"INSTALL_INSTRUCTIONS": "Sample instructions",
"WARNINGS": "Sample Warning",
# Create a patch"Creating RR patch %s", patch_data.patch_id)
patch_builder.create_patch(patch_data, ostree_clone_name, formal)"RR Patch build done")
if inservice:
patch_data = PatchRecipeData()
patch_data.patch_id = pname + "_NRR_INSVC"
patch_data.metadata = {
"DESCRIPTION": "Test In Service patch",
"INSTALL_INSTRUCTIONS": "Sample instructions",
"WARNINGS": "Sample Warning",
patch_data.restart_script["full_path"] = self.restart_script
patch_data.restart_script["metadata_name"] = os.path.basename(self.restart_script)"Creating inservice patch %s", patch_data.patch_id)"restart script %s", patch_data.restart_script["full_path"])
patch_builder.create_patch(patch_data, ostree_clone_name, formal)"Inservice patch build done")
clone_repo_path = os.path.join(patch_builder.deploy_dir, ostree_clone_name)
if requires:
# Build the 2nd patch which will follow similar steps but will set the requires flag
# Update pkg
self.update_pkg(pname + "_REQUIRES")
# build image to trigger a new ostree commit
# Update patch ID and set requires
patch_data = PatchRecipeData()
patch_data.patch_id = pname + "_RR_ALL_NODES_REQUIRES"
patch_data.metadata = {
"DESCRIPTION": "Test patch with dependency",
"INSTALL_INSTRUCTIONS": "Sample instructions",
"WARNINGS": "Sample Warning",
# Create a patch"Creating RR Requires patch %s", patch_data.patch_id)
patch_builder.create_patch(patch_data, ostree_clone_name, formal)"Requires patch build done")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Debian build_test_patches")
parser.add_argument("-sw", "--software-version", type=str, help="Patch Software version, will prefix the patch name", default=None, required=True)
parser.add_argument("-r", "--requires", action="store_true", help="Builds the 2nd patch which requires the rr_patch")
parser.add_argument("-i", "--inservice", action="store_true", help="Builds the in service patch")
parser.add_argument("-f", "--formal", action="store_true", help="Signs the patch with formal key")
args = parser.parse_args()
log.debug("Args: %s", args)
try:"Building test patches")
patch_name = args.software_version
test_patch_builder = TestPatchBuilder(args.software_version)
test_patch_builder.create_test_patches(patch_name, args.requires, args.inservice, args.formal)"Test patch build completed")
except TestPatchCreationException:
log.exception("Error while creating test patches")