dotnet / sdk-container-builds

Libraries and build tooling to create container images from .NET projects using MSBuild
https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container
MIT License
179 stars 34 forks source link

Better handle container publishing when there's no network connectivity #589

Open afscrome opened 3 weeks ago

afscrome commented 3 weeks ago

Currently dotnet publish /t:PublishContainer will fail if you have no network connectivity.

If you cannot connect to the remote registry (e.g. mcr.microsoft.com, MYORG.azurecr.io), the publish process should fall back to the local registry to get the base image. (Perhaps emitting a warning to say that it may not be using the latest container version)

Repro Steps

  1. Disconnect from any internet / network connections
  2. Run dotnet publish /t:PublishContainer

Expected Results:

The SDK build should fall back to any locally cached version of the base image in your local registry

Actual Results:

error MSB4018: The "CreateNewImage" task failed unexpectedly. [C:\src\ACTest\app\Sample.csproj]
error MSB4018: System.Net.Http.HttpRequestException: No such host is known. (mcr.microsoft.com:443) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:  ---> System.Net.Sockets.SocketException (11001): No such host is known. [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|285_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    --- End of inner exception stack trace --- [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.NET.Build.Containers.AuthHandshakeMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /_/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs:line 387 [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.NET.Build.Containers.DefaultManifestOperations.GetAsync(String repositoryName, String reference, CancellationToken cancellationToken) in /_/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultManifestOperations.cs:line 31 [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.NET.Build.Containers.Registry.GetImageManifestAsync(String repositoryName, String reference, String runtimeIdentifier, IManifestPicker manifestPicker, CancellationToken cancellationToken) in /_/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs:line 171 [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ExecuteAsync(CancellationToken cancellationToken) in /_/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs:line 81 [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Execute() in /_/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs:line 36 [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [C:\src\ACTest\app\Sample.csproj]
error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [C:\src\ACTest\app\Sample.csproj]
baronfel commented 3 weeks ago

I disagree slightly - we do not use local registries for storage, and to my knowledge neither do Jib and ko. Instead, we should enable using the local storage we already maintain for blobs as a fallback location for manifests as well. This would mean

afscrome commented 3 weeks ago

My main desire is that if using dotnet publish /t:PublishContainer in a local dev loop, I want to that to continue to work fine if I loose network connectivity. (e.g. network outage, working on a train / plane etc.)

My initial thinking is that currently the tooling gets unhappy with the default command if you publish without a local registry, so using the local registry seemed reasonable. But if there's an alternative solution I'm not too fussed.

error : Cannot find docker/podman executable. [C:\src\ACTest\app\Sample.csproj]
error CONTAINER1012: The local registry is not available, but pushing to a local registry was requested. [C:\src\A