// emptyExitedGarbage discards sufficiently aged pods from exitedGarbageDir() func emptyExitedGarbage(gracePeriod time.Duration) error { if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeExitedGarbageDir, func(p *pkgPod.Pod) { gp := p.Path() st := &syscall.Stat_t{} if err := syscall.Lstat(gp, st); err != nil { if err != syscall.ENOENT { stderr.PrintE(fmt.Sprintf("unable to stat %q, ignoring", gp), err) } return } if expiration := time.Unix(st.Ctim.Unix()).Add(gracePeriod); time.Now().After(expiration) { if err := p.ExclusiveLock(); err != nil { return } stdout.Printf("Garbage collecting pod %q", p.UUID) deletePod(p) } else { stderr.Printf("pod %q not removed: still within grace period (%s)", p.UUID, gracePeriod) } }); err != nil { return err } return nil }
// renameAborted renames failed prepares to the garbage directory func renameAborted() error { if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludePrepareDir, func(p *pkgPod.Pod) { if p.State() == pkgPod.AbortedPrepare { stderr.Printf("moving failed prepare %q to garbage", p.UUID) if err := p.ToGarbage(); err != nil && err != os.ErrNotExist { stderr.PrintE("rename error", err) } } }); err != nil { return err } return nil }
// emptyGarbage discards everything from garbageDir() func emptyGarbage() error { if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeGarbageDir, func(p *pkgPod.Pod) { if err := p.ExclusiveLock(); err != nil { return } stdout.Printf("Garbage collecting pod %q", p.UUID) deletePod(p) }); err != nil { return err } return nil }
// renameExited renames exited pods to the exitedGarbage directory func renameExited() error { if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeRunDir, func(p *pkgPod.Pod) { if p.State() == pkgPod.Exited { stderr.Printf("moving pod %q to garbage", p.UUID) if err := p.ToExitedGarbage(); err != nil && err != os.ErrNotExist { stderr.PrintE("rename error", err) } } }); err != nil { return err } return nil }
// renameExpired renames expired prepared pods to the garbage directory func renameExpired(preparedExpiration time.Duration) error { if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludePreparedDir, func(p *pkgPod.Pod) { st := &syscall.Stat_t{} pp := p.Path() if err := syscall.Lstat(pp, st); err != nil { if err != syscall.ENOENT { stderr.PrintE(fmt.Sprintf("unable to stat %q, ignoring", pp), err) } return } if expiration := time.Unix(st.Ctim.Unix()).Add(preparedExpiration); time.Now().After(expiration) { stderr.Printf("moving expired prepared pod %q to garbage", p.UUID) if err := p.ToGarbage(); err != nil && err != os.ErrNotExist { stderr.PrintE("rename error", err) } } }); err != nil { return err } return nil }
func (s *v1AlphaAPIServer) ListPods(ctx context.Context, request *v1alpha.ListPodsRequest) (*v1alpha.ListPodsResponse, error) { var pods []*v1alpha.Pod if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeMostDirs, func(p *pkgPod.Pod) { pod := s.getBasicPod(p) fillPodDetails(s.store, p, pod) // Filters are combined with 'OR'. if !satisfiesAnyPodFilters(pod, request.Filters) { return } if !request.Detail { pod.Manifest = nil } pods = append(pods, pod) }); err != nil { stderr.PrintE("failed to list pod", err) return nil, err } return &v1alpha.ListPodsResponse{Pods: pods}, nil }
func getReferencedTreeStoreIDs() (map[string]struct{}, error) { treeStoreIDs := map[string]struct{}{} // Consider pods in preparing, prepared, run, exitedgarbage state if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeMostDirs, func(p *pkgPod.Pod) { stage1TreeStoreID, err := p.GetStage1TreeStoreID() if err != nil { stderr.PrintE(fmt.Sprintf("cannot get stage1 treestoreID for pod %s", p.UUID), err) return } appsTreeStoreIDs, err := p.GetAppsTreeStoreIDs() if err != nil { stderr.PrintE(fmt.Sprintf("cannot get apps treestoreID for pod %s", p.UUID), err) return } allTreeStoreIDs := append(appsTreeStoreIDs, stage1TreeStoreID) for _, treeStoreID := range allTreeStoreIDs { treeStoreIDs[treeStoreID] = struct{}{} } }); err != nil { return nil, errwrap.Wrap(errors.New("failed to get pod handles"), err) } return treeStoreIDs, nil }
func runList(cmd *cobra.Command, args []string) int { var errors []error tabBuffer := new(bytes.Buffer) tabOut := getTabOutWithWriter(tabBuffer) if !flagNoLegend && flagFormat == outputFormatTabbed { 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") } } var pods []*lib.Pod if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeMostDirs, func(p *pkgPod.Pod) { if flagFormat != outputFormatTabbed { pod, err := lib.NewPodFromInternalPod(p) if err != nil { errors = append(errors, err) } else { pods = append(pods, pod) } return } var pm schema.PodManifest var err error if p.PodManifestAvailable() { // TODO(vc): we should really hold a shared lock here to prevent gc of the pod _, manifest, err := p.PodManifest() if err != nil { errors = append(errors, newPodListReadError(p, err)) return } pm = *manifest } 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.State() nets := fmtNets(p.Nets) created, err := p.CreationTime() 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.StartTime() 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] } if len(pm.Apps) == 0 { appsToPrint = append(appsToPrint, printedApp{ uuid: uuid, appName: "-", imgName: "-", imgID: "-", state: state, nets: nets, created: createdStr, started: startedStr, }) } 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 254 } switch flagFormat { case outputFormatTabbed: tabOut.Flush() stdout.Print(tabBuffer) case outputFormatJSON: result, err := json.Marshal(pods) if err != nil { stderr.PrintE("error marshaling the pods", err) return 254 } stdout.Print(string(result)) case outputFormatPrettyJSON: result, err := json.MarshalIndent(pods, "", "\t") if err != nil { stderr.PrintE("error marshaling the pods", err) return 254 } stdout.Print(string(result)) } if len(errors) > 0 { printErrors(errors, "listing pods") } return 0 }