Add option for activation scripts on patch build

This change adds the option 'activation scripts' to the patch recipe,
allowing the user to add one or multiples scripts that will be copied to
the patch and added to the metadata.

Test plan:
    PASS - Create patch with one activation script, check if file is on
    patch and check value in the patch's metadata.
    PASS - Create patch with multiple activation scripts, check if files
    are inside the patch and check values in the patch's metadata.
    PASS - Create patch without any activation script, check if files
    are inside the patch and check if value in the patch's metadata.
    PASS - Check if patch-builder fails when patch recipe doesn't have
    activate script element.

Story: 2010676
Task: 51239

Change-Id: I7073f59dfd7eefa0986a39fd70d4207bb437c9ba
Signed-off-by: Dostoievski Batista <dostoievski.albinobatista@windriver.com>
This commit is contained in:
Dostoievski Batista 2024-10-31 15:04:25 -03:00
parent e89bdfc4c1
commit c1fa37d541
8 changed files with 58 additions and 2 deletions

View File

@ -17,6 +17,7 @@
-->
</requires>
<semantics></semantics>
<activation_scripts></activation_scripts>
<!-- Pre and Post install hook scripts -->
<!-- Both fields require the full path to hook scripts -->
<pre_install>scripts/pre-install.sh</pre_install>

View File

@ -12,6 +12,7 @@
<status>DEV</status>
<requires></requires>
<semantics></semantics>
<activation_scripts></activation_scripts>
<!-- Pre and Post install hook scripts are optional -->
<!-- Both fields require the full path to hook scripts -->
<pre_install></pre_install>

View File

@ -17,6 +17,7 @@
-->
</requires>
<semantics></semantics>
<activation_scripts></activation_scripts>
<!-- Pre and Post install hook scripts -->
<!-- Both fields require the full path to hook scripts -->
<pre_install>scripts/pre-install.sh</pre_install>

View File

@ -17,6 +17,7 @@
-->
</requires>
<semantics></semantics>
<activation_scripts></activation_scripts>
<!-- Pre and Post install hook scripts are optional -->
<!-- Both fields require the full path to hook scripts -->
<pre_install>scripts/pre-install.sh</pre_install>

View File

@ -39,9 +39,16 @@ The patch builder requires the following tags in the input xml (or patch recipe)
-->
</requires>
<semantics></semantics>
<!--
Activation scripts are scripts used to help with the upgrade of containerized solutions
Leave blank if no scripts are required. Field should be full path to the files.
-->
<activation_scripts>
<script>01-example.sh</script>
</activation_scripts>
<!--
Pre and Post install hook scripts that are executed before/after patch installation.
Leave if blank if no scripts are required. Both fields require full path to the files.
Leave blank if no scripts are required. Both fields require full path to the files.
-->
<pre_install>scripts/pre-install.sh</pre_install>
<post_install>scripts/post-install.sh</post_install>

View File

@ -22,6 +22,13 @@
<xs:element name="semantics" type="xs:string"/>
<xs:element name="pre_install" type="xs:string"/>
<xs:element name="post_install" type="xs:string"/>
<xs:element name="activation_scripts">
<xs:complexType>
<xs:sequence>
<xs:element name="script" type="xs:string" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="stx_packages">
<xs:complexType>
<xs:sequence>

View File

@ -45,6 +45,7 @@ PACKAGES = 'packages'
STX_PACKAGES = 'stx_packages'
BINARY_PACKAGES = 'binary_packages'
SEMANTICS = 'semantics'
ACTIVATION_SCRIPTS = 'activation_scripts'
class PatchMetadata(object):
@ -53,6 +54,7 @@ class PatchMetadata(object):
self.stx_packages = []
self.binary_packages = []
self.requires = []
self.activation_scripts = []
# Verify if the path to the patch builder folder is set
if not PATCH_BUILDER_PATH:
@ -138,6 +140,13 @@ class PatchMetadata(object):
else:
self.__add_text_tag_to_xml(top_tag, POST_INSTALL, "")
if self.activation_scripts:
activation_scripts_tag = ET.SubElement(top_tag, ACTIVATION_SCRIPTS)
for script in self.activation_scripts:
self.__add_text_tag_to_xml(activation_scripts_tag, "script", script.split('/')[-1])
else:
self.__add_text_tag_to_xml(top_tag, ACTIVATION_SCRIPTS, "")
packages_tag = ET.SubElement(top_tag, PACKAGES)
for package in sorted(self.debs):
self.__add_text_tag_to_xml(packages_tag, "deb", package)
@ -152,6 +161,19 @@ class PatchMetadata(object):
return [tag_content]
return tag_content
def _validate_activation_script(self, script_list):
'''
Validate if scripts filename start with an integer
'''
for fullpath_script in script_list:
try:
name = os.path.basename(fullpath_script)
int(name.split("-")[0])
except Exception:
logger.error("Error while parsing the activation script:")
logger.error("Filename '%s' doesn't start with an integer." % fullpath_script)
sys.exit(1)
def parse_metadata(self, patch_recipe):
self.patch_id = f"{patch_recipe[COMPONENT]}-{patch_recipe[SW_VERSION]}"
self.sw_version = patch_recipe[SW_VERSION]
@ -172,6 +194,17 @@ class PatchMetadata(object):
if 'id' in patch_recipe[REQUIRES]:
self.requires = self.__tag_to_list(patch_recipe[REQUIRES]['id'])
self.semantics = patch_recipe[SEMANTICS]
if 'script' in patch_recipe[ACTIVATION_SCRIPTS]:
# the xml parser transform the 'script' value in string or in
# array depending on how much elements we add.
scripts_lst = []
if isinstance(patch_recipe[ACTIVATION_SCRIPTS]['script'], str):
scripts_lst.append(self.check_script_path(patch_recipe[ACTIVATION_SCRIPTS]['script']))
else:
for script in patch_recipe[ACTIVATION_SCRIPTS]['script']:
scripts_lst.append(self.check_script_path(script))
self._validate_activation_script(scripts_lst)
self.activation_scripts = scripts_lst
self.debs = []
if self.status != 'DEV' and self.status != 'REL':
@ -202,7 +235,7 @@ class PatchMetadata(object):
logger.error(f"Line {error.line}: {error.message}")
sys.exit(1)
print(xml_dict)
logger.info(xml_dict)
self.parse_metadata(xml_dict)

View File

@ -97,6 +97,11 @@ class PatchBuilder(object):
logger.debug(f"Copying post-install script: {post_install}")
self.copy_rename_script(post_install, "POST_INSTALL")
# Copy all activate scripts
if self.metadata.activation_scripts:
for script in self.metadata.activation_scripts:
self.copy_rename_script(path_to_script=script, rename=False)
# if the patch includes the 'software' package we need to make deploy-precheck
# and upgrade_utils.py from .deb file accessible directly from patch file
if 'software' in self.metadata.stx_packages: