mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
87
cmd/podmanV2/images/import.go
Normal file
87
cmd/podmanV2/images/import.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package images
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podmanV2/parse"
|
||||||
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
importDescription = `Create a container image from the contents of the specified tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz).
|
||||||
|
|
||||||
|
Note remote tar balls can be specified, via web address.
|
||||||
|
Optionally tag the image. You can specify the instructions using the --change option.`
|
||||||
|
importCommand = &cobra.Command{
|
||||||
|
Use: "import [flags] PATH [REFERENCE]",
|
||||||
|
Short: "Import a tarball to create a filesystem image",
|
||||||
|
Long: importDescription,
|
||||||
|
RunE: importCon,
|
||||||
|
PersistentPreRunE: preRunE,
|
||||||
|
Example: `podman import http://example.com/ctr.tar url-image
|
||||||
|
cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported
|
||||||
|
cat ctr.tar | podman import -`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
importOpts entities.ImageImportOptions
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
|
Command: importCommand,
|
||||||
|
})
|
||||||
|
|
||||||
|
importCommand.SetHelpTemplate(registry.HelpTemplate())
|
||||||
|
importCommand.SetUsageTemplate(registry.UsageTemplate())
|
||||||
|
flags := importCommand.Flags()
|
||||||
|
flags.StringArrayVarP(&importOpts.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR")
|
||||||
|
flags.StringVarP(&importOpts.Message, "message", "m", "", "Set commit message for imported image")
|
||||||
|
flags.BoolVarP(&importOpts.Quiet, "quiet", "q", false, "Suppress output")
|
||||||
|
}
|
||||||
|
|
||||||
|
func importCon(cmd *cobra.Command, args []string) error {
|
||||||
|
var (
|
||||||
|
source string
|
||||||
|
reference string
|
||||||
|
)
|
||||||
|
switch len(args) {
|
||||||
|
case 0:
|
||||||
|
return errors.Errorf("need to give the path to the tarball, or must specify a tarball of '-' for stdin")
|
||||||
|
case 1:
|
||||||
|
source = args[0]
|
||||||
|
case 2:
|
||||||
|
source = args[0]
|
||||||
|
// TODO when save is merged, we need to process reference
|
||||||
|
// like it is done in there or we end up with docker.io prepends
|
||||||
|
// instead of the localhost ones
|
||||||
|
reference = args[1]
|
||||||
|
default:
|
||||||
|
return errors.Errorf("too many arguments. Usage TARBALL [REFERENCE]")
|
||||||
|
}
|
||||||
|
errFileName := parse.ValidateFileName(source)
|
||||||
|
errURL := parse.ValidURL(source)
|
||||||
|
if errURL == nil {
|
||||||
|
importOpts.SourceIsURL = true
|
||||||
|
}
|
||||||
|
if errFileName != nil && errURL != nil {
|
||||||
|
return multierror.Append(errFileName, errURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
importOpts.Source = source
|
||||||
|
importOpts.Reference = reference
|
||||||
|
|
||||||
|
response, err := registry.ImageEngine().Import(context.Background(), importOpts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(response.Id)
|
||||||
|
return nil
|
||||||
|
}
|
@ -300,7 +300,7 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.WriteResponse(w, http.StatusOK, handlers.LibpodImagesImportReport{ID: importedImage})
|
utils.WriteResponse(w, http.StatusOK, entities.ImageImportReport{Id: importedImage})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImagesPull is the v2 libpod endpoint for pulling images. Note that the
|
// ImagesPull is the v2 libpod endpoint for pulling images. Note that the
|
||||||
|
@ -38,7 +38,7 @@ type swagLibpodImagesLoadResponse struct {
|
|||||||
// swagger:response DocsLibpodImagesImportResponse
|
// swagger:response DocsLibpodImagesImportResponse
|
||||||
type swagLibpodImagesImportResponse struct {
|
type swagLibpodImagesImportResponse struct {
|
||||||
// in:body
|
// in:body
|
||||||
Body LibpodImagesImportReport
|
Body entities.ImageImportReport
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull response
|
// Pull response
|
||||||
|
@ -38,10 +38,6 @@ type LibpodImagesLoadReport struct {
|
|||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LibpodImagesImportReport struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type LibpodImagesPullReport struct {
|
type LibpodImagesPullReport struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
}
|
}
|
||||||
|
@ -217,14 +217,14 @@ func Build(nameOrId string) {}
|
|||||||
// Imports adds the given image to the local image store. This can be done by file and the given reader
|
// 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
|
// or via the url parameter. Additional metadata can be associated with the image by using the changes and
|
||||||
// message parameters. The image can also be tagged given a reference. One of url OR r must be provided.
|
// message parameters. The image can also be tagged given a reference. One of url OR r must be provided.
|
||||||
func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (string, error) {
|
func Import(ctx context.Context, changes []string, message, reference, u *string, r io.Reader) (*entities.ImageImportReport, error) {
|
||||||
var id handlers.IDResponse
|
var report entities.ImageImportReport
|
||||||
if r != nil && u != nil {
|
if r != nil && u != nil {
|
||||||
return "", errors.New("url and r parameters cannot be used together")
|
return nil, errors.New("url and r parameters cannot be used together")
|
||||||
}
|
}
|
||||||
conn, err := bindings.GetClient(ctx)
|
conn, err := bindings.GetClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
for _, change := range changes {
|
for _, change := range changes {
|
||||||
@ -241,9 +241,9 @@ func Import(ctx context.Context, changes []string, message, reference, u *string
|
|||||||
}
|
}
|
||||||
response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params)
|
response, err := conn.DoRequest(r, http.MethodPost, "/images/import", params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
return id.ID, response.Process(&id)
|
return &report, response.Process(&report)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull is the binding for libpod's v2 endpoints for pulling images. Note that
|
// Pull is the binding for libpod's v2 endpoints for pulling images. Note that
|
||||||
|
@ -15,4 +15,5 @@ type ImageEngine interface {
|
|||||||
Tag(ctx context.Context, nameOrId string, tags []string, options ImageTagOptions) error
|
Tag(ctx context.Context, nameOrId string, tags []string, options ImageTagOptions) error
|
||||||
Untag(ctx context.Context, nameOrId string, tags []string, options ImageUntagOptions) error
|
Untag(ctx context.Context, nameOrId string, tags []string, options ImageUntagOptions) error
|
||||||
Load(ctx context.Context, opts ImageLoadOptions) (*ImageLoadReport, error)
|
Load(ctx context.Context, opts ImageLoadOptions) (*ImageLoadReport, error)
|
||||||
|
Import(ctx context.Context, opts ImageImportOptions) (*ImageImportReport, error)
|
||||||
}
|
}
|
||||||
|
@ -184,3 +184,16 @@ type ImageLoadOptions struct {
|
|||||||
type ImageLoadReport struct {
|
type ImageLoadReport struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageImportOptions struct {
|
||||||
|
Changes []string
|
||||||
|
Message string
|
||||||
|
Quiet bool
|
||||||
|
Reference string
|
||||||
|
Source string
|
||||||
|
SourceIsURL bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageImportReport struct {
|
||||||
|
Id string
|
||||||
|
}
|
||||||
|
@ -303,6 +303,7 @@ func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string,
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
|
func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
|
||||||
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
|
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -336,3 +337,11 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions)
|
|||||||
}
|
}
|
||||||
return &entities.ImageLoadReport{Name: name}, nil
|
return &entities.ImageLoadReport{Name: name}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
|
||||||
|
id, err := ir.Libpod.Import(ctx, opts.Source, opts.Reference, opts.Changes, opts.Message, opts.Quiet)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &entities.ImageImportReport{Id: id}, nil
|
||||||
|
}
|
||||||
|
@ -167,3 +167,20 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions)
|
|||||||
defer f.Close()
|
defer f.Close()
|
||||||
return images.Load(ir.ClientCxt, f, &opts.Name)
|
return images.Load(ir.ClientCxt, f, &opts.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
sourceURL *string
|
||||||
|
f *os.File
|
||||||
|
)
|
||||||
|
if opts.SourceIsURL {
|
||||||
|
sourceURL = &opts.Source
|
||||||
|
} else {
|
||||||
|
f, err = os.Open(opts.Source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return images.Import(ir.ClientCxt, opts.Changes, &opts.Message, &opts.Reference, sourceURL, f)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user