diff options
-rw-r--r-- | Makefile | 33 | ||||
-rw-r--r-- | cmd/crio/config.go | 192 | ||||
-rw-r--r-- | cmd/crio/daemon_linux.go | 20 | ||||
-rw-r--r-- | cmd/crio/main.go | 532 | ||||
-rw-r--r-- | cmd/crioctl/container.go | 653 | ||||
-rw-r--r-- | cmd/crioctl/image.go | 173 | ||||
-rw-r--r-- | cmd/crioctl/info.go | 31 | ||||
-rw-r--r-- | cmd/crioctl/main.go | 113 | ||||
-rw-r--r-- | cmd/crioctl/sandbox.go | 386 | ||||
-rw-r--r-- | cmd/crioctl/system.go | 41 |
10 files changed, 7 insertions, 2167 deletions
@@ -41,7 +41,7 @@ KPOD_LDFLAGS := -X main.kpodVersion=${KPOD_VERSION} LDFLAGS := -ldflags '${BASE_LDFLAGS}' LDFLAGS_KPOD := -ldflags '${BASE_LDFLAGS} ${KPOD_LDFLAGS}' -all: binaries crio.conf docs +all: binaries docs default: help @@ -49,7 +49,7 @@ help: @echo "Usage: make <target>" @echo @echo " * 'install' - Install binaries to system locations" - @echo " * 'binaries' - Build crio, conmon, pause, crioctl and kpod" + @echo " * 'binaries' - Build conmon and kpod" @echo " * 'integration' - Execute integration tests" @echo " * 'clean' - Clean artifacts" @echo " * 'lint' - Execute the source code linter" @@ -62,6 +62,9 @@ ifeq ("$(wildcard $(GOPKGDIR))","") endif touch "$(GOPATH)/.gopathok" +.bindir: + mkdir -p bin/ + lint: .gopathok @echo "checking lint" @./.tool/lint @@ -72,9 +75,6 @@ gofmt: conmon: $(MAKE) -C $@ -pause: - $(MAKE) -C $@ - test/bin2img/bin2img: .gopathok $(wildcard test/bin2img/*.go) $(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/bin2img @@ -84,18 +84,9 @@ test/copyimg/copyimg: .gopathok $(wildcard test/copyimg/*.go) test/checkseccomp/checkseccomp: .gopathok $(wildcard test/checkseccomp/*.go) $(GO) build $(LDFLAGS) -tags "$(BUILDTAGS) containers_image_ostree_stub" -o $@ $(PROJECT)/test/checkseccomp -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 - -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 - kpod: .gopathok $(shell hack/find-godeps.sh $(GOPKGDIR) cmd/kpod $(PROJECT)) $(GO) build $(LDFLAGS_KPOD) -tags "$(BUILDTAGS)" -o bin/$@ $(PROJECT)/cmd/kpod -crio.conf: crio - ./bin/crio --config="" config --default > crio.conf - clean: ifneq ($(GOPATH),) rm -f "$(GOPATH)/.gopathok" @@ -105,9 +96,8 @@ endif rm -fr test/testdata/redis-image find . -name \*~ -delete find . -name \#\* -delete - rm -f bin/crioctl bin/crio bin/kpod + rm -f bin/kpod make -C conmon clean - make -C pause clean rm -f test/bin2img/bin2img rm -f test/copyimg/copyimg rm -f test/checkseccomp/checkseccomp @@ -127,7 +117,7 @@ testunit: localintegration: clean binaries test-binaries ./test/test_runner.sh ${TESTFLAGS} -binaries: crio conmon pause kpod crioctl +binaries: .bindir conmon kpod test-binaries: test/bin2img/bin2img test/copyimg/copyimg test/checkseccomp/checkseccomp MANPAGES_MD := $(wildcard docs/*.md) @@ -147,11 +137,8 @@ docs: $(MANPAGES) install: .gopathok install.bin install.man install.bin: - install ${SELINUXOPT} -D -m 755 bin/crio $(BINDIR)/crio - install ${SELINUXOPT} -D -m 755 bin/crioctl $(BINDIR)/crioctl install ${SELINUXOPT} -D -m 755 bin/kpod $(BINDIR)/kpod install ${SELINUXOPT} -D -m 755 bin/conmon $(LIBEXECDIR)/crio/conmon - install ${SELINUXOPT} -D -m 755 bin/pause $(LIBEXECDIR)/crio/pause install.man: install ${SELINUXOPT} -d -m 755 $(MANDIR)/man1 @@ -162,7 +149,6 @@ install.man: install ${SELINUXOPT} -m 644 $(filter %.8,$(MANPAGES)) -t $(MANDIR)/man8 install.config: - install ${SELINUXOPT} -D -m 644 crio.conf $(ETCDIR_CRIO)/crio.conf install ${SELINUXOPT} -D -m 644 seccomp.json $(ETCDIR_CRIO)/seccomp.json install ${SELINUXOPT} -D -m 644 crio-umount.conf $(OCIUMOUNTINSTALLDIR)/crio-umount.conf @@ -170,11 +156,6 @@ install.completions: install ${SELINUXOPT} -d -m 755 ${BASHINSTALLDIR} install ${SELINUXOPT} -m 644 -D completions/bash/kpod ${BASHINSTALLDIR} -install.systemd: - install ${SELINUXOPT} -D -m 644 contrib/systemd/crio.service $(PREFIX)/lib/systemd/system/crio.service - ln -sf crio.service $(PREFIX)/lib/systemd/system/cri-o.service - install ${SELINUXOPT} -D -m 644 contrib/systemd/crio-shutdown.service $(PREFIX)/lib/systemd/system/crio-shutdown.service - uninstall: rm -f $(BINDIR)/crio rm -f $(BINDIR)/crioctl diff --git a/cmd/crio/config.go b/cmd/crio/config.go deleted file mode 100644 index 76e3361d4..000000000 --- a/cmd/crio/config.go +++ /dev/null @@ -1,192 +0,0 @@ -package main - -import ( - "os" - "text/template" - - "github.com/kubernetes-incubator/cri-o/server" - "github.com/urfave/cli" -) - -var commentedConfigTemplate = template.Must(template.New("config").Parse(` -# The "crio" table contains all of the server options. -[crio] - -# root is a path to the "root directory". CRIO stores all of its data, -# including container images, in this directory. -root = "{{ .Root }}" - -# run is a path to the "run directory". CRIO stores all of its state -# in this directory. -runroot = "{{ .RunRoot }}" - -# storage_driver select which storage driver is used to manage storage -# of images and containers. -storage_driver = "{{ .Storage }}" - -# storage_option is used to pass an option to the storage driver. -storage_option = [ -{{ range $opt := .StorageOptions }}{{ printf "\t%q,\n" $opt }}{{ end }}] - -# The "crio.api" table contains settings for the kubelet/gRPC -# interface (which is also used by crioctl). -[crio.api] - -# listen is the path to the AF_LOCAL socket on which crio will listen. -listen = "{{ .Listen }}" - -# stream_address is the IP address on which the stream server will listen -stream_address = "{{ .StreamAddress }}" - -# stream_port is the port on which the stream server will listen -stream_port = "{{ .StreamPort }}" - -# file_locking is whether file-based locking will be used instead of -# in-memory locking -file_locking = {{ .FileLocking }} - -# The "crio.runtime" table contains settings pertaining to the OCI -# runtime used and options for how to set up and manage the OCI runtime. -[crio.runtime] - -# runtime is the OCI compatible runtime used for trusted container workloads. -# This is a mandatory setting as this runtime will be the default one -# and will also be used for untrusted container workloads if -# runtime_untrusted_workload is not set. -runtime = "{{ .Runtime }}" - -# runtime_untrusted_workload is the OCI compatible runtime used for untrusted -# container workloads. This is an optional setting, except if -# default_container_trust is set to "untrusted". -runtime_untrusted_workload = "{{ .RuntimeUntrustedWorkload }}" - -# default_workload_trust is the default level of trust crio puts in container -# workloads. It can either be "trusted" or "untrusted", and the default -# is "trusted". -# Containers can be run through different container runtimes, depending on -# the trust hints we receive from kubelet: -# - If kubelet tags a container workload as untrusted, crio will try first to -# run it through the untrusted container workload runtime. If it is not set, -# crio will use the trusted runtime. -# - If kubelet does not provide any information about the container workload trust -# level, the selected runtime will depend on the default_container_trust setting. -# If it is set to "untrusted", then all containers except for the host privileged -# ones, will be run by the runtime_untrusted_workload runtime. Host privileged -# containers are by definition trusted and will always use the trusted container -# runtime. If default_container_trust is set to "trusted", crio will use the trusted -# container runtime for all containers. -default_workload_trust = "{{ .DefaultWorkloadTrust }}" - -# no_pivot instructs the runtime to not use pivot_root, but instead use MS_MOVE -no_pivot = {{ .NoPivot }} - -# conmon is the path to conmon binary, used for managing the runtime. -conmon = "{{ .Conmon }}" - -# conmon_env is the environment variable list for conmon process, -# used for passing necessary environment variable to conmon or runtime. -conmon_env = [ -{{ range $env := .ConmonEnv }}{{ printf "\t%q,\n" $env }}{{ end }}] - -# selinux indicates whether or not SELinux will be used for pod -# separation on the host. If you enable this flag, SELinux must be running -# on the host. -selinux = {{ .SELinux }} - -# seccomp_profile is the seccomp json profile path which is used as the -# default for the runtime. -seccomp_profile = "{{ .SeccompProfile }}" - -# apparmor_profile is the apparmor profile name which is used as the -# default for the runtime. -apparmor_profile = "{{ .ApparmorProfile }}" - -# cgroup_manager is the cgroup management implementation to be used -# for the runtime. -cgroup_manager = "{{ .CgroupManager }}" - -# hooks_dir_path is the oci hooks directory for automatically executed hooks -hooks_dir_path = "{{ .HooksDirPath }}" - -# default_mounts is the mounts list to be mounted for the container when created -default_mounts = [ -{{ range $mount := .DefaultMounts }}{{ printf "\t%q, \n" $mount }}{{ end }}] - -# pids_limit is the number of processes allowed in a container -pids_limit = {{ .PidsLimit }} - -# log_size_max is the max limit for the container log size in bytes. -# Negative values indicate that no limit is imposed. -log_size_max = {{ .LogSizeMax }} - -# The "crio.image" table contains settings pertaining to the -# management of OCI images. -[crio.image] - -# default_transport is the prefix we try prepending to an image name if the -# image name as we receive it can't be parsed as a valid source reference -default_transport = "{{ .DefaultTransport }}" - -# pause_image is the image which we use to instantiate infra containers. -pause_image = "{{ .PauseImage }}" - -# pause_command is the command to run in a pause_image to have a container just -# sit there. If the image contains the necessary information, this value need -# not be specified. -pause_command = "{{ .PauseCommand }}" - -# signature_policy is the name of the file which decides what sort of policy we -# use when deciding whether or not to trust an image that we've pulled. -# Outside of testing situations, it is strongly advised that this be left -# unspecified so that the default system-wide policy will be used. -signature_policy = "{{ .SignaturePolicyPath }}" - -# image_volumes controls how image volumes are handled. -# The valid values are mkdir and ignore. -image_volumes = "{{ .ImageVolumes }}" - -# insecure_registries is used to skip TLS verification when pulling images. -insecure_registries = [ -{{ range $opt := .InsecureRegistries }}{{ printf "\t%q,\n" $opt }}{{ end }}] - -# registries is used to specify a comma separated list of registries to be used -# when pulling an unqualified image (e.g. fedora:rawhide). -registries = [ -{{ range $opt := .Registries }}{{ printf "\t%q,\n" $opt }}{{ end }}] - -# The "crio.network" table contains settings pertaining to the -# management of CNI plugins. -[crio.network] - -# network_dir is is where CNI network configuration -# files are stored. -network_dir = "{{ .NetworkDir }}" - -# plugin_dir is is where CNI plugin binaries are stored. -plugin_dir = "{{ .PluginDir }}" -`)) - -// TODO: Currently ImageDir isn't really used, so we haven't added it to this -// template. Add it once the storage code has been merged. - -var configCommand = cli.Command{ - Name: "config", - Usage: "generate crio configuration files", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "default", - Usage: "output the default configuration", - }, - }, - Action: func(c *cli.Context) error { - // At this point, app.Before has already parsed the user's chosen - // config file. So no need to handle that here. - config := c.App.Metadata["config"].(*server.Config) - if c.Bool("default") { - config = server.DefaultConfig() - } - - // Output the commented config. - return commentedConfigTemplate.ExecuteTemplate(os.Stdout, "config", config) - }, -} diff --git a/cmd/crio/daemon_linux.go b/cmd/crio/daemon_linux.go deleted file mode 100644 index 884d3f269..000000000 --- a/cmd/crio/daemon_linux.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build linux - -package main - -import ( - systemdDaemon "github.com/coreos/go-systemd/daemon" - "github.com/sirupsen/logrus" -) - -func sdNotify() { - if _, err := systemdDaemon.SdNotify(true, "READY=1"); err != nil { - logrus.Warnf("Failed to sd_notify systemd: %v", err) - } -} - -// notifySystem sends a message to the host when the server is ready to be used -func notifySystem() { - // Tell the init daemon we are accepting requests - go sdNotify() -} diff --git a/cmd/crio/main.go b/cmd/crio/main.go deleted file mode 100644 index e58adb114..000000000 --- a/cmd/crio/main.go +++ /dev/null @@ -1,532 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net" - "net/http" - _ "net/http/pprof" - "os" - "os/signal" - "sort" - "strings" - "time" - - "github.com/containers/storage/pkg/reexec" - "github.com/kubernetes-incubator/cri-o/libkpod" - "github.com/kubernetes-incubator/cri-o/server" - "github.com/kubernetes-incubator/cri-o/version" - "github.com/opencontainers/selinux/go-selinux" - "github.com/sirupsen/logrus" - "github.com/soheilhy/cmux" - "github.com/urfave/cli" - "golang.org/x/sys/unix" - "google.golang.org/grpc" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" -) - -// gitCommit is the commit that the binary is being built from. -// It will be populated by the Makefile. -var gitCommit = "" - -func validateConfig(config *server.Config) error { - switch config.ImageVolumes { - case libkpod.ImageVolumesMkdir: - case libkpod.ImageVolumesIgnore: - case libkpod.ImageVolumesBind: - default: - return fmt.Errorf("Unrecognized image volume type specified") - - } - - // This needs to match the read buffer size in conmon - if config.LogSizeMax >= 0 && config.LogSizeMax < 8192 { - return fmt.Errorf("log size max should be negative or >= 8192") - } - return nil -} - -func mergeConfig(config *server.Config, ctx *cli.Context) error { - // Don't parse the config if the user explicitly set it to "". - if path := ctx.GlobalString("config"); path != "" { - if err := config.UpdateFromFile(path); err != nil { - if ctx.GlobalIsSet("config") || !os.IsNotExist(err) { - return err - } - - // We don't error out if --config wasn't explicitly set and the - // default doesn't exist. But we will log a warning about it, so - // the user doesn't miss it. - logrus.Warnf("default configuration file does not exist: %s", server.CrioConfigPath) - } - } - - // Override options set with the CLI. - if ctx.GlobalIsSet("conmon") { - config.Conmon = ctx.GlobalString("conmon") - } - if ctx.GlobalIsSet("pause-command") { - config.PauseCommand = ctx.GlobalString("pause-command") - } - if ctx.GlobalIsSet("pause-image") { - config.PauseImage = ctx.GlobalString("pause-image") - } - if ctx.GlobalIsSet("signature-policy") { - config.SignaturePolicyPath = ctx.GlobalString("signature-policy") - } - if ctx.GlobalIsSet("root") { - config.Root = ctx.GlobalString("root") - } - if ctx.GlobalIsSet("runroot") { - config.RunRoot = ctx.GlobalString("runroot") - } - if ctx.GlobalIsSet("storage-driver") { - config.Storage = ctx.GlobalString("storage-driver") - } - if ctx.GlobalIsSet("storage-opt") { - config.StorageOptions = ctx.GlobalStringSlice("storage-opt") - } - if ctx.GlobalIsSet("file-locking") { - config.FileLocking = ctx.GlobalBool("file-locking") - } - if ctx.GlobalIsSet("insecure-registry") { - config.InsecureRegistries = ctx.GlobalStringSlice("insecure-registry") - } - if ctx.GlobalIsSet("registry") { - config.Registries = ctx.GlobalStringSlice("registry") - } - if ctx.GlobalIsSet("default-transport") { - config.DefaultTransport = ctx.GlobalString("default-transport") - } - if ctx.GlobalIsSet("listen") { - config.Listen = ctx.GlobalString("listen") - } - if ctx.GlobalIsSet("stream-address") { - config.StreamAddress = ctx.GlobalString("stream-address") - } - if ctx.GlobalIsSet("stream-port") { - config.StreamPort = ctx.GlobalString("stream-port") - } - if ctx.GlobalIsSet("runtime") { - config.Runtime = ctx.GlobalString("runtime") - } - if ctx.GlobalIsSet("selinux") { - config.SELinux = ctx.GlobalBool("selinux") - } - if ctx.GlobalIsSet("seccomp-profile") { - config.SeccompProfile = ctx.GlobalString("seccomp-profile") - } - if ctx.GlobalIsSet("apparmor-profile") { - config.ApparmorProfile = ctx.GlobalString("apparmor-profile") - } - if ctx.GlobalIsSet("cgroup-manager") { - config.CgroupManager = ctx.GlobalString("cgroup-manager") - } - if ctx.GlobalIsSet("hooks-dir-path") { - config.HooksDirPath = ctx.GlobalString("hooks-dir-path") - } - if ctx.GlobalIsSet("default-mounts") { - config.DefaultMounts = ctx.GlobalStringSlice("default-mounts") - } - if ctx.GlobalIsSet("pids-limit") { - config.PidsLimit = ctx.GlobalInt64("pids-limit") - } - if ctx.GlobalIsSet("log-size-max") { - config.LogSizeMax = ctx.GlobalInt64("log-size-max") - } - if ctx.GlobalIsSet("cni-config-dir") { - config.NetworkDir = ctx.GlobalString("cni-config-dir") - } - if ctx.GlobalIsSet("cni-plugin-dir") { - config.PluginDir = ctx.GlobalString("cni-plugin-dir") - } - if ctx.GlobalIsSet("image-volumes") { - config.ImageVolumes = libkpod.ImageVolumesType(ctx.GlobalString("image-volumes")) - } - return nil -} - -func catchShutdown(gserver *grpc.Server, sserver *server.Server, hserver *http.Server, signalled *bool) { - sig := make(chan os.Signal, 10) - signal.Notify(sig, unix.SIGINT, unix.SIGTERM) - go func() { - for s := range sig { - switch s { - case unix.SIGINT: - logrus.Debugf("Caught SIGINT") - case unix.SIGTERM: - logrus.Debugf("Caught SIGTERM") - default: - continue - } - *signalled = true - gserver.GracefulStop() - hserver.Shutdown(context.Background()) - // TODO(runcom): enable this after https://github.com/kubernetes/kubernetes/pull/51377 - //sserver.StopStreamServer() - sserver.StopExitMonitor() - if err := sserver.Shutdown(); err != nil { - logrus.Warnf("error shutting down main service %v", err) - } - return - } - }() -} - -func main() { - if reexec.Init() { - return - } - app := cli.NewApp() - - var v []string - v = append(v, version.Version) - if gitCommit != "" { - v = append(v, fmt.Sprintf("commit: %s", gitCommit)) - } - app.Name = "crio" - app.Usage = "crio server" - app.Version = strings.Join(v, "\n") - app.Metadata = map[string]interface{}{ - "config": server.DefaultConfig(), - } - - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "config", - Value: server.CrioConfigPath, - Usage: "path to configuration file", - }, - cli.StringFlag{ - Name: "conmon", - Usage: "path to the conmon executable", - }, - cli.StringFlag{ - Name: "listen", - Usage: "path to crio socket", - }, - cli.StringFlag{ - Name: "stream-address", - Usage: "bind address for streaming socket", - }, - cli.StringFlag{ - Name: "stream-port", - Usage: "bind port for streaming socket (default: \"10010\")", - }, - cli.StringFlag{ - Name: "log", - Value: "", - Usage: "set the log file path where internal debug information is written", - }, - cli.StringFlag{ - Name: "log-format", - Value: "text", - Usage: "set the format used by logs ('text' (default), or 'json')", - }, - cli.StringFlag{ - Name: "log-level", - Usage: "log messages above specified level: debug, info (default), warn, error, fatal or panic", - }, - - cli.StringFlag{ - Name: "pause-command", - Usage: "name of the pause command in the pause image", - }, - cli.StringFlag{ - Name: "pause-image", - Usage: "name of the pause image", - }, - cli.StringFlag{ - Name: "signature-policy", - Usage: "path to signature policy file", - }, - cli.StringFlag{ - Name: "root", - Usage: "crio root dir", - }, - cli.StringFlag{ - Name: "runroot", - Usage: "crio state dir", - }, - cli.StringFlag{ - Name: "storage-driver", - Usage: "storage driver", - }, - cli.StringSliceFlag{ - Name: "storage-opt", - Usage: "storage driver option", - }, - cli.BoolFlag{ - Name: "file-locking", - Usage: "enable or disable file-based locking", - }, - cli.StringSliceFlag{ - Name: "insecure-registry", - Usage: "whether to disable TLS verification for the given registry", - }, - cli.StringSliceFlag{ - Name: "registry", - Usage: "registry to be prepended when pulling unqualified images, can be specified multiple times", - }, - cli.StringFlag{ - Name: "default-transport", - Usage: "default transport", - }, - cli.StringFlag{ - Name: "runtime", - Usage: "OCI runtime path", - }, - cli.StringFlag{ - Name: "seccomp-profile", - Usage: "default seccomp profile path", - }, - cli.StringFlag{ - Name: "apparmor-profile", - Usage: "default apparmor profile name (default: \"crio-default\")", - }, - cli.BoolFlag{ - Name: "selinux", - Usage: "enable selinux support", - }, - cli.StringFlag{ - Name: "cgroup-manager", - Usage: "cgroup manager (cgroupfs or systemd)", - }, - cli.Int64Flag{ - Name: "pids-limit", - Value: libkpod.DefaultPidsLimit, - Usage: "maximum number of processes allowed in a container", - }, - cli.Int64Flag{ - Name: "log-size-max", - Value: libkpod.DefaultLogSizeMax, - Usage: "maximum log size in bytes for a container", - }, - cli.StringFlag{ - Name: "cni-config-dir", - Usage: "CNI configuration files directory", - }, - cli.StringFlag{ - Name: "cni-plugin-dir", - Usage: "CNI plugin binaries directory", - }, - cli.StringFlag{ - Name: "image-volumes", - Value: string(libkpod.ImageVolumesMkdir), - Usage: "image volume handling ('mkdir', 'bind', or 'ignore')", - }, - cli.StringFlag{ - Name: "hooks-dir-path", - Usage: "set the OCI hooks directory path", - Value: libkpod.DefaultHooksDirPath, - Hidden: true, - }, - cli.StringSliceFlag{ - Name: "default-mounts", - Usage: "add one or more default mount paths in the form host:container", - Hidden: true, - }, - cli.BoolFlag{ - Name: "profile", - Usage: "enable pprof remote profiler on localhost:6060", - }, - cli.IntFlag{ - Name: "profile-port", - Value: 6060, - Usage: "port for the pprof profiler", - }, - cli.BoolFlag{ - Name: "enable-metrics", - Usage: "enable metrics endpoint for the servier on localhost:9090", - }, - cli.IntFlag{ - Name: "metrics-port", - Value: 9090, - Usage: "port for the metrics endpoint", - }, - } - - sort.Sort(cli.FlagsByName(app.Flags)) - sort.Sort(cli.FlagsByName(configCommand.Flags)) - - app.Commands = []cli.Command{ - configCommand, - } - - app.Before = func(c *cli.Context) error { - // Load the configuration file. - config := c.App.Metadata["config"].(*server.Config) - if err := mergeConfig(config, c); err != nil { - return err - } - - if err := validateConfig(config); err != nil { - return err - } - - cf := &logrus.TextFormatter{ - TimestampFormat: "2006-01-02 15:04:05.000000000Z07:00", - FullTimestamp: true, - } - - logrus.SetFormatter(cf) - - if loglevel := c.GlobalString("log-level"); loglevel != "" { - level, err := logrus.ParseLevel(loglevel) - if err != nil { - return err - } - - logrus.SetLevel(level) - } - - if path := c.GlobalString("log"); path != "" { - f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666) - if err != nil { - return err - } - logrus.SetOutput(f) - } - - switch c.GlobalString("log-format") { - case "text": - // retain logrus's default. - case "json": - logrus.SetFormatter(new(logrus.JSONFormatter)) - default: - return fmt.Errorf("unknown log-format %q", c.GlobalString("log-format")) - } - - return nil - } - - app.Action = func(c *cli.Context) error { - if c.GlobalBool("profile") { - profilePort := c.GlobalInt("profile-port") - profileEndpoint := fmt.Sprintf("localhost:%v", profilePort) - go func() { - http.ListenAndServe(profileEndpoint, nil) - }() - } - - args := c.Args() - if len(args) > 0 { - for _, command := range app.Commands { - if args[0] == command.Name { - break - } - } - return fmt.Errorf("command %q not supported", args[0]) - } - - config := c.App.Metadata["config"].(*server.Config) - - if !config.SELinux { - selinux.SetDisabled() - } - - if _, err := os.Stat(config.Runtime); os.IsNotExist(err) { - // path to runtime does not exist - return fmt.Errorf("invalid --runtime value %q", err) - } - - // Remove the socket if it already exists - if _, err := os.Stat(config.Listen); err == nil { - if err := os.Remove(config.Listen); err != nil { - logrus.Fatal(err) - } - } - lis, err := net.Listen("unix", config.Listen) - if err != nil { - logrus.Fatalf("failed to listen: %v", err) - } - - s := grpc.NewServer() - - service, err := server.New(config) - if err != nil { - logrus.Fatal(err) - } - - if c.GlobalBool("enable-metrics") { - metricsPort := c.GlobalInt("metrics-port") - me, err := service.CreateMetricsEndpoint() - if err != nil { - logrus.Fatalf("Failed to create metrics endpoint: %v", err) - } - l, err := net.Listen("tcp", fmt.Sprintf(":%v", metricsPort)) - if err != nil { - logrus.Fatalf("Failed to create listener for metrics: %v", err) - } - go func() { - if err := http.Serve(l, me); err != nil { - logrus.Fatalf("Failed to serve metrics endpoint: %v", err) - } - }() - } - - runtime.RegisterRuntimeServiceServer(s, service) - runtime.RegisterImageServiceServer(s, service) - - // after the daemon is done setting up we can notify systemd api - notifySystem() - - go func() { - service.StartExitMonitor() - }() - - m := cmux.New(lis) - grpcL := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc")) - httpL := m.Match(cmux.HTTP1Fast()) - - infoMux := service.GetInfoMux() - srv := &http.Server{ - Handler: infoMux, - ReadTimeout: 5 * time.Second, - } - - graceful := false - catchShutdown(s, service, srv, &graceful) - - go s.Serve(grpcL) - go srv.Serve(httpL) - - serverCloseCh := make(chan struct{}) - go func() { - defer close(serverCloseCh) - if err := m.Serve(); err != nil { - if graceful && strings.Contains(strings.ToLower(err.Error()), "use of closed network connection") { - err = nil - } else { - logrus.Errorf("Failed to serve grpc grpc request: %v", err) - } - } - }() - - // TODO(runcom): enable this after https://github.com/kubernetes/kubernetes/pull/51377 - //streamServerCloseCh := service.StreamingServerCloseChan() - serverExitMonitorCh := service.ExitMonitorCloseChan() - select { - // TODO(runcom): enable this after https://github.com/kubernetes/kubernetes/pull/51377 - //case <-streamServerCloseCh: - case <-serverExitMonitorCh: - case <-serverCloseCh: - } - - service.Shutdown() - - // TODO(runcom): enable this after https://github.com/kubernetes/kubernetes/pull/51377 - //<-streamServerCloseCh - //logrus.Debug("closed stream server") - <-serverExitMonitorCh - logrus.Debug("closed exit monitor") - <-serverCloseCh - logrus.Debug("closed main server") - - return nil - } - - if err := app.Run(os.Args); err != nil { - logrus.Fatal(err) - } -} diff --git a/cmd/crioctl/container.go b/cmd/crioctl/container.go deleted file mode 100644 index e420e6c99..000000000 --- a/cmd/crioctl/container.go +++ /dev/null @@ -1,653 +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" - remocommandconsts "k8s.io/apimachinery/pkg/util/remotecommand" - 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) - } - 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.NewExecutor(&restclient.Config{}, "GET", execURL) - if err != nil { - return err - } - - options := remotecommand.StreamOptions{ - SupportedProtocols: remocommandconsts.SupportedStreamingProtocols, - 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 - }, -} diff --git a/cmd/crioctl/image.go b/cmd/crioctl/image.go deleted file mode 100644 index 426c67e9d..000000000 --- a/cmd/crioctl/image.go +++ /dev/null @@ -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}}) -} diff --git a/cmd/crioctl/info.go b/cmd/crioctl/info.go deleted file mode 100644 index 1f06f594a..000000000 --- a/cmd/crioctl/info.go +++ /dev/null @@ -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 - }, -} diff --git a/cmd/crioctl/main.go b/cmd/crioctl/main.go deleted file mode 100644 index 3d77867fe..000000000 --- a/cmd/crioctl/main.go +++ /dev/null @@ -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.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) - } -} diff --git a/cmd/crioctl/sandbox.go b/cmd/crioctl/sandbox.go deleted file mode 100644 index e44183be3..000000000 --- a/cmd/crioctl/sandbox.go +++ /dev/null @@ -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 -} diff --git a/cmd/crioctl/system.go b/cmd/crioctl/system.go deleted file mode 100644 index 7e04161c2..000000000 --- a/cmd/crioctl/system.go +++ /dev/null @@ -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 -} |