mirror of
https://github.com/containers/podman.git
synced 2025-05-29 22:46:25 +08:00
Merge pull request #5656 from baude/v2imagetag
podman v2 image tag and untag
This commit is contained in:
34
cmd/podmanV2/images/tag.go
Normal file
34
cmd/podmanV2/images/tag.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package images
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
tagDescription = "Adds one or more additional names to locally-stored image."
|
||||||
|
tagCommand = &cobra.Command{
|
||||||
|
Use: "tag [flags] IMAGE TARGET_NAME [TARGET_NAME...]",
|
||||||
|
Short: "Add an additional name to a local image",
|
||||||
|
Long: tagDescription,
|
||||||
|
RunE: tag,
|
||||||
|
Args: cobra.MinimumNArgs(2),
|
||||||
|
Example: `podman tag 0e3bbc2 fedora:latest
|
||||||
|
podman tag imageID:latest myNewImage:newTag
|
||||||
|
podman tag httpd myregistryhost:5000/fedora/httpd:v2`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
|
Command: tagCommand,
|
||||||
|
})
|
||||||
|
tagCommand.SetHelpTemplate(registry.HelpTemplate())
|
||||||
|
tagCommand.SetUsageTemplate(registry.UsageTemplate())
|
||||||
|
}
|
||||||
|
|
||||||
|
func tag(cmd *cobra.Command, args []string) error {
|
||||||
|
return registry.ImageEngine().Tag(registry.GetContext(), args[0], args[1:], entities.ImageTagOptions{})
|
||||||
|
}
|
33
cmd/podmanV2/images/untag.go
Normal file
33
cmd/podmanV2/images/untag.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package images
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
untagCommand = &cobra.Command{
|
||||||
|
Use: "untag [flags] IMAGE [NAME...]",
|
||||||
|
Short: "Remove a name from a local image",
|
||||||
|
Long: "Removes one or more names from a locally-stored image.",
|
||||||
|
RunE: untag,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Example: `podman untag 0e3bbc2
|
||||||
|
podman untag imageID:latest otherImageName:latest
|
||||||
|
podman untag httpd myregistryhost:5000/fedora/httpd:v2`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
|
Command: untagCommand,
|
||||||
|
})
|
||||||
|
untagCommand.SetHelpTemplate(registry.HelpTemplate())
|
||||||
|
untagCommand.SetUsageTemplate(registry.UsageTemplate())
|
||||||
|
}
|
||||||
|
|
||||||
|
func untag(cmd *cobra.Command, args []string) error {
|
||||||
|
return registry.ImageEngine().Untag(registry.GetContext(), args[0], args[1:], entities.ImageUntagOptions{})
|
||||||
|
}
|
@ -510,3 +510,29 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: commitImage.ID()}) // nolint
|
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: commitImage.ID()}) // nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UntagImage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
|
|
||||||
|
name := utils.GetName(r)
|
||||||
|
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
|
||||||
|
if err != nil {
|
||||||
|
utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tag := "latest"
|
||||||
|
if len(r.Form.Get("tag")) > 0 {
|
||||||
|
tag = r.Form.Get("tag")
|
||||||
|
}
|
||||||
|
if len(r.Form.Get("repo")) < 1 {
|
||||||
|
utils.Error(w, "repo tag is required", http.StatusBadRequest, errors.New("repo parameter is required to tag an image"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
repo := r.Form.Get("repo")
|
||||||
|
tagName := fmt.Sprintf("%s:%s", repo, tag)
|
||||||
|
if err := newImage.UntagImage(tagName); err != nil {
|
||||||
|
utils.Error(w, "failed to untag", http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
utils.WriteResponse(w, http.StatusCreated, "")
|
||||||
|
}
|
||||||
|
@ -1019,5 +1019,39 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
|
|||||||
// 500:
|
// 500:
|
||||||
// $ref: '#/responses/InternalError'
|
// $ref: '#/responses/InternalError'
|
||||||
r.Handle(VersionedPath("/libpod/commit"), s.APIHandler(libpod.CommitContainer)).Methods(http.MethodPost)
|
r.Handle(VersionedPath("/libpod/commit"), s.APIHandler(libpod.CommitContainer)).Methods(http.MethodPost)
|
||||||
|
// swagger:operation POST /libpod/images/{name:.*}/untag libpod libpodUntagImage
|
||||||
|
// ---
|
||||||
|
// tags:
|
||||||
|
// - images
|
||||||
|
// summary: Untag an image
|
||||||
|
// description: Untag an image
|
||||||
|
// parameters:
|
||||||
|
// - in: path
|
||||||
|
// name: name:.*
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// description: the name or ID of the container
|
||||||
|
// - in: query
|
||||||
|
// name: repo
|
||||||
|
// type: string
|
||||||
|
// description: the repository to untag
|
||||||
|
// - in: query
|
||||||
|
// name: tag
|
||||||
|
// type: string
|
||||||
|
// description: the name of the tag to untag
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// responses:
|
||||||
|
// 201:
|
||||||
|
// description: no error
|
||||||
|
// 400:
|
||||||
|
// $ref: '#/responses/BadParamError'
|
||||||
|
// 404:
|
||||||
|
// $ref: '#/responses/NoSuchImage'
|
||||||
|
// 409:
|
||||||
|
// $ref: '#/responses/ConflictError'
|
||||||
|
// 500:
|
||||||
|
// $ref: '#/responses/InternalError'
|
||||||
|
r.Handle(VersionedPath("/libpod/images/{name:.*}/untag"), s.APIHandler(libpod.UntagImage)).Methods(http.MethodPost)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,22 @@ func Tag(ctx context.Context, nameOrID, tag, repo string) error {
|
|||||||
return response.Process(nil)
|
return response.Process(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Untag removes a name from locally-stored image. Both the tag and repo parameters are required.
|
||||||
|
func Untag(ctx context.Context, nameOrID, tag, repo string) error {
|
||||||
|
conn, err := bindings.GetClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params := url.Values{}
|
||||||
|
params.Set("tag", tag)
|
||||||
|
params.Set("repo", repo)
|
||||||
|
response, err := conn.DoRequest(nil, http.MethodPost, "/images/%s/untag", params, nameOrID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return response.Process(nil)
|
||||||
|
}
|
||||||
|
|
||||||
func Build(nameOrId string) {}
|
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
|
||||||
|
@ -11,4 +11,6 @@ type ImageEngine interface {
|
|||||||
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
|
List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error)
|
||||||
Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error)
|
Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error)
|
||||||
Pull(ctx context.Context, rawImage string, opts ImagePullOptions) (*ImagePullReport, error)
|
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
|
||||||
}
|
}
|
||||||
|
@ -171,3 +171,6 @@ type ImagePruneReport struct {
|
|||||||
Report Report
|
Report Report
|
||||||
Size int64
|
Size int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ImageTagOptions struct{}
|
||||||
|
type ImageUntagOptions struct{}
|
||||||
|
@ -264,3 +264,28 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
|
|||||||
// copy(report.Report.Id, id)
|
// copy(report.Report.Id, id)
|
||||||
// return &report, nil
|
// return &report, nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, options entities.ImageTagOptions) error {
|
||||||
|
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, tag := range tags {
|
||||||
|
if err := newImage.TagImage(tag); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
|
||||||
|
newImage, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, tag := range tags {
|
||||||
|
if err := newImage.UntagImage(tag); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -3,9 +3,11 @@ package tunnel
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/containers/image/v5/docker/reference"
|
||||||
images "github.com/containers/libpod/pkg/bindings/images"
|
images "github.com/containers/libpod/pkg/bindings/images"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
"github.com/containers/libpod/pkg/domain/utils"
|
"github.com/containers/libpod/pkg/domain/utils"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
|
func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
|
||||||
@ -93,3 +95,53 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti
|
|||||||
}
|
}
|
||||||
return &entities.ImagePullReport{Images: pulledImages}, nil
|
return &entities.ImagePullReport{Images: pulledImages}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, options entities.ImageTagOptions) error {
|
||||||
|
for _, newTag := range tags {
|
||||||
|
var (
|
||||||
|
tag, repo string
|
||||||
|
)
|
||||||
|
ref, err := reference.Parse(newTag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if t, ok := ref.(reference.Tagged); ok {
|
||||||
|
tag = t.Tag()
|
||||||
|
}
|
||||||
|
if r, ok := ref.(reference.Named); ok {
|
||||||
|
repo = r.Name()
|
||||||
|
}
|
||||||
|
if len(repo) < 1 {
|
||||||
|
return errors.Errorf("invalid image name %q", nameOrId)
|
||||||
|
}
|
||||||
|
if err := images.Tag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
|
||||||
|
for _, newTag := range tags {
|
||||||
|
var (
|
||||||
|
tag, repo string
|
||||||
|
)
|
||||||
|
ref, err := reference.Parse(newTag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if t, ok := ref.(reference.Tagged); ok {
|
||||||
|
tag = t.Tag()
|
||||||
|
}
|
||||||
|
if r, ok := ref.(reference.Named); ok {
|
||||||
|
repo = r.Name()
|
||||||
|
}
|
||||||
|
if len(repo) < 1 {
|
||||||
|
return errors.Errorf("invalid image name %q", nameOrId)
|
||||||
|
}
|
||||||
|
if err := images.Untag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user