github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/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  package main
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"os"
    21  	"os/exec"
    22  	"strings"
    23  	"testing"
    24  
    25  	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types"
    26  	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/steveeJ/gexpect"
    27  	"github.com/coreos/rkt/tests/testutils"
    28  )
    29  
    30  const (
    31  	rmImageReferenced = `rkt: image ID %q is referenced by some containers, cannot remove.`
    32  	rmImageOk         = "rkt: successfully removed aci for image ID:"
    33  
    34  	unreferencedACI = "rkt-unreferencedACI.aci"
    35  	unreferencedApp = "coreos.com/rkt-unreferenced"
    36  	referencedApp   = "coreos.com/rkt-inspect"
    37  
    38  	stage1App = "coreos.com/rkt/stage1"
    39  )
    40  
    41  func TestImageRunRm(t *testing.T) {
    42  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
    43  	defer os.Remove(imageFile)
    44  	ctx := testutils.NewRktRunCtx()
    45  	defer ctx.Cleanup()
    46  
    47  	cmd := fmt.Sprintf("%s --insecure-skip-verify fetch %s", ctx.Cmd(), imageFile)
    48  	t.Logf("Fetching %s: %v", imageFile, cmd)
    49  	spawnAndWaitOrFail(t, cmd, true)
    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-skip-verify run --mds-register=false %s", ctx.Cmd(), referencedACI)
    54  	t.Logf("Running %s: %v", referencedACI, cmd)
    55  	spawnAndWaitOrFail(t, cmd, true)
    56  
    57  	t.Logf("Retrieving stage1 image ID")
    58  	stage1ImageID, err := getImageId(ctx, stage1App)
    59  	if err != nil {
    60  		t.Fatalf("rkt didn't terminate correctly: %v", err)
    61  	}
    62  
    63  	t.Logf("Retrieving %s image ID", referencedApp)
    64  	referencedImageID, err := getImageId(ctx, referencedApp)
    65  	if err != nil {
    66  		t.Fatalf("rkt didn't terminate correctly: %v", err)
    67  	}
    68  
    69  	t.Logf("Retrieving %s image ID", unreferencedApp)
    70  	unreferencedImageID, err := getImageId(ctx, unreferencedApp)
    71  	if err != nil {
    72  		t.Fatalf("rkt didn't terminate correctly: %v", err)
    73  	}
    74  
    75  	t.Logf("Removing stage1 image (should work)")
    76  	if err := removeImageId(ctx, stage1ImageID, true); err != nil {
    77  		t.Fatalf("unexpected error: %v", err)
    78  	}
    79  
    80  	t.Logf("Removing image for app %s (should work)", referencedApp)
    81  	if err := removeImageId(ctx, referencedImageID, true); err != nil {
    82  		t.Fatalf("unexpected error: %v", err)
    83  	}
    84  
    85  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
    86  	if err := removeImageId(ctx, unreferencedImageID, true); err != nil {
    87  		t.Fatalf("unexpected error: %v", err)
    88  	}
    89  }
    90  
    91  func TestImagePrepareRmRun(t *testing.T) {
    92  	imageFile := patchTestACI(unreferencedACI, fmt.Sprintf("--name=%s", unreferencedApp))
    93  	defer os.Remove(imageFile)
    94  	ctx := testutils.NewRktRunCtx()
    95  	defer ctx.Cleanup()
    96  
    97  	cmd := fmt.Sprintf("%s --insecure-skip-verify fetch %s", ctx.Cmd(), imageFile)
    98  	t.Logf("Fetching %s: %v", imageFile, cmd)
    99  	spawnAndWaitOrFail(t, cmd, true)
   100  
   101  	// at this point we know that RKT_INSPECT_IMAGE env var is not empty
   102  	referencedACI := os.Getenv("RKT_INSPECT_IMAGE")
   103  	cmds := strings.Fields(ctx.Cmd())
   104  	prepareCmd := exec.Command(cmds[0], cmds[1:]...)
   105  	prepareCmd.Args = append(prepareCmd.Args, "--insecure-skip-verify", "prepare", referencedACI)
   106  	output, err := prepareCmd.Output()
   107  	if err != nil {
   108  		t.Fatalf("Cannot read the output: %v", err)
   109  	}
   110  
   111  	podIDStr := strings.TrimSpace(string(output))
   112  	podID, err := types.NewUUID(podIDStr)
   113  	if err != nil {
   114  		t.Fatalf("%q is not a valid UUID: %v", podIDStr, err)
   115  	}
   116  
   117  	t.Logf("Retrieving stage1 imageID")
   118  	stage1ImageID, err := getImageId(ctx, stage1App)
   119  	if err != nil {
   120  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   121  	}
   122  
   123  	t.Logf("Retrieving %s image ID", referencedApp)
   124  	referencedImageID, err := getImageId(ctx, referencedApp)
   125  	if err != nil {
   126  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   127  	}
   128  
   129  	t.Logf("Retrieving %s image ID", unreferencedApp)
   130  	unreferencedImageID, err := getImageId(ctx, unreferencedApp)
   131  	if err != nil {
   132  		t.Fatalf("rkt didn't terminate correctly: %v", err)
   133  	}
   134  
   135  	t.Logf("Removing stage1 image (should work)")
   136  	if err := removeImageId(ctx, stage1ImageID, true); err != nil {
   137  		t.Fatalf("unexpected error: %v", err)
   138  	}
   139  
   140  	t.Logf("Removing image for app %s (should work)", referencedApp)
   141  	if err := removeImageId(ctx, referencedImageID, true); err != nil {
   142  		t.Fatalf("unexpected error: %v", err)
   143  	}
   144  
   145  	t.Logf("Removing image for app %s (should work)", unreferencedApp)
   146  	if err := removeImageId(ctx, unreferencedImageID, true); err != nil {
   147  		t.Fatalf("unexpected error: %v", err)
   148  	}
   149  
   150  	cmd = fmt.Sprintf("%s run-prepared --mds-register=false %s", ctx.Cmd(), podID.String())
   151  	t.Logf("Running %s: %v", referencedACI, cmd)
   152  	spawnAndWaitOrFail(t, cmd, true)
   153  }
   154  
   155  func getImageId(ctx *testutils.RktRunCtx, name string) (string, error) {
   156  	cmd := fmt.Sprintf(`/bin/sh -c "%s image list --fields=id,name --no-legend | grep %s | awk '{print $1}'"`, ctx.Cmd(), name)
   157  	child, err := gexpect.Spawn(cmd)
   158  	if err != nil {
   159  		return "", fmt.Errorf("Cannot exec rkt: %v", err)
   160  	}
   161  	imageID, err := child.ReadLine()
   162  	imageID = strings.TrimSpace(imageID)
   163  	imageID = string(bytes.Trim([]byte(imageID), "\x00"))
   164  	if err != nil {
   165  		return "", fmt.Errorf("Cannot exec: %v", err)
   166  	}
   167  	if err := child.Wait(); err != nil {
   168  		return "", fmt.Errorf("rkt didn't terminate correctly: %v", err)
   169  	}
   170  	return imageID, nil
   171  }
   172  
   173  func removeImageId(ctx *testutils.RktRunCtx, imageID string, shouldWork bool) error {
   174  	expect := fmt.Sprintf(rmImageReferenced, imageID)
   175  	if shouldWork {
   176  		expect = rmImageOk
   177  	}
   178  	cmd := fmt.Sprintf("%s image rm %s", ctx.Cmd(), imageID)
   179  	child, err := gexpect.Spawn(cmd)
   180  	if err != nil {
   181  		return fmt.Errorf("Cannot exec: %v", err)
   182  	}
   183  	if err := expectWithOutput(child, expect); err != nil {
   184  		return fmt.Errorf("Expected %q but not found: %v", expect, err)
   185  	}
   186  	if err := child.Wait(); err != nil {
   187  		return fmt.Errorf("rkt didn't terminate correctly: %v", err)
   188  	}
   189  	return nil
   190  }