dotnet / arcade

Tools that provide common build infrastructure for multiple .NET Foundation projects.
MIT License
671 stars 349 forks source link

Add .NET-based tooling to construct RPM packages #15191

Closed jkoritzinsky closed 4 weeks ago

jkoritzinsky commented 1 month ago

Introduce APIs to handle reading/writing RPMs and build an MSBuild integration for them.

Unlike the Deb tooling PR, this PR does not opt-in all repositories to the new tooling automatically. Repositories will need to set the UseArcadeRpmTooling property to true to opt-in to the new tooling.

This tooling (like the Deb tooling) is designed to have a set of APIs that can be re-used by SignTool to enable unwrapping/rewrapping RPMs.

Fixes #15143

NikolaMilosavljevic commented 4 weeks ago

I've diffed the package contents and metadata, of old and new-style of packages. Here are my findings.

Apphost package

Package contains the following directories, previously no directories were included:

/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>/runtimes/linux-x64/native
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>/runtimes/linux-x64
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>/runtimes
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64
/usr/share/dotnet/packs
/usr/share/dotnet

We likely need to include the following, which exludes the last two dirs in the list:

/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>/runtimes/linux-x64/native
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>/runtimes/linux-x64
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>/runtimes
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64/<version>
/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.linux-x64

Host package

Package contains symlink that uses a relative path:

/usr/bin/dotnet -> ../share/dotnet/dotnet

Previously this was an absolute path:

/usr/bin/dotnet -> /usr/share/dotnet/dotnet

Runtime package

Package contains the following directories:

/usr/share/dotnet/shared
/usr/share/dotnet
/usr/share/dotnet/shared/Microsoft.NETCore.App
/usr/share/dotnet/shared/Microsoft.NETCore.App/<version>

First two should not be included. This is currently implemented with https://github.com/dotnet/runtime/blob/251ef76584bd6568439b5cbb3eb19bd13e42b93e/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.props#L66

Runtime-deps package

Package dependencies are listed as follows:

rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(FileDigests) <= 4.6.0-1
libicu >=
krb5-libs >=

Previously, this was the dependency list:

krb5-libs
libicu
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1

Dependency without versions should not include >=

Targeting-pack package

Package contains the following directories:

/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/<version>/ref/net10.0
/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/<version>/ref
/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/<version>/analyzers
/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/<version>/data
/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/<version>
/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref
/usr/share/dotnet/packs
/usr/share/dotnet

Last two dirs should not be included in this package.

Metadata differences

Source RPM value is empty for all of the packages:

Source RPM  : (none)

In old packages, this has a value, like the following:

Source RPM  : dotnet-runtime-10.0-10.0.0-0.1.alpha.1.24531.2.src.rpm
jkoritzinsky commented 4 weeks ago

Thanks for doing an extensive diff!

I'll add an API to explicitly specify owned directories so we can get the correct behavior.

I'll investigate the dependency differences and figure out the right flags for versionless dependencies.

I intentionally didn't add the source RPM metadata as we don't actually ship a package with that name to rebuild from source, so there really is no source RPM. I can add back this metadata if we want to include it anyway.

I wanted to have the symlink be relative as it works on the installed machine just as well as an absolute symlink and is easier to generate (uses the same tooling as the debian package build)

jkoritzinsky commented 4 weeks ago

Including directories is now opt-in through the RpmOwnedDirectory item, which corresponds to the directories JSON entry. All directory entries not specified as an RpmOwnedDirectory item will not be included in the RPM payload or metadata.

After we get this tooling in and start switching over to using it, I plan on providing some integration between this tooling and the SFX SDK (as that knows what directories are owned) to make this easier for the framework packs. I'll file a follow-up issue for that once this is merged in.