Automatically add prechecks scripts to patch
When building a patch that includes the software package, the deploy-precheck script and the upgrade_utils.py will be automatically fetched from .deb file and included directly inside the patch. With this there is no need to have element 'deploy_precheck' in XML recipe schema. Test Plan: PASS: Create patch successfully with software package included. Upload it to a AIO-SX system. Run "software deploy precheck" on the installed patch. PASS: Create patch successfully without software package included. Upload it to a AIO-SX system. Run "software deploy precheck" on the installed patch. Story: 2010676 Task: 49978 Change-Id: I9d470ed049d42880bb515320324de1e3a0e05680 Signed-off-by: Dostoievski Batista <dostoievski.albinobatista@windriver.com>
This commit is contained in:
parent
ef12b8b2ba
commit
8e93ec62d7
|
@ -20,7 +20,6 @@
|
||||||
<!-- Pre and Post install hook scripts -->
|
<!-- Pre and Post install hook scripts -->
|
||||||
<pre_install>scripts/pre-install.sh</pre_install>
|
<pre_install>scripts/pre-install.sh</pre_install>
|
||||||
<post_install>scripts/post-install.sh</post_install>
|
<post_install>scripts/post-install.sh</post_install>
|
||||||
<deploy_precheck></deploy_precheck>
|
|
||||||
<!-- Packages to be included -->
|
<!-- Packages to be included -->
|
||||||
<stx_packages>
|
<stx_packages>
|
||||||
<!-- Starlingx packages -->
|
<!-- Starlingx packages -->
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
<!-- Pre and Post install hook scripts are optional -->
|
<!-- Pre and Post install hook scripts are optional -->
|
||||||
<pre_install></pre_install>
|
<pre_install></pre_install>
|
||||||
<post_install></post_install>
|
<post_install></post_install>
|
||||||
<deploy_precheck></deploy_precheck>
|
|
||||||
<!-- Packages to be included -->
|
<!-- Packages to be included -->
|
||||||
<stx_packages>
|
<stx_packages>
|
||||||
<!-- Starlingx packages -->
|
<!-- Starlingx packages -->
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
<!-- Pre and Post install hook scripts -->
|
<!-- Pre and Post install hook scripts -->
|
||||||
<pre_install>scripts/pre-install.sh</pre_install>
|
<pre_install>scripts/pre-install.sh</pre_install>
|
||||||
<post_install>scripts/post-install.sh</post_install>
|
<post_install>scripts/post-install.sh</post_install>
|
||||||
<deploy_precheck>scripts/deploy-precheck.sh</deploy_precheck>
|
|
||||||
<!-- Packages to be included -->
|
<!-- Packages to be included -->
|
||||||
<stx_packages>
|
<stx_packages>
|
||||||
<!-- Starlingx packages -->
|
<!-- Starlingx packages -->
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
<!-- Pre and Post install hook scripts are optional -->
|
<!-- Pre and Post install hook scripts are optional -->
|
||||||
<pre_install>scripts/pre-install.sh</pre_install>
|
<pre_install>scripts/pre-install.sh</pre_install>
|
||||||
<post_install>scripts/post-install.sh</post_install>
|
<post_install>scripts/post-install.sh</post_install>
|
||||||
<deploy_precheck>scripts/deploy-precheck.sh</deploy_precheck>
|
|
||||||
<!-- Packages to be included -->
|
<!-- Packages to be included -->
|
||||||
<stx_packages>
|
<stx_packages>
|
||||||
<!-- Starlingx packages -->
|
<!-- Starlingx packages -->
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
<xs:element name="semantics" type="xs:string"/>
|
<xs:element name="semantics" type="xs:string"/>
|
||||||
<xs:element name="pre_install" type="xs:string"/>
|
<xs:element name="pre_install" type="xs:string"/>
|
||||||
<xs:element name="post_install" type="xs:string"/>
|
<xs:element name="post_install" type="xs:string"/>
|
||||||
<xs:element name="deploy_precheck" type="xs:string"/>
|
|
||||||
<xs:element name="stx_packages">
|
<xs:element name="stx_packages">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
|
|
|
@ -35,7 +35,6 @@ WARNINGS = 'warnings'
|
||||||
REBOOT_REQUIRED = 'reboot_required'
|
REBOOT_REQUIRED = 'reboot_required'
|
||||||
PRE_INSTALL = 'pre_install'
|
PRE_INSTALL = 'pre_install'
|
||||||
POST_INSTALL = 'post_install'
|
POST_INSTALL = 'post_install'
|
||||||
DEPLOY_PRECHECK = 'deploy_precheck'
|
|
||||||
UNREMOVABLE = 'unremovable'
|
UNREMOVABLE = 'unremovable'
|
||||||
REQUIRES = 'requires'
|
REQUIRES = 'requires'
|
||||||
REQUIRES_PATCH_ID = 'req_patch_id'
|
REQUIRES_PATCH_ID = 'req_patch_id'
|
||||||
|
@ -97,7 +96,6 @@ class PatchMetadata(object):
|
||||||
# strip path from pre_install and post_install scripts
|
# strip path from pre_install and post_install scripts
|
||||||
self.pre_install = self.pre_install.split('/')[-1]
|
self.pre_install = self.pre_install.split('/')[-1]
|
||||||
self.post_install = self.post_install.split('/')[-1]
|
self.post_install = self.post_install.split('/')[-1]
|
||||||
self.deploy_precheck = self.deploy_precheck.split('/')[-1]
|
|
||||||
|
|
||||||
top_tag = ET.Element(PATCH_ROOT_TAG)
|
top_tag = ET.Element(PATCH_ROOT_TAG)
|
||||||
self.__add_text_tag_to_xml(top_tag, PATCH_ID, self.patch_id)
|
self.__add_text_tag_to_xml(top_tag, PATCH_ID, self.patch_id)
|
||||||
|
@ -127,7 +125,6 @@ class PatchMetadata(object):
|
||||||
|
|
||||||
self.__add_text_tag_to_xml(top_tag, PRE_INSTALL, self.pre_install)
|
self.__add_text_tag_to_xml(top_tag, PRE_INSTALL, self.pre_install)
|
||||||
self.__add_text_tag_to_xml(top_tag, POST_INSTALL, self.post_install)
|
self.__add_text_tag_to_xml(top_tag, POST_INSTALL, self.post_install)
|
||||||
self.__add_text_tag_to_xml(top_tag, DEPLOY_PRECHECK, self.deploy_precheck)
|
|
||||||
|
|
||||||
packages_tag = ET.SubElement(top_tag, PACKAGES)
|
packages_tag = ET.SubElement(top_tag, PACKAGES)
|
||||||
for package in sorted(self.debs):
|
for package in sorted(self.debs):
|
||||||
|
@ -158,7 +155,6 @@ class PatchMetadata(object):
|
||||||
self.reboot_required = patch_recipe[REBOOT_REQUIRED]
|
self.reboot_required = patch_recipe[REBOOT_REQUIRED]
|
||||||
self.pre_install = self.check_script_path(patch_recipe[PRE_INSTALL])
|
self.pre_install = self.check_script_path(patch_recipe[PRE_INSTALL])
|
||||||
self.post_install = self.check_script_path(patch_recipe[POST_INSTALL])
|
self.post_install = self.check_script_path(patch_recipe[POST_INSTALL])
|
||||||
self.deploy_precheck = self.check_script_path(patch_recipe[DEPLOY_PRECHECK])
|
|
||||||
self.unremovable = patch_recipe[UNREMOVABLE]
|
self.unremovable = patch_recipe[UNREMOVABLE]
|
||||||
self.status = patch_recipe[STATUS]
|
self.status = patch_recipe[STATUS]
|
||||||
if 'id' in patch_recipe[REQUIRES]:
|
if 'id' in patch_recipe[REQUIRES]:
|
||||||
|
|
|
@ -40,7 +40,8 @@ PATCH_OUTPUT = os.path.join(BUILD_ROOT, "patch_output")
|
||||||
PATCH_SCRIPTS = {
|
PATCH_SCRIPTS = {
|
||||||
"PRE_INSTALL": "pre-install.sh",
|
"PRE_INSTALL": "pre-install.sh",
|
||||||
"POST_INSTALL": "post-install.sh",
|
"POST_INSTALL": "post-install.sh",
|
||||||
"DEPLOY_PRECHECK": "deploy-precheck.sh"
|
"DEPLOY_PRECHECK": "deploy-precheck",
|
||||||
|
"UPGRADE_UTILS": "upgrade_utils.py",
|
||||||
}
|
}
|
||||||
|
|
||||||
class PatchBuilder(object):
|
class PatchBuilder(object):
|
||||||
|
@ -92,7 +93,7 @@ class PatchBuilder(object):
|
||||||
|
|
||||||
pre_install = self.metadata.pre_install
|
pre_install = self.metadata.pre_install
|
||||||
post_install = self.metadata.post_install
|
post_install = self.metadata.post_install
|
||||||
deploy_precheck = self.metadata.deploy_precheck
|
|
||||||
# pre/post install scripts
|
# pre/post install scripts
|
||||||
if pre_install:
|
if pre_install:
|
||||||
logger.debug(f"Copying pre-install script: {pre_install}")
|
logger.debug(f"Copying pre-install script: {pre_install}")
|
||||||
|
@ -102,9 +103,23 @@ class PatchBuilder(object):
|
||||||
logger.debug(f"Copying post-install script: {post_install}")
|
logger.debug(f"Copying post-install script: {post_install}")
|
||||||
self.copy_script("POST_INSTALL", post_install)
|
self.copy_script("POST_INSTALL", post_install)
|
||||||
|
|
||||||
if deploy_precheck:
|
# if the patch includes the 'software' package we need to make deploy-precheck
|
||||||
logger.debug(f"Copying deploy pre-check script: {deploy_precheck}")
|
# and upgrade_utils.py from .deb file accessible directly from patch file
|
||||||
self.copy_script("DEPLOY_PRECHECK", deploy_precheck)
|
if 'software' in self.metadata.stx_packages:
|
||||||
|
# create temporary folder to hold our files until we copy them to the patch
|
||||||
|
tmp_folder = tempfile.mkdtemp(prefix='deb_')
|
||||||
|
|
||||||
|
logger.info(f"Patch includes the software package, getting scripts from deb file...")
|
||||||
|
path_deployprecheck = self.get_file_from_deb(dl_dir, tmp_folder, 'software', 'deploy-precheck')
|
||||||
|
logger.debug(f"Copying deploy-precheck script: {path_deployprecheck}")
|
||||||
|
self.copy_script("DEPLOY_PRECHECK", path_deployprecheck)
|
||||||
|
|
||||||
|
path_upgradeutils = self.get_file_from_deb(dl_dir, tmp_folder, 'software', 'upgrade_utils.py')
|
||||||
|
logger.debug(f"Copying upgrade_utils.py script: {path_upgradeutils}")
|
||||||
|
self.copy_script("UPGRADE_UTILS", path_upgradeutils)
|
||||||
|
|
||||||
|
# we remove temporary folder
|
||||||
|
shutil.rmtree(tmp_folder)
|
||||||
|
|
||||||
if not pre_install and not post_install and self.metadata.reboot_required == 'N':
|
if not pre_install and not post_install and self.metadata.reboot_required == 'N':
|
||||||
logger.warn("In service patch without restart scripts provided")
|
logger.warn("In service patch without restart scripts provided")
|
||||||
|
@ -135,6 +150,54 @@ class PatchBuilder(object):
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Script type provided is not valid one: {script_type}")
|
raise ValueError(f"Script type provided is not valid one: {script_type}")
|
||||||
|
|
||||||
|
def get_file_from_deb(self, download_dir, tmp_folder, package_name, script_name):
|
||||||
|
'''Get specific file from inside .deb file and make it available in temporary folder
|
||||||
|
|
||||||
|
:param download_dir: Full path of directory where the deb is downloaded
|
||||||
|
:param tmp_folder: Temporary folder where file will be available
|
||||||
|
:param package_name: Name of the package
|
||||||
|
:param script_name: Name of file that should be searched
|
||||||
|
|
||||||
|
:returns string: full path for the script file
|
||||||
|
'''
|
||||||
|
# from download dir, search for {package_name}_*.deb package
|
||||||
|
pkg_name = None
|
||||||
|
for file in os.listdir(download_dir):
|
||||||
|
if file.startswith(f'{package_name}_') and file.endswith('.deb'):
|
||||||
|
pkg_name = file
|
||||||
|
|
||||||
|
if not pkg_name:
|
||||||
|
erro_msg = f'Unable to find {package_name} package inside download folder'
|
||||||
|
logger.error(erro_msg)
|
||||||
|
raise FileNotFoundError(erro_msg)
|
||||||
|
|
||||||
|
deb_path = os.path.join(download_dir, pkg_name)
|
||||||
|
|
||||||
|
# we copy deb to the temporary folder
|
||||||
|
shutil.copy(deb_path, tmp_folder)
|
||||||
|
|
||||||
|
# We first unpack deb file and get data.tar.xz from there
|
||||||
|
cmd = ['ar', '-x', os.path.join(tmp_folder, pkg_name)]
|
||||||
|
subprocess.check_call(cmd, cwd=tmp_folder)
|
||||||
|
|
||||||
|
# With data.tar.xz, we try to find script file
|
||||||
|
data_tar = tarfile.open(os.path.join(tmp_folder, 'data.tar.xz'))
|
||||||
|
script_tarpath = None
|
||||||
|
for member in data_tar.getnames():
|
||||||
|
if member.endswith(script_name):
|
||||||
|
script_tarpath = member
|
||||||
|
|
||||||
|
if not script_tarpath:
|
||||||
|
erro_msg = f"Unable to find {script_name} inside data tar."
|
||||||
|
logger.error(erro_msg)
|
||||||
|
raise FileNotFoundError(erro_msg)
|
||||||
|
|
||||||
|
# We extract said file to the temporary folder
|
||||||
|
data_tar.extract(script_tarpath, path=tmp_folder)
|
||||||
|
data_tar.close()
|
||||||
|
|
||||||
|
return os.path.join(tmp_folder, script_tarpath)
|
||||||
|
|
||||||
def __sign_and_pack(self, patch_file):
|
def __sign_and_pack(self, patch_file):
|
||||||
"""
|
"""
|
||||||
Generates the patch signatures and pack the .patch file
|
Generates the patch signatures and pack the .patch file
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Copyright (c) 2023 Wind River Systems, Inc.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# The patching subsystem provides a patch-functions bash source file
|
|
||||||
# with useful function and variable definitions.
|
|
||||||
#
|
|
||||||
. /etc/patching/patch-functions
|
|
||||||
|
|
||||||
#
|
|
||||||
# Declare an overall script return code
|
|
||||||
#
|
|
||||||
declare -i GLOBAL_RC=$PATCH_STATUS_OK
|
|
||||||
|
|
||||||
echo "Pre deploy check script"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Exit the script with the overall return code
|
|
||||||
#
|
|
||||||
exit $GLOBAL_RC
|
|
Loading…
Reference in New Issue