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