Skip to content

Commit

Permalink
PR
Browse files Browse the repository at this point in the history
Signed-off-by: willdavsmith <willdavsmith@gmail.com>
  • Loading branch information
willdavsmith committed Jun 6, 2024
1 parent 9bad8e3 commit 8efe737
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
33 changes: 23 additions & 10 deletions pkg/cli/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,9 @@ func helmChartFromContainerRegistry(version string, config *helm.Configuration,
// This happens for ghcr in particular because ghcr does not use
// subdomains - the scope of a login is all of ghcr.io.
// https://github.com/helm/helm/issues/12584
var errUnexpectedStatus containerderrors.ErrUnexpectedStatus
if errors.As(err, &errUnexpectedStatus) {
unwrappedErr := UnwrapAll(err)
unexpectedStatusErr, ok := unwrappedErr.(containerderrors.ErrUnexpectedStatus)
if ok {
if unexpectedStatusErr.StatusCode == http.StatusForbidden && strings.Contains(unexpectedStatusErr.RequestURL, "ghcr.io") {
return nil, fmt.Errorf("recieved 403 unauthorized when downloading helm chart from the registry. you may want to perform a `docker logout ghcr.io` and re-try the command")
}
}
err := extractHelmError(err)
if err != nil {
return nil, err
}

return nil, fmt.Errorf("error downloading helm chart from the registry for version: %s, release name: %s. Error: %w", version, releaseName, err)
Expand Down Expand Up @@ -179,7 +173,26 @@ func runUpgrade(upgradeClient *helm.Upgrade, releaseName string, helmChart *char
return err
}

func UnwrapAll(err error) error {
// extractHelmError is a helper function to extract a specific error
// (403 unauthorized when downloading a helm chart from ghcr.io) from a chain of errors.
// If the error is not found, it returns nil.
func extractHelmError(err error) error {
var errUnexpectedStatus containerderrors.ErrUnexpectedStatus
if errors.As(err, &errUnexpectedStatus) {
unwrappedErr := unwrapAll(err)
switch unexpectedStatusErr := unwrappedErr.(type) {
case containerderrors.ErrUnexpectedStatus:
if unexpectedStatusErr.StatusCode == http.StatusForbidden && strings.Contains(unexpectedStatusErr.RequestURL, "ghcr.io") {
return fmt.Errorf("recieved 403 unauthorized when downloading helm chart from the registry. you may want to perform a `docker logout ghcr.io` and re-try the command")
}
}
}

return nil
}

// UnwrapAll unwraps all errors in a chain of errors and returns the root error.
func unwrapAll(err error) error {
for {
unwrapped := errors.Unwrap(err)
if unwrapped == nil {
Expand Down
30 changes: 27 additions & 3 deletions pkg/cli/helm/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package helm
import (
"errors"
"fmt"
"net/http"
"testing"

containerderrors "github.com/containerd/containerd/remotes/errors"
"github.com/stretchr/testify/assert"
)

Expand All @@ -13,12 +15,34 @@ func TestUnwrapAll(t *testing.T) {
err2 := errors.New("error 2")
err3 := errors.New("error 3")

err := UnwrapAll(err1)
err := unwrapAll(err1)
assert.Equal(t, err1, err)

err = UnwrapAll(fmt.Errorf("%w: wrapped error 2", err2))
err = unwrapAll(fmt.Errorf("%w: wrapped error 2", err2))
assert.Equal(t, err2, err)

err = UnwrapAll(fmt.Errorf("%w: wrapped error 2", fmt.Errorf("%w: wrapped error 3", err3)))
err = unwrapAll(fmt.Errorf("%w: wrapped error 2", fmt.Errorf("%w: wrapped error 3", err3)))
assert.Equal(t, err3, err)
}

func TestExtractHelmError(t *testing.T) {
err := errors.New("error")
extractedErr := extractHelmError(err)
assert.Nil(t, extractedErr)

err = fmt.Errorf("%w: wrapped error", errors.New("error"))
extractedErr = extractHelmError(err)
assert.Nil(t, extractedErr)

err = fmt.Errorf("%w: wrapped error", containerderrors.ErrUnexpectedStatus{})
extractedErr = extractHelmError(err)
assert.Nil(t, extractedErr)

err = fmt.Errorf("%w: wrapped error", containerderrors.ErrUnexpectedStatus{StatusCode: http.StatusForbidden, RequestURL: "ghcr.io/myregistry"})
extractedErr = extractHelmError(err)
assert.Equal(t, errors.New("recieved 403 unauthorized when downloading helm chart from the registry. you may want to perform a `docker logout ghcr.io` and re-try the command"), extractedErr)

err = containerderrors.ErrUnexpectedStatus{StatusCode: http.StatusForbidden, RequestURL: "ghcr.io/myregistry"}
extractedErr = extractHelmError(err)
assert.Equal(t, errors.New("recieved 403 unauthorized when downloading helm chart from the registry. you may want to perform a `docker logout ghcr.io` and re-try the command"), extractedErr)
}

0 comments on commit 8efe737

Please sign in to comment.