func TestGetStoreKeyFromApp(t *testing.T) { dir, err := ioutil.TempDir("", "fetch-image") if err != nil { t.Fatalf("error creating tempdir: %v", err) } defer os.RemoveAll(dir) s, err := store.NewStore(dir) if err != nil { t.Fatalf("unexpected error %v", err) } defer s.Dump(false) // Test an aci without os and arch labels a, err := aci.NewBasicACI(dir, "example.com/app") defer a.Close() if err != nil { t.Fatalf("unexpected error %v", err) } // Rewind the ACI if _, err := a.Seek(0, 0); err != nil { t.Fatalf("unexpected error %v", err) } _, err = s.WriteACI(a, false) if err != nil { t.Fatalf("unexpected error %v", err) } _, err = getStoreKeyFromApp(s, "example.com/app") if err != nil { t.Fatalf("unexpected error: %v", err) } }
func getStore() *store.Store { s, err := store.NewStore(storeDir) if err != nil { log.Fatalf("Unable to open a new ACI store: %s", err) } return s }
func importOciBundle(cmd *cobra.Command, args []string) (exit int) { //command is "rkt image import-oci oci-bundle-path" if len(args) < 1 { fmt.Printf("command should be: rkt image import-oci ocibundle") return 1 } aciImage, err := Oci2aciImage(args[0]) if err != nil { fmt.Printf("convert oci bundle to aci image error: %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("error opening ACI file %s: %v", aciImage, err) return 1 } key, err := s.WriteACI(aciFile, true) if err != nil { fmt.Printf("error write ACI file: %v", err) return 1 } fmt.Println(key) 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 runFetch(cmd *cobra.Command, args []string) (exit int) { if err := parseApps(&rktApps, args, cmd.Flags(), false); err != nil { stderr.PrintE("unable to parse arguments", err) return 1 } if rktApps.Count() < 1 { stderr.Print("must provide at least one image") return 1 } if flagStoreOnly && flagNoStore { stderr.Print("both --store-only and --no-store specified") return 1 } s, err := store.NewStore(getDataDir()) if err != nil { stderr.PrintE("cannot open store", err) return 1 } ks := getKeystore() config, err := getConfig() if err != nil { stderr.PrintE("cannot get configuration", 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.Print(hash) return nil }) if err != nil { stderr.Error(err) return 1 } return }
// deletePod cleans up files and resource associated with the pod // pod must be under exclusive lock and be in either ExitedGarbage // or Garbage state func deletePod(p *pod) { if !p.isExitedGarbage && !p.isGarbage { panic(fmt.Sprintf("logic error: deletePod called with non-garbage pod %q (status %q)", p.uuid, p.getState())) } if p.isExitedGarbage { s, err := store.NewStore(getDataDir()) if err != nil { stderr("Cannot open store: %v", err) return } defer s.Close() stage1TreeStoreID, err := p.getStage1TreeStoreID() if err != nil { stderr("Error getting stage1 treeStoreID: %v", err) return } stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID) // execute stage1's GC if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil { stderr("Stage1 GC of pod %q failed: %v", p.uuid, err) return } if p.usesOverlay() { apps, err := p.getApps() if err != nil { stderr("Error retrieving app hashes from pod manifest: %v", err) return } for _, a := range apps { dest := filepath.Join(common.AppPath(p.path(), a.Name), "rootfs") if err := syscall.Unmount(dest, 0); err != nil { // machine could have been rebooted and mounts lost. // ignore "does not exist" and "not a mount point" errors if err != syscall.ENOENT && err != syscall.EINVAL { stderr("Error unmounting app at %v: %v", dest, err) } } } s1 := filepath.Join(common.Stage1ImagePath(p.path()), "rootfs") if err := syscall.Unmount(s1, 0); err != nil { // machine could have been rebooted and mounts lost. // ignore "does not exist" and "not a mount point" errors if err != syscall.ENOENT && err != syscall.EINVAL { stderr("Error unmounting stage1 at %v: %v", s1, err) return } } } } if err := os.RemoveAll(p.path()); err != nil { stderr("Unable to remove pod %q: %v", p.uuid, err) } }
func runRmImage(cmd *cobra.Command, args []string) (exit int) { if len(args) < 1 { stderr("rkt: Must provide at least one image key") return 1 } s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("rkt: cannot open store: %v", err) return 1 } //TODO(sgotti) Which return code to use when the removal fails only for some images? done := 0 errors := 0 staleErrors := 0 for _, pkey := range args { errors++ h, err := types.NewHash(pkey) if err != nil { stderr("rkt: wrong imageID %q: %v", pkey, err) continue } key, err := s.ResolveKey(h.String()) if err != nil { stderr("rkt: imageID %q not valid: %v", pkey, err) continue } if key == "" { stderr("rkt: imageID %q doesn't exists", pkey) continue } if err = s.RemoveACI(key); err != nil { if serr, ok := err.(*store.StoreRemovalError); ok { staleErrors++ stderr("rkt: some files cannot be removed for imageID %q: %v", pkey, serr) } else { stderr("rkt: error removing aci for imageID %q: %v", pkey, err) continue } } stdout("rkt: successfully removed aci for imageID: %q", pkey) errors-- done++ } if done > 0 { stderr("rkt: %d image(s) successfully removed", done) } if errors > 0 { stderr("rkt: %d image(s) cannot be removed", errors) } if staleErrors > 0 { stderr("rkt: %d image(s) removed but left some stale files", staleErrors) } 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 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 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.PrintE("problem retrieving pod", err) return 1 } defer p.Close() if !p.isRunning() { stderr.Printf("pod %q isn't currently running", p.uuid) return 1 } podPID, err := p.getContainerPID1() if err != nil { stderr.PrintE(fmt.Sprintf("unable to determine the pid for pod %q", p.uuid), err) return 1 } appName, err := getAppName(p) if err != nil { stderr.PrintE("unable to determine app name", err) return 1 } argv, err := getEnterArgv(p, args) if err != nil { stderr.PrintE("enter failed", err) return 1 } s, err := store.NewStore(getDataDir()) if err != nil { stderr.PrintE("cannot open store", err) return 1 } stage1TreeStoreID, err := p.getStage1TreeStoreID() if err != nil { stderr.PrintE("error getting stage1 treeStoreID", err) return 1 } stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID) if err = stage0.Enter(p.path(), podPID, *appName, stage1RootFS, argv); err != nil { stderr.PrintE("enter failed", 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 newV1AlphaAPIServer() (*v1AlphaAPIServer, error) { s, err := store.NewStore(getDataDir()) if err != nil { return nil, err } return &v1AlphaAPIServer{ store: s, }, nil }
func newV1AlphaAPIServer() (*v1AlphaAPIServer, error) { s, err := store.NewStore(globalFlags.Dir) if err != nil { return nil, err } return &v1AlphaAPIServer{ store: s, }, nil }
func runImages(cmd *cobra.Command, args []string) (exit int) { if !flagNoLegend { headerFields := []string{} for _, f := range flagImagesFields { headerFields = append(headerFields, ImagesFieldHeaderMap[f]) } fmt.Fprintf(tabOut, "%s\n", strings.Join(headerFields, "\t")) } s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("images: cannot open store: %v\n", err) return 1 } sortAciinfoFields := []string{} for _, f := range flagImagesSortFields { sortAciinfoFields = append(sortAciinfoFields, ImagesFieldAciInfoMap[f]) } aciInfos, err := s.GetAllACIInfos(sortAciinfoFields, bool(flagImagesSortAsc)) if err != nil { stderr("images: unable to get aci infos: %v", err) return } for _, aciInfo := range aciInfos { im, err := s.GetImageManifest(aciInfo.BlobKey) if err != nil { // ignore aciInfo with missing image manifest as it can be deleted in the meantime continue } version, ok := im.Labels.Get("version") for _, f := range flagImagesFields { switch f { case keyField: fmt.Fprintf(tabOut, "%s", aciInfo.BlobKey) case nameField: fmt.Fprintf(tabOut, "%s", aciInfo.Name) if ok { fmt.Fprintf(tabOut, ":%s", version) } case importTimeField: fmt.Fprintf(tabOut, "%s", aciInfo.ImportTime.Format(defaultTimeLayout)) case latestField: fmt.Fprintf(tabOut, "%t", aciInfo.Latest) } fmt.Fprintf(tabOut, "\t") } fmt.Fprintf(tabOut, "\n") } tabOut.Flush() return 0 }
func runGcImage(cmd *cobra.Command, args []string) (exit int) { s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("rkt: cannot open store: %v", err) return 1 } if err := gcTreeStore(s); err != nil { stderr("rkt: failed to remove unreferenced treestores: %v", err) return 1 } return 0 }
func runFetch(args []string) (exit int) { if err := parseApps(&rktApps, args, &fetchFlags, 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 } 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, }, withDeps: true, } err = rktApps.Walk(func(app *apps.App) error { hash, err := ft.fetchImage(app.Image, app.Asc, true) if err != nil { return err } shortHash := types.ShortHash(hash) fmt.Println(shortHash) return nil }) if err != nil { stderr("%v", err) return 1 } return }
// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir() func emptyExitedGarbage(gracePeriod time.Duration) error { if err := walkPods(includeExitedGarbageDir, func(p *pod) { gp := p.path() st := &syscall.Stat_t{} if err := syscall.Lstat(gp, st); err != nil { if err != syscall.ENOENT { stderr("Unable to stat %q, ignoring: %v", gp, err) } return } if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) { if err := p.ExclusiveLock(); err != nil { return } stdout("Garbage collecting pod %q", p.uuid) s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("Cannot open store: %v", err) return } stage1ID, err := p.getStage1Hash() if err != nil { stderr("Error getting stage1 hash") return } stage1RootFS := s.GetTreeStoreRootFS(stage1ID.String()) // execute stage1's GC if err := stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil { stderr("Stage1 GC of pod %q failed: %v", p.uuid, err) return } if err := os.RemoveAll(gp); err != nil { stderr("Unable to remove pod %q: %v", p.uuid, err) } } }); err != nil { return err } return nil }
func runGcImage(cmd *cobra.Command, args []string) (exit int) { s, err := store.NewStore(getDataDir()) if err != nil { stderr("rkt: cannot open store: %v", err) return 1 } if err := gcTreeStore(s); err != nil { stderr("rkt: failed to remove unreferenced treestores: %v", err) return 1 } if err := gcStore(s, flagImageGracePeriod); err != nil { stderr("rkt: %v", err) return 1 } return 0 }
func runRmImage(cmd *cobra.Command, args []string) (exit int) { if len(args) < 1 { stderr.Print("must provide at least one image ID") return 1 } s, err := store.NewStore(getDataDir()) if err != nil { stderr.PrintE("cannot open store", err) return 1 } if err := rmImages(s, args); err != nil { stderr.Error(err) return 1 } return 0 }
func runGCImage(cmd *cobra.Command, args []string) (exit int) { s, err := store.NewStore(getDataDir()) if err != nil { stderr.PrintE("cannot open store", err) return 1 } if err := gcTreeStore(s); err != nil { stderr.PrintE("failed to remove unreferenced treestores", err) return 1 } if err := gcStore(s, flagImageGracePeriod); err != nil { stderr.Error(err) return 1 } return 0 }
func runRmImage(cmd *cobra.Command, args []string) (exit int) { if len(args) < 1 { stderr("rkt: Must provide at least one image ID") return 1 } s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("rkt: cannot open store: %v", err) return 1 } if err := rmImages(s, args); err != nil { stderr("rKt: %v", err) return 1 } return 0 }
// deletePod cleans up files and resource associated with the pod // pod must be under exclusive lock and be in either ExitedGarbage // or Garbage state func deletePod(p *pod) { if !p.isExitedGarbage && !p.isGarbage { stderr.Panicf("logic error: deletePod called with non-garbage pod %q (status %q)", p.uuid, p.getState()) } if p.isExitedGarbage { s, err := store.NewStore(getDataDir()) if err != nil { stderr.PrintE("cannot open store", err) return } defer s.Close() // execute stage1's GC stage1TreeStoreID, err := p.getStage1TreeStoreID() if err != nil { stderr.PrintE("error getting stage1 treeStoreID", err) stderr.Print("skipping stage1 GC") } else { if globalFlags.Debug { stage0.InitDebug() } stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID) if err = stage0.GC(p.path(), p.uuid, stage1RootFS); err != nil { stderr.PrintE(fmt.Sprintf("problem performing stage1 GC on %q", p.uuid), err) } } // unmount all leftover mounts if err := stage0.MountGC(p.path(), p.uuid.String()); err != nil { stderr.PrintE(fmt.Sprintf("GC of leftover mounts for pod %q failed", p.uuid), err) return } } if err := os.RemoveAll(p.path()); err != nil { stderr.PrintE(fmt.Sprintf("unable to remove pod %q", p.uuid), err) os.Exit(1) } }
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 runImageCatManifest(cmd *cobra.Command, args []string) (exit int) { if len(args) != 1 { cmd.Usage() return 1 } s, err := store.NewStore(getDataDir()) if err != nil { stderr.PrintE("cannot open store", err) return 1 } key, err := getStoreKeyFromAppOrHash(s, args[0]) if err != nil { stderr.Error(err) return 1 } manifest, err := s.GetImageManifest(key) if err != nil { stderr.PrintE("cannot get image manifest", err) return 1 } var b []byte if flagPrettyPrint { b, err = json.MarshalIndent(manifest, "", "\t") } else { b, err = json.Marshal(manifest) } if err != nil { stderr.PrintE("cannot read the image manifest", err) return 1 } stdout.Print(string(b)) return 0 }
// deletePod cleans up files and resource associated with the pod // pod must be under exclusive lock and be in either ExitedGarbage // or Garbage state func deletePod(p *pod) { if !p.isExitedGarbage && !p.isGarbage { panic(fmt.Sprintf("Logic error: deletePod called with non-garbage pod %q (status %q)", p.uuid, p.getState())) } if p.isExitedGarbage { s, err := store.NewStore(getDataDir()) if err != nil { stderr("Cannot open store: %v", err) return } defer s.Close() // execute stage1's GC stage1TreeStoreID, err := p.getStage1TreeStoreID() if err != nil { stderr("Error getting stage1 treeStoreID: %v", err) stderr("Skipping stage1 GC") } else { stage1RootFS := s.GetTreeStoreRootFS(stage1TreeStoreID) if err = stage0.GC(p.path(), p.uuid, stage1RootFS, globalFlags.Debug); err != nil { stderr("Problem performing stage1 GC on %q: %v", p.uuid, err) } } // unmount all leftover mounts if err := stage0.MountGC(p.path(), p.uuid.String()); err != nil { stderr("GC of leftover mounts for pod %q failed: %v\n", p.uuid, err) return } } if err := os.RemoveAll(p.path()); err != nil { stderr("Unable to remove pod %q: %v", p.uuid, err) os.Exit(1) } }
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 runRunPrepared(args []string) (exit int) { if len(args) != 1 { printCommandUsageByName(cmdRunPreparedName) 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 } imgs, err := p.getAppsHashes() if err != nil { stderr("prepared-run: unable to get apps hashes: %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, Images: imgs, } stage0.Run(rcfg, p.path()) // 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 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 TestFetchImage(t *testing.T) { dir, err := ioutil.TempDir("", "fetch-image") if err != nil { t.Fatalf("error creating tempdir: %v", err) } defer os.RemoveAll(dir) s, err := store.NewStore(dir) if err != nil { t.Fatalf("unexpected error %v", err) } defer s.Dump(false) ks, ksPath, err := keystore.NewTestKeystore() if err != nil { t.Errorf("unexpected error %v", err) } defer os.RemoveAll(ksPath) key := keystoretest.KeyMap["example.com/app"] if _, err := ks.StoreTrustedKeyPrefix("example.com/app", bytes.NewBufferString(key.ArmoredPublicKey)); err != nil { t.Fatalf("unexpected error %v", err) } a, err := aci.NewBasicACI(dir, "example.com/app") defer a.Close() if err != nil { t.Fatalf("unexpected error %v", err) } // Rewind the ACI if _, err := a.Seek(0, 0); err != nil { t.Fatalf("unexpected error %v", err) } asc, err := aci.NewDetachedSignature(key.ArmoredPrivateKey, a) if err != nil { t.Fatalf("unexpected error %v", err) } // Rewind the ACI. if _, err := a.Seek(0, 0); err != nil { t.Fatalf("unexpected error %v", err) } ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch filepath.Ext(r.URL.Path) { case ".aci": io.Copy(w, a) return case ".asc": io.Copy(w, asc) return default: t.Fatalf("unknown extension %v", r.URL.Path) } })) defer ts.Close() ft := &fetcher{ imageActionData: imageActionData{ s: s, ks: ks, }, } _, err = ft.fetchImage(fmt.Sprintf("%s/app.aci", ts.URL), "", true) if err != nil { t.Fatalf("unexpected error: %v", err) } }