Merge pull request #5656 from baude/v2imagetag

podman v2 image tag and untag
This commit is contained in:
OpenShift Merge Robot
2020-04-01 16:10:10 +02:00
committed by GitHub
9 changed files with 225 additions and 0 deletions

View 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{})
}

View 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{})
}

View File

@ -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, "")
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -171,3 +171,6 @@ type ImagePruneReport struct {
Report Report
Size int64
}
type ImageTagOptions struct{}
type ImageUntagOptions struct{}

View File

@ -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
}

View File

@ -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
}