Pre-version check

11 views
Skip to first unread message

Andrej Valek

unread,
Feb 16, 2026, 5:50:11 AM (4 days ago) Feb 16
to swup...@googlegroups.com
Hi all!

Maybe I wanted to make some "special" behavior, but I don't think so.
Let me describe, what I wanted to achieve. Lets assume, that your HW is
running on version 0.3.0 and you wanted to upgrade it to version 0.5.0.
But some important changes are in the version 0.4.0. So what you wanted
to achieve is, that the users which are update to new version had
version 0.4.0 installed. I think, I can't use "install-if-higher" which
won't check the minimal required version.

According to docu
https://sbabic.github.io/swupdate/sw-description.html#scripts there are
schell/lua script supported. So I created a "shell" script, which should
do this checking in "preinstall" step.

> Scripts runs in the order they are put into the sw-description file.
The result of a script is valuated by SWUpdate, that stops the update
with an error if the result is <> 0.

scripts: (
    {
        filename = "test.sh";
        type = "preinstall";
        data = "0.5.0";
    }
);

// test.sh
#!/bin/sh

logger -t swupdate.sh "xxx"

exit 0

This is just an example to do a version check before flashing.

[TRACE] : SWUPDATE running :  [extract_files] :     size 1328288 Not
required: skipping
[TRACE] : SWUPDATE running :  [extract_files] : Found file
[TRACE] : SWUPDATE running :  [extract_files] :     filename test.sh
[TRACE] : SWUPDATE running :  [extract_files] :     size 761 required
[TRACE] : SWUPDATE running :  [extract_padding] : Expecting up to 512
padding bytes at end-of-file
[TRACE] : SWUPDATE running :  [network_initializer] : Valid image found:
copying to FLASH
[INFO ] : SWUPDATE running :  Installation in progress
[TRACE] : SWUPDATE running :  [__run_cmd] : /tmp/scripts/test.sh 0.5.0
command returned 0
[INFO ] : SWUPDATE successful ! SWUPDATE successful !
[TRACE] : SWUPDATE running :  [network_initializer] : Main thread sleep
again !
[INFO ] : No SWUPDATE running :  Waiting for requests...
[INFO ] : SWUPDATE running :  [endupdate] : SWUpdate was successful !

So why it didn't continue in flashing? When the script exited with 1,
there was an error. SO basically any kind of script will stop the
flashing, or am I wrong???

So Maybe I placed the script into wrong position of sw-description. So I
moved into "image" section.

copy1: {
    images: (
        {
            filename = "@@ROOTFS_IMAGE@@";
            sha256 = "$swupdate_get_sha256(@@ROOTFS_IMAGE@@)";
            type = "raw";
            compressed = "zlib";
            device = "/dev/@@ROOT_PART_NAME_A@@";
            installed-directly = true;
        },
        {
            filename = "@@BOOTLOADER_IMAGE@@";
            type = "raw";
            device = "/dev/@@BOOT_PART_NAME_A@@";
            offset = "@@IMX_BOOT_SEEK@@K";
            sha256 = "$swupdate_get_sha256(@@BOOTLOADER_IMAGE@@)";
            name = "boot-container";
            version = "@@IMX_BOOT_VERSION@@";
        }
    );
    scripts: (
        {
            filename = "test.sh";
            type = "preinstall";
            data = "@@VERSION@@";
        }
    );
    bootenv: (
        {
            name = "toggle_partition";

Then I have an parsing error:

[TRACE] : SWUPDATE running : [start_delta_downloader] : Starting
Internal process for downloading chunks
[TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file
[TRACE] : SWUPDATE running :  [extract_file_to_tmp] :     filename
sw-description
[TRACE] : SWUPDATE running :  [extract_file_to_tmp] :     size 3259
[DEBUG] : SWUPDATE running :  [parse_cfg] : Parsing config file
/tmp/sw-description
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.9.0
[TRACE] : SWUPDATE running :  [get_common_fields] : reboot_required 1
[ERROR] : SWUPDATE failed [0] ERROR parser.c : parser : 1051 : Found
nothing to install
[DEBUG] : SWUPDATE running :  [parse_json] : Parsing config file
/tmp/sw-description
[ERROR] : SWUPDATE failed [0] ERROR parser.c : parse_json : 1137 : JSON
File corrupted
[ERROR] : SWUPDATE failed [0] ERROR parser.c : parse : 164 : no parser
available to parse sw-description!
[ERROR] : SWUPDATE failed [0] ERROR stream_interface.c : extract_files :
182 : Compatible SW not found
[ERROR] : SWUPDATE failed [1] Image invalid or corrupted. Not installing ...
swupdate_image_write failed: Connection reset by peer
[ERROR] : SWUPDATE failed [0] ERROR install_from_file.c : endupdate : 55
: SWUpdate *failed* !

So what am I doing wrong, or how to make this working.

Many thanks,
Andy

Stefano Babic

unread,
Feb 16, 2026, 6:13:05 AM (4 days ago) Feb 16
to Andrej Valek, swup...@googlegroups.com
Hi Andrej,

On 2/16/26 11:49, 'Andrej Valek' via swupdate wrote:
> Hi all!
>
> Maybe I wanted to make some "special" behavior, but I don't think so.
> Let me describe, what I wanted to achieve. Lets assume, that your HW is
> running on version 0.3.0 and you wanted to upgrade it to version 0.5.0.
> But some important changes are in the version 0.4.0. So what you wanted
> to achieve is, that the users which are update to new version had
> version 0.4.0 installed.

This is supported out of the box via comman line parms. You pass to
SWUpdate which is the minimum and the maximum version.

-N, --no-downgrading <version> : not install a release older as <version>
--max-version <version>: not install a release bigger as <version>

version is the general version in sw-description that is put in the header:

software = {
version = <your fancy< version>;

min and max version can be also be set via IPC, see the swupdate-ipc
tool for details.

> I think, I can't use "install-if-higher" which
> won't check the minimal required version.

This is *NOT* for the global version, this check the version of the
single artifact. Like version of bootloader, etc..

>
> According to docu https://sbabic.github.io/swupdate/sw-
> description.html#scripts there are schell/lua script supported. So I
> created a "shell" script, which should do this checking in "preinstall"
> step.

Why are you not using Lua ?

>
> > Scripts runs in the order they are put into the sw-description file.

More or less...

> The result of a script is valuated by SWUpdate, that stops the update
> with an error if the result is <> 0.
>
> scripts: (
>     {
>         filename = "test.sh";
>         type = "preinstall";
>         data = "0.5.0";
>     }
> );

A script is put into the SWU, and the order of artifacts in the SWU is
not deterministic. That means a shell script as preinstall will run
before installing artifacts that are temporarily stored, but after any
artifact where streaming (installed-directly is set) is activated.


>
> // test.sh
> #!/bin/sh
>
> logger -t swupdate.sh "xxx"
>
> exit 0
>
> This is just an example to do a version check before flashing.
>
> [TRACE] : SWUPDATE running :  [extract_files] :     size 1328288 Not
> required: skipping

==> skipping means it is not installed.

> [TRACE] : SWUPDATE running :  [extract_files] : Found file
> [TRACE] : SWUPDATE running :  [extract_files] :     filename test.sh
> [TRACE] : SWUPDATE running :  [extract_files] :     size 761 required
> [TRACE] : SWUPDATE running :  [extract_padding] : Expecting up to 512
> padding bytes at end-of-file
> [TRACE] : SWUPDATE running :  [network_initializer] : Valid image found:
> copying to FLASH
> [INFO ] : SWUPDATE running :  Installation in progress
> [TRACE] : SWUPDATE running :  [__run_cmd] : /tmp/scripts/test.sh 0.5.0
> command returned 0
> [INFO ] : SWUPDATE successful ! SWUPDATE successful !
> [TRACE] : SWUPDATE running :  [network_initializer] : Main thread sleep
> again !
> [INFO ] : No SWUPDATE running :  Waiting for requests...
> [INFO ] : SWUPDATE running :  [endupdate] : SWUpdate was successful !
>
> So why it didn't continue in flashing?

Because there is nothing more to do.

> When the script exited with 1,
> there was an error. SO basically any kind of script will stop the
> flashing, or am I wrong???

Any script returning an error will immediately stop the update.

>
> So Maybe I placed the script into wrong position of sw-description. So I
> moved into "image" section.

If it is a script it is not an image. A dog won't be a cat.

>
> copy1: {
>     images: (
>         {
>             filename = "@@ROOTFS_IMAGE@@";
>             sha256 = "$swupdate_get_sha256(@@ROOTFS_IMAGE@@)";
>             type = "raw";
>             compressed = "zlib";
>             device = "/dev/@@ROOT_PART_NAME_A@@";
>             installed-directly = true;

This runs before any script.

>         },
>         {
>             filename = "@@BOOTLOADER_IMAGE@@";
>             type = "raw";
>             device = "/dev/@@BOOT_PART_NAME_A@@";
>             offset = "@@IMX_BOOT_SEEK@@K";
>             sha256 = "$swupdate_get_sha256(@@BOOTLOADER_IMAGE@@)";
>             name = "boot-container";
>             version = "@@IMX_BOOT_VERSION@@";

This makes no sense if you do not set "installed-if-different".

>         }
>     );
>     scripts: (
>         {
>             filename = "test.sh";
>             type = "preinstall";
>             data = "@@VERSION@@";

This will run after installing the image.

>         }
>     );
>     bootenv: (
>         {
>             name = "toggle_partition";
>
> Then I have an parsing error:
>
> [TRACE] : SWUPDATE running : [start_delta_downloader] : Starting
> Internal process for downloading chunks
> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file
> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] :     filename sw-
> description
> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] :     size 3259
> [DEBUG] : SWUPDATE running :  [parse_cfg] : Parsing config file /tmp/sw-
> description
> [TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.9.0

So your version is already 0.9.0, neither 0.4.0 nor 0.5.0.

> [TRACE] : SWUPDATE running :  [get_common_fields] : reboot_required 1
> [ERROR] : SWUPDATE failed [0] ERROR parser.c : parser : 1051 : Found
> nothing to install

You haven't informed SWUpdate what should be done and it cannot identify
which section should be taken.

> [DEBUG] : SWUPDATE running :  [parse_json] : Parsing config file /tmp/
> sw-description
> [ERROR] : SWUPDATE failed [0] ERROR parser.c : parse_json : 1137 : JSON
> File corrupted
> [ERROR] : SWUPDATE failed [0] ERROR parser.c : parse : 164 : no parser
> available to parse sw-description!
> [ERROR] : SWUPDATE failed [0] ERROR stream_interface.c : extract_files :
> 182 : Compatible SW not found
> [ERROR] : SWUPDATE failed [1] Image invalid or corrupted. Not
> installing ...
> swupdate_image_write failed: Connection reset by peer
> [ERROR] : SWUPDATE failed [0] ERROR install_from_file.c : endupdate :
> 55 : SWUpdate *failed* !
>
> So what am I doing wrong, or how to make this working.
Best regards,
Stefano Babic

Andrej Valek

unread,
Feb 16, 2026, 7:01:58 AM (4 days ago) Feb 16
to Stefano Babic, swup...@googlegroups.com
Hi Stefano,

Thanks for the answers.

On 16.02.2026 12:12, Stefano Babic wrote:
> Hi Andrej,
>
> On 2/16/26 11:49, 'Andrej Valek' via swupdate wrote:
>> Hi all!
>>
>> Maybe I wanted to make some "special" behavior, but I don't think so.
>> Let me describe, what I wanted to achieve. Lets assume, that your HW
>> is running on version 0.3.0 and you wanted to upgrade it to version
>> 0.5.0. But some important changes are in the version 0.4.0. So what
>> you wanted to achieve is, that the users which are update to new
>> version had version 0.4.0 installed.
>
> This is supported out of the box via comman line parms. You pass to
> SWUpdate which is the minimum and the maximum version.
>
>  -N, --no-downgrading <version> : not install a release older as
> <version>
>      --max-version     <version>: not install a release bigger as
> <version>
That's fine, but how can I change it on running system, where only
swupdate is the possible interact? On the other hand I don't want to
block users to no installing the older versions where the "chanages"
weren't introduce.
>
> version is the general version in sw-description that is put in the
> header:
>
> software = {
>   version =  <your fancy< version>;
>
I know that the version is global and can be overridden in each section :).
> min and max version can be also be set via IPC, see the swupdate-ipc
> tool for details.
There is only a "web" variant used. So should I bundle calling this API
from script?
>
>> I think, I can't use "install-if-higher" which won't check the
>> minimal required version.
>
> This is *NOT* for the global version, this check the version of the
> single artifact. Like version of bootloader, etc..
>
Ah, yes. On the other hand I don't want to install just one artifact. I
need an overall check.
>>
>> According to docu https://sbabic.github.io/swupdate/sw-
>> description.html#scripts there are schell/lua script supported. So I
>> created a "shell" script, which should do this checking in
>> "preinstall" step.
>
> Why are you not using Lua ?
Why should I? Is there any benefit against shell?
>
>>
>>  > Scripts runs in the order they are put into the sw-description file.
>
> More or less...
>
>> The result of a script is valuated by SWUpdate, that stops the update
>> with an error if the result is <> 0.
>>
>> scripts: (
>>      {
>>          filename = "test.sh";
>>          type = "preinstall";
>>          data = "0.5.0";
>>      }
>> );
>
> A script is put into the SWU, and the order of artifacts in the SWU is
> not deterministic. That means a shell script as preinstall will run
> before installing artifacts that are temporarily stored, but after any
> artifact where streaming (installed-directly is set) is activated.
>
So how to ship the script with SWU and prevent the installation?
So maybe I named it wrongly.
>
>>
>> copy1: {
>>      images: (
>>          {
>>              filename = "@@ROOTFS_IMAGE@@";
>>              sha256 = "$swupdate_get_sha256(@@ROOTFS_IMAGE@@)";
>>              type = "raw";
>>              compressed = "zlib";
>>              device = "/dev/@@ROOT_PART_NAME_A@@";
>>              installed-directly = true;
>
> This runs before any script.
>
>>          },
>>          {
>>              filename = "@@BOOTLOADER_IMAGE@@";
>>              type = "raw";
>>              device = "/dev/@@BOOT_PART_NAME_A@@";
>>              offset = "@@IMX_BOOT_SEEK@@K";
>>              sha256 = "$swupdate_get_sha256(@@BOOTLOADER_IMAGE@@)";
>>              name = "boot-container";
>>              version = "@@IMX_BOOT_VERSION@@";
>
> This makes no sense if you do not set "installed-if-different".
>
>>          }
>>      );
>>      scripts: (
>>          {
>>              filename = "test.sh";
>>              type = "preinstall";
>>              data = "@@VERSION@@";
>
> This will run after installing the image.
Why after if there is "preinstall" ?
>
>>          }
>>      );
>>      bootenv: (
>>          {
>>              name = "toggle_partition";
>>
>> Then I have an parsing error:
>>
>> [TRACE] : SWUPDATE running : [start_delta_downloader] : Starting
>> Internal process for downloading chunks
>> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file
>> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] :  filename sw-
>> description
>> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] :     size 3259
>> [DEBUG] : SWUPDATE running :  [parse_cfg] : Parsing config file
>> /tmp/sw- description
>> [TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.9.0
>
> So your version is already 0.9.0, neither 0.4.0 nor 0.5.0.
Yes, I forgot the change it to 0.5.0. I was using the version 0.9.0, but
for reporting here I changed to 0.5.0.
>
>> [TRACE] : SWUPDATE running : [get_common_fields] : reboot_required 1
>> [ERROR] : SWUPDATE failed [0] ERROR parser.c : parser : 1051 : Found
>> nothing to install
>
> You haven't informed SWUpdate what should be done and it cannot
> identify which section should be taken.
>
>> [DEBUG] : SWUPDATE running :  [parse_json] : Parsing config file
>> /tmp/ sw-description
>> [ERROR] : SWUPDATE failed [0] ERROR parser.c : parse_json : 1137 :
>> JSON File corrupted
>> [ERROR] : SWUPDATE failed [0] ERROR parser.c : parse : 164 : no
>> parser available to parse sw-description!
>> [ERROR] : SWUPDATE failed [0] ERROR stream_interface.c :
>> extract_files : 182 : Compatible SW not found
>> [ERROR] : SWUPDATE failed [1] Image invalid or corrupted. Not
>> installing ...
>> swupdate_image_write failed: Connection reset by peer
>> [ERROR] : SWUPDATE failed [0] ERROR install_from_file.c : endupdate :
>> 55 : SWUpdate *failed* !
>>
>> So what am I doing wrong, or how to make this working.
Ok, so I should keep the "script" section in the root.
> Best regards,
> Stefano Babic
>
Ok, after some investigation I made it working... . There was an error
on my side :). The problem was, that I was testing it without SW image
selection. So yes, it didn't install something, while it didn't find
something.

Ok, but at the end, how to write the "error" message into "web messages"
from shell. Basically I wanted to inform users. Does something like:

echo "<0>Error: New version $NEW_VERSION does not match required version
$REQ_VERSION"
logger -t swupdate.sh "New version $NEW_VERSION does not match required
version $REQ_VERSION"

works?

Thank you,
Andy

Stefano Babic

unread,
Feb 16, 2026, 7:17:24 AM (4 days ago) Feb 16
to Andrej Valek, swup...@googlegroups.com
On 2/16/26 13:01, Andrej Valek wrote:
> Hi Stefano,
>
> Thanks for the answers.
>
> On 16.02.2026 12:12, Stefano Babic wrote:
>> Hi Andrej,
>>
>> On 2/16/26 11:49, 'Andrej Valek' via swupdate wrote:
>>> Hi all!
>>>
>>> Maybe I wanted to make some "special" behavior, but I don't think so.
>>> Let me describe, what I wanted to achieve. Lets assume, that your HW
>>> is running on version 0.3.0 and you wanted to upgrade it to version
>>> 0.5.0. But some important changes are in the version 0.4.0. So what
>>> you wanted to achieve is, that the users which are update to new
>>> version had version 0.4.0 installed.
>>
>> This is supported out of the box via comman line parms. You pass to
>> SWUpdate which is the minimum and the maximum version.
>>
>>  -N, --no-downgrading <version> : not install a release older as
>> <version>
>>      --max-version     <version>: not install a release bigger as
>> <version>
> That's fine, but how can I change it on running system, where only
> swupdate is the possible interact? On the other hand I don't want to
> block users to no installing the older versions where the "chanages"
> weren't introduce.

If your system is already in field, you have to live with the SWUpdate
version that is installed. The best way to make this check is to add an
"embedded-script" to sw-description becaus ethis runs at parse time
before anything is done.

>>
>> version is the general version in sw-description that is put in the
>> header:
>>
>> software = {
>>   version =  <your fancy< version>;
>>
> I know that the version is global and can be overridden in each section :).
>> min and max version can be also be set via IPC, see the swupdate-ipc
>> tool for details.
> There is only a "web" variant used. So should I bundle calling this API
> from script?
>>
>>> I think, I can't use "install-if-higher" which won't check the
>>> minimal required version.
>>
>> This is *NOT* for the global version, this check the version of the
>> single artifact. Like version of bootloader, etc..
>>
> Ah, yes. On the other hand I don't want to install just one artifact. I
> need an overall check.

That means you have to check this and not in the artifact.

>>>
>>> According to docu https://sbabic.github.io/swupdate/sw-
>>> description.html#scripts there are schell/lua script supported. So I
>>> created a "shell" script, which should do this checking in
>>> "preinstall" step.
>>
>> Why are you not using Lua ?
> Why should I? Is there any benefit against shell?

Apart security issues (Lua is running in context of SWUodate without
external tools), LUa can guarntee that check will be done in advance.

>>
>>>
>>>  > Scripts runs in the order they are put into the sw-description file.
>>
>> More or less...
>>
>>> The result of a script is valuated by SWUpdate, that stops the update
>>> with an error if the result is <> 0.
>>>
>>> scripts: (
>>>      {
>>>          filename = "test.sh";
>>>          type = "preinstall";
>>>          data = "0.5.0";
>>>      }
>>> );
>>
>> A script is put into the SWU, and the order of artifacts in the SWU is
>> not deterministic. That means a shell script as preinstall will run
>> before installing artifacts that are temporarily stored, but after any
>> artifact where streaming (installed-directly is set) is activated.
>>
> So how to ship the script with SWU and prevent the installation?

Do it in Lua as embedded-script.
Because it is "preinstalling" at the best SWUpdate can do. If the script
is packaged later than a streamed artifact, it will run later. If you
want to be sure the check is done in advance, write Lua code inside
sw-description.

>>
>>>          }
>>>      );
>>>      bootenv: (
>>>          {
>>>              name = "toggle_partition";
>>>
>>> Then I have an parsing error:
>>>
>>> [TRACE] : SWUPDATE running : [start_delta_downloader] : Starting
>>> Internal process for downloading chunks
>>> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file
>>> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] :  filename sw-
>>> description
>>> [TRACE] : SWUPDATE running :  [extract_file_to_tmp] :     size 3259
>>> [DEBUG] : SWUPDATE running :  [parse_cfg] : Parsing config file /tmp/
>>> sw- description
There is an internal Lua library that exposed functions to Lua. You can use

require "swupdate"

and then you have full SWUpdate's logging, so you can write something

swupdate.error('I cannot install version')

This will be shown by the Web application.

>
> echo "<0>Error: New version $NEW_VERSION does not match required version
> $REQ_VERSION"
> logger -t swupdate.sh "New version $NEW_VERSION does not match required
> version $REQ_VERSION"

Best regards,
Stefano Babic

Andrej Valek

unread,
Feb 16, 2026, 10:15:05 AM (4 days ago) Feb 16
to Stefano Babic, swup...@googlegroups.com
Hi Stefano,

Thanks for pointing me out to the right direction ;).

BR,
Andy
Reply all
Reply to author
Forward
0 new messages