Skip to content

Commit

Permalink
Add comments for exported interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
ueokande committed Jul 21, 2019
1 parent c7d9f58 commit 6e7a7ae
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 102 deletions.
27 changes: 16 additions & 11 deletions logbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@ package main
import (
"context"

"github.com/gdamore/tcell"
"github.com/gdamore/tcell/views"
"github.com/ueokande/logbook/pkg/k8s"
"github.com/ueokande/logbook/pkg/types"
"github.com/ueokande/logbook/pkg/ui"
corev1 "k8s.io/api/core/v1"
)

var (
StylePodActive = tcell.StyleDefault.Foreground(tcell.ColorGreen)
StylePodError = tcell.StyleDefault.Foreground(tcell.ColorRed)
StylePodPending = tcell.StyleDefault.Foreground(tcell.ColorYellow)
)

// AppConfig is a config for Logbook App
type AppConfig struct {
Cluster string
Namespace string
}

// App is an application of logbook
type App struct {
client *k8s.Client
ui *ui.UI
Expand All @@ -34,6 +30,7 @@ type App struct {
*views.Application
}

// NewApp returns new App instance
func NewApp(client *k8s.Client, config *AppConfig) *App {
w := ui.NewUI()
w.SetContext(config.Cluster, config.Namespace)
Expand All @@ -44,8 +41,8 @@ func NewApp(client *k8s.Client, config *AppConfig) *App {
ui: w,

namespace: config.Namespace,
logworker: NewWorker(context.Background()),
podworker: NewWorker(context.Background()),
logworker: NewWorker(context.TODO()),
podworker: NewWorker(context.TODO()),

Application: new(views.Application),
}
Expand All @@ -56,12 +53,14 @@ func NewApp(client *k8s.Client, config *AppConfig) *App {
return app
}

// OnContainerSelected handles events on container selected by UI
func (app *App) OnContainerSelected(name string, index int) {
pod := app.currentPod
app.ui.ClearPager()
app.StartTailLog(pod.Namespace, pod.Name, name)
}

// OnPodSelected handles events on pod selected by UI
func (app *App) OnPodSelected(name string, index int) {
app.currentPod = app.pods[index]
pod := app.currentPod
Expand All @@ -72,10 +71,12 @@ func (app *App) OnPodSelected(name string, index int) {
app.ui.SelectContainerAt(0)
}

// OnQuit handles events on quit is required by UI
func (app *App) OnQuit() {
app.Quit()
}

// StartTailLog starts tailing logs for container of pod in namespace
func (app *App) StartTailLog(namespace, pod, container string) {
app.StopTailLog()

Expand Down Expand Up @@ -105,11 +106,13 @@ func (app *App) StartTailLog(namespace, pod, container string) {
})
}

// StopTailLog stops tailing logs
func (app *App) StopTailLog() {
app.logworker.Stop()
// TODO handle err
}

// StartTailPods tarts tailing pods on Kubernetes
func (app *App) StartTailPods() {
app.StopTailLog()
app.podworker.Start(func(ctx context.Context) error {
Expand All @@ -124,12 +127,12 @@ func (app *App) StartTailPods() {
switch ev.Type {
case k8s.PodAdded:
app.pods = append(app.pods, pod)
app.ui.AddPod(pod.Name, k8s.GetPodStatus(pod))
app.ui.AddPod(pod.Name, types.GetPodStatus(pod))
if len(app.pods) == 1 {
app.ui.SelectPodAt(0)
}
case k8s.PodModified:
app.ui.SetPodStatus(pod.Name, k8s.GetPodStatus(pod))
app.ui.SetPodStatus(pod.Name, types.GetPodStatus(pod))
case k8s.PodDeleted:
for i, p := range app.pods {
if p.Name == pod.Name {
Expand All @@ -146,11 +149,13 @@ func (app *App) StartTailPods() {
})
}

// StopTailPods stops tailing pods
func (app *App) StopTailPods() {
app.podworker.Stop()
// TODO handle err
}

// Run starts logbook application
func (app *App) Run(ctx context.Context) error {
app.StartTailPods()
return app.Application.Run()
Expand Down
15 changes: 8 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,31 @@ func init() {
}
}

type Params struct {
// params contains values of the command-line parameter
type params struct {
namespace string
kubeconfig string
}

func main() {
params := Params{}
p := params{}

cmd := &cobra.Command{}
cmd.Short = "View logs on multiple pods and containers from Kubernetes"

cmd.Flags().StringVarP(&params.namespace, "namespace", "n", params.namespace, "Kubernetes namespace to use. Default to namespace configured in Kubernetes context")
cmd.Flags().StringVarP(&params.kubeconfig, "kubeconfig", "", params.kubeconfig, " Path to kubeconfig file to use")
cmd.Flags().StringVarP(&p.namespace, "namespace", "n", p.namespace, "Kubernetes namespace to use. Default to namespace configured in Kubernetes context")
cmd.Flags().StringVarP(&p.kubeconfig, "kubeconfig", "", p.kubeconfig, " Path to kubeconfig file to use")

cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

context, err := k8s.LoadCurrentContext(params.kubeconfig)
context, err := k8s.LoadCurrentContext(p.kubeconfig)
if err != nil {
return err
}

client, err := k8s.NewClient(params.kubeconfig)
client, err := k8s.NewClient(p.kubeconfig)
if err != nil {
return err
}
Expand All @@ -54,7 +55,7 @@ func main() {
if len(context.Namespace) > 0 {
config.Namespace = context.Namespace
}
if len(params.namespace) > 0 {
if len(p.namespace) > 0 {
config.Namespace = context.Namespace
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/k8s/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import (
"k8s.io/client-go/tools/clientcmd/api"
)

// Client is a wrapper for a Kubernetes client
type Client struct {
clientset *kubernetes.Clientset
}

// NewClient loads Kubernetes configuration by the kubeconfig and returns new
// Client
func NewClient(kubeconfig string) (*Client, error) {
kubeConfig := getKubeConfig(kubeconfig)
clientConfig, err := kubeConfig.ClientConfig()
Expand All @@ -27,6 +30,7 @@ func NewClient(kubeconfig string) (*Client, error) {
}, nil
}

// LoadCurrentContext loads a context in KUBECONFIG and returns it
func LoadCurrentContext(kubeconfig string) (*api.Context, error) {
kubeConfig := getKubeConfig(kubeconfig)
rawConfig, err := kubeConfig.RawConfig()
Expand Down
3 changes: 3 additions & 0 deletions pkg/k8s/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
corev1 "k8s.io/api/core/v1"
)

// WatchLogs watches container's logs of pod in namespace. It returns channels
// to subscribe log lines.
func (c *Client) WatchLogs(ctx context.Context, namespace, pod, container string) (<-chan string, error) {
opts := &corev1.PodLogOptions{
Container: container,
Expand All @@ -19,6 +21,7 @@ func (c *Client) WatchLogs(ctx context.Context, namespace, pod, container string
return nil, err
}

// TODO handle s.Err()
s := bufio.NewScanner(r)

ch := make(chan string)
Expand Down
56 changes: 0 additions & 56 deletions pkg/k8s/pod_status.go

This file was deleted.

11 changes: 8 additions & 3 deletions pkg/k8s/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ import (
"k8s.io/apimachinery/pkg/watch"
)

// PodEventType represents an event type of the pod
type PodEventType int

// The event type of the pods
const (
PodAdded PodEventType = iota
PodModified
PodDeleted
PodAdded PodEventType = iota // The pod is added
PodModified // The pod is updated
PodDeleted // The pod is deleted
)

// PodEvent represents an event of the pods in Kubernetes API
type PodEvent struct {
Type PodEventType
Pod *corev1.Pod
}

// WatchPods watches pods from Kubernetes API in namespace. It returns a
// channel to subscribe pods.
func (c *Client) WatchPods(ctx context.Context, namespace string) (<-chan *PodEvent, error) {
r, err := c.clientset.CoreV1().Pods(namespace).Watch(metav1.ListOptions{})
if err != nil {
Expand Down
72 changes: 65 additions & 7 deletions pkg/types/pod_status.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,71 @@
package types

import (
corev1 "k8s.io/api/core/v1"
)

// PodStatus represents pod's status
type PodStatus string

// PodStatus is a pod status of the pod. They determined the pod's phase,
// status and its containers.
const (
PodRunning PodStatus = "Running"
PodSucceeded = "Succeeded"
PodPending = "Pending"
PodTerminating = "Terminating"
PodInitializing = "Initializing"
PodFailed = "Failed"
PodUnknown = "Unknown"
PodRunning PodStatus = "Running" // The pod is running successfully,
PodSucceeded = "Succeeded" // The pod created by job is completed successfully,
PodPending = "Pending" // The Pod has been accepted, but some of the container images has not been created.
PodTerminating = "Terminating" // The pod is terminating
PodInitializing = "Initializing" // The init containers are running, or some of the container is initializing.
PodFailed = "Failed" // The pod fails on the init ocntaienrs, or one or more of the container exits without exit code 0.
PodUnknown = "Unknown" // Unknown phase or status
)

// GetPodStatus returns the status of the pod as PodStatus
func GetPodStatus(pod *corev1.Pod) PodStatus {
switch pod.Status.Phase {
case corev1.PodSucceeded:
return PodSucceeded
case corev1.PodPending:
return PodPending
case corev1.PodFailed:
return PodFailed
case corev1.PodUnknown:
return PodUnknown
}

for _, container := range pod.Status.InitContainerStatuses {
switch {
case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0:
continue
case container.State.Terminated != nil:
return PodFailed
default:
return PodInitializing
}
break
}

hasCompleted := false
hasRunning := false
for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- {
container := pod.Status.ContainerStatuses[i]
if container.State.Waiting != nil && container.State.Waiting.Reason != "" {
return PodInitializing
} else if container.State.Terminated != nil && container.State.Terminated.Reason == "Completed" {
hasCompleted = true
} else if container.State.Terminated != nil {
return PodFailed
} else if container.Ready && container.State.Running != nil {
hasRunning = true
}
}
if hasCompleted && hasRunning {
return PodRunning
}

if pod.DeletionTimestamp != nil && pod.Status.Reason == "NodeLost" {
return PodUnknown
} else if pod.DeletionTimestamp != nil {
return PodTerminating
}
return PodRunning
}
9 changes: 0 additions & 9 deletions pkg/ui/pod_style.go

This file was deleted.

Loading

0 comments on commit 6e7a7ae

Please sign in to comment.