Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semantic version comparison #1400

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

js731ca
Copy link

@js731ca js731ca commented May 2, 2024

This PR adds min-version and max-version configuration options to the system.conf, that can be set to a version triplet Major.Minor.Patch. If now bundles are versioned in a way that follows the semantic versioning scheme - e.g. 1.2.3-g35f26fd - the bundle version can be compared against these configured limits, and the installation will be (gracefully) refused should the bundle version not fall within set limits.


  • What do you use the feature for?

    updates can introduce breaking changes, which could render a device inoperable should a downgrade happen; with this feature a breaking change could advance the min-version and from then on refuse to install "older" bundles.

  • How does RAUC benefit from the feature?

    new feature :-D
    similar feature to the compatible check, but orthogonal

  • How did you verify the feature works?

    added tests were feasible; manually on project/target hardware

  • If hardware is needed for the feature, which hardware is supported and which
    hardware did you test with?

    no special requirements, just a hardware platform that uses rauc

@js731ca js731ca force-pushed the semantic-version-comparison branch from a81db8b to d91d6cb Compare May 3, 2024 04:26
@js731ca
Copy link
Author

js731ca commented May 3, 2024

v1.1: address issues raised bystyle and stable (debian:testing)
the other build failures seemed unrelated to this PR?

src/utils.c Fixed Show resolved Hide resolved
src/utils.c Fixed Show fixed Hide fixed
src/utils.c Fixed Show fixed Hide fixed
src/utils.c Fixed Show fixed Hide fixed
src/utils.c Fixed Show fixed Hide fixed
@js731ca js731ca force-pushed the semantic-version-comparison branch from d91d6cb to d2da1c5 Compare May 3, 2024 10:11
@js731ca
Copy link
Author

js731ca commented May 3, 2024

v1.2: second round of PR check fixes :-)
addressing(?) CodeCL and stable (debian:testing) findings

@jluebbe
Copy link
Member

jluebbe commented May 3, 2024

Thanks for your contribution!

I understand your "protect against downgrades" use-case for a min-version in the system.conf. So far, we've pointed users at other ways this could be done:

  • the pre-install handler in system.conf
  • the install-check hook in the manifest
  • rotating signing keys

Doing the bundle version comparison in RAUC itself would make it more explicit (which is good).

Before reviewing the code, I'd like to discuss some high-level questions:

  • What's the use-case for a max-version in the system.conf? To use it, I'd need to know which future version will be incompatible with the version I'm currently developing, which seems difficult.
  • min-version seems a bit unspecific. Maybe min-bundle-version would be better? Not sure though...
  • Are there valid reasons where a bundle would have to override the version check?

Even if having a max-version in the system.conf may not be useful, there is the related use-case of "require intermediate updates". In that case, a bundle would have a min-version or min-system-version. The issue here is that RAUC doesn't really have concept of a system version (only the version of a bundle that was used to install to a slot).

A possible way to solve that would be to use the system-info handler to provide the system version. Another way would be to define that the bundle version of the booted slot is the system version. But what about systems installed from a disk image?

@jluebbe jluebbe added the enhancement Adds new functionality or enhanced handling to RAUC label May 3, 2024
@js731ca
Copy link
Author

js731ca commented May 3, 2024

Thanks for your contribution!

:-D

I understand your "protect against downgrades" use-case for a min-version in the system.conf. So far, we've pointed users at other ways this could be done:

  • the pre-install handler in system.conf
  • the install-check hook in the manifest
  • rotating signing keys

our stop-gap solution so far is a pre-install handler, but we found that it is somewhat lacking in status feedback: the (manual) rauc install bundle just fails, and one has to look into the service logs/journal to piece together why - doing this in rauc is clearer: versions mismatch, aborting bundle install

rotating signing keys puts (a lot of) burden on the PKI infrastructure... which is not always feasible/easy

Doing the bundle version comparison in RAUC itself would make it more explicit (which is good).

Before reviewing the code, I'd like to discuss some high-level questions:

  • What's the use-case for a max-version in the system.conf? To use it, I'd need to know which future version will be incompatible with the version I'm currently developing, which seems difficult.

none so far, added it mostly for symmetry/completeness sake.
i could picture someone doing hardware development and having a scheme where the hardware revision matches the major revision? that way a min 4.0.x and max 4.999.999 could make sense to filter out bundles that have the same compatible over hardware revisions...

  • min-version seems a bit unspecific. Maybe min-bundle-version would be better? Not sure though...

the way we're using it is system-version == bundle version; so it would depend on the definition

  • Are there valid reasons where a bundle would have to override the version check?

are you referring to the --ignore-version-limit parameter? that is meant for bootstrapping/manual intervention

Even if having a max-version in the system.conf may not be useful, there is the related use-case of "require intermediate updates". In that case, a bundle would have a min-version or min-system-version. The issue here is that RAUC doesn't really have concept of a system version (only the version of a bundle that was used to install to a slot).

A possible way to solve that would be to use the system-info handler to provide the system version. Another way would be to define that the bundle version of the booted slot is the system version. But what about systems installed from a disk image?

oooh, that the slot status (= "installed bundle version") is empty after an initial bringup from a diskimage is sth i missed - thnx!
as mentioned "the way we use it" is by defining bundle-version = system version - since a bundle installs a rootfs/system of some known version

@js731ca
Copy link
Author

js731ca commented May 3, 2024

But what about systems installed from a disk image?

on rethinking: those should also be ok, since they bring the system.conf with it; isn't the usual flow that a system is initially brought up from a disk image, and then updated via bundles?

or what was your train-o-thought that led to the above question?

@js731ca js731ca force-pushed the semantic-version-comparison branch from d2da1c5 to 654d147 Compare May 3, 2024 12:31
@js731ca
Copy link
Author

js731ca commented May 3, 2024

v1.3: third round: addressing style->codespell check findings

@ejoerns
Copy link
Member

ejoerns commented May 3, 2024

our stop-gap solution so far is a pre-install handler, but we found that it is somewhat lacking in status feedback: the (manual) rauc install bundle just fails, and one has to look into the service logs/journal to piece together why - doing this in rauc is clearer: versions mismatch, aborting bundle install

Note that for this purpose, the 'install-check' handler has an explicit 'interface' for user-visible feedback:

If available, RAUC will use the last line printed to standard error by the hook executable as the rejection reason message and provide it to the user

It's not ideal, but better than digging in logs 😏

https://rauc.readthedocs.io/en/latest/using.html#install-hooks

@jluebbe
Copy link
Member

jluebbe commented May 3, 2024

Doing the bundle version comparison in RAUC itself would make it more explicit (which is good).
Before reviewing the code, I'd like to discuss some high-level questions:

  • What's the use-case for a max-version in the system.conf? To use it, I'd need to know which future version will be incompatible with the version I'm currently developing, which seems difficult.

none so far, added it mostly for symmetry/completeness sake.

Hmm. I don't think min-version/max-version have symmetric use-cases.
To me, min-version is about prohibiting downgrades. In that case, the running image is newer and the developer has the necessary information to set the correct limit.

For max-version, I only see the use-case of prohibiting updates to versions which no longer contain the necessary migration code from old installed versions or for which dependencies required during installation (e.g. by hooks in the bundle) are not available in old versions. In that case, the developer would know while creating the new bundle what the oldest supported installed version would be and accordingly, it should be part of the bundle manifest. To update from an older version, an intermediate update would need to be installed in that case. (That's what I meant with "require intermediate updates" above.)

i could picture someone doing hardware development and having a scheme where the hardware revision matches the major revision? that way a min 4.0.x and max 4.999.999 could make sense to filter out bundles that have the same compatible over hardware revisions...

If you really have incompatible hardware, I'd suggest handling that via different compatible strings (or perhaps variants) instead of overloading both concepts into the same "version". See below for more.

  • min-version seems a bit unspecific. Maybe min-bundle-version would be better? Not sure though...

the way we're using it is system-version == bundle version; so it would depend on the definition

As we've not been using this strict definition in RAUC so far, other users could be using a different approach. Spending time on good naming usually pays of in the long term. :)

  • Are there valid reasons where a bundle would have to override the version check?

are you referring to the --ignore-version-limit parameter? that is meant for bootstrapping/manual intervention

No, the --ignore-version-limit parameter was clear.

I meant that with the install-check approach, you could later decide to produce a bundle which allows a downgrade, as the check is implemented in code shipped in the bundle itself.
Think about this scenario: You roll out a version 3.0.0 to the field which also sets min-version=3.0.0. Then it turns out that it contains a regression from 2.9.0.
With your approach, you'd need to create a bundle with version 3.0.1 but which actually contains the 2.9.0 images. This might be undesirable, if the bundle version is also used in other contexts.

Similar considerations are the reason why we've not simply used the bundle version and installed software version interchangeably so far.

But even with your approach, a bundle with a full custom handle could be used to get out of such a situation, it's just not easy or continent. :)
So a warning to be careful with min-version might be enough.

Even if having a max-version in the system.conf may not be useful, there is the related use-case of "require intermediate updates". In that case, a bundle would have a min-version or min-system-version. The issue here is that RAUC doesn't really have concept of a system version (only the version of a bundle that was used to install to a slot).
A possible way to solve that would be to use the system-info handler to provide the system version. Another way would be to define that the bundle version of the booted slot is the system version. But what about systems installed from a disk image?

oooh, that the slot status (= "installed bundle version") is empty after an initial bringup from a diskimage is sth i missed - thnx! as mentioned "the way we use it" is by defining bundle-version = system version - since a bundle installs a rootfs/system of some known version

on rethinking: those should also be ok, since they bring the system.conf with it; isn't the usual flow that a system is initially brought up from a disk image, and then updated via bundles?

or what was your train-o-thought that led to the above question?

That only relevant for the "require intermediate updates" case and not for "protect against downgrades". We don't need to implement both cases at the same time, but we need to make sure to have clear semantics which work for both.

You're right, that's the usual flow. I was thinking about: The factory originally installed 1.0.0 and later 2.0.0 via disk images. Some time passes and you now want to release a 4.0.0 update bundle, but can't support a direct upgrade from 1.0.0. You could have a hypothetical min-system-version=2.0.0 in the bundle manifest, but RAUC on a device fresh from the factory would have no information in the slot status. So it couldn't reject installation on the 1.0.0 devices and allow it on 2.0.0 devices.

So the question becomes: How do we get an "installed bundle version" on devices which have never installed a bundle. If that's even a valid concept. :)

@js731ca
Copy link
Author

js731ca commented May 3, 2024

6 failing and 10 successful checks

looking through those logs... can't see how those should be fixed :-S
are they false positives?

@jluebbe
Copy link
Member

jluebbe commented May 3, 2024

A different question: SemVer requires the version core to consist of exactly three parts. We've seen projects use date-based versions (such as 2024.05, 2024.1 or similar). These would be rejected by your parser. Perhaps it would be useful in the context of RAUC to relax this requirement?

You've only implemented comparison for the version core, any specific reason for that?

@jluebbe
Copy link
Member

jluebbe commented May 3, 2024

6 failing and 10 successful checks

looking through those logs... can't see how those should be fixed :-S are they false positives?

Let's focus on the design questions for now. Then we can look at the implementation details. :)

@js731ca
Copy link
Author

js731ca commented May 3, 2024

A different question: SemVer requires the version core to consist of exactly three parts. We've seen projects use date-based versions (such as 2024.05, 2024.1 or similar). These would be rejected by your parser. Perhaps it would be useful in the context of RAUC to relax this requirement?

yes it would reject those, since it compares a triplet guint[3]; continuing that thought also single number versions would need to be handled - ideas on how? :-)

You've only implemented comparison for the version core, any specific reason for that?

the version core is <numeric identifiers> only = straight forward to compare,
but "pre-build" and "build" are <alphanumeric identifier>; how would one tell which is less-then another?

@jluebbe
Copy link
Member

jluebbe commented May 3, 2024

A different question: SemVer requires the version core to consist of exactly three parts. We've seen projects use date-based versions (such as 2024.05, 2024.1 or similar). These would be rejected by your parser. Perhaps it would be useful in the context of RAUC to relax this requirement?

yes it would reject those, since it compares a triplet guint[3]; continuing that thought also single number versions would need to be handled - ideas on how? :-)

You've only implemented comparison for the version core, any specific reason for that?

the version core is <numeric identifiers> only = straight forward to compare, but "pre-build" and "build" are <alphanumeric identifier>; how would one tell which is less-then another?

https://semver.org/#spec-item-11 describes a precedence algorithm which handles these cases. We could apply the pre-release logic to version core as well.

Perhaps https://manpages.debian.org/unstable/dpkg-dev/deb-version.5.en.html is also useful as inspiration, as that's less restrictive.

@js731ca
Copy link
Author

js731ca commented May 3, 2024

Doing the bundle version comparison in RAUC itself would make it more explicit (which is good).
Before reviewing the code, I'd like to discuss some high-level questions:

  • What's the use-case for a max-version in the system.conf? To use it, I'd need to know which future version will be incompatible with the version I'm currently developing, which seems difficult.

none so far, added it mostly for symmetry/completeness sake.

Hmm. I don't think min-version/max-version have symmetric use-cases. To me, min-version is about prohibiting downgrades. In that case, the running image is newer and the developer has the necessary information to set the correct limit.

For max-version, I only see the use-case of prohibiting updates to versions which no longer contain the necessary migration code from old installed versions or for which dependencies required during installation (e.g. by hooks in the bundle) are not available in old versions. In that case, the developer would know while creating the new bundle what the oldest supported installed version would be and accordingly, it should be part of the bundle manifest. To update from an older version, an intermediate update would need to be installed in that case. (That's what I meant with "require intermediate updates" above.)

we're starting to speculate possible use-cases :-D
my thought was "if there is a lower-bound check; $someone will want an upper-bound check" - and since both are optional, it was easy to implement and there if $someone needs it

i could picture someone doing hardware development and having a scheme where the hardware revision matches the major revision? that way a min 4.0.x and max 4.999.999 could make sense to filter out bundles that have the same compatible over hardware revisions...

If you really have incompatible hardware, I'd suggest handling that via different compatible strings (or perhaps variants) instead of overloading both concepts into the same "version". See below for more.

true, that would be cleaner

  • min-version seems a bit unspecific. Maybe min-bundle-version would be better? Not sure though...

the way we're using it is system-version == bundle version; so it would depend on the definition

As we've not been using this strict definition in RAUC so far, other users could be using a different approach. Spending time on good naming usually pays of in the long term. :)

ACK, since it's the system.conf which holds these -> changing it with one of the next pushes

  • Are there valid reasons where a bundle would have to override the version check?

are you referring to the --ignore-version-limit parameter? that is meant for bootstrapping/manual intervention

No, the --ignore-version-limit parameter was clear.

I meant that with the install-check approach, you could later decide to produce a bundle which allows a downgrade, as the check is implemented in code shipped in the bundle itself. Think about this scenario: You roll out a version 3.0.0 to the field which also sets min-version=3.0.0. Then it turns out that it contains a regression from 2.9.0. With your approach, you'd need to create a bundle with version 3.0.1 but which actually contains the 2.9.0 images. This might be undesirable, if the bundle version is also used in other contexts.

or use the --ignore-version-limit to downgrade again?
come to thing of that... the switch is for the commandline, but what about an install triggered from an application via dbus? hm...

Similar considerations are the reason why we've not simply used the bundle version and installed software version interchangeably so far.

But even with your approach, a bundle with a full custom handle could be used to get out of such a situation, it's just not easy or continent. :) So a warning to be careful with min-version might be enough.

Even if having a max-version in the system.conf may not be useful, there is the related use-case of "require intermediate updates". In that case, a bundle would have a min-version or min-system-version. The issue here is that RAUC doesn't really have concept of a system version (only the version of a bundle that was used to install to a slot).
A possible way to solve that would be to use the system-info handler to provide the system version. Another way would be to define that the bundle version of the booted slot is the system version. But what about systems installed from a disk image?

oooh, that the slot status (= "installed bundle version") is empty after an initial bringup from a diskimage is sth i missed - thnx! as mentioned "the way we use it" is by defining bundle-version = system version - since a bundle installs a rootfs/system of some known version
on rethinking: those should also be ok, since they bring the system.conf with it; isn't the usual flow that a system is initially brought up from a disk image, and then updated via bundles?
or what was your train-o-thought that led to the above question?

That only relevant for the "require intermediate updates" case and not for "protect against downgrades". We don't need to implement both cases at the same time, but we need to make sure to have clear semantics which work for both.

You're right, that's the usual flow. I was thinking about: The factory originally installed 1.0.0 and later 2.0.0 via disk images. Some time passes and you now want to release a 4.0.0 update bundle, but can't support a direct upgrade from 1.0.0. You could have a hypothetical min-system-version=2.0.0 in the bundle manifest, but RAUC on a device fresh from the factory would have no information in the slot status. So it couldn't reject installation on the 1.0.0 devices and allow it on 2.0.0 devices.

So the question becomes: How do we get an "installed bundle version" on devices which have never installed a bundle. If that's even a valid concept. :)

i was wrong there: the comparison happens between system.conf <> new bundle;
the rauc.status (which is initially empty, and only after bundle installation has versions) does not factor in

@jluebbe
Copy link
Member

jluebbe commented May 3, 2024

Hmm. I don't think min-version/max-version have symmetric use-cases. To me, min-version is about prohibiting downgrades. In that case, the running image is newer and the developer has the necessary information to set the correct limit.
For max-version, I only see the use-case of prohibiting updates to versions which no longer contain the necessary migration code from old installed versions or for which dependencies required during installation (e.g. by hooks in the bundle) are not available in old versions. In that case, the developer would know while creating the new bundle what the oldest supported installed version would be and accordingly, it should be part of the bundle manifest. To update from an older version, an intermediate update would need to be installed in that case. (That's what I meant with "require intermediate updates" above.)

we're starting to speculate possible use-cases :-D my thought was "if there is a lower-bound check; $someone will want an upper-bound check" - and since both are optional, it was easy to implement and there if $someone needs it

Any optional features still has costs, in maintenance, interactions with other features and complexity that needs to be documented. RAUC is opinionated and intended to discourage "incorrect" usage, so any new feature needs to have a clear use and be consistent with the rest of the design. That's not always easy. :)

  • Are there valid reasons where a bundle would have to override the version check?

are you referring to the --ignore-version-limit parameter? that is meant for bootstrapping/manual intervention

No, the --ignore-version-limit parameter was clear.
I meant that with the install-check approach, you could later decide to produce a bundle which allows a downgrade, as the check is implemented in code shipped in the bundle itself. Think about this scenario: You roll out a version 3.0.0 to the field which also sets min-version=3.0.0. Then it turns out that it contains a regression from 2.9.0. With your approach, you'd need to create a bundle with version 3.0.1 but which actually contains the 2.9.0 images. This might be undesirable, if the bundle version is also used in other contexts.

or use the --ignore-version-limit to downgrade again? come to thing of that... the switch is for the commandline, but what about an install triggered from an application via dbus? hm...

A CLI or D-Bus switch wouldn't help, as these are normally not under the control of the person installing the update (except in a development scenario).

For now, I'd tend to add a warning to the documentation mentioning this potential issue.

That only relevant for the "require intermediate updates" case and not for "protect against downgrades". We don't need to implement both cases at the same time, but we need to make sure to have clear semantics which work for both.
You're right, that's the usual flow. I was thinking about: The factory originally installed 1.0.0 and later 2.0.0 via disk images. Some time passes and you now want to release a 4.0.0 update bundle, but can't support a direct upgrade from 1.0.0. You could have a hypothetical min-system-version=2.0.0 in the bundle manifest, but RAUC on a device fresh from the factory would have no information in the slot status. So it couldn't reject installation on the 1.0.0 devices and allow it on 2.0.0 devices.
So the question becomes: How do we get an "installed bundle version" on devices which have never installed a bundle. If that's even a valid concept. :)

i was wrong there: the comparison happens between system.conf <> new bundle; the rauc.status (which is initially empty, and only after bundle installation has versions) does not factor in

I'm confident enough that we can handle these use-cases separately, so we don't need to discuss he "require intermediate updates" case here.

@js731ca js731ca force-pushed the semantic-version-comparison branch from 654d147 to 9a6382a Compare May 4, 2024 06:27
@js731ca
Copy link
Author

js731ca commented May 4, 2024

v2: changes included, based on the discussions so far:

  • rename('min-version', 'min-bundle-version')
  • remove('max-version')
  • include pre_release in comparison (and add more tests for that)
  • relax version parsing to allow: '2020.02' or just '321'

@js731ca js731ca force-pushed the semantic-version-comparison branch from 9a6382a to eecd6db Compare May 5, 2024 00:46
@js731ca
Copy link
Author

js731ca commented May 5, 2024

v2.1: fixing style findings once more
rechecking build errors on the semver_parse_test: false positive? seems ok locally

@js731ca js731ca force-pushed the semantic-version-comparison branch from eecd6db to 9690e09 Compare May 5, 2024 14:46
@js731ca
Copy link
Author

js731ca commented May 5, 2024

v2.2: another style fix, and hopefully a fix for the failing build test run

Copy link
Member

@jluebbe jluebbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced that the split into semver_parse and semver_less_equal is useful.

semver_less_equal could encounters overflows while parsing the pre-release parts, so it would need to be able to return GErrors as well.

What do you think about keeping the version as a string in both RaucConfig and RaucManifest, getting rid of semver_parse and handling the core version by iterating through a GStrv in semver_less_equal, similar to how you implemented the pre-release parsing?

During config parsing, one could use semver_less_equal("0", config_version, &ierror) == TRUE to check if the given min-bundle-version is sensible.

src/config_file.c Outdated Show resolved Hide resolved
src/install.c Outdated Show resolved Hide resolved
src/manifest.c Outdated Show resolved Hide resolved
test/utils.c Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
docs/reference.rst Show resolved Hide resolved
@js731ca
Copy link
Author

js731ca commented May 9, 2024

I'm not convinced that the split into semver_parse and semver_less_equal is useful.

semver_less_equal could encounters overflows while parsing the pre-release parts, so it would need to be able to return GErrors as well.

What do you think about keeping the version as a string in both RaucConfig and RaucManifest, getting rid of semver_parse and handling the core version by iterating through a GStrv in semver_less_equal, similar to how you implemented the pre-release parsing?

During config parsing, one could use semver_less_equal("0", config_version, &ierror) == TRUE to check if the given min-bundle-version is sensible.

thats an idea! basically pushing the whole handling (=parsing+comparing) into one place, and back to the point in time bundles are installed (or created...) -- i'll rework the PR towards that; and also pickup all the other comments&findings = thnx!

@js731ca js731ca force-pushed the semantic-version-comparison branch from 9690e09 to 2d99888 Compare May 11, 2024 06:44
src/install.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
src/utils.c Outdated Show resolved Hide resolved
@js731ca js731ca force-pushed the semantic-version-comparison branch 5 times, most recently from 332b097 to 736d5d1 Compare May 14, 2024 12:32
@js731ca
Copy link
Author

js731ca commented May 14, 2024

v4: rebase onto master

  • more specific errors
  • (finally) fixing leaks
  • cover more comparison cases; with tests too
  • s/ascii_isdigit/ascii_string_to_unsigned/

@js731ca js731ca requested a review from jluebbe May 14, 2024 12:38
test/utils.c Dismissed Show dismissed Hide dismissed
Add a parser to decompose a semantic version [1] string into its constituents.

Link: https://semver.org/
Signed-off-by: Johannes Schneider <[email protected]>
Add a utility function to do a version A <= version B comparison.

Signed-off-by: Johannes Schneider <[email protected]>
@js731ca js731ca force-pushed the semantic-version-comparison branch from 736d5d1 to 4c7a5b1 Compare May 14, 2024 13:36
@js731ca
Copy link
Author

js731ca commented May 14, 2024

v4.1: minor change: use more g_return_val_if_fail

Copy link
Member

@jluebbe jluebbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core code looks fine now.

What's still missing is test coverage for the new code in config_file.c and install.c. For the config, you can add two cases (good and invalid) similar to config_file_logger_full and config_file_logger_invalid_event in test/config_file.c.

Testing the check during installation is more involved, so I'll probably add that myself after this is merged.

@js731ca
Copy link
Author

js731ca commented May 15, 2024

The core code looks fine now.

:-D

What's still missing is test coverage for the new code in config_file.c and install.c. For the config, you can add two cases (good and invalid) similar to config_file_logger_full and config_file_logger_invalid_event in test/config_file.c.

added with v4.2 :-)

Testing the check during installation is more involved, so I'll probably add that myself after this is merged.

wow true... managed to cobble sth together that seems to get the job done; but the boilerplate seems way thicker than it needs to be - feel free to take the blowtorch to it ;-D

while putting it together, was wondering if the actual version check should be moved into this r_install_make_plans and then have a test similar to test_install_image_variants that just has a system.conf and compares multiple bundle-manifests; instead of the current incarnation that actually has to construct&install bundles... thoughts?

@js731ca js731ca force-pushed the semantic-version-comparison branch 3 times, most recently from 7fea555 to 413ae02 Compare May 15, 2024 06:34
Add a min (semantic) version key to the system section of the config
file, which can/will be used to compare the version string of an
incoming bundles against during installation.

Signed-off-by: Johannes Schneider <[email protected]>
Add a version comparison/check between the "core version" of the
semantic version set in the bundles manifest, and the system.conf set
"min-bundle-version".

Signed-off-by: Johannes Schneider <[email protected]>
Add a switch to disable any version comparison/checks during installation.

Signed-off-by: Johannes Schneider <[email protected]>
Change the string parsing to also allow "relaxed semantic version"
parsing where not the full Major.Minor.Patch is required, but also
variants with just Minor.Patch[-pre_release][+build] or
Patch[-pre_release][+build] are allowed.

Note that internally the core-version is still kept as as guint[3] but
the missing version parts are just filled in with zero.

Signed-off-by: Johannes Schneider <[email protected]>
Add test coverage for the new system.conf option: 'min-bundle-version'.

Signed-off-by: Johannes Schneider <[email protected]>
Add test cases for bundle installations on a system that sets a
minimum barrier.

Signed-off-by: Johannes Schneider <[email protected]>
@js731ca js731ca force-pushed the semantic-version-comparison branch 2 times, most recently from 89af3c1 to c93004f Compare May 15, 2024 09:29
@js731ca
Copy link
Author

js731ca commented May 15, 2024

v4.2:
src/config:

  • fixed minor memleak in the config (uncovered by the test :-)
  • removed unneeded error pointer handling

test/install:

  • fix grubenv errors
  • and failing github/actions, since they run tests as non-root

the build is "almost green", not sure where the remaining failure comes from :-S


Thought/suggestion: moving the mountprefix= into the tmp/rauc-XXXXX would allow test runs on systems that have a RO rootfs (the default mkdir /mnt/rauc fails)

@js731ca js731ca requested a review from jluebbe May 15, 2024 09:44
@jluebbe
Copy link
Member

jluebbe commented May 15, 2024

Thought/suggestion: moving the mountprefix= into the tmp/rauc-XXXXX would allow test runs on systems that have a RO rootfs (the default mkdir /mnt/rauc fails)

We're currently reworking the tests a bit (see #1401), hopefully simplifying this a bit.

In general, you should use ./qemu-test / ./qemu-test shell during development, as this allows running the largest set of tests without affecting your host system. Tests that have requirements that are not fulfilled by the host should be skipped.

No need to try things out in this PR right now, I'll take a closer look later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Adds new functionality or enhanced handling to RAUC
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants