Skip to content

Commit

Permalink
Merge pull request rkt#3403 from euank/fix-misc-list-issues
Browse files Browse the repository at this point in the history
stage0: improve list --format behavior and flags
  • Loading branch information
Sergiusz Urbaniak authored Nov 24, 2016
2 parents 511bc08 + 2698e6c commit fce0966
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 48 deletions.
34 changes: 19 additions & 15 deletions lib/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,31 @@ import pkgPod "github.com/coreos/rkt/pkg/pod"

// NewPodFromInternalPod converts *pkgPod.Pod to *Pod
func NewPodFromInternalPod(p *pkgPod.Pod) (*Pod, error) {
_, manifest, err := p.PodManifest()
if err != nil {
return nil, err
}

pod := &Pod{
UUID: p.UUID.String(),
State: p.State(),
Networks: p.Nets,
}

startTime, err := p.StartTime()
if err != nil {
return nil, err
}

if !startTime.IsZero() {
startedAt := startTime.Unix()
pod.StartedAt = &startedAt
}

if !p.PodManifestAvailable() {
return pod, nil
}
// TODO(vc): we should really hold a shared lock here to prevent gc of the pod
_, manifest, err := p.PodManifest()
if err != nil {
return nil, err
}

for _, app := range manifest.Apps {
pod.AppNames = append(pod.AppNames, app.Name.String())
}
Expand All @@ -47,15 +61,5 @@ func NewPodFromInternalPod(p *pkgPod.Pod) (*Pod, error) {
}
}

startTime, err := p.StartTime()
if err != nil {
return nil, err
}

if !startTime.IsZero() {
startedAt := startTime.Unix()
pod.StartedAt = &startedAt
}

return pod, nil
}
46 changes: 31 additions & 15 deletions pkg/pod/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -979,24 +979,29 @@ func (p *Pod) CreationTime() (time.Time, error) {
// StartTime returns the time when the pod was started.
func (p *Pod) StartTime() (time.Time, error) {
var (
t time.Time
err error
t time.Time
retErr error
)
if p.isRunning() || p.AfterRun() {
// check pid and ppid files, since stage1 implementations can choose
// which one to implement.
t, err = p.getModTime("pid")
if os.IsNotExist(err) {
t, err = p.getModTime("ppid")
// if there's an error starting the pod, it can be "exited" without
// the "ppid" (or "pid") files being created, return an error only
// if it's different than ENOENT.
if os.IsNotExist(err) {
err = nil
}

if !p.isRunning() && !p.AfterRun() {
// hasn't started
return t, nil
}

// check pid and ppid since stage1s can choose one xor the other
for _, ctimeFile := range []string{"pid", "ppid"} {
t, err := p.getModTime(ctimeFile)
if err == nil {
return t, nil
}
// if there's an error starting the pod, it can go to "exited" without
// creating a ppid/pid file, so ignore not-exist errors.
if !os.IsNotExist(err) {
retErr = err
}
}
return t, err

return t, retErr
}

// GCMarkedTime returns the time when the pod is marked by gc.
Expand Down Expand Up @@ -1155,6 +1160,17 @@ func (p *Pod) isRunning() bool {
!p.isExited && !p.isExitedGarbage && !p.isExitedDeleting && !p.isGarbage && !p.isDeleting && !p.isGone
}

// PodManifestAvailable returns whether the caller should reasonably expect
// PodManifest to function in the pod's current state.
// Namely, in Preparing, AbortedPrepare, and Deleting it's possible for the
// manifest to not be present
func (p *Pod) PodManifestAvailable() bool {
if p.isPreparing || p.isAbortedPrepare || p.isDeleting {
return false
}
return true
}

// AfterRun returns true if the pod is in a post-running state, otherwise it returns false.
func (p *Pod) AfterRun() bool {
return p.isExitedDeleting || p.isDeleting || p.isExited || p.isGarbage
Expand Down
6 changes: 3 additions & 3 deletions rkt/app_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var (
func init() {
cmdApp.AddCommand(cmdAppStatus)
cmdAppStatus.Flags().StringVar(&flagAppName, "app", "", "choose app within the pod, this flag must be set")
cmdAppStatus.Flags().StringVar(&flagFormat, "format", "", "choose the output format, allowed format includes 'json', 'json-pretty'. If empty, then the result is printed as key value pairs")
cmdAppStatus.Flags().Var(&flagFormat, "format", "choose the output format, allowed format includes 'json', 'json-pretty'. If empty, then the result is printed as key value pairs")
}

func printApp(app *rkt.App) {
Expand Down Expand Up @@ -112,14 +112,14 @@ func runAppStatus(cmd *cobra.Command, args []string) (exit int) {

// TODO(yifan): Print yamls.
switch flagFormat {
case "json":
case outputFormatJSON:
result, err := json.Marshal(apps[0])
if err != nil {
stderr.PrintE("error marshaling the app status", err)
return 1
}
stdout.Print(string(result))
case "json-pretty":
case outputFormatPrettyJSON:
result, err := json.MarshalIndent(apps[0], "", "\t")
if err != nil {
stderr.PrintE("error marshaling the app status", err)
Expand Down
21 changes: 10 additions & 11 deletions rkt/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ var (
}
flagNoLegend bool
flagFullOutput bool
flagFormat string
flagFormat outputFormat
)

func init() {
cmdRkt.AddCommand(cmdList)
cmdList.Flags().BoolVar(&flagNoLegend, "no-legend", false, "suppress a legend with the list")
cmdList.Flags().BoolVar(&flagFullOutput, "full", false, "use long output format")
cmdList.Flags().StringVar(&flagFormat, "format", "", "choose the output format, allowed format includes 'json', 'json-pretty'. If empty, then the result is printed as key value pairs")
cmdList.Flags().Var(&flagFormat, "format", "choose the output format, allowed format includes 'json', 'json-pretty'. If empty, then the result is printed as key value pairs")
}

func runList(cmd *cobra.Command, args []string) int {
var errors []error
tabBuffer := new(bytes.Buffer)
tabOut := getTabOutWithWriter(tabBuffer)

if !flagNoLegend && flagFormat == "" {
if !flagNoLegend && flagFormat == outputFormatTabbed {
if flagFullOutput {
fmt.Fprintf(tabOut, "UUID\tAPP\tIMAGE NAME\tIMAGE ID\tSTATE\tCREATED\tSTARTED\tNETWORKS\n")
} else {
Expand All @@ -69,22 +69,21 @@ func runList(cmd *cobra.Command, args []string) int {
var pods []*lib.Pod

if err := pkgPod.WalkPods(getDataDir(), pkgPod.IncludeMostDirs, func(p *pkgPod.Pod) {
if flagFormat != "" {
if flagFormat != outputFormatTabbed {
pod, err := lib.NewPodFromInternalPod(p)
if err != nil {
errors = append(errors, err)
} else {
pods = append(pods, pod)
}
pods = append(pods, pod)
return
}

var pm schema.PodManifest
var err error

podState := p.State()
if podState != pkgPod.Preparing && podState != pkgPod.AbortedPrepare && podState != pkgPod.Deleting {
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))
Expand Down Expand Up @@ -196,17 +195,17 @@ func runList(cmd *cobra.Command, args []string) int {
}

switch flagFormat {
case "":
case outputFormatTabbed:
tabOut.Flush()
stdout.Print(tabBuffer)
case "json":
case outputFormatJSON:
result, err := json.Marshal(pods)
if err != nil {
stderr.PrintE("error marshaling the pods", err)
return 254
}
stdout.Print(string(result))
case "json-pretty":
case outputFormatPrettyJSON:
result, err := json.MarshalIndent(pods, "", "\t")
if err != nil {
stderr.PrintE("error marshaling the pods", err)
Expand Down
8 changes: 4 additions & 4 deletions rkt/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const (
func init() {
cmdRkt.AddCommand(cmdStatus)
cmdStatus.Flags().BoolVar(&flagWait, "wait", false, "toggle waiting for the pod to exit")
cmdStatus.Flags().StringVar(&flagFormat, "format", "", "choose the output format, allowed format includes 'json', 'json-pretty'. If empty, then the result is printed as key value pairs")
cmdStatus.Flags().Var(&flagFormat, "format", "choose the output format, allowed format includes 'json', 'json-pretty'. If empty, then the result is printed as key value pairs")
}

func runStatus(cmd *cobra.Command, args []string) (exit int) {
Expand Down Expand Up @@ -97,19 +97,19 @@ func getExitStatuses(p *pkgPod.Pod) (map[string]int, error) {

// printStatus prints the pod's pid and per-app status codes
func printStatus(p *pkgPod.Pod) error {
if flagFormat != "" {
if flagFormat != outputFormatTabbed {
pod, err := lib.NewPodFromInternalPod(p)
if err != nil {
return fmt.Errorf("error converting pod: %v", err)
}
switch flagFormat {
case "json":
case outputFormatJSON:
result, err := json.Marshal(pod)
if err != nil {
return fmt.Errorf("error marshaling the pod: %v", err)
}
stdout.Print(string(result))
case "json-pretty":
case outputFormatPrettyJSON:
result, err := json.MarshalIndent(pod, "", "\t")
if err != nil {
return fmt.Errorf("error marshaling the pod: %v", err)
Expand Down

0 comments on commit fce0966

Please sign in to comment.