Requesting automatic alias for dotnet

Hey folks,

Have been working with Sergio &c at the rally in NYC to snap .NET Core. There is an SDK and Runtime piece which are invoked using the same command ‘dotnet’ followed by appropriate verbs and options.

alias dotnet-sdk dotnet
alias dotnet-runtime dotnet

dotnet is the ‘host’ (aka muxer) and has two distinct roles: activate a runtime to launch an application, and activate an SDK to dispatch commands to it. The host is a native executable and its supporting policy libraries (installed in host/fxr). There is typically only one host on a given machine, although that isn’t a strict requirement.

if both uses are backing onto the same command, dotnet, then why not create your snap as dotnet and expose that command as dotnet rather than having a dotnet-sdk and a dotnet-runtime both aliased to the name dotnet?

These are the user stories behind this decision:

  • I am an application developer using the dotnet SDK to create apps locally on my computer/CI, hence I will install the SDK to do so.
  • I am a user of a compiled application, so I will install the dotnet runtime to execute my application.
  • I am an application developer creating a snap of my application, choosing to embed the runtime, the dotnet plugin would use the dotnet-sdk snap to build and add the runtime to the snap.
  • I am an application developer creating a snap of my application, taking advange of the content interface slots entry offered by the dotnet-runtime, the dotnet plugin would use the dotnet-sdk snap to build and add the runtime to the snap.

Some clarifications, it is just like java in this case, the SDK includes the runtime so users would generally not have both installed unless they are in a development/testing iteration cycle following that last user story I exposed.

My point was that the dotnet command is part of the .NET Core SDK. There is no .NET Core Runtime as a separate entity from upstream. See https://www.microsoft.com/net/core where the only distributable is the SDK package. With .NET Core you can run or build an application with the dotnet command, but to redistribute you are likely to use dotnet publish which builds your application into a binary which executes directly, not through the dotnet run mechanism, thus you do not need dotnet available as a program in the target system, or package as a dll which requires presence of the whole .NET Core SDK and the dotnet command.

The runtime can be distributed separate from the SDK to enable a shared runtime experience for portable applications. Access to the dotnet command is needed for this scenario.

If you build and publish this type of application, there are no native execution assets included and the only way to get there is with dotnet myapp.dll. There is a self-contained model in which you define the target systems (eg linux-x64) then deploy the application along with target platform specific native dependencies and runtime assets as a unit.

Application deployment info at https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli.

dotnet is clearly associated with this project (and won’t conflict with debs/rpms exept in the expected way). It seems slightly odd that dotnet is being provided by both so on systems where both the sdk and the runtime are installed, the user needs to make a choice. While snapd will handle this fine, the user might wonder which to choose. I’m inclined to give +1 but I do wonder if there is a better way-- could dotnet-sdk use dotnet-runtime’s content interface? This way systems could have only the runtime installed, but sdk systems would have both.

That dotnet is provided by both sdk and runtime is by design and matches the construction of our other deployment constructions (deb, rpm, msi, zip, tar, …). By default, the runtime and sdk native installers install into the same product root. There are a few other directories but this should explain the layout:

/dotnet
  dotnet (this is the executable under discussion)
  /host  
  /sdk  (can have side-by-side versions)
    /2.0.0
  /shared (shared runtime libraries)
    /Microsoft.NETCore.App (can be any number of side-by-side versions with our 'regular' installs)
      /2.0.0 

The combination of the dotnet executable and host activation policy found under /host determine which runtime to utilize for a given portable application. Where all of the functional components of the install can be versioned side-by-side, dotnet is a single shared entry point.

I agree that a snap install complicates matters a bit in that runtime and sdk are installed as separate units rather than layered in the same directory. Generally, the SDK is the single entry point for developer usage where as the runtime would be used for application deployment so I think we could mitigate somewhat with documentation. Having the SDK utilize an installed Runtime via content interface is a really interesting idea but would result in the Snap offering being quite different in construction from our other acquisition artifacts.

Thanks for the additional information. Since it is clear that this is by design and reflective of what upstream is doing elsewhere, it sounds like having the current layout with alias in both snaps would be more clear for dotnet developers than not. +1

Yeah, assuming that developers will generally install the sdk and not the runtime alone, sounds fine to have the alias in both. Also, it’s easy and cheap to change our minds if we learn more about use cases and come up with something else instead.

So +1 and let’s see how it goes.

Thanks all. What are the next steps?

The auto-aliases will be enabled assuming we don’t hear any relevant complaints here before the end of the voting period which should be over soon.

2 votes for, 0 against. Granting both aliases. This is live now.

Since there is a dotnet snap and two snaps that provide the ‘dotnet’ alias, I decided to look into how snapd behaves in various situations: Process for aliases, auto-connections and tracks

"

  • if a snap is installed with an alias, then installing a snap with the name of the alias (ie snap install ) results in the snap being uninstallable until the alias is removed with snap unalias
  • if a snap is installed that has an automatic alias that matches the name of an already installed snap, then installing the snap with the alias results in the snap being uninstallable (this may be a bug, but it is safe)
  • if two snaps have an automatic alias with the same name, the second snap is not installable until the first’s alias is removed with snap unalias

"

So, in terms of these three snaps:

  1. if dotnet-runtime or dotnet-sdk are installed, dotnet is not installable until the ‘dotnet’ alias is removed
  2. if dotnet is installed, dotnet-runtime and dotnet-sdk are not installable
  3. if one of dotnet-runtime or dotnet-sdk are installed, then the other one is not installable until the first’s alias is removed

@niemeyer - there is a bug here since with ‘1’ you can install all three if you install dotnet-runtime and dotnet-sdk first (and unaliasing ‘dotnet’), but with ‘2’ you can only install dotnet. I suspect the correct behavior is if a snap declaration grants an auto-alias, we should warn but not grant the alias if it is already taken (covers ‘2’ and ‘3’). For ‘1’ we should error, instructing the user to unalias, thus making the snap with the name of the alias installable.

Maybe I am just being dense here but surely dotnet-sdk it just dotnet-runtime + some extra stuff. So why not just break it up into 2 snaps that have a dependency on dotnet-runtime? All this faffing around with alias seems unnecessarily complicated.

If you want to install dotnet-sdk it pulls in dotnet-runtime and overlays new directories for it.

If you want to install dotnet alongside a system dotnet that is another aspect completely. Then you need a single alias to separate the snap from the system anyway.

Don’t flame, just thinking out loud.

@veritanuda - that would be the preferred solution and matches how sdk/runtime installation interactions work everywhere else. This wasn’t attempted because I didn’t know it was an option so guidance on the yaml authoring would be excellent!

It would look like the content interface based snaps which leverage the dotnet-runtime snap; it would be rather similar, where the SDK would have a plugs entry as would an application snap.

Hey folks,

We’ve started encountering permissions issues where both the direct command (dotnet-sdk.dotnet ) and the automatic alias require sudo. Since both invocations are affected, it may not have anything to do with the automatic alias.

Dropping a simlink to /snap/dotnet-sdk/current/dotnet into /usr/local/bin/dotnet allows running the command as a normal user.

Any idea what’s going on?

Yes,

drwx------ 3 root root     53 Oct  7 23:54 snap

You are shipping the ./snap directory as readable only by root. Then, because your dotnet commands require ./snap/command-chain/snapcraft-runner to execute correctly any attempts to use the commands fail unless the user is root.