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

Linux Packaging #2622

Closed
RheaAyase opened this issue Feb 28, 2017 · 65 comments
Closed

Linux Packaging #2622

RheaAyase opened this issue Feb 28, 2017 · 65 comments
Labels
question Answer questions and provide assistance, not an issue with source code or documentation.
Milestone

Comments

@RheaAyase
Copy link
Member

A few things to make clear regarding packaging.

  1. What are we packaging? A single package that contains everything, or two or even three separate packages? (host, framework...)

  2. How do we call it? There are debian based packages with naming as dotnet-host, dotnet-hostfxr, dotnet-sharedframework. Now imagine dnf install or apt-get install - what would the user install when, which takes me to my next question...

  3. What are the dependencies of these packages, which would depend on which one?

  4. How do we version it? What would our packages be when it comes to versions? Using the above dotnet-host as example: dotnet-host-1.0

  5. And how can user combine versions/whatever at the same time? Say Bob has sdk 1.1 some time in the future, and wishes to be able to target framework 1.0 and 1.1. Our understanding is that Bob would have to install a package for said sdk, which as such would have only the latest framework as dependency (or not even that) and Bob would have to optionally add whatever other framework he would like to publish for.

  6. Bonus question. Where does our (packagers) responsibility start? Say we will have to fix something our-distro-specific and pushing it upstream is not good enough. Say we need the fix ASAP. We can of course build it ourselves with the fix, and we would, but what about nuget packages that do not contain this fix, if someone would be targeting their application for our distro, from some other platform? Can we be responsible for this somehow, can we get the fix in faster than with next whatever update in a few months?

Last but not least, I would like to suggest that these could be compiled into nice packaging guidelines for all the various Linux distributions out there.

cc @Fedora-dotnet @omajid @tmds @nmilosev
(I hope that I got everything covered and didn't mix my notes up, please correct me if so...)

@ellismg
Copy link
Contributor

ellismg commented Mar 1, 2017

/cc @Petermarcu @piotrpMSFT @leecow @bleroy @gkhanna79

What are we packaging? A single package that contains everything, or two or even three separate packages? (host, framework...)

Let's take a moment and step back and look at the different pieces of the product. There are three major parts:

  1. The host (also known as the muxer or dotnet). This is the native goup built from dotnet/core-setup. It contains both the host itself (dotnet) and the supporting policy libraries (installed in host/fxr). dotnet's job is to either active a run-time and launch an application against it or to active an SDK and let the SDK handle a command. The reason there are two components is due to how we service the component on Windows. On Windows trying to update a file that's in use by another program requires a reboot, so we want to put as much logic into something that we can version easily (in case there are bugs). dotnet itself is very small, it tries to find the newest version of the framework resolver (libhostfxr.so) and then call functions there. That library then needs to find the correct run-time and activate it. While you can have multiple copies of libhostfxr.so installed, the newest version wins.
  2. One or more shared frameworks. The shared frameworks live in shared/Microsoft.NETCore.App/<version>. The host will roll forward across patch versions, so if an application targets Microsoft.NETCore.App 1.0.0 and only 1.0.4 is present, it will launch against the 1.0.4 version. The SDK, as a managed application, has a dependency on a version of the shared framework, but you can have additional shared framework's installed (e.g. maybe you want to have the FTS and LTS versions installed)
  3. One or more versions of the tooling. While you can have multiple versions of the tools installed (and the muxer can load the right one based on project settings) the recommendation is to always use the newest tools (you can always target older versions of the shared framework).

How do we call it? There are debian based packages with naming as dotnet-host, dotnet-hostfxr, dotnet-sharedframework. Now imagine dnf install or apt-get install - what would the user install when, which takes me to my next question...

What are the dependencies of these packages, which would depend on which one?

How do we version it? What would our packages be when it comes to versions? Using the above dotnet-host as example: dotnet-host-1.0

We haven't really gone back and done a look across all the packages to understand how we want to name them, but given the above, this would be my straw-man (note I haven't actually talked to anyone about this, so this isn't some official guidance, it's just what I've been thinking recently.)

  • dotnet-host. This package contains both the latest dotnet executable and the newest resolver in host/fxr/<version>. When a newer version of the host or resolver comes out, this package would have its version number bumped. dnf upgrading it would remove the older versions of the resolver in host/fxr/<version>.
  • dotnet-sharedframework-1.0 ,dotnet-sharedframework-1.1, dotnet-sharedframework-2.0. These are packages that represnet a shared framework (at the major and minor level). When patches are made to the shared framework, these packages get updated. So for example, after the 1.0.5 shared framework ships, dotnet-sharedframework-1.0 is offered an update and that update would remove the 1.0.4 folder from shared/Microsoft.NETCore.App and lay down a 1.0.5 version. Existing 1.0.X applications would roll forward to this newer version. You could imagine an end user having multiple dotnet-sharedframework-X.Y packages installed (they have some applications that run on the LTS shared framework, but also some newer ones that run the newer FTS framework, or they are developing applications and want to run on a newer framework to get all the newest improvements.
  • dotnet-sdk. This is the newest version of the tooling. My understanding is the plan going forward is you'll be able to use the newest version of the tooling to target /any/ version of .NET Core. In this world, when there are tooling updates, this package version updates and when installed you get the newer version in sdk/<version>.

As far as dependencies go, I imagine that dotnet-sdk would depend on some version of dotnet-host and some dotnet-sharedframework-X.Y package (whatever package represents the shared framework the SDK was compiled for. I can image that dotnet-sharedframework-X.Y depends on the dotnet-host package as well, since if you are installing a shared framework you probabbly want the host so you can actually activate it. It's also possible at some point that you might need version > X of the host to activate some version of the framework.

And how can user combine versions/whatever at the same time? Say Bob has sdk 1.1 some time in the future, and wishes to be able to target framework 1.0 and 1.1. Our understanding is that Bob would have to install a package for said sdk, which as such would have only the latest framework as dependency (or not even that) and Bob would have to optionally add whatever other framework he would like to publish for.

In the above world, the host and tooling version in place. Shared frameworks can be installed independently at the major.minor level, but there's no packages for specific patch versions.

Bonus question. Where does our (packagers) responsibility start? Say we will have to fix something our-distro-specific and pushing it upstream is not good enough. Say we need the fix ASAP. We can of course build it ourselves with the fix, and we would, but what about nuget packages that do not contain this fix, if someone would be targeting their application for our distro, from some other platform? Can we be responsible for this somehow, can we get the fix in faster than with next whatever update in a few months?

A distro maintainer could always update whatever code ships in the shared framework, build a new copy of the shared framework and release an update. The issue above is only an issue for two cases:

  • There's a change in a component outside the shared framework (e.g. ASP.NET or some part of the CoreFX stack that does not ship as part of the shared framework).
  • Cases where folks are publishing standalone.

There aren't great solutions for either cases. Since these dependencies are pulled down from nuget.org, there's no easy way for folks to do patches without having a revision shipped. The closest workaround would be to have a custom nuget server (or local source) and tell folks to reference that (and then publish packages to that feed which have you fixes). I believe things could be ordered in a way such that your version of the package would "win".

For the first case, it's possible that the new dotnet-cache feature could help. In this case, you could publish updated versions of the files to the cache and then when publishing applications folks could say: "I know these assemblies are cached, please don't include them in my application".

Regardless, there's real engineering work to be done here. I'm interested in how distributions handle other package managers. E.g. if I'm using npm, when do I get distro maintained versions of packages and when do I get things from npm.org?

Last but not least, I would like to suggest that these could be compiled into nice packaging guidelines for all the various Linux distributions out there.

Bertrand plans to produce something, but as I said above, we don't have great guidance today, so if you can help us figure out what makes sense that would be great.

@bleroy
Copy link

bleroy commented Mar 1, 2017

Seen from the user's perspective, I would expect most developers will want to just install the latest SDK. Users who want to setup a server environment where the tooling is not required will prefer dotnet-sharedframework-*. I don't see a scenario where you'd get only the muxer, this is mostly to be a dependency for the others. This makes me think we might want to tweak those package names a bit so the most common usage is made easiest. Maybe shorten the shared frameworks to just dotnet-1.0, dotnet-1.1, etc. dotnet-sdk is nice and clear, but we might want to give it dibs to the even simpler dotnet package name. This would be nice because someone just guessing the package name would mostly get exactly what they would expect.

I was thinking the same thing about giving distro package maintainers possibilities to update through a private NuGet feed that wins over nuget.org. Looks like the right thing to do.

About npm, as far as I can tell, things are a little different. The packages include npm, node, or both. Npm is just the tooling. Node does contain the standard library, but that pretty much comes as a monolithic thing, not packages. Everything else comes from the public npm repo, or from private npm repos. Those are relatively recent, and I haven't seen signs that they are used for distro-specific patching. I'm not even sure the scenario makes much sense for Node because of the monolithic nature of the SL. If you want, I could look into other platforms that would be closer in nature to .NET. Maybe Java or Go?

Of course this will have to be settled more precisely and written down in documentation form.

@Petermarcu
Copy link
Member

Petermarcu commented Mar 1, 2017

One thing I've liked is a package convention I've seen which has "platformname" for the execution runtime, and "platformname-dev" for the development assets for that package. Is that a convention we should follow? It's very intuitive in that people ask the right questions. If someone sees a dockerfile with a -dev package in it they know its for development and they also then look for one that doesn't have -dev in it for production. This is similar to the first proposal @bleroy gave.

Java: sudo apt-get install default-jre gets the runtime sudo apt-get install default-jdk gets the sdk.

Java is the most like .NET in that it has a "shared framework". Things like go are different because you get the runtime as an output of your build. Node is somewhat similar in that you can run on a shared node install but it is different in that its not a compiled language and its completely natural to expect a compiler and most of the SDK to be available at runtime.

There is a lot of other content here that I didn't get to yet but I wanted to mention that. I'll try to read more of this tonight.

@bleroy
Copy link

bleroy commented Mar 1, 2017

Maybe:

  • dotnet -> latest runtime / shared fx
  • dotnet-major.minor -> specific runtime / shared fx
  • dotnet-sdk -> latest sdk

@Petermarcu
Copy link
Member

I personally like that pattern

@Petermarcu
Copy link
Member

Petermarcu commented Mar 1, 2017

A couple comments but I think @ellismg has really well articulated much of it.

I could see there being a challenge when installing the dotnet-sdk package (latest) brings in dotnet-1.1, then we update the sdk to have 2.0 in it and updating dotnet-sdk would remove dotnet-1.1 and install dotnet-2.0

Am I correct on that being the behavior of the package manager? Is there a way to express that a dependency should be brought in on install but not removed when the referring package changes? Based on this, there may be other ways we should think about this.

One of the other options is to couple the sdk with a specific runtime and host to deliver only whole stacks.

dotnet-sdk -> dotnet-1.1-sdk -> dotnet-1.1 ->dotnet-host-1.1 -> dotnet-versionselector

update after 2.0 ships:

dotnet-sdk -> dotnet-2.0-sdk -> dotnet-2.0 ->dotnet-host-2.0 -> dotnet-versionselector

Hopefully this would leave dotnet-1.1-sdk alone if it were there and just install dotnet-2.0-sdk and its dependencies as well.

This is where my package manager knowledge falls short so I'm definitely looking for insight from others :)

My goal is that updating the SDK wouldn't remove a runtime that apps on the machine may be depending on.

@omajid
Copy link
Member

omajid commented Mar 1, 2017

Hey everyone. Thanks for the great input and thoughts.

@ellismg said:

It's also possible at some point that you might need version > X of the host to activate some version of the framework.

Would it be fair to say that users will want:

  1. Latest version of dotnet-host (or equivalent)
  2. Latest version of dotnet-sdk (or equivalent)
  3. Multiple versions of dotnet-sharedfamework (or equivalent)

Is this combination is working for 1.0 and 1.1? Is it expected to continue working for 2.0 and foreseeable future?

If multiple installations of host are supported, is the dotnet binary shared and only hostfxr.so provided by different packages?

I'm interested in how distributions handle other package managers. E.g. if I'm using npm, when do I get distro maintained versions of packages and when do I get things from npm.org?

I can describe how some distributions handle what Maven does. Maven is a build tool for Java that does a bunch of things, but I am only going to talk about the pieces that are analogous to dotnet restore.

Fedora ships with a maven version that pretty much behaves like upstream. So if a user uses mvn (think dotnet restore), maven will go out to Maven Central (think nuget.org) and download the packages exactly like how any other upstream build of maven will do it. That means a user using mvn will not run into any surprises if they have used mvn anywhere else.

Fedora also ships with a variant of maven called mvn-local that ignores packages from Maven Central. Fedora uses that for creating distribution packages for maven. mvn-local obeys distribution policies: it does not check Maven Central for packages, it only looks for packages currently installed on disk and uses significantly relaxed version constraints to find matching packages.

We might want to do something similar: the default mode of dotnet restore will do what it does on any platform but a custom variant might use some other command to find only the distro-available dependencies.

@Petermarcu said:

One thing I've liked is a package convention I've seen which has "platformname" for the execution runtime, and "platformname-dev" for the development assets for that package. Is that a convention we should follow?

Just an FYI, some distributions use -dev, others use -devel here. Most often, these are used for C/C++ packages, where -dev (or -devel) contains the headers and unversioned shared object.

I like the dotnet-1.0 and dotnet-sdk idea. I also prefer -runtime over -sharedframework, but we should pick a name that will make .NET Core internally consistent. If .NET Core only ever refers to "Shared Framework" then calling the distro package something different might be confusing.

A dotnet package which is equivalent to the latest dotnet-x.y might need some considering. Python, for example, suggest #!/usr/bin/python to invoke python2, not python3. What are our API compat goals?

I could see there being a challenge when installing the dotnet-sdk package (latest) brings in dotnet-1.1, then we update the sdk to have 2.0 in it and updating dotnet-sdk would remove dotnet-1.1 and install dotnet-2.0.

Am I correct on that being the behavior of the package manager?

Most package managers are not that smart. In fact, I don't think anything is ever removed automatically. Both Debian and Fedora remove automatically installed packages on explicit uninstall.

@Petermarcu
Copy link
Member

Good input. Sounds like "-sdk" is the way to go for the name. Sounds like we also don't need "-runtime" because thats what "dotnet" is when it doesn't have "-sdk".

  1. Latest version of dotnet-host (or equivalent)
  2. Latest version of dotnet-sdk (or equivalent)
  3. Multiple versions of dotnet-sharedfamework (or equivalent)

dotnet/core-setup#1 and dotnet/core-setup#2 are correct.

For dotnet/core-setup#3 it's unclear to me if over time users will want to be able to get multiple copies of "-sdk". That would depend on the SDK always being backwards compatible. If it ever broke, the fix would be to explicitly install some version of the "-sdk" package. To me, that says that dotnet-sdk needs to have a version option as well like dotnet-1.0-sdk.

@leecow
Copy link
Member

leecow commented Mar 1, 2017

To touch on a question in Matt's original post, the current Ubuntu debs are authored to resolve and download dependencies at install time. eg apt-get install dotnet-dev-1.0.0-preview2.1-003177 also downloads and installs the defined dotnet-host, dotnet-hostfxr, dotnet-sharedframework and dotnet-sdk (in that order) packages.

I would want to be very careful about automatically removing past versions.

@gkhanna79
Copy link
Member

When a newer version of the host or resolver comes out, this package would have its version number bumped.

@ellismg Does this mean the new package will be dotnet-host-1.0.1?

dotnet-sharedframework-1.0 is offered an update and that update would remove the 1.0.4 folder from shared/Microsoft.NETCore.App and lay down a 1.0.5 version

How would the user revert back to 1.0.4 if they ran into issues with 1.0.5?

I can image that dotnet-sharedframework-X.Y depends on the dotnet-host package as well

Correct.

This makes me think we might want to tweak those package names a bit so the most common usage is made easiest

I think we want to have the packages be componentized and something like dotnet-1.0 is what would be equivalent to the Windows bundle we generate (whether, on RHEL, it is a bundle or triggers the chain is an implementation detail). dotnet-sharedframework-* is still worth having in its own right.

then we update the sdk to have 2.0 in it and updating dotnet-sdk would remove dotnet-1.1 and install dotnet-2.0

Is the convention for things like dotnet-sdk to be the version distro maintainer are chosen to be default or is it intended to be latest? I ask this because what I have seen (e.g. with lldb) is that packages like lldb seem to be distro blessed versions and to pull down the specific package you need to call it out (e.g. lldb-3.8). Thus, if maintainer chooses to update the defaults (from 2.0 to 2.1), then uninstalling the older version maybe fine - though uninstalling across versions (2.0 uninstalling 1.1) does not sound right.

@ellismg
Copy link
Contributor

ellismg commented Mar 2, 2017

When a newer version of the host or resolver comes out, this package would have its version number bumped.

@ellismg Does this mean the new package will be dotnet-host-1.0.1?

There are two components to the package. The name of the package (in my proposal, that's dotnet-host) and the version. I'd advocate just bumping the version. That means anyone who does a dnf update and has dotnet-host installed would get the newer version.

This is in contrast to how I would say we should handle the shared framework. In that world we bake the major and minor number into the package name and bump the version of the RPM when patch releases come out. When a new major or minor version of the SF is released, packagers produce a new package (with a 1.0.0 version).

How would the user revert back to 1.0.4 if they ran into issues with 1.0.5?

The same way they revert to an older version of any software that their package maintainer updates if there are issues. Sometimes the rpm's are archived and there's tooling to downgrade a package, sometimes you may need to build it yourself (from the source RPM).

Is the convention for things like dotnet-sdk to be the version distro maintainer are chosen to be default or is it intended to be latest? I ask this because what I have seen (e.g. with lldb) is that packages like lldb seem to be distro blessed versions and to pull down the specific package you need to call it out (e.g. lldb-3.8). Thus, if maintainer chooses to update the defaults (from 2.0 to 2.1), then uninstalling the older version maybe fine - though uninstalling across versions (2.0 uninstalling 1.1) does not sound right.

My view on the situation (and I'm sure I'll be corrected by folks more in the know like @omajid) is that packages which need to be installable side by side bake version numbers into their package names. python vs python3 is a representative example here. clang and friends sometimes do this because certain ABIs are not stable across versions and so it's reasonable to have multiple installed.

If we think it makes sense to have the ability to install SDKs side by side, then we probably want to include part of the version in the package identity. If we don't expect that's something we want to support (easily) because we believe the move to latest story is what we want everyone doing, then we should not include version information in the package name.

@omajid
Copy link
Member

omajid commented Mar 2, 2017

Matt's entirely correct. A few points that I thought might be worth clarifying.

A (distro) package is generally identified by two components: name and version. The version in turn often consists of two components: the upstream version and the distribution version. As an example for python on my system, the name is python, the upstream version is 2.7.13 and the distro version is 1.fc25 (Ubuntu might do it as 2ubuntu1). The upstream version is the version that the upstream release corresponds to. The distro version is essentially how many times a distro has built/patched the upstream version.

When it comes time to upgrade packages, the package manager looks at names to find "same" packages and versions to determine if it's an upgrade. For example, if it sees I have python-2.7.13-1.fc25 installed and it sees there's a package named python-2.7.13-2.fc25 available, it uses the name to identify that they are both the same package. It then compares the versions to identify that the new package is an upgrade for the old package. When asked to perform the upgrade, the package manager removes the old version and installs the new version. It's a bit more complicated than that to ensure that a no point there are missing files, but conceptually a removal followed by an install is what happens.

So if we call two packages as foo, it tells the package manager they are different versions of the same package and one should be replaced with the other on an upgrade/downgrade.

In other words, if we want to make two packages be installable side-by-side, we should give them different names. If we want to make one package be an upgrade for another, we should give them the same name.

Often implicit in this entire convention is that the package stays compatible. A bump from one version to the next should not break anything, including the user experience and the command line interaction. This isn't true for distros with rolling releases, but they announce an upcoming break in advance.

So if foo version 2 is not compatible with foo version 1, and both are being added to a distro they may get added as foo and foo2 or foo1 and foo or even foo1 and foo2. This is up to the package maintainers.

Given that we want 1.0.1 shared framework to be replaced by 1.0.2, we should call it something like dotnet-1.0-sharedframework(or dotnet-sharedframework-1.0), and give them versions of 1.0.1 and 1.0.2.

I prefer dotnet-$VERSION-$COMPONENT over dotnet-$COMPONENT-$VERSION, as that allows users to do sudo dnf install 'dotnet-1.0*' or sudo apt install 'dotnet-1.0*' to install all components for dotnet-1.0.

Also, my understanding is that upgrading never removes a package. There's two notable exceptions. One, a package foo can explicitly say that it's a replacement and upgrade for bar and the package manager will remove bar and install foo to comply. Another is basically a special case for the kernel package, lets ignore that for this discussion.

@RheaAyase
Copy link
Member Author

Sorry for the somewhat late reply, I had a bunch of PTO last week and didn't get to sit down long enough to go through this.

@bleroy said:

dotnet -> latest runtime / shared fx
dotnet-major.minor -> specific runtime / shared fx
dotnet-sdk -> latest sdk

Yes that is what I was thinking about (I don't like the current naming for debian branch...)

  • Except that the dotnet-sdk might be a bit different for every distro. (As @omajid replied to @Petermarcu) I do not see this as a problem, so for example the Fedora branch would use -devel while the Debian branch would use -dev ...
  • And to add to the above, dotnet-host which would be dependency for both. (Or rather for the framework where the sdk would depend on the framework anyway...)

@omajid said:

Also, my understanding is that upgrading never removes a package. There's two notable exceptions. One, a package foo can explicitly say that it's a replacement and upgrade for bar and the package manager will remove bar and install foo to comply. Another is basically a special case for the kernel package, lets ignore that for this discussion.

Not even if its dependency no longer exists? I thought that it would remove said dependency.


So to sum the whole discussion up and what we could agree on I hope. Please correct me if I mixed something up =)

Packages:

  • dotnet-host - Refer to @ellismg's comment. [No relevant dotnet dependency]
  • dotnet - Always the latest dotnet shared framework; i.e. update would even roll over minor and major versions. This is to better allow updating of the dotnet-sdk... [Depends on dotnet-host]
  • dotnet-major.minor - Specific shared framework that would not update its major/minor versions. This includes the upstream version baked into the name. [Depends on dotnet-host]
  • dotnet-sdk where the sdk can be substitued by devel or dev - whatever is the distributions convention. [Depends on dotnet]

This scenario has one right now relevant problem. Someone may want to stick with project.json for a while longer, but as soon as they run update their sdk will roll over to the csproj tooling and they are screwed... I think that this is a breaking change we all have to get over and it will be fine =)
If someone would strongly insist on having multiple versions of the sdk, then it would have to be handled the same as the framework. (Whether dotnet-version-sdk or dotnet-sdk-version should be up to the maintainer / distro conventions, same as dev/devel)

(Note that the above update refers to package manager update command, such as apt-get update or dnf update)


Lets please iterate on the above suggested conventions and lets come up with something that could be considered guidelines so we don't have complete chaos between different Linux distributions... Can anyone summon other people involved in packaging for other distros?

@omajid
Copy link
Member

omajid commented Mar 15, 2017

Not even if its dependency no longer exists? I thought that it would remove said dependency.

The case that I am referring to is the following:

  • foo, version 1 depends on bar
  • foo, version 2 depends on baz

In this case the dependency on bar does not exist when foo, 2 is installed. Upgrading from foo, 1 to foo, 2 does not remove bar. Both Fedora and Debian have explicit steps to make a package (baz here) replace another by uninstalling that other package (bar here).

I just tried this out. I created 3 packages:

  • foo
  • bar
  • baz

foo requires bar. Build and install foo and bar:

$ sudo dnf install ./RPMS/x86_64/foo-1-1.fc25.x86_64.rpm ./RPMS/x86_64/bar-1-1.fc25.x86_64.rpm 
Last metadata expiration check: 1:07:49 ago on Wed Mar 15 17:12:09 2017.
Dependencies resolved.
==============================================================================================================================================================================================================================================
 Package                                              Arch                                                    Version                                                     Repository                                                     Size
==============================================================================================================================================================================================================================================
Installing:
 bar                                                  x86_64                                                  1-1.fc25                                                    @commandline                                                  6.0 k
 foo                                                  x86_64                                                  1-1.fc25                                                    @commandline                                                  6.0 k

Transaction Summary
==============================================================================================================================================================================================================================================
Install  2 Packages

Then version bump foo to 2, and make it require baz instead of bar. Then try and install that:

$ sudo dnf install ./RPMS/x86_64/foo-2-1.fc25.x86_64.rpm ./RPMS/x86_64/baz-1-1.fc25.x86_64.rpm                                                                                                                         
Last metadata expiration check: 1:08:16 ago on Wed Mar 15 17:12:09 2017.
Dependencies resolved.
==============================================================================================================================================================================================================================================
 Package                                              Arch                                                    Version                                                     Repository                                                     Size
==============================================================================================================================================================================================================================================
Installing:
 baz                                                  x86_64                                                  1-1.fc25                                                    @commandline                                                  6.0 k
Upgrading:
 foo                                                  x86_64                                                  2-1.fc25                                                    @commandline                                                  6.0 k

Transaction Summary
==============================================================================================================================================================================================================================================
Install  1 Package
Upgrade  1 Package

And to confirm, the package manager knows nothing requires bar:

$ rpm -q --whatrequires bar
no package requires bar

@omajid
Copy link
Member

omajid commented Mar 15, 2017

dotnet-sdk where the sdk can be substitued by devel or dev - whatever is the distributions convention. [Depends on dotnet]

I would prefer if the .NET Core project made a recommendation (of course, distros can ignore it if they want). I personally prefer sdk, over -dev/-devel since that's what https://www.microsoft.com/net/download/core calls it. Is there another name for it used here on github or on microsoft.com?

@bleroy
Copy link

bleroy commented Mar 15, 2017

Yes, sdk would be preferable as far as we're concerned. Let's go for that.

@RheaAyase
Copy link
Member Author

Updated to reflect your preferences, I'm also inclined to it, was just wondering how strong are the dev/devel conventions... Do we have anything else to add to this, or can we write it up somewhere in a better .md file perhaps, as guidelines?


Packages:

  • dotnet-host - Refer to @ellismg's comment. [No relevant dotnet dependency]
  • dotnet - Always the latest dotnet shared framework; i.e. update would even roll over minor and major versions. This is to better allow updating of the dotnet-sdk... [Depends on dotnet-host]
  • dotnet-major.minor - Specific shared framework that would not update its major/minor versions. This includes the upstream version baked into the name. [Depends on dotnet-host]
  • dotnet-sdk - Always the latest sdk. [Depends on dotnet]

@fsateler
Copy link

fsateler commented Mar 16, 2017

Not even if its dependency no longer exists? I thought that it would remove said dependency.

The case that I am referring to is the following:

-foo, version 1 depends on bar
-foo, version 2 depends on baz

In this case the dependency on bar does not exist when foo, 2 is installed. Upgrading from foo, 1 to foo, 2 does not remove bar. Both Fedora and Debian have explicit steps to make a package (baz here) replace another by uninstalling that other package (bar here).

On debian and derived distros, this is true, but only if you use apt-get. If you use apt or aptitude, automatically installed packages will be removed if nothing else depends on them. This can be easily worked around by creating a virtual package dotnet-runtime, that all dotnet-major.minor packages Provide. dotnet could then Recommend this virtual package, which would cause apt to consider the package still needed. Mutatis mutandis the same for the -sdk variants if it is so desired.

@gegenschall
Copy link

Hey everyone,

I'm currently maintaining .NET Core on Arch Linux (as AUR packages) and want to chime in on this discussion. Thanks @omajid for notifying me about it.

First of all: Arch Linux is not an officially supported distribution by .NET Core, so I (and the maintainers before me) had to jump through some hoops to get it running. Specifically I haven't been able to build .NET Core from source because of the bootstrapping mechanism, but that's an entirely different topic. Currently the packages build the native components from source and replace the corresponding files from an official Ubuntu 16.04 build. (ugh...)

There are 4 packages that I maintain:

Package Purpose Current Version Dependencies
dotnet-sdk Contains the latest sdk 1.0.1-1 dotnet, dotnet-cli
dotnet Contains the latest shared framework 1.1.1-1
dotnet-lts Contains the latest LTS shared framework 1.0.4-1
dotnet-cli dotnet binary and libhostfxr 1:1.1.1-1 dotnet

Notes:

  • Both dotnet and dotnet-lts provide the dotnet feature
  • dotnet-cli depends on dotnet, meaning that dotnet or dotnet-lts will satisfy this dependency
  • I dislike the name dotnet-cli and would have chosen something else, but the package was already in the AUR when I took over as a maintainer.

As far as I can see, this pretty much corresponds to what @RheaAyase wrote with the exception of dependencies which I'll adapt accordingly.

@bleroy
Copy link

bleroy commented Mar 20, 2017

Thanks all, this is very useful. We'll certainly add documentation with recommendations on package naming based on your input.

@gegenschall can you give more details about some scenarios where someone would install dotnet-cli and not dotnet-sdk? I understand you said this is something you inherited, but is there a compelling reason to keep it around?

@RheaAyase
Copy link
Member Author

@gegenschall:
Yep your scheme is close enough to the idea, with a small difference - that we would prefer dotnet.major.minor instead of dotnet-lts because... which lts? :p

@gegenschall
Copy link

@bleroy If you were to deploy a server you wouldn't need the SDK, right? But this is a case you most likely wouldn't do with Arch + .NET Core as its officially unsupported, you're right.
Apart from that I guess I would annoy several people if I remove or rename dotnet-cli...

@RheaAyase You are absolutely right! I'll upload dotnet-major.minor packages, point dotnet to the latest, and ask for a deletion of dotnet-lts.

@bleroy
Copy link

bleroy commented Mar 21, 2017

@gegenschall if you deploy to a server, you should only need the shared framework release, no?

@RheaAyase
Copy link
Member Author

@bleroy that should depend on the host because that is what decides which version of framework to use for said application you want to run. You can have as many versions of framework as you wish.

@bleroy
Copy link

bleroy commented Mar 21, 2017

oooh, no, ok, sorry, so @gegenschall's dotnet-cli is just our dotnet-host... That was actually clearly stated...

@bleroy
Copy link

bleroy commented Apr 5, 2017

@tmds
Copy link
Member

tmds commented Apr 6, 2017

@bleroy Looks great.

dotnet is a latest runtime package? Since apps need a specific major.minor to work, I don't get why this package is useful. Can it be removed? Does that make sense?

@Petermarcu
Copy link
Member

@rakeshsinghranchi @vivmishra to make sure they see this and follow along on the proposed changes.

@RheaAyase
Copy link
Member Author

@tmds we've discussed this for a month, I don't see why would we not have the dotnet package with latest version. That should be the default thing when someone installs sdk, framework, etc. If they want specific version, there are specific versions.

@RheaAyase
Copy link
Member Author

Also @bleroy this document does not reflect what was discussed here at all.

@tmds
Copy link
Member

tmds commented Apr 8, 2017

ut what if the dotnet package was itself an empty package that just references the latest dotnet-major.minor? Updating would get the new latest, but wouldn't remove the old one, and this way we can be both side-by-side and have a simple way to get the latest. Wouldn't that work?

That would work, but it is not adding anything useful. Apps require a specific dotnet version. The sdk meta package points to a specific sdk. The specific sdk points to specific dotnet version. So, it's not useful as a dependency.

As part of an update, you want to get the fixes for the versions you have installed (patch update). Updating to the latest (major/minor update), installs a version of dotnet you are not using.

@bleroy
Copy link

bleroy commented Apr 9, 2017

Yes, apps require a specific version, but that's just one scenario. There is value in being able to install "dotnet", and having updates that add the latest to the system. I agree it's not useful as a dependency, but it's useful by itself. I'm fine with making it optional, however.

@tmds
Copy link
Member

tmds commented Apr 9, 2017

it's useful by itself

How did you reach that conclusion? I miss the rationale for the package when reading this thread.

@bleroy
Copy link

bleroy commented Apr 9, 2017

"There is value in being able to install "dotnet", and having updates that add the latest to the system". Makes it easier to maintain a runtime environment in a back compat way. "dotnet" without version number is also more discoverable.
But, again, if you're unconvinced, and would rather not ship a dotnet package, I can move that one to be optional.

@RheaAyase
Copy link
Member Author

My opinion from my two points of view:

As a user I see no reason to have always the latest major.minor on my server. When I update my server-side application's code, to use newer version, then I'll also manually update the framework - always keeping but one installed to save HDD space for economical reasons (I don't have freebie Azure VM)

As a developer I would like my SDK to be the latest, and my framework to be -all of them- because I will probably work with more than one at a time with different projects.

Based on these two points of view, I see no point in having the dotnet package, however, the -sdk that will add new frameworks (without removing anything) would be nice.

@bleroy
Copy link

bleroy commented Apr 10, 2017

Yes, those are two important scenarios.

There's also the scenario where as a hoster, I want to keep my servers ready to welcome apps written for all versions of .NET Core. This can be achieved in two ways: I can manually install versioned shared frameworks as they come out, or I can install dotnet once and update it to get new versions side by side.

Another is the one where as a a new user, I can easily discover the dotnet and dotnet-sdk packages and start experimenting.

I do agree however that dotnet is the least necessary of all these packages, and could be made optional. I'll go ahead and make that change in the recommendations.

@tmds
Copy link
Member

tmds commented Apr 10, 2017

I like the idea of a dotnet package as a user-experience but it doesn't work well:

  • If a user wants to do development, he should install the dotnet-sdk package.
  • If a user wants to run an app, he should install the specific dotnet-x.y the app requires.

Now, what if we rename the dotnet-host package to dotnet?
When installed, the user gets the dotnet executable which can tell him many interesting things like:

  • there is no sdk installed -> install 'dotnet-sdk' to get the latest
  • your app needs runtime x.y, -> please install 'dotnet-x.y'
  • your app needs sdk x.y -> please install 'dotnet-sdk-x.y'

Thoughts?

@bleroy
Copy link

bleroy commented Apr 10, 2017

That's an interesting idea, especially as the host consists of a "dotnet" executable, but the host remains pretty useless on its own, which is why the package so far has been considered as a dependency only, not as a standalone thing.

It also comes with strong constraints on how much it can do without an SDK, and what help messages we can put in there (and how they can be localized). We also can't make assumptions about the name of the dotnet-sdk package, since those are only recommendations, or even the acquisition mechanism, so we'd have to adopt language that is more vague and as such less useful than what you suggest.

If the new user experience is what we want to aim dotnet at, then making it a synonym of dotnet-sdk would probably be more useful than pointing it to the host. Another issue with aliasing it to either SDK or host however is that there's a symmetry between versioned and unversioned SDK packages that would be lost between the dotnet and dotnet-major.minor packages, which would cause confusion.

In the end, we seem to be stuck between the idea of having a dotnet package at all, and the possibility to make it useful. At this point, you've convinced me that it would actually be better to not have it at all, since I don't see what experience we could put behind it that would match any reasonable expectations.

@RheaAyase
Copy link
Member Author

There's also the scenario where as a hoster, I want to keep my servers ready to welcome apps written for all versions of .NET Core. This can be achieved in two ways: I can manually install versioned shared frameworks as they come out, or I can install dotnet once and update it to get new versions side by side.

True, I haven't thought of that, however in that case they could just install the sdk which will effectively do the same thing. The only in-production actual use of this that comes to my mind is an university, where every student has an account on some powerful server to run their heavy calculations or projects, etc... They won't cry for the extra 100MBs from having an sdk instead of just the framework...

If the new user experience is what we want to aim dotnet at, then making it a synonym of dotnet-sdk would probably be more useful than pointing it to the host.

I think so, and I would be inclined to this solution, if we are to have some dotnet package...


Can I assume then, that these are our current go-to names or is there anything else?

  • dotnet-host - Always the latest host [No relevant dotnet dependency]
  • dotnet-major.minor: A shared framework with the specified version (only the latest patch version for a given major+minor combination should be available in the package manager). [Depends on dotnet-host]
  • dotnet-sdk-major.minor: An SDK with the specified version, where the version specified is a version of the dependent framework. [Depends on dotnet-major.minor]
  • dotnet-sdk: The latest major.minor SDK. [Depends on dotnet-sdk-major.minor]

@bleroy
Copy link

bleroy commented Apr 10, 2017

Yes.

I'll remove the dotnet package from the doc entirely then.

@RheaAyase
Copy link
Member Author

//bump

Is this published already?

@bleroy
Copy link

bleroy commented Apr 25, 2017

The PR has been submitted: dotnet/docs#2014. Publication date will depend on the doc team's schedule. I'll close this issue when that's done.

@bleroy
Copy link

bleroy commented May 9, 2017

Following the discussion that happened elsewhere on naming of .NET downloads, packages, and container images (https://github.com/dotnet/designs/issues/2), we'd like to make the following change to the package naming guidelines... Instead of just dotnet-[major].[minor], we'd like to align on other names and call it dotnet-runtime-[major].[minor]. This is also more explicit, and hopefully can steer more people to the package they need. This would be the only change on our end. @richlander will also make changes on his end to bring more consistency with this effort in naming of other files.

@RheaAyase
Copy link
Member Author

RheaAyase commented May 9, 2017

Fine by me.


  • dotnet-host - Always the latest host [No relevant dotnet dependency]
  • dotnet-runtime-major.minor: A shared framework with the specified version (only the latest patch version for a given major+minor combination should be available in the package manager). [Depends on dotnet-host]
  • dotnet-sdk-major.minor: An SDK with the specified version, where the version specified is a version of the dependent framework. [Depends on dotnet-runtime-major.minor]
  • dotnet-sdk: The latest major.minor SDK. [Depends on dotnet-sdk-major.minor]

@colltoaction
Copy link
Contributor

  • From my .NET Core and Linux user perspective I'd appreciate if the dotnet package provided the dotnet command
  • If I were a new user trying out .NET Core it'd be discouraging if I couldn't install just dotnet, but instead have to dig through the packages and try to understand what host, sdk or runtime mean

Then, maybe we can change dotnet-sdk to dotnet to get a really good first-time experience, where you install one package and get a full development environment. Experienced people will investigate what other options they have.

@RheaAyase
Copy link
Member Author

RheaAyase commented May 11, 2017

If you were a new user trying out .net then you would be directed by everyone to dnf/apt-get/whatever install dotnet-sdk instead of dotnet which is the SDK that you as a new user trying it out are looking for and should know and understand the difference. Similarly you are installing python-dev(el) etc, and not just python...
(Python is probably a bad example here but... you get the point, it's always dev(el)... another kinda related example would be mono)

@oscarvarto
Copy link

Any updates for availability on Arch Linux based distros?

@omajid
Copy link
Member

omajid commented Aug 11, 2017

The generic linux-x64 binary for 2.0 (preview) should work on arch. Can you try that? We are also working to make it easier to build .NET Core form source. We have a Fedora package here that you could try to adapt and build on arch too: https://pagure.io/fedora-dotnet/tree/f26

@gegenschall
Copy link

I'm sorry, I never reported back. My apologies!

Arch packages are using the recommended naming scheme since about 2.0.0-preview1. They are available here:
dotnet - "Meta package", depends on dotnet-runtime-2.0
dotnet-host
dotnet-runtime-2.0
dotnet-sdk-2.0
dotnet-runtime-1.1
dotnet-sdk-1.1

One minor nitpick:
Version for the {runtime,sdk}-2.0 packages was something along the lines of 2.0.0_preview2_00xxxx-00 which is not recognized to be older than 2.0.0. I had to use the epoch keyword to force it being newer than the preview packages.

@omajid
Copy link
Member

omajid commented Aug 16, 2017

Version for the {runtime,sdk}-2.0 packages was something along the lines of 2.0.0_preview2_00xxxx-00 which is not recognized to be older than 2.0.0. I had to use the epoch keyword to force it being newer than the preview packages.

Not sure how Arch normally does it, but on Fedora-land we have to make pre-release packages have a 0 "fedora release version" just to handle cases like this.

Our Preview 2 packages are versioned as 2.0.0-0.3.preview2 right now so we can move to 2.0.0-1 later.

@omajid
Copy link
Member

omajid commented Oct 20, 2017

I just found out about https://github.com/dotnet/cli/issues/4014 which also touched on this.

@tmds
Copy link
Member

tmds commented Mar 29, 2018

@RheaAyase can we close this with the recent update to the packaging doc? https://docs.microsoft.com/en-us/dotnet/core/build/distribution-packaging

@brad-jones
Copy link

Sorry to dig up an old issue but I am struggling to see how one can install multiple versions through a package manager such as dnf on Fedora.

Yes I have read and re-read: https://docs.microsoft.com/en-us/dotnet/core/build/distribution-packaging

My understanding is that I should be to install several specific versions of the SDK & Runtime side-by-side.

Eg:

dnf install dotnet-sdk-2.1.302
dnf install dotnet-sdk-2.1.402

However at least for the Fedora repo, it would seem builds have stopped being published in this way.

$ dnf --showduplicates list dotnet-sdk*
Last metadata expiration check: 1:14:07 ago on Thu 13 Sep 2018 14:31:03 AEST.
Available Packages
dotnet-sdk-2.1.x86_64                   2.1.300-1               packages-microsoft-com-prod
dotnet-sdk-2.1.x86_64                   2.1.301-1               packages-microsoft-com-prod
dotnet-sdk-2.1.x86_64                   2.1.302-1               packages-microsoft-com-prod
dotnet-sdk-2.1.x86_64                   2.1.400-1               packages-microsoft-com-prod
dotnet-sdk-2.1.x86_64                   2.1.401-1               packages-microsoft-com-prod
dotnet-sdk-2.1.x86_64                   2.1.402-1               packages-microsoft-com-prod
dotnet-sdk-2.1.200.x86_64               2.1.200-1               packages-microsoft-com-prod
dotnet-sdk-2.1.201.x86_64               2.1.201-1               packages-microsoft-com-prod
dotnet-sdk-2.1.202.x86_64               2.1.202-1               packages-microsoft-com-prod
dotnet-sdk-2.1.300-rc1-008673.x86_64    2.1.300_rc1_008673-1    packages-microsoft-com-prod

Sure I can install a specific version like this dnf install dotnet-sdk-2.1-2.1.302-1 but then come along later and dnf install dotnet-sdk-2.1-2.1.402-1 now 302 has been uninstalled.

Am I missing something obvious? Or is this just not possible?

@RheaAyase
Copy link
Member Author

@brad-jones You should always use software packaged by the contributors to the Linux distribution in question, not by 3rd party or upstream ;)

Our packages may contain Fedora specific tweaks and fixes, and you can most certainly install them side by side.

rjanek@RedHat:~/dev/qe$ dotnet --info
<snip>
.NET Core SDKs installed:
  2.1.302 [/usr/lib64/dotnet/sdk]
  2.1.401 [/usr/lib64/dotnet/sdk]

@brad-jones
Copy link

@RheaAyase thanks for the tip about the copr repo, I am up and running again.

I guess my next question is, then why isn't the copr repo used in the official dotnet core installation instructions at https://www.microsoft.com/net/download/linux-package-manager/fedora28/sdk-2.1.402

@RheaAyase
Copy link
Member Author

@brad-jones that is a good question ;p

It is something that I suggested many times without any answer at all. Maybe it will change finally, given the recent developments...

@msftgits msftgits transferred this issue from dotnet/core-setup Jan 30, 2020
@msftgits msftgits added this to the Future milestone Jan 30, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests