func runRunPrepared(cmd *cobra.Command, args []string) (exit int) { if len(args) != 1 { cmd.Usage() return 254 } p, err := pkgPod.PodFromUUIDString(getDataDir(), args[0]) if err != nil { stderr.PrintE("problem retrieving pod", err) return 254 } defer p.Close() s, err := imagestore.NewStore(storeDir()) if err != nil { stderr.PrintE("cannot open store", err) return 254 } ts, err := treestore.NewStore(treeStoreDir(), s) if err != nil { stderr.PrintE("cannot open treestore", err) return 254 } if p.State() != pkgPod.Prepared { stderr.Printf("pod %q is not prepared", p.UUID) return 254 } _, manifest, err := p.PodManifest() if err != nil { stderr.PrintE("cannot read pod manifest", err) return 254 } if flagInteractive { if len(manifest.Apps) > 1 { stderr.Print("interactive option only supports pods with one app") return 254 } } // 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.Error(err) return 254 } } if err := p.ToRun(); err != nil { stderr.PrintE("cannot transition to run", err) return 254 } lfd, err := p.Fd() if err != nil { stderr.PrintE("unable to get lock fd", err) return 254 } rktgid, err := common.LookupGid(common.RktGroup) if err != nil { stderr.Printf("group %q not found, will use default gid when rendering images", common.RktGroup) rktgid = -1 } ovlOk := true if err := common.PathSupportsOverlay(getDataDir()); err != nil { if oerr, ok := err.(common.ErrOverlayUnsupported); ok { stderr.Printf("disabling overlay support: %q", oerr.Error()) ovlOk = false } else { stderr.PrintE("error determining overlay support", err) return 254 } } ovlPrep := p.UsesOverlay() // should not happen, maybe the data directory moved from an overlay-enabled fs to another location // between prepare and run-prepared if ovlPrep && !ovlOk { stderr.Print("unable to run prepared overlay-enabled pod: overlay not supported") return 254 } DNSConfMode, DNSConfig, HostsEntries, err := parseDNSFlags(flagHostsEntries, flagDNS, flagDNSSearch, flagDNSOpt, flagDNSDomain) if err != nil { stderr.PrintE("error with dns flags", err) return 254 } rcfg := stage0.RunConfig{ CommonConfig: &stage0.CommonConfig{ DataDir: getDataDir(), Store: s, TreeStore: ts, UUID: p.UUID, Debug: globalFlags.Debug, }, Net: flagNet, LockFd: lfd, Interactive: flagInteractive, DNSConfMode: DNSConfMode, DNSConfig: DNSConfig, HostsEntries: *HostsEntries, MDSRegister: flagMDSRegister, Apps: manifest.Apps, RktGid: rktgid, Hostname: flagHostname, InsecureCapabilities: globalFlags.InsecureFlags.SkipCapabilities(), InsecurePaths: globalFlags.InsecureFlags.SkipPaths(), InsecureSeccomp: globalFlags.InsecureFlags.SkipSeccomp(), UseOverlay: ovlPrep && ovlOk, } if globalFlags.Debug { stage0.InitDebug() } stage0.Run(rcfg, p.Path(), getDataDir()) // execs, never returns return 254 }
func runPrepare(cmd *cobra.Command, args []string) (exit int) { var err error origStdout := os.Stdout privateUsers := user.NewBlankUidRange() if flagQuiet { if os.Stdout, err = os.Open("/dev/null"); err != nil { stderr.PrintE("unable to open /dev/null", err) return 254 } } if flagStoreOnly && flagNoStore { stderr.Print("both --store-only and --no-store specified") return 254 } if flagPrivateUsers { if !common.SupportsUserNS() { stderr.Print("--private-users is not supported, kernel compiled without user namespace support") return 254 } privateUsers.SetRandomUidRange(user.DefaultRangeCount) } if err = parseApps(&rktApps, args, cmd.Flags(), true); err != nil { stderr.PrintE("error parsing app image arguments", err) return 254 } if len(flagPodManifest) > 0 && (rktApps.Count() > 0 || (*appsVolume)(&rktApps).String() != "" || (*appMount)(&rktApps).String() != "" || len(flagPorts) > 0 || flagStoreOnly || flagNoStore || flagInheritEnv || !flagExplicitEnv.IsEmpty() || !flagEnvFromFile.IsEmpty()) { stderr.Print("conflicting flags set with --pod-manifest (see --help)") return 254 } if rktApps.Count() < 1 && len(flagPodManifest) == 0 { stderr.Print("must provide at least one image or specify the pod manifest") return 254 } s, err := imagestore.NewStore(storeDir()) if err != nil { stderr.PrintE("cannot open store", err) return 254 } ts, err := treestore.NewStore(treeStoreDir(), s) if err != nil { stderr.PrintE("cannot open treestore", err) return 254 } config, err := getConfig() if err != nil { stderr.PrintE("cannot get configuration", err) return 254 } s1img, err := getStage1Hash(s, ts, config) if err != nil { stderr.Error(err) return 254 } fn := &image.Finder{ S: s, Ts: ts, 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.PrintE("error finding images", err) return 254 } p, err := pkgPod.NewPod(getDataDir()) if err != nil { stderr.PrintE("error creating new pod", err) return 254 } cfg := stage0.CommonConfig{ DataDir: getDataDir(), Store: s, TreeStore: ts, Stage1Image: *s1img, UUID: p.UUID, Debug: globalFlags.Debug, } ovlOk := true if err := common.PathSupportsOverlay(getDataDir()); err != nil { if oerr, ok := err.(common.ErrOverlayUnsupported); ok { stderr.Printf("disabling overlay support: %q", oerr.Error()) ovlOk = false } else { stderr.PrintE("error determining overlay support", err) return 254 } } pcfg := stage0.PrepareConfig{ CommonConfig: &cfg, UseOverlay: !flagNoOverlay && ovlOk, PrivateUsers: privateUsers, SkipTreeStoreCheck: globalFlags.InsecureFlags.SkipOnDiskCheck(), } if len(flagPodManifest) > 0 { pcfg.PodManifest = flagPodManifest } else { pcfg.Ports = []types.ExposedPort(flagPorts) pcfg.InheritEnv = flagInheritEnv pcfg.ExplicitEnv = flagExplicitEnv.Strings() pcfg.EnvFromFile = flagEnvFromFile.Strings() pcfg.Apps = &rktApps } if globalFlags.Debug { stage0.InitDebug() } keyLock, err := lock.SharedKeyLock(lockDir(), common.PrepareLock) if err != nil { stderr.PrintE("cannot get shared prepare lock", err) return 254 } if err = stage0.Prepare(pcfg, p.Path(), p.UUID); err != nil { stderr.PrintE("error setting up stage0", err) keyLock.Close() return 254 } keyLock.Close() if err := p.Sync(); err != nil { stderr.PrintE("error syncing pod data", err) return 254 } if err := p.ToPrepared(); err != nil { stderr.PrintE("error transitioning to prepared", err) return 254 } os.Stdout = origStdout // restore output in case of --quiet stdout.Printf("%s", p.UUID.String()) return 0 }
func runAppSandbox(cmd *cobra.Command, args []string) int { s, err := imagestore.NewStore(storeDir()) if err != nil { stderr.PrintE("cannot open store", err) return 1 } ts, err := treestore.NewStore(treeStoreDir(), s) if err != nil { stderr.PrintE("cannot open treestore", err) return 1 } config, err := getConfig() if err != nil { stderr.PrintE("cannot get configuration", err) return 1 } s1img, err := getStage1Hash(s, ts, config) if err != nil { stderr.Error(err) return 1 } p, err := pod.NewPod(getDataDir()) if err != nil { stderr.PrintE("error creating new pod", err) return 1 } if flagUUIDFileSave != "" { if err := pod.WriteUUIDToFile(p.UUID, flagUUIDFileSave); err != nil { stderr.PrintE("error saving pod UUID to file", err) return 1 } } processLabel, mountLabel, err := label.InitLabels("/var/run/rkt/mcs", []string{}) if err != nil { stderr.PrintE("error initialising SELinux", err) return 1 } p.MountLabel = mountLabel cfg := stage0.CommonConfig{ DataDir: getDataDir(), MountLabel: mountLabel, ProcessLabel: processLabel, Store: s, TreeStore: ts, Stage1Image: *s1img, UUID: p.UUID, Debug: globalFlags.Debug, Mutable: true, } ovlOk := true if err := common.PathSupportsOverlay(getDataDir()); err != nil { if oerr, ok := err.(common.ErrOverlayUnsupported); ok { stderr.Printf("disabling overlay support: %q", oerr.Error()) ovlOk = false } else { stderr.PrintE("error determining overlay support", err) return 1 } } useOverlay := !flagNoOverlay && ovlOk pcfg := stage0.PrepareConfig{ CommonConfig: &cfg, UseOverlay: useOverlay, PrivateUsers: user.NewBlankUidRange(), SkipTreeStoreCheck: globalFlags.InsecureFlags.SkipOnDiskCheck(), Apps: &rktApps, Ports: []types.ExposedPort(flagAppPorts), UserAnnotations: parseAnnotations(&flagAnnotations), UserLabels: parseLabels(&flagLabels), } if globalFlags.Debug { stage0.InitDebug() } keyLock, err := lock.SharedKeyLock(lockDir(), common.PrepareLock) if err != nil { stderr.PrintE("cannot get shared prepare lock", err) return 1 } err = stage0.Prepare(pcfg, p.Path(), p.UUID) if err != nil { stderr.PrintE("error setting up stage0", err) keyLock.Close() return 1 } keyLock.Close() // get the lock fd for run lfd, err := p.Fd() if err != nil { stderr.PrintE("error getting pod lock fd", err) return 1 } // skip prepared by jumping directly to run, we own this pod if err := p.ToRun(); err != nil { stderr.PrintE("unable to transition to run", err) return 1 } rktgid, err := common.LookupGid(common.RktGroup) if err != nil { stderr.Printf("group %q not found, will use default gid when rendering images", common.RktGroup) rktgid = -1 } DNSConfMode, DNSConfig, HostsEntries, err := parseDNSFlags(flagHostsEntries, flagDNS, flagDNSSearch, flagDNSOpt, flagDNSDomain) if err != nil { stderr.PrintE("error with dns flags", err) return 1 } rcfg := stage0.RunConfig{ CommonConfig: &cfg, Net: flagNet, LockFd: lfd, Interactive: true, DNSConfMode: DNSConfMode, DNSConfig: DNSConfig, MDSRegister: false, LocalConfig: globalFlags.LocalConfigDir, RktGid: rktgid, Hostname: flagHostname, InsecureCapabilities: globalFlags.InsecureFlags.SkipCapabilities(), InsecurePaths: globalFlags.InsecureFlags.SkipPaths(), InsecureSeccomp: globalFlags.InsecureFlags.SkipSeccomp(), UseOverlay: useOverlay, HostsEntries: *HostsEntries, } _, manifest, err := p.PodManifest() if err != nil { stderr.PrintE("cannot get the pod manifest", err) return 1 } rcfg.Apps = manifest.Apps stage0.Run(rcfg, p.Path(), getDataDir()) // execs, never returns return 1 }
func runRun(cmd *cobra.Command, args []string) (exit int) { privateUsers := user.NewBlankUidRange() err := parseApps(&rktApps, args, cmd.Flags(), true) if err != nil { stderr.PrintE("error parsing app image arguments", err) return 254 } if flagStoreOnly && flagNoStore { stderr.Print("both --store-only and --no-store specified") return 254 } if flagPrivateUsers { if !common.SupportsUserNS() { stderr.Print("--private-users is not supported, kernel compiled without user namespace support") return 254 } privateUsers.SetRandomUidRange(user.DefaultRangeCount) } if len(flagPorts) > 0 && flagNet.None() { stderr.Print("--port flag does not work with 'none' networking") return 254 } if len(flagPorts) > 0 && flagNet.Host() { stderr.Print("--port flag does not work with 'host' networking") return 254 } if flagMDSRegister && flagNet.None() { stderr.Print("--mds-register flag does not work with --net=none. Please use 'host', 'default' or an equivalent network") return 254 } if len(flagPodManifest) > 0 && (rktApps.Count() > 0 || (*appsVolume)(&rktApps).String() != "" || (*appMount)(&rktApps).String() != "" || len(flagPorts) > 0 || flagStoreOnly || flagNoStore || flagInheritEnv || !flagExplicitEnv.IsEmpty() || !flagEnvFromFile.IsEmpty()) { stderr.Print("conflicting flags set with --pod-manifest (see --help)") return 254 } if flagInteractive && rktApps.Count() > 1 { stderr.Print("interactive option only supports one image") return 254 } if rktApps.Count() < 1 && len(flagPodManifest) == 0 { stderr.Print("must provide at least one image or specify the pod manifest") return 254 } s, err := imagestore.NewStore(storeDir()) if err != nil { stderr.PrintE("cannot open store", err) return 254 } ts, err := treestore.NewStore(treeStoreDir(), s) if err != nil { stderr.PrintE("cannot open treestore", err) return 254 } config, err := getConfig() if err != nil { stderr.PrintE("cannot get configuration", err) return 254 } s1img, err := getStage1Hash(s, ts, config) if err != nil { stderr.Error(err) return 254 } fn := &image.Finder{ S: s, Ts: ts, 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.Error(err) return 254 } p, err := pkgPod.NewPod(getDataDir()) if err != nil { stderr.PrintE("error creating new pod", err) return 254 } // if requested, write out pod UUID early so "rkt rm" can // clean it up even if something goes wrong if flagUUIDFileSave != "" { if err := pkgPod.WriteUUIDToFile(p.UUID, flagUUIDFileSave); err != nil { stderr.PrintE("error saving pod UUID to file", err) return 254 } } processLabel, mountLabel, err := label.InitLabels("/var/run/rkt/mcs", []string{}) if err != nil { stderr.PrintE("error initialising SELinux", err) return 254 } p.MountLabel = mountLabel cfg := stage0.CommonConfig{ DataDir: getDataDir(), MountLabel: mountLabel, ProcessLabel: processLabel, Store: s, TreeStore: ts, Stage1Image: *s1img, UUID: p.UUID, Debug: globalFlags.Debug, Mutable: false, } ovlOk := true if err := common.PathSupportsOverlay(getDataDir()); err != nil { if oerr, ok := err.(common.ErrOverlayUnsupported); ok { stderr.Printf("disabling overlay support: %q", oerr.Error()) ovlOk = false } else { stderr.PrintE("error determining overlay support", err) return 254 } } useOverlay := !flagNoOverlay && ovlOk pcfg := stage0.PrepareConfig{ CommonConfig: &cfg, UseOverlay: useOverlay, PrivateUsers: privateUsers, SkipTreeStoreCheck: globalFlags.InsecureFlags.SkipOnDiskCheck(), } if len(flagPodManifest) > 0 { pcfg.PodManifest = flagPodManifest } else { pcfg.Ports = []types.ExposedPort(flagPorts) pcfg.InheritEnv = flagInheritEnv pcfg.ExplicitEnv = flagExplicitEnv.Strings() pcfg.EnvFromFile = flagEnvFromFile.Strings() pcfg.Apps = &rktApps } if globalFlags.Debug { stage0.InitDebug() } keyLock, err := lock.SharedKeyLock(lockDir(), common.PrepareLock) if err != nil { stderr.PrintE("cannot get shared prepare lock", err) return 254 } err = stage0.Prepare(pcfg, p.Path(), p.UUID) if err != nil { stderr.PrintE("error setting up stage0", err) keyLock.Close() return 254 } keyLock.Close() // get the lock fd for run lfd, err := p.Fd() if err != nil { stderr.PrintE("error getting pod lock fd", err) return 254 } // skip prepared by jumping directly to run, we own this pod if err := p.ToRun(); err != nil { stderr.PrintE("unable to transition to run", err) return 254 } rktgid, err := common.LookupGid(common.RktGroup) if err != nil { stderr.Printf("group %q not found, will use default gid when rendering images", common.RktGroup) rktgid = -1 } DNSConfMode, DNSConfig, HostsEntries, err := parseDNSFlags(flagHostsEntries, flagDNS, flagDNSSearch, flagDNSOpt, flagDNSDomain) if err != nil { stderr.PrintE("error with dns flags", err) return 254 } rcfg := stage0.RunConfig{ CommonConfig: &cfg, Net: flagNet, LockFd: lfd, Interactive: flagInteractive, DNSConfMode: DNSConfMode, DNSConfig: DNSConfig, MDSRegister: flagMDSRegister, LocalConfig: globalFlags.LocalConfigDir, RktGid: rktgid, Hostname: flagHostname, InsecureCapabilities: globalFlags.InsecureFlags.SkipCapabilities(), InsecurePaths: globalFlags.InsecureFlags.SkipPaths(), InsecureSeccomp: globalFlags.InsecureFlags.SkipSeccomp(), UseOverlay: useOverlay, HostsEntries: *HostsEntries, } _, manifest, err := p.PodManifest() if err != nil { stderr.PrintE("cannot get the pod manifest", err) return 254 } if len(manifest.Apps) == 0 { stderr.Print("pod must contain at least one application") return 254 } rcfg.Apps = manifest.Apps stage0.Run(rcfg, p.Path(), getDataDir()) // execs, never returns return 254 }