예제 #1
0
func runCatManifest(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	pod, err := getPodFromUUIDString(args[0])
	if err != nil {
		stderr("cat-manifest: problem retrieving pod: %v", err)
		return 1
	}
	defer pod.Close()

	manifest, err := pod.getManifest()
	if err != nil {
		return 1
	}

	var b []byte
	if flagPMPrettyPrint {
		b, err = json.MarshalIndent(manifest, "", "\t")
	} else {
		b, err = json.Marshal(manifest)
	}
	if err != nil {
		stderr("cat-manifest: cannot read the pod manifest: %v", err)
		return 1
	}

	stdout(string(b))
	return 0
}
예제 #2
0
파일: status.go 프로젝트: matomesc/rkt
func runStatus(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	p, err := getPodFromUUIDString(args[0])
	if err != nil {
		stderr("Problem retrieving pod: %v", err)
		return 1
	}
	defer p.Close()

	if flagWait {
		if err := p.waitExited(); err != nil {
			stderr("Unable to wait for pod: %v", err)
			return 1
		}
	}

	if err = printStatus(p); err != nil {
		stderr("Unable to print status: %v", err)
		return 1
	}

	return 0
}
예제 #3
0
파일: trust.go 프로젝트: fdserr/rkt
func runTrust(cmd *cobra.Command, args []string) (exit int) {
	if flagPrefix == "" && !flagRoot {
		if len(args) != 0 {
			stderr("--root required for non-prefixed (root) keys")
		} else {
			cmd.Usage()
		}
		return 1
	}

	if flagPrefix != "" && flagRoot {
		stderr("--root and --prefix usage mutually exclusive")
		return 1
	}

	// if the user included a scheme with the prefix, error on it
	u, err := url.Parse(flagPrefix)
	if err == nil && u.Scheme != "" {
		stderr("--prefix must not contain a URL scheme, omit %s://", u.Scheme)
		return 1
	}

	pkls, err := getPubKeyLocations(flagPrefix, args)
	if err != nil {
		stderr("Error determining key location: %v", err)
		return 1
	}

	if err := addKeys(pkls, flagPrefix); err != nil {
		stderr("Error adding keys: %v", err)
		return 1
	}

	return 0
}
예제 #4
0
파일: rm.go 프로젝트: krieg/rkt
func runRm(cmd *cobra.Command, args []string) (exit int) {
	var podUUID *types.UUID
	var err error

	switch {
	case len(args) == 0 && flagUUIDFile != "":
		podUUID, err = readUUIDFromFile(flagUUIDFile)
		if err != nil {
			stderr("Unable to read UUID from file: %v", err)
			return 1
		}

	case len(args) == 1 && flagUUIDFile == "":
		podUUID, err = resolveUUID(args[0])
		if err != nil {
			stderr("Unable to resolve UUID: %v", err)
			return 1
		}
	default:
		cmd.Usage()
		return 1
	}

	p, err := getPod(podUUID)
	if err != nil {
		stderr("Cannot get pod: %v", err)
		return 1
	}

	return removePod(p)
}
예제 #5
0
파일: status.go 프로젝트: NeilW/rkt
func runStatus(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	podUUID, err := resolveUUID(args[0])
	if err != nil {
		stderr("Unable to resolve UUID: %v", err)
		return 1
	}

	p, err := getPod(podUUID)
	if err != nil {
		stderr("Unable to get pod: %v", err)
		return 1
	}
	defer p.Close()

	if flagWait {
		if err := p.waitExited(); err != nil {
			stderr("Unable to wait for pod: %v", err)
			return 1
		}
	}

	if err = printStatus(p); err != nil {
		stderr("Unable to print status: %v", err)
		return 1
	}

	return 0
}
예제 #6
0
파일: trust.go 프로젝트: ngorskig/rkt
func runTrust(cmd *cobra.Command, args []string) (exit int) {
	if globalFlags.InsecureSkipVerify {
		// --insecure-skip-verify disable the keystore but we need it for rkt trust
		stderr("--insecure-skip-verify cannot be used with rkt trust")
		return 1
	}

	if flagPrefix == "" && !flagRoot {
		if len(args) != 0 {
			stderr("--root required for non-prefixed (root) keys")
		} else {
			cmd.Usage()
		}
		return 1
	}

	if flagPrefix != "" && flagRoot {
		stderr("--root and --prefix usage mutually exclusive")
		return 1
	}

	ks := getKeystore()
	if ks == nil {
		stderr("could not get the keystore")
		return 1
	}

	// if the user included a scheme with the prefix, error on it
	u, err := url.Parse(flagPrefix)
	if err == nil && u.Scheme != "" {
		stderr("--prefix must not contain a URL scheme, omit %s://", u.Scheme)
		return 1
	}

	pkls := args
	m := &pubkey.Manager{
		InsecureAllowHttp:  flagAllowHTTP,
		TrustKeysFromHttps: globalFlags.TrustKeysFromHttps,
		Ks:                 ks,
		Debug:              globalFlags.Debug,
	}
	if len(pkls) == 0 {
		pkls, err = m.GetPubKeyLocations(flagPrefix)
		if err != nil {
			stderr("Error determining key location: %v", err)
			return 1
		}
	}

	acceptOpt := pubkey.AcceptAsk
	if globalFlags.InsecureSkipVerify {
		acceptOpt = pubkey.AcceptForce
	}
	if err := m.AddKeys(pkls, flagPrefix, acceptOpt, pubkey.OverrideDeny); err != nil {
		stderr("Error adding keys: %v", err)
		return 1
	}

	return 0
}
func runImageImport(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 2 {
		cmd.Usage()
		return 1
	}

	outFile := args[1]
	ext := filepath.Ext(outFile)
	if ext != schema.ACIExtension {
		stderr("rkt: Extension must be %s (given %s)", schema.ACIExtension, ext)
		return 1
	}

	aciImgPath, err := oci2aciImage(args[0])
	if err != nil {
		stderr("rkt: oci2aci failed: %s", err)
		return 1
	}

	if err = run(exec.Command("mv", aciImgPath, args[1])); err != nil {
		return 1
	}

	return 0
}
예제 #8
0
func runImageImport(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	//convert oci bundle to aci image
	aciImage, err := oci2aci.Oci2aciImage(args[0])
	if err != nil {
		fmt.Printf("oci2aci failed: %v", err)
		return 1
	}

	//save aci to rkt store
	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		fmt.Printf("cannot open store: %v", err)
		return 1
	}
	aciFile, err := os.Open(aciImage)
	if err != nil {
		fmt.Printf("opening ACI file %s failed: %v", aciImage, err)
		return 1
	}
	key, err := s.WriteACI(aciFile, true)
	if err != nil {
		fmt.Printf("write ACI file failed: %v", err)
		return 1
	}
	fmt.Println(key)
	return 0
}
예제 #9
0
파일: fetch.go 프로젝트: mischief/rkt
func runFetch(cmd *cobra.Command, args []string) (exit int) {
	if err := parseApps(&rktApps, args, cmd.Flags(), false); err != nil {
		stderr("fetch: unable to parse arguments: %v", err)
		return 1
	}

	if rktApps.Count() < 1 {
		stderr("fetch: must provide at least one image")
		return 1
	}

	if flagStoreOnly && flagNoStore {
		stderr("both --store-only and --no-store specified")
		return 1
	}

	s, err := store.NewStore(getDataDir())
	if err != nil {
		stderr("fetch: cannot open store: %v", err)
		return 1
	}
	ks := getKeystore()
	config, err := getConfig()
	if err != nil {
		stderr("fetch: cannot get configuration: %v", err)
		return 1
	}
	ft := &image.Fetcher{
		S:                  s,
		Ks:                 ks,
		Headers:            config.AuthPerHost,
		DockerAuth:         config.DockerCredentialsPerRegistry,
		InsecureFlags:      globalFlags.InsecureFlags,
		Debug:              globalFlags.Debug,
		TrustKeysFromHTTPS: globalFlags.TrustKeysFromHTTPS,

		StoreOnly: flagStoreOnly,
		NoStore:   flagNoStore,
		WithDeps:  true,
	}

	err = rktApps.Walk(func(app *apps.App) error {
		hash, err := ft.FetchImage(app.Image, app.Asc, app.ImType)
		if err != nil {
			return err
		}
		if !flagFullHash {
			hash = types.ShortHash(hash)
		}
		stdout(hash)
		return nil
	})
	if err != nil {
		stderr("%v", err)
		return 1
	}

	return
}
예제 #10
0
파일: help.go 프로젝트: NeilW/rkt
func getSubCommands(cmd *cobra.Command) []*cobra.Command {
	subCommands := []*cobra.Command{}
	for _, subCmd := range cmd.Commands() {
		subCommands = append(subCommands, subCmd)
		subCommands = append(subCommands, getSubCommands(subCmd)...)
	}
	return subCommands
}
예제 #11
0
func runImageCatManifest(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("image cat-manifest: cannot open store: %v", err)
		return 1
	}

	var key string
	if _, err := types.NewHash(args[0]); err == nil {
		key, err = s.ResolveKey(args[0])
		if err != nil {
			stderr("image cat-manifest: cannot resolve key: %v", err)
			return 1
		}
	} else {
		app, err := discovery.NewAppFromString(args[0])
		if err != nil {
			stderr("image cat-manifest: cannot parse the image name: %v", err)
			return 1
		}
		labels, err := types.LabelsFromMap(app.Labels)
		if err != nil {
			stderr("image cat-manifest: invalid labels in the name: %v", err)
			return 1
		}
		key, err = s.GetACI(app.Name, labels)
		if err != nil {
			stderr("image cat-manifest: cannot find image: %v", err)
			return 1
		}
	}

	manifest, err := s.GetImageManifest(key)
	if err != nil {
		stderr("image cat-manifest: cannot get image manifest: %v", err)
		return 1
	}

	var b []byte
	if flagPrettyPrint {
		b, err = json.MarshalIndent(manifest, "", "\t")
	} else {
		b, err = json.Marshal(manifest)
	}
	if err != nil {
		stderr("image cat-manifest: cannot read the image manifest: %v", err)
		return 1
	}

	stdout(string(b))
	return 0
}
예제 #12
0
파일: fetch.go 프로젝트: NeilW/rkt
func runFetch(cmd *cobra.Command, args []string) (exit int) {
	if err := parseApps(&rktApps, args, cmd.Flags(), false); err != nil {
		stderr("fetch: unable to parse arguments: %v", err)
		return 1
	}

	if rktApps.Count() < 1 {
		stderr("fetch: must provide at least one image")
		return 1
	}

	if flagStoreOnly && flagNoStore {
		stderr("both --store-only and --no-store specified")
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("fetch: cannot open store: %v", err)
		return 1
	}
	ks := getKeystore()
	config, err := getConfig()
	if err != nil {
		stderr("fetch: cannot get configuration: %v", err)
		return 1
	}
	ft := &fetcher{
		imageActionData: imageActionData{
			s:                  s,
			ks:                 ks,
			headers:            config.AuthPerHost,
			dockerAuth:         config.DockerCredentialsPerRegistry,
			insecureSkipVerify: globalFlags.InsecureSkipVerify,
			debug:              globalFlags.Debug,
		},
		storeOnly: flagStoreOnly,
		noStore:   flagNoStore,
		withDeps:  true,
	}

	err = rktApps.Walk(func(app *apps.App) error {
		hash, err := ft.fetchImage(app.Image, app.Asc)
		if err != nil {
			return err
		}
		shortHash := types.ShortHash(hash)
		stdout(shortHash)
		return nil
	})
	if err != nil {
		stderr("%v", err)
		return 1
	}

	return
}
예제 #13
0
파일: enter.go 프로젝트: matomesc/rkt
func runEnter(cmd *cobra.Command, args []string) (exit int) {
	if len(args) < 1 {
		cmd.Usage()
		return 1
	}

	p, err := getPodFromUUIDString(args[0])
	if err != nil {
		stderr("Problem problem retrieving pod: %v", err)
		return 1
	}
	defer p.Close()

	if !p.isRunning() {
		stderr("Pod %q isn't currently running", p.uuid)
		return 1
	}

	podPID, err := p.getContainerPID1()
	if err != nil {
		stderr("Unable to determine the pid for pod %q: %v", p.uuid, err)
		return 1
	}

	appName, err := getAppName(p)
	if err != nil {
		stderr("Unable to determine app name: %v", err)
		return 1
	}

	argv, err := getEnterArgv(p, args)
	if err != nil {
		stderr("Enter failed: %v", err)
		return 1
	}

	s, err := store.NewStore(getDataDir())
	if err != nil {
		stderr("Cannot open store: %v", err)
		return 1
	}

	stage1TreeStoreID, err := p.getStage1TreeStoreID()
	if err != nil {
		stderr("Error getting stage1 treeStoreID: %v", err)
		return 1
	}

	stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID)

	if err = stage0.Enter(p.path(), podPID, *appName, stage1RootFS, argv); err != nil {
		stderr("Enter failed: %v", err)
		return 1
	}
	// not reached when stage0.Enter execs /enter
	return 0
}
예제 #14
0
func runImageExport(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 2 {
		cmd.Usage()
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("image export: cannot open store: %v", err)
		return 1
	}

	key, err := getKeyFromAppOrHash(s, args[0])
	if err != nil {
		stderr("image export: %v", err)
		return 1
	}

	aci, err := s.ReadStream(key)
	if err != nil {
		stderr("image export: error reading image: %v", err)
		return 1
	}
	defer aci.Close()

	mode := os.O_CREATE | os.O_WRONLY
	if flagOverwriteACI {
		mode |= os.O_TRUNC
	} else {
		mode |= os.O_EXCL
	}
	f, err := os.OpenFile(args[1], mode, 0644)
	if err != nil {
		if os.IsExist(err) {
			stderr("image export: output ACI file exists (try --overwrite)")
		} else {
			stderr("image export: unable to open output ACI file %s: %v", args[1], err)
		}
		return 1
	}
	defer func() {
		err := f.Close()
		if err != nil {
			stderr("image export: error closing output ACI file: %v", err)
			exit = 1
		}
	}()

	_, err = io.Copy(f, aci)
	if err != nil {
		stderr("image export: error writing to output ACI file: %v", err)
		return 1
	}

	return 0
}
예제 #15
0
파일: rm.go 프로젝트: matomesc/rkt
func runRm(cmd *cobra.Command, args []string) (exit int) {
	var podUUID *types.UUID
	var podUUIDs []*types.UUID
	var err error

	switch {
	case len(args) == 0 && flagUUIDFile != "":
		podUUID, err = readUUIDFromFile(flagUUIDFile)
		if err != nil {
			stderr("Unable to read UUID from file: %v", err)
			return 1
		}
		podUUIDs = append(podUUIDs, podUUID)

	case len(args) > 0 && flagUUIDFile == "":
		for _, uuid := range args {
			podUUID, err := resolveUUID(uuid)
			if err != nil {
				stderr("Unable to resolve UUID: %v", err)
			} else {
				podUUIDs = append(podUUIDs, podUUID)
			}
		}

	default:
		cmd.Usage()
		return 1
	}

	ret := 0
	for _, podUUID = range podUUIDs {
		p, err := getPod(podUUID)
		if err != nil {
			ret = 1
			stderr("Cannot get pod: %v", err)
		}

		if removePod(p) {
			stdout("%q", p.uuid)
		} else {
			ret = 1
		}
	}

	if ret == 1 {
		stderr("Failed to remove one or more pods")
	}

	return ret
}
예제 #16
0
파일: trust.go 프로젝트: NeilW/rkt
func runTrust(cmd *cobra.Command, args []string) (exit int) {
	if globalFlags.InsecureSkipVerify {
		// --insecure-skip-verify disable the keystore but we need it for rkt trust
		stderr("--insecure-skip-verify cannot be used with rkt trust")
		return 1
	}

	if flagPrefix == "" && !flagRoot {
		if len(args) != 0 {
			stderr("--root required for non-prefixed (root) keys")
		} else {
			cmd.Usage()
		}
		return 1
	}

	if flagPrefix != "" && flagRoot {
		stderr("--root and --prefix usage mutually exclusive")
		return 1
	}

	// if the user included a scheme with the prefix, error on it
	u, err := url.Parse(flagPrefix)
	if err == nil && u.Scheme != "" {
		stderr("--prefix must not contain a URL scheme, omit %s://", u.Scheme)
		return 1
	}

	pkls := args
	if len(pkls) == 0 {
		pkls, err = getPubKeyLocations(flagPrefix, flagAllowHTTP, globalFlags.Debug)
		if err != nil {
			stderr("Error determining key location: %v", err)
			return 1
		}
	}

	// allow override
	if err := addKeys(pkls, flagPrefix, flagAllowHTTP, globalFlags.InsecureSkipVerify, true); err != nil {
		stderr("Error adding keys: %v", err)
		return 1
	}

	return 0
}
예제 #17
0
파일: help.go 프로젝트: danieltaborda/rkt
func usageFunc(cmd *cobra.Command) error {
	subCommands := getSubCommands(cmd)
	commandUsageTemplate.Execute(tabOut, struct {
		Executable  string
		Cmd         *cobra.Command
		CmdFlags    *pflag.FlagSet
		SubCommands []*cobra.Command
		Version     string
	}{
		cliName,
		cmd,
		cmd.Flags(),
		subCommands,
		version.Version,
	})
	tabOut.Flush()
	return nil
}
예제 #18
0
파일: help.go 프로젝트: matomesc/rkt
func usageFunc(cmd *cobra.Command) error {
	subCommands := getSubCommands(cmd)
	tabOut := getTabOutWithWriter(os.Stdout)
	commandUsageTemplate.Execute(tabOut, struct {
		Cmd         *cobra.Command
		LocalFlags  string
		GlobalFlags string
		SubCommands []*cobra.Command
		Version     string
	}{
		cmd,
		rktFlagUsages(cmd.LocalFlags()),
		rktFlagUsages(cmd.InheritedFlags()),
		subCommands,
		version.Version,
	})
	tabOut.Flush()
	return nil
}
예제 #19
0
파일: stage1hash.go 프로젝트: ngorskig/rkt
// getStage1Hash will try to fetch stage1 from store if it is a
// default one. If that fails it will try to get via usual fetching
// from disk or network.
//
// As a special case, if stage1 image path is a default and not
// overriden by --stage1-image flag and it is has no scheme, it will
// try to fetch it from two places on disk - from the path directly if
// it is absolute and then from the same directory where rkt binary
// resides.
//
// The passed command must have "stage1-image" string flag registered.
func getStage1Hash(s *store.Store, cmd *cobra.Command) (*types.Hash, error) {
	fn := &finder{
		imageActionData: imageActionData{
			s: s,
		},
		storeOnly: false,
		noStore:   false,
		withDeps:  false,
	}

	imageFlag := cmd.Flags().Lookup(stage1ImageFlagName)
	if imageFlag == nil {
		panic(fmt.Sprintf("Expected flag --%s to be registered in command %s", stage1ImageFlagName, cmd.Name()))
	}
	path := imageFlag.Value.String()
	if path == defaultStage1Image {
		return getDefaultStage1Hash(fn, imageFlag.Changed)
	}
	return getCustomStage1Hash(fn, path)
}
예제 #20
0
파일: stage1hash.go 프로젝트: matomesc/rkt
// getStage1Hash will try to fetch stage1 from store if it is a
// default one. If that fails it will try to get via usual fetching
// from disk or network.
//
// As a special case, if stage1 image path is a default and not
// overriden by --stage1-image flag and it is has no scheme, it will
// try to fetch it from two places on disk - from the path directly if
// it is absolute and then from the same directory where rkt binary
// resides.
//
// The passed command must have "stage1-image" string flag registered.
func getStage1Hash(s *store.Store, cmd *cobra.Command) (*types.Hash, error) {
	fn := &image.Finder{
		S:                  s,
		InsecureFlags:      globalFlags.InsecureFlags,
		TrustKeysFromHttps: globalFlags.TrustKeysFromHttps,

		StoreOnly: false,
		NoStore:   false,
		WithDeps:  false,
	}

	imageFlag := cmd.Flags().Lookup(stage1ImageFlagName)
	if imageFlag == nil {
		panic(fmt.Sprintf("Expected flag --%s to be registered in command %s", stage1ImageFlagName, cmd.Name()))
	}
	path := imageFlag.Value.String()
	if path == defaultStage1Image {
		return getDefaultStage1Hash(fn, imageFlag.Changed)
	}
	return getCustomStage1Hash(fn, path)
}
예제 #21
0
func runImageCatManifest(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("image cat-manifest: cannot open store: %v", err)
		return 1
	}

	key, err := getKeyFromAppOrHash(s, args[0])
	if err != nil {
		stderr("image cat-manifest: %v", err)
		return 1
	}

	manifest, err := s.GetImageManifest(key)
	if err != nil {
		stderr("image cat-manifest: cannot get image manifest: %v", err)
		return 1
	}

	var b []byte
	if flagPrettyPrint {
		b, err = json.MarshalIndent(manifest, "", "\t")
	} else {
		b, err = json.Marshal(manifest)
	}
	if err != nil {
		stderr("image cat-manifest: cannot read the image manifest: %v", err)
		return 1
	}

	stdout(string(b))
	return 0
}
예제 #22
0
파일: enter.go 프로젝트: harpe1999/rkt
func runEnter(cmd *cobra.Command, args []string) (exit int) {
	if len(args) < 1 {
		cmd.Usage()
		return 1
	}

	podUUID, err := resolveUUID(args[0])
	if err != nil {
		stderr("Unable to resolve UUID: %v", err)
		return 1
	}

	p, err := getPod(podUUID)
	if err != nil {
		stderr("Failed to open pod %q: %v", podUUID, err)
		return 1
	}
	defer p.Close()

	if !p.isRunning() {
		stderr("Pod %q isn't currently running", podUUID)
		return 1
	}

	podPID, err := p.getPID()
	if err != nil {
		stderr("Unable to determine the pid for pod %q: %v", podUUID, err)
		return 1
	}

	appName, err := getAppName(p)
	if err != nil {
		stderr("Unable to determine app name: %v", err)
		return 1
	}

	argv, err := getEnterArgv(p, args)
	if err != nil {
		stderr("Enter failed: %v", err)
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("Cannot open store: %v", err)
		return 1
	}

	stage1ID, err := p.getStage1Hash()
	if err != nil {
		stderr("Error getting stage1 hash")
		return 1
	}

	stage1RootFS := s.GetTreeStoreRootFS(stage1ID.String())

	if err = stage0.Enter(p.path(), podPID, *appName, stage1RootFS, argv); err != nil {
		stderr("Enter failed: %v", err)
		return 1
	}
	// not reached when stage0.Enter execs /enter
	return 0
}
예제 #23
0
파일: run.go 프로젝트: fdserr/rkt
func runRun(cmd *cobra.Command, args []string) (exit int) {
	err := parseApps(&rktApps, args, cmd.Flags(), true)
	if err != nil {
		stderr("run: error parsing app image arguments: %v", err)
		return 1
	}

	if len(flagPorts) > 0 && !flagPrivateNet.Any() {
		stderr("--port flag requires --private-net")
		return 1
	}

	if len(flagPodManifest) > 0 && (len(flagVolumes) > 0 || len(flagPorts) > 0 || flagInheritEnv || !flagExplicitEnv.IsEmpty() || rktApps.Count() > 0 || flagLocal) {
		stderr("conflicting flags set with --pod-manifest (see --help)")
		return 1
	}

	if globalFlags.Dir == "" {
		log.Printf("dir unset - using temporary directory")
		var err error
		globalFlags.Dir, err = ioutil.TempDir("", "rkt")
		if err != nil {
			stderr("error creating temporary directory: %v", err)
			return 1
		}
	}

	if flagInteractive && rktApps.Count() > 1 {
		stderr("run: interactive option only supports one image")
		return 1
	}

	if rktApps.Count() < 1 && len(flagPodManifest) == 0 {
		stderr("run: must provide at least one image or specify the pod manifest")
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("run: cannot open store: %v", err)
		return 1
	}

	config, err := getConfig()
	if err != nil {
		stderr("run: cannot get configuration: %v", err)
		return 1
	}
	fn := &finder{
		imageActionData: imageActionData{
			s:                  s,
			headers:            config.AuthPerHost,
			dockerAuth:         config.DockerCredentialsPerRegistry,
			insecureSkipVerify: globalFlags.InsecureSkipVerify,
			debug:              globalFlags.Debug,
		},
		local:    flagLocal,
		withDeps: false,
	}
	s1img, err := fn.findImage(flagStage1Image, "", false)
	if err != nil {
		stderr("Error finding stage1 image %q: %v", flagStage1Image, err)
		return 1
	}

	fn.ks = getKeystore()
	fn.withDeps = true
	if err := fn.findImages(&rktApps); err != nil {
		stderr("%v", err)
		return 1
	}

	p, err := newPod()
	if err != nil {
		stderr("Error creating new pod: %v", err)
		return 1
	}

	processLabel, mountLabel, err := label.InitLabels(nil)
	if err != nil {
		stderr("Error initialising SELinux: %v", err)
		return 1
	}

	cfg := stage0.CommonConfig{
		MountLabel:   mountLabel,
		ProcessLabel: processLabel,
		Store:        s,
		Stage1Image:  *s1img,
		UUID:         p.uuid,
		Debug:        globalFlags.Debug,
	}

	pcfg := stage0.PrepareConfig{
		CommonConfig: cfg,
		UseOverlay:   !flagNoOverlay && common.SupportsOverlay(),
	}

	if len(flagPodManifest) > 0 {
		pcfg.PodManifest = flagPodManifest
	} else {
		pcfg.Volumes = []types.Volume(flagVolumes)
		pcfg.Ports = []types.ExposedPort(flagPorts)
		pcfg.InheritEnv = flagInheritEnv
		pcfg.ExplicitEnv = flagExplicitEnv.Strings()
		pcfg.Apps = &rktApps
	}

	err = stage0.Prepare(pcfg, p.path(), p.uuid)
	if err != nil {
		stderr("run: error setting up stage0: %v", err)
		return 1
	}

	// get the lock fd for run
	lfd, err := p.Fd()
	if err != nil {
		stderr("Error getting pod lock fd: %v", err)
		return 1
	}

	// skip prepared by jumping directly to run, we own this pod
	if err := p.xToRun(); err != nil {
		stderr("run: unable to transition to run: %v", err)
		return 1
	}

	rcfg := stage0.RunConfig{
		CommonConfig: cfg,
		PrivateNet:   flagPrivateNet,
		LockFd:       lfd,
		Interactive:  flagInteractive,
		MDSRegister:  flagMDSRegister,
		LocalConfig:  globalFlags.LocalConfigDir,
	}

	imgs, err := p.getApps()
	if err != nil {
		stderr("run: cannot get the image hashes in the pod manifest: %v", err)
		return 1
	}
	rcfg.Images = imgs
	stage0.Run(rcfg, p.path()) // execs, never returns

	return 1
}
예제 #24
0
파일: run.go 프로젝트: atd-schubert/rkt
func runRun(cmd *cobra.Command, args []string) (exit int) {
	privateUsers := uid.NewBlankUidRange()
	err := parseApps(&rktApps, args, cmd.Flags(), true)
	if err != nil {
		stderr("run: error parsing app image arguments: %v", err)
		return 1
	}

	if flagStoreOnly && flagNoStore {
		stderr("both --store-only and --no-store specified")
		return 1
	}

	if flagPrivateUsers {
		if !common.SupportsUserNS() {
			stderr("run: --private-users is not supported, kernel compiled without user namespace support")
			return 1
		}
		privateUsers.SetRandomUidRange(uid.DefaultRangeCount)
	}

	if len(flagPorts) > 0 && flagNet.None() {
		stderr("--port flag does not work with 'none' networking")
		return 1
	}
	if len(flagPorts) > 0 && flagNet.Host() {
		stderr("--port flag does not work with 'host' networking")
		return 1
	}

	if flagMDSRegister && flagNet.None() {
		stderr("--mds-register flag does not work with --net=none. Please use 'host', 'default' or an equivalent network")
		return 1
	}

	if len(flagPodManifest) > 0 && (len(flagPorts) > 0 || flagInheritEnv || !flagExplicitEnv.IsEmpty() || rktApps.Count() > 0 || flagStoreOnly || flagNoStore) {
		stderr("conflicting flags set with --pod-manifest (see --help)")
		return 1
	}

	if flagInteractive && rktApps.Count() > 1 {
		stderr("run: interactive option only supports one image")
		return 1
	}

	if rktApps.Count() < 1 && len(flagPodManifest) == 0 {
		stderr("run: must provide at least one image or specify the pod manifest")
		return 1
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("run: cannot open store: %v", err)
		return 1
	}

	config, err := getConfig()
	if err != nil {
		stderr("run: cannot get configuration: %v", err)
		return 1
	}
	fn := &finder{
		imageActionData: imageActionData{
			s:                  s,
			headers:            config.AuthPerHost,
			dockerAuth:         config.DockerCredentialsPerRegistry,
			insecureSkipVerify: globalFlags.InsecureSkipVerify,
			debug:              globalFlags.Debug,
		},
		storeOnly: flagStoreOnly,
		noStore:   flagNoStore,
		withDeps:  false,
	}

	s1img, err := getStage1Hash(s, cmd)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	fn.ks = getKeystore()
	fn.withDeps = true
	if err := fn.findImages(&rktApps); err != nil {
		stderr("%v", err)
		return 1
	}

	p, err := newPod()
	if err != nil {
		stderr("Error creating new pod: %v", err)
		return 1
	}

	// if requested, write out pod UUID early so "rkt rm" can
	// clean it up even if something goes wrong
	if flagUUIDFileSave != "" {
		if err := writeUUIDToFile(p.uuid, flagUUIDFileSave); err != nil {
			stderr("Error saving pod UUID to file: %v", err)
			return 1
		}
	}

	processLabel, mountLabel, err := label.InitLabels(nil)
	if err != nil {
		stderr("Error initialising SELinux: %v", err)
		return 1
	}

	cfg := stage0.CommonConfig{
		MountLabel:   mountLabel,
		ProcessLabel: processLabel,
		Store:        s,
		Stage1Image:  *s1img,
		UUID:         p.uuid,
		Debug:        globalFlags.Debug,
	}

	pcfg := stage0.PrepareConfig{
		CommonConfig: cfg,
		UseOverlay:   !flagNoOverlay && common.SupportsOverlay(),
		PrivateUsers: privateUsers,
	}

	if len(flagPodManifest) > 0 {
		pcfg.PodManifest = flagPodManifest
	} else {
		pcfg.Ports = []types.ExposedPort(flagPorts)
		pcfg.InheritEnv = flagInheritEnv
		pcfg.ExplicitEnv = flagExplicitEnv.Strings()
		pcfg.Apps = &rktApps
	}

	if globalFlags.Debug {
		stage0.InitDebug()
	}

	keyLock, err := lock.SharedKeyLock(lockDir(), common.PrepareLock)
	if err != nil {
		stderr("rkt: cannot get shared prepare lock: %v", err)
		return 1
	}
	err = stage0.Prepare(pcfg, p.path(), p.uuid)
	if err != nil {
		stderr("run: error setting up stage0: %v", err)
		keyLock.Close()
		return 1
	}
	keyLock.Close()

	// get the lock fd for run
	lfd, err := p.Fd()
	if err != nil {
		stderr("Error getting pod lock fd: %v", err)
		return 1
	}

	// skip prepared by jumping directly to run, we own this pod
	if err := p.xToRun(); err != nil {
		stderr("run: unable to transition to run: %v", err)
		return 1
	}

	rktgid, err := common.LookupGid(common.RktGroup)
	if err != nil {
		stderr("run: group %q not found, will use default gid when rendering images", common.RktGroup)
		rktgid = -1
	}

	rcfg := stage0.RunConfig{
		CommonConfig: cfg,
		Net:          flagNet,
		LockFd:       lfd,
		Interactive:  flagInteractive,
		MDSRegister:  flagMDSRegister,
		LocalConfig:  globalFlags.LocalConfigDir,
		RktGid:       rktgid,
	}

	apps, err := p.getApps()
	if err != nil {
		stderr("run: cannot get the appList in the pod manifest: %v", err)
		return 1
	}
	rcfg.Apps = apps
	stage0.Run(rcfg, p.path(), globalFlags.Dir) // execs, never returns

	return 1
}
예제 #25
0
파일: prepare.go 프로젝트: krieg/rkt
func runPrepare(cmd *cobra.Command, args []string) (exit int) {
	var err error
	origStdout := os.Stdout
	if flagQuiet {
		if os.Stdout, err = os.Open("/dev/null"); err != nil {
			stderr("prepare: unable to open /dev/null")
			return 1
		}
	}

	if err = parseApps(&rktApps, args, cmd.Flags(), true); err != nil {
		stderr("prepare: error parsing app image arguments: %v", err)
		return 1
	}

	if len(flagPodManifest) > 0 && (len(flagVolumes) > 0 || len(flagPorts) > 0 || flagInheritEnv || !flagExplicitEnv.IsEmpty() || flagLocal) {
		stderr("prepare: conflicting flags set with --pod-manifest (see --help)")
		return 1
	}

	if rktApps.Count() < 1 && len(flagPodManifest) == 0 {
		stderr("prepare: must provide at least one image or specify the pod manifest")
		return 1
	}

	if globalFlags.Dir == "" {
		log.Printf("dir unset - using temporary directory")
		globalFlags.Dir, err = ioutil.TempDir("", "rkt")
		if err != nil {
			stderr("prepare: error creating temporary directory: %v", err)
			return 1
		}
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("prepare: cannot open store: %v", err)
		return 1
	}

	config, err := getConfig()
	if err != nil {
		stderr("prepare: cannot get configuration: %v", err)
		return 1
	}
	fn := &finder{
		imageActionData: imageActionData{
			s:                  s,
			headers:            config.AuthPerHost,
			dockerAuth:         config.DockerCredentialsPerRegistry,
			insecureSkipVerify: globalFlags.InsecureSkipVerify,
			debug:              globalFlags.Debug,
		},
		local:    flagLocal,
		withDeps: false,
	}

	s1img, err := getStage1Hash(s, flagStage1Image)
	if err != nil {
		stderr("prepare: %v", err)
		return 1
	}

	fn.ks = getKeystore()
	fn.withDeps = true
	if err := fn.findImages(&rktApps); err != nil {
		stderr("%v", err)
		return 1
	}

	p, err := newPod()
	if err != nil {
		stderr("prepare: error creating new pod: %v", err)
		return 1
	}

	cfg := stage0.CommonConfig{
		Store:       s,
		Stage1Image: *s1img,
		UUID:        p.uuid,
		Debug:       globalFlags.Debug,
	}

	pcfg := stage0.PrepareConfig{
		CommonConfig: cfg,
		UseOverlay:   !flagNoOverlay && common.SupportsOverlay(),
	}

	if len(flagPodManifest) > 0 {
		pcfg.PodManifest = flagPodManifest
	} else {
		pcfg.Volumes = []types.Volume(flagVolumes)
		pcfg.Ports = []types.ExposedPort(flagPorts)
		pcfg.InheritEnv = flagInheritEnv
		pcfg.ExplicitEnv = flagExplicitEnv.Strings()
		pcfg.Apps = &rktApps
	}

	if err = stage0.Prepare(pcfg, p.path(), p.uuid); err != nil {
		stderr("prepare: error setting up stage0: %v", err)
		return 1
	}

	if err := p.sync(); err != nil {
		stderr("prepare: error syncing pod data: %v", err)
		return 1
	}

	if err := p.xToPrepared(); err != nil {
		stderr("prepare: error transitioning to prepared: %v", err)
		return 1
	}

	os.Stdout = origStdout // restore output in case of --quiet
	stdout("%s", p.uuid.String())

	return 0
}
예제 #26
0
func runRunPrepared(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	p, err := getPodFromUUIDString(args[0])
	if err != nil {
		stderr("prepared-run: problem retrieving pod: %v", err)
		return 1
	}
	defer p.Close()

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("prepared-run: cannot open store: %v", err)
		return 1
	}

	if !p.isPrepared {
		stderr("prepared-run: pod %q is not prepared", p.uuid)
		return 1
	}

	if flagInteractive {
		ac, err := p.getAppCount()
		if err != nil {
			stderr("prepared-run: cannot get pod's app count: %v", err)
			return 1
		}
		if ac > 1 {
			stderr("prepared-run: interactive option only supports pods with one app")
			return 1
		}
	}

	// Make sure we have a metadata service available before we move to
	// run state so that the user can rerun the command without needing
	// to prepare the image again.
	if flagMDSRegister {
		if err := stage0.CheckMdsAvailability(); err != nil {
			stderr("prepare-run: %v", err)
			return 1
		}
	}

	if err := p.xToRun(); err != nil {
		stderr("prepared-run: cannot transition to run: %v", err)
		return 1
	}

	lfd, err := p.Fd()
	if err != nil {
		stderr("prepared-run: unable to get lock fd: %v", err)
		return 1
	}

	apps, err := p.getApps()
	if err != nil {
		stderr("prepared-run: unable to get app list: %v", err)
		return 1
	}

	rktgid, err := common.LookupGid(common.RktGroup)
	if err != nil {
		stderr("prepared-run: group %q not found, will use default gid when rendering images", common.RktGroup)
		rktgid = -1
	}

	rcfg := stage0.RunConfig{
		CommonConfig: stage0.CommonConfig{
			Store: s,
			UUID:  p.uuid,
			Debug: globalFlags.Debug,
		},
		Net:         flagNet,
		LockFd:      lfd,
		Interactive: flagInteractive,
		MDSRegister: flagMDSRegister,
		Apps:        apps,
		RktGid:      rktgid,
	}
	if globalFlags.Debug {
		stage0.InitDebug()
	}
	stage0.Run(rcfg, p.path(), globalFlags.Dir) // execs, never returns
	return 1
}
예제 #27
0
func runImageRender(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 2 {
		cmd.Usage()
		return 1
	}
	outputDir := args[1]

	s, err := store.NewStore(getDataDir())
	if err != nil {
		stderr("image render: cannot open store: %v", err)
		return 1
	}

	key, err := getStoreKeyFromAppOrHash(s, args[0])
	if err != nil {
		stderr("image render: %v", err)
		return 1
	}

	id, _, err := s.RenderTreeStore(key, false)
	if err != nil {
		stderr("image render: error rendering ACI: %v", err)
		return 1
	}
	if _, err := s.CheckTreeStore(id); err != nil {
		stderr("image render: warning: tree cache is in a bad state. Rebuilding...")
		var err error
		if id, _, err = s.RenderTreeStore(key, true); err != nil {
			stderr("image render: error rendering ACI: %v", err)
			return 1
		}
	}

	if _, err := os.Stat(outputDir); err == nil {
		if !flagRenderOverwrite {
			stderr("image render: output directory exists (try --overwrite)")
			return 1
		}

		// don't allow the user to delete the root filesystem by mistake
		if outputDir == "/" {
			stderr("image extract: this would delete your root filesystem. Refusing.")
			return 1
		}

		if err := os.RemoveAll(outputDir); err != nil {
			stderr("image render: error removing existing output dir: %v", err)
			return 1
		}
	}
	rootfsOutDir := outputDir
	if !flagRenderRootfsOnly {
		if err := os.MkdirAll(outputDir, 0755); err != nil {
			stderr("image render: error creating output directory: %v", err)
			return 1
		}
		rootfsOutDir = filepath.Join(rootfsOutDir, "rootfs")

		manifest, err := s.GetImageManifest(key)
		if err != nil {
			stderr("image render: error getting manifest: %v", err)
			return 1
		}

		mb, err := json.Marshal(manifest)
		if err != nil {
			stderr("image render: error marshalling image manifest: %v", err)
			return 1
		}

		if err := ioutil.WriteFile(filepath.Join(outputDir, "manifest"), mb, 0700); err != nil {
			stderr("image render: error writing image manifest: %v", err)
			return 1
		}
	}

	cachedTreePath := s.GetTreeStoreRootFS(id)
	if err := fileutil.CopyTree(cachedTreePath, rootfsOutDir, uid.NewBlankUidRange()); err != nil {
		stderr("image render: error copying ACI rootfs: %v", err)
		return 1
	}

	return 0
}
예제 #28
0
파일: image_extract.go 프로젝트: NeilW/rkt
func runImageExtract(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 2 {
		cmd.Usage()
		return 1
	}
	outputDir := args[1]

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("image extract: cannot open store: %v", err)
		return 1
	}

	key, err := getStoreKeyFromAppOrHash(s, args[0])
	if err != nil {
		stderr("image extract: %v", err)
		return 1
	}

	aci, err := s.ReadStream(key)
	if err != nil {
		stderr("image extract: error reading ACI from the store: %v", err)
		return 1
	}

	// ExtractTar needs an absolute path
	absOutputDir, err := filepath.Abs(outputDir)
	if err != nil {
		stderr("image extract: error converting output to an absolute path: %v", err)
		return 1
	}

	if _, err := os.Stat(absOutputDir); err == nil {
		if !flagExtractOverwrite {
			stderr("image extract: output directory exists (try --overwrite)")
			return 1
		}

		// don't allow the user to delete the root filesystem by mistake
		if absOutputDir == "/" {
			stderr("image extract: this would delete your root filesystem. Refusing.")
			return 1
		}

		if err := os.RemoveAll(absOutputDir); err != nil {
			stderr("image extract: error removing existing output dir: %v", err)
			return 1
		}
	}

	// if the user only asks for the rootfs we extract the image to a temporary
	// directory and then move/copy the rootfs to the output directory, if not
	// we just extract the image to the output directory
	extractDir := absOutputDir
	if flagExtractRootfsOnly {
		rktTmpDir, err := s.TmpDir()
		if err != nil {
			stderr("image extract: error creating rkt temporary directory: %v", err)
			return 1
		}

		tmpDir, err := ioutil.TempDir(rktTmpDir, "rkt-image-extract-")
		if err != nil {
			stderr("image extract: error creating temporary directory: %v", err)
			return 1
		}
		defer os.RemoveAll(tmpDir)

		extractDir = tmpDir
	} else {
		if err := os.MkdirAll(absOutputDir, 0755); err != nil {
			stderr("image extract: error creating output directory: %v", err)
			return 1
		}
	}

	if err := tar.ExtractTar(aci, extractDir, false, uid.NewBlankUidRange(), nil); err != nil {
		stderr("image extract: error extracting ACI: %v", err)
		return 1
	}

	if flagExtractRootfsOnly {
		rootfsDir := filepath.Join(extractDir, "rootfs")
		if err := os.Rename(rootfsDir, absOutputDir); err != nil {
			if e, ok := err.(*os.LinkError); ok && e.Err == syscall.EXDEV {
				// it's on a different device, fall back to copying
				if err := fileutil.CopyTree(rootfsDir, absOutputDir, uid.NewBlankUidRange()); err != nil {
					stderr("image extract: error copying ACI rootfs: %v", err)
					return 1
				}
			} else {
				stderr("image extract: error moving ACI rootfs: %v", err)
				return 1
			}
		}
	}

	return 0
}
예제 #29
0
func runRunPrepared(cmd *cobra.Command, args []string) (exit int) {
	if len(args) != 1 {
		cmd.Usage()
		return 1
	}

	podUUID, err := resolveUUID(args[0])
	if err != nil {
		stderr("Unable to resolve UUID: %v", err)
		return 1
	}

	if globalFlags.Dir == "" {
		log.Printf("dir unset - using temporary directory")
		var err error
		globalFlags.Dir, err = ioutil.TempDir("", "rkt")
		if err != nil {
			stderr("error creating temporary directory: %v", err)
			return 1
		}
	}

	s, err := store.NewStore(globalFlags.Dir)
	if err != nil {
		stderr("prepared-run: cannot open store: %v", err)
		return 1
	}

	p, err := getPod(podUUID.String())
	if err != nil {
		stderr("prepared-run: cannot get pod: %v", err)
		return 1
	}

	if !p.isPrepared {
		stderr("prepared-run: pod %q is not prepared", podUUID.String())
		return 1
	}

	if flagInteractive {
		ac, err := p.getAppCount()
		if err != nil {
			stderr("prepared-run: cannot get pod's app count: %v", err)
			return 1
		}
		if ac > 1 {
			stderr("prepared-run: interactive option only supports pods with one app")
			return 1
		}
	}

	if err := p.xToRun(); err != nil {
		stderr("prepared-run: cannot transition to run: %v", err)
		return 1
	}

	lfd, err := p.Fd()
	if err != nil {
		stderr("prepared-run: unable to get lock fd: %v", err)
		return 1
	}

	s1img, err := p.getStage1Hash()
	if err != nil {
		stderr("prepared-run: unable to get stage1 Hash: %v", err)
		return 1
	}

	apps, err := p.getApps()
	if err != nil {
		stderr("prepared-run: unable to get app list: %v", err)
		return 1
	}

	rcfg := stage0.RunConfig{
		CommonConfig: stage0.CommonConfig{
			Store:       s,
			Stage1Image: *s1img,
			UUID:        p.uuid,
			Debug:       globalFlags.Debug,
		},
		PrivateNet:  flagPrivateNet,
		LockFd:      lfd,
		Interactive: flagInteractive,
		MDSRegister: flagMDSRegister,
		Apps:        apps,
	}
	stage0.Run(rcfg, p.path()) // execs, never returns
	return 1
}
예제 #30
0
파일: prepare.go 프로젝트: matomesc/rkt
func runPrepare(cmd *cobra.Command, args []string) (exit int) {
	var err error
	origStdout := os.Stdout
	privateUsers := uid.NewBlankUidRange()
	if flagQuiet {
		if os.Stdout, err = os.Open("/dev/null"); err != nil {
			stderr("prepare: unable to open /dev/null: %v", err)
			return 1
		}
	}

	if flagStoreOnly && flagNoStore {
		stderr("both --store-only and --no-store specified")
		return 1
	}

	if flagPrivateUsers {
		if !common.SupportsUserNS() {
			stderr("prepare: --private-users is not supported, kernel compiled without user namespace support")
			return 1
		}
		privateUsers.SetRandomUidRange(uid.DefaultRangeCount)
	}

	if err = parseApps(&rktApps, args, cmd.Flags(), true); err != nil {
		stderr("prepare: error parsing app image arguments: %v", err)
		return 1
	}

	if len(flagPodManifest) > 0 && (len(flagPorts) > 0 || flagInheritEnv || !flagExplicitEnv.IsEmpty() || flagStoreOnly || flagNoStore) {
		stderr("prepare: conflicting flags set with --pod-manifest (see --help)")
		return 1
	}

	if rktApps.Count() < 1 && len(flagPodManifest) == 0 {
		stderr("prepare: must provide at least one image or specify the pod manifest")
		return 1
	}

	s, err := store.NewStore(getDataDir())
	if err != nil {
		stderr("prepare: cannot open store: %v", err)
		return 1
	}

	config, err := getConfig()
	if err != nil {
		stderr("prepare: cannot get configuration: %v", err)
		return 1
	}

	s1img, err := getStage1Hash(s, cmd)
	if err != nil {
		stderr("prepare: %v", err)
		return 1
	}

	fn := &image.Finder{
		S:                  s,
		Ks:                 getKeystore(),
		Headers:            config.AuthPerHost,
		DockerAuth:         config.DockerCredentialsPerRegistry,
		InsecureFlags:      globalFlags.InsecureFlags,
		Debug:              globalFlags.Debug,
		TrustKeysFromHttps: globalFlags.TrustKeysFromHttps,

		StoreOnly: flagStoreOnly,
		NoStore:   flagNoStore,
		WithDeps:  true,
	}
	if err := fn.FindImages(&rktApps); err != nil {
		stderr("prepare: %v", err)
		return 1
	}

	p, err := newPod()
	if err != nil {
		stderr("prepare: error creating new pod: %v", err)
		return 1
	}

	cfg := stage0.CommonConfig{
		Store:       s,
		Stage1Image: *s1img,
		UUID:        p.uuid,
		Debug:       globalFlags.Debug,
	}

	pcfg := stage0.PrepareConfig{
		CommonConfig: &cfg,
		UseOverlay:   !flagNoOverlay && common.SupportsOverlay(),
		PrivateUsers: privateUsers,
	}

	if len(flagPodManifest) > 0 {
		pcfg.PodManifest = flagPodManifest
	} else {
		pcfg.Ports = []types.ExposedPort(flagPorts)
		pcfg.InheritEnv = flagInheritEnv
		pcfg.ExplicitEnv = flagExplicitEnv.Strings()
		pcfg.Apps = &rktApps
	}

	if globalFlags.Debug {
		stage0.InitDebug()
	}

	keyLock, err := lock.SharedKeyLock(lockDir(), common.PrepareLock)
	if err != nil {
		stderr("rkt: cannot get shared prepare lock: %v", err)
		return 1
	}
	if err = stage0.Prepare(pcfg, p.path(), p.uuid); err != nil {
		stderr("prepare: error setting up stage0: %v", err)
		keyLock.Close()
		return 1
	}
	keyLock.Close()

	if err := p.sync(); err != nil {
		stderr("prepare: error syncing pod data: %v", err)
		return 1
	}

	if err := p.xToPrepared(); err != nil {
		stderr("prepare: error transitioning to prepared: %v", err)
		return 1
	}

	os.Stdout = origStdout // restore output in case of --quiet
	stdout("%s", p.uuid.String())

	return 0
}