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

Add takeover action for some device types #35

Merged
merged 3 commits into from
Nov 17, 2024
Merged

Conversation

pipex
Copy link
Contributor

@pipex pipex commented Sep 27, 2024

This is a proof of concept on how we could repurpose this module to indicate that a takeover is needed between certain versions for some device types.

Change-type: minor

@flowzone-app flowzone-app bot enabled auto-merge September 27, 2024 14:16
@kb2ma
Copy link
Contributor

kb2ma commented Oct 4, 2024

The logic looks sound here, but it really jumps outside the logic framework in getHupActionType(). One alternative might be to define takeoverTargetVersion as a property of ActionConfig, which helps indicate it is a special case. Then below where those properties are looked up in getHupActionType(), first test if it's a takeover -- If targetTakeoverVersion is defined, currentVersion is less than tTV, and targetVersion is greater than tTV, then change the actionName to 'takeover'. Otherwise the action remains 'balenahup'.

We also could expand the value of takeoverTargetVersion to be an array if necessary.

@pipex
Copy link
Contributor Author

pipex commented Oct 21, 2024

I agree that is another way to do it, but I think that also jumps outside the logic no? You would still need to check in the else clause

} else {
// Takeover overrides the checks below for the device type
if (this.isTakeoverRequired(deviceType, currentVersion, targetVersion)) {
return 'takeover';
}
actionName = 'balenahup';
}
for the targetTakeoverVersion which is pretty close to what we do with the isTakeoverRequired

Please correct me if I'm misunderstanding your point

@kb2ma
Copy link
Contributor

kb2ma commented Oct 22, 2024

If takeoverTargetVersion is a property of ActionConfig, we could consider takeover as a special case for balenahup -- and that is essentially its purpose. So in getHUPActionType(), the actionName initially would be 'balenahup'. Then takeoverTargetVersion would be read where the other actionConfig version values currently are read. Finally, at the end of getHUPActionType() there are some validation conditionals. Maybe just before those add the logic to see if takeoverTargetVersion is being crossed for balenahup, and if so return 'takeover' instead.

What I meant by jumping out of the flow is two things:

  • The current logic in getHUPActionType() returns immediately if isTakeoverRequired() is true
  • The definition of DeviceTypeConfig includes a special case for takeover minTargetVersion, which I found confusing

So the definition for jetson-xavier-nx-device-emmc could be like below, which also could be an array of strings for multiple jumps.

		'jetson-xavier-nx-devkit-emmc': {
			balenahup: {
				// NOTE: this version is here as a placeholder for
				// testing. Replace with the correct version before merging
				takeoverTargetVersion: '5.1.45+rev1',

I would say the key that makes this approach reasonable/possible is that getHUPActionType() returns only the name of the action.

@pipex
Copy link
Contributor Author

pipex commented Oct 22, 2024

Yes, I like this, it makes takeover kind of a special case of balenahup instead of its own process which is a good way to model it.

takeover minTargetVersion, which I found confusing

I agree this is confusing

I'll make the changes

@kb2ma
Copy link
Contributor

kb2ma commented Oct 22, 2024

@pipex, I was thinking about how to stage this work so it's easy to pull the trigger when all the other pieces are ready. How about this plan:

  1. Add all 3 device types: jetson-xavier, jetson-xavier-nx-devkit, jetson-xavier-nx-devkit-emmc
  2. Set the targetTakeoverVersion to 99.99.99 so it won't be invoked
  3. Merge this PR

Then all we need to do is create a PR that sets the right version for those three DTs.

lib/index.ts Outdated
@@ -72,7 +72,7 @@ export class HUPActionHelper {
deviceType: string,
currentVersion: string,
targetVersion: string,
) {
): ActionName | 'takeover' {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just make 'takeover' another ActionName? As is, this likely forces clients to add this extra option as well. For example, see balena-proxy services.action-backend.actions.config.ts.

Copy link
Contributor

@kb2ma kb2ma Oct 24, 2024

Choose a reason for hiding this comment

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

After more review I see how this decision is a judgement call. I'd still rather keep the names simple for clients and modify the type definition for the ActionsConfig as needed (just for action?). A comment for ActionName will help explain how it's different.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was the first thing I did, but I would have to create an additional item here

For those actions minSourceVersion and minTargetVersion are required and those values don't really make sense for takeover (or I don't know what to use)

I guess I could omit takeover in the type definition here

actions: { [K in ActionName]: ActionConfig };
but that also seems just as dirty?

I'm not entirely sure what is the best course of action

Copy link
Contributor

@kb2ma kb2ma Nov 15, 2024

Choose a reason for hiding this comment

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

@pipex I created PR #37 that adds a commit with changes to add 'takeover' as an action name. It builds OK with balena-proxy. I didn't define an ActionConfig because that seemed simplest. But really we also could define one with empty string values for minSourceVersion and minTargetVersion.

I think it's perfectly fine to use comments in the implementation to explain the use of 'takeover'. We could modify the abstractions to accommodate how 'takeover' is used, but I don't see the value when we're not sure how our use of takeover will evolve.

As you say above, because of my implementation I modified the actions definition so an entry is optional. IMO, I would rather keep the interface to getHUPActionType() simple/unchanged. Let the implementation jump through whatever hoops are required to make it work.

I also added the expected minTakeoverVersion for the three device types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kb2ma I think the problem with doing it like that is that making the ActionConfig optional removes some guarantees that are used by the code in getHUPActionType().

The code below expects minSourceVersion and minTargetVersion to always be defined. The type in config.ts also enforces it and the code won't compile if you add an action without those values.

const {
minSourceVersion,
targetMajorVersion,
minTargetVersion,
minTakeoverVersion,
maxTargetVersion,
} = {
...actionsConfig.actions[actionName],
...defaultActions[actionName],
...deviceActions[actionName],
};
if (bSemver.lt(currentVersion, minSourceVersion)) {
throw new HUPActionError(
`Current OS version must be >= ${minSourceVersion}`,
);
}

I think that if we want to use takeover as action we could set some nonsense values for those two variables (e.g v99.99.99) and add a comment about the reason for that configuration.

After that we'll be able to return takeover from getHUPActionType maintaining the type guarantees

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a new commit with the proposed change. Included the new jetson xavier versions

Copy link
Contributor

Choose a reason for hiding this comment

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

Good compromise. We always can add some metadata to ActionConfig in the future to differentiate takeover from the others. Let me try building and using this locally on my BoB.

@kb2ma
Copy link
Contributor

kb2ma commented Oct 24, 2024

Inspected the rework but have not tested yet. Overall looks good except for the comment above on ActionName.

This commit adds `minTakeoverVersion` to indicate a version jump that requires a takeover instead of
`balenahup`. This is used by `getHupActionType` to identify the need
for a takeover update.
Also define expected minTakeoverVersion for Xavier device types
@@ -33,6 +33,15 @@ export const actionsConfig: ActionsConfig = {
minSourceVersion: '2.0.0+rev1',
minTargetVersion: '2.2.0+rev1',
},
takeover: {
// Takeover is a possible action returned by getHUPActionType
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice comment!

@kb2ma kb2ma self-requested a review November 17, 2024 17:08
Copy link
Contributor

@kb2ma kb2ma left a comment

Choose a reason for hiding this comment

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

Tested a few different ways; works as expected.

@flowzone-app flowzone-app bot merged commit 14c7dcd into master Nov 17, 2024
51 checks passed
@flowzone-app flowzone-app bot deleted the takeover-update branch November 17, 2024 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants