Ejemplo n.º 1
0
// NewPodFromInternalPod converts *pkgPod.Pod to *Pod
func NewPodFromInternalPod(p *pkgPod.Pod) (*Pod, error) {
	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())
	}

	if len(manifest.UserAnnotations) > 0 {
		pod.UserAnnotations = make(map[string]string)
		for name, value := range manifest.UserAnnotations {
			pod.UserAnnotations[name] = value
		}
	}

	if len(manifest.UserLabels) > 0 {
		pod.UserLabels = make(map[string]string)
		for name, value := range manifest.UserLabels {
			pod.UserLabels[name] = value
		}
	}

	return pod, nil
}
Ejemplo n.º 2
0
// fillPodDetails fills the v1pod's dynamic info in place, e.g. the pod's state,
// the pod's network info, the apps' state, etc. Such information can change
// during the lifecycle of the pod, so we need to read it in every request.
func fillPodDetails(store *imagestore.Store, p *pkgPod.Pod, v1pod *v1alpha.Pod) {
	v1pod.Pid = -1

	switch p.State() {
	case pkgPod.Embryo:
		v1pod.State = v1alpha.PodState_POD_STATE_EMBRYO
		// When a pod is in embryo state, there is not much
		// information to return.
		return
	case pkgPod.Preparing:
		v1pod.State = v1alpha.PodState_POD_STATE_PREPARING
	case pkgPod.AbortedPrepare:
		v1pod.State = v1alpha.PodState_POD_STATE_ABORTED_PREPARE
	case pkgPod.Prepared:
		v1pod.State = v1alpha.PodState_POD_STATE_PREPARED
	case pkgPod.Running:
		v1pod.State = v1alpha.PodState_POD_STATE_RUNNING
		v1pod.Networks = getNetworks(p)
	case pkgPod.Deleting:
		v1pod.State = v1alpha.PodState_POD_STATE_DELETING
	case pkgPod.Exited:
		v1pod.State = v1alpha.PodState_POD_STATE_EXITED
	case pkgPod.Garbage, pkgPod.ExitedGarbage:
		v1pod.State = v1alpha.PodState_POD_STATE_GARBAGE
	default:
		v1pod.State = v1alpha.PodState_POD_STATE_UNDEFINED
		return
	}

	createdAt, err := p.CreationTime()
	if err != nil {
		stderr.PrintE(fmt.Sprintf("failed to get the creation time for pod %q", p.UUID), err)
	} else if !createdAt.IsZero() {
		v1pod.CreatedAt = createdAt.UnixNano()
	}

	startedAt, err := p.StartTime()
	if err != nil {
		stderr.PrintE(fmt.Sprintf("failed to get the start time for pod %q", p.UUID), err)
	} else if !startedAt.IsZero() {
		v1pod.StartedAt = startedAt.UnixNano()

	}

	gcMarkedAt, err := p.GCMarkedTime()
	if err != nil {
		stderr.PrintE(fmt.Sprintf("failed to get the gc marked time for pod %q", p.UUID), err)
	} else if !gcMarkedAt.IsZero() {
		v1pod.GcMarkedAt = gcMarkedAt.UnixNano()
	}

	pid, err := p.Pid()
	if err != nil {
		stderr.PrintE(fmt.Sprintf("failed to get the PID for pod %q", p.UUID), err)
	} else {
		v1pod.Pid = int32(pid)
	}

	if v1pod.State == v1alpha.PodState_POD_STATE_RUNNING {
		pid, err := p.ContainerPid1()
		if err != nil {
			stderr.PrintE(fmt.Sprintf("failed to get the container PID1 for pod %q", p.UUID), err)
		} else {
			cgroup, err := getPodCgroup(p, pid)
			if err != nil {
				stderr.PrintE(fmt.Sprintf("failed to get the cgroup path for pod %q", p.UUID), err)
			} else {
				v1pod.Cgroup = cgroup
			}
		}
	}

	for _, app := range v1pod.Apps {
		readStatus := false

		if p.State() == pkgPod.Running {
			readStatus = true
			app.State = v1alpha.AppState_APP_STATE_RUNNING
		} else if p.AfterRun() {
			readStatus = true
			app.State = v1alpha.AppState_APP_STATE_EXITED
		} else {
			app.State = v1alpha.AppState_APP_STATE_UNDEFINED
		}

		if readStatus {
			exitCode, err := p.AppExitCode(app.Name)
			if err != nil {
				stderr.PrintE(fmt.Sprintf("failed to read status for app %q", app.Name), err)
			}
			app.ExitCode = int32(exitCode)
		}
	}
}
Ejemplo n.º 3
0
// printStatus prints the pod's pid and per-app status codes
func printStatus(p *pkgPod.Pod) error {
	if flagFormat != outputFormatTabbed {
		pod, err := lib.NewPodFromInternalPod(p)
		if err != nil {
			return fmt.Errorf("error converting pod: %v", err)
		}
		switch flagFormat {
		case outputFormatJSON:
			result, err := json.Marshal(pod)
			if err != nil {
				return fmt.Errorf("error marshaling the pod: %v", err)
			}
			stdout.Print(string(result))
		case outputFormatPrettyJSON:
			result, err := json.MarshalIndent(pod, "", "\t")
			if err != nil {
				return fmt.Errorf("error marshaling the pod: %v", err)
			}
			stdout.Print(string(result))
		}
		return nil
	}

	state := p.State()
	stdout.Printf("state=%s", state)

	created, err := p.CreationTime()
	if err != nil {
		return fmt.Errorf("unable to get creation time for pod %q: %v", p.UUID, err)
	}
	createdStr := created.Format(defaultTimeLayout)

	stdout.Printf("created=%s", createdStr)

	started, err := p.StartTime()
	if err != nil {
		return fmt.Errorf("unable to get start time for pod %q: %v", p.UUID, err)
	}
	var startedStr string
	if !started.IsZero() {
		startedStr = started.Format(defaultTimeLayout)
		stdout.Printf("started=%s", startedStr)
	}

	if state == pkgPod.Running {
		stdout.Printf("networks=%s", fmtNets(p.Nets))
	}

	if state == pkgPod.Running || state == pkgPod.Deleting || state == pkgPod.ExitedDeleting || state == pkgPod.Exited || state == pkgPod.ExitedGarbage {
		var pid int
		pidCh := make(chan int, 1)

		// Wait slightly because the pid file might not be written yet when the state changes to 'Running'.
		go func() {
			for {
				pid, err := p.Pid()
				if err == nil {
					pidCh <- pid
					return
				}
				time.Sleep(time.Millisecond * 100)
			}
		}()

		select {
		case pid = <-pidCh:
		case <-time.After(time.Second):
			return fmt.Errorf("unable to get PID for pod %q: %v", p.UUID, err)
		}

		stdout.Printf("pid=%d\nexited=%t", pid, (state == pkgPod.Exited || state == pkgPod.ExitedGarbage))

		if state != pkgPod.Running {
			stats, err := getExitStatuses(p)
			if err != nil {
				return fmt.Errorf("unable to get exit statuses for pod %q: %v", p.UUID, err)
			}
			for app, stat := range stats {
				stdout.Printf("app-%s=%d", app, stat)
			}
		}
	}
	return nil
}
Ejemplo n.º 4
0
Archivo: status.go Proyecto: nhlfr/rkt
// printStatus prints the pod's pid and per-app status codes
func printStatus(p *pkgPod.Pod) error {
	state := p.State()
	stdout.Printf("state=%s", state)

	created, err := p.CreationTime()
	if err != nil {
		return fmt.Errorf("unable to get creation time for pod %q: %v", p.UUID, err)
	}
	createdStr := created.Format(defaultTimeLayout)

	stdout.Printf("created=%s", createdStr)

	started, err := p.StartTime()
	if err != nil {
		return fmt.Errorf("unable to get start time for pod %q: %v", p.UUID, err)
	}
	var startedStr string
	if !started.IsZero() {
		startedStr = started.Format(defaultTimeLayout)
		stdout.Printf("started=%s", startedStr)
	}

	if state == pkgPod.Running {
		stdout.Printf("networks=%s", fmtNets(p.Nets))
	}

	if state == pkgPod.Running || state == pkgPod.Deleting || state == pkgPod.ExitedDeleting || state == pkgPod.Exited || state == pkgPod.ExitedGarbage {
		var pid int
		pidCh := make(chan int, 1)

		// Wait slightly because the pid file might not be written yet when the state changes to 'Running'.
		go func() {
			for {
				pid, err := p.Pid()
				if err == nil {
					pidCh <- pid
					return
				}
				time.Sleep(time.Millisecond * 100)
			}
		}()

		select {
		case pid = <-pidCh:
		case <-time.After(time.Second):
			return fmt.Errorf("unable to get PID for pod %q: %v", p.UUID, err)
		}

		stdout.Printf("pid=%d\nexited=%t", pid, (state == pkgPod.Exited || state == pkgPod.ExitedGarbage))

		if state != pkgPod.Running {
			stats, err := getExitStatuses(p)
			if err != nil {
				return fmt.Errorf("unable to get exit statuses for pod %q: %v", p.UUID, err)
			}
			for app, stat := range stats {
				stdout.Printf("app-%s=%d", app, stat)
			}
		}
	}
	return nil
}