github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/tests/rkt_image_rm_test.go (about)

     1  // Copyright 2015 The rkt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build host coreos src kvm
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"os"
    23  	"os/exec"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/appc/spec/schema/types"
    28  	"github.com/coreos/gexpect"
    29  	"github.com/rkt/rkt/tests/testutils"
    30  )
    31  
    32  const (
    33  	rmImageOk = "rm: 1 image(s) successfully removed"
    34  
    35  	unreferencedACI = "rkt-unreferencedACI.aci"
    36  	unreferencedApp = "coreos.com/rkt-unreferenced"
    37  	referencedApp   = "coreos.com/rkt-inspect"
    38  
    39  	stage1App = "coreos.com/rkt/stage1"
    40  )
    41  
    42  func TestImageRunRmName(t *testing.T) {
    43  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
    44  	defer os.Remove(imageFile)
    45  	ctx := testutils.NewRktRunCtx()
    46  	defer ctx.Cleanup()
    47  
    48  	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
    49  	spawnAndWaitOrFail(t, cmd, 0)
    50  
    51  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
    52  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
    53  	cmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), referencedACI)
    54  	spawnAndWaitOrFail(t, cmd, 0)
    55  
    56  	t.Logf("Retrieving stage1 image name")
    57  	stage1ImageName := getImageName(t, ctx, stage1App)
    58  
    59  	t.Logf("Removing stage1 image (should work)")
    60  	removeImage(t, ctx, stage1ImageName)
    61  
    62  	t.Logf("Removing image for app %s (should work)", referencedApp)
    63  	removeImage(t, ctx, referencedApp)
    64  
    65  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
    66  	removeImage(t, ctx, unreferencedApp)
    67  }
    68  
    69  func TestImageRunRmID(t *testing.T) {
    70  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
    71  	defer os.Remove(imageFile)
    72  	ctx := testutils.NewRktRunCtx()
    73  	defer ctx.Cleanup()
    74  
    75  	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
    76  	t.Logf("Fetching %s", imageFile)
    77  	spawnAndWaitOrFail(t, cmd, 0)
    78  
    79  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
    80  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
    81  	cmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), referencedACI)
    82  	t.Logf("Running %s", referencedACI)
    83  	spawnAndWaitOrFail(t, cmd, 0)
    84  
    85  	t.Logf("Retrieving stage1 image ID")
    86  	stage1ImageID, err := getImageID(ctx, stage1App)
    87  	if err != nil {
    88  		t.Fatalf("rkt didn't terminate correctly: %v", err)
    89  	}
    90  
    91  	t.Logf("Retrieving %s image ID", referencedApp)
    92  	referencedImageID, err := getImageID(ctx, referencedApp)
    93  	if err != nil {
    94  		t.Fatalf("rkt didn't terminate correctly: %v", err)
    95  	}
    96  
    97  	t.Logf("Retrieving %s image ID", unreferencedApp)
    98  	unreferencedImageID, err := getImageID(ctx, unreferencedApp)
    99  	if err != nil {
   100  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   101  	}
   102  
   103  	t.Logf("Removing stage1 image (should work)")
   104  	removeImage(t, ctx, stage1ImageID)
   105  
   106  	t.Logf("Removing image for app %s (should work)", referencedApp)
   107  	removeImage(t, ctx, referencedImageID)
   108  
   109  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
   110  	removeImage(t, ctx, unreferencedImageID)
   111  }
   112  
   113  func TestImageRunRmDuplicate(t *testing.T) {
   114  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
   115  	defer os.Remove(imageFile)
   116  	ctx := testutils.NewRktRunCtx()
   117  	defer ctx.Cleanup()
   118  
   119  	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
   120  	t.Logf("Fetching %s", imageFile)
   121  	spawnAndWaitOrFail(t, cmd, 0)
   122  
   123  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
   124  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
   125  	cmd = fmt.Sprintf("%s --insecure-options=image run --mds-register=false %s", ctx.Cmd(), referencedACI)
   126  	t.Logf("Running %s", referencedACI)
   127  	spawnAndWaitOrFail(t, cmd, 0)
   128  
   129  	t.Logf("Retrieving %s image ID", referencedApp)
   130  	referencedImageID, err := getImageID(ctx, referencedApp)
   131  	if err != nil {
   132  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   133  	}
   134  
   135  	t.Logf("Retrieving %s image ID", unreferencedApp)
   136  	unreferencedImageID, err := getImageID(ctx, unreferencedApp)
   137  	if err != nil {
   138  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   139  	}
   140  
   141  	t.Logf("Removing image for app %s (should work)", referencedApp)
   142  	removeImage(t, ctx, referencedApp, referencedImageID)
   143  
   144  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
   145  	removeImage(t, ctx, unreferencedImageID, unreferencedApp)
   146  }
   147  
   148  func TestImagePrepareRmNameRun(t *testing.T) {
   149  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
   150  	defer os.Remove(imageFile)
   151  	ctx := testutils.NewRktRunCtx()
   152  	defer ctx.Cleanup()
   153  
   154  	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
   155  	t.Logf("Fetching %s", imageFile)
   156  	spawnAndWaitOrFail(t, cmd, 0)
   157  
   158  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
   159  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
   160  	cmds := strings.Fields(ctx.Cmd())
   161  	prepareCmd := exec.Command(cmds[0], cmds[1:]...)
   162  	prepareCmd.Args = append(prepareCmd.Args, "--insecure-options=image", "prepare", referencedACI)
   163  	output, err := prepareCmd.Output()
   164  	if err != nil {
   165  		t.Fatalf("Cannot read the output: %v", err)
   166  	}
   167  
   168  	podIDStr := strings.TrimSpace(string(output))
   169  	podID, err := types.NewUUID(podIDStr)
   170  	if err != nil {
   171  		t.Fatalf("%q is not a valid UUID: %v", podIDStr, err)
   172  	}
   173  
   174  	t.Logf("Retrieving stage1 image name")
   175  	stage1ImageName := getImageName(t, ctx, stage1App)
   176  
   177  	t.Logf("Removing stage1 image (should work)")
   178  	removeImage(t, ctx, stage1ImageName)
   179  
   180  	t.Logf("Removing image for app %s (should work)", referencedApp)
   181  	removeImage(t, ctx, referencedApp)
   182  
   183  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
   184  	removeImage(t, ctx, unreferencedApp)
   185  
   186  	cmd = fmt.Sprintf("%s run-prepared --mds-register=false %s", ctx.Cmd(), podID.String())
   187  	t.Logf("Running %s", referencedACI)
   188  	spawnAndWaitOrFail(t, cmd, 0)
   189  }
   190  
   191  func TestImagePrepareRmIDRun(t *testing.T) {
   192  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
   193  	defer os.Remove(imageFile)
   194  	ctx := testutils.NewRktRunCtx()
   195  	defer ctx.Cleanup()
   196  
   197  	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
   198  	t.Logf("Fetching %s", imageFile)
   199  	spawnAndWaitOrFail(t, cmd, 0)
   200  
   201  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
   202  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
   203  	cmds := strings.Fields(ctx.Cmd())
   204  	prepareCmd := exec.Command(cmds[0], cmds[1:]...)
   205  	prepareCmd.Args = append(prepareCmd.Args, "--insecure-options=image", "prepare", referencedACI)
   206  	output, err := prepareCmd.Output()
   207  	if err != nil {
   208  		t.Fatalf("Cannot read the output: %v", err)
   209  	}
   210  
   211  	podIDStr := strings.TrimSpace(string(output))
   212  	podID, err := types.NewUUID(podIDStr)
   213  	if err != nil {
   214  		t.Fatalf("%q is not a valid UUID: %v", podIDStr, err)
   215  	}
   216  
   217  	t.Logf("Retrieving stage1 imageID")
   218  	stage1ImageID, err := getImageID(ctx, stage1App)
   219  	if err != nil {
   220  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   221  	}
   222  
   223  	t.Logf("Retrieving %s image ID", referencedApp)
   224  	referencedImageID, err := getImageID(ctx, referencedApp)
   225  	if err != nil {
   226  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   227  	}
   228  
   229  	t.Logf("Retrieving %s image ID", unreferencedApp)
   230  	unreferencedImageID, err := getImageID(ctx, unreferencedApp)
   231  	if err != nil {
   232  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   233  	}
   234  
   235  	t.Logf("Removing stage1 image (should work)")
   236  	removeImage(t, ctx, stage1ImageID)
   237  
   238  	t.Logf("Removing image for app %s (should work)", referencedApp)
   239  	removeImage(t, ctx, referencedImageID)
   240  
   241  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
   242  	removeImage(t, ctx, unreferencedImageID)
   243  
   244  	cmd = fmt.Sprintf("%s run-prepared --mds-register=false %s", ctx.Cmd(), podID.String())
   245  	t.Logf("Running %s", referencedACI)
   246  	spawnAndWaitOrFail(t, cmd, 0)
   247  }
   248  
   249  func TestImagePrepareRmDuplicate(t *testing.T) {
   250  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
   251  	defer os.Remove(imageFile)
   252  	ctx := testutils.NewRktRunCtx()
   253  	defer ctx.Cleanup()
   254  
   255  	cmd := fmt.Sprintf("%s --insecure-options=image fetch %s", ctx.Cmd(), imageFile)
   256  	t.Logf("Fetching %s", imageFile)
   257  	spawnAndWaitOrFail(t, cmd, 0)
   258  
   259  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
   260  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
   261  	cmds := strings.Fields(ctx.Cmd())
   262  	prepareCmd := exec.Command(cmds[0], cmds[1:]...)
   263  	prepareCmd.Args = append(prepareCmd.Args, "--insecure-options=image", "prepare", referencedACI)
   264  	output, err := prepareCmd.Output()
   265  	if err != nil {
   266  		t.Fatalf("Cannot read the output: %v", err)
   267  	}
   268  
   269  	podIDStr := strings.TrimSpace(string(output))
   270  	podID, err := types.NewUUID(podIDStr)
   271  	if err != nil {
   272  		t.Fatalf("%q is not a valid UUID: %v", podIDStr, err)
   273  	}
   274  
   275  	t.Logf("Retrieving %s image ID", referencedApp)
   276  	referencedImageID, err := getImageID(ctx, referencedApp)
   277  	if err != nil {
   278  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   279  	}
   280  
   281  	t.Logf("Retrieving %s image ID", unreferencedApp)
   282  	unreferencedImageID, err := getImageID(ctx, unreferencedApp)
   283  	if err != nil {
   284  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   285  	}
   286  
   287  	t.Logf("Removing image for app %s (should work)", referencedApp)
   288  	removeImage(t, ctx, referencedApp, referencedImageID)
   289  
   290  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
   291  	removeImage(t, ctx, unreferencedImageID, unreferencedApp)
   292  
   293  	cmd = fmt.Sprintf("%s run-prepared --mds-register=false %s", ctx.Cmd(), podID.String())
   294  	t.Logf("Running %s", referencedACI)
   295  	spawnAndWaitOrFail(t, cmd, 0)
   296  }
   297  
   298  func getImageName(t *testing.T, ctx *testutils.RktRunCtx, name string) string {
   299  	cmd := fmt.Sprintf(`/bin/sh -c "%s image list --fields=name --no-legend | grep %s"`, ctx.Cmd(), name)
   300  	child := spawnOrFail(t, cmd)
   301  	imageName, err := child.ReadLine()
   302  	imageName = strings.TrimSpace(imageName)
   303  	imageName = string(bytes.Trim([]byte(imageName), "\x00"))
   304  	if err != nil {
   305  		t.Fatalf("Cannot exec: %v", err)
   306  	}
   307  	waitOrFail(t, child, 0)
   308  	return imageName
   309  }
   310  
   311  func getImageID(ctx *testutils.RktRunCtx, name string) (string, error) {
   312  	cmd := fmt.Sprintf(`/bin/sh -c "%s image list --fields=id,name --no-legend | grep %s | awk '{print $1}'"`, ctx.Cmd(), name)
   313  	child, err := gexpect.Spawn(cmd)
   314  	if err != nil {
   315  		return "", fmt.Errorf("Cannot exec rkt: %v", err)
   316  	}
   317  	imageID, err := child.ReadLine()
   318  	imageID = strings.TrimSpace(imageID)
   319  	imageID = string(bytes.Trim([]byte(imageID), "\x00"))
   320  	if err != nil {
   321  		return "", fmt.Errorf("Cannot exec: %v", err)
   322  	}
   323  	if err := child.Wait(); err != nil {
   324  		return "", fmt.Errorf("rkt didn't terminate correctly: %v", err)
   325  	}
   326  	return imageID, nil
   327  }
   328  
   329  func removeImage(t *testing.T, ctx *testutils.RktRunCtx, images ...string) {
   330  	cmd := fmt.Sprintf("%s image rm %s", ctx.Cmd(), strings.Join(images, " "))
   331  	child, err := gexpect.Spawn(cmd)
   332  	if err != nil {
   333  		t.Fatalf("Cannot exec: %v", err)
   334  	}
   335  	if err := expectWithOutput(child, rmImageOk); err != nil {
   336  		t.Fatalf("Expected %q but not found: %v", rmImageOk, err)
   337  	}
   338  	if err := child.Wait(); err != nil {
   339  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   340  	}
   341  }