func registerPod(p *Pod, ip net.IP) error { uuid := p.UUID.String() cmf, err := os.Open(common.PodManifestPath(p.Root)) if err != nil { return fmt.Errorf("failed opening runtime manifest: %v", err) } defer cmf.Close() pth := fmt.Sprintf("/pods/%v?ip=%v", uuid, ip.To4().String()) if err := httpRequest("PUT", pth, cmf); err != nil { return fmt.Errorf("failed to register pod with metadata svc: %v", err) } for _, app := range p.Manifest.Apps { ampath := common.ImageManifestPath(p.Root, app.Image.ID) amf, err := os.Open(ampath) if err != nil { fmt.Errorf("failed reading app manifest %q: %v", ampath, err) } defer amf.Close() if err := registerApp(uuid, app.Name.String(), amf); err != nil { fmt.Errorf("failed to register app with metadata svc: %v", err) } } return nil }
// UpdateManifest updates the given pod manifest in the given path atomically on the file system. // The pod manifest has to be locked using LockManifest first to avoid races in case of concurrent writes. func (p *Pod) UpdateManifest(m *schema.PodManifest, path string) error { if !p.mutable { return ErrImmutable } mpath := common.PodManifestPath(path) mstat, err := os.Stat(mpath) if err != nil { return err } tmpf, err := ioutil.TempFile(path, "") if err != nil { return err } defer func() { tmpf.Close() os.Remove(tmpf.Name()) }() if err := tmpf.Chmod(mstat.Mode().Perm()); err != nil { return err } if err := json.NewEncoder(tmpf).Encode(m); err != nil { return err } if err := os.Rename(tmpf.Name(), mpath); err != nil { return err } return nil }
// getAppImageID returns the image id to enter // If one was supplied in the flags then it's simply returned // If the PM contains a single image, that image's id is returned // If the PM has multiple images, the ids and names are printed and an error is returned func getAppImageID(p *pod) (*types.Hash, error) { if !flagAppImageID.Empty() { return &flagAppImageID, nil } // figure out the image id, or show a list if multiple are present b, err := ioutil.ReadFile(common.PodManifestPath(p.path())) if err != nil { return nil, fmt.Errorf("error reading pod manifest: %v", err) } m := schema.PodManifest{} if err = m.UnmarshalJSON(b); err != nil { return nil, fmt.Errorf("unable to load manifest: %v", err) } switch len(m.Apps) { case 0: return nil, fmt.Errorf("pod contains zero apps") case 1: return &m.Apps[0].Image.ID, nil default: } stderr("Pod contains multiple apps:") for _, ra := range m.Apps { stderr("\t%s: %s", types.ShortHash(ra.Image.ID.String()), ra.Name.String()) } return nil, fmt.Errorf("specify app using \"rkt enter --imageid ...\"") }
// getAppName returns the app name to enter // If one was supplied in the flags then it's simply returned // If the PM contains a single app, that app's name is returned // If the PM has multiple apps, the names are printed and an error is returned func getAppName(p *pod) (*types.ACName, error) { if flagAppName != "" { return types.NewACName(flagAppName) } // figure out the app name, or show a list if multiple are present b, err := ioutil.ReadFile(common.PodManifestPath(p.path())) if err != nil { return nil, fmt.Errorf("error reading pod manifest: %v", err) } m := schema.PodManifest{} if err = m.UnmarshalJSON(b); err != nil { return nil, fmt.Errorf("unable to load manifest: %v", err) } switch len(m.Apps) { case 0: return nil, fmt.Errorf("pod contains zero apps") case 1: return &m.Apps[0].Name, nil default: } stderr("Pod contains multiple apps:") for _, ra := range m.Apps { stderr("\t%v", ra.Name) } return nil, fmt.Errorf("specify app using \"rkt enter --app= ...\"") }
// LoadPod loads a Pod Manifest (as prepared by stage0), the runtime data, and // its associated Application Manifests, under $root/stage1/opt/stage1/$apphash func LoadPod(root string, uuid *types.UUID, rp *RuntimePod) (*Pod, error) { p := &Pod{ Root: root, UUID: *uuid, Images: make(map[string]*schema.ImageManifest), UidRange: *user.NewBlankUidRange(), } // Unserialize runtime parameters if rp != nil { p.RuntimePod = *rp } else { buf, err := ioutil.ReadFile(filepath.Join(p.Root, RuntimeConfigPath)) if err != nil { return nil, errwrap.Wrap(errors.New("failed reading runtime params"), err) } if err := json.Unmarshal(buf, &p.RuntimePod); err != nil { return nil, errwrap.Wrap(errors.New("failed unmarshalling runtime params"), err) } } buf, err := ioutil.ReadFile(common.PodManifestPath(p.Root)) if err != nil { return nil, errwrap.Wrap(errors.New("failed reading pod manifest"), err) } pm := &schema.PodManifest{} if err := json.Unmarshal(buf, pm); err != nil { return nil, errwrap.Wrap(errors.New("failed unmarshalling pod manifest"), err) } p.Manifest = pm for i, app := range p.Manifest.Apps { impath := common.ImageManifestPath(p.Root, app.Name) buf, err := ioutil.ReadFile(impath) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed reading image manifest %q", impath), err) } im := &schema.ImageManifest{} if err = json.Unmarshal(buf, im); err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed unmarshalling image manifest %q", impath), err) } if _, ok := p.Images[app.Name.String()]; ok { return nil, fmt.Errorf("got multiple definitions for app: %v", app.Name) } if app.App == nil { p.Manifest.Apps[i].App = im.App } p.Images[app.Name.String()] = im } if err := p.UidRange.Deserialize([]byte(p.PrivateUsers)); err != nil { return nil, err } return p, nil }
func updatePodManifest(dir string, newPodManifest *schema.PodManifest) error { pmb, err := json.Marshal(newPodManifest) if err != nil { return err } debug("Writing pod manifest") return updateFile(common.PodManifestPath(dir), pmb) }
// registerPod registers pod with metadata service. // Returns authentication token to be passed in the URL func registerPod(root string, uuid *types.UUID, apps schema.AppList) (token string, rerr error) { u := uuid.String() var err error token, err = generateMDSToken() if err != nil { rerr = errwrap.Wrap(errors.New("failed to generate MDS token"), err) return } pmfPath := common.PodManifestPath(root) pmf, err := os.Open(pmfPath) if err != nil { rerr = errwrap.Wrap(fmt.Errorf("failed to open runtime manifest (%v)", pmfPath), err) return } pth := fmt.Sprintf("/pods/%v?token=%v", u, token) err = httpRequest("PUT", pth, pmf) pmf.Close() if err != nil { rerr = errwrap.Wrap(errors.New("failed to register pod with metadata svc"), err) return } defer func() { if rerr != nil { unregisterPod(root, uuid) } }() rf, err := os.Create(filepath.Join(root, mdsRegisteredFile)) if err != nil { rerr = errwrap.Wrap(errors.New("failed to create mds-register file"), err) return } rf.Close() for _, app := range apps { ampath := common.ImageManifestPath(root, app.Name) amf, err := os.Open(ampath) if err != nil { rerr = errwrap.Wrap(fmt.Errorf("failed reading app manifest %q", ampath), err) return } err = registerApp(u, app.Name.String(), amf) amf.Close() if err != nil { rerr = errwrap.Wrap(errors.New("failed to register app with metadata svc"), err) return } } return }
// registerPod registers pod with metadata service. // Returns authentication token to be passed in the URL func registerPod(root string, uuid *types.UUID, apps schema.AppList) (token string, rerr error) { u := uuid.String() var err error token, err = generateMDSToken() if err != nil { rerr = fmt.Errorf("failed to generate MDS token: %v", err) return } pmfPath := common.PodManifestPath(root) pmf, err := os.Open(pmfPath) if err != nil { rerr = fmt.Errorf("failed to open runtime manifest (%v): %v", pmfPath, err) return } pth := fmt.Sprintf("/pods/%v?token=%v", u, token) err = httpRequest("PUT", pth, pmf) pmf.Close() if err != nil { rerr = fmt.Errorf("failed to register pod with metadata svc: %v", err) return } defer func() { if rerr != nil { unregisterPod(uuid) } }() for _, app := range apps { ampath := common.ImageManifestPath(root, app.Image.ID) amf, err := os.Open(ampath) if err != nil { rerr = fmt.Errorf("failed reading app manifest %q: %v", ampath, err) return } err = registerApp(u, app.Name.String(), amf) amf.Close() if err != nil { rerr = fmt.Errorf("failed to register app with metadata svc: %v", err) return } } return }
func runList(cmd *cobra.Command, args []string) (exit int) { if !flagNoLegend { fmt.Fprintf(tabOut, "UUID\tACI\tSTATE\tNETWORKS\n") } if err := walkPods(includeMostDirs, func(p *pod) { m := schema.PodManifest{} app_zero := "" if !p.isPreparing && !p.isAbortedPrepare && !p.isExitedDeleting { // TODO(vc): we should really hold a shared lock here to prevent gc of the pod manifFile, err := p.readFile(common.PodManifestPath("")) if err != nil { stderr("Unable to read manifest: %v", err) return } err = m.UnmarshalJSON(manifFile) if err != nil { stderr("Unable to load manifest: %v", err) return } if len(m.Apps) == 0 { stderr("Pod contains zero apps") return } app_zero = m.Apps[0].Name.String() } uuid := "" if flagFullOutput { uuid = p.uuid.String() } else { uuid = p.uuid.String()[:8] } fmt.Fprintf(tabOut, "%s\t%s\t%s\t%s\n", uuid, app_zero, p.getState(), fmtNets(p.nets)) for i := 1; i < len(m.Apps); i++ { fmt.Fprintf(tabOut, "\t%s\n", m.Apps[i].Name.String()) } }); err != nil { stderr("Failed to get pod handles: %v", err) return 1 } tabOut.Flush() return 0 }
// Prepare sets up a pod based on the given config. func Prepare(cfg PrepareConfig, dir string, uuid *types.UUID) error { if err := os.MkdirAll(common.AppsInfoPath(dir), defaultRegularDirPerm); err != nil { return fmt.Errorf("error creating apps info directory: %v", err) } debug("Preparing stage1") if err := prepareStage1Image(cfg, cfg.Stage1Image, dir, cfg.UseOverlay); err != nil { return fmt.Errorf("error preparing stage1: %v", err) } var pmb []byte var err error if len(cfg.PodManifest) > 0 { pmb, err = validatePodManifest(cfg, dir) } else { pmb, err = generatePodManifest(cfg, dir) } if err != nil { return err } cfg.CommonConfig.ManifestData = string(pmb) debug("Writing pod manifest") fn := common.PodManifestPath(dir) if err := ioutil.WriteFile(fn, pmb, defaultRegularFilePerm); err != nil { return fmt.Errorf("error writing pod manifest: %v", err) } if cfg.UseOverlay { // mark the pod as prepared with overlay f, err := os.Create(filepath.Join(dir, common.OverlayPreparedFilename)) if err != nil { return fmt.Errorf("error writing overlay marker file: %v", err) } defer f.Close() } if cfg.PrivateUsers.Shift > 0 { // mark the pod as prepared for user namespaces uidrangeBytes := cfg.PrivateUsers.Serialize() if err := ioutil.WriteFile(filepath.Join(dir, common.PrivateUsersPreparedFilename), uidrangeBytes, defaultRegularFilePerm); err != nil { return fmt.Errorf("error writing userns marker file: %v", err) } } return nil }
// Prepare sets up a pod based on the given config. func Prepare(cfg PrepareConfig, dir string, uuid *types.UUID) error { log.Printf("Preparing stage1") if err := prepareStage1Image(cfg, cfg.Stage1Image, dir, cfg.UseOverlay); err != nil { return fmt.Errorf("error preparing stage1: %v", err) } var pmb []byte var err error if len(cfg.PodManifest) > 0 { pmb, err = validatePodManifest(cfg, dir) } else { pmb, err = generatePodManifest(cfg, dir) } if err != nil { return err } log.Printf("Writing pod manifest") fn := common.PodManifestPath(dir) if err := ioutil.WriteFile(fn, pmb, 0700); err != nil { return fmt.Errorf("error writing pod manifest: %v", err) } fn = path.Join(dir, common.Stage1IDFilename) if err := ioutil.WriteFile(fn, []byte(cfg.Stage1Image.String()), 0700); err != nil { return fmt.Errorf("error writing stage1 ID: %v", err) } if cfg.UseOverlay { // mark the pod as prepared with overlay f, err := os.Create(filepath.Join(dir, common.OverlayPreparedFilename)) if err != nil { return fmt.Errorf("error writing overlay marker file: %v", err) } defer f.Close() } if cfg.PrivateUsers.Shift > 0 { // mark the pod as prepared for user namespaces uidrangeBytes := cfg.PrivateUsers.Serialize() if err := ioutil.WriteFile(filepath.Join(dir, common.PrivateUsersPreparedFilename), uidrangeBytes, 0700); err != nil { return fmt.Errorf("error writing userns marker file: %v", err) } } return nil }
// getAppCount returns the app count of a pod. It can only be called on prepared pods. func (p *pod) getAppCount() (int, error) { if !p.isPrepared { return -1, fmt.Errorf("error: only prepared pods can get their app count") } b, err := ioutil.ReadFile(common.PodManifestPath(p.path())) if err != nil { return -1, fmt.Errorf("error reading pod manifest: %v", err) } m := schema.PodManifest{} if err = m.UnmarshalJSON(b); err != nil { return -1, fmt.Errorf("unable to load manifest: %v", err) } return len(m.Apps), nil }
// LoadPod loads a Pod Manifest (as prepared by stage0) and // its associated Application Manifests, under $root/stage1/opt/stage1/$apphash func LoadPod(root string, uuid *types.UUID) (*Pod, error) { p := &Pod{ Root: root, UUID: *uuid, Apps: make(map[string]*schema.ImageManifest), } buf, err := ioutil.ReadFile(common.PodManifestPath(p.Root)) if err != nil { return nil, fmt.Errorf("failed reading pod manifest: %v", err) } pm := &schema.PodManifest{} if err := json.Unmarshal(buf, pm); err != nil { return nil, fmt.Errorf("failed unmarshalling pod manifest: %v", err) } p.Manifest = pm for i, app := range p.Manifest.Apps { ampath := common.ImageManifestPath(p.Root, app.Image.ID) buf, err := ioutil.ReadFile(ampath) if err != nil { return nil, fmt.Errorf("failed reading app manifest %q: %v", ampath, err) } am := &schema.ImageManifest{} if err = json.Unmarshal(buf, am); err != nil { return nil, fmt.Errorf("failed unmarshalling app manifest %q: %v", ampath, err) } name := am.Name.String() if _, ok := p.Apps[name]; ok { return nil, fmt.Errorf("got multiple definitions for app: %s", name) } if app.App == nil { p.Manifest.Apps[i].App = am.App } p.Apps[name] = am } return p, nil }
func registerPod(p *Pod, token string) (rerr error) { uuid := p.UUID.String() cmf, err := os.Open(common.PodManifestPath(p.Root)) if err != nil { rerr = fmt.Errorf("failed opening runtime manifest: %v", err) return } pth := fmt.Sprintf("/pods/%v?token=%v", uuid, token) err = httpRequest("PUT", pth, cmf) cmf.Close() if err != nil { rerr = fmt.Errorf("failed to register pod with metadata svc: %v", err) return } defer func() { if rerr != nil { unregisterPod(p) } }() for _, app := range p.Manifest.Apps { ampath := common.ImageManifestPath(p.Root, app.Image.ID) amf, err := os.Open(ampath) if err != nil { rerr = fmt.Errorf("failed reading app manifest %q: %v", ampath, err) return } err = registerApp(uuid, app.Name.String(), amf) amf.Close() if err != nil { rerr = fmt.Errorf("failed to register app with metadata svc: %v", err) return } } return nil }
// LoadPod loads a Pod Manifest (as prepared by stage0) and // its associated Application Manifests, under $root/stage1/opt/stage1/$apphash func LoadPod(root string, uuid *types.UUID) (*Pod, error) { p := &Pod{ Root: root, UUID: *uuid, Images: make(map[string]*schema.ImageManifest), } buf, err := ioutil.ReadFile(common.PodManifestPath(p.Root)) if err != nil { return nil, errwrap.Wrap(errors.New("failed reading pod manifest"), err) } pm := &schema.PodManifest{} if err := json.Unmarshal(buf, pm); err != nil { return nil, errwrap.Wrap(errors.New("failed unmarshalling pod manifest"), err) } p.Manifest = pm for i, app := range p.Manifest.Apps { impath := common.ImageManifestPath(p.Root, app.Name) buf, err := ioutil.ReadFile(impath) if err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed reading image manifest %q", impath), err) } im := &schema.ImageManifest{} if err = json.Unmarshal(buf, im); err != nil { return nil, errwrap.Wrap(fmt.Errorf("failed unmarshalling image manifest %q", impath), err) } if _, ok := p.Images[app.Name.String()]; ok { return nil, fmt.Errorf("got multiple definitions for app: %v", app.Name) } if app.App == nil { p.Manifest.Apps[i].App = im.App } p.Images[app.Name.String()] = im } return p, nil }
func runList(cmd *cobra.Command, args []string) (exit int) { s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("list: cannot open store: %v", err) return 1 } if !flagNoLegend { fmt.Fprintf(tabOut, "UUID\tAPP\tACI\tSTATE\tNETWORKS\n") } if err := walkPods(includeMostDirs, func(p *pod) { pm := schema.PodManifest{} if !p.isPreparing && !p.isAbortedPrepare && !p.isExitedDeleting { // TODO(vc): we should really hold a shared lock here to prevent gc of the pod pmf, err := p.readFile(common.PodManifestPath("")) if err != nil { stderr("Unable to read pod manifest: %v", err) return } if err := pm.UnmarshalJSON(pmf); err != nil { stderr("Unable to load manifest: %v", err) return } if len(pm.Apps) == 0 { stderr("Pod contains zero apps") return } } uuid := "" if flagFullOutput { uuid = p.uuid.String() } else { uuid = p.uuid.String()[:8] } for i, app := range pm.Apps { // Retrieve the image from the store. im, err := s.GetImageManifest(app.Image.ID.String()) if err != nil { stderr("Unable to load image manifest: %v", err) } if i == 0 { fmt.Fprintf(tabOut, "%s\t%s\t%s\t%s\t%s\n", uuid, app.Name.String(), im.Name.String(), p.getState(), fmtNets(p.nets)) } else { fmt.Fprintf(tabOut, "\t%s\t%s\t\t\n", app.Name.String(), im.Name.String()) } } }); err != nil { stderr("Failed to get pod handles: %v", err) return 1 } tabOut.Flush() return 0 }
func runList(cmd *cobra.Command, args []string) int { s, err := store.NewStore(globalFlags.Dir) if err != nil { stderr("list: cannot open store: %v", err) return 1 } var errors []error tabBuffer := new(bytes.Buffer) tabOut := getTabOutWithWriter(tabBuffer) if !flagNoLegend { if flagFullOutput { fmt.Fprintf(tabOut, "UUID\tAPP\tIMAGE NAME\tIMAGE ID\tSTATE\tNETWORKS\n") } else { fmt.Fprintf(tabOut, "UUID\tAPP\tIMAGE NAME\tSTATE\tNETWORKS\n") } } if err := walkPods(includeMostDirs, func(p *pod) { pm := schema.PodManifest{} if !p.isPreparing && !p.isAbortedPrepare && !p.isExitedDeleting { // TODO(vc): we should really hold a shared lock here to prevent gc of the pod pmf, err := p.readFile(common.PodManifestPath("")) if err != nil { errors = append(errors, newPodListReadError(p, err)) return } if err := pm.UnmarshalJSON(pmf); err != nil { errors = append(errors, newPodListLoadError(p, err, pmf)) return } if len(pm.Apps) == 0 { errors = append(errors, newPodListZeroAppsError(p)) return } } type printedApp struct { uuid string appName string imgName string imgID string state string nets string } var appsToPrint []printedApp uuid := p.uuid.String() state := p.getState() nets := fmtNets(p.nets) if !flagFullOutput { uuid = uuid[:8] } for _, app := range pm.Apps { // Retrieve the image from the store. imj, err := s.GetImageManifestJSON(app.Image.ID.String()) if err != nil { errors = append(errors, newPodListImageStoreFailure(p, err, &pm, app)) return } var im *schema.ImageManifest if err = json.Unmarshal(imj, &im); err != nil { errors = append(errors, newPodListImageLoadFailure(p, err, &pm, imj, app)) return } imageName := im.Name.String() if version, ok := im.Labels.Get("version"); ok { imageName = fmt.Sprintf("%s:%s", imageName, version) } var imageID string if flagFullOutput { imageID = app.Image.ID.String()[:19] } appsToPrint = append(appsToPrint, printedApp{ uuid: uuid, appName: app.Name.String(), imgName: imageName, imgID: imageID, state: state, nets: nets, }) // clear those variables so they won't be // printed for another apps in the pod as they // are actually describing a pod, not an app uuid = "" state = "" nets = "" } // if we reached that point, then it means that the // pod and all its apps are valid, so they can be // printed for _, app := range appsToPrint { if flagFullOutput { fmt.Fprintf(tabOut, "%s\t%s\t%s\t%s\t%s\t%s\n", app.uuid, app.appName, app.imgName, app.imgID, app.state, app.nets) } else { fmt.Fprintf(tabOut, "%s\t%s\t%s\t%s\t%s\n", app.uuid, app.appName, app.imgName, app.state, app.nets) } } }); err != nil { stderr("Failed to get pod handles: %v", err) return 1 } if len(errors) > 0 { sep := "----------------------------------------" stderr("%d error(s) encountered when listing pods:", len(errors)) stderr("%s", sep) for _, err := range errors { stderr("%s", err.Error()) stderr("%s", sep) } stderr("Misc:") stderr(" rkt's appc version: %s", schema.AppContainerVersion) stderr("%s", sep) // make a visible break between errors and the listing stderr("") } tabOut.Flush() stdout("%s", tabBuffer.String()) return 0 }
// Prepare sets up a pod based on the given config. func Prepare(cfg PrepareConfig, dir string, uuid *types.UUID) error { if err := os.MkdirAll(common.AppsInfoPath(dir), common.DefaultRegularDirPerm); err != nil { return errwrap.Wrap(errors.New("error creating apps info directory"), err) } debug("Preparing stage1") if err := prepareStage1Image(cfg, dir); err != nil { return errwrap.Wrap(errors.New("error preparing stage1"), err) } var pmb []byte var err error if len(cfg.PodManifest) > 0 { pmb, err = validatePodManifest(cfg, dir) } else { pmb, err = generatePodManifest(cfg, dir) } if err != nil { return err } cfg.CommonConfig.ManifestData = string(pmb) // create pod lock file for app add/rm operations. f, err := os.OpenFile(common.PodManifestLockPath(dir), os.O_CREATE|os.O_RDWR, 0600) if err != nil { return err } f.Close() debug("Writing pod manifest") fn := common.PodManifestPath(dir) if err := ioutil.WriteFile(fn, pmb, common.DefaultRegularFilePerm); err != nil { return errwrap.Wrap(errors.New("error writing pod manifest"), err) } f, err = os.OpenFile(common.PodCreatedPath(dir), os.O_CREATE|os.O_RDWR, common.DefaultRegularFilePerm) if err != nil { return err } f.Close() if cfg.UseOverlay { // mark the pod as prepared with overlay f, err := os.Create(filepath.Join(dir, common.OverlayPreparedFilename)) if err != nil { return errwrap.Wrap(errors.New("error writing overlay marker file"), err) } defer f.Close() } if cfg.PrivateUsers.Shift > 0 { // mark the pod as prepared for user namespaces uidrangeBytes := cfg.PrivateUsers.Serialize() if err := ioutil.WriteFile(filepath.Join(dir, common.PrivateUsersPreparedFilename), uidrangeBytes, common.DefaultRegularFilePerm); err != nil { return errwrap.Wrap(errors.New("error writing userns marker file"), err) } } return nil }
func runList(cmd *cobra.Command, args []string) int { var errors []error tabBuffer := new(bytes.Buffer) tabOut := getTabOutWithWriter(tabBuffer) if !flagNoLegend { if flagFullOutput { fmt.Fprintf(tabOut, "UUID\tAPP\tIMAGE NAME\tIMAGE ID\tSTATE\tCREATED\tSTARTED\tNETWORKS\n") } else { fmt.Fprintf(tabOut, "UUID\tAPP\tIMAGE NAME\tSTATE\tCREATED\tSTARTED\tNETWORKS\n") } } if err := walkPods(includeMostDirs, func(p *pod) { pm := schema.PodManifest{} if !p.isPreparing && !p.isAbortedPrepare && !p.isExitedDeleting { // TODO(vc): we should really hold a shared lock here to prevent gc of the pod pmf, err := p.readFile(common.PodManifestPath("")) if err != nil { errors = append(errors, newPodListReadError(p, err)) return } if err := pm.UnmarshalJSON(pmf); err != nil { errors = append(errors, newPodListLoadError(p, err, pmf)) return } if len(pm.Apps) == 0 { errors = append(errors, newPodListZeroAppsError(p)) return } } type printedApp struct { uuid string appName string imgName string imgID string state string nets string created string started string } var appsToPrint []printedApp uuid := p.uuid.String() state := p.getState() nets := fmtNets(p.nets) created, err := p.getCreationTime() if err != nil { errors = append(errors, errwrap.Wrap(fmt.Errorf("unable to get creation time for pod %q", uuid), err)) } var createdStr string if flagFullOutput { createdStr = created.Format(defaultTimeLayout) } else { createdStr = humanize.Time(created) } started, err := p.getStartTime() if err != nil { errors = append(errors, errwrap.Wrap(fmt.Errorf("unable to get start time for pod %q", uuid), err)) } var startedStr string if !started.IsZero() { if flagFullOutput { startedStr = started.Format(defaultTimeLayout) } else { startedStr = humanize.Time(started) } } if !flagFullOutput { uuid = uuid[:8] } for _, app := range pm.Apps { imageName, err := getImageName(p, app.Name) if err != nil { errors = append(errors, newPodListLoadImageManifestError(p, err)) imageName = "--" } var imageID string if flagFullOutput { imageID = app.Image.ID.String()[:19] } appsToPrint = append(appsToPrint, printedApp{ uuid: uuid, appName: app.Name.String(), imgName: imageName, imgID: imageID, state: state, nets: nets, created: createdStr, started: startedStr, }) // clear those variables so they won't be // printed for another apps in the pod as they // are actually describing a pod, not an app uuid = "" state = "" nets = "" createdStr = "" startedStr = "" } // if we reached that point, then it means that the // pod and all its apps are valid, so they can be // printed for _, app := range appsToPrint { if flagFullOutput { fmt.Fprintf(tabOut, "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", app.uuid, app.appName, app.imgName, app.imgID, app.state, app.created, app.started, app.nets) } else { fmt.Fprintf(tabOut, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", app.uuid, app.appName, app.imgName, app.state, app.created, app.started, app.nets) } } }); err != nil { stderr.PrintE("failed to get pod handles", err) return 1 } if len(errors) > 0 { sep := "----------------------------------------" stderr.Printf("%d error(s) encountered when listing pods:", len(errors)) stderr.Print(sep) for _, err := range errors { stderr.Error(err) stderr.Print(sep) } stderr.Print("misc:") stderr.Printf(" rkt's appc version: %s", schema.AppContainerVersion) stderr.Print(sep) // make a visible break between errors and the listing stderr.Print("") } tabOut.Flush() stdout.Print(tabBuffer) return 0 }