2014-09-09 20:32:14 -04:00
package main
import (
2015-04-22 17:12:46 -04:00
"fmt"
2014-09-09 20:32:14 -04:00
"os/exec"
"strings"
2015-04-18 12:46:47 -04:00
"github.com/go-check/check"
2014-09-09 20:32:14 -04:00
)
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiWithContainerFails ( c * check . C ) {
2014-09-09 20:32:14 -04:00
errSubstr := "is using it"
// create a container
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "run" , "-d" , "busybox" , "true" )
2014-10-14 16:09:19 -04:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "failed to create a container: %s, %v" , out , err )
2014-10-14 16:09:19 -04:00
}
2014-09-09 20:32:14 -04:00
2015-04-06 09:21:18 -04:00
cleanedContainerID := strings . TrimSpace ( out )
2014-09-09 20:32:14 -04:00
// try to delete the image
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "rmi" , "busybox" )
2014-09-09 20:32:14 -04:00
if err == nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Container %q is using image, should not be able to rmi: %q" , cleanedContainerID , out )
2014-09-09 20:32:14 -04:00
}
if ! strings . Contains ( out , errSubstr ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Container %q is using image, error message should contain %q: %v" , cleanedContainerID , errSubstr , out )
2014-09-09 20:32:14 -04:00
}
// make sure it didn't delete the busybox name
2015-04-18 12:46:47 -04:00
images , _ := dockerCmd ( c , "images" )
2014-09-09 20:32:14 -04:00
if ! strings . Contains ( images , "busybox" ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "The name 'busybox' should not have been removed from images: %q" , images )
2014-09-09 20:32:14 -04:00
}
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiTag ( c * check . C ) {
imagesBefore , _ := dockerCmd ( c , "images" , "-a" )
dockerCmd ( c , "tag" , "busybox" , "utest:tag1" )
dockerCmd ( c , "tag" , "busybox" , "utest/docker:tag2" )
dockerCmd ( c , "tag" , "busybox" , "utest:5000/docker:tag3" )
2014-09-09 20:32:14 -04:00
{
2015-04-18 12:46:47 -04:00
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
2014-12-03 20:47:28 -05:00
if strings . Count ( imagesAfter , "\n" ) != strings . Count ( imagesBefore , "\n" ) + 3 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "before: %q\n\nafter: %q\n" , imagesBefore , imagesAfter )
2014-09-09 20:32:14 -04:00
}
}
2015-04-18 12:46:47 -04:00
dockerCmd ( c , "rmi" , "utest/docker:tag2" )
2014-09-09 20:32:14 -04:00
{
2015-04-18 12:46:47 -04:00
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
2014-12-03 20:47:28 -05:00
if strings . Count ( imagesAfter , "\n" ) != strings . Count ( imagesBefore , "\n" ) + 2 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "before: %q\n\nafter: %q\n" , imagesBefore , imagesAfter )
2014-09-09 20:32:14 -04:00
}
}
2015-04-18 12:46:47 -04:00
dockerCmd ( c , "rmi" , "utest:5000/docker:tag3" )
2014-09-09 20:32:14 -04:00
{
2015-04-18 12:46:47 -04:00
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
2014-12-03 20:47:28 -05:00
if strings . Count ( imagesAfter , "\n" ) != strings . Count ( imagesBefore , "\n" ) + 1 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "before: %q\n\nafter: %q\n" , imagesBefore , imagesAfter )
2014-09-09 20:32:14 -04:00
}
}
2015-04-18 12:46:47 -04:00
dockerCmd ( c , "rmi" , "utest:tag1" )
2014-09-09 20:32:14 -04:00
{
2015-04-18 12:46:47 -04:00
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
2014-12-03 20:47:28 -05:00
if strings . Count ( imagesAfter , "\n" ) != strings . Count ( imagesBefore , "\n" ) + 0 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "before: %q\n\nafter: %q\n" , imagesBefore , imagesAfter )
2014-09-09 20:32:14 -04:00
}
}
}
2014-10-02 19:39:39 -04:00
2015-05-29 14:12:58 -04:00
func ( s * DockerSuite ) TestRmiImgIDMultipleTag ( c * check . C ) {
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "run" , "-d" , "busybox" , "/bin/sh" , "-c" , "mkdir '/busybox-one'" )
2015-05-29 14:12:58 -04:00
if err != nil {
c . Fatalf ( "failed to create a container:%s, %v" , out , err )
}
2015-07-14 16:15:00 -04:00
2015-05-29 14:12:58 -04:00
containerID := strings . TrimSpace ( out )
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "commit" , containerID , "busybox-one" )
2015-05-29 14:12:58 -04:00
if err != nil {
c . Fatalf ( "failed to commit a new busybox-one:%s, %v" , out , err )
}
imagesBefore , _ := dockerCmd ( c , "images" , "-a" )
dockerCmd ( c , "tag" , "busybox-one" , "busybox-one:tag1" )
dockerCmd ( c , "tag" , "busybox-one" , "busybox-one:tag2" )
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
if strings . Count ( imagesAfter , "\n" ) != strings . Count ( imagesBefore , "\n" ) + 2 {
c . Fatalf ( "tag busybox to create 2 more images with same imageID; docker images shows: %q\n" , imagesAfter )
}
imgID , err := inspectField ( "busybox-one:tag1" , "Id" )
c . Assert ( err , check . IsNil )
// run a container with the image
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "run" , "-d" , "busybox-one" , "top" )
2015-05-29 14:12:58 -04:00
if err != nil {
c . Fatalf ( "failed to create a container:%s, %v" , out , err )
}
2015-07-14 16:15:00 -04:00
2015-05-29 14:12:58 -04:00
containerID = strings . TrimSpace ( out )
// first checkout without force it fails
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "rmi" , imgID )
2015-05-29 14:12:58 -04:00
expected := fmt . Sprintf ( "Conflict, cannot delete %s because the running container %s is using it, stop it and use -f to force" , imgID [ : 12 ] , containerID [ : 12 ] )
if err == nil || ! strings . Contains ( out , expected ) {
c . Fatalf ( "rmi tagged in multiple repos should have failed without force: %s, %v, expected: %s" , out , err , expected )
}
dockerCmd ( c , "stop" , containerID )
dockerCmd ( c , "rmi" , "-f" , imgID )
imagesAfter , _ = dockerCmd ( c , "images" , "-a" )
if strings . Contains ( imagesAfter , imgID [ : 12 ] ) {
c . Fatalf ( "rmi -f %s failed, image still exists: %q\n\n" , imgID , imagesAfter )
}
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiImgIDForce ( c * check . C ) {
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "run" , "-d" , "busybox" , "/bin/sh" , "-c" , "mkdir '/busybox-test'" )
2015-04-10 21:24:21 -04:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "failed to create a container:%s, %v" , out , err )
2015-04-10 21:24:21 -04:00
}
2015-07-14 16:15:00 -04:00
2015-04-10 21:24:21 -04:00
containerID := strings . TrimSpace ( out )
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "commit" , containerID , "busybox-test" )
2015-04-10 21:24:21 -04:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "failed to commit a new busybox-test:%s, %v" , out , err )
2015-04-10 21:24:21 -04:00
}
2015-04-18 12:46:47 -04:00
imagesBefore , _ := dockerCmd ( c , "images" , "-a" )
dockerCmd ( c , "tag" , "busybox-test" , "utest:tag1" )
dockerCmd ( c , "tag" , "busybox-test" , "utest:tag2" )
dockerCmd ( c , "tag" , "busybox-test" , "utest/docker:tag3" )
dockerCmd ( c , "tag" , "busybox-test" , "utest:5000/docker:tag4" )
2015-04-10 21:24:21 -04:00
{
2015-04-18 12:46:47 -04:00
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
2015-04-10 21:24:21 -04:00
if strings . Count ( imagesAfter , "\n" ) != strings . Count ( imagesBefore , "\n" ) + 4 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "tag busybox to create 4 more images with same imageID; docker images shows: %q\n" , imagesAfter )
2015-04-10 21:24:21 -04:00
}
}
2015-05-17 22:06:13 -04:00
imgID , err := inspectField ( "busybox-test" , "Id" )
c . Assert ( err , check . IsNil )
2015-04-22 17:12:46 -04:00
// first checkout without force it fails
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "rmi" , imgID )
2015-04-22 17:12:46 -04:00
if err == nil || ! strings . Contains ( out , fmt . Sprintf ( "Conflict, cannot delete image %s because it is tagged in multiple repositories, use -f to force" , imgID ) ) {
2015-04-27 16:33:30 -04:00
c . Fatalf ( "rmi tagged in multiple repos should have failed without force:%s, %v" , out , err )
2015-04-22 17:12:46 -04:00
}
2015-04-18 12:46:47 -04:00
dockerCmd ( c , "rmi" , "-f" , imgID )
2015-04-10 21:24:21 -04:00
{
2015-04-18 12:46:47 -04:00
imagesAfter , _ := dockerCmd ( c , "images" , "-a" )
2015-04-10 21:24:21 -04:00
if strings . Contains ( imagesAfter , imgID [ : 12 ] ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "rmi -f %s failed, image still exists: %q\n\n" , imgID , imagesAfter )
2015-04-10 21:24:21 -04:00
}
}
}
2015-06-23 06:38:50 -04:00
// See https://github.com/docker/docker/issues/14116
func ( s * DockerSuite ) TestRmiImageIDForceWithRunningContainersAndMultipleTags ( c * check . C ) {
dockerfile := "FROM busybox\nRUN echo test 14116\n"
imgID , err := buildImage ( "test-14116" , dockerfile , false )
c . Assert ( err , check . IsNil )
newTag := "newtag"
dockerCmd ( c , "tag" , imgID , newTag )
dockerCmd ( c , "run" , "-d" , imgID , "top" )
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "rmi" , "-f" , imgID )
2015-06-23 06:38:50 -04:00
if err == nil || ! strings . Contains ( out , "stop it and retry" ) {
c . Log ( out )
c . Fatalf ( "rmi -f should not delete image with running containers" )
}
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiTagWithExistingContainers ( c * check . C ) {
2014-10-02 19:39:39 -04:00
container := "test-delete-tag"
newtag := "busybox:newtag"
bb := "busybox:latest"
2015-07-27 14:13:25 -04:00
if out , _ , err := dockerCmdWithError ( "tag" , bb , newtag ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not tag busybox: %v: %s" , err , out )
2014-10-02 19:39:39 -04:00
}
2015-07-27 14:13:25 -04:00
if out , _ , err := dockerCmdWithError ( "run" , "--name" , container , bb , "/bin/true" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not run busybox: %v: %s" , err , out )
2014-10-02 19:39:39 -04:00
}
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "rmi" , newtag )
2014-10-02 19:39:39 -04:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not remove tag %s: %v: %s" , newtag , err , out )
2014-10-02 19:39:39 -04:00
}
if d := strings . Count ( out , "Untagged: " ) ; d != 1 {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Expected 1 untagged entry got %d: %q" , d , out )
2014-10-02 19:39:39 -04:00
}
}
2014-11-17 15:49:29 -05:00
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiForceWithExistingContainers ( c * check . C ) {
2014-11-17 15:49:29 -05:00
image := "busybox-clone"
2015-02-14 05:44:56 -05:00
cmd := exec . Command ( dockerBinary , "build" , "--no-cache" , "-t" , image , "-" )
cmd . Stdin = strings . NewReader ( ` FROM busybox
MAINTAINER foo ` )
if out , _ , err := runCommandWithOutput ( cmd ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not build %s: %s, %v" , image , out , err )
2014-11-17 15:49:29 -05:00
}
2015-07-27 14:13:25 -04:00
if out , _ , err := dockerCmdWithError ( "run" , "--name" , "test-force-rmi" , image , "/bin/true" ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not run container: %s, %v" , out , err )
2014-11-17 15:49:29 -05:00
}
2015-07-27 14:13:25 -04:00
if out , _ , err := dockerCmdWithError ( "rmi" , "-f" , image ) ; err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not remove image %s: %s, %v" , image , out , err )
2014-11-17 15:49:29 -05:00
}
}
2015-02-25 23:01:35 -05:00
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiWithMultipleRepositories ( c * check . C ) {
2015-02-25 23:01:35 -05:00
newRepo := "127.0.0.1:5000/busybox"
oldRepo := "busybox"
newTag := "busybox:test"
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "tag" , oldRepo , newRepo )
2015-02-25 23:01:35 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not tag busybox: %v: %s" , err , out )
2015-02-25 23:01:35 -05:00
}
2015-07-14 16:15:00 -04:00
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "run" , "--name" , "test" , oldRepo , "touch" , "/home/abcd" )
2015-02-25 23:01:35 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "failed to run container: %v, output: %s" , err , out )
2015-02-25 23:01:35 -05:00
}
2015-07-14 16:15:00 -04:00
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "commit" , "test" , newTag )
2015-02-25 23:01:35 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "failed to commit container: %v, output: %s" , err , out )
2015-02-25 23:01:35 -05:00
}
2015-07-14 16:15:00 -04:00
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "rmi" , newTag )
2015-02-25 23:01:35 -05:00
if err != nil {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "failed to remove image: %v, output: %s" , err , out )
2015-02-25 23:01:35 -05:00
}
if ! strings . Contains ( out , "Untagged: " + newTag ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Could not remove image %s: %s, %v" , newTag , out , err )
2015-02-25 23:01:35 -05:00
}
2015-03-04 16:18:45 -05:00
}
2015-04-18 12:46:47 -04:00
func ( s * DockerSuite ) TestRmiBlank ( c * check . C ) {
2015-03-04 16:18:45 -05:00
// try to delete a blank image name
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "rmi" , "" )
2015-03-04 16:18:45 -05:00
if err == nil {
2015-04-18 12:46:47 -04:00
c . Fatal ( "Should have failed to delete '' image" )
2015-03-04 16:18:45 -05:00
}
if strings . Contains ( out , "No such image" ) {
2015-04-18 12:46:47 -04:00
c . Fatalf ( "Wrong error message generated: %s" , out )
2015-03-04 16:18:45 -05:00
}
2015-07-01 07:34:43 -04:00
if ! strings . Contains ( out , "Image name can not be blank" ) {
c . Fatalf ( "Expected error message not generated: %s" , out )
}
2015-07-27 14:13:25 -04:00
out , _ , err = dockerCmdWithError ( "rmi" , " " )
2015-07-01 07:34:43 -04:00
if err == nil {
c . Fatal ( "Should have failed to delete '' image" )
}
if ! strings . Contains ( out , "No such image" ) {
c . Fatalf ( "Expected error message not generated: %s" , out )
}
2015-02-25 23:01:35 -05:00
}
2015-07-10 09:35:44 -04:00
func ( s * DockerSuite ) TestRmiContainerImageNotFound ( c * check . C ) {
// Build 2 images for testing.
imageNames := [ ] string { "test1" , "test2" }
imageIds := make ( [ ] string , 2 )
for i , name := range imageNames {
dockerfile := fmt . Sprintf ( "FROM busybox\nMAINTAINER %s\nRUN echo %s\n" , name , name )
id , err := buildImage ( name , dockerfile , false )
c . Assert ( err , check . IsNil )
imageIds [ i ] = id
}
// Create a long-running container.
dockerCmd ( c , "run" , "-d" , imageNames [ 0 ] , "top" )
// Create a stopped container, and then force remove its image.
dockerCmd ( c , "run" , imageNames [ 1 ] , "true" )
dockerCmd ( c , "rmi" , "-f" , imageIds [ 1 ] )
// Try to remove the image of the running container and see if it fails as expected.
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "rmi" , "-f" , imageIds [ 0 ] )
2015-07-10 09:35:44 -04:00
if err == nil || ! strings . Contains ( out , "is using it" ) {
c . Log ( out )
c . Fatal ( "The image of the running container should not be removed." )
}
}