Skip to content

Implement workload redirects #18166

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

Merged
merged 26 commits into from
Jul 19, 2021

Conversation

mhutch
Copy link
Contributor

@mhutch mhutch commented Jun 9, 2021

Implements workload redirects as defined in dotnet/designs#221

@ghost
Copy link

ghost commented Jun 9, 2021

I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label.

@mhutch
Copy link
Contributor Author

mhutch commented Jun 9, 2021

I haven't added tests yet, but this demonstrates the transparent redirect approach

@mhutch mhutch requested review from wli3, sfoslund and dsplaisted June 9, 2021 05:21
@mhutch mhutch force-pushed the workload-redirects branch 8 times, most recently from a5b4d60 to 4c178ef Compare June 10, 2021 22:50
/// <param name="advertisingManifestResolver">A resolver that composes the advertising manifests with the installed manifests that do not have corresponding advertising manifests</param>
/// <param name="existingWorkloads">The IDs of all of the installed workloads</param>
/// <returns></returns>
public IEnumerable<WorkloadId> GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable<WorkloadId> installedWorkloads)
Copy link

Choose a reason for hiding this comment

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

That is a new logic? WorkloadManifestUpdater.CalculateManifestUpdates is doing similar

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is to replace it. This one handles redirects and cross-manifest dependencies.

@@ -34,4 +43,14 @@ public enum WorkloadDefinitionKind
Dev,
Build
}

public class WorkloadRedirect : BaseWorkloadDefinition
Copy link

Choose a reason for hiding this comment

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

I need more time to thing about it. So far to me, it is transparent in the workload manifest sense. However, workload ID is used many places outside manifest reader. Mostly installation record, and UI for display. As an ID, it should be unique. And now the assumption breaks.

Every time we compare workload id, we need to consider if they are just an alias. And when we iterate workloads, which "id" we should display?

The current code should not be able to resolve installation record mismatch. We need some kind of migration of installation record. But what if there is a downgrade?

We need to re-evaluate every place we have a workloadid.toString and comparison. In general, I don't like 2 ID can point to the same thing (nuget package id being inconsistently case sensitive/ in sensitive caused a lot bugs already). It is a lot for the caller to watch out. Maybe we could override "==" and "toString". But I still prefer to just have another layer of "display id" and never change the "true id"

@wli3
Copy link

wli3 commented Jun 28, 2021

@mhutch hows the progress?

@mhutch mhutch force-pushed the workload-redirects branch from 88bc040 to 11d15c2 Compare July 6, 2021 21:14
@sfoslund
Copy link
Member

sfoslund commented Jul 6, 2021

@mhutch is this PR ready for review?

@mhutch
Copy link
Contributor Author

mhutch commented Jul 7, 2021

@sfoslund all the existing commits are ready for review, yes. I have a couple more commits to come.

Copy link
Member

@sfoslund sfoslund left a comment

Choose a reason for hiding this comment

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

LGTM overall but I'm not sure why CI isn't running. Can we move this out of draft mode? I'd like to get this in this week if possible.

@@ -512,7 +510,7 @@ public PackInfo(string id, string version, WorkloadPackKind kind, string path, s
/// <summary>
/// The workload pack ID. The NuGet package ID <see cref="ResolvedPackageId"/> may differ from this.
/// </summary>
public string Id { get; }
public WorkloadPackId Id { get; }
Copy link
Member

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this PackInfo.Id type change caused #20350.

@@ -463,7 +463,8 @@ private static BaseWorkloadDefinition ReadWorkloadDefinition(WorkloadId id, ref
{
throw new WorkloadManifestFormatException(Strings.RedirectWorkloadHasOtherKeys, id);
}
return new WorkloadRedirect (id, replacementId);
throw new NotImplementedException("Workload redirects are not yet fully implemented");
//return new WorkloadRedirect (id, replacementId);
Copy link
Member

Choose a reason for hiding this comment

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

Remove commented out code

/// <param name="advertisingManifestResolver">A resolver that composes the advertising manifests with the installed manifests that do not have corresponding advertising manifests</param>
/// <param name="existingWorkloads">The IDs of all of the installed workloads</param>
/// <returns></returns>
public IEnumerable<WorkloadId> GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable<WorkloadId> installedWorkloads)
Copy link
Member

Choose a reason for hiding this comment

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

This looks great, I'll update the existing code to start using it when this is checked in.

{
throw new Exception($"Duplicate workload manifest {manifestId}");
throw new WorkloadManifestCompositionException($"Manifest '{manifestId}' from provider {manifestProvider} does not match payload id '{manifest.Id}'");
Copy link
Member

Choose a reason for hiding this comment

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

Do we expect users to see these errors? If so, they should be localized.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They probably should, yes. I didn't worry because it's possible they'll never be seen, and they aren't very useful to end-users. They're basically internal errors and indicate either the manifests themselves are broken or the combination of manifests is broken.

That said, a lot of the workload manifest errors are localized, so these probably should be too for consistency.

Perhaps the CLI should catch WorkloadManifestCompositionException and WorkloadManifestFormatException and report an error that says the installation (or nuget sources) is broken and suggests repairing or reinstalling.

@marcpopMSFT
Copy link
Member

@mhutch Is this ready to take out of draft and get CI running as I believe some work from others (Sarah and Will) is waiting on this PR?

@mhutch mhutch marked this pull request as ready for review July 12, 2021 23:18
@sfoslund
Copy link
Member

@mhutch do you mind resolving the conflicts so we can get CI running and merge? Let me know if you need a hand, I'm happy to help.

@mhutch
Copy link
Contributor Author

mhutch commented Jul 13, 2021

@sfoslund sure, i can rebase & resolve. is this targeting the right branch?

@sfoslund
Copy link
Member

is this targeting the right branch?

Yep!

mhutch added 15 commits July 16, 2021 20:15
Manifests have an "informational path" describing where they were
loaded from. The workload resolver includes the manifest IDs and
associated informational path in composition errors, so it's easier
to see what caused the conflict.
IIRC WorkloadId used to be private but now it's public there's no
reason not to use it
We are not fully certain that they are transparent and that they won't
cause unintended knock-on effects.
* Better error for missing base workload
* Now returns information about where the pack was referenced
  so better errors can be provided
* Factored out a helper for enumerating base workloads
Platform checks should take restrictions on base workloads into account,
as clarified in dotnet/designs#230.
This means that the CLI can no longer trivially display the RIDs for
the platforms on which the workloads are available. This could be added
back in future using the RID graph to coalesce values, but would probably
need additional work to ensure the values were user friendly.

The resolver no longer returns workload definitions. The ensures clients
use the resolver's APIs that work on the composed manifest data. Having
all code that deals with manifest data direct in a central location
helps keep behaviour consistent.

It also does not be return abstract or empty workloads as these
cannot be installed.
Ensures aliased pack IDs are always resolved
Also improves errors from unresolved redirects, and handles
redirects in a second pass so they're not dependent on order
of manifests and definitions
We now have a collection of the manifests that are loaded, so use
that rather than rescanning. This makes it behave correctly for
correct for overlay resolvers.

Also return an "Info" object to be consistent with other API. We
may want to add more information onto this object in future.
Fallout from the switch from string to id structs
When getting a suggestion for workloads to satisfy missing packs,
first determine which cannot be installed on the current machine,
and report them with a specific error code NETSDK1178.
@mhutch mhutch force-pushed the workload-redirects branch from 8cd699f to 0537ca7 Compare July 17, 2021 08:07
@mhutch mhutch changed the base branch from main to release/6.0.1xx-preview7 July 17, 2021 23:26
@dsplaisted
Copy link
Member

@mhutch @sfoslund I fixed some issues with the tests here. There are still more failing tests which I may be able to investigate later.

@mhutch mhutch force-pushed the workload-redirects branch from 485bc39 to f4ed4c7 Compare July 19, 2021 06:57
This prevents it from erroring out because it loads the same manifest
twice in the workload update test.
@dsplaisted
Copy link
Member

@mhutch @sfoslund I think I've fixed the remainder of the test failures.

I replaced IWorkloadResolver.IsWorkloadPlatformCompatible with IsPlatformIncompatibleWorkload in order to support querying whether a workload which wasn't returned by GetAvailableWorkloads was a valid workload ID which wasn't available on the current platform, in order to generate the correct error message.

Copy link
Member

@sfoslund sfoslund left a comment

Choose a reason for hiding this comment

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

LGTM, a few nits from my previous review are still left but we can follow up on those later. @mhutch @dsplaisted can we merge this?

Copy link
Member

@sfoslund sfoslund left a comment

Choose a reason for hiding this comment

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

LGTM, a few nits from my previous review are still left but we can follow up on those later. @mhutch @dsplaisted can we merge this?

@mhutch
Copy link
Contributor Author

mhutch commented Jul 19, 2021

Sounds good to me :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants