dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.72k forks source link

No executable found matching command "dotnet-.....dll" #2568

Closed blackdwarf closed 4 years ago

blackdwarf commented 7 years ago

Steps to reproduce

Starting a Linux-based WebApi with systemd: # sudo systemctl start kestrel-wolverine.service

On command line this works (in current directory of dll): $ dotnet Wolverine.dll Hosting environment: Production Content root path: /var/aspnetcore/Wolverine Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.

This doesn't: $ /usr/bin/dotnet /var/aspnetcore/Wolverine/Wolverine.dll No executable found matching command "dotnet-/var/aspnetcore/Wolverine/Wolverine.dll"

Expected behavior

Starting up the service for Nginx to interact with on port 5000

Actual behavior

# sudo sudo journalctl -fu kestrel-wolverine.service Dec 23 09:47:02 sheltered systemd[1]: Started Example .NET Web API Application running on Debian. Dec 23 09:47:02 sheltered Wolverine[66237]: No executable found matching command "dotnet-/var/aspnetcore/Wolverine/Wolverine.dll" Dec 23 09:47:02 sheltered systemd[1]: kestrel-wolverine.service: main process exited, code=exited, status=1/FAILURE

Environment data

dotnet --info output: .NET Command Line Tools (1.0.0-preview2-1-003177)

Product Information: Version: 1.0.0-preview2-1-003177 Commit SHA-1 hash: a2df9c2576

Runtime Environment: OS Name: debian OS Version: 8 OS Platform: Linux RID: debian.8-x64

Moved from dotnet/cli#5137 for @daneb

gkhanna79 commented 7 years ago

@schellap PTAL at this.

@blackdwarf Is the kestrel-Wolverine service always installed on a Linux box? If not, how should it be installed to get the repro going?

gkhanna79 commented 7 years ago

CC @ramarag

daneb commented 7 years ago

@gkhanna79 I just created a new boilerplate C# WebAPI from dotnet cli - named it Wolverine. Followed instructions Dotnet Core Docs

I published the project, made a zip of the output and setup Nginx and created a service definition file for the above Project which is kestrel-Wolverine.

HTH

schellap commented 7 years ago

When you run on the command line, can you share the export COREHOST_TRACE=1 output on a github Gist or pastebin?

daneb commented 7 years ago

@schellap (from the initial issue on core-cli)

Jan 03 16:20:21 sheltered systemd[1]: Unit kestrel-wolverine.service entered failed state.
Jan 03 16:20:22 sheltered systemd[1]: kestrel-wolverine.service holdoff time over, scheduling restart.
Jan 03 16:20:22 sheltered systemd[1]: Stopping Example .NET Web API Application running on Debian...
Jan 03 16:20:22 sheltered systemd[1]: Starting Example .NET Web API Application running on Debian...
Jan 03 16:20:22 sheltered systemd[1]: kestrel-wolverine.service start request repeated too quickly, refusing to start.
Jan 03 16:20:22 sheltered systemd[1]: Failed to start Example .NET Web API Application running on Debian.
Jan 03 16:20:22 sheltered systemd[1]: Unit kestrel-wolverine.service entered failed state.
Jan 03 16:20:35 sheltered systemd[1]: [/etc/systemd/system/kestrel-wolverine.service:6] Executable path is not absolute, ignoring: COREHOST_TRACE=1 /usr/bin/dotnet Wolverine.dll
Jan 03 16:20:35 sheltered systemd[1]: kestrel-wolverine.service lacks ExecStart setting. Refusing.
ramarag commented 7 years ago

@daneb please provide the trace generated when run with export COREHOST_TRACE=1. If that will not be sufficient, we would need full steps to reproduce this issue

omajid commented 7 years ago

Can someone provide the systemd service file?

Systemd unit files are a little weird, Exec=COREHOST_TRACE=1 /usr/bin/dotnet Wolverine.dll is interpreted as trying to run CORESHOST_TRACE=1 or something, which it refuses. Use the following syntax:

Environment=COREHOST_TRACE=1 ANOTHER_VAR_YOU_WANT_TO_SET=another_value
Exec=/usr/bin/dotnet /path/to/Wolverine.dll

I would suggest adding in LD_DEBUG=all if this might have anything to do with the runtime dynamic linker.

omajid commented 7 years ago

Here's what I did:

$ ~/dotnet-1.1.1/dotnet --info
.NET Command Line Tools (1.0.0-preview2-1-003176)

Product Information:
 Version:            1.0.0-preview2-1-003176
 Commit SHA-1 hash:  de817fd2d5

Runtime Environment:
 OS Name:     rhel
 OS Version:  7.2
 OS Platform: Linux
 RID:         rhel.7.2-x64

This is a custom build with 1.0 RC 2 tooling (project.json, not csproj) but 1.1.1 shared framework.

$ mkdir hello-web
$ cd hello-web/
$ ~/dotnet-1.1.1/dotnet new -t web
Created new C# project in /home/omajid/hello-web.
$ ~/dotnet-1.1.1/dotnet restore
log  : Restoring packages for /home/omajid/hello-web/project.json...
warn : Dependency specified was Microsoft.NETCore.App (>= 1.1.0-preview1-001153-00) but ended up with Microsoft.NETCore.App 1.1.0.
log  : Installing Microsoft.Composition 1.0.27.
log  : Installing Microsoft.CodeAnalysis.Workspaces.Common 1.3.0.
[ snip ]
log  : Installing Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore 1.0.0-preview2-final.
log  : Writing lock file to disk. Path: /home/omajid/hello-web/project.lock.json
log  : /home/omajid/hello-web/project.json
log  : Restore completed in 10574ms.
$ ~/dotnet-1.1.1/dotnet build
Project hello-web (.NETCoreApp,Version=v1.1) will be compiled because expected outputs are missing
Compiling hello-web for .NETCoreApp,Version=v1.1
/home/omajid/hello-web/project.json(5,30): warning NU1007: Dependency specified was Microsoft.NETCore.App >= 1.1.0-pre
view1-001153-00 but ended up with Microsoft.NETCore.App 1.1.0.

Compilation succeeded.
    1 Warning(s)
    0 Error(s)

Time elapsed 00:00:02.2834976

$ ~/dotnet-1.1.1/dotnet run
Project hello-web (.NETCoreApp,Version=v1.1) was previously compiled. Skipping compilation.
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
      User profile is available. Using '/home/omajid/.aspnet/DataProtection-Keys' as key repository; keys will not be 
encrypted at rest.
Hosting environment: Production
Content root path: /home/omajid/hello-web
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
^C
$ ~/dotnet-1.1.1/dotnet bin/Debug/netcoreapp1.1/hello-web.dll 
info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
      User profile is available. Using '/home/omajid/.aspnet/DataProtection-Keys' as key repository; keys will not be 
encrypted at rest.
Hosting environment: Production
Content root path: /home/omajid/hello-web
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
^C
$ cat /etc/systemd/system/dotnet-test.service
[Unit]
Description=Example .NET Web API Application

[Service]
WorkingDirectory=/home/omajid/hello-web/bin/
ExecStart=/home/omajid/dotnet-1.1.1/dotnet /home/omajid/hello-web/bin/Debug/netcoreapp1.1/hello-web.dll
Restart=always
RestartSec=10                                          # Restart service after 10 seconds if dotnet service crashes
SyslogIdentifier=dotnet-example
User=omajid
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl start dotnet-test.service
$ sudo journalctl -fu dotnet-test.service
- Logs begin at Fri 2017-03-17 09:34:54 EDT. --
Mar 17 21:49:00 localhost.localdomain systemd[1]: [/etc/systemd/system/dotnet-test.service:8] Failed to parse usec_t v
alue, ignoring: 10                                          # Restart service after 10 seconds if dotnet service crash
es
Mar 17 21:49:01 localhost.localdomain systemd[1]: [/etc/systemd/system/dotnet-test.service:8] Failed to parse usec_t v
alue, ignoring: 10                                          # Restart service after 10 seconds if dotnet service crash
es
Mar 17 21:49:01 localhost.localdomain systemd[1]: [/etc/systemd/system/dotnet-test.service:8] Failed to parse usec_t v
alue, ignoring: 10                                          # Restart service after 10 seconds if dotnet service crash
es
Mar 17 21:49:05 localhost.localdomain systemd[1]: [/etc/systemd/system/dotnet-test.service:8] Failed to parse usec_t v
alue, ignoring: 10                                          # Restart service after 10 seconds if dotnet service crash
es
Mar 17 21:49:05 localhost.localdomain systemd[1]: Started Example .NET Web API Application.
Mar 17 21:49:05 localhost.localdomain systemd[1]: Starting Example .NET Web API Application...
Mar 17 21:49:05 localhost.localdomain dotnet-example[28672]: Hosting environment: Production
Mar 17 21:49:05 localhost.localdomain dotnet-example[28672]: Content root path: /home/omajid/hello-web/bin
Mar 17 21:49:05 localhost.localdomain dotnet-example[28672]: Now listening on: http://localhost:5000
Mar 17 21:49:05 localhost.localdomain dotnet-example[28672]: Application started. Press Ctrl+C to shut down.

Looks like the syntax for RestartSec is a bit off but it works for me otherwise.

ramarag commented 7 years ago

@omajid does this issue no longer repros ?

gkhanna79 commented 7 years ago

Closing for now as it does not appear to repro. Please reactivate the issue if it does and share details of repro steps.

NickMRamirez commented 7 years ago

I have had this happen, using the following (running in Docker on Linux Mint):

cd app

sudo docker run --rm -it -p 5000 -v $(pwd):/srv -e ASPNETCORE_URLS=http://+:5000 -w /srv --entrypoint /usr/bin/dotnet microsoft/dotnet "./test.dll"

Gives:

No executable found matching command "dotnet-./test.dll"

Even without Docker, a simple way to repro it is to intentionally give a bad filename for the DLL, such as:

dotnet ./test.

Gives:

No executable found matching command "dotnet-./test."

This works fine:

dotnet ./test.dll

More error info:

Microsoft.DotNet.Cli.Utils.CommandUnknownException: No executable found matching command "dotnet-./test"
   at Microsoft.DotNet.Cli.Utils.Command.Create(ICommandResolverPolicy commandResolverPolicy, String commandName, IEnumerable`1 args, NuGetFramework framework, String configuration, String outputPath, String applicationName)
   at Microsoft.DotNet.Cli.Utils.Command.Create(String commandName, IEnumerable`1 args, NuGetFramework framework, String configuration, String outputPath, String applicationName)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)

I think it's happening in https://github.com/dotnet/cli/blob/cc80822c16b955a1f664f8a65ed2c76c3c52a824/src/dotnet/Program.cs

Maybe this part of the code:

int exitCode;
Func<string[], int> builtIn;
if (s_builtIns.TryGetValue(command, out builtIn))
{
                exitCode = builtIn(appArgs.ToArray());
}
else
{
                CommandResult result = Command.Create(
                        "dotnet-" + command,
                        appArgs,
                        FrameworkConstants.CommonFrameworks.NetStandardApp15)
                    .Execute();
                exitCode = result.ExitCode;
}

It seems like there should be a branch off in the logic somewhere to handle running a framework-dependent assembly, but I'm not sure where.

gkhanna79 commented 7 years ago

Which .NET Core SDK/FX version are you able to repro it on?

CC @eerhardt @ramarag

NickMRamirez commented 7 years ago

I'm using version 1.1.2 on Debian and Linux Mint.

omajid commented 7 years ago

@ramarag Sorry, this got buried in my github notifications. (I really need to find a way to manage issues i am interested in). I could never reproduce the original issue. This has always worked for me.

@NickMRamirez Just to clarify, what do you expect to happen with this?

sudo docker run --rm -it -p 5000 -v $(pwd):/srv -e ASPNETCORE_URLS=http://+:5000 -w /srv --entrypoint /usr/bin/dotnet microsoft/dotnet "./test.dll"

NickMRamirez commented 7 years ago

@omajid Using that Docker command, it should use the microsoft/dotnet image, which already contains the .NET Core libraries. After I compile a vanilla .NET Core webapi project, I want to run my "test.dll" in the container, such as I would do when not using a container, with the command:

cd /srv dotnet ./test.dll

The Docker command sets /srv as the current working directory and tries to run the /usr/bin/dotnet ./test.dll command inside the container. This should spin up the app and start listening on port 5000, which I've exposed to the outside of the container with the -p argument. Instead, I get the error.

eerhardt commented 7 years ago

What happens when you either:

  1. Remove the quotes --entrypoint /usr/bin/dotnet microsoft/dotnet ./test.dll
  2. Wrap the whole entry point in quotes: --entrypoint "/usr/bin/dotnet microsoft/dotnet ./test.dll"

?

My guess is that the dotnet host isn't seeing your argument as an assembly to execute (guessing that the quotes are the problem). Thus, the host is calling into the managed CLI code, which tries finding a command named "dotnet-./test.", which obviously doesn't exist.

See the examples from https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime:

$ docker run -it --entrypoint /bin/bash example/redis -c ls -l
$ docker run -it --entrypoint /usr/bin/redis-cli example/redis --help
NickMRamirez commented 7 years ago

Well...today, the command works mysteriously. The same command I was trying before.

ghost commented 7 years ago

I may be able to shed some light on this...

I was getting ready to post a repro, as I was able to run it direct, but when running via the service it failed with same message as in the OP's example.

No executable found matching command "dotnet-/path/to/app/myexampleapp.dll"

When enabling COREHOST_TRACE=1 and reading the logs, this was the first line that differed between the running as a service and direct:

Application '/path/to/app/myexampleapp.dll' is not a managed executable.

Everything else up to that point in the logs appeared to be identical.

The problem I had was that the path was typo'ed. (Two characters that looked very similar were transposed).

It would be great, and make thing a lot faster to debug, if dotnet could return a really clear message: File or path not found. rather than "No executable found matching command" or "Application 'x' is not a managed executable"

dvbava commented 7 years ago

I had same error message on Cent OS "o executable found matching command "dotnet-.....dll" Notice that insted of 'No....', the message started with double quotes like "o executable found..... with no matching closing double quotes.

it works fine if I type following command on bash shell.
[ ~$]dotnet my.app.dll

However if i copy paste same command in VS2017 in a file named run.sh as dotnet my.app.dll

then run as [ ~$]bash run.sh "o executable found matching command "dotnet-.....dll"

However if I go to bash command prompt and type [ ~$] nano run.sh then type by hand dotnet my.app.dll

and save and close, Now it works fine... bash run.sh ....

So there is no logic in error message: "o executable found matching command "dotnet-.....dll"

its completely misguiding message.

kyland-holmes commented 6 years ago

This is probably the most frustrating bug in using this CLI. I can't believe the bug has actually been closed.

eerhardt commented 6 years ago

@KyKoPho - can you describe the steps you've taken to run into this bug? If there is something we can do to better, we'd like to do it. Knowing the steps you've taken would help in learning what we can do better.

The original reported issue looks to no longer be reproducible, which was why this was closed.

dvbava commented 6 years ago

@eerhardt is there anything i am missing ? How does it make difference if I create run.sh file on vs2017 on win 10 vs nano on cent os 7.

Is it encoding do you think.. as error message is bit different... "o executable....
Instead of "No executable....

eerhardt commented 6 years ago

If you create a file on a Windows machine, it will use \r\n for each new line (by default). If you create a file on a Unix machine, the newline will just be \n.

My guess is that the \r is getting included in the string for the .dll name when executing the .sh file. So the dotnet host is setting the assembly name as my.app.dll\r, which doesn't end in .dll. So the host gets confused and thinks you are trying to run an SDK command (like dotnet build), and it forwards the command to the SDK.

See https://github.com/dotnet/core-setup/blob/786a4fdd71d98b82414a639b4f0094d8bab93cf2/src/corehost/cli/fxr/fx_muxer.cpp#L1121

For how the host figures out if the path specified is a managed app or not.

Try putting a space ` after the.dll` in your .sh file and see if that fixes it.

kyland-holmes commented 6 years ago

This service throws the reported error no matter what path you give dotnet:

` version: "3" services:

platform-inbox: image: "microsoft/aspnetcore-build:1.1.2" env_file: .env environment:

Here are the contents of my .env that are relevant:

ENVIRONMENT=integration_local INBOX_RUN_PATH=/build/inbox/Onvia.Platform.Inbox/Onvia.Platform.Inbox/bin/Debug/netcoreapp1.1/Onvia.Platform.Inbox.dll LOG_LOCATION=/c/Logs

kyland-holmes commented 6 years ago

Sorry, having formatting issues with the above.... Perhaps you will see the issue right up front. I have also tested using Unix line endings everywhere as well as moving the last dotnet command into a shell script that I then add to the image, but no dice. Also, I'm running Docker on Windows, latest version.

eerhardt commented 6 years ago

working_dir: /build/Onvia.Platform.Inbox/src/Onvia.Platform.Inbox vs. INBOX_RUN_PATH=/build/inbox/Onvia.Platform.Inbox/Onvia.Platform.Inbox

One has a src in the middle. The other doesn't.

Also, one has inbox.

ghost commented 6 years ago

@eerhardt I think the problem is that the messages being given arn't terribly clear. i.e there's not an actual fault in dotnet, but the messaging is opaque as to the reason things arn't working.

No executable found matching command "dotnet-/path/to/app/myexampleapp.dll"

and with tracing enabled:

Application '/path/to/app/myexampleapp.dll' is not a managed executable.

...when what SHOULD be said is "File or path {0} is not found" i.e actually make it dead clear "I don't know what you gave me, I can't find that file"

kyland-holmes commented 6 years ago

@eerhardt Those paths are correct. This is a build container scenario where the stuff to build is in working_dir and the stuff to run is in the INBOX_RUN_PATH.

Assuming all of my paths are correct, which I haveave verified multiple times by bashing into the container, it stands to reason that there is a bug in the dotnet CLI.

kyland-holmes commented 6 years ago

@eerhardt Also, thank you for your very prompt replies!

kyland-holmes commented 6 years ago

@eerhardt. You should be able to repro this using a trivial docker compose using Docker for Windows on Windows 10 with the Linux Subsystem activated. Using the app net core 1.1.2 image from Microsoft and a command of dotnet {path} with any valid or invalid path and any value for working_dir as long as you have something mounted in the volumes and use a path under that mapped path.

NickMRamirez commented 6 years ago

@KyKoPho Using .NET Core 2.0, this Dockerfile works for me:

FROM microsoft/aspnetcore:2.0.0
ENV ASPNETCORE_URLS=http://+:80
EXPOSE 80
WORKDIR /app
COPY output .
ENTRYPOINT ["dotnet", "mysite.dll"]

Do you get the error using the .NET Core 2.0 SDK?

kyland-holmes commented 6 years ago

Unfortunately, we cannot upgrade to 2.0 because there are still some many problems building in other scenarios with 2.0. For example, building in visual studio. I will try this in 1.1.2 using the ENTRYPOINT style you use above. At some point in the near future, we will likely do a full upgrade of all of our services to 2.0, but at the last attempt we made I September, there were some serious limitations with other tooling.

NickMRamirez commented 6 years ago

@KyKoPho I had posted a comment where I said I thought that working_dir might have been affecting the path of INBOX_RUN_PATH...but since you are using an absolute path for that variable, it seems like it should find it so I deleted the comment.