From af45f3af38247a66417104cce6ab83a79ae0a07d Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Tue, 17 Dec 2024 15:46:49 -0300 Subject: [PATCH] client: Add proxy host to skopoe calls The proxy host address was not passed to skopoe and as a consequence, it is not possible to connect to proxy to inspect OCI image. Closes: #1509 Signed-off-by: Winicius Silva --- client/oci_images.go | 62 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/client/oci_images.go b/client/oci_images.go index 3a5316365c1..b23733854a3 100644 --- a/client/oci_images.go +++ b/client/oci_images.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "io" + "net/http" + "net/url" "os" "os/exec" "path/filepath" @@ -31,6 +33,21 @@ type ociInfo struct { } `json:"LayersData"` } +// Get the proxy host value. +func (r *ProtocolOCI) getProxyHost() (*url.URL, error) { + req, err := http.NewRequest("GET", r.httpHost, nil) + if err != nil { + return nil, err + } + + proxy, err := r.http.Transport.(*http.Transport).Proxy(req) + if err != nil { + return nil, err + } + + return proxy, nil +} + // Image handling functions // GetImages returns a list of available images as Image structs. @@ -99,6 +116,21 @@ func (r *ProtocolOCI) GetImage(fingerprint string) (*api.Image, string, error) { func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*ImageFileResponse, error) { ctx := context.Background() + // Get proxy details. + proxy, err := r.getProxyHost() + if err != nil { + return nil, err + } + + var env []string + if proxy != nil { + env = []string{ + fmt.Sprintf("HTTPS_PROXY=%s", proxy), + fmt.Sprintf("HTTP_PROXY=%s", proxy), + } + } + + // Get the cached entry. info, ok := r.cache[fingerprint] if !ok { _, err := exec.LookPath("skopeo") @@ -118,7 +150,7 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I return nil, fmt.Errorf("OCI image export currently requires root access") } - _, err := exec.LookPath("umoci") + _, err = exec.LookPath("umoci") if err != nil { return nil, fmt.Errorf("OCI container handling requires \"umoci\" be present on the system") } @@ -146,7 +178,10 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I req.ProgressHandler(ioprogress.ProgressData{Text: "Retrieving OCI image from registry"}) } - stdout, err := subprocess.RunCommand( + stdout, _, err := subprocess.RunCommandSplit( + ctx, + env, + nil, "skopeo", "--insecure-policy", "copy", @@ -305,8 +340,29 @@ func (r *ProtocolOCI) GetImageAliasNames() ([]string, error) { // GetImageAlias returns an existing alias as an ImageAliasesEntry struct. func (r *ProtocolOCI) GetImageAlias(name string) (*api.ImageAliasesEntry, string, error) { + // Get proxy details. + proxy, err := r.getProxyHost() + if err != nil { + return nil, "", err + } + + var env []string + if proxy != nil { + env = []string{ + fmt.Sprintf("HTTPS_PROXY=%s", proxy), + fmt.Sprintf("HTTP_PROXY=%s", proxy), + } + } + // Get the image information from skopeo. - stdout, err := subprocess.RunCommand("skopeo", "inspect", fmt.Sprintf("%s/%s", strings.Replace(r.httpHost, "https://", "docker://", -1), name)) + stdout, _, err := subprocess.RunCommandSplit( + context.TODO(), + env, + nil, + "skopeo", + "inspect", + fmt.Sprintf("%s/%s", strings.Replace(r.httpHost, "https://", "docker://", -1), name)) + if err != nil { logger.Debug("Error getting image alias", logger.Ctx{"name": name, "stdout": stdout, "stderr": err}) return nil, "", err