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 }
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 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 }
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 }
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) }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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) 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 } } // 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 } rcfg := stage0.RunConfig{ CommonConfig: stage0.CommonConfig{ Store: s, UUID: p.uuid, Debug: globalFlags.Debug, }, PrivateNet: flagPrivateNet, LockFd: lfd, Interactive: flagInteractive, MDSRegister: flagMDSRegister, Apps: apps, } stage0.Run(rcfg, p.path(), globalFlags.Dir) // execs, never returns return 1 }
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 }
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 }