summaryrefslogtreecommitdiff
path: root/cmd/crioctl/sandbox.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/crioctl/sandbox.go')
-rw-r--r--cmd/crioctl/sandbox.go386
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
+}