mirror of
https://github.com/containers/podman.git
synced 2025-06-24 03:08:13 +08:00
Merge pull request #4712 from openSUSE/untag-command
Add `untag` sub-command
This commit is contained in:
10
API.md
10
API.md
@ -185,6 +185,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
|
||||
|
||||
[func UnpausePod(name: string) string](#UnpausePod)
|
||||
|
||||
[func UntagImage(name: string, tag: string) string](#UntagImage)
|
||||
|
||||
[func VolumeCreate(options: VolumeCreateOpts) string](#VolumeCreate)
|
||||
|
||||
[func VolumeRemove(options: VolumeRemoveOpts) []string, map[string]](#VolumeRemove)
|
||||
@ -1234,6 +1236,14 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.UnpausePod '{"name": "foo
|
||||
"pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f"
|
||||
}
|
||||
~~~
|
||||
### <a name="UntagImage"></a>func UntagImage
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
method UntagImage(name: [string](https://godoc.org/builtin#string), tag: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
|
||||
UntagImage takes the name or ID of an image in local storage as well as the
|
||||
tag name to be removed. If the image cannot be found, an
|
||||
[ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of
|
||||
the image is returned on success.
|
||||
### <a name="VolumeCreate"></a>func VolumeCreate
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
|
@ -681,3 +681,7 @@ type SystemDfValues struct {
|
||||
Verbose bool
|
||||
Format string
|
||||
}
|
||||
|
||||
type UntagValues struct {
|
||||
PodmanCommand
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ var imageSubCommands = []*cobra.Command{
|
||||
_saveCommand,
|
||||
_tagCommand,
|
||||
_treeCommand,
|
||||
_untagCommand,
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -68,6 +68,7 @@ var mainCommands = []*cobra.Command{
|
||||
imageCommand.Command,
|
||||
_startCommand,
|
||||
systemCommand.Command,
|
||||
_untagCommand,
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
|
67
cmd/podman/untag.go
Normal file
67
cmd/podman/untag.go
Normal file
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/pkg/adapter"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
untagCommand cliconfig.UntagValues
|
||||
|
||||
_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: func(cmd *cobra.Command, args []string) error {
|
||||
untagCommand.InputArgs = args
|
||||
untagCommand.GlobalFlags = MainGlobalOpts
|
||||
untagCommand.Remote = remoteclient
|
||||
return untag(&untagCommand)
|
||||
},
|
||||
Example: `podman untag 0e3bbc2
|
||||
podman untag imageID:latest otherImageName:latest
|
||||
podman untag httpd myregistryhost:5000/fedora/httpd:v2`,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
untagCommand.Command = _untagCommand
|
||||
untagCommand.SetHelpTemplate(HelpTemplate())
|
||||
untagCommand.SetUsageTemplate(UsageTemplate())
|
||||
}
|
||||
|
||||
func untag(c *cliconfig.UntagValues) error {
|
||||
args := c.InputArgs
|
||||
|
||||
if len(args) == 0 {
|
||||
return errors.Errorf("at least one image name needs to be specified")
|
||||
}
|
||||
|
||||
runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not create runtime")
|
||||
}
|
||||
defer runtime.DeferredShutdown(false)
|
||||
|
||||
newImage, err := runtime.NewImageFromLocal(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tags := args[1:]
|
||||
if len(args) == 1 {
|
||||
// Remove all tags if not explicitly specified
|
||||
tags = newImage.Names()
|
||||
}
|
||||
logrus.Debugf("Tags to be removed: %v", tags)
|
||||
|
||||
for _, tag := range tags {
|
||||
if err := newImage.UntagImage(tag); err != nil {
|
||||
return errors.Wrapf(err, "removing %q from %q", tag, newImage.InputName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -860,6 +860,12 @@ method PushImage(name: string, tag: string, compress: bool, format: string, remo
|
||||
# be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of the image is returned on success.
|
||||
method TagImage(name: string, tagged: string) -> (image: string)
|
||||
|
||||
# UntagImage takes the name or ID of an image in local storage as well as the
|
||||
# tag name to be removed. If the image cannot be found, an
|
||||
# [ImageNotFound](#ImageNotFound) error will be returned; otherwise, the ID of
|
||||
# the image is returned on success.
|
||||
method UntagImage(name: string, tag: string) -> (image: string)
|
||||
|
||||
# RemoveImage takes the name or ID of an image as well as a boolean that determines if containers using that image
|
||||
# should be deleted. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error will be returned. The
|
||||
# ID of the removed image is returned when complete. See also [DeleteUnusedImages](DeleteUnusedImages).
|
||||
|
1
docs/source/markdown/links/podman-image-untag.1
Normal file
1
docs/source/markdown/links/podman-image-untag.1
Normal file
@ -0,0 +1 @@
|
||||
.so man1/podman-untag.1
|
@ -27,6 +27,7 @@ The image command allows you to manage images
|
||||
| save | [podman-save(1)](podman-save.1.md) | Save an image to docker-archive or oci. |
|
||||
| sign | [podman-image-sign(1)](podman-image-sign.1.md) | Create a signature for an image. |
|
||||
| tag | [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. |
|
||||
| untag | [podman-untag(1)](podman-untag.1.md) | Removes one or more names from a locally-stored image. |
|
||||
| tree | [podman-image-tree(1)](podman-image-tree.1.md) | Prints layer hierarchy of an image in a tree format. |
|
||||
| trust | [podman-image-trust(1)](podman-image-trust.1.md)| Manage container registry image trust policy. |
|
||||
|
||||
|
37
docs/source/markdown/podman-untag.1.md
Normal file
37
docs/source/markdown/podman-untag.1.md
Normal file
@ -0,0 +1,37 @@
|
||||
% podman-untag(1)
|
||||
|
||||
## NAME
|
||||
podman\-untag - Removes one or more names from a locally-stored image
|
||||
|
||||
## SYNOPSIS
|
||||
**podman untag** *image*[:*tag*] [*target-names*[:*tag*]] [*options*]
|
||||
|
||||
**podman image untag** *image*[:*tag*] [target-names[:*tag*]] [*options*]
|
||||
|
||||
## DESCRIPTION
|
||||
Removes one or all names of an image. A name refers to the entire image name,
|
||||
including the optional *tag* after the `:`. If no target image names are
|
||||
specified, `untag` will remove all tags for the image at once.
|
||||
|
||||
## OPTIONS
|
||||
|
||||
**--help**, **-h**
|
||||
|
||||
Print usage statement
|
||||
|
||||
## EXAMPLES
|
||||
|
||||
```
|
||||
$ podman untag 0e3bbc2
|
||||
|
||||
$ podman untag imageName:latest otherImageName:latest
|
||||
|
||||
$ podman untag httpd myregistryhost:5000/fedora/httpd:v2
|
||||
```
|
||||
|
||||
|
||||
## SEE ALSO
|
||||
podman(1)
|
||||
|
||||
## HISTORY
|
||||
December 2019, Originally compiled by Sascha Grunert <sgrunert@suse.com>
|
@ -201,6 +201,7 @@ the exit codes follow the `chroot` standard, see below:
|
||||
| [podman-umount(1)](podman-umount.1.md) | Unmount a working container's root filesystem. |
|
||||
| [podman-unpause(1)](podman-unpause.1.md) | Unpause one or more containers. |
|
||||
| [podman-unshare(1)](podman-unshare.1.md) | Run a command inside of a modified user namespace. |
|
||||
| [podman-untag(1)](podman-untag.1.md) | Removes one or more names from a locally-stored image. |
|
||||
| [podman-varlink(1)](podman-varlink.1.md) | Runs the varlink backend interface. |
|
||||
| [podman-version(1)](podman-version.1.md) | Display the Podman version information. |
|
||||
| [podman-volume(1)](podman-volume.1.md) | Simple management tool for volumes. |
|
||||
|
@ -413,6 +413,12 @@ func (ci *ContainerImage) TagImage(tag string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// UntagImage removes a single tag from an image
|
||||
func (ci *ContainerImage) UntagImage(tag string) error {
|
||||
_, err := iopodman.UntagImage().Call(ci.Runtime.Conn, ci.ID(), tag)
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveImage calls varlink to remove an image
|
||||
func (r *LocalRuntime) RemoveImage(ctx context.Context, img *ContainerImage, force bool) (*image.ImageDeleteResponse, error) {
|
||||
ir := image.ImageDeleteResponse{}
|
||||
|
@ -450,6 +450,18 @@ func (i *LibpodAPI) TagImage(call iopodman.VarlinkCall, name, tag string) error
|
||||
return call.ReplyTagImage(newImage.ID())
|
||||
}
|
||||
|
||||
// UntagImage accepts an image name and tag as strings and removes the tag from the local store.
|
||||
func (i *LibpodAPI) UntagImage(call iopodman.VarlinkCall, name, tag string) error {
|
||||
newImage, err := i.Runtime.ImageRuntime().NewFromLocal(name)
|
||||
if err != nil {
|
||||
return call.ReplyImageNotFound(name, err.Error())
|
||||
}
|
||||
if err := newImage.UntagImage(tag); err != nil {
|
||||
return call.ReplyErrorOccurred(err.Error())
|
||||
}
|
||||
return call.ReplyUntagImage(newImage.ID())
|
||||
}
|
||||
|
||||
// RemoveImage accepts a image name or ID as a string and force bool to determine if it should
|
||||
// remove the image even if being used by stopped containers
|
||||
func (i *LibpodAPI) RemoveImage(call iopodman.VarlinkCall, name string, force bool) error {
|
||||
|
73
test/e2e/untag_test.go
Normal file
73
test/e2e/untag_test.go
Normal file
@ -0,0 +1,73 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/containers/libpod/test/utils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Podman untag", func() {
|
||||
var (
|
||||
tempdir string
|
||||
err error
|
||||
podmanTest *PodmanTestIntegration
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tempdir, err = CreateTempDirInTempDir()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
podmanTest = PodmanTestCreate(tempdir)
|
||||
podmanTest.Setup()
|
||||
podmanTest.RestoreAllArtifacts()
|
||||
|
||||
for _, tag := range []string{"test", "foo", "bar"} {
|
||||
session := podmanTest.PodmanNoCache([]string{"tag", ALPINE, tag})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
podmanTest.Cleanup()
|
||||
f := CurrentGinkgoTestDescription()
|
||||
processTestResult(f)
|
||||
|
||||
})
|
||||
|
||||
It("podman untag all", func() {
|
||||
session := podmanTest.PodmanNoCache([]string{"untag", ALPINE})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
results := podmanTest.PodmanNoCache([]string{"images", ALPINE})
|
||||
results.WaitWithDefaultTimeout()
|
||||
Expect(results.ExitCode()).To(Equal(0))
|
||||
Expect(results.OutputToStringArray()).To(HaveLen(1))
|
||||
})
|
||||
|
||||
It("podman untag single", func() {
|
||||
session := podmanTest.PodmanNoCache([]string{"untag", ALPINE, "localhost/test:latest"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
results := podmanTest.PodmanNoCache([]string{"images"})
|
||||
results.WaitWithDefaultTimeout()
|
||||
Expect(results.ExitCode()).To(Equal(0))
|
||||
Expect(results.OutputToStringArray()).To(HaveLen(5))
|
||||
Expect(results.LineInOuputStartsWith("docker.io/library/alpine")).To(BeTrue())
|
||||
Expect(results.LineInOuputStartsWith("localhost/foo")).To(BeTrue())
|
||||
Expect(results.LineInOuputStartsWith("localhost/bar")).To(BeTrue())
|
||||
Expect(results.LineInOuputStartsWith("localhost/test")).To(BeFalse())
|
||||
})
|
||||
|
||||
It("podman untag not enough arguments", func() {
|
||||
session := podmanTest.PodmanNoCache([]string{"untag"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).NotTo(Equal(0))
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user