[2/4] wic: rawcopy: Add support for packed images

Message ID 20220210161738.17989-2-stefan.herbrechtsmeier-oss@weidmueller.com
State Accepted, archived
Commit 4c97d25791389ece041565981ba3207ce9949a1a
Headers show
Series [1/4] wic: partition: Support valueless keys in sourceparams | expand

Commit Message

Stefan Herbrechtsmeier Feb. 10, 2022, 4:17 p.m. UTC
From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Add support for packed images to wic rawcopy handler do minimize disk
usage in deploy directory and reuse of packed images between wic and
swupdate. Add `unpack` to sourceparams to unpack an bz2, gz and xz
archives.

Example:
part / --source rawcopy --sourceparams="file=core-image-minimal-qemu.ext4.gz,unpack"

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

---

 scripts/lib/wic/plugins/source/rawcopy.py | 28 ++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

Comments

Ulrich Ölmann Feb. 11, 2022, 4:17 p.m. UTC | #1
Hi Stefan!

On Thu, Feb 10 2022 at 17:17 +0100, "Stefan Herbrechtsmeier" <stefan.herbrechtsmeier-oss@weidmueller.com> wrote:
> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>
> Add support for packed images to wic rawcopy handler do minimize disk
> usage in deploy directory and reuse of packed images between wic and
> swupdate. Add `unpack` to sourceparams to unpack an bz2, gz and xz
> archives.
>
> Example:
> part / --source rawcopy --sourceparams="file=core-image-minimal-qemu.ext4.gz,unpack"
>
> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>
> ---
>
>  scripts/lib/wic/plugins/source/rawcopy.py | 28 ++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py
> index fa7b1eb8ac..7816e00e49 100644
> --- a/scripts/lib/wic/plugins/source/rawcopy.py
> +++ b/scripts/lib/wic/plugins/source/rawcopy.py
> @@ -4,6 +4,8 @@
>  
>  import logging
>  import os
> +import signal
> +import subprocess
>  
>  from wic import WicError
>  from wic.pluginbase import SourcePlugin
> @@ -38,6 +40,24 @@ class RawCopyPlugin(SourcePlugin):
>  
>          exec_cmd(cmd)
>  
> +    @staticmethod
> +    def do_image_uncompression(src, dst, workdir):
> +        def subprocess_setup():
> +            # Python installs a SIGPIPE handler by default. This is usually not what
> +            # non-Python subprocesses expect.
> +            # SIGPIPE errors are known issues with gzip/bash
> +            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
> +
> +        decompressor = {
> +            ".bz2": "bzip2",
> +            ".gz": "gzip",
> +            ".xz": "xz"
> +        }.get(os.path.splitext(src)[1])
> +        if not decompressor:
> +            raise WicError("Compression not support")

Here is a small typo: s/support/supported/ .

And what about substituting "Compression" by "Compressor" to express
that not compression in general but only this individual compressor is
currently unsupported? (Or even better: in addition explicitely name the
currently unsupported compressor in the error message?)

Best regards
Ulrich


> +        cmd = "%s -dc %s > %s" % (decompressor, src, dst)
> +        subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=workdir)
> +
>      @classmethod
>      def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
>                               oe_builddir, bootimg_dir, kernel_dir,
> @@ -56,7 +76,13 @@ class RawCopyPlugin(SourcePlugin):
>          if 'file' not in source_params:
>              raise WicError("No file specified")
>  
> -        src = os.path.join(kernel_dir, source_params['file'])
> +        if 'unpack' in source_params:
> +            img = os.path.join(kernel_dir, source_params['file'])
> +            src = os.path.join(cr_workdir, os.path.splitext(source_params['file'])[0])
> +            RawCopyPlugin.do_image_uncompression(img, src, cr_workdir)
> +        else:
> +            src = os.path.join(kernel_dir, source_params['file'])
> +
>          dst = os.path.join(cr_workdir, "%s.%s" % (os.path.basename(source_params['file']), part.lineno))
>  
>          if not os.path.exists(os.path.dirname(dst)):
Stefan Herbrechtsmeier Feb. 11, 2022, 4:35 p.m. UTC | #2
Hi Ulrich,

Am 11.02.2022 um 17:17 schrieb Ulrich Ölmann:
> On Thu, Feb 10 2022 at 17:17 +0100, "Stefan Herbrechtsmeier" <stefan.herbrechtsmeier-oss@weidmueller.com> wrote:
>> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>>
>> Add support for packed images to wic rawcopy handler do minimize disk
>> usage in deploy directory and reuse of packed images between wic and
>> swupdate. Add `unpack` to sourceparams to unpack an bz2, gz and xz
>> archives.
>>
>> Example:
>> part / --source rawcopy --sourceparams="file=core-image-minimal-qemu.ext4.gz,unpack"
>>
>> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>>
>> ---
>>
>>   scripts/lib/wic/plugins/source/rawcopy.py | 28 ++++++++++++++++++++++-
>>   1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py
>> index fa7b1eb8ac..7816e00e49 100644
>> --- a/scripts/lib/wic/plugins/source/rawcopy.py
>> +++ b/scripts/lib/wic/plugins/source/rawcopy.py
>> @@ -4,6 +4,8 @@
>>   
>>   import logging
>>   import os
>> +import signal
>> +import subprocess
>>   
>>   from wic import WicError
>>   from wic.pluginbase import SourcePlugin
>> @@ -38,6 +40,24 @@ class RawCopyPlugin(SourcePlugin):
>>   
>>           exec_cmd(cmd)
>>   
>> +    @staticmethod
>> +    def do_image_uncompression(src, dst, workdir):
>> +        def subprocess_setup():
>> +            # Python installs a SIGPIPE handler by default. This is usually not what
>> +            # non-Python subprocesses expect.
>> +            # SIGPIPE errors are known issues with gzip/bash
>> +            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
>> +
>> +        decompressor = {
>> +            ".bz2": "bzip2",
>> +            ".gz": "gzip",
>> +            ".xz": "xz"
>> +        }.get(os.path.splitext(src)[1])
>> +        if not decompressor:
>> +            raise WicError("Compression not support")
> 
> Here is a small typo: s/support/supported/ .
> 
> And what about substituting "Compression" by "Compressor" to express
> that not compression in general but only this individual compressor is
> currently unsupported? (Or even better: in addition explicitely name the
> currently unsupported compressor in the error message?)

What about the following:

Not supported compressor extension: %s

Best regards
   Stefan
Ulrich Ölmann Feb. 11, 2022, 5:08 p.m. UTC | #3
Hi Stefan,

On Fri, Feb 11 2022 at 17:35 +0100, "Stefan Herbrechtsmeier" <stefan.herbrechtsmeier-oss@weidmueller.com> wrote:
> Am 11.02.2022 um 17:17 schrieb Ulrich Ölmann:
>> On Thu, Feb 10 2022 at 17:17 +0100, "Stefan Herbrechtsmeier" <stefan.herbrechtsmeier-oss@weidmueller.com> wrote:
>>> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>>>
>>> Add support for packed images to wic rawcopy handler do minimize disk
>>> usage in deploy directory and reuse of packed images between wic and
>>> swupdate. Add `unpack` to sourceparams to unpack an bz2, gz and xz
>>> archives.
>>>
>>> Example:
>>> part / --source rawcopy --sourceparams="file=core-image-minimal-qemu.ext4.gz,unpack"
>>>
>>> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>>>
>>> ---
>>>
>>>   scripts/lib/wic/plugins/source/rawcopy.py | 28 ++++++++++++++++++++++-
>>>   1 file changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py
>>> index fa7b1eb8ac..7816e00e49 100644
>>> --- a/scripts/lib/wic/plugins/source/rawcopy.py
>>> +++ b/scripts/lib/wic/plugins/source/rawcopy.py
>>> @@ -4,6 +4,8 @@
>>>     import logging
>>>   import os
>>> +import signal
>>> +import subprocess
>>>     from wic import WicError
>>>   from wic.pluginbase import SourcePlugin
>>> @@ -38,6 +40,24 @@ class RawCopyPlugin(SourcePlugin):
>>>             exec_cmd(cmd)
>>>   +    @staticmethod
>>> +    def do_image_uncompression(src, dst, workdir):
>>> +        def subprocess_setup():
>>> +            # Python installs a SIGPIPE handler by default. This is usually not what
>>> +            # non-Python subprocesses expect.
>>> +            # SIGPIPE errors are known issues with gzip/bash
>>> +            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
>>> +
>>> +        decompressor = {
>>> +            ".bz2": "bzip2",
>>> +            ".gz": "gzip",
>>> +            ".xz": "xz"
>>> +        }.get(os.path.splitext(src)[1])
>>> +        if not decompressor:
>>> +            raise WicError("Compression not support")
>> Here is a small typo: s/support/supported/ .
>> And what about substituting "Compression" by "Compressor" to express
>> that not compression in general but only this individual compressor is
>> currently unsupported? (Or even better: in addition explicitely name the
>> currently unsupported compressor in the error message?)
>
> What about the following:
>
> Not supported compressor extension: %s

of course, that also sounds like a good alternative.

Have a nice weekend!
Ulrich


> Best regards
>   Stefan

Patch

diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py
index fa7b1eb8ac..7816e00e49 100644
--- a/scripts/lib/wic/plugins/source/rawcopy.py
+++ b/scripts/lib/wic/plugins/source/rawcopy.py
@@ -4,6 +4,8 @@ 
 
 import logging
 import os
+import signal
+import subprocess
 
 from wic import WicError
 from wic.pluginbase import SourcePlugin
@@ -38,6 +40,24 @@  class RawCopyPlugin(SourcePlugin):
 
         exec_cmd(cmd)
 
+    @staticmethod
+    def do_image_uncompression(src, dst, workdir):
+        def subprocess_setup():
+            # Python installs a SIGPIPE handler by default. This is usually not what
+            # non-Python subprocesses expect.
+            # SIGPIPE errors are known issues with gzip/bash
+            signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+        decompressor = {
+            ".bz2": "bzip2",
+            ".gz": "gzip",
+            ".xz": "xz"
+        }.get(os.path.splitext(src)[1])
+        if not decompressor:
+            raise WicError("Compression not support")
+        cmd = "%s -dc %s > %s" % (decompressor, src, dst)
+        subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=workdir)
+
     @classmethod
     def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
                              oe_builddir, bootimg_dir, kernel_dir,
@@ -56,7 +76,13 @@  class RawCopyPlugin(SourcePlugin):
         if 'file' not in source_params:
             raise WicError("No file specified")
 
-        src = os.path.join(kernel_dir, source_params['file'])
+        if 'unpack' in source_params:
+            img = os.path.join(kernel_dir, source_params['file'])
+            src = os.path.join(cr_workdir, os.path.splitext(source_params['file'])[0])
+            RawCopyPlugin.do_image_uncompression(img, src, cr_workdir)
+        else:
+            src = os.path.join(kernel_dir, source_params['file'])
+
         dst = os.path.join(cr_workdir, "%s.%s" % (os.path.basename(source_params['file']), part.lineno))
 
         if not os.path.exists(os.path.dirname(dst)):