-
Notifications
You must be signed in to change notification settings - Fork 64
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
driver: support for credentials helper and auth config file #265
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
|
@@ -10,54 +10,61 @@ import ( | ||
"fmt" | "fmt" | ||
"io" | "io" | ||
"net/http" | "net/http" | ||
|
|||
"github.com/hashicorp/nomad-driver-podman/registry" | |||
) | ) | ||
|
|
||
// ImagePull pulls a image from a remote location to local storage | // ImagePull pulls a image from a remote location to local storage | ||
func (c *API) ImagePull(ctx context.Context, nameWithTag string, auth ImageAuthConfig) (string, error) { | func (c *API) ImagePull(ctx context.Context, pullConfig *registry.PullConfig) (string, error) { | ||
var id string | pullConfig.Log(c.logger) | ||
headers := map[string]string{} |
|
||
|
var ( | ||
// handle authentication | headers = make(map[string]string) | ||
usesAuth := auth.Username != "" && auth.Password != "" | repository = pullConfig.Image | ||
if usesAuth { | tlsVerify = pullConfig.TLSVerify | ||
authHeader, err := NewAuthHeader(auth) | ) | ||
Comment on lines
+21
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just some Go curiosity, is there an advantage to declaring the variables like this instead of using the walrus There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope none at all; doing it this way just makes |
|||
|
|||
// if the task or driver are configured with an auth block, attempt to find | |||
// credentials that are compatible with the given image, and set the appropriate | |||
// header if found | |||
if pullConfig.AuthAvailable() { | |||
auth, err := registry.ResolveRegistryAuthentication(repository, pullConfig) | |||
if err != nil { | if err != nil { | ||
return "", err | return "", fmt.Errorf("failed to determine authentication for %q: %w", repository, err) | ||
} | } | ||
headers["X-Registry-Auth"] = authHeader | auth.SetHeader(headers) | ||
} | } | ||
|
|
||
c.logger.Trace("image pull details", "tls_verify", auth.TLSVerify, "reference", nameWithTag, "uses_auth", usesAuth) | urlPath := fmt.Sprintf("/v1.0.0/libpod/images/pull?reference=%s&tlsVerify=%t", repository, tlsVerify) | ||
|
|
||
urlPath := fmt.Sprintf("/v1.0.0/libpod/images/pull?reference=%s&tlsVerify=%t", nameWithTag, auth.TLSVerify) | |||
res, err := c.PostWithHeaders(ctx, urlPath, nil, headers) | res, err := c.PostWithHeaders(ctx, urlPath, nil, headers) | ||
if err != nil { | if err != nil { | ||
return "", err | return "", fmt.Errorf("failed to pull image: %w", err) | ||
} | } | ||
|
|||
defer ignoreClose(res.Body) | defer ignoreClose(res.Body) | ||
|
|||
if res.StatusCode != http.StatusOK { | if res.StatusCode != http.StatusOK { | ||
body, _ := io.ReadAll(res.Body) | body, _ := io.ReadAll(res.Body) | ||
return "", fmt.Errorf("cannot pull image, status code: %d: %s", res.StatusCode, body) | return "", fmt.Errorf("cannot pull image, status code: %d: %s", res.StatusCode, body) | ||
} | } | ||
|
|
||
dec := json.NewDecoder(res.Body) | var ( | ||
var report ImagePullReport | dec = json.NewDecoder(res.Body) | ||
for { | report ImagePullReport | ||
decErr := dec.Decode(&report) | id string | ||
if errors.Is(decErr, io.EOF) { | ) | ||
break | |||
} else if decErr != nil { | |||
return "", fmt.Errorf("Error reading response: %w", decErr) | |||
} | |||
|
|
||
if report.Error != "" { | for { | ||
return "", errors.New(report.Error) | decodeErr := dec.Decode(&report) | ||
} | switch { | ||
|
case errors.Is(decodeErr, io.EOF): | ||
if report.ID != "" { | return id, nil | ||
case decodeErr != nil: | |||
return "", fmt.Errorf("failed to read image pull response: %w", decodeErr) | |||
case report.Error != "": | |||
return "", fmt.Errorf("image pull report indicates error: %s", report.Error) | |||
case report.ID != "": | |||
id = report.ID | id = report.ID | ||
} | } | ||
} | } | ||
return id, nil | |||
} | } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reads a bit inverted to me, but something like
c.logger.Info("pull config", pullConfig.LogTags()...)
looks a bit weird as well 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's a bit unusual but it nicely hides the ~20 lines of gunk specific to the thing being logged