mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #19266 from tonistiigi/fix-untag-on-rmi-by-id
Fix rmi by ID untagging image on error
This commit is contained in:
commit
1e1a3c9508
2 changed files with 26 additions and 5 deletions
|
@ -128,6 +128,10 @@ func (daemon *Daemon) ImageDelete(imageRef string, force, prune bool) ([]types.I
|
|||
// remove that reference.
|
||||
// FIXME: Is this the behavior we want?
|
||||
if len(repoRefs) == 1 {
|
||||
if conflict := daemon.checkImageDeleteConflict(imgID, force, true); conflict != nil {
|
||||
return nil, conflict
|
||||
}
|
||||
|
||||
parsedRef, err := daemon.removeImageRef(repoRefs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -241,7 +245,7 @@ func (idc *imageDeleteConflict) Error() string {
|
|||
func (daemon *Daemon) imageDeleteHelper(imgID image.ID, records *[]types.ImageDelete, force, prune, quiet bool) error {
|
||||
// First, determine if this image has any conflicts. Ignore soft conflicts
|
||||
// if force is true.
|
||||
if conflict := daemon.checkImageDeleteConflict(imgID, force); conflict != nil {
|
||||
if conflict := daemon.checkImageDeleteConflict(imgID, force, false); conflict != nil {
|
||||
if quiet && (!daemon.imageIsDangling(imgID) || conflict.used) {
|
||||
// Ignore conflicts UNLESS the image is "dangling" or not being used in
|
||||
// which case we want the user to know.
|
||||
|
@ -293,7 +297,7 @@ func (daemon *Daemon) imageDeleteHelper(imgID image.ID, records *[]types.ImageDe
|
|||
// using the image. A soft conflict is any tags/digest referencing the given
|
||||
// image or any stopped container using the image. If ignoreSoftConflicts is
|
||||
// true, this function will not check for soft conflict conditions.
|
||||
func (daemon *Daemon) checkImageDeleteConflict(imgID image.ID, ignoreSoftConflicts bool) *imageDeleteConflict {
|
||||
func (daemon *Daemon) checkImageDeleteConflict(imgID image.ID, ignoreSoftConflicts bool, ignoreRefConflict bool) *imageDeleteConflict {
|
||||
// Check for hard conflicts first.
|
||||
if conflict := daemon.checkImageDeleteHardConflict(imgID); conflict != nil {
|
||||
return conflict
|
||||
|
@ -305,7 +309,7 @@ func (daemon *Daemon) checkImageDeleteConflict(imgID image.ID, ignoreSoftConflic
|
|||
return nil
|
||||
}
|
||||
|
||||
return daemon.checkImageDeleteSoftConflict(imgID)
|
||||
return daemon.checkImageDeleteSoftConflict(imgID, ignoreRefConflict)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) checkImageDeleteHardConflict(imgID image.ID) *imageDeleteConflict {
|
||||
|
@ -338,9 +342,9 @@ func (daemon *Daemon) checkImageDeleteHardConflict(imgID image.ID) *imageDeleteC
|
|||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) checkImageDeleteSoftConflict(imgID image.ID) *imageDeleteConflict {
|
||||
func (daemon *Daemon) checkImageDeleteSoftConflict(imgID image.ID, ignoreRefConflict bool) *imageDeleteConflict {
|
||||
// Check if any repository tags/digest reference this image.
|
||||
if len(daemon.referenceStore.References(imgID)) > 0 {
|
||||
if !ignoreRefConflict && len(daemon.referenceStore.References(imgID)) > 0 {
|
||||
return &imageDeleteConflict{
|
||||
imgID: imgID,
|
||||
message: "image is referenced in one or more repositories",
|
||||
|
|
|
@ -337,3 +337,20 @@ func (s *DockerSuite) TestRmiWithParentInUse(c *check.C) {
|
|||
|
||||
dockerCmd(c, "rmi", imageID)
|
||||
}
|
||||
|
||||
// #18873
|
||||
func (s *DockerSuite) TestRmiByIDHardConflict(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
dockerCmd(c, "create", "busybox")
|
||||
|
||||
imgID, err := inspectField("busybox:latest", "Id")
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
_, _, err = dockerCmdWithError("rmi", imgID[:12])
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
// check that tag was not removed
|
||||
imgID2, err := inspectField("busybox:latest", "Id")
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(imgID, checker.Equals, imgID2)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue