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

Public Docker Hub OCI registry now needs access token and username inputting into the External Feed in Octopus #8982

Open
Clare-Octopus opened this issue Aug 22, 2024 · 0 comments
Labels
kind/bug This issue represents a verified problem we are committed to solving

Comments

@Clare-Octopus
Copy link

Clare-Octopus commented Aug 22, 2024

Severity

Not blocking customers but they now need to create a free DockerHub account and generate a PAT to be able to pull helm charts from Public Docker Repo

Version

2024.2.9391 / 2024.3.10989

Latest Version

I could reproduce the problem in the latest build

What happened?

Previously, customers could authenticate anonymously to the Public Docker Hub Repo using an OCI Registry Feed in Octopus (not require a Username/Password in the External Feed setup in Octopus) as per our documentation on OCI Registry Feeds.

However, now when you try and pull a helm chart you see this error on the create release page:

Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation

image

We required the ability to download the manifest file for us to be able to validate the container correctly and this no longer works unauthenticated.

Please see workaround below to get you up and running again.

Reproduction

  1. Create a new external feed of type OCI Registry Feed in Octopus and use our documentation here to set it up for a Public Docker Hub repository. Ensure you save the feed (you won't be able to save and test).
  2. Create a new project and include a Deploy a Helm Chart Step.
  3. For the Chart Package action in that step chose the OCI Registry Feed we setup in Step 1.
  4. Physically type the repository and package name in (ie if using our Octopus Helm Chart you need to type octopusdeploy/octopusdeploy-helm).
  5. Fill in the rest of the chart for deployment and save it.
  6. Create a release and see the error message.
  7. Now go back into your External Feeds and use the workaround steps below to add a username and PAT to the feed in Octopus and save it.
  8. Go to create a release for the same project we create in step 2 and see a version number for that package will now be shown and you can now deploy.

Error and Stacktrace

2024-08-22 09:53:42.3805   3660    104  INFO  "HTTP" "GET" to "192.168.0.201""/api/Spaces-1/feeds" "completed" with 200 in 00:00:00.0119649 (11ms) by "octoadmin"
2024-08-22 09:53:42.3805   3660    104  WARN  Failed to get authentication header. Assuming this feed does not support search.
System.Exception: Unable to retrieve authentication token required to perform operation.
   at Octopus.Core.Packages.Oci.OciRegistryClient.RetrieveAuthenticationToken(String authUrl, NetworkCredential credential, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 361
   at Octopus.Core.Packages.Oci.OciRegistryClient.GetAuthRequestHeader(HttpResponseMessage response, NetworkCredential credential, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 369
   at Octopus.Core.Packages.Oci.OciRegistryClient.<>c__DisplayClass16_0.<<Get>g__GetTokenFromAuthService|0>d.MoveNext() in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 329
2024-08-22 09:53:42.3805   3660    104 ERROR  Unhandled error on request: "Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation."
Octopus.Core.Packages.Docker.DockerRegistrySearchNotSupportedException: Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation.
   at Octopus.Core.Packages.Oci.OciRegistryClient.<>c__DisplayClass16_0.<<Get>g__GetTokenFromAuthService|0>d.MoveNext() in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 334
--- End of stack trace from previous location ---
   at Octopus.Core.Packages.Oci.OciRegistryClient.Get(Uri url, ICredentials credentials, CancellationToken cancellationToken, Action`1 customAcceptHeader) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 285
   at Octopus.Core.Packages.Oci.OciRegistryClient.GetAllPages(Uri url, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 170
   at Octopus.Core.Packages.Oci.OciRegistryClient.ListVersions(Uri url, String packageId, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 161
   at Octopus.Core.Packages.Oci.OciRegistryPackageFeed.ListVersions(String packageId, ILogger logger, PackageVersionSearchOptions searchOptions, CancellationToken cancellationToken, Int32 skip, Int32 take, Boolean includeReleaseNotes) in ./source/Octopus.Core/Packages/Oci/OciRegistryPackageFeed.cs:line 104
   at Octopus.Core.Features.Feeds.GetFeedPackageVersionsRequestHandler.Handle(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Core/Features/Feeds/GetFeedPackageVersionsRequestHandler.cs:line 56
   at Octopus.Core.Infrastructure.Mediator.AutofacMediator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Core.Infrastructure.Mediator.Decorators.SystemComponentModelValidationDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Core.Infrastructure.Mediator.Decorators.FluentValidationsDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Core.Infrastructure.Mediator.Decorators.MessageBusSiphoningDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Server.Web.Controllers.Feeds.GetFeedPackageVersionsController.GetFeedPackageVersions(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Controllers/Feeds/GetFeedPackageVersionsController.cs:line 25
   at lambda_method2122224(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Octopus.Server.Web.Middleware.BoundaryTrailerRewriteMiddleware.Invoke(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/BoundaryTrailerRewriteMiddleware.cs:line 45
   at Octopus.Server.Web.Infrastructure.Authentication.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) in ./source/Octopus.Server/Web/Infrastructure/Authentication/AuthorizationMiddlewareResultHandler.cs:line 50
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 31
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 42
   at Octopus.Server.Web.Middleware.OctopusClientOldVersionWarningMiddleware.InvokeAsync(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/OctopusClientOldVersionWarningMiddleware.cs:line 24
   at Octopus.Server.Web.Middleware.DynamicContentHeadersMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/DynamicContentHeadersMiddleware.cs:line 50
   at Octopus.Server.Web.Middleware.MaintenanceModeMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/MaintenanceModeMiddleware.cs:line 58
   at Octopus.Server.Web.Middleware.OctopusAuthenticationMiddleware.InvokeAsync(HttpContext context, IUserAuthenticator userAuthenticator, IUserSessionService userSessionService, IWebAuthCache authCache, ILogger logger) in ./source/Octopus.Server/Web/Middleware/OctopusAuthenticationMiddleware.cs:line 61
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.Middleware.TelemetryMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/TelemetryMiddleware.cs:line 64
   at Octopus.Server.Web.Middleware.ErrorHandlingMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/ErrorHandlingMiddleware.cs:line 51
2024-08-22 09:53:42.3805   3660    104  INFO  "HTTP" "GET" to "192.168.0.201""/api/Spaces-1/feeds/Feeds-1489/packages/versions" "completed" with 500 in 00:00:00.6958322 (695ms) by "octoadmin"
Octopus.Core.Packages.Docker.DockerRegistrySearchNotSupportedException: Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation.
   at Octopus.Core.Packages.Oci.OciRegistryClient.<>c__DisplayClass16_0.<<Get>g__GetTokenFromAuthService|0>d.MoveNext() in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 334
--- End of stack trace from previous location ---
   at Octopus.Core.Packages.Oci.OciRegistryClient.Get(Uri url, ICredentials credentials, CancellationToken cancellationToken, Action`1 customAcceptHeader) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 285
   at Octopus.Core.Packages.Oci.OciRegistryClient.GetAllPages(Uri url, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 170
   at Octopus.Core.Packages.Oci.OciRegistryClient.ListVersions(Uri url, String packageId, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 161
   at Octopus.Core.Packages.Oci.OciRegistryPackageFeed.ListVersions(String packageId, ILogger logger, PackageVersionSearchOptions searchOptions, CancellationToken cancellationToken, Int32 skip, Int32 take, Boolean includeReleaseNotes) in ./source/Octopus.Core/Packages/Oci/OciRegistryPackageFeed.cs:line 104
   at Octopus.Core.Features.Feeds.GetFeedPackageVersionsRequestHandler.Handle(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Core/Features/Feeds/GetFeedPackageVersionsRequestHandler.cs:line 56
   at Octopus.Core.Infrastructure.Mediator.AutofacMediator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Core.Infrastructure.Mediator.Decorators.SystemComponentModelValidationDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Core.Infrastructure.Mediator.Decorators.FluentValidationsDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Core.Infrastructure.Mediator.Decorators.MessageBusSiphoningDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
   at Octopus.Server.Web.Controllers.Feeds.GetFeedPackageVersionsController.GetFeedPackageVersions(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Controllers/Feeds/GetFeedPackageVersionsController.cs:line 25
   at lambda_method2122224(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Octopus.Server.Web.Middleware.BoundaryTrailerRewriteMiddleware.Invoke(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/BoundaryTrailerRewriteMiddleware.cs:line 45
   at Octopus.Server.Web.Infrastructure.Authentication.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) in ./source/Octopus.Server/Web/Infrastructure/Authentication/AuthorizationMiddlewareResultHandler.cs:line 50
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 31
   at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 42
   at Octopus.Server.Web.Middleware.OctopusClientOldVersionWarningMiddleware.InvokeAsync(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/OctopusClientOldVersionWarningMiddleware.cs:line 24
   at Octopus.Server.Web.Middleware.DynamicContentHeadersMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/DynamicContentHeadersMiddleware.cs:line 50
   at Octopus.Server.Web.Middleware.MaintenanceModeMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/MaintenanceModeMiddleware.cs:line 58
   at Octopus.Server.Web.Middleware.OctopusAuthenticationMiddleware.InvokeAsync(HttpContext context, IUserAuthenticator userAuthenticator, IUserSessionService userSessionService, IWebAuthCache authCache, ILogger logger) in ./source/Octopus.Server/Web/Middleware/OctopusAuthenticationMiddleware.cs:line 61
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Octopus.Server.Web.Middleware.TelemetryMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/TelemetryMiddleware.cs:line 64
   at Octopus.Server.Web.Middleware.ErrorHandlingMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/ErrorHandlingMiddleware.cs:line 51
2024-08-22 09:53:42.3805   3660    104  INFO  "HTTP" "POST" to "192.168.0.201""/bff/telemetry/recordPortalOperation" "completed" with 200 in 00:00:00.0095793 (9ms) by "octoadmin"

More Information

Initial customer ticket (internal) - https://octopus.zendesk.com/agent/tickets/200053
R and D (internal) - https://octopusdeploy.slack.com/archives/CNHBHV2BX/p1724256060753389

Workaround

For this to work now, you need to create a free Docker Hub account.

From there you need to create a Personal Access Token (PAT) by following Docker's Official Documentation on Create and Manage Access Tokens.

The token itself needs to have Public Repo Read Only access permissions (you can give it any description you want):

image

Once that is created save the PAT for future use and copy that into your Octopus OCI Registry external feed for DockerHub Public Repositories alongside your Username from your DockerHub Profile:

image

Save the feed and you should now be able to pull Public DockerHub images.

Please also note that when you do input the Username and PAT you wont be able to search for packages in the feed test or search for the package in the step itself due to this GitHub issue so you will need to type the package in the step manually and save the step, after that the release creation will pickup the versions from those packages.

For example if using our Octopus Helm Chart you need to type octopusdeploy/octopusdeploy-helm in the step:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug This issue represents a verified problem we are committed to solving
Projects
None yet
Development

No branches or pull requests

1 participant