예제 #1
0
func testFetchNoStore(t *testing.T, args string, image string, imageArgs string, finalURL string) {
	remoteFetchMsgTpl := `remote fetching from URL %q`
	remoteFetchMsg := fmt.Sprintf(remoteFetchMsgTpl, finalURL)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	if _, err := importImageAndFetchHash(t, ctx, "", image); err != nil {
		t.Skip(fmt.Sprintf("%v, probably a network failure. Skipping...", err))
	}

	cmd := fmt.Sprintf("%s --no-store %s %s %s", ctx.Cmd(), args, image, imageArgs)

	// 1. Run cmd with the image available in the store, should get $remoteFetchMsg.
	err := runRktAndCheckRegexOutput(t, cmd, remoteFetchMsg)
	status, _ := common.GetExitStatus(err)
	if status != 0 {
		t.Logf("%v", err)
		t.Skip("remote fetching failed, probably a network failure. Skipping...")
	}

	if err != nil {
		t.Fatalf("%q should be found: %v", remoteFetchMsg, err)
	}
}
예제 #2
0
파일: rkt_tests.go 프로젝트: joshix/rkt
func waitOrFail(t *testing.T, child *gexpect.ExpectSubprocess, expectedStatus int) {
	err := child.Wait()
	status, _ := common.GetExitStatus(err)
	if status != expectedStatus {
		t.Fatalf("rkt terminated with unexpected status %d, expected %d\nOutput:\n%s", status, expectedStatus, child.Collect())
	}
}
예제 #3
0
func testFetchDefault(t *testing.T, arg string, image string, imageArgs string, finalURL string) {
	remoteFetchMsgTpl := `remote fetching from URL %q`
	storeMsgTpl := `using image from local store for .* %s`
	if finalURL == "" {
		finalURL = image
	}
	remoteFetchMsg := fmt.Sprintf(remoteFetchMsgTpl, finalURL)
	storeMsg := fmt.Sprintf(storeMsgTpl, image)

	ctx := testutils.NewRktRunCtx()
	defer ctx.Cleanup()

	cmd := fmt.Sprintf("%s %s %s %s", ctx.Cmd(), arg, image, imageArgs)

	// 1. Run cmd with the image not available in the store, should get $remoteFetchMsg.
	err := runRktAndCheckRegexOutput(t, cmd, remoteFetchMsg)
	status, _ := common.GetExitStatus(err)
	if status != 0 {
		t.Logf("%v", err)
		t.Skip("remote fetching failed, probably a network failure. Skipping...")
	}

	// 2. Run cmd with the image available in the store, should get $storeMsg.
	runRktAndCheckRegexOutput(t, cmd, storeMsg)
}
예제 #4
0
파일: rkt_tests.go 프로젝트: joshix/rkt
func runRkt(t *testing.T, rktCmd string, uid, gid int) (string, int) {
	child, err := gexpect.Command(rktCmd)
	if err != nil {
		t.Fatalf("cannot exec rkt: %v", err)
	}
	if gid != 0 {
		child.Cmd.SysProcAttr = &syscall.SysProcAttr{}
		child.Cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
	}

	err = child.Start()
	if err != nil {
		t.Fatalf("cannot start rkt: %v", err)
	}

	_, linesChan := child.AsyncInteractChannels()

	var buf bytes.Buffer
	for line := range linesChan {
		buf.WriteString(line + "\n") // reappend newline
	}

	status, _ := common.GetExitStatus(child.Wait())
	return buf.String(), status
}
예제 #5
0
파일: rkt_tests.go 프로젝트: joshix/rkt
func checkExitStatus(child *gexpect.ExpectSubprocess) error {
	err := child.Wait()
	status, _ := common.GetExitStatus(err)
	if status != 0 {
		return fmt.Errorf("rkt terminated with unexpected status %d, expected %d\nOutput:\n%s", status, 0, child.Collect())
	}

	return nil
}
예제 #6
0
파일: app.go 프로젝트: joshix/rkt
func StopApp(cfg StopConfig) error {
	pod, err := pkgPod.PodFromUUIDString(cfg.DataDir, cfg.UUID.String())
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod manifest"), err)
	}
	defer pod.Close()

	_, pm, err := pod.PodManifest()
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod manifest"), err)
	}

	var mutable bool
	ms, ok := pm.Annotations.Get("coreos.com/rkt/stage1/mutable")
	if ok {
		mutable, err = strconv.ParseBool(ms)
		if err != nil {
			return errwrap.Wrap(errors.New("error parsing mutable annotation"), err)
		}
	}

	if !mutable {
		return errors.New("immutable pod: cannot start application")
	}

	app := pm.Apps.Get(*cfg.AppName)
	if app == nil {
		return fmt.Errorf("error: nonexistent app %q", *cfg.AppName)
	}

	args := []string{
		fmt.Sprintf("--app=%s", cfg.AppName),
	}

	ce := CrossingEntrypoint{
		PodPath:        cfg.PodPath,
		PodPID:         cfg.PodPID,
		AppName:        cfg.AppName.String(),
		EntrypointName: appStopEntrypoint,
		EntrypointArgs: args,
		Interactive:    false,
	}
	if err := ce.Run(); err != nil {
		status, err := common.GetExitStatus(err)
		// exit status 5 comes from systemctl and means the unit doesn't exist
		if status == 5 {
			return fmt.Errorf("app %q is not running", app.Name)
		}

		return err
	}

	return nil
}
예제 #7
0
파일: rkt_tests.go 프로젝트: intelsdi-x/rkt
// waitOrFail waits for the child to exit, draining all its output.
// If a non-negative return value is provided, child exit status must match.
func waitOrFail(t *testing.T, child *gexpect.ExpectSubprocess, expectedStatus int) {
	bufOut := []string{}
	// TODO(lucab): gexpect should accept those channels from the caller
	ttyIn, ttyOut := child.AsyncInteractChannels()
	close(ttyIn)
	// drain output till gexpect closes the channel (on EOF or error)
	for line := range ttyOut {
		bufOut = append(bufOut, line)
	}
	err := child.Wait()
	status, _ := common.GetExitStatus(err)
	if expectedStatus >= 0 && status != expectedStatus {
		t.Fatalf("rkt terminated with unexpected status %d, expected %d\nOutput:\n%s", status, expectedStatus, bufOut)
	}
}
예제 #8
0
파일: app.go 프로젝트: kinvolk/rkt
func StopApp(cfg StopConfig) error {
	pod, err := pkgPod.PodFromUUIDString(cfg.DataDir, cfg.UUID.String())
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod manifest"), err)
	}
	defer pod.Close()

	pm, err := pod.SandboxManifest()
	if err != nil {
		return errwrap.Wrap(errors.New("cannot stop application"), err)
	}

	app := pm.Apps.Get(*cfg.AppName)
	if app == nil {
		return fmt.Errorf("error: nonexistent app %q", *cfg.AppName)
	}

	args := []string{
		fmt.Sprintf("--debug=%t", cfg.Debug),
		fmt.Sprintf("--app=%s", cfg.AppName),
	}

	ce := CrossingEntrypoint{
		PodPath:        cfg.PodPath,
		PodPID:         cfg.PodPID,
		AppName:        cfg.AppName.String(),
		EntrypointName: appStopEntrypoint,
		EntrypointArgs: args,
		Interactive:    false,
	}
	if err := ce.Run(); err != nil {
		status, err := common.GetExitStatus(err)
		// exit status 5 comes from systemctl and means the unit doesn't exist
		if status == 5 {
			return fmt.Errorf("app %q is not running", app.Name)
		}

		return err
	}

	return nil
}
예제 #9
0
파일: app.go 프로젝트: kinvolk/rkt
func RmApp(cfg RmConfig) error {
	pod, err := pkgPod.PodFromUUIDString(cfg.DataDir, cfg.UUID.String())
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod"), err)
	}
	defer pod.Close()

	debug("locking sandbox manifest")
	if err := pod.ExclusiveLockManifest(); err != nil {
		return errwrap.Wrap(errors.New("failed to lock sandbox manifest"), err)
	}
	defer pod.UnlockManifest()

	pm, err := pod.SandboxManifest()
	if err != nil {
		return errwrap.Wrap(errors.New("cannot remove application, sandbox validation failed"), err)
	}

	app := pm.Apps.Get(*cfg.AppName)
	if app == nil {
		return fmt.Errorf("error: nonexistent app %q", *cfg.AppName)
	}

	if cfg.PodPID > 0 {
		// Call app-stop and app-rm entrypoint only if the pod is still running.
		// Otherwise, there's not much we can do about it except unmounting/removing
		// the file system.
		args := []string{
			fmt.Sprintf("--debug=%t", cfg.Debug),
			fmt.Sprintf("--app=%s", cfg.AppName),
		}

		ce := CrossingEntrypoint{
			PodPath:        cfg.PodPath,
			PodPID:         cfg.PodPID,
			AppName:        cfg.AppName.String(),
			EntrypointName: appStopEntrypoint,
			EntrypointArgs: args,
			Interactive:    false,
		}
		if err := ce.Run(); err != nil {
			status, err := common.GetExitStatus(err)
			// ignore nonexistent units failing to stop. Exit status 5
			// comes from systemctl and means the unit doesn't exist
			if err != nil {
				return err
			} else if status != 5 {
				return fmt.Errorf("exit status %d", status)
			}
		}

		ce.EntrypointName = appRmEntrypoint
		if err := ce.Run(); err != nil {
			return err
		}
	}

	if cfg.UsesOverlay {
		treeStoreID, err := ioutil.ReadFile(common.AppTreeStoreIDPath(cfg.PodPath, *cfg.AppName))
		if err != nil {
			return err
		}

		appRootfs := common.AppRootfsPath(cfg.PodPath, *cfg.AppName)
		if err := syscall.Unmount(appRootfs, 0); err != nil {
			return err
		}

		ts := filepath.Join(cfg.PodPath, "overlay", string(treeStoreID))
		if err := os.RemoveAll(ts); err != nil {
			return errwrap.Wrap(errors.New("error removing app info directory"), err)
		}
	}

	appInfoDir := common.AppInfoPath(cfg.PodPath, *cfg.AppName)
	if err := os.RemoveAll(appInfoDir); err != nil {
		return errwrap.Wrap(errors.New("error removing app info directory"), err)
	}

	if err := os.RemoveAll(common.AppPath(cfg.PodPath, *cfg.AppName)); err != nil {
		return err
	}

	appStatusPath := filepath.Join(common.Stage1RootfsPath(cfg.PodPath), "rkt", "status", cfg.AppName.String())
	if err := os.Remove(appStatusPath); err != nil && !os.IsNotExist(err) {
		return err
	}

	envPath := filepath.Join(common.Stage1RootfsPath(cfg.PodPath), "rkt", "env", cfg.AppName.String())
	if err := os.Remove(envPath); err != nil && !os.IsNotExist(err) {
		return err
	}

	for i, app := range pm.Apps {
		if app.Name == *cfg.AppName {
			pm.Apps = append(pm.Apps[:i], pm.Apps[i+1:]...)
			break
		}
	}

	return pod.UpdateManifest(pm, cfg.PodPath)
}
예제 #10
0
파일: app.go 프로젝트: joshix/rkt
func RmApp(cfg RmConfig) error {
	pod, err := pkgPod.PodFromUUIDString(cfg.DataDir, cfg.UUID.String())
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod"), err)
	}
	defer pod.Close()

	debug("locking pod manifest")
	if err := pod.ExclusiveManifestLock(); err != nil {
		return errwrap.Wrap(errors.New("failed to lock pod manifest"), err)
	}
	defer pod.ManifestUnlock()

	_, pm, err := pod.PodManifest()
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod manifest"), err)
	}

	var mutable bool
	ms, ok := pm.Annotations.Get("coreos.com/rkt/stage1/mutable")
	if ok {
		mutable, err = strconv.ParseBool(ms)
		if err != nil {
			return errwrap.Wrap(errors.New("error parsing mutable annotation"), err)
		}
	}

	if !mutable {
		return errors.New("immutable pod: cannot remove application")
	}

	app := pm.Apps.Get(*cfg.AppName)
	if app == nil {
		return fmt.Errorf("error: nonexistent app %q", *cfg.AppName)
	}

	if cfg.PodPID > 0 {
		// Call app-stop and app-rm entrypoint only if the pod is still running.
		// Otherwise, there's not much we can do about it except unmounting/removing
		// the file system.
		args := []string{
			fmt.Sprintf("--app=%s", cfg.AppName),
		}

		ce := CrossingEntrypoint{
			PodPath:        cfg.PodPath,
			PodPID:         cfg.PodPID,
			AppName:        cfg.AppName.String(),
			EntrypointName: appStopEntrypoint,
			EntrypointArgs: args,
			Interactive:    false,
		}
		if err := ce.Run(); err != nil {
			status, err := common.GetExitStatus(err)
			// ignore nonexistent units failing to stop. Exit status 5
			// comes from systemctl and means the unit doesn't exist
			if err != nil {
				return err
			} else if status != 5 {
				return fmt.Errorf("exit status %d", status)
			}
		}

		ce.EntrypointName = appRmEntrypoint
		if err := ce.Run(); err != nil {
			return err
		}
	}

	if cfg.UsesOverlay {
		treeStoreID, err := ioutil.ReadFile(common.AppTreeStoreIDPath(cfg.PodPath, *cfg.AppName))
		if err != nil {
			return err
		}

		appRootfs := common.AppRootfsPath(cfg.PodPath, *cfg.AppName)
		if err := syscall.Unmount(appRootfs, 0); err != nil {
			return err
		}

		ts := filepath.Join(cfg.PodPath, "overlay", string(treeStoreID))
		if err := os.RemoveAll(ts); err != nil {
			return errwrap.Wrap(errors.New("error removing app info directory"), err)
		}
	}

	appInfoDir := common.AppInfoPath(cfg.PodPath, *cfg.AppName)
	if err := os.RemoveAll(appInfoDir); err != nil {
		return errwrap.Wrap(errors.New("error removing app info directory"), err)
	}

	if err := os.RemoveAll(common.AppPath(cfg.PodPath, *cfg.AppName)); err != nil {
		return err
	}

	appStatusPath := filepath.Join(common.Stage1RootfsPath(cfg.PodPath), "rkt", "status", cfg.AppName.String())
	if err := os.Remove(appStatusPath); err != nil && !os.IsNotExist(err) {
		return err
	}

	envPath := filepath.Join(common.Stage1RootfsPath(cfg.PodPath), "rkt", "env", cfg.AppName.String())
	if err := os.Remove(envPath); err != nil && !os.IsNotExist(err) {
		return err
	}

	removeAppFromPodManifest(pm, cfg.AppName)

	if err := updatePodManifest(cfg.PodPath, pm); err != nil {
		return err
	}

	return nil
}