mirror of
https://github.com/containers/podman.git
synced 2025-05-28 13:40:33 +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
|
||||
}
|
||||
|
||||
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:
|
||||
// $ref: '#/responses/InternalError'
|
||||
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
|
||||
}
|
||||
|
@ -197,6 +197,22 @@ func Tag(ctx context.Context, nameOrID, tag, repo string) error {
|
||||
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) {}
|
||||
|
||||
// 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)
|
||||
Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, 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
|
||||
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)
|
||||
// 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 (
|
||||
"context"
|
||||
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
images "github.com/containers/libpod/pkg/bindings/images"
|
||||
"github.com/containers/libpod/pkg/domain/entities"
|
||||
"github.com/containers/libpod/pkg/domain/utils"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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