[PATCH 3/3] binman: Add gzip bintool
Stefan Herbrechtsmeier
stefan.herbrechtsmeier-oss at weidmueller.com
Tue Aug 2 14:27:58 CEST 2022
From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier at weidmueller.com>
Add gzip bintool to binman to support on-the-fly compression of Linux
kernel images and FPGA bitstreams. The SPL basic fitImage implementation
supports only gzip decompression.
Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier at weidmueller.com>
---
tools/binman/btool/gzip.py | 94 ++++++++++++++++++++++++++++++++++++++
tools/binman/comp_util.py | 17 +++++--
tools/binman/ftest.py | 18 ++++++++
3 files changed, 124 insertions(+), 5 deletions(-)
create mode 100644 tools/binman/btool/gzip.py
diff --git a/tools/binman/btool/gzip.py b/tools/binman/btool/gzip.py
new file mode 100644
index 0000000000..27fb654ed5
--- /dev/null
+++ b/tools/binman/btool/gzip.py
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Bintool implementation for gzip
+
+gzip allows compression and decompression of files.
+
+Documentation is available via::
+
+ man gzip
+"""
+
+import re
+import tempfile
+
+from binman import bintool
+from patman import tools
+
+# pylint: disable=C0103
+class Bintoolgzip(bintool.Bintool):
+ """Compression/decompression using the gzip algorithm
+
+ This bintool supports running `gzip` to compress and decompress data, as
+ used by binman.
+
+ It is also possible to fetch the tool, which uses `apt` to install it.
+
+ Documentation is available via::
+
+ man gzip
+ """
+ def __init__(self, name):
+ super().__init__(name, 'gzip compression')
+
+ def compress(self, indata):
+ """Compress data with gzip
+
+ Args:
+ indata (bytes): Data to compress
+
+ Returns:
+ bytes: Compressed data
+ """
+ with tempfile.NamedTemporaryFile(prefix='comp.tmp',
+ dir=tools.get_output_dir()) as tmp:
+ tools.write_file(tmp.name, indata)
+ args = ['-c', tmp.name]
+ return self.run_cmd(*args, binary=True)
+
+ def decompress(self, indata):
+ """Decompress data with gzip
+
+ Args:
+ indata (bytes): Data to decompress
+
+ Returns:
+ bytes: Decompressed data
+ """
+ with tempfile.NamedTemporaryFile(prefix='decomp.tmp',
+ dir=tools.get_output_dir()) as inf:
+ tools.write_file(inf.name, indata)
+ args = ['-cd', inf.name]
+ return self.run_cmd(*args, binary=True)
+
+ def fetch(self, method):
+ """Fetch handler for gzip
+
+ This installs the gzip package using the apt utility.
+
+ Args:
+ method (FETCH_...): Method to use
+
+ Returns:
+ True if the file was fetched and now installed, None if a method
+ other than FETCH_BIN was requested
+
+ Raises:
+ Valuerror: Fetching could not be completed
+ """
+ if method != bintool.FETCH_BIN:
+ return None
+ return self.apt_install('gzip')
+
+ def version(self):
+ """Version handler
+
+ Returns:
+ str: Version number of gzip
+ """
+ out = self.run_cmd('-V').strip()
+ if not out:
+ return super().version()
+ m_version = re.match(r'.*gzip ([0-9.]*).*', out)
+ return m_version.group(1) if m_version else out
diff --git a/tools/binman/comp_util.py b/tools/binman/comp_util.py
index 269bbf7975..1d30f1613c 100644
--- a/tools/binman/comp_util.py
+++ b/tools/binman/comp_util.py
@@ -8,6 +8,9 @@ import tempfile
from binman import bintool
from patman import tools
+GZIP = bintool.Bintool.create('gzip')
+HAVE_GZIP = GZIP.is_present()
+
LZ4 = bintool.Bintool.create('lz4')
HAVE_LZ4 = LZ4.is_present()
@@ -21,19 +24,21 @@ def compress(indata, algo):
Note that for lzma this uses an old version of the algorithm, not that
provided by xz.
- This requires 'lz4' and 'lzma_alone' tools. It also requires an output
+ This requires 'gzip', 'lz4' and 'lzma_alone' tools. It also requires an output
directory to be previously set up, by calling PrepareOutputDir().
Args:
indata (bytes): Input data to compress
- algo (str): Algorithm to use ('none', 'lz4' or 'lzma')
+ algo (str): Algorithm to use ('none', 'gzip', 'lz4' or 'lzma')
Returns:
bytes: Compressed data
"""
if algo == 'none':
return indata
- if algo == 'lz4':
+ if algo == 'gzip':
+ data = GZIP.compress(indata)
+ elif algo == 'lz4':
data = LZ4.compress(indata)
# cbfstool uses a very old version of lzma
elif algo == 'lzma':
@@ -48,12 +53,12 @@ def decompress(indata, algo):
Note that for lzma this uses an old version of the algorithm, not that
provided by xz.
- This requires 'lz4' and 'lzma_alone' tools. It also requires an output
+ This requires 'gzip', 'lz4' and 'lzma_alone' tools. It also requires an output
directory to be previously set up, by calling PrepareOutputDir().
Args:
indata (bytes): Input data to decompress
- algo (str): Algorithm to use ('none', 'lz4' or 'lzma')
+ algo (str): Algorithm to use ('none', 'gzip', 'lz4' or 'lzma')
Returns:
(bytes) Compressed data
@@ -62,6 +67,8 @@ def decompress(indata, algo):
return indata
if algo == 'lz4':
data = LZ4.decompress(indata)
+ elif algo == 'gzip':
+ data = GZIP.decompress(indata)
elif algo == 'lzma':
data = LZMA_ALONE.decompress(indata)
else:
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index b1f564ed7d..5956ffa6e4 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5226,6 +5226,24 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
comp_util.decompress(b'1234', 'invalid')
self.assertIn("Unknown algorithm 'invalid'", str(e.exception))
+ def testGzipCompress(self):
+ """Test gzip compress"""
+ if not comp_util.HAVE_GZIP:
+ self.skipTest('gzip not available')
+ data = comp_util.compress(COMPRESS_DATA, 'gzip')
+ gzip = bintool.Bintool.create('gzip')
+ orig = gzip.decompress(data)
+ self.assertEquals(COMPRESS_DATA, orig)
+
+ def testGzipDecompress(self):
+ """Test gzip decompress"""
+ if not comp_util.HAVE_GZIP:
+ self.skipTest('gzip not available')
+ gzip = bintool.Bintool.create('gzip')
+ data = gzip.compress(COMPRESS_DATA)
+ orig = comp_util.decompress(data, 'gzip')
+ self.assertEquals(COMPRESS_DATA, orig)
+
def testBintoolDocs(self):
"""Test for creation of bintool documentation"""
with test_util.capture_sys_output() as (stdout, stderr):
--
2.30.2
More information about the U-Boot
mailing list