drop crioctl source code
Signed-off-by: Wei Wei <weiwei.inf@gmail.com>
This commit is contained in:
parent
5f5a7a3648
commit
3006a2159a
13 changed files with 45 additions and 1470 deletions
|
@ -32,7 +32,6 @@ jobs:
|
||||||
- make .gitvalidation
|
- make .gitvalidation
|
||||||
- make gofmt
|
- make gofmt
|
||||||
- make lint
|
- make lint
|
||||||
- make verify
|
|
||||||
- make testunit
|
- make testunit
|
||||||
- make docs
|
- make docs
|
||||||
- make
|
- make
|
||||||
|
@ -42,14 +41,12 @@ jobs:
|
||||||
- make .gitvalidation
|
- make .gitvalidation
|
||||||
- make gofmt
|
- make gofmt
|
||||||
- make lint
|
- make lint
|
||||||
- make verify
|
|
||||||
- make testunit
|
- make testunit
|
||||||
- make docs
|
- make docs
|
||||||
- make
|
- make
|
||||||
go: 1.9.x
|
go: 1.9.x
|
||||||
- script:
|
- script:
|
||||||
- make .gitvalidation
|
- make .gitvalidation
|
||||||
- make verify
|
|
||||||
- make testunit
|
- make testunit
|
||||||
- make docs
|
- make docs
|
||||||
- make
|
- make
|
||||||
|
|
14
Makefile
14
Makefile
|
@ -46,7 +46,7 @@ help:
|
||||||
@echo "Usage: make <target>"
|
@echo "Usage: make <target>"
|
||||||
@echo
|
@echo
|
||||||
@echo " * 'install' - Install binaries to system locations"
|
@echo " * 'install' - Install binaries to system locations"
|
||||||
@echo " * 'binaries' - Build crio, conmon, pause, and crioctl"
|
@echo " * 'binaries' - Build crio, conmon and pause"
|
||||||
@echo " * 'integration' - Execute integration tests"
|
@echo " * 'integration' - Execute integration tests"
|
||||||
@echo " * 'clean' - Clean artifacts"
|
@echo " * 'clean' - Clean artifacts"
|
||||||
@echo " * 'lint' - Execute the source code linter"
|
@echo " * 'lint' - Execute the source code linter"
|
||||||
|
@ -66,9 +66,6 @@ lint: .gopathok
|
||||||
gofmt:
|
gofmt:
|
||||||
@./hack/verify-gofmt.sh
|
@./hack/verify-gofmt.sh
|
||||||
|
|
||||||
verify:
|
|
||||||
@./hack/validate/deprecate-crioctl
|
|
||||||
|
|
||||||
conmon:
|
conmon:
|
||||||
$(MAKE) -C $@
|
$(MAKE) -C $@
|
||||||
|
|
||||||
|
@ -87,9 +84,6 @@ test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go)
|
||||||
crio: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crio $(PROJECT))
|
crio: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crio $(PROJECT))
|
||||||
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o bin/$@ $(PROJECT)/cmd/crio
|
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o bin/$@ $(PROJECT)/cmd/crio
|
||||||
|
|
||||||
crioctl: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/crioctl $(PROJECT))
|
|
||||||
$(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o bin/$@ $(PROJECT)/cmd/crioctl
|
|
||||||
|
|
||||||
crio.conf: crio
|
crio.conf: crio
|
||||||
./bin/crio --config="" config --default > crio.conf
|
./bin/crio --config="" config --default > crio.conf
|
||||||
|
|
||||||
|
@ -102,7 +96,7 @@ endif
|
||||||
rm -fr test/testdata/redis-image
|
rm -fr test/testdata/redis-image
|
||||||
find . -name \*~ -delete
|
find . -name \*~ -delete
|
||||||
find . -name \#\* -delete
|
find . -name \#\* -delete
|
||||||
rm -f bin/crioctl bin/crio
|
rm -f bin/crio
|
||||||
make -C conmon clean
|
make -C conmon clean
|
||||||
make -C pause clean
|
make -C pause clean
|
||||||
rm -f test/bin2img/bin2img
|
rm -f test/bin2img/bin2img
|
||||||
|
@ -124,7 +118,7 @@ testunit:
|
||||||
localintegration: clean binaries test-binaries
|
localintegration: clean binaries test-binaries
|
||||||
./test/test_runner.sh ${TESTFLAGS}
|
./test/test_runner.sh ${TESTFLAGS}
|
||||||
|
|
||||||
binaries: crio conmon pause crioctl
|
binaries: crio conmon pause
|
||||||
test-binaries: test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
|
test-binaries: test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp
|
||||||
|
|
||||||
MANPAGES_MD := $(wildcard docs/*.md)
|
MANPAGES_MD := $(wildcard docs/*.md)
|
||||||
|
@ -142,7 +136,6 @@ install: .gopathok install.bin install.man
|
||||||
|
|
||||||
install.bin:
|
install.bin:
|
||||||
install ${SELINUXOPT} -D -m 755 bin/crio $(BINDIR)/crio
|
install ${SELINUXOPT} -D -m 755 bin/crio $(BINDIR)/crio
|
||||||
install ${SELINUXOPT} -D -m 755 bin/crioctl $(BINDIR)/crioctl
|
|
||||||
install ${SELINUXOPT} -D -m 755 bin/conmon $(LIBEXECDIR)/crio/conmon
|
install ${SELINUXOPT} -D -m 755 bin/conmon $(LIBEXECDIR)/crio/conmon
|
||||||
install ${SELINUXOPT} -D -m 755 bin/pause $(LIBEXECDIR)/crio/pause
|
install ${SELINUXOPT} -D -m 755 bin/pause $(LIBEXECDIR)/crio/pause
|
||||||
|
|
||||||
|
@ -168,7 +161,6 @@ install.systemd:
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(BINDIR)/crio
|
rm -f $(BINDIR)/crio
|
||||||
rm -f $(BINDIR)/crioctl
|
|
||||||
rm -f $(LIBEXECDIR)/crio/conmon
|
rm -f $(LIBEXECDIR)/crio/conmon
|
||||||
rm -f $(LIBEXECDIR)/crio/pause
|
rm -f $(LIBEXECDIR)/crio/pause
|
||||||
for i in $(filter %.1,$(MANPAGES)); do \
|
for i in $(filter %.1,$(MANPAGES)); do \
|
||||||
|
|
|
@ -28,8 +28,7 @@ storage_driver = "{{ .Storage }}"
|
||||||
storage_option = [
|
storage_option = [
|
||||||
{{ range $opt := .StorageOptions }}{{ printf "\t%q,\n" $opt }}{{ end }}]
|
{{ range $opt := .StorageOptions }}{{ printf "\t%q,\n" $opt }}{{ end }}]
|
||||||
|
|
||||||
# The "crio.api" table contains settings for the kubelet/gRPC
|
# The "crio.api" table contains settings for the kubelet/gRPC interface.
|
||||||
# interface (which is also used by crioctl).
|
|
||||||
[crio.api]
|
[crio.api]
|
||||||
|
|
||||||
# listen is the path to the AF_LOCAL socket on which crio will listen.
|
# listen is the path to the AF_LOCAL socket on which crio will listen.
|
||||||
|
|
|
@ -1,654 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/kubernetes-incubator/cri-o/client"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
restclient "k8s.io/client-go/rest"
|
|
||||||
"k8s.io/client-go/tools/remotecommand"
|
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var containerCommand = cli.Command{
|
|
||||||
Name: "container",
|
|
||||||
Aliases: []string{"ctr"},
|
|
||||||
Subcommands: []cli.Command{
|
|
||||||
createContainerCommand,
|
|
||||||
inspectContainerCommand,
|
|
||||||
startContainerCommand,
|
|
||||||
stopContainerCommand,
|
|
||||||
removeContainerCommand,
|
|
||||||
containerStatusCommand,
|
|
||||||
listContainersCommand,
|
|
||||||
execSyncCommand,
|
|
||||||
execCommand,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type createOptions struct {
|
|
||||||
// configPath is path to the config for container
|
|
||||||
configPath string
|
|
||||||
// name sets the container name
|
|
||||||
name string
|
|
||||||
// podID of the container
|
|
||||||
podID string
|
|
||||||
// labels for the container
|
|
||||||
labels map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
var createContainerCommand = cli.Command{
|
|
||||||
Name: "create",
|
|
||||||
Usage: "create a container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "pod",
|
|
||||||
Usage: "the id of the pod sandbox to which the container belongs",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "config",
|
|
||||||
Value: "config.json",
|
|
||||||
Usage: "the path of a container config file",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "name",
|
|
||||||
Value: "",
|
|
||||||
Usage: "the name of the container",
|
|
||||||
},
|
|
||||||
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)
|
|
||||||
|
|
||||||
if !context.IsSet("pod") {
|
|
||||||
return fmt.Errorf("Please specify the id of the pod sandbox to which the container belongs via the --pod option")
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := createOptions{
|
|
||||||
configPath: context.String("config"),
|
|
||||||
name: context.String("name"),
|
|
||||||
podID: context.String("pod"),
|
|
||||||
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.CreateContainer
|
|
||||||
err = CreateContainer(client, opts)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Creating container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var startContainerCommand = cli.Command{
|
|
||||||
Name: "start",
|
|
||||||
Usage: "start a container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of 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)
|
|
||||||
|
|
||||||
err = StartContainer(client, context.String("id"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Starting the container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var stopContainerCommand = cli.Command{
|
|
||||||
Name: "stop",
|
|
||||||
Usage: "stop a container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of the container",
|
|
||||||
},
|
|
||||||
cli.Int64Flag{
|
|
||||||
Name: "timeout",
|
|
||||||
Value: 10,
|
|
||||||
Usage: "seconds to wait to kill the container after a graceful stop is requested",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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 = StopContainer(client, context.String("id"), context.Int64("timeout"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Stopping the container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var removeContainerCommand = cli.Command{
|
|
||||||
Name: "remove",
|
|
||||||
Usage: "remove a container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of 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)
|
|
||||||
|
|
||||||
err = RemoveContainer(client, context.String("id"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Removing the container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var containerStatusCommand = cli.Command{
|
|
||||||
Name: "status",
|
|
||||||
Usage: "get the status of a container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of 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)
|
|
||||||
|
|
||||||
err = ContainerStatus(client, context.String("id"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Getting the status of the container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var execSyncCommand = cli.Command{
|
|
||||||
Name: "execsync",
|
|
||||||
Usage: "exec a command synchronously in a container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of the container",
|
|
||||||
},
|
|
||||||
cli.Int64Flag{
|
|
||||||
Name: "timeout",
|
|
||||||
Value: 0,
|
|
||||||
Usage: "timeout for the command",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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 = ExecSync(client, context.String("id"), context.Args(), context.Int64("timeout"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("execing command in container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var execCommand = cli.Command{
|
|
||||||
Name: "exec",
|
|
||||||
Usage: "prepare a streaming endpoint to execute a command in the container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of the container",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "tty",
|
|
||||||
Usage: "whether to use tty",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "stdin",
|
|
||||||
Usage: "whether to stream to stdin",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "url",
|
|
||||||
Usage: "do not exec command, just prepare streaming endpoint",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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 = Exec(client, context.String("id"), context.Bool("tty"), context.Bool("stdin"), context.Bool("url"), context.Args())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("execing command in container failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type listOptions struct {
|
|
||||||
// id of the container
|
|
||||||
id string
|
|
||||||
// podID of the container
|
|
||||||
podID string
|
|
||||||
// state of the container
|
|
||||||
state string
|
|
||||||
// quiet is for listing just container IDs
|
|
||||||
quiet bool
|
|
||||||
// labels are selectors for the container
|
|
||||||
labels map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
var listContainersCommand = cli.Command{
|
|
||||||
Name: "list",
|
|
||||||
Usage: "list containers",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "quiet",
|
|
||||||
Usage: "list only container IDs",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "filter by container id",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "pod",
|
|
||||||
Value: "",
|
|
||||||
Usage: "filter by container pod id",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "state",
|
|
||||||
Value: "",
|
|
||||||
Usage: "filter by container state",
|
|
||||||
},
|
|
||||||
cli.StringSliceFlag{
|
|
||||||
Name: "label",
|
|
||||||
Usage: "filter by key=value label",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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"),
|
|
||||||
podID: context.String("pod"),
|
|
||||||
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 = ListContainers(client, opts)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("listing containers failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateContainer sends a CreateContainerRequest to the server, and parses
|
|
||||||
// the returned CreateContainerResponse.
|
|
||||||
func CreateContainer(client pb.RuntimeServiceClient, opts createOptions) error {
|
|
||||||
config, err := loadContainerConfig(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.CreateContainer(context.Background(), &pb.CreateContainerRequest{
|
|
||||||
PodSandboxId: opts.podID,
|
|
||||||
Config: config,
|
|
||||||
// TODO(runcom): this is missing PodSandboxConfig!!!
|
|
||||||
// we should/could find a way to retrieve it from the fs and set it here
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(r.ContainerId)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartContainer sends a StartContainerRequest to the server, and parses
|
|
||||||
// the returned StartContainerResponse.
|
|
||||||
func StartContainer(client pb.RuntimeServiceClient, ID string) error {
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
_, err := client.StartContainer(context.Background(), &pb.StartContainerRequest{
|
|
||||||
ContainerId: ID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(ID)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopContainer sends a StopContainerRequest to the server, and parses
|
|
||||||
// the returned StopContainerResponse.
|
|
||||||
func StopContainer(client pb.RuntimeServiceClient, ID string, timeout int64) error {
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
_, err := client.StopContainer(context.Background(), &pb.StopContainerRequest{
|
|
||||||
ContainerId: ID,
|
|
||||||
Timeout: timeout,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(ID)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveContainer sends a RemoveContainerRequest to the server, and parses
|
|
||||||
// the returned RemoveContainerResponse.
|
|
||||||
func RemoveContainer(client pb.RuntimeServiceClient, ID string) error {
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
_, err := client.RemoveContainer(context.Background(), &pb.RemoveContainerRequest{
|
|
||||||
ContainerId: ID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(ID)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContainerStatus sends a ContainerStatusRequest to the server, and parses
|
|
||||||
// the returned ContainerStatusResponse.
|
|
||||||
func ContainerStatus(client pb.RuntimeServiceClient, ID string) error {
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
r, err := client.ContainerStatus(context.Background(), &pb.ContainerStatusRequest{
|
|
||||||
ContainerId: 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)
|
|
||||||
}
|
|
||||||
fmt.Printf("Attempt: %v\n", r.Status.Metadata.Attempt)
|
|
||||||
}
|
|
||||||
// TODO(mzylowski): print it prettier
|
|
||||||
fmt.Printf("Status: %s\n", r.Status.State)
|
|
||||||
ctm := time.Unix(0, r.Status.CreatedAt)
|
|
||||||
fmt.Printf("Created: %v\n", ctm)
|
|
||||||
stm := time.Unix(0, r.Status.StartedAt)
|
|
||||||
fmt.Printf("Started: %v\n", stm)
|
|
||||||
ftm := time.Unix(0, r.Status.FinishedAt)
|
|
||||||
fmt.Printf("Finished: %v\n", ftm)
|
|
||||||
fmt.Printf("Exit Code: %v\n", r.Status.ExitCode)
|
|
||||||
fmt.Printf("Reason: %v\n", r.Status.Reason)
|
|
||||||
if r.Status.Image != nil {
|
|
||||||
fmt.Printf("Image: %v\n", r.Status.Image.Image)
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// TODO: https://github.com/kubernetes-incubator/cri-o/issues/531
|
|
||||||
//
|
|
||||||
//fmt.Printf("ImageRef: %v\n", r.Status.ImageRef)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecSync sends an ExecSyncRequest to the server, and parses
|
|
||||||
// the returned ExecSyncResponse.
|
|
||||||
func ExecSync(client pb.RuntimeServiceClient, ID string, cmd []string, timeout int64) error {
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
r, err := client.ExecSync(context.Background(), &pb.ExecSyncRequest{
|
|
||||||
ContainerId: ID,
|
|
||||||
Cmd: cmd,
|
|
||||||
Timeout: timeout,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println("Stdout:")
|
|
||||||
fmt.Println(string(r.Stdout))
|
|
||||||
fmt.Println("Stderr:")
|
|
||||||
fmt.Println(string(r.Stderr))
|
|
||||||
fmt.Printf("Exit code: %v\n", r.ExitCode)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exec sends an ExecRequest to the server, and parses
|
|
||||||
// the returned ExecResponse.
|
|
||||||
func Exec(client pb.RuntimeServiceClient, ID string, tty bool, stdin bool, urlOnly bool, cmd []string) error {
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
r, err := client.Exec(context.Background(), &pb.ExecRequest{
|
|
||||||
ContainerId: ID,
|
|
||||||
Cmd: cmd,
|
|
||||||
Tty: tty,
|
|
||||||
Stdin: stdin,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if urlOnly {
|
|
||||||
fmt.Println("URL:")
|
|
||||||
fmt.Println(r.Url)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
execURL, err := url.Parse(r.Url)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
streamExec, err := remotecommand.NewSPDYExecutor(&restclient.Config{}, "GET", execURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
options := remotecommand.StreamOptions{
|
|
||||||
Stdout: os.Stdout,
|
|
||||||
Stderr: os.Stderr,
|
|
||||||
Tty: tty,
|
|
||||||
}
|
|
||||||
|
|
||||||
if stdin {
|
|
||||||
options.Stdin = os.Stdin
|
|
||||||
}
|
|
||||||
|
|
||||||
return streamExec.Stream(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListContainers sends a ListContainerRequest to the server, and parses
|
|
||||||
// the returned ListContainerResponse.
|
|
||||||
func ListContainers(client pb.RuntimeServiceClient, opts listOptions) error {
|
|
||||||
filter := &pb.ContainerFilter{}
|
|
||||||
if opts.id != "" {
|
|
||||||
filter.Id = opts.id
|
|
||||||
}
|
|
||||||
if opts.podID != "" {
|
|
||||||
filter.PodSandboxId = opts.podID
|
|
||||||
}
|
|
||||||
if opts.state != "" {
|
|
||||||
st := &pb.ContainerStateValue{}
|
|
||||||
st.State = pb.ContainerState_CONTAINER_UNKNOWN
|
|
||||||
switch opts.state {
|
|
||||||
case "created":
|
|
||||||
st.State = pb.ContainerState_CONTAINER_CREATED
|
|
||||||
filter.State = st
|
|
||||||
case "running":
|
|
||||||
st.State = pb.ContainerState_CONTAINER_RUNNING
|
|
||||||
filter.State = st
|
|
||||||
case "stopped":
|
|
||||||
st.State = pb.ContainerState_CONTAINER_EXITED
|
|
||||||
filter.State = st
|
|
||||||
default:
|
|
||||||
log.Fatalf("--state should be one of created, running or stopped")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if opts.labels != nil {
|
|
||||||
filter.LabelSelector = opts.labels
|
|
||||||
}
|
|
||||||
r, err := client.ListContainers(context.Background(), &pb.ListContainersRequest{
|
|
||||||
Filter: filter,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, c := range r.GetContainers() {
|
|
||||||
if opts.quiet {
|
|
||||||
fmt.Println(c.Id)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Printf("ID: %s\n", c.Id)
|
|
||||||
fmt.Printf("Pod: %s\n", c.PodSandboxId)
|
|
||||||
if c.Metadata != nil {
|
|
||||||
if c.Metadata.Name != "" {
|
|
||||||
fmt.Printf("Name: %s\n", c.Metadata.Name)
|
|
||||||
}
|
|
||||||
fmt.Printf("Attempt: %v\n", c.Metadata.Attempt)
|
|
||||||
}
|
|
||||||
fmt.Printf("Status: %s\n", c.State)
|
|
||||||
if c.Image != nil {
|
|
||||||
fmt.Printf("Image: %s\n", c.Image.Image)
|
|
||||||
}
|
|
||||||
ctm := time.Unix(0, c.CreatedAt)
|
|
||||||
fmt.Printf("Created: %v\n", ctm)
|
|
||||||
if c.Labels != nil {
|
|
||||||
fmt.Println("Labels:")
|
|
||||||
for _, k := range getSortedKeys(c.Labels) {
|
|
||||||
fmt.Printf("\t%s -> %s\n", k, c.Labels[k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if c.Annotations != nil {
|
|
||||||
fmt.Println("Annotations:")
|
|
||||||
for _, k := range getSortedKeys(c.Annotations) {
|
|
||||||
fmt.Printf("\t%s -> %s\n", k, c.Annotations[k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Println()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var inspectContainerCommand = cli.Command{
|
|
||||||
Name: "inspect",
|
|
||||||
Usage: "get container info from crio daemon",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of the container",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(context *cli.Context) error {
|
|
||||||
ID := context.String("id")
|
|
||||||
if ID == "" {
|
|
||||||
return fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
c, err := client.New(context.GlobalString("connect"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cInfo, err := c.ContainerInfo(ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonBytes, err := json.MarshalIndent(cInfo, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(string(jsonBytes))
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var imageCommand = cli.Command{
|
|
||||||
Name: "image",
|
|
||||||
Subcommands: []cli.Command{
|
|
||||||
pullImageCommand,
|
|
||||||
listImageCommand,
|
|
||||||
imageStatusCommand,
|
|
||||||
removeImageCommand,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var pullImageCommand = cli.Command{
|
|
||||||
Name: "pull",
|
|
||||||
Usage: "pull an image",
|
|
||||||
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.NewImageServiceClient(conn)
|
|
||||||
|
|
||||||
_, err = PullImage(client, context.Args().Get(0))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("pulling image failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var listImageCommand = cli.Command{
|
|
||||||
Name: "list",
|
|
||||||
Usage: "list images",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "quiet",
|
|
||||||
Usage: "list only image 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.NewImageServiceClient(conn)
|
|
||||||
|
|
||||||
r, err := ListImages(client, context.Args().Get(0))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("listing images failed: %v", err)
|
|
||||||
}
|
|
||||||
quiet := context.Bool("quiet")
|
|
||||||
for _, image := range r.Images {
|
|
||||||
if quiet {
|
|
||||||
fmt.Printf("%s\n", image.Id)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Printf("ID: %s\n", image.Id)
|
|
||||||
for _, tag := range image.RepoTags {
|
|
||||||
fmt.Printf("Tag: %s\n", tag)
|
|
||||||
}
|
|
||||||
for _, digest := range image.RepoDigests {
|
|
||||||
fmt.Printf("Digest: %s\n", digest)
|
|
||||||
}
|
|
||||||
if image.Size_ != 0 {
|
|
||||||
fmt.Printf("Size: %d\n", image.Size_)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var imageStatusCommand = cli.Command{
|
|
||||||
Name: "status",
|
|
||||||
Usage: "return the status of an image",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Usage: "id of the image",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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.NewImageServiceClient(conn)
|
|
||||||
|
|
||||||
r, err := ImageStatus(client, context.String("id"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("image status request failed: %v", err)
|
|
||||||
}
|
|
||||||
image := r.Image
|
|
||||||
if image == nil {
|
|
||||||
return fmt.Errorf("no such image present")
|
|
||||||
}
|
|
||||||
fmt.Printf("ID: %s\n", image.Id)
|
|
||||||
for _, tag := range image.RepoTags {
|
|
||||||
fmt.Printf("Tag: %s\n", tag)
|
|
||||||
}
|
|
||||||
for _, digest := range image.RepoDigests {
|
|
||||||
fmt.Printf("Digest: %s\n", digest)
|
|
||||||
}
|
|
||||||
fmt.Printf("Size: %d\n", image.Size_)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
var removeImageCommand = cli.Command{
|
|
||||||
Name: "remove",
|
|
||||||
Usage: "remove an image",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "id of the image",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
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.NewImageServiceClient(conn)
|
|
||||||
|
|
||||||
_, err = RemoveImage(client, context.String("id"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("removing the image failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// PullImage sends a PullImageRequest to the server, and parses
|
|
||||||
// the returned PullImageResponse.
|
|
||||||
func PullImage(client pb.ImageServiceClient, image string) (*pb.PullImageResponse, error) {
|
|
||||||
return client.PullImage(context.Background(), &pb.PullImageRequest{Image: &pb.ImageSpec{Image: image}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListImages sends a ListImagesRequest to the server, and parses
|
|
||||||
// the returned ListImagesResponse.
|
|
||||||
func ListImages(client pb.ImageServiceClient, image string) (*pb.ListImagesResponse, error) {
|
|
||||||
return client.ListImages(context.Background(), &pb.ListImagesRequest{Filter: &pb.ImageFilter{Image: &pb.ImageSpec{Image: image}}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImageStatus sends an ImageStatusRequest to the server, and parses
|
|
||||||
// the returned ImageStatusResponse.
|
|
||||||
func ImageStatus(client pb.ImageServiceClient, image string) (*pb.ImageStatusResponse, error) {
|
|
||||||
return client.ImageStatus(context.Background(), &pb.ImageStatusRequest{Image: &pb.ImageSpec{Image: image}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveImage sends a RemoveImageRequest to the server, and parses
|
|
||||||
// the returned RemoveImageResponse.
|
|
||||||
func RemoveImage(client pb.ImageServiceClient, image string) (*pb.RemoveImageResponse, error) {
|
|
||||||
if image == "" {
|
|
||||||
return nil, fmt.Errorf("ID cannot be empty")
|
|
||||||
}
|
|
||||||
return client.RemoveImage(context.Background(), &pb.RemoveImageRequest{Image: &pb.ImageSpec{Image: image}})
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/kubernetes-incubator/cri-o/client"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
|
||||||
|
|
||||||
var infoCommand = cli.Command{
|
|
||||||
Name: "info",
|
|
||||||
Usage: "get crio daemon info",
|
|
||||||
Action: func(context *cli.Context) error {
|
|
||||||
c, err := client.New(context.GlobalString("connect"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
di, err := c.DaemonInfo()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonBytes, err := json.MarshalIndent(di, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(string(jsonBytes))
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is populated by the Makefile from the VERSION file
|
|
||||||
// in the repository
|
|
||||||
var version = ""
|
|
||||||
|
|
||||||
// gitCommit is the commit that the binary is being built from.
|
|
||||||
// It will be populated by the Makefile.
|
|
||||||
var gitCommit = ""
|
|
||||||
|
|
||||||
func getClientConnection(context *cli.Context) (*grpc.ClientConn, error) {
|
|
||||||
conn, err := grpc.Dial(context.GlobalString("connect"), grpc.WithInsecure(), grpc.WithTimeout(context.GlobalDuration("timeout")),
|
|
||||||
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
|
|
||||||
return net.DialTimeout("unix", addr, timeout)
|
|
||||||
}))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to connect: %v", err)
|
|
||||||
}
|
|
||||||
return conn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func openFile(path string) (*os.File, error) {
|
|
||||||
f, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return nil, fmt.Errorf("config at %s not found", path)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadPodSandboxConfig(path string) (*pb.PodSandboxConfig, error) {
|
|
||||||
f, err := openFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
var config pb.PodSandboxConfig
|
|
||||||
if err := json.NewDecoder(f).Decode(&config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadContainerConfig(path string) (*pb.ContainerConfig, error) {
|
|
||||||
f, err := openFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
var config pb.ContainerConfig
|
|
||||||
if err := json.NewDecoder(f).Decode(&config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
app := cli.NewApp()
|
|
||||||
var v []string
|
|
||||||
if version != "" {
|
|
||||||
v = append(v, version)
|
|
||||||
}
|
|
||||||
if gitCommit != "" {
|
|
||||||
v = append(v, fmt.Sprintf("commit: %s", gitCommit))
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Name = "crioctl"
|
|
||||||
app.Usage = "client for crio"
|
|
||||||
app.Version = strings.Join(v, "\n")
|
|
||||||
|
|
||||||
app.Commands = []cli.Command{
|
|
||||||
podSandboxCommand,
|
|
||||||
containerCommand,
|
|
||||||
runtimeVersionCommand,
|
|
||||||
imageCommand,
|
|
||||||
infoCommand,
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Flags = []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "connect",
|
|
||||||
Value: "/var/run/crio/crio.sock",
|
|
||||||
Usage: "Socket to connect to",
|
|
||||||
},
|
|
||||||
cli.DurationFlag{
|
|
||||||
Name: "timeout",
|
|
||||||
Value: 10 * time.Second,
|
|
||||||
Usage: "Timeout of connecting to server",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,386 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
"golang.org/x/net/context"
|
|
||||||
pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var runtimeVersionCommand = cli.Command{
|
|
||||||
Name: "runtimeversion",
|
|
||||||
Usage: "get runtime version information",
|
|
||||||
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)
|
|
||||||
|
|
||||||
// Test RuntimeServiceClient.Version
|
|
||||||
version := "v1alpha1"
|
|
||||||
err = Version(client, version)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Getting the runtime version failed: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version sends a VersionRequest to the server, and parses the returned VersionResponse.
|
|
||||||
func Version(client pb.RuntimeServiceClient, version string) error {
|
|
||||||
r, err := client.Version(context.Background(), &pb.VersionRequest{Version: version})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("VersionResponse: Version: %s, RuntimeName: %s, RuntimeVersion: %s, RuntimeApiVersion: %s\n", r.Version, r.RuntimeName, r.RuntimeVersion, r.RuntimeApiVersion)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1 +1 @@
|
||||||
runtime-endpoint: /var/run/crio.sock
|
runtime-endpoint: /var/run/crio/crio.sock
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Check that no new tests are being added using crioctl
|
|
||||||
|
|
||||||
export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
||||||
source "${SCRIPTDIR}/.validate"
|
|
||||||
|
|
||||||
IFS=$'\n'
|
|
||||||
files=( $(validate_diff --diff-filter=ACMR --name-only -- 'test/*.bats' || true) )
|
|
||||||
unset IFS
|
|
||||||
|
|
||||||
badFiles=()
|
|
||||||
for f in "${files[@]}"; do
|
|
||||||
# we use "git show" here to validate that what's committed doesn't contain crioctl calls
|
|
||||||
if git show "$VALIDATE_HEAD:$f" | grep -q crioctl; then
|
|
||||||
badFiles+=( "$f" )
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ ${#badFiles[@]} -eq 0 ]; then
|
|
||||||
echo 'Congratulations! No new tests have been added using crioctl.'
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "These files use crioctl instead of crictl:"
|
|
||||||
echo ""
|
|
||||||
for f in "${badFiles[@]}"; do
|
|
||||||
echo " - $f"
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
false
|
|
||||||
fi
|
|
10
transfer.md
10
transfer.md
|
@ -7,8 +7,8 @@ This document outlines useful information for ops and dev transfer as it relates
|
||||||
## Abstract
|
## Abstract
|
||||||
|
|
||||||
The `crio` daemon is intended to provide the [CRI](https://github.com/kubernetes/community/blob/master/contributors/devel/container-runtime-interface.md) socket needed for Kubernetes to use for automating deployment, scaling, and management of containerized applications (See the document for [configuring kubernetes to use CRI-O](./kubernetes.md) for more information on that).
|
The `crio` daemon is intended to provide the [CRI](https://github.com/kubernetes/community/blob/master/contributors/devel/container-runtime-interface.md) socket needed for Kubernetes to use for automating deployment, scaling, and management of containerized applications (See the document for [configuring kubernetes to use CRI-O](./kubernetes.md) for more information on that).
|
||||||
Therefore the `crioctl` command line is a client that interfaces to the same grpc socket as the kubernetes daemon would, for talking to the `crio` daemon.
|
Therefore the [crictl](https://github.com/kubernetes-incubator/cri-tools) command line is a client that interfaces to the same grpc socket as the kubernetes daemon would, for talking to the `crio` daemon.
|
||||||
In many ways `crioctl` is only as feature rich as the Kubernetes CRI requires.
|
In many ways [crictl](https://github.com/kubernetes-incubator/cri-tools) is only as feature rich as the Kubernetes CRI requires.
|
||||||
There are additional tools e.g. `kpod` and [`buildah`](https://github.com/projectatomic/buildah) that provide a feature rich set of commands for all operational needs in a Kubernetes environment.
|
There are additional tools e.g. `kpod` and [`buildah`](https://github.com/projectatomic/buildah) that provide a feature rich set of commands for all operational needs in a Kubernetes environment.
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,12 +24,12 @@ Following provides equivalent with CRI-O tools for gathering information or jump
|
||||||
|
|
||||||
| Existing Step | CRI-O (and friends) |
|
| Existing Step | CRI-O (and friends) |
|
||||||
| :---: | :---: |
|
| :---: | :---: |
|
||||||
| `docker exec` | [`crioctl ctr exec`](./docs/crio.8.md) |
|
| `docker exec` | [`crictl exec`](https://github.com/kubernetes-incubator/cri-tools/blob/master/docs/crictl.md) |
|
||||||
| `docker info` | [`kpod info`](./docs/kpod-info.1.md) |
|
| `docker info` | [`kpod info`](./docs/kpod-info.1.md) |
|
||||||
| `docker inspect` | [`kpod inspect`](./docs/kpod-inspect.1.md) |
|
| `docker inspect` | [`kpod inspect`](./docs/kpod-inspect.1.md) |
|
||||||
| `docker logs` | [`kpod logs`](./docs/kpod-logs.1.md) |
|
| `docker logs` | [`kpod logs`](./docs/kpod-logs.1.md) |
|
||||||
| `docker ps` | [`crioctl ctr list`](./docs/crio.8.md) or [`runc list`](https://github.com/opencontainers/runc/blob/master/man/runc-list.8.md) |
|
| `docker ps` | [`crictl ps`](https://github.com/kubernetes-incubator/cri-tools/blob/master/docs/crictl.md) or [`runc list`](https://github.com/opencontainers/runc/blob/master/man/runc-list.8.md) |
|
||||||
| `docker stats` | [`kpod stats`](./docs/kpod-stats.1.md) or `crioctl ctr status`|
|
| `docker stats` | [`kpod stats`](./docs/kpod-stats.1.md) |
|
||||||
|
|
||||||
If you were already using steps like `kubectl exec` (or `oc exec` on OpenShift), they will continue to function the same way.
|
If you were already using steps like `kubectl exec` (or `oc exec` on OpenShift), they will continue to function the same way.
|
||||||
|
|
||||||
|
|
54
tutorial.md
54
tutorial.md
|
@ -26,7 +26,7 @@ gcloud compute ssh cri-o
|
||||||
This section will walk you through installing the following components:
|
This section will walk you through installing the following components:
|
||||||
|
|
||||||
* crio - The implementation of the Kubernetes CRI, which manages Pods.
|
* crio - The implementation of the Kubernetes CRI, which manages Pods.
|
||||||
* crioctl - The crio client for testing.
|
* crictl - The CRI client for testing.
|
||||||
* cni - The Container Network Interface
|
* cni - The Container Network Interface
|
||||||
* runc - The OCI runtime to launch the container
|
* runc - The OCI runtime to launch the container
|
||||||
|
|
||||||
|
@ -100,6 +100,12 @@ go version
|
||||||
go version go1.7.4 linux/amd64
|
go version go1.7.4 linux/amd64
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Get crictl
|
||||||
|
|
||||||
|
```
|
||||||
|
go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
|
||||||
|
```
|
||||||
|
|
||||||
#### Build crio from source
|
#### Build crio from source
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -130,7 +136,6 @@ Output:
|
||||||
|
|
||||||
```
|
```
|
||||||
install -D -m 755 crio /usr/local/bin/crio
|
install -D -m 755 crio /usr/local/bin/crio
|
||||||
install -D -m 755 crioctl /usr/local/bin/crioctl
|
|
||||||
install -D -m 755 conmon/conmon /usr/local/libexec/crio/conmon
|
install -D -m 755 conmon/conmon /usr/local/libexec/crio/conmon
|
||||||
install -D -m 755 pause/pause /usr/local/libexec/crio/pause
|
install -D -m 755 pause/pause /usr/local/libexec/crio/pause
|
||||||
install -d -m 755 /usr/local/share/man/man{1,5,8}
|
install -d -m 755 /usr/local/share/man/man{1,5,8}
|
||||||
|
@ -182,12 +187,19 @@ sudo systemctl start crio
|
||||||
#### Ensure the crio service is running
|
#### Ensure the crio service is running
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl runtimeversion
|
sudo crictl --runtime-endpoint /var/run/crio/crio.sock info
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
VersionResponse: Version: 0.1.0, RuntimeName: runc, RuntimeVersion: 1.0.0-rc4, RuntimeApiVersion: v1alpha1
|
Version: 0.1.0
|
||||||
|
RuntimeName: cri-o
|
||||||
|
RuntimeVersion: 1.9.0-dev
|
||||||
|
RuntimeApiVersion: v1alpha1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> to avoid set --runtime-endpoint when call crictl,
|
||||||
|
> you can export $CRI_RUNTIME_ENDPOINT=/var/run/crio/crio.sock
|
||||||
|
> or cp crictl.yaml /etc/crictl.yaml from this repo
|
||||||
|
|
||||||
### CNI plugins
|
### CNI plugins
|
||||||
|
|
||||||
This tutorial will use the latest version of `CNI` plugins from the master branch and build it from source.
|
This tutorial will use the latest version of `CNI` plugins from the master branch and build it from source.
|
||||||
|
@ -288,13 +300,15 @@ cd $GOPATH/src/github.com/kubernetes-incubator/cri-o
|
||||||
Next create the Pod and capture the Pod ID for later use:
|
Next create the Pod and capture the Pod ID for later use:
|
||||||
|
|
||||||
```
|
```
|
||||||
POD_ID=$(sudo crioctl pod run --config test/testdata/sandbox_config.json)
|
POD_ID=$(sudo crictl runs test/testdata/sandbox_config.json)
|
||||||
```
|
```
|
||||||
|
|
||||||
Use the `crioctl` command to get the status of the Pod:
|
> sudo crictl runs test/testdata/sandbox_config.json
|
||||||
|
|
||||||
|
Use the `crictl` command to get the status of the Pod:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl pod status --id $POD_ID
|
sudo crictl inspects --output table $POD_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
|
@ -320,25 +334,27 @@ Annotations:
|
||||||
|
|
||||||
### Create a Redis container inside the Pod
|
### Create a Redis container inside the Pod
|
||||||
|
|
||||||
Use the `crioctl` command to pull the redis image, create a redis container from a container configuration and attach it to the Pod created earlier:
|
Use the `crictl` command to pull the redis image, create a redis container from a container configuration and attach it to the Pod created earlier:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl image pull redis:alpine
|
sudo crictl pull redis:alpine
|
||||||
CONTAINER_ID=$(sudo crioctl ctr create --pod $POD_ID --config test/testdata/container_redis.json)
|
CONTAINER_ID=$(sudo crictl create $POD_ID test/testdata/container_redis.json test/testdata/sandbox_config.json)
|
||||||
```
|
```
|
||||||
|
|
||||||
The `crioctl ctr create` command will take a few seconds to return because the redis container needs to be pulled.
|
> sudo crictl create $POD_ID test/testdata/container_redis.json test/testdata/sandbox_config.json
|
||||||
|
|
||||||
|
The `crictl create` command will take a few seconds to return because the redis container needs to be pulled.
|
||||||
|
|
||||||
Start the Redis container:
|
Start the Redis container:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl ctr start --id $CONTAINER_ID
|
sudo crictl start $CONTAINER_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
Get the status for the Redis container:
|
Get the status for the Redis container:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl ctr status --id $CONTAINER_ID
|
sudo crictl inspect $CONTAINER_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
Output:
|
Output:
|
||||||
|
@ -395,25 +411,25 @@ sudo journalctl -u crio --no-pager
|
||||||
### Stop the redis container and delete the Pod
|
### Stop the redis container and delete the Pod
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl ctr stop --id $CONTAINER_ID
|
sudo crictl stop $CONTAINER_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl ctr remove --id $CONTAINER_ID
|
sudo crictl rm $CONTAINER_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl pod stop --id $POD_ID
|
sudo crictl stops $POD_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl pod remove --id $POD_ID
|
sudo crictl rms $POD_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl pod list
|
sudo crictl sandboxes
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo crioctl ctr list
|
sudo crictl ps
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in a new issue