summaryrefslogtreecommitdiff
path: root/pkg/bindings/images/images.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/bindings/images/images.go')
-rw-r--r--pkg/bindings/images/images.go232
1 files changed, 173 insertions, 59 deletions
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index 2305e0101..e0802a6e1 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -1,6 +1,7 @@
package images
import (
+ "bytes"
"context"
"fmt"
"io"
@@ -8,10 +9,14 @@ import (
"net/url"
"strconv"
+ "github.com/containers/buildah"
"github.com/containers/image/v5/types"
"github.com/containers/libpod/pkg/api/handlers"
+ "github.com/containers/libpod/pkg/auth"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/docker/go-units"
+ jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
@@ -22,7 +27,7 @@ func Exists(ctx context.Context, nameOrID string) (bool, error) {
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/exists", nil, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/exists", nil, nil, nameOrID)
if err != nil {
return false, err
}
@@ -48,7 +53,7 @@ func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entit
}
params.Set("filters", strFilters)
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/json", params)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/json", params, nil)
if err != nil {
return imageSummary, err
}
@@ -67,15 +72,29 @@ func GetImage(ctx context.Context, nameOrID string, size *bool) (*entities.Image
params.Set("size", strconv.FormatBool(*size))
}
inspectedData := entities.ImageInspectReport{}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/json", params, nil, nameOrID)
if err != nil {
return &inspectedData, err
}
return &inspectedData, response.Process(&inspectedData)
}
-func Tree(ctx context.Context, nameOrId string) error {
- return bindings.ErrNotImplemented
+// Tree retrieves a "tree" based representation of the given image
+func Tree(ctx context.Context, nameOrId string, whatRequires *bool) (*entities.ImageTreeReport, error) {
+ var report entities.ImageTreeReport
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ params := url.Values{}
+ if whatRequires != nil {
+ params.Set("size", strconv.FormatBool(*whatRequires))
+ }
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/tree", params, nil, nameOrId)
+ if err != nil {
+ return nil, err
+ }
+ return &report, response.Process(&report)
}
// History returns the parent layers of an image.
@@ -85,7 +104,7 @@ func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse,
if err != nil {
return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/history", nil, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/history", nil, nil, nameOrID)
if err != nil {
return history, err
}
@@ -102,43 +121,13 @@ func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadRe
if name != nil {
params.Set("reference", *name)
}
- response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params)
+ response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params, nil)
if err != nil {
return nil, err
}
return &report, response.Process(&report)
}
-// Remove deletes an image from local storage. The optional force parameter
-// will forcibly remove the image by removing all all containers, including
-// those that are Running, first.
-func Remove(ctx context.Context, images []string, opts entities.ImageRemoveOptions) (*entities.ImageRemoveReport, error) {
- var report handlers.LibpodImagesRemoveReport
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return nil, err
- }
- params := url.Values{}
- params.Set("all", strconv.FormatBool(opts.All))
- params.Set("force", strconv.FormatBool(opts.Force))
- for _, i := range images {
- params.Add("images", i)
- }
-
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/remove", params)
- if err != nil {
- return nil, err
- }
- if err := response.Process(&report); err != nil {
- return nil, err
- }
- var rmError error
- if report.Error != "" {
- rmError = errors.New(report.Error)
- }
- return &report.ImageRemoveReport, rmError
-}
-
// Export saves an image from local storage as a tarball or image archive. The optional format
// parameter is used to change the format of the output.
func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, compress *bool) error {
@@ -153,7 +142,7 @@ func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, c
if compress != nil {
params.Set("compress", strconv.FormatBool(*compress))
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/get", params, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/%s/get", params, nil, nameOrID)
if err != nil {
return err
}
@@ -162,7 +151,7 @@ func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, c
_, err = io.Copy(w, response.Body)
return err
}
- return nil
+ return response.Process(nil)
}
// Prune removes unused images from local storage. The optional filters can be used to further
@@ -186,7 +175,7 @@ func Prune(ctx context.Context, all *bool, filters map[string][]string) ([]strin
}
params.Set("filters", stringFilter)
}
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/prune", params)
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/prune", params, nil)
if err != nil {
return deleted, err
}
@@ -202,7 +191,7 @@ func Tag(ctx context.Context, nameOrID, tag, repo string) error {
params := url.Values{}
params.Set("tag", tag)
params.Set("repo", repo)
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/tag", params, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/tag", params, nil, nameOrID)
if err != nil {
return err
}
@@ -218,14 +207,115 @@ func Untag(ctx context.Context, nameOrID, tag, repo string) error {
params := url.Values{}
params.Set("tag", tag)
params.Set("repo", repo)
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/untag", params, nameOrID)
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/untag", params, nil, nameOrID)
if err != nil {
return err
}
return response.Process(nil)
}
-func Build(nameOrId string) {}
+// Build creates an image using a containerfile reference
+func Build(ctx context.Context, containerFiles []string, options entities.BuildOptions, tarfile io.Reader) (*entities.BuildReport, error) {
+ var (
+ platform string
+ report entities.BuildReport
+ )
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return nil, err
+ }
+ params := url.Values{}
+ params.Set("dockerfile", containerFiles[0])
+ if t := options.Output; len(t) > 0 {
+ params.Set("t", t)
+ }
+ // TODO Remote, Quiet
+ if options.NoCache {
+ params.Set("nocache", "1")
+ }
+ // TODO cachefrom
+ if options.PullPolicy == buildah.PullAlways {
+ params.Set("pull", "1")
+ }
+ if options.RemoveIntermediateCtrs {
+ params.Set("rm", "1")
+ }
+ if options.ForceRmIntermediateCtrs {
+ params.Set("forcerm", "1")
+ }
+ if mem := options.CommonBuildOpts.Memory; mem > 0 {
+ params.Set("memory", strconv.Itoa(int(mem)))
+ }
+ if memSwap := options.CommonBuildOpts.MemorySwap; memSwap > 0 {
+ params.Set("memswap", strconv.Itoa(int(memSwap)))
+ }
+ if cpuShares := options.CommonBuildOpts.CPUShares; cpuShares > 0 {
+ params.Set("cpushares", strconv.Itoa(int(cpuShares)))
+ }
+ if cpuSetCpus := options.CommonBuildOpts.CPUSetCPUs; len(cpuSetCpus) > 0 {
+ params.Set("cpusetcpues", cpuSetCpus)
+ }
+ if cpuPeriod := options.CommonBuildOpts.CPUPeriod; cpuPeriod > 0 {
+ params.Set("cpuperiod", strconv.Itoa(int(cpuPeriod)))
+ }
+ if cpuQuota := options.CommonBuildOpts.CPUQuota; cpuQuota > 0 {
+ params.Set("cpuquota", strconv.Itoa(int(cpuQuota)))
+ }
+ if buildArgs := options.Args; len(buildArgs) > 0 {
+ bArgs, err := jsoniter.MarshalToString(buildArgs)
+ if err != nil {
+ return nil, err
+ }
+ params.Set("buildargs", bArgs)
+ }
+ if shmSize := options.CommonBuildOpts.ShmSize; len(shmSize) > 0 {
+ shmBytes, err := units.RAMInBytes(shmSize)
+ if err != nil {
+ return nil, err
+ }
+ params.Set("shmsize", strconv.Itoa(int(shmBytes)))
+ }
+ if options.Squash {
+ params.Set("squash", "1")
+ }
+ if labels := options.Labels; len(labels) > 0 {
+ l, err := jsoniter.MarshalToString(labels)
+ if err != nil {
+ return nil, err
+ }
+ params.Set("labels", l)
+ }
+
+ // TODO network?
+ if OS := options.OS; len(OS) > 0 {
+ platform += OS
+ }
+ if arch := options.Architecture; len(arch) > 0 {
+ platform += "/" + arch
+ }
+ if len(platform) > 0 {
+ params.Set("platform", platform)
+ }
+ // TODO outputs?
+
+ response, err := conn.DoRequest(tarfile, http.MethodPost, "/build", params, nil)
+ if err != nil {
+ return nil, err
+ }
+ var streamReponse []byte
+ bb := bytes.NewBuffer(streamReponse)
+ if _, err = io.Copy(bb, response.Body); err != nil {
+ return nil, err
+ }
+ var s struct {
+ Stream string `json:"stream"`
+ }
+ if err := jsoniter.UnmarshalFromString(bb.String(), &s); err != nil {
+ return nil, err
+ }
+ fmt.Print(s.Stream)
+ return &report, nil
+}
// Imports adds the given image to the local image store. This can be done by file and the given reader
// or via the url parameter. Additional metadata can be associated with the image by using the changes and
@@ -252,7 +342,7 @@ func Import(ctx context.Context, changes []string, message, reference, u *string
if u != nil {
params.Set("url", *u)
}
- response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params)
+ response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params, nil)
if err != nil {
return nil, err
}
@@ -270,16 +360,22 @@ func Pull(ctx context.Context, rawImage string, options entities.ImagePullOption
}
params := url.Values{}
params.Set("reference", rawImage)
- params.Set("credentials", options.Credentials)
params.Set("overrideArch", options.OverrideArch)
params.Set("overrideOS", options.OverrideOS)
- if options.TLSVerify != types.OptionalBoolUndefined {
- val := bool(options.TLSVerify == types.OptionalBoolTrue)
- params.Set("tlsVerify", strconv.FormatBool(val))
+ if options.SkipTLSVerify != types.OptionalBoolUndefined {
+ // Note: we have to verify if skipped is false.
+ verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse)
+ params.Set("tlsVerify", strconv.FormatBool(verifyTLS))
}
params.Set("allTags", strconv.FormatBool(options.AllTags))
- response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params)
+ // TODO: have a global system context we can pass around (1st argument)
+ header, err := auth.Header(nil, options.Authfile, options.Username, options.Password)
+ if err != nil {
+ return nil, err
+ }
+
+ response, err := conn.DoRequest(nil, http.MethodPost, "/images/pull", params, header)
if err != nil {
return nil, err
}
@@ -307,17 +403,28 @@ func Push(ctx context.Context, source string, destination string, options entiti
if err != nil {
return err
}
+
+ // TODO: have a global system context we can pass around (1st argument)
+ header, err := auth.Header(nil, options.Authfile, options.Username, options.Password)
+ if err != nil {
+ return err
+ }
+
params := url.Values{}
- params.Set("credentials", options.Credentials)
params.Set("destination", destination)
- if options.TLSVerify != types.OptionalBoolUndefined {
- val := bool(options.TLSVerify == types.OptionalBoolTrue)
- params.Set("tlsVerify", strconv.FormatBool(val))
+ if options.SkipTLSVerify != types.OptionalBoolUndefined {
+ // Note: we have to verify if skipped is false.
+ verifyTLS := bool(options.SkipTLSVerify == types.OptionalBoolFalse)
+ params.Set("tlsVerify", strconv.FormatBool(verifyTLS))
}
path := fmt.Sprintf("/images/%s/push", source)
- _, err = conn.DoRequest(nil, http.MethodPost, path, params)
- return err
+ response, err := conn.DoRequest(nil, http.MethodPost, path, params, header)
+ if err != nil {
+ return err
+ }
+
+ return response.Process(err)
}
// Search is the binding for libpod's v2 endpoints for Search images.
@@ -333,12 +440,19 @@ func Search(ctx context.Context, term string, opts entities.ImageSearchOptions)
params.Set("filters", f)
}
- if opts.TLSVerify != types.OptionalBoolUndefined {
- val := bool(opts.TLSVerify == types.OptionalBoolTrue)
- params.Set("tlsVerify", strconv.FormatBool(val))
+ if opts.SkipTLSVerify != types.OptionalBoolUndefined {
+ // Note: we have to verify if skipped is false.
+ verifyTLS := bool(opts.SkipTLSVerify == types.OptionalBoolFalse)
+ params.Set("tlsVerify", strconv.FormatBool(verifyTLS))
+ }
+
+ // TODO: have a global system context we can pass around (1st argument)
+ header, err := auth.Header(nil, opts.Authfile, "", "")
+ if err != nil {
+ return nil, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/images/search", params)
+ response, err := conn.DoRequest(nil, http.MethodGet, "/images/search", params, header)
if err != nil {
return nil, err
}