Patch extraction and validation enhancements
This commit updates patch extraction process to read and untar specific files. Additionally, it updates the process used to extract sw_version from deeply nested tar archives of a patch file. Test Plan: [PASS] Ran below command in DC env that invokes this code path sw-patch --os-region-name SystemController upload <patch>.patch [PASS] Uploaded an in-service and RR patch Story: 2010993 Task: 49289 Change-Id: I7ada7b55f458c50ed3bf51e66841cc49592f2f71 Signed-off-by: Jessica Castelino <jessica.castelino@windriver.com>
This commit is contained in:
parent
8aed4785a3
commit
00575b6dc2
@ -202,8 +202,7 @@ def parse_pkgver(pkgver):
|
||||
def get_release_from_patch(patchfile):
|
||||
rel = ""
|
||||
try:
|
||||
cmd = "tar xf %s -O metadata.tar | tar x -O" % patchfile
|
||||
metadata_str = subprocess.check_output(cmd, shell=True)
|
||||
metadata_str = subprocess.check_output(['tar', '--to-command=tar -xO', '-xf', patchfile, 'metadata.tar'])
|
||||
root = ElementTree.fromstring(metadata_str)
|
||||
# Extract release version
|
||||
rel = root.findtext('sw_version')
|
||||
|
@ -157,8 +157,7 @@ def write_xml_file(top,
|
||||
def get_release_from_patch(patchfile):
|
||||
rel = ""
|
||||
try:
|
||||
cmd = "tar xf %s -O metadata.tar | tar x -O" % patchfile
|
||||
metadata_str = subprocess.check_output(cmd, shell=True)
|
||||
metadata_str = subprocess.check_output(['tar', '--to-command=tar -xO', '-xf', patchfile, 'metadata.tar'])
|
||||
root = ElementTree.fromstring(metadata_str)
|
||||
# Extract release version
|
||||
rel = root.findtext('sw_version')
|
||||
@ -625,22 +624,21 @@ class PatchFile(object):
|
||||
# Open the patch file and extract the contents to the current dir
|
||||
tar = tarfile.open(path, "r:gz")
|
||||
|
||||
filelist = []
|
||||
for f in tar.getmembers():
|
||||
filelist.append(f.name)
|
||||
|
||||
if detached_signature_file not in filelist:
|
||||
msg = "Patch not signed"
|
||||
tar.extract("signature")
|
||||
try:
|
||||
tar.extract(detached_signature_file)
|
||||
except KeyError:
|
||||
msg = "Patch has not been signed"
|
||||
LOG.warning(msg)
|
||||
|
||||
for f in filelist:
|
||||
tar.extract(f)
|
||||
|
||||
# Filelist used for signature validation and verification
|
||||
sig_filelist = ["metadata.tar", "software.tar"]
|
||||
if "semantics.tar" in filelist:
|
||||
if "semantics.tar" in [f.name for f in tar.getmembers()]:
|
||||
sig_filelist.append("semantics.tar")
|
||||
|
||||
for f in sig_filelist:
|
||||
tar.extract(f)
|
||||
|
||||
# Verify the data integrity signature first
|
||||
sigfile = open("signature", "r")
|
||||
sig = int(sigfile.read(), 16)
|
||||
@ -676,6 +674,11 @@ class PatchFile(object):
|
||||
LOG.error(msg)
|
||||
raise ReleaseValidationFailure(msg)
|
||||
|
||||
# Restart script
|
||||
for f in tar.getmembers():
|
||||
if f.name not in sig_filelist:
|
||||
tar.extract(f)
|
||||
|
||||
tar = tarfile.open("metadata.tar")
|
||||
tar.extractall()
|
||||
|
||||
|
@ -157,8 +157,7 @@ def write_xml_file(top,
|
||||
def get_release_from_patch(patchfile):
|
||||
rel = ""
|
||||
try:
|
||||
cmd = "tar xf %s -O metadata.tar | tar x -O" % patchfile
|
||||
metadata_str = subprocess.check_output(cmd, shell=True)
|
||||
metadata_str = subprocess.check_output(['tar', '--to-command=tar -xO', '-xf', patchfile, 'metadata.tar'])
|
||||
root = ElementTree.fromstring(metadata_str)
|
||||
# Extract release version
|
||||
rel = root.findtext('sw_version')
|
||||
@ -618,22 +617,21 @@ class PatchFile(object):
|
||||
# Open the patch file and extract the contents to the current dir
|
||||
tar = tarfile.open(path, "r:gz")
|
||||
|
||||
filelist = []
|
||||
for f in tar.getmembers():
|
||||
filelist.append(f.name)
|
||||
|
||||
if detached_signature_file not in filelist:
|
||||
msg = "Patch not signed"
|
||||
tar.extract("signature")
|
||||
try:
|
||||
tar.extract(detached_signature_file)
|
||||
except KeyError:
|
||||
msg = "Patch has not been signed"
|
||||
LOG.warning(msg)
|
||||
|
||||
for f in filelist:
|
||||
tar.extract(f)
|
||||
|
||||
# Filelist used for signature validation and verification
|
||||
sig_filelist = ["metadata.tar", "software.tar"]
|
||||
if "semantics.tar" in filelist:
|
||||
if "semantics.tar" in [f.name for f in tar.getmembers()]:
|
||||
sig_filelist.append("semantics.tar")
|
||||
|
||||
for f in sig_filelist:
|
||||
tar.extract(f)
|
||||
|
||||
# Verify the data integrity signature first
|
||||
sigfile = open("signature", "r")
|
||||
sig = int(sigfile.read(), 16)
|
||||
@ -669,6 +667,11 @@ class PatchFile(object):
|
||||
LOG.error(msg)
|
||||
raise PatchValidationFailure(msg)
|
||||
|
||||
# Restart script
|
||||
for f in tar.getmembers():
|
||||
if f.name not in sig_filelist:
|
||||
tar.extract(f)
|
||||
|
||||
tar = tarfile.open("metadata.tar")
|
||||
tar.extractall()
|
||||
|
||||
|
@ -106,6 +106,14 @@ class FakeTar(object):
|
||||
return True
|
||||
|
||||
|
||||
class NoSignatureTar(FakeTar):
|
||||
def extract(self, filename):
|
||||
if filename == "signature.v2": # pylint: disable=no-else-raise
|
||||
raise KeyError("Signature doesn't exist")
|
||||
else:
|
||||
return filename
|
||||
|
||||
|
||||
class CgcsPatchFunctionsTestCase(testtools.TestCase):
|
||||
|
||||
def create_element_tree_from_dict(self, tree_root, dict_obj):
|
||||
@ -208,9 +216,9 @@ class CgcsPatchFunctionsTestCase(testtools.TestCase):
|
||||
_mock_log_warning,
|
||||
_mock_open):
|
||||
test_obj = PatchFile()
|
||||
_mock_open.return_value = FakeTar(["file1"])
|
||||
_mock_open.return_value = NoSignatureTar(["file1"])
|
||||
self.assertRaises(PatchValidationFailure, test_obj.read_patch, "fake_path")
|
||||
_mock_log_warning.assert_any_call('Patch not signed')
|
||||
_mock_log_warning.assert_any_call('Patch has not been signed')
|
||||
_mock_log_error.assert_any_call('Patch failed verification')
|
||||
|
||||
@mock.patch.object(tarfile, "open")
|
||||
|
Loading…
Reference in New Issue
Block a user