diff options
author | Brent Baude <bbaude@redhat.com> | 2020-03-31 12:59:08 -0500 |
---|---|---|
committer | Brent Baude <bbaude@redhat.com> | 2020-04-01 14:10:57 -0500 |
commit | 8500ce6b9ab0050b925ec3b899495cb2cc8d367f (patch) | |
tree | 554448ea6140ef2a2814fe44b41b5da6f86b06f3 | |
parent | d534e524272121a6489c1a2a2c11c6b389027ecd (diff) | |
download | podman-8500ce6b9ab0050b925ec3b899495cb2cc8d367f.tar.gz podman-8500ce6b9ab0050b925ec3b899495cb2cc8d367f.tar.bz2 podman-8500ce6b9ab0050b925ec3b899495cb2cc8d367f.zip |
podmanv2 load
enable podman load for v2
add reexec into main
add systemd build flag to v2 makefile
Signed-off-by: Brent Baude <bbaude@redhat.com>
-rw-r--r-- | cmd/podmanV2/Makefile | 2 | ||||
-rw-r--r-- | cmd/podmanV2/images/load.go | 61 | ||||
-rw-r--r-- | cmd/podmanV2/main.go | 6 | ||||
-rw-r--r-- | libpod/image/image.go | 6 | ||||
-rw-r--r-- | libpod/image/image_test.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/swagger.go | 2 | ||||
-rw-r--r-- | pkg/bindings/images/images.go | 10 | ||||
-rw-r--r-- | pkg/bindings/test/images_test.go | 4 | ||||
-rw-r--r-- | pkg/domain/entities/engine_image.go | 1 | ||||
-rw-r--r-- | pkg/domain/entities/images.go | 12 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 21 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 10 |
13 files changed, 125 insertions, 14 deletions
diff --git a/cmd/podmanV2/Makefile b/cmd/podmanV2/Makefile index 147a78d9c..f2f7bd73c 100644 --- a/cmd/podmanV2/Makefile +++ b/cmd/podmanV2/Makefile @@ -1,2 +1,2 @@ all: - GO111MODULE=off go build -tags 'ABISupport' + GO111MODULE=off go build -tags 'ABISupport systemd' diff --git a/cmd/podmanV2/images/load.go b/cmd/podmanV2/images/load.go new file mode 100644 index 000000000..f60dc4908 --- /dev/null +++ b/cmd/podmanV2/images/load.go @@ -0,0 +1,61 @@ +package images + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/spf13/cobra" +) + +var ( + loadDescription = "Loads an image from a locally stored archive (tar file) into container storage." + loadCommand = &cobra.Command{ + Use: "load [flags] [NAME[:TAG]]", + Short: "Load an image from container archive", + Long: loadDescription, + RunE: load, + Args: cobra.MaximumNArgs(1), + PersistentPreRunE: preRunE, + } +) + +var ( + loadOpts entities.ImageLoadOptions +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: loadCommand, + }) + + loadCommand.SetHelpTemplate(registry.HelpTemplate()) + loadCommand.SetUsageTemplate(registry.UsageTemplate()) + flags := loadCommand.Flags() + flags.StringVarP(&loadOpts.Input, "input", "i", "", "Read from specified archive file (default: stdin)") + flags.BoolVarP(&loadOpts.Quiet, "quiet", "q", false, "Suppress the output") + flags.StringVar(&loadOpts.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file") + if registry.IsRemote() { + _ = flags.MarkHidden("signature-policy") + } + +} + +func load(cmd *cobra.Command, args []string) error { + if len(args) > 0 { + repo, err := image.NormalizedTag(args[0]) + if err != nil { + return err + } + loadOpts.Name = repo.Name() + } + response, err := registry.ImageEngine().Load(context.Background(), loadOpts) + if err != nil { + return err + } + fmt.Println("Loaded image: " + response.Name) + return nil +} diff --git a/cmd/podmanV2/main.go b/cmd/podmanV2/main.go index e4daabb66..6781a7f06 100644 --- a/cmd/podmanV2/main.go +++ b/cmd/podmanV2/main.go @@ -15,6 +15,7 @@ import ( _ "github.com/containers/libpod/cmd/podmanV2/volumes" "github.com/containers/libpod/libpod" "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/storage/pkg/reexec" "github.com/sirupsen/logrus" ) @@ -45,6 +46,11 @@ func init() { } func main() { + if reexec.Init() { + // We were invoked with a different argv[0] indicating that we + // had a specific job to do as a subprocess, and it's done. + return + } for _, c := range registry.Commands { if Contains(registry.EngineOptions.EngineMode, c.Mode) { parent := rootCmd diff --git a/libpod/image/image.go b/libpod/image/image.go index 5f914ed79..80cc6f15a 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -512,8 +512,8 @@ func getImageDigest(ctx context.Context, src types.ImageReference, sc *types.Sys return "@" + imageDigest.Hex(), nil } -// normalizedTag returns the canonical version of tag for use in Image.Names() -func normalizedTag(tag string) (reference.Named, error) { +// NormalizedTag returns the canonical version of tag for use in Image.Names() +func NormalizedTag(tag string) (reference.Named, error) { decomposedTag, err := decompose(tag) if err != nil { return nil, err @@ -541,7 +541,7 @@ func (i *Image) TagImage(tag string) error { if err := i.reloadImage(); err != nil { return err } - ref, err := normalizedTag(tag) + ref, err := NormalizedTag(tag) if err != nil { return err } diff --git a/libpod/image/image_test.go b/libpod/image/image_test.go index 19f7eee1e..3cd368cdc 100644 --- a/libpod/image/image_test.go +++ b/libpod/image/image_test.go @@ -292,7 +292,7 @@ func TestNormalizedTag(t *testing.T) { {"ns/busybox:latest", "localhost/ns/busybox:latest"}, // Unqualified with a dot-less namespace {"docker.io/busybox:latest", "docker.io/library/busybox:latest"}, // docker.io without /library/ } { - res, err := normalizedTag(c.input) + res, err := NormalizedTag(c.input) if c.expected == "" { assert.Error(t, err, c.input) } else { diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index bc227d9a1..19c6102be 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -254,7 +254,7 @@ func ImagesLoad(w http.ResponseWriter, r *http.Request) { return } } - utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesLoadReport{ID: loadedImage}) + utils.WriteResponse(w, http.StatusOK, entities.ImageLoadReport{Name: loadedImage}) } func ImagesImport(w http.ResponseWriter, r *http.Request) { diff --git a/pkg/api/handlers/swagger.go b/pkg/api/handlers/swagger.go index 52763a050..12de3a3bd 100644 --- a/pkg/api/handlers/swagger.go +++ b/pkg/api/handlers/swagger.go @@ -31,7 +31,7 @@ type swagImageInspect struct { // swagger:response DocsLibpodImagesLoadResponse type swagLibpodImagesLoadResponse struct { // in:body - Body []LibpodImagesLoadReport + Body entities.ImageLoadReport } // Import response diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index ddc67bebc..6c739494b 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -91,11 +91,11 @@ func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse, return history, response.Process(&history) } -func Load(ctx context.Context, r io.Reader, name *string) (string, error) { - var id handlers.IDResponse +func Load(ctx context.Context, r io.Reader, name *string) (*entities.ImageLoadReport, error) { + var report entities.ImageLoadReport conn, err := bindings.GetClient(ctx) if err != nil { - return "", err + return nil, err } params := url.Values{} if name != nil { @@ -103,9 +103,9 @@ func Load(ctx context.Context, r io.Reader, name *string) (string, error) { } response, err := conn.DoRequest(r, http.MethodPost, "/images/load", params) if err != nil { - return "", err + return nil, err } - return id.ID, response.Process(&id) + return &report, response.Process(&report) } // Remove deletes an image from local storage. The optional force parameter will forcibly remove diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index dc01a793b..992720196 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -219,7 +219,7 @@ var _ = Describe("Podman images", func() { Expect(err).To(BeNil()) names, err := images.Load(bt.conn, f, nil) Expect(err).To(BeNil()) - Expect(names).To(Equal(alpine.name)) + Expect(names.Name).To(Equal(alpine.name)) exists, err = images.Exists(bt.conn, alpine.name) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) @@ -235,7 +235,7 @@ var _ = Describe("Podman images", func() { newName := "quay.io/newname:fizzle" names, err = images.Load(bt.conn, f, &newName) Expect(err).To(BeNil()) - Expect(names).To(Equal(alpine.name)) + Expect(names.Name).To(Equal(alpine.name)) exists, err = images.Exists(bt.conn, newName) Expect(err).To(BeNil()) Expect(exists).To(BeTrue()) diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go index 2ca48e795..4cc2a67b9 100644 --- a/pkg/domain/entities/engine_image.go +++ b/pkg/domain/entities/engine_image.go @@ -14,4 +14,5 @@ type ImageEngine interface { Pull(ctx context.Context, rawImage string, opts ImagePullOptions) (*ImagePullReport, error) Tag(ctx context.Context, nameOrId string, tags []string, options ImageTagOptions) error Untag(ctx context.Context, nameOrId string, tags []string, options ImageUntagOptions) error + Load(ctx context.Context, opts ImageLoadOptions) (*ImageLoadReport, error) } diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 20682b05b..a6c7baebd 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -172,3 +172,15 @@ type ImageInspectReport struct { Images []*ImageData Errors map[string]error } + +type ImageLoadOptions struct { + Name string + Tag string + Input string + Quiet bool + SignaturePolicy string +} + +type ImageLoadReport struct { + Name string +} diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 5a7acb2f7..c3a2bb288 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -315,3 +315,24 @@ func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string } return nil } + +func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) { + var ( + writer io.Writer + ) + if !opts.Quiet { + writer = os.Stderr + } + name, err := ir.Libpod.LoadImage(ctx, opts.Name, opts.Input, writer, opts.SignaturePolicy) + if err != nil { + return nil, err + } + newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(name) + if err != nil { + return nil, errors.Wrap(err, "image loaded but no additional tags were created") + } + if err := newImage.TagImage(opts.Name); err != nil { + return nil, errors.Wrapf(err, "error adding %q to image %q", opts.Name, newImage.InputName) + } + return &entities.ImageLoadReport{Name: name}, nil +} diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 6a8b9be37..a4a0fccaf 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -2,6 +2,7 @@ package tunnel import ( "context" + "os" "github.com/containers/image/v5/docker/reference" images "github.com/containers/libpod/pkg/bindings/images" @@ -157,3 +158,12 @@ func (ir *ImageEngine) Inspect(_ context.Context, names []string, opts entities. } return &report, nil } + +func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) { + f, err := os.Open(opts.Input) + if err != nil { + return nil, err + } + defer f.Close() + return images.Load(ir.ClientCxt, f, &opts.Name) +} |