Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

add: translate registry unauthorized error when running a private image (#2101) #2102

Merged
merged 5 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pkg/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
apierror "k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -290,6 +290,10 @@ func (s *Run) Run(cmd *cobra.Command, args []string) (err error) {

image, deployArgs, err := imageSource.GetImageAndDeployArgs(cmd.Context(), c)
if err != nil {
if apierrors.IsUnauthorized(err) {
logrus.Debugf("Error pulling %s: %v", image, err)
return fmt.Errorf("not authorized to pull %s - Use `acorn login <REGISTRY>` to login to the registry", image)
}
err = client.TranslateNotAllowed(err)
if naErr := (*imageallowrules.ErrImageNotAllowed)(nil); errors.As(err, &naErr) {
if _, isPattern := autoupgrade.AutoUpgradePattern(image); isPattern {
Expand Down Expand Up @@ -329,7 +333,7 @@ func (s *Run) update(ctx context.Context, c client.Client, imageSource imagesour
}

app, err := c.AppGet(ctx, s.Name)
if apierror.IsNotFound(err) {
if apierrors.IsNotFound(err) {
if !imageSource.IsImageSet() {
return nil, false, fmt.Errorf("acorn \"%s\" is missing but can not be created without specifying an image to run or build", s.Name)
}
Expand Down
28 changes: 26 additions & 2 deletions pkg/server/registry/apigroups/acorn/images/detail.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ package images

import (
"context"
"fmt"
"net/http"
"strings"

"github.com/acorn-io/mink/pkg/stores"
"github.com/acorn-io/mink/pkg/types"
"github.com/acorn-io/mink/pkg/validator"
api "github.com/acorn-io/runtime/pkg/apis/api.acorn.io"
apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
"github.com/acorn-io/runtime/pkg/imagedetails"
"github.com/acorn-io/runtime/pkg/images"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -54,23 +59,42 @@ func (s *ImageDetailStrategy) Create(ctx context.Context, obj types.Object) (typ
}
ns, _ := request.NamespaceFrom(ctx)
opts := []remote.Option{s.remoteOpt}
imageName := strings.ReplaceAll(details.ImageName, "+", "/")
if details.Auth != nil {
imageName := strings.ReplaceAll(details.ImageName, "+", "/")
ref, err := name.ParseReference(imageName)
if err == nil {
opts = append(opts, remote.WithAuthFromKeychain(images.NewSimpleKeychain(ref.Context(), *details.Auth, nil)))
}
}
return imagedetails.GetImageDetails(ctx, s.client, ns, details.ImageName, imagedetails.GetImageDetailsOptions{
id, err := imagedetails.GetImageDetails(ctx, s.client, ns, details.ImageName, imagedetails.GetImageDetailsOptions{
Profiles: details.Profiles,
DeployArgs: details.DeployArgs,
Nested: details.NestedDigest,
NoDefaultReg: details.NoDefaultRegistry,
IncludeNested: details.IncludeNested,
RemoteOpts: opts,
})

return id, translateRegistryErrors(err, imageName)
}

func (s *ImageDetailStrategy) New() types.Object {
return &apiv1.ImageDetails{}
}

func translateRegistryErrors(in error, imageName string) error {
if in == nil {
return nil
}
if terr, ok := in.(*transport.Error); ok {
switch terr.StatusCode {
case http.StatusNotFound:
return errors.NewNotFound(schema.GroupResource{Group: api.Group, Resource: "images"}, imageName)
case http.StatusUnauthorized:
return errors.NewUnauthorized(fmt.Sprintf("pulling image %s: %v", imageName, terr))
case http.StatusForbidden:
return errors.NewForbidden(schema.GroupResource{Group: api.Group, Resource: "images"}, imageName, terr)
}
}
return in
}