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

net48 and net6 #422

Merged
merged 48 commits into from
Nov 21, 2022
Merged

net48 and net6 #422

merged 48 commits into from
Nov 21, 2022

Conversation

veochen-octopus
Copy link
Contributor

@veochen-octopus veochen-octopus commented Oct 4, 2022

Background

  • net452 is end of support and is preventing us from getting security patches both in the framework itself and 3rd party libraries.
  • We'll need to support Ubuntu 22.04 pretty soon so net6 is also required.

Results

Fixes [sc-12030]
Fixes [sc-27468]
Fixes #424

Before

<TargetFrameworks>net452;netcoreapp3.1</TargetFrameworks>

After

<TargetFrameworks>net48;net6.0</TargetFrameworks>

How to review this PR

Quality ✔️

Pre-requisites

  • I have read How we use GitHub Issues for help deciding when and where it's appropriate to make an issue.
  • I have considered informing or consulting the right people, according to the ownership map.
  • I have considered appropriate testing for my change.

@@ -186,7 +186,7 @@ static bool HasPrivateKey(X509Certificate2 certificate2)
{
try
{
return certificate2.HasPrivateKey && certificate2.PrivateKey != null;
return certificate2.GetRSAPrivateKey() != null;
Copy link
Contributor Author

@veochen-octopus veochen-octopus Oct 16, 2022

Choose a reason for hiding this comment

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

Changed due to the PrivateKey property supposedly not working in .net framework with EphemeralKeySet.

Keys loaded in this manner are almost always loaded via Windows CNG. Therefore, callers must access the private key by calling extension methods, such as cert.GetRSAPrivateKey(). The X509Certificate2.PrivateKey property does not function.

I'm assuming GetECDsaPrivateKey doesn't come into play here. There's only reference to RSA.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also TODO: Add a comment that this may be reverted to .PrivateKey once .NET framework is dropped entirely. Will use this change to trigger the final build before merge.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this TODO need action?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that was confusing. Looking at it again, no action needed.

@@ -103,7 +103,7 @@ static X509Certificate2 FromBase64String(string? thumbprint, string certificateS
}
}

#if NET472_OR_GREATER || NETCOREAPP || NETSTANDARD
#if NETCOREAPP || NETSTANDARD
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 used to be bypassed as we were targeting net452, but breaks net48. With EphemeralKeySet the cert loses the private key once added to the key store. As per the doc

Since the keys are not persisted to disk, certificates loaded with this flag are not good candidates to add to an X509Store.

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 essentially allows us to keep the same behaviour as net452

@veochen-octopus
Copy link
Contributor Author

veochen-octopus commented Oct 17, 2022

Github still configured to wait for a status from the "real" tentacle project in teamcity. Thinking once the PR is ready, we update the main build first to target net48, then get a green build and merge.

Here's a green build on the cloned project - https://build.octopushq.com/buildConfiguration/TeamFireAndMotion_OctopusTentacleNet48_SensibleDefaultsChainFullChain/5907122?hideProblemsFromDependencies=false&hideTestsFromDependencies=false&expandBuildChangesSection=true&expandPull+Request+Details=true

<PackageReference Include="FluentAssertions" Version="6.7.0" />
<PackageReference Include="Assent" Version="1.8.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Taking the opportunity to update some test packages. No non-test dependencies were changed.

@veochen-octopus veochen-octopus marked this pull request as ready for review October 17, 2022 02:22
@veochen-octopus veochen-octopus requested a review from a team as a code owner October 17, 2022 02:22
@tothegills
Copy link
Contributor

What kind of customer comms are we doing? Does that need to happen before this is merged?

@veochen-octopus
Copy link
Contributor Author

veochen-octopus commented Oct 17, 2022

What kind of customer comms are we doing? Does that need to happen before this is merged?

@tothegills I think @octokhor is handling the comms side of things.

Given the change of plan, I'll piggyback the net6 changes onto this PR as well so we end up with only 1 major/minor version bump. Moving PR back to draft for now.

@veochen-octopus veochen-octopus marked this pull request as draft October 17, 2022 20:28
@veochen-octopus veochen-octopus changed the title net48 net48 and net6 Oct 17, 2022
@veochen-octopus veochen-octopus force-pushed the veo/net48 branch 2 times, most recently from 2d1a73f to 1d1767c Compare October 19, 2022 05:52
@@ -70,7 +70,7 @@ class InMemoryCryptoKeyNixSource : ICryptoKeyNixSource
readonly byte[] iv;
public InMemoryCryptoKeyNixSource()
{
var d = new RijndaelManaged();
var d = Aes.Create();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

RijndaelManaged obsolete. All references changed to Aes.Create

@@ -97,7 +97,7 @@ X509Certificate2 Generate(string fullName, bool exportable)
using (var ms = new MemoryStream())
{
store.Save(ms, exportpw.ToCharArray(), random);
var platformSpecificX509KeyStorageFlags = PlatformDetection.IsRunningOnMac ? X509KeyStorageFlags.DefaultKeySet : X509KeyStorageFlags.EphemeralKeySet;
var platformSpecificX509KeyStorageFlags = PlatformDetection.IsRunningOnNix ? X509KeyStorageFlags.EphemeralKeySet : X509KeyStorageFlags.DefaultKeySet;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't think EphemeralKeySet works with Windows at all. See other change.

BlockSize = 128,
Key = key
};
var provider = Aes.Create();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Another obsolete. Updated to current standard.


static bool HasFlagEphemeralKeySet(X509KeyStorageFlags flags)
{
return flags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);
return !PlatformDetection.IsRunningOnWindows && flags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);
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 based on the assumption that EphemeralKeySet doesn't work with Windows. See the issue mentioned in the comment - dotnet/runtime#23749. Halibut uses SslStream which in the current version of Windows is not compatible with EphemeralKeySet causing authentication to fail, on Windows tentacles only. All signs are suggesting this only works with Linux.

@veochen-octopus
Copy link
Contributor Author

Not sure about the best way to update the teamcity build. There are quite a few changes to be made and it's hard to keep track of them. Thinking probably the easiest is to replace the old tentacle project with the new one and make sure everything has the correct names and ids, get a green build and merge.


WORKDIR /tmp
RUN msiexec /i Octopus.Tentacle.%BUILD_NUMBER%-x64.msi /qn /l*v Tentacle-Installation.log
COPY _artifacts/tentacle "${INSTALLATION_FOLDER}"
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 the only way I've found that works with COPY and Windows paths that contain spaces, i.e. with an ARG. Open to suggestions.

@veochen-octopus veochen-octopus marked this pull request as ready for review October 20, 2022 04:03
@tothegills
Copy link
Contributor

It'd be worth creating an Octopus Server branch, updating the Tentacle version and running the Octopus Server test suite.

Copy link
Contributor

@tothegills tothegills left a comment

Choose a reason for hiding this comment

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

Great work, way to move this forward.
I think there are some installer pre-reqs that need updating.
I think Fixes should be a public issue in this repository.
It would be great to have a green Octopus Server build with these changes integrated.


<PropertyRef Id="NETFRAMEWORK45" />
<PropertyRef Id="NETFRAMEWORK40FULLINSTALLROOTDIR" />
<Condition Message="This application requires Microsoft .NET Framework 4.5 Runtime in order to run. Please install the .NET Framework and then run this installer again."><![CDATA[Installed OR NETFRAMEWORK45]]></Condition>
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this message about .NET framework 4.5 is still true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 I think this was auto generated. Let me see where it got this information from.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can I please get some help on this? Don't want to dump too much time into learning Wix (can do that later). But from what I can see from the manual, there's no good replacement for NETFRAMEWORK45 for net48. This is wix v3. Not sure about v4.

Also found a snippet in their source code that has both similar and very different settings. A little confused...

@@ -91,8 +91,9 @@ public void ComplexTypeGetsHandledCorrectly()
var store = new InMemoryKeyValueStore(mapper);

var settings = store.TryGet<TestConfig[]>("Test");
settings.value.Single().SettingA.Should().Be("some value", "strings should get parsed");
settings.value.Single().SomethingElse.Should().Be(12, "ints should get parsed");
settings.value.Should().NotBeNull();
Copy link
Contributor

Choose a reason for hiding this comment

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

The null check is an important assertion

@@ -38,34 +38,40 @@ public string CheckServerCommunicationsIsOpen(Uri serverAddress, IWebProxy? prox

Retry("Checking that server communications are open", () =>
{
#pragma warning disable DE0003
// TODO see if can deal with SYSLIB0014
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this TODO still to do? What are the plans for doing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removing this TODO. Fix would be to properly inject an HttpClient (or the factory) and go async from there. Treating it as out of scope for now, as it might not be a local change. But important to address later on. Ideally make tentacle more async overall.

@@ -186,7 +186,7 @@ static bool HasPrivateKey(X509Certificate2 certificate2)
{
try
{
return certificate2.HasPrivateKey && certificate2.PrivateKey != null;
return certificate2.GetRSAPrivateKey() != null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this TODO need action?

@@ -9,13 +9,13 @@ public static class AssemblyExtensions
public static string GetFileVersion(this Assembly assembly)
{
var fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.FullLocalPath());
return fileVersionInfo.FileVersion;
return fileVersionInfo.FileVersion ?? "";
Copy link
Contributor

Choose a reason for hiding this comment

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

Is "" a good backup value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question. We could return "0.0.0". It would be more friendly to the semantic version parser. But it would also hide the fact that there is no version. Thinking about the responsibility of this method, should it know what a good default is? Maybe we should simply return a string? and let the consumer decide what they want to use as the default. For example

// SemanticVersionInfo.cs
SemanticVersion = SemanticVersion.Parse(assembly.GetInformationalVersion() ?? "0.0.0");

// OctopusTentacle.cs
public static readonly string InformationalVersion = AssemblyExtensions.GetInformationalVersion(Assembly) ?? "Unknown";

@veochen-octopus
Copy link
Contributor Author

veochen-octopus commented Oct 27, 2022

Main changes

  • Updated AssemblyExtensions.GetInformationalVersion to return a string? and force the consumer to provide a default, i.e. assembly.GetInformationalVersion() ?? "0.0.0"
  • Updated Product.wxs to require net48. (Couldn't merge your PR Shane so I've copied your change)
  • Enabled Ubuntu 22.04 test and added libssl3 to the deb dependencies so that the test is passing
  • Renamed new Teamcity build to Octopus Tentacle 2022 and updated build ids.
    • Need to make sure the build number is valid before switching to the new build

Green build on the server referencing this tentacle build

Remaining discussion points

  • Is this a major or minor version?
  • There was something else 🤔

Future work

  • Lots of obsolete warnings/errors from the upgrade. Most are suppressed for now. Need to properly address.
  • Related to ☝️ might want to make Tentacle more async.

@@ -85,8 +85,7 @@ void RunLinuxPackageTestsFor(TestConfigurationOnLinuxDistribution testConfigurat
new TestConfigurationOnLinuxDistribution(NetCore, "linux-x64", "debian:oldstable-slim", "deb"),
new TestConfigurationOnLinuxDistribution(NetCore, "linux-x64", "debian:stable-slim", "deb"),
new TestConfigurationOnLinuxDistribution(NetCore, "linux-x64", "linuxmintd/mint19.3-amd64", "deb"),
// new TestConfigurationOnLinuxDistribution(NetCore, "linux-x64", "ubuntu:latest", "deb"), // 22.04 doesn't support netcore, https://github.com/dotnet/core/issues/7038
// new TestConfigurationOnLinuxDistribution(NetCore, "linux-x64", "ubuntu:rolling", "deb"), // 22.04 doesn't support netcore, https://github.com/dotnet/core/issues/7038
new TestConfigurationOnLinuxDistribution(NetCore, "linux-x64", "ubuntu:jammy", "deb"), // 22.04
Copy link
Contributor

Choose a reason for hiding this comment

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

It's helpful to test against latest and rolling because they alert us to problems that are not caught by testing the explicit versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added these back and turned them on. I assume when this starts to fail, we'll disable them again until we're ready for the next upgrade?

Copy link
Contributor

@tothegills tothegills left a comment

Choose a reason for hiding this comment

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

Looks good to me. Intending to merge this PR on November 21st.

@veochen-octopus veochen-octopus merged commit cd4af33 into main Nov 21, 2022
@veochen-octopus veochen-octopus deleted the veo/net48 branch November 21, 2022 01:00
@shortcut-integration
Copy link

This pull request has been linked to Shortcut Story #27468: Target .NET Core 6 in Tentacle.

@shortcut-integration
Copy link

This pull request has been linked to Shortcut Story #12030: Target .NET framework 4.8 in Tentacle.

veochen-octopus added a commit that referenced this pull request Dec 13, 2022
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.

Ensure support for Octopus Tentacle on Ubuntu 22.04
3 participants