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

Epic: Enable preventing automatic updates on specific OS versions #3925

Closed
5 tasks done
jandubois opened this issue Feb 10, 2023 · 16 comments
Closed
5 tasks done

Epic: Enable preventing automatic updates on specific OS versions #3925

jandubois opened this issue Feb 10, 2023 · 16 comments
Assignees
Labels
area/updates kind/enhancement New feature or request kind/epic Umbrella-bug for a group of related issues priority/0 Work needs to go into the next release or force a patch
Milestone

Comments

@jandubois
Copy link
Member

jandubois commented Feb 10, 2023

E.g. if our new release doesn't work on macOS Catalina anymore, we must prevent the auto-updater from downloading and installing it, if the current platform is Catalina. Otherwise we are breaking a working system, with no way to recover but via Factory-Reset and re-installing the old version.

Issues:

Acceptance Criteria

  • If platform is macOS Catalina, once Rancher Desktop is launched in 1.9.0 and the auto-updater is enabled, it should not update it with the newest released version in case this version is no longer supported. UI must display a message stating that the newest version is no longer compatible.
  • If platform is macOS Catalina, once Rancher Desktop is launched in 1.9.0 and the auto-updater is enabled, auto-updater must update Rancher Desktop to the latest compatible version with macOS Catalina.
  • Check if older versions of Rancher Desktop are able to successfully update to 1.9.0 (new structure of Upgrade Responder will not brake and user will be able to download the latest version successfully. This applies to all platforms. Test with package builds - (dev builds)?
  • On windows, the WSL needs to be included in the information that is sent to the Upgrade Responder under extraInfo. If it is not feasible to get the WSL version, wether it's not an App Store version or just not installed at all, it cannot include the WSL key to the Upgrade Responder.
@jandubois jandubois added kind/enhancement New feature or request area/updates labels Feb 10, 2023
@gaktive gaktive modified the milestones: Later, Next Feb 17, 2023
@gaktive gaktive added the priority/0 Work needs to go into the next release or force a patch label Feb 21, 2023
@jandubois
Copy link
Member Author

This story may become redundant when #4010 is implemented; let's research first what functionality we can provide by having multiple update channels.

We would still want to add a diagnostic that tells the user that they are on a deprecated platform and need to upgrade before they can install further RD updates. Otherwise they might assume the auto-updater is broken and install the update manually.

On Windows we could prevent installation in the MSI installer, but for macOS we don't have any way to prevent the user from dragging the new version on top of the old one.

@adamkpickering
Copy link
Member

adamkpickering commented Feb 22, 2023

So when LonghornProvider requests the list of available versions from Upgrade Responder, it does this via a POST request with the following payload:

{
  "appVersion": "1.6.0",
  "extraInfo": {
    "platform":"<platform>-<arch>"
  }
}

The Upgrade Responder server sends back something in the following format:

{
  "versions": [
    {
      "Name": "v1.5.0",
      "ReleaseDate": "2022-07-28T11:00:00Z",
      "Tags": [
        "v1.5.0"
      ]
    },
    {
      "Name": "v0.7.1",
      "ReleaseDate": "2021-12-20T14:30:00Z",
      "Tags": [
        "v0.7.1"
      ]
    },
    ...
  ]
}

So there is no information about OS version at the moment.

The solution that comes to my mind is to fork Upgrade Responder and make a few modifications:

  • take the requester's OS version in the POST request from LonghornProvider
  • add a field to the version objects in the response that indicates whether a version is supported for the OS, OS version and architecture that was sent in the POST request

If a requester doesn't include its OS version in the POST request, we know that it is from version 1.7.0 or earlier. So, we are able to treat this case specially in whatever way we choose. Maybe we allow an upgrade to 1.7.1, in which we can add code that sends the OS version?

Otherwise, we can configure the Upgrade Responder with information about which versions of Rancher Desktop are supported on which OS-architecture-OS version combinations. If an instance of Rancher Desktop receives info from the Upgrade Responder that indicates that there is a newer version of Rancher Desktop, but this version is not supported for the OS, architecture and OS version indicated in the request, we can make the RD UI display a message along the lines of "please upgrade to a newer version of your OS to use the latest version of RD".

@adamkpickering
Copy link
Member

If we choose to go the route of forking Upgrade Responder, here is what I propose.

We change the "response config" that is passed to the UR to something like this:

{
  "Rules": [
    {
      "Criteria": {
        "CurrentRDVersion": "<1.8.0",
        "Platform": "*",
        "Arch": "*",
        "PlatformVersion": "*"
      },
      "Constraints": {
        "Version": "<=1.8.0"
      }
    },
    {
      "Criteria": {
        "CurrentRDVersion": "*",
        "Platform": "darwin",
        "Arch": "*",
        "PlatformVersion": "<11.0.0"
      },
      "Constraints": {
        "Version": "<=1.8.0"
      }
    },
    {
      "Criteria": {
        "CurrentRDVersion": "*",
        "Platform": "*",
        "Arch": "*",
        "PlatformVersion": "*"
      },
      "Constraints": {
        "Version": ">=0.0.0"
      }
    },
  ],
  "Versions": [
    {
      "Name": "v1.5.0",
      "ReleaseDate": "2022-07-28T11:00:00Z",
      "Tags": [
        "v1.5.0"
      ]
    },
    {
      "Name": "v0.7.1",
      "ReleaseDate": "2021-12-20T14:30:00Z",
      "Tags": [
        "v0.7.1"
      ]
    },
    ...
  ]
}

The Versions key is unchanged. The meaningful addition is Rules. Each element of Rules has a set conditions that determine whether a given request matches it (under Criteria). Each element also has a set of restrictions that apply if there is a match (under Constraints). Currently there is only a Version constraint, but we could add more in the future if needed.

When a request comes in, it ideally contains info on the platform, the version of the platform, the architecture, and the current version of RD on the requestor. This info is used to find the first rule that matches. Then, using the Constraints part of the rule, a Supported key is added to each element of Versions. This key says whether the given version is supported for the received specs. So, Upgrade Responder returns a JSON object that is identical to what it does right now, with the addition of the Supported key to each version:

{
  "versions": [
    {
      "Name": "v1.5.0",
      "Supported": true,
      "ReleaseDate": "2022-07-28T11:00:00Z",
      "Tags": [
        "v1.5.0"
      ]
    },
    {
      "Name": "v0.7.1",
      "Supported": false,
      "ReleaseDate": "2021-12-20T14:30:00Z",
      "Tags": [
        "v0.7.1"
      ]
    },
    ...
  ]
}

If no rules match, that is considered an error. This is why we have three rules:

  • The first rule matches any install of RD that has a version less than or equal to 1.8.0. It prevents RD from upgrading to anything past 1.8.0. Of course, once RD is running 1.8.0 it will be able to upgrade to newer versions if supported for the system it's running on.
  • The second rule matches macOS Catalina and earlier. This rule limits the version to 1.8.0.
  • The third rule is a catch-all rule. It matches anything and does not restrict the version the instance can upgrade to.

I'd optimistically estimate 3 days to make these changes to Upgrade Responder, and another 3 days to get it working on the Rancher Desktop side. These estimates don't include time for reviews.

@gaktive gaktive added the kind/epic Umbrella-bug for a group of related issues label Feb 23, 2023
@adamkpickering adamkpickering changed the title Updater needs to know when we stop supporting older OS versions Enable preventing automatic updates on specific OS versions Feb 23, 2023
@jandubois
Copy link
Member Author

  • The first rule matches any install of RD that has a version less than or equal to 1.8.0. It prevents RD from upgrading to anything past 1.8.0. Of course, once RD is running 1.8.0 it will be able to upgrade to newer versions if supported for the system it's running on.

This rule is not needed since we will never return rules to requests from versions before 1.8.0, as they have no logic to deal with them.

@jandubois jandubois modified the milestones: 1.8, 1.9 Mar 8, 2023
@adamkpickering
Copy link
Member

We can hard-code that into the changes if you want. Though it will make the code a little messier and less flexible, given that we have to hard-code handling this case.

@jandubois
Copy link
Member Author

We can hard-code that into the changes if you want. Though it will make the code a little messier and less flexible, given that we have to hard-code handling this case.

Maybe I misunderstand it, but don't you have to hard-code it into the code anyways. Versions before 1.8 don't know about the Supported property, so you have to filter out all versions that have Supported=false for requests from pre-1.8 releases anyways.

Otherwise you would need another flag in your rules that says: if this rule matches, don't include unsupported versions in the response.

@adamkpickering
Copy link
Member

Ah, you're right. We'll have to hard-code that then. Might as well eliminate the first rule while we're at it.

@mook-as
Copy link
Contributor

mook-as commented Mar 8, 2023

The old code just looked for a latest tag, whereas I don't believe the new code looks at tags at all.
We can just have the latest tag stuck on the version we want 1.8 to upgrade to.

@jandubois
Copy link
Member Author

The old code just looked for a latest tag, whereas I don't believe the new code looks at tags at all.
We can just have the latest tag stuck on the version we want 1.8 to upgrade to.

That is a good idea, so we don't have to hardcode the version in the code.

We still don't need the first rule for this though.

Unless we let the server set the latest tag on the highest version number that is Supported. Not sure if there is much point to it though.

Similarly we could set a "newest" tag on the very newest release, so the client can tell that there is an unsupported upgrade as well because latest and newest tags are on different versions. Again, there may be no advantage to this over doing it client-side.

@jandubois jandubois changed the title Enable preventing automatic updates on specific OS versions Epic: Enable preventing automatic updates on specific OS versions Mar 17, 2023
@adamkpickering
Copy link
Member

The old code just looked for a latest tag, whereas I don't believe the new code looks at tags at all.
We can just have the latest tag stuck on the version we want 1.8 to upgrade to.

That's a great idea. It might be weird for people to see a "latest" tag on what will end up being a very old version of RD, but we should document all of this in the developer documentation anyways.

Versions before 1.8 don't know about the Supported property, so you have to filter out all versions that have Supported=false for requests from pre-1.8 releases anyways.

It's true that versions of RD before 1.8 (actually 1.9 after deferring this change) have no knowledge of Supported. But typescript turns into javascript after transpiling. So when RD deserializes the JSON response from the server into a javascript object, the Supported key may or may not be there - it doesn't matter, because we don't reference it. This has always bothered me about typescript, but in this case it's helpful.

@jandubois
Copy link
Member Author

Just re-reading the spec and discussion here, and one thing that is irritating me is that the Rules section uses plain versions, and the Versions section prefixes them with v. There should be a consistent style across all fields.

I assume for backwards compatibility reasons that means the rules should use vX.Y.Z style versions too. If that is not necessary, then I prefer dropping the prefix.

@jandubois
Copy link
Member Author

I'm wondering of the versions with "Supported": false settings should include an explanation, like "This version requires macOS 13.3 or later".

Otherwise the client can only say "There is a newer version available, but it is not compatible with your system".

E.g. the user upgrades from Catalina to Monterey, but it doesn't help because we really need "Ventura". But the user's machine is not compatible with Ventura, so they went through all the effort to upgrade to Monterey for nothing.

@adamkpickering
Copy link
Member

Just re-reading the spec and discussion here, and one thing that is irritating me is that the Rules section uses plain versions, and the Versions section prefixes them with v. There should be a consistent style across all fields.

I assume for backwards compatibility reasons that means the rules should use vX.Y.Z style versions too. If that is not necessary, then I prefer dropping the prefix.

I looked into our options here. Luckily, the current client code properly handles Name fields whether they have a v in them or not. This is important because it is used in getting the latest release from github via its tag, which is a semver prefixed by a v.

I am confident that we can drop the v prefix. I will make a few tweaks to the Upgrade Responder config parsing code to enforce this.

@adamkpickering
Copy link
Member

I'm wondering of the versions with "Supported": false settings should include an explanation, like "This version requires macOS 13.3 or later".

Otherwise the client can only say "There is a newer version available, but it is not compatible with your system".

E.g. the user upgrades from Catalina to Monterey, but it doesn't help because we really need "Ventura". But the user's machine is not compatible with Ventura, so they went through all the effort to upgrade to Monterey for nothing.

I think I figured out a feasible way of adding better feedback to the Latest Version Not Supported card in the UI.

For a while I was trying to think of a way to autogenerate a human-readable string from Rule.Criteria. I don't this is the right way to do it, since it would be complicated, probably bug-ridden and wouldn't produce very helpful output anyways.

I think the best way to do it is to add a field called Explanation to Rule. This field holds a string that is the human-readable equivalent of Rule.Criteria. It would answer the question, "why is this version not supported on my system?" So a Rule would look like this:

{
  "Explanation": "macOS 11.0.0 or later is required.",
  "Criteria": {
    "CurrentRDVersion": "*",
     "Platform": "darwin",
     "Arch": "*",
     "PlatformVersion": "<11.0.0"
  },
  "Constraints": {
    "Version": "<=1.8.0"
  }
}

This lets us easily handle cases where there are multiple Criteria:

{
  "Explanation": "macOS 11.0.0 or later is required on M1 machines.",
  "Criteria": {
    "CurrentRDVersion": "*",
     "Platform": "darwin",
     "Arch": "arm64",
     "PlatformVersion": "<11.0.0"
  },
  "Constraints": {
    "Version": "<=1.8.0"
  }
}

But how would this make it through to Rancher Desktop, and then to the UI? I'd suggest adding a field to the response Upgrade Responder gives when Supported == false:

{
  "versions": [
    {
      "Name": "v1.5.0",
      "Supported": true,
      "ReleaseDate": "2022-07-28T11:00:00Z",
      "Tags": [
        "v1.5.0"
      ]
    },
    {
      "Name": "v1.10.0",
      "Supported": false,
      "Explanation": "macOS 11.0.0 or later is required."
      "ReleaseDate": "2021-12-20T14:30:00Z",
      "Tags": [
        "v0.7.1"
      ]
    },
    ...
  ]
}

This message can then be passed through to the UI. The Latest Version Not Supported card would look something like this:


Latest Version Not Supported

A newer version of Rancher Desktop is available, but not supported on your system.

macOS 11.0.0 or later is required.

For more information see the installation documentation.


We can tweak this message. It might be nice to indicate which version is available for an update but unsupported. Maybe we want someone who knows about UI to weigh in here?

@gaktive
Copy link
Contributor

gaktive commented Jun 26, 2023

There should be a story tied to docs but we'll close this.

@gaktive gaktive closed this as completed Jun 26, 2023
@jandubois
Copy link
Member Author

There should be a story tied to docs but we'll close this.

The story is #5028, and is about copying the information from this Epic into a permanent location inside the repo itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/updates kind/enhancement New feature or request kind/epic Umbrella-bug for a group of related issues priority/0 Work needs to go into the next release or force a patch
Projects
None yet
Development

No branches or pull requests

4 participants