func cmdShowImage(img *jetpack.Image) error { output := fmt.Sprintf("ID\t%v\nName\t%v\nTimestamp\t%v\n", img.Hash, img, img.Timestamp.Format(time.RFC3339), ) if len(img.Manifest.Dependencies) > 0 { output += "Dependencies" for _, dep := range img.Manifest.Dependencies { if dimg, err := Host.GetImage(*dep.ImageID, "", nil); err != nil { // FIXME: export GetImageDependency? return errors.Trace(err) } else { output += fmt.Sprintf("\t%v %v\n", types.ShortHash(dimg.Hash.String()), dimg) } } } if app := img.Manifest.App; app != nil { output += "App\t\n" + appDetails(app) } tw := tabwriter.NewWriter(os.Stdout, 2, 8, 2, ' ', 0) fmt.Fprint(tw, output) return tw.Flush() }
func doListF(w io.Writer, header string, items [][]string) error { if !LongHash { for i := range items { items[i][0] = types.ShortHash(items[i][0]) } } lines := make([]string, len(items)) for i, item := range items { if Quiet { lines[i] = item[0] } else { lines[i] = strings.Join(item, "\t") } } sort.Strings(lines) if !(Quiet || MachineFriendly || header == "") { lines = append([]string{header}, lines...) } output := strings.Join(lines, "\n") if MachineFriendly { _, err := fmt.Println(output) return err } else { tw := tabwriter.NewWriter(w, 2, 8, 2, ' ', 0) fmt.Fprintln(tw, output) return tw.Flush() } }
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 }
func TestResumedFetch(t *testing.T) { image := "rkt-inspect-implicit-fetch.aci" imagePath := patchTestACI(image, "--exec=/inspect") defer os.Remove(imagePath) hash := types.ShortHash("sha512-" + getHashOrPanic(imagePath)) kill := make(chan struct{}) reportkill := make(chan struct{}) shouldInterrupt := &synchronizedBool{} shouldInterrupt.Write(true) server := httptest.NewServer(testServerHandler(t, shouldInterrupt, imagePath, kill, reportkill)) defer server.Close() ctx := testutils.NewRktRunCtx() defer ctx.Cleanup() cmd := fmt.Sprintf("%s --no-store --insecure-options=image fetch %s", ctx.Cmd(), server.URL) child := spawnOrFail(t, cmd) <-kill err := child.Close() if err != nil { panic(err) } reportkill <- struct{}{} // rkt has fetched the first half of the image // If it fetches the first half again these channels will be written to. // Closing them to make the test panic if they're written to. close(kill) close(reportkill) child = spawnOrFail(t, cmd) if _, _, err := expectRegexWithOutput(child, ".*"+hash); err != nil { t.Fatalf("hash didn't match: %v", err) } waitOrFail(t, child, 0) }
func TestResumedFetchInvalidCache(t *testing.T) { image := "rkt-inspect-implicit-fetch.aci" imagePath := patchTestACI(image, "--exec=/inspect") defer os.Remove(imagePath) hash := types.ShortHash("sha512-" + getHashOrPanic(imagePath)) kill := make(chan struct{}) reportkill := make(chan struct{}) ctx := testutils.NewRktRunCtx() defer ctx.Cleanup() shouldInterrupt := &synchronizedBool{} shouldInterrupt.Write(true) // Fetch the first half of the image, and kill rkt once it reaches halfway. server := httptest.NewServer(testServerHandler(t, shouldInterrupt, imagePath, kill, reportkill)) defer server.Close() cmd := fmt.Sprintf("%s --no-store --insecure-options=image fetch %s", ctx.Cmd(), server.URL) child := spawnOrFail(t, cmd) <-kill err := child.Close() if err != nil { panic(err) } reportkill <- struct{}{} // Fetch the image again. The server doesn't support Etags or the // Last-Modified header, so the cached version should be invalidated. If // rkt tries to use the cache, the hash won't check out. shouldInterrupt.Write(false) child = spawnOrFail(t, cmd) if _, s, err := expectRegexWithOutput(child, ".*"+hash); err != nil { t.Fatalf("hash didn't match: %v\nin: %s", err, s) } waitOrFail(t, child, 0) }