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
Stage 1 of Package Reference Compatibility Validation #346
Conversation
@@ -40,6 +40,13 @@ | |||
"SubscriptionName": "" | |||
} | |||
}, | |||
"PackageCompatibility": { | |||
"ServiceBus": { | |||
"ConnectionString": "servicebus string", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: empty strings like the other ones
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cleaned up.
Got a link to the ServerCommon PR as well? |
return validatorStatus.ToValidationResult(); | ||
} | ||
|
||
// Add the status, so subsequent calls don't try to reevaluate the same thing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: re-evaluate
{ | ||
public PackageCompatibilityValidationMessage(string packageId, string packageVersion, Uri nupkgUri, Guid validationId) | ||
{ | ||
PackageId = packageId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null checks
|
||
namespace Validation.PackageCompatibility.Core.Messages | ||
{ | ||
public class PackageCompatibilityValidationMessageSerializer : IBrokeredMessageSerializer<PackageCompatibilityValidationMessage> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is not needed right now, right?
} | ||
catch (DbUpdateConcurrencyException e) | ||
{ | ||
_logger.LogWarning("trouble saving changes async - {0}", e.Message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How could this case happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meant to use DbUpdateException.
Just in case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would instead recommend having a big try/catch around your entire validation flow so that it does not effect package publish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[assembly: AssemblyTitle("Validation.PackageCompatibility.Core")] | ||
[assembly: AssemblyDescription("")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("HP Inc.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No clue lol.
It's supposed to be autogened.
Didn't find any mentions of HP in the code otherwise.
<Version>4.7.0-preview1-4929</Version> | ||
</PackageReference> | ||
</ItemGroup> | ||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs our sign targets -- see other csproj
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added it.
@@ -85,6 +85,11 @@ | |||
<Name>Validation.PackageSigning.Core</Name> | |||
</ProjectReference> | |||
</ItemGroup> | |||
<ItemGroup> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, otherwise the packaging version gets bumped up because of the different version in NuGet.PackageCompatibility.Core project.
Attempting to get the same version throughout the whole solution breaks some signing APIs.
.vs/config/applicationhost.config
Outdated
@@ -163,12 +163,20 @@ | |||
</site> | |||
<site name="Validation.Callback.Vcs" id="2"> | |||
<application path="/" applicationPool="Clr4IntegratedAppPool"> | |||
<virtualDirectory path="/" physicalPath="C:\src\NuGet.Jobs\src\Validation.Callback.Vcs" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sutff shouldn't change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this in ignore?
@@ -86,7 +91,7 @@ public override void Init(IDictionary<string, string> jobArgsDictionary) | |||
return; | |||
} | |||
|
|||
var runner = GetRequiredService<OrchestrationRunner>(); | |||
var runner = GetRequiredService<OrchestrationRunner>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: trailing spaces
// Try check the whole thing | ||
try | ||
{ | ||
var validatorStatus = await _validatorStateService.GetStatusAsync(request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: move all of the code in the try
into a helper method to minimize chance of putting logic outside of the try
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogWarning($"Validation failed for the validation request {0}.{Environment.NewLine}Exception: {1}", request.ToString(), e.ToString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LogWarning
has an overload that accepts an exception I think.
private static void ConfigurePackageCompatibilityValidator(ContainerBuilder builder) | ||
{ | ||
|
||
// Configure the validator state service for the package compatibility validator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configure [](start = 15, length = 9)
There's an extra line on 357 and on 376
@@ -5,6 +5,8 @@ | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Net.Http; | |||
using System.Reflection; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these usings necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cleaned up.
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogWarning($"Validation failed for the validation request {0}.{Environment.NewLine}Exception: {1}", request.ToString(), e.ToString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let the logger call ToString
. ToString
may be expensive and the logger may choose to not emit the log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed that up, after getting the same feedback from @joelverhagen
); | ||
|
||
// Do validation | ||
await Validate(message, CancellationToken.None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate [](start = 22, length = 8)
If Validate
throws, won't a validation get "stuck" in Incomplete
state? Should Validate
happen before the TryAddValidatorStatusAsync
?
{ | ||
public class PackageCompatibilityValidationMessage | ||
{ | ||
public PackageCompatibilityValidationMessage(string packageId, string packageVersion, Uri nupkgUri, Guid validationId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PackageCompatibilityValidationMessage [](start = 15, length = 37)
Is this just used for the PackageCompatibilityValidator.Validate method? A public class seems like over kill, maybe a private class in PackageCompatibilityValidator would be better. Also, are all of these parameters used? It seems like PackageId is not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In phase 2, this validation will run in it's own proc, and it'll be used there for logging and better visibility, analogous to the way the package id/version are used in the signing validation.
} | ||
catch (DbUpdateException e) | ||
{ | ||
_logger.LogWarning("trouble saving changes async - {0}", e.Message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Message [](start = 75, length = 7)
You should log the full exception instead of e.Message
as the real exception may be hidden in a InnerException
. If the database fails to save here, won't the PackageCompatibilityValidator think that it's successfully finished SetPackageCompatibilityState
and set the validator status to ValidationStatus.Succeeded
?
/// <summary> | ||
/// Configuration for initializing the <see cref="PackageCompatibilityValidator"/>. | ||
/// </summary> | ||
public class PackageCompatibilityValidator : IValidator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PackageCompatibilityValidator [](start = 17, length = 29)
Validators that are outside of the NuGet.Services.Validation.Orchestrator
project are not supported today. This is a low-priority "bug" in the Orchestrator that we will fix in the future. The type that extends IValidator
will need to be moved, the implementation can be kept here.
See this:
IEnumerable<Type> candidateTypes = GetCandidateTypes(Assembly.GetCallingAssembly()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's useful feedback.
This is currently in the Orchestrator project though, just making sure you noticed that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh. I can't read :)
} | ||
|
||
// Add the status, so subsequent calls don't try to re-evaluate the same thing | ||
await _validatorStateService.TryAddValidatorStatusAsync(request, validatorStatus, ValidationStatus.Incomplete); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TryAddValidatorStatusAsync [](start = 41, length = 26)
TryAddValidatorStatusAsync
can return a ValidationStatus
that is NOT Incomplete
. In such a case, you should immediately return the other status.
This could happen if the message to validate a package is duplicated and one message finishes validating the package AFTER both validators have verified that the validation hasn't started yet.
validatorStatus.State = ValidationStatus.Succeeded; | ||
|
||
await _validatorStateService.SaveStatusAsync(validatorStatus); | ||
return validatorStatus.ToValidationResult(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ToValidationResult [](start = 35, length = 18)
You should be returning the status according to the SaveStatusAsync
as two threads may attempt the SaveStatusAsync
call. It seems like today this won't be an issue as wewill only persist Succeeded
, but I would rather be resilient to future changes :)
🔔 |
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogWarning(0, e, "Validation failed for the validation request {request}", request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just request ID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
er, Validation ID
// Treat every validation as succeeded, as we don't want to block | ||
validatorStatus.State = ValidationStatus.Succeeded; | ||
|
||
var result = await _validatorStateService.SaveStatusAsync(validatorStatus); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this case fails do we really want to fail push?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would this fail?
What state would the validation be stuck in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor it back to the "old" state.
It's not the prettiest but, it makes sure we're not in a weird state even though it doesn't hurt it.
Looks good so far. Things to do prior to checking in:
|
a1d1008
to
a7bd6d9
Compare
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogWarning(0, e, "Validation failed in the validator for the following request {request}", request.ValidationId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: for the following request {request}
-> for the following validation id {ValidationId}
. Same thing with line 82
dd404d4
to
f25b0a4
Compare
I've added some more changes. |
IPackageDownloader packageDownloader, | ||
ILogger<PackageCompatibilityValidator> logger) | ||
{ | ||
_validatorStateService = validatorStateService; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null checks
_validationContext.PackageCompatibilityIssues.Add( | ||
new PackageCompatibilityIssue() | ||
{ | ||
ClientIssueCode = log.Code.ToString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storing the client issue code as is, can cause issues if you want to have server specific validations that are not available on client side.
For Package Signing Joel has a server side error code that "wraps" all client side error codes, and granular server side error codes for other problems.
I recommend the same approach here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I discussed this with @joelverhagen.
The idea for the Package Reference validations is that they'll always be client controlled.
The APIs used are the exact ones as the one in the client code.
Also not reusing that table allows us more freedom to evolve the design moving forward.
@@ -71,6 +78,7 @@ | |||
"AnnouncementsUrl": "https://github.com/NuGet/Announcements/issues", | |||
"TwitterUrl": "https://twitter.com/nuget" | |||
}, | |||
"PackageDownloadTimeout": "10:00", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is specific to PackageCompatibility validator, please move the config there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only here, because the validator is currently running in-proc.
Once the validator is in it's own process it will get moved out of here.
I'm ok with checking this in to DEV branch, however, it shouldn't run as is because downloading the package in the Orchestrator might impact perf. |
f25b0a4
to
34c4c46
Compare
f65f784
to
1143816
Compare
More progress on NuGet/NuGetGallery#6317.
* Feed2Catalog: replace inner loops with one outer loop (#329) Resolve NuGet/Engineering#1526. * V3: rename asynchronous IStorage methods (#336) Progress on NuGet/NuGetGallery#6267. * Test: fix flaky basic search tests (#337) Progress on NuGet/NuGetGallery#6292. * Add signing to search service (#338) Progress on https://github.com/NuGet/Engineering/issues/1644 * Test: add registration tests (#341) Progress on NuGet/NuGetGallery#6317. * remove unused scripts (#340) * MonitoringProcessor: improve throughput (#342) Progress on NuGet/NuGetGallery#6327. * Catalog2Dnx: improve throughput (#335) Progress on NuGet/NuGetGallery#6267. * Functional tests should not be dependent on a specific hash and file size of the test package (#343) * Add MicroBuild dependency and signing of output DLLs (#345) Progress on https://github.com/NuGet/Engineering/issues/1644 * Rewrite SafeRoleEnvironment to not use Assembly.LoadWithPartialName (#339) * Test: improve and add registration tests (#346) More progress on NuGet/NuGetGallery#6317. * Use ServerCommon commit that is consistent with other repositories (#347) Progress on https://github.com/NuGet/Engineering/issues/1644 * [Monitoring] Ensure packages are signed (#348) This adds a validation to ensure indexed packages are signed by verifying that the package contains a [package signature file](https://github.com/NuGet/Home/wiki/Package-Signatures-Technical-Details#-the-package-signature-file). This validation is disabled for now. To enable this validation, the flag `-expectsSignature true` must be added to ng.exe's command line arguments. This validation will be enabled once all packages are repository signed. Part of NuGet/Engineering#1627 * V3: make stylistic consistency and cleanup changes (#349) Progress on NuGet/NuGetGallery#6411.
Unfortunately this work didn't get merged a few years back and I don't see this getting put high on the priority list soon again. |
😭 |
More progress on NuGet/NuGetGallery#6317.
* Feed2Catalog: replace inner loops with one outer loop (#329) Resolve NuGet/Engineering#1526. * V3: rename asynchronous IStorage methods (#336) Progress on NuGet/NuGetGallery#6267. * Test: fix flaky basic search tests (#337) Progress on NuGet/NuGetGallery#6292. * Add signing to search service (#338) Progress on https://github.com/NuGet/Engineering/issues/1644 * Test: add registration tests (#341) Progress on NuGet/NuGetGallery#6317. * remove unused scripts (#340) * MonitoringProcessor: improve throughput (#342) Progress on NuGet/NuGetGallery#6327. * Catalog2Dnx: improve throughput (#335) Progress on NuGet/NuGetGallery#6267. * Functional tests should not be dependent on a specific hash and file size of the test package (#343) * Add MicroBuild dependency and signing of output DLLs (#345) Progress on https://github.com/NuGet/Engineering/issues/1644 * Rewrite SafeRoleEnvironment to not use Assembly.LoadWithPartialName (#339) * Test: improve and add registration tests (#346) More progress on NuGet/NuGetGallery#6317. * Use ServerCommon commit that is consistent with other repositories (#347) Progress on https://github.com/NuGet/Engineering/issues/1644 * [Monitoring] Ensure packages are signed (#348) This adds a validation to ensure indexed packages are signed by verifying that the package contains a [package signature file](https://github.com/NuGet/Home/wiki/Package-Signatures-Technical-Details#-the-package-signature-file). This validation is disabled for now. To enable this validation, the flag `-expectsSignature true` must be added to ng.exe's command line arguments. This validation will be enabled once all packages are repository signed. Part of NuGet/Engineering#1627 * V3: make stylistic consistency and cleanup changes (#349) Progress on NuGet/NuGetGallery#6411.
Part of NuGet/Home#6533
ServerCommon PR:
NuGet/ServerCommon#138
I will update the common packages later.
Add an in-proc validator for package reference compatibility, that persist the issues in it's own table, that should allow us to nuke it later.
The validator always "succeeds" because don't want to fail validation, and we don't have the means to rerun a validation right now.
Stage 2 will make it out of proc.