예제 #1
0
파일: app.go 프로젝트: joshix/rkt
func StartApp(cfg StartConfig) 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()

	_, 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),
	}

	if _, err := os.Create(common.AppStartedPath(cfg.PodPath, cfg.AppName.String())); err != nil {
		log.FatalE(fmt.Sprintf("error creating %s-started file", cfg.AppName.String()), err)
	}

	ce := CrossingEntrypoint{
		PodPath:        cfg.PodPath,
		PodPID:         cfg.PodPID,
		AppName:        cfg.AppName.String(),
		EntrypointName: appStartEntrypoint,
		EntrypointArgs: args,
		Interactive:    false,
	}
	if err := ce.Run(); err != nil {
		return err
	}

	return nil
}
예제 #2
0
파일: app.go 프로젝트: kinvolk/rkt
func StartApp(cfg StartConfig) 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()

	pm, err := pod.SandboxManifest()
	if err != nil {
		return errwrap.Wrap(errors.New("cannot start 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),
	}

	if _, err := os.Create(common.AppStartedPath(cfg.PodPath, cfg.AppName.String())); err != nil {
		log.FatalE(fmt.Sprintf("error creating %s-started file", cfg.AppName.String()), err)
	}

	ce := CrossingEntrypoint{
		PodPath:        cfg.PodPath,
		PodPID:         cfg.PodPID,
		AppName:        cfg.AppName.String(),
		EntrypointName: appStartEntrypoint,
		EntrypointArgs: args,
		Interactive:    false,
	}
	if err := ce.Run(); err != nil {
		return err
	}

	return nil
}
예제 #3
0
파일: app.go 프로젝트: kinvolk/rkt
func appState(app *App, pod *pkgPod.Pod) error {
	app.State = AppStateUnknown

	defer func() {
		if pod.IsAfterRun() {
			// If the pod is hard killed, set the app to 'exited' state.
			// Other than this case, status file is guaranteed to be written.
			if app.State != AppStateExited {
				app.State = AppStateExited
				t, err := pod.GCMarkedTime()
				if err != nil {
					fmt.Fprintf(os.Stderr, "Cannot get GC marked time: %v", err)
				}
				if !t.IsZero() {
					finishedAt := t.UnixNano()
					app.FinishedAt = &finishedAt
				}
			}
		}
	}()

	// Check if the app is created.
	fi, err := os.Stat(common.AppCreatedPath(pod.Path(), app.Name))
	if err != nil {
		if !os.IsNotExist(err) {
			return fmt.Errorf("cannot stat app creation file: %v", err)
		}
		return nil
	}

	app.State = AppStateCreated
	createdAt := fi.ModTime().UnixNano()
	app.CreatedAt = &createdAt

	// Check if the app is started.
	fi, err = os.Stat(common.AppStartedPath(pod.Path(), app.Name))
	if err != nil {
		if !os.IsNotExist(err) {
			return fmt.Errorf("cannot stat app started file: %v", err)
		}
		return nil
	}

	app.State = AppStateRunning
	startedAt := fi.ModTime().UnixNano()
	app.StartedAt = &startedAt

	// Check if the app is exited.
	appStatusFile := common.AppStatusPath(pod.Path(), app.Name)
	fi, err = os.Stat(appStatusFile)
	if err != nil {
		if !os.IsNotExist(err) {
			return fmt.Errorf("cannot stat app exited file: %v", err)
		}
		return nil
	}

	app.State = AppStateExited
	finishedAt := fi.ModTime().UnixNano()
	app.FinishedAt = &finishedAt

	// Read exit code.
	exitCode, err := readExitCode(appStatusFile)
	if err != nil {
		return err
	}
	app.ExitCode = &exitCode

	return nil
}
예제 #4
0
파일: app.go 프로젝트: nhlfr/rkt
func StartApp(cfg StartConfig) error {
	p, err := stage1types.LoadPod(cfg.Dir, cfg.UUID)
	if err != nil {
		return errwrap.Wrap(errors.New("error loading pod manifest"), err)
	}

	pm := p.Manifest

	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)
	}

	eep, err := getStage1Entrypoint(cfg.Dir, enterEntrypoint)
	if err != nil {
		return errwrap.Wrap(errors.New("error determining 'enter' entrypoint"), err)
	}

	args := []string{
		cfg.UUID.String(),
		cfg.AppName.String(),
		filepath.Join(common.Stage1RootfsPath(cfg.Dir), eep),
		strconv.Itoa(cfg.PodPID),
	}

	if cfg.InsecureCapabilities {
		args = append(args, "--disable-capabilities-restriction")
	}
	if cfg.InsecurePaths {
		args = append(args, "--disable-paths")
	}
	if cfg.InsecureSeccomp {
		args = append(args, "--disable-seccomp")
	}

	privateUsers, err := preparedWithPrivateUsers(cfg.Dir)
	if err != nil {
		log.FatalE("error reading user namespace information", err)
	}

	if privateUsers != "" {
		args = append(args, fmt.Sprintf("--private-users=%s", privateUsers))
	}

	if _, err := os.Create(common.AppStartedPath(p.Root, cfg.AppName.String())); err != nil {
		log.FatalE(fmt.Sprintf("error creating %s-started file", cfg.AppName.String()), err)
	}

	if err := callEntrypoint(cfg.Dir, appStartEntrypoint, args); err != nil {
		return err
	}

	return nil
}