diff options
Diffstat (limited to 'cmd/crioctl/sandbox.go')
-rw-r--r-- | cmd/crioctl/sandbox.go | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/cmd/crioctl/sandbox.go b/cmd/crioctl/sandbox.go new file mode 100644 index 000000000..e44183be3 --- /dev/null +++ b/cmd/crioctl/sandbox.go @@ -0,0 +1,386 @@ +package main + +import ( + "fmt" + "log" + "sort" + "strings" + "time" + + "github.com/urfave/cli" + "golang.org/x/net/context" + pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" +) + +var podSandboxCommand = cli.Command{ + Name: "pod", + Subcommands: []cli.Command{ + runPodSandboxCommand, + stopPodSandboxCommand, + removePodSandboxCommand, + podSandboxStatusCommand, + listPodSandboxCommand, + }, +} + +var runPodSandboxCommand = cli.Command{ + Name: "run", + Usage: "run a pod", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "config", + Value: "", + Usage: "the path of a pod sandbox config file", + }, + cli.StringFlag{ + Name: "name", + Value: "", + Usage: "the name of the pod sandbox", + }, + cli.StringSliceFlag{ + Name: "label", + Usage: "add key=value labels to the container", + }, + }, + Action: func(context *cli.Context) error { + // Set up a connection to the server. + conn, err := getClientConnection(context) + if err != nil { + return fmt.Errorf("failed to connect: %v", err) + } + defer conn.Close() + client := pb.NewRuntimeServiceClient(conn) + + opts := createOptions{ + configPath: context.String("config"), + name: context.String("name"), + labels: make(map[string]string), + } + + for _, l := range context.StringSlice("label") { + pair := strings.Split(l, "=") + if len(pair) != 2 { + return fmt.Errorf("incorrectly specified label: %v", l) + } + opts.labels[pair[0]] = pair[1] + } + + // Test RuntimeServiceClient.RunPodSandbox + err = RunPodSandbox(client, opts) + if err != nil { + return fmt.Errorf("Creating the pod sandbox failed: %v", err) + } + return nil + }, +} + +var stopPodSandboxCommand = cli.Command{ + Name: "stop", + Usage: "stop a pod sandbox", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "id", + Value: "", + Usage: "id of the pod sandbox", + }, + }, + Action: func(context *cli.Context) error { + // Set up a connection to the server. + conn, err := getClientConnection(context) + if err != nil { + return fmt.Errorf("failed to connect: %v", err) + } + defer conn.Close() + client := pb.NewRuntimeServiceClient(conn) + + err = StopPodSandbox(client, context.String("id")) + if err != nil { + return fmt.Errorf("stopping the pod sandbox failed: %v", err) + } + return nil + }, +} + +var removePodSandboxCommand = cli.Command{ + Name: "remove", + Usage: "remove a pod sandbox", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "id", + Value: "", + Usage: "id of the pod sandbox", + }, + }, + Action: func(context *cli.Context) error { + // Set up a connection to the server. + conn, err := getClientConnection(context) + if err != nil { + return fmt.Errorf("failed to connect: %v", err) + } + defer conn.Close() + client := pb.NewRuntimeServiceClient(conn) + + err = RemovePodSandbox(client, context.String("id")) + if err != nil { + return fmt.Errorf("removing the pod sandbox failed: %v", err) + } + return nil + }, +} + +var podSandboxStatusCommand = cli.Command{ + Name: "status", + Usage: "return the status of a pod", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "id", + Value: "", + Usage: "id of the pod", + }, + }, + Action: func(context *cli.Context) error { + // Set up a connection to the server. + conn, err := getClientConnection(context) + if err != nil { + return fmt.Errorf("failed to connect: %v", err) + } + defer conn.Close() + client := pb.NewRuntimeServiceClient(conn) + + err = PodSandboxStatus(client, context.String("id")) + if err != nil { + return fmt.Errorf("getting the pod sandbox status failed: %v", err) + } + return nil + }, +} + +var listPodSandboxCommand = cli.Command{ + Name: "list", + Usage: "list pod sandboxes", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "id", + Value: "", + Usage: "filter by pod sandbox id", + }, + cli.StringFlag{ + Name: "state", + Value: "", + Usage: "filter by pod sandbox state", + }, + cli.StringSliceFlag{ + Name: "label", + Usage: "filter by key=value label", + }, + cli.BoolFlag{ + Name: "quiet", + Usage: "list only pod IDs", + }, + }, + Action: func(context *cli.Context) error { + // Set up a connection to the server. + conn, err := getClientConnection(context) + if err != nil { + return fmt.Errorf("failed to connect: %v", err) + } + defer conn.Close() + client := pb.NewRuntimeServiceClient(conn) + + opts := listOptions{ + id: context.String("id"), + state: context.String("state"), + quiet: context.Bool("quiet"), + labels: make(map[string]string), + } + + for _, l := range context.StringSlice("label") { + pair := strings.Split(l, "=") + if len(pair) != 2 { + return fmt.Errorf("incorrectly specified label: %v", l) + } + opts.labels[pair[0]] = pair[1] + } + + err = ListPodSandboxes(client, opts) + if err != nil { + return fmt.Errorf("listing pod sandboxes failed: %v", err) + } + return nil + }, +} + +// RunPodSandbox sends a RunPodSandboxRequest to the server, and parses +// the returned RunPodSandboxResponse. +func RunPodSandbox(client pb.RuntimeServiceClient, opts createOptions) error { + config, err := loadPodSandboxConfig(opts.configPath) + if err != nil { + return err + } + + // Override the name by the one specified through CLI + if opts.name != "" { + config.Metadata.Name = opts.name + } + + for k, v := range opts.labels { + config.Labels[k] = v + } + + r, err := client.RunPodSandbox(context.Background(), &pb.RunPodSandboxRequest{Config: config}) + if err != nil { + return err + } + fmt.Println(r.PodSandboxId) + return nil +} + +// StopPodSandbox sends a StopPodSandboxRequest to the server, and parses +// the returned StopPodSandboxResponse. +func StopPodSandbox(client pb.RuntimeServiceClient, ID string) error { + if ID == "" { + return fmt.Errorf("ID cannot be empty") + } + _, err := client.StopPodSandbox(context.Background(), &pb.StopPodSandboxRequest{PodSandboxId: ID}) + if err != nil { + return err + } + fmt.Println(ID) + return nil +} + +// RemovePodSandbox sends a RemovePodSandboxRequest to the server, and parses +// the returned RemovePodSandboxResponse. +func RemovePodSandbox(client pb.RuntimeServiceClient, ID string) error { + if ID == "" { + return fmt.Errorf("ID cannot be empty") + } + _, err := client.RemovePodSandbox(context.Background(), &pb.RemovePodSandboxRequest{PodSandboxId: ID}) + if err != nil { + return err + } + fmt.Println(ID) + return nil +} + +// PodSandboxStatus sends a PodSandboxStatusRequest to the server, and parses +// the returned PodSandboxStatusResponse. +func PodSandboxStatus(client pb.RuntimeServiceClient, ID string) error { + if ID == "" { + return fmt.Errorf("ID cannot be empty") + } + r, err := client.PodSandboxStatus(context.Background(), &pb.PodSandboxStatusRequest{PodSandboxId: ID}) + if err != nil { + return err + } + fmt.Printf("ID: %s\n", r.Status.Id) + if r.Status.Metadata != nil { + if r.Status.Metadata.Name != "" { + fmt.Printf("Name: %s\n", r.Status.Metadata.Name) + } + if r.Status.Metadata.Uid != "" { + fmt.Printf("UID: %s\n", r.Status.Metadata.Uid) + } + if r.Status.Metadata.Namespace != "" { + fmt.Printf("Namespace: %s\n", r.Status.Metadata.Namespace) + } + fmt.Printf("Attempt: %v\n", r.Status.Metadata.Attempt) + } + fmt.Printf("Status: %s\n", r.Status.State) + ctm := time.Unix(0, r.Status.CreatedAt) + fmt.Printf("Created: %v\n", ctm) + if r.Status.Network != nil { + fmt.Printf("IP Address: %v\n", r.Status.Network.Ip) + } + if r.Status.Labels != nil { + fmt.Println("Labels:") + for _, k := range getSortedKeys(r.Status.Labels) { + fmt.Printf("\t%s -> %s\n", k, r.Status.Labels[k]) + } + } + if r.Status.Annotations != nil { + fmt.Println("Annotations:") + for _, k := range getSortedKeys(r.Status.Annotations) { + fmt.Printf("\t%s -> %s\n", k, r.Status.Annotations[k]) + } + } + return nil +} + +// ListPodSandboxes sends a ListPodSandboxRequest to the server, and parses +// the returned ListPodSandboxResponse. +func ListPodSandboxes(client pb.RuntimeServiceClient, opts listOptions) error { + filter := &pb.PodSandboxFilter{} + if opts.id != "" { + filter.Id = opts.id + } + if opts.state != "" { + st := &pb.PodSandboxStateValue{} + st.State = pb.PodSandboxState_SANDBOX_NOTREADY + switch opts.state { + case "ready": + st.State = pb.PodSandboxState_SANDBOX_READY + filter.State = st + case "notready": + st.State = pb.PodSandboxState_SANDBOX_NOTREADY + filter.State = st + default: + log.Fatalf("--state should be ready or notready") + } + } + if opts.labels != nil { + filter.LabelSelector = opts.labels + } + r, err := client.ListPodSandbox(context.Background(), &pb.ListPodSandboxRequest{ + Filter: filter, + }) + if err != nil { + return err + } + for _, pod := range r.Items { + if opts.quiet { + fmt.Println(pod.Id) + continue + } + fmt.Printf("ID: %s\n", pod.Id) + if pod.Metadata != nil { + if pod.Metadata.Name != "" { + fmt.Printf("Name: %s\n", pod.Metadata.Name) + } + if pod.Metadata.Uid != "" { + fmt.Printf("UID: %s\n", pod.Metadata.Uid) + } + if pod.Metadata.Namespace != "" { + fmt.Printf("Namespace: %s\n", pod.Metadata.Namespace) + } + fmt.Printf("Attempt: %v\n", pod.Metadata.Attempt) + } + fmt.Printf("Status: %s\n", pod.State) + ctm := time.Unix(0, pod.CreatedAt) + fmt.Printf("Created: %v\n", ctm) + if pod.Labels != nil { + fmt.Println("Labels:") + for _, k := range getSortedKeys(pod.Labels) { + fmt.Printf("\t%s -> %s\n", k, pod.Labels[k]) + } + } + if pod.Annotations != nil { + fmt.Println("Annotations:") + for _, k := range getSortedKeys(pod.Annotations) { + fmt.Printf("\t%s -> %s\n", k, pod.Annotations[k]) + } + } + fmt.Println() + } + return nil +} + +func getSortedKeys(m map[string]string) []string { + var keys []string + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + return keys +} |