Temporary cri-containerd change

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2018-03-12 08:27:03 +00:00
parent 25c403415a
commit ba93435337
20 changed files with 267 additions and 504 deletions

View File

@ -43,7 +43,7 @@ github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010a github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010a
github.com/google/go-cmp v0.1.0 github.com/google/go-cmp v0.1.0
# cri dependencies # cri dependencies
github.com/containerd/cri-containerd c9081b2ec0eefc799f0f1caabbea29d516c72c44 github.com/containerd/cri-containerd dcc278739fb31c5369f927c69716275c084c3d53 https://github.com/Random-Liu/cri-containerd.git
github.com/blang/semver v3.1.0 github.com/blang/semver v3.1.0
github.com/containernetworking/cni v0.6.0 github.com/containernetworking/cni v0.6.0
github.com/containernetworking/plugins v0.6.0 github.com/containernetworking/plugins v0.6.0

View File

@ -24,7 +24,8 @@ See [test dashboard](https://k8s-testgrid.appspot.com/sig-node-containerd)
| CRI-Containerd Version | Kubernetes Version | | CRI-Containerd Version | Kubernetes Version |
|:----------------------:|:------------------:| |:----------------------:|:------------------:|
| v1.0.0-alpha.x | 1.7, 1.8 | | v1.0.0-alpha.x | 1.7, 1.8 |
| v1.0.0-beta.x | 1.9+ | | v1.0.0-beta.x | 1.9 |
| HEAD | 1.10+ |
## Production Quality Cluster on GCE ## Production Quality Cluster on GCE
For a production quality cluster on GCE brought up with `kube-up.sh` refer [here](docs/kube-up.md). For a production quality cluster on GCE brought up with `kube-up.sh` refer [here](docs/kube-up.md).
## Installing with Ansible and Kubeadm ## Installing with Ansible and Kubeadm
@ -58,7 +59,7 @@ backport version of `libseccomp-dev` is required. See [travis.yml](.travis.yml)
2. Install other dependencies: 2. Install other dependencies:
* **`nsenter`**: Required by CNI and portforward. * **`nsenter`**: Required by CNI and portforward.
* **`socat`**: Required by portforward. * **`socat`**: Required by portforward.
3. Install and setup a go 1.9.x development environment. 3. Install and setup a go 1.10 development environment.
4. Make a local clone of this repository. 4. Make a local clone of this repository.
5. Install binary dependencies by running the following command from your cloned `cri-containerd/` project directory: 5. Install binary dependencies by running the following command from your cloned `cri-containerd/` project directory:
```bash ```bash

View File

@ -1,269 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package options
import (
"fmt"
"os"
"github.com/BurntSushi/toml"
"github.com/containerd/containerd"
"github.com/spf13/pflag"
)
const (
// configFilePathArgName is the path to the config file.
configFilePathArgName = "config"
// defaultConfigFilePath is the default config file path.
defaultConfigFilePath = "/etc/cri-containerd/config.toml"
)
// ContainerdConfig contains toml config related to containerd
type ContainerdConfig struct {
// RootDir is the root directory path for containerd.
// TODO(random-liu): Remove this field when no longer support cri-containerd standalone mode.
RootDir string `toml:"root_dir" json:"rootDir,omitempty"`
// Snapshotter is the snapshotter used by containerd.
Snapshotter string `toml:"snapshotter" json:"snapshotter,omitempty"`
// Endpoint is the containerd endpoint path.
// TODO(random-liu): Remove this field when no longer support cri-containerd standalone mode.
Endpoint string `toml:"endpoint" json:"endpoint,omitempty"`
// Runtime is the runtime to use in containerd. We may support
// other runtimes in the future.
Runtime string `toml:"runtime" json:"runtime,omitempty"`
// RuntimeEngine is the name of the runtime engine used by containerd.
// Containerd default should be "runc"
// We may support other runtime engines in the future.
RuntimeEngine string `toml:"runtime_engine" json:"runtimeEngine,omitempty"`
// RuntimeRoot is the directory used by containerd for runtime state.
// Containerd default should be "/run/containerd/runc"
RuntimeRoot string `toml:"runtime_root" json:"runtimeRoot,omitempty"`
}
// CniConfig contains toml config related to cni
type CniConfig struct {
// NetworkPluginBinDir is the directory in which the binaries for the plugin is kept.
NetworkPluginBinDir string `toml:"bin_dir" json:"binDir,omitempty"`
// NetworkPluginConfDir is the directory in which the admin places a CNI conf.
NetworkPluginConfDir string `toml:"conf_dir" json:"confDir,omitempty"`
}
// PluginConfig contains toml config related to CRI plugin,
// it is a subset of Config.
type PluginConfig struct {
// ContainerdConfig contains config related to containerd
ContainerdConfig `toml:"containerd" json:"containerd,omitempty"`
// CniConfig contains config related to cni
CniConfig `toml:"cni" json:"cni,omitempty"`
// Registry contains config related to the registry
Registry `toml:"registry" json:"registry,omitempty"`
// StreamServerAddress is the ip address streaming server is listening on.
StreamServerAddress string `toml:"stream_server_address" json:"streamServerAddress,omitempty"`
// StreamServerPort is the port streaming server is listening on.
StreamServerPort string `toml:"stream_server_port" json:"streamServerPort,omitempty"`
// EnableSelinux indicates to enable the selinux support.
EnableSelinux bool `toml:"enable_selinux" json:"enableSelinux,omitempty"`
// SandboxImage is the image used by sandbox container.
SandboxImage string `toml:"sandbox_image" json:"sandboxImage,omitempty"`
// StatsCollectPeriod is the period (in seconds) of snapshots stats collection.
StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod,omitempty"`
// SystemdCgroup enables systemd cgroup support.
SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup,omitempty"`
// EnableIPv6DAD enables IPv6 DAD.
// TODO(random-liu): Use optimistic_dad when it's GA.
EnableIPv6DAD bool `toml:"enable_ipv6_dad" json:"enableIPv6DAD,omitempty"`
}
// Config contains toml config related cri-containerd daemon.
// TODO(random-liu): Make this an internal config object when we no longer support cri-containerd
// standalone mode. At that time, we can clean this up.
type Config struct {
// PluginConfig is the config for CRI plugin.
PluginConfig
// ContainerdRootDir is the root directory path for containerd.
ContainerdRootDir string `toml:"-" json:"containerdRootDir,omitempty"`
// ContainerdEndpoint is the containerd endpoint path.
ContainerdEndpoint string `toml:"-" json:"containerdEndpoint,omitempty"`
// SocketPath is the path to the socket which cri-containerd serves on.
// TODO(random-liu): Remove SocketPath when no longer support cri-containerd
// standalone mode.
SocketPath string `toml:"socket_path" json:"socketPath,omitempty"`
// RootDir is the root directory path for managing cri-containerd files
// (metadata checkpoint etc.)
RootDir string `toml:"root_dir" json:"rootDir,omitempty"`
// TODO(random-liu): Remove following fields when we no longer support cri-containerd
// standalone mode.
// CgroupPath is the path for the cgroup that cri-containerd is placed in.
CgroupPath string `toml:"cgroup_path" json:"cgroupPath,omitempty"`
// OOMScore adjust the cri-containerd's oom score
OOMScore int `toml:"oom_score" json:"oomScore,omitempty"`
// EnableProfiling is used for enable profiling via host:port/debug/pprof/
EnableProfiling bool `toml:"profiling" json:"enableProfiling,omitempty"`
// ProfilingPort is the port for profiling via host:port/debug/pprof/
ProfilingPort string `toml:"profiling_port" json:"profilingPort,omitempty"`
// ProfilingAddress is address for profiling via host:port/debug/pprof/
ProfilingAddress string `toml:"profiling_addr" json:"profilingAddress,omitempty"`
// LogLevel is the logrus log level.
LogLevel string `toml:"log_level" json:"logLevel,omitempty"`
}
// CRIContainerdOptions contains cri-containerd command line and toml options.
type CRIContainerdOptions struct {
// Config contains cri-containerd toml config
Config
// ConfigFilePath is the path to the TOML config file.
ConfigFilePath string `toml:"-"`
}
// NewCRIContainerdOptions returns a reference to CRIContainerdOptions
func NewCRIContainerdOptions() *CRIContainerdOptions {
return &CRIContainerdOptions{}
}
// AddFlags adds cri-containerd command line options to pflag.
func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) {
defaults := DefaultConfig()
fs.StringVar(&c.ConfigFilePath, configFilePathArgName,
defaultConfigFilePath, "Path to the config file.")
fs.StringVar(&c.LogLevel, "log-level",
defaults.LogLevel, "Set the logging level [trace, debug, info, warn, error, fatal, panic].")
fs.StringVar(&c.SocketPath, "socket-path",
defaults.SocketPath, "Path to the socket which cri-containerd serves on.")
fs.StringVar(&c.RootDir, "root-dir",
defaults.RootDir, "Root directory path for cri-containerd managed files (metadata checkpoint etc).")
fs.StringVar(&c.ContainerdRootDir, "containerd-root-dir",
defaults.ContainerdRootDir, "Root directory path where containerd stores persistent data.")
fs.StringVar(&c.ContainerdEndpoint, "containerd-endpoint",
defaults.ContainerdEndpoint, "Path to the containerd endpoint.")
fs.StringVar(&c.ContainerdConfig.Snapshotter, "containerd-snapshotter",
defaults.ContainerdConfig.Snapshotter, "The snapshotter used by containerd.")
fs.StringVar(&c.ContainerdConfig.Runtime, "containerd-runtime",
defaults.ContainerdConfig.Runtime, "The runtime used by containerd.")
fs.StringVar(&c.ContainerdConfig.RuntimeEngine, "containerd-runtime-engine",
defaults.ContainerdConfig.RuntimeEngine, "Runtime engine used by containerd. Defaults to containerd's default if not specified.")
fs.StringVar(&c.ContainerdConfig.RuntimeRoot, "containerd-runtime-root",
defaults.ContainerdConfig.RuntimeRoot, "The directory used by containerd for runtime state. Defaults to containerd's default if not specified.")
fs.StringVar(&c.NetworkPluginBinDir, "network-bin-dir",
defaults.NetworkPluginBinDir, "The directory for putting network binaries.")
fs.StringVar(&c.NetworkPluginConfDir, "network-conf-dir",
defaults.NetworkPluginConfDir, "The directory for putting network plugin configuration files.")
fs.StringVar(&c.StreamServerAddress, "stream-addr",
defaults.StreamServerAddress, "The ip address streaming server is listening on. The default host interface is used if not specified.")
fs.StringVar(&c.StreamServerPort, "stream-port",
defaults.StreamServerPort, "The port streaming server is listening on.")
fs.StringVar(&c.CgroupPath, "cgroup-path",
defaults.CgroupPath, "The cgroup that cri-containerd is part of. Cri-containerd is not placed in a cgroup if none is specified.")
fs.BoolVar(&c.EnableSelinux, "enable-selinux",
defaults.EnableSelinux, "Enable selinux support. By default not enabled.")
fs.StringVar(&c.SandboxImage, "sandbox-image",
defaults.SandboxImage, "The image used by sandbox container.")
fs.IntVar(&c.StatsCollectPeriod, "stats-collect-period",
defaults.StatsCollectPeriod, "The period (in seconds) of snapshots stats collection.")
fs.BoolVar(&c.SystemdCgroup, "systemd-cgroup",
defaults.SystemdCgroup, "Enables systemd cgroup support. By default not enabled.")
fs.IntVar(&c.OOMScore, "oom-score",
defaults.OOMScore, "Adjust the cri-containerd's oom score.")
fs.BoolVar(&c.EnableProfiling, "profiling",
defaults.EnableProfiling, "Enable profiling via web interface host:port/debug/pprof/.")
fs.StringVar(&c.ProfilingPort, "profiling-port",
defaults.ProfilingPort, "Profiling port for web interface host:port/debug/pprof/.")
fs.StringVar(&c.ProfilingAddress, "profiling-addr",
defaults.ProfilingAddress, "Profiling address for web interface host:port/debug/pprof/.")
fs.BoolVar(&c.EnableIPv6DAD, "enable-ipv6-dad",
defaults.EnableIPv6DAD, "Enable IPv6 DAD (duplicate address detection) for pod sandbox network. Enabling this will increase pod sandbox start latency by several seconds.")
fs.Var(&c.Registry, "registry",
"Registry config for image pull eg --registry=myregistry.io=https://mymirror.io/ --registry=myregistry2.io=https://mymirror2.io/")
}
// InitFlags load configurations from config file, and then overwrite with flags.
// This function must be called inside `Run`, at that time flags should have been
// parsed once.
// precedence: commandline > configfile > default
func (c *CRIContainerdOptions) InitFlags(fs *pflag.FlagSet) error {
// Load default config file if none provided
if _, err := toml.DecodeFile(c.ConfigFilePath, &c.Config); err != nil {
// the absence of default config file is normal case.
if !fs.Changed(configFilePathArgName) && os.IsNotExist(err) {
return nil
}
return err
}
// Add this for backward compatibility.
// TODO(random-liu): Remove this when we no longer support cri-containerd standalone mode.
c.ContainerdRootDir = c.ContainerdConfig.RootDir
c.ContainerdEndpoint = c.ContainerdConfig.Endpoint
// What is the reason for applying the command line twice?
// Because the values from command line have the highest priority.
// The path of toml configuration file if from the command line,
// and triggers the first parse.
// The first parse generates the default value and the value from command line at the same time.
// But the priority of the toml config value is higher than the default value,
// Without a way to insert the toml config value between the default value and the command line value.
// We parse twice one for default value, one for commandline value.
return fs.Parse(os.Args[1:])
}
// PrintDefaultTomlConfig print default toml config of cri-containerd.
func PrintDefaultTomlConfig() {
if err := toml.NewEncoder(os.Stdout).Encode(DefaultConfig()); err != nil {
fmt.Println(err)
return
}
}
// DefaultConfig returns default configurations of cri-containerd.
func DefaultConfig() Config {
return Config{
PluginConfig: PluginConfig{
CniConfig: CniConfig{
NetworkPluginBinDir: "/opt/cni/bin",
NetworkPluginConfDir: "/etc/cni/net.d",
},
ContainerdConfig: ContainerdConfig{
Snapshotter: containerd.DefaultSnapshotter,
Runtime: "io.containerd.runtime.v1.linux",
RuntimeEngine: "",
RuntimeRoot: "",
},
StreamServerAddress: "",
StreamServerPort: "10010",
EnableSelinux: false,
SandboxImage: "gcr.io/google_containers/pause:3.0",
StatsCollectPeriod: 10,
SystemdCgroup: false,
EnableIPv6DAD: false,
Registry: Registry{
Mirrors: map[string]Mirror{
"docker.io": {
Endpoints: []string{"https://registry-1.docker.io"},
},
},
},
},
ContainerdRootDir: "/var/lib/containerd",
ContainerdEndpoint: "/run/containerd/containerd.sock",
SocketPath: "/var/run/cri-containerd.sock",
RootDir: "/var/lib/cri-containerd",
CgroupPath: "",
OOMScore: -999,
EnableProfiling: true,
ProfilingPort: "10011",
ProfilingAddress: "127.0.0.1",
LogLevel: "info",
}
}

View File

@ -1,88 +0,0 @@
/*
Copyright 2018 The Containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package options
import (
"fmt"
"net/url"
"strings"
)
// Mirror contains the config related to the registry mirror
type Mirror struct {
Endpoints []string `toml:"endpoint" json:"endpoint,omitempty"`
// TODO (Abhi) We might need to add auth per namespace. Looks like
// image auth information is passed by kube itself.
}
// Registry is registry settings configured
type Registry struct {
Mirrors map[string]Mirror `toml:"mirrors" json:"mirrors,omitempty"`
}
// String returns the string format of registry type
func (r *Registry) String() string {
// Its not used hence return empty string
return ""
}
// Set validates and converts into the internal registry struct
func (r *Registry) Set(s string) error {
// --registry docker.io=https://mymirror.io,http://mymirror2.io
// If no option is set then return format error
if len(s) == 0 {
return fmt.Errorf("incomplete registry mirror option")
}
var mirrors []string
host := "docker.io"
opt := strings.Split(s, "=")
if len(opt) > 1 {
// If option is set in the format "mynamespace.io=https://mymirror.io,https://mymirror2.io"
// Then associate the mirror urls for the namespace only"
host = opt[0]
mirrors = strings.Split(opt[1], ",")
} else {
// If option is set in the format "https://mymirror.io,https://mymirror.io"
// Then associate mirror against default docker.io namespace
mirrors = strings.Split(opt[0], ",")
}
// Validate the format of the urls passed
for _, u := range mirrors {
_, err := url.Parse(u)
if err != nil {
return fmt.Errorf("invalid registry mirror url format %v: %v", u, err)
}
}
if r.Mirrors == nil {
r.Mirrors = make(map[string]Mirror)
}
if _, ok := r.Mirrors[host]; !ok {
r.Mirrors[host] = Mirror{}
}
m := r.Mirrors[host]
m.Endpoints = append(m.Endpoints, mirrors...)
r.Mirrors[host] = m
return nil
}
// Type returns a string name for the option type
func (r *Registry) Type() string {
return "list"
}

View File

@ -17,20 +17,27 @@ limitations under the License.
package cri package cri
import ( import (
"flag"
"path/filepath" "path/filepath"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/containerd/cri-containerd/cmd/cri-containerd/options" criconfig "github.com/containerd/cri-containerd/pkg/config"
"github.com/containerd/cri-containerd/pkg/server" "github.com/containerd/cri-containerd/pkg/server"
) )
// criVersion is the CRI version supported by the CRI plugin.
const criVersion = "v1alpha2"
// TODO(random-liu): Use github.com/pkg/errors for our errors. // TODO(random-liu): Use github.com/pkg/errors for our errors.
// Register CRI service plugin // Register CRI service plugin
func init() { func init() {
config := options.DefaultConfig().PluginConfig config := criconfig.DefaultConfig()
plugin.Register(&plugin.Registration{ plugin.Register(&plugin.Registration{
Type: plugin.GRPCPlugin, Type: plugin.GRPCPlugin,
ID: "cri", ID: "cri",
@ -49,9 +56,11 @@ func init() {
} }
func initCRIService(ic *plugin.InitContext) (interface{}, error) { func initCRIService(ic *plugin.InitContext) (interface{}, error) {
ic.Meta.Platforms = []imagespec.Platform{platforms.DefaultSpec()}
ic.Meta.Exports = map[string]string{"CRIVersion": criVersion}
ctx := ic.Context ctx := ic.Context
pluginConfig := ic.Config.(*options.PluginConfig) pluginConfig := ic.Config.(*criconfig.PluginConfig)
c := options.Config{ c := criconfig.Config{
PluginConfig: *pluginConfig, PluginConfig: *pluginConfig,
// This is a hack. We assume that containerd root directory // This is a hack. We assume that containerd root directory
// is one level above plugin directory. // is one level above plugin directory.
@ -62,6 +71,10 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
} }
log.G(ctx).Infof("Start cri plugin with config %+v", c) log.G(ctx).Infof("Start cri plugin with config %+v", c)
if err := setGLogLevel(); err != nil {
return nil, errors.Wrap(err, "failed to set glog level")
}
s, err := server.NewCRIContainerdService(c) s, err := server.NewCRIContainerdService(c)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to create CRI service") return nil, errors.Wrap(err, "failed to create CRI service")
@ -70,10 +83,32 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
// Use a goroutine to initialize cri service. The reason is that currently // Use a goroutine to initialize cri service. The reason is that currently
// cri service requires containerd to be initialize. // cri service requires containerd to be initialize.
go func() { go func() {
if err := s.Run(false); err != nil { if err := s.Run(); err != nil {
log.G(ctx).WithError(err).Fatal("Failed to run CRI service") log.G(ctx).WithError(err).Fatal("Failed to run CRI service")
} }
// TODO(random-liu): Whether and how we can stop containerd. // TODO(random-liu): Whether and how we can stop containerd.
}() }()
return s, nil return s, nil
} }
// Set glog level.
func setGLogLevel() error {
l := logrus.GetLevel()
if err := flag.Set("logtostderr", "true"); err != nil {
return err
}
switch l {
case log.TraceLevel:
return flag.Set("v", "5")
case logrus.DebugLevel:
return flag.Set("v", "4")
case logrus.InfoLevel:
return flag.Set("v", "2")
// glog doesn't support following filters. Defaults to v=0.
case logrus.WarnLevel:
case logrus.ErrorLevel:
case logrus.FatalLevel:
case logrus.PanicLevel:
}
return nil
}

View File

@ -0,0 +1,127 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package config
import "github.com/containerd/containerd"
// ContainerdConfig contains toml config related to containerd
type ContainerdConfig struct {
// Snapshotter is the snapshotter used by containerd.
Snapshotter string `toml:"snapshotter" json:"snapshotter,omitempty"`
// Runtime is the runtime to use in containerd. We may support
// other runtimes in the future.
Runtime string `toml:"runtime" json:"runtime,omitempty"`
// RuntimeEngine is the name of the runtime engine used by containerd.
// Containerd default should be "runc"
// We may support other runtime engines in the future.
RuntimeEngine string `toml:"runtime_engine" json:"runtimeEngine,omitempty"`
// RuntimeRoot is the directory used by containerd for runtime state.
// Containerd default should be "/run/containerd/runc"
RuntimeRoot string `toml:"runtime_root" json:"runtimeRoot,omitempty"`
}
// CniConfig contains toml config related to cni
type CniConfig struct {
// NetworkPluginBinDir is the directory in which the binaries for the plugin is kept.
NetworkPluginBinDir string `toml:"bin_dir" json:"binDir,omitempty"`
// NetworkPluginConfDir is the directory in which the admin places a CNI conf.
NetworkPluginConfDir string `toml:"conf_dir" json:"confDir,omitempty"`
}
// Mirror contains the config related to the registry mirror
type Mirror struct {
// Endpoints are endpoints for a namespace. CRI plugin will try the endpoints
// one by one until a working one is found.
Endpoints []string `toml:"endpoint" json:"endpoint,omitempty"`
// TODO (Abhi) We might need to add auth per namespace. Looks like
// image auth information is passed by kube itself.
}
// Registry is registry settings configured
type Registry struct {
// Mirrors are namespace to mirror mapping for all namespaces.
Mirrors map[string]Mirror `toml:"mirrors" json:"mirrors,omitempty"`
}
// PluginConfig contains toml config related to CRI plugin,
// it is a subset of Config.
type PluginConfig struct {
// ContainerdConfig contains config related to containerd
ContainerdConfig `toml:"containerd" json:"containerd,omitempty"`
// CniConfig contains config related to cni
CniConfig `toml:"cni" json:"cni,omitempty"`
// Registry contains config related to the registry
Registry `toml:"registry" json:"registry,omitempty"`
// StreamServerAddress is the ip address streaming server is listening on.
StreamServerAddress string `toml:"stream_server_address" json:"streamServerAddress,omitempty"`
// StreamServerPort is the port streaming server is listening on.
StreamServerPort string `toml:"stream_server_port" json:"streamServerPort,omitempty"`
// EnableSelinux indicates to enable the selinux support.
EnableSelinux bool `toml:"enable_selinux" json:"enableSelinux,omitempty"`
// SandboxImage is the image used by sandbox container.
SandboxImage string `toml:"sandbox_image" json:"sandboxImage,omitempty"`
// StatsCollectPeriod is the period (in seconds) of snapshots stats collection.
StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod,omitempty"`
// SystemdCgroup enables systemd cgroup support.
SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup,omitempty"`
// EnableIPv6DAD enables IPv6 DAD.
// TODO(random-liu): Use optimistic_dad when it's GA.
EnableIPv6DAD bool `toml:"enable_ipv6_dad" json:"enableIPv6DAD,omitempty"`
}
// Config contains all configurations for cri server.
type Config struct {
// PluginConfig is the config for CRI plugin.
PluginConfig
// ContainerdRootDir is the root directory path for containerd.
ContainerdRootDir string `json:"containerdRootDir,omitempty"`
// ContainerdEndpoint is the containerd endpoint path.
ContainerdEndpoint string `json:"containerdEndpoint,omitempty"`
// RootDir is the root directory path for managing cri-containerd files
// (metadata checkpoint etc.)
RootDir string `json:"rootDir,omitempty"`
}
// DefaultConfig returns default configurations of cri plugin.
func DefaultConfig() PluginConfig {
return PluginConfig{
CniConfig: CniConfig{
NetworkPluginBinDir: "/opt/cni/bin",
NetworkPluginConfDir: "/etc/cni/net.d",
},
ContainerdConfig: ContainerdConfig{
Snapshotter: containerd.DefaultSnapshotter,
Runtime: "io.containerd.runtime.v1.linux",
RuntimeEngine: "",
RuntimeRoot: "",
},
StreamServerAddress: "",
StreamServerPort: "10010",
EnableSelinux: false,
SandboxImage: "gcr.io/google_containers/pause:3.0",
StatsCollectPeriod: 10,
SystemdCgroup: false,
EnableIPv6DAD: false,
Registry: Registry{
Mirrors: map[string]Mirror{
"docker.io": {
Endpoints: []string{"https://registry-1.docker.io"},
},
},
},
}
}

View File

@ -36,6 +36,7 @@ import (
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
ctrdutil "github.com/containerd/cri-containerd/pkg/containerd/util"
"github.com/containerd/cri-containerd/pkg/util" "github.com/containerd/cri-containerd/pkg/util"
) )
@ -80,6 +81,7 @@ func Import(ctx context.Context, client *containerd.Client, reader io.Reader) (_
if err != nil { if err != nil {
return nil, err return nil, err
} }
// TODO(random-liu): Fix this after containerd client is fixed (containerd/containerd#2193)
defer done() // nolint: errcheck defer done() // nolint: errcheck
cs := client.ContentStore() cs := client.ContentStore()
@ -134,9 +136,13 @@ func Import(ctx context.Context, client *containerd.Client, reader io.Reader) (_
// TODO(random-liu): Consider whether we should keep images already imported // TODO(random-liu): Consider whether we should keep images already imported
// even when there is an error. // even when there is an error.
for _, ref := range refs { for _, ref := range refs {
if err := is.Delete(ctx, ref); err != nil { func() {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if err := is.Delete(deferCtx, ref); err != nil {
log.G(ctx).WithError(err).Errorf("Failed to remove image %q", ref) log.G(ctx).WithError(err).Errorf("Failed to remove image %q", ref)
} }
}()
} }
}() }()
for _, mfst := range mfsts { for _, mfst := range mfsts {

View File

@ -501,7 +501,7 @@ func (r *dockerBase) fetchTokenWithOAuth(ctx context.Context, to tokenOptions) (
// Registries without support for POST may return 404 for POST /v2/token. // Registries without support for POST may return 404 for POST /v2/token.
// As of September 2017, GCR is known to return 404. // As of September 2017, GCR is known to return 404.
if (resp.StatusCode == 405 && r.username != "") || resp.StatusCode == 404 { if (resp.StatusCode == 405 && r.username != "") || resp.StatusCode == 404 || resp.StatusCode == 401 {
return r.getToken(ctx, to) return r.getToken(ctx, to)
} else if resp.StatusCode < 200 || resp.StatusCode >= 400 { } else if resp.StatusCode < 200 || resp.StatusCode >= 400 {
b, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB b, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB

View File

@ -0,0 +1,35 @@
/*
Copyright 2018 The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
"time"
"golang.org/x/net/context"
)
// deferCleanupTimeout is the default timeout for containerd cleanup operations
// in defer.
const deferCleanupTimeout = 1 * time.Minute
// DeferContext returns a context for containerd cleanup operations in defer.
// A default timeout is applied to avoid cleanup operation pending forever.
// TODO(random-liu): Add namespace after local services are used.
// (containerd/containerd#2183)
func DeferContext() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), deferCleanupTimeout)
}

View File

@ -47,6 +47,7 @@ import (
"github.com/containerd/cri-containerd/pkg/annotations" "github.com/containerd/cri-containerd/pkg/annotations"
customopts "github.com/containerd/cri-containerd/pkg/containerd/opts" customopts "github.com/containerd/cri-containerd/pkg/containerd/opts"
ctrdutil "github.com/containerd/cri-containerd/pkg/containerd/util"
cio "github.com/containerd/cri-containerd/pkg/server/io" cio "github.com/containerd/cri-containerd/pkg/server/io"
containerstore "github.com/containerd/cri-containerd/pkg/store/container" containerstore "github.com/containerd/cri-containerd/pkg/store/container"
"github.com/containerd/cri-containerd/pkg/util" "github.com/containerd/cri-containerd/pkg/util"
@ -240,7 +241,9 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
if err := cntr.Delete(ctx, containerd.WithSnapshotCleanup); err != nil { deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if err := cntr.Delete(deferCtx, containerd.WithSnapshotCleanup); err != nil {
logrus.WithError(err).Errorf("Failed to delete containerd container %q", id) logrus.WithError(err).Errorf("Failed to delete containerd container %q", id)
} }
} }

View File

@ -31,6 +31,7 @@ import (
"k8s.io/client-go/tools/remotecommand" "k8s.io/client-go/tools/remotecommand"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri-containerd/pkg/containerd/util"
cioutil "github.com/containerd/cri-containerd/pkg/ioutil" cioutil "github.com/containerd/cri-containerd/pkg/ioutil"
cio "github.com/containerd/cri-containerd/pkg/server/io" cio "github.com/containerd/cri-containerd/pkg/server/io"
"github.com/containerd/cri-containerd/pkg/util" "github.com/containerd/cri-containerd/pkg/util"
@ -128,7 +129,9 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
return nil, fmt.Errorf("failed to create exec %q: %v", execID, err) return nil, fmt.Errorf("failed to create exec %q: %v", execID, err)
} }
defer func() { defer func() {
if _, err := process.Delete(ctx); err != nil { deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if _, err := process.Delete(deferCtx); err != nil {
logrus.WithError(err).Errorf("Failed to delete exec process %q for container %q", execID, id) logrus.WithError(err).Errorf("Failed to delete exec process %q for container %q", execID, id)
} }
}() }()

View File

@ -28,6 +28,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri-containerd/pkg/containerd/util"
cio "github.com/containerd/cri-containerd/pkg/server/io" cio "github.com/containerd/cri-containerd/pkg/server/io"
containerstore "github.com/containerd/cri-containerd/pkg/store/container" containerstore "github.com/containerd/cri-containerd/pkg/store/container"
sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox" sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox"
@ -121,8 +122,10 @@ func (c *criContainerdService) startContainer(ctx context.Context,
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
// It's possible that task is deleted by event monitor. // It's possible that task is deleted by event monitor.
if _, err := task.Delete(ctx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) { if _, err := task.Delete(deferCtx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) {
logrus.WithError(err).Errorf("Failed to delete containerd task %q", id) logrus.WithError(err).Errorf("Failed to delete containerd task %q", id)
} }
} }

View File

@ -29,6 +29,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
ctrdutil "github.com/containerd/cri-containerd/pkg/containerd/util"
containerstore "github.com/containerd/cri-containerd/pkg/store/container" containerstore "github.com/containerd/cri-containerd/pkg/store/container"
"github.com/containerd/cri-containerd/pkg/util" "github.com/containerd/cri-containerd/pkg/util"
) )
@ -78,8 +79,10 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
// Reset spec on error. // Reset spec on error.
if err := updateContainerSpec(ctx, cntr.Container, oldSpec); err != nil { if err := updateContainerSpec(deferCtx, cntr.Container, oldSpec); err != nil {
logrus.WithError(err).Errorf("Failed to update spec %+v for container %q", oldSpec, id) logrus.WithError(err).Errorf("Failed to update spec %+v for container %q", oldSpec, id)
} }
} }

View File

@ -21,9 +21,9 @@ import (
"github.com/containerd/containerd" "github.com/containerd/containerd"
eventtypes "github.com/containerd/containerd/api/events" eventtypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/api/services/events/v1"
containerdio "github.com/containerd/containerd/cio" containerdio "github.com/containerd/containerd/cio"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -137,6 +137,7 @@ func (em *eventMonitor) handleEvent(evt *events.Envelope) {
return return
} }
logrus.WithError(err).Errorf("Failed to get container %q", e.ContainerID) logrus.WithError(err).Errorf("Failed to get container %q", e.ContainerID)
return
} }
err = cntr.Status.UpdateSync(func(status containerstore.Status) (containerstore.Status, error) { err = cntr.Status.UpdateSync(func(status containerstore.Status) (containerstore.Status, error) {
status.Reason = oomExitReason status.Reason = oomExitReason

View File

@ -37,6 +37,7 @@ import (
"github.com/containerd/cri-containerd/pkg/annotations" "github.com/containerd/cri-containerd/pkg/annotations"
customopts "github.com/containerd/cri-containerd/pkg/containerd/opts" customopts "github.com/containerd/cri-containerd/pkg/containerd/opts"
ctrdutil "github.com/containerd/cri-containerd/pkg/containerd/util"
"github.com/containerd/cri-containerd/pkg/log" "github.com/containerd/cri-containerd/pkg/log"
sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox" sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox"
"github.com/containerd/cri-containerd/pkg/util" "github.com/containerd/cri-containerd/pkg/util"
@ -193,7 +194,9 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
if err := container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil { deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
if err := container.Delete(deferCtx, containerd.WithSnapshotCleanup); err != nil {
logrus.WithError(err).Errorf("Failed to delete containerd container %q", id) logrus.WithError(err).Errorf("Failed to delete containerd container %q", id)
} }
} }
@ -288,9 +291,11 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
deferCtx, deferCancel := ctrdutil.DeferContext()
defer deferCancel()
// Cleanup the sandbox container if an error is returned. // Cleanup the sandbox container if an error is returned.
// It's possible that task is deleted by event monitor. // It's possible that task is deleted by event monitor.
if _, err := task.Delete(ctx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) { if _, err := task.Delete(deferCtx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) {
logrus.WithError(err).Errorf("Failed to delete sandbox container %q", id) logrus.WithError(err).Errorf("Failed to delete sandbox container %q", id)
} }
} }

View File

@ -19,10 +19,7 @@ package server
import ( import (
"fmt" "fmt"
"io" "io"
"net"
"os"
"path/filepath" "path/filepath"
"syscall"
"time" "time"
"github.com/containerd/containerd" "github.com/containerd/containerd"
@ -37,9 +34,9 @@ import (
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/server/streaming" "k8s.io/kubernetes/pkg/kubelet/server/streaming"
"github.com/containerd/cri-containerd/cmd/cri-containerd/options"
api "github.com/containerd/cri-containerd/pkg/api/v1" api "github.com/containerd/cri-containerd/pkg/api/v1"
"github.com/containerd/cri-containerd/pkg/atomic" "github.com/containerd/cri-containerd/pkg/atomic"
criconfig "github.com/containerd/cri-containerd/pkg/config"
osinterface "github.com/containerd/cri-containerd/pkg/os" osinterface "github.com/containerd/cri-containerd/pkg/os"
"github.com/containerd/cri-containerd/pkg/registrar" "github.com/containerd/cri-containerd/pkg/registrar"
containerstore "github.com/containerd/cri-containerd/pkg/store/container" containerstore "github.com/containerd/cri-containerd/pkg/store/container"
@ -48,12 +45,8 @@ import (
snapshotstore "github.com/containerd/cri-containerd/pkg/store/snapshot" snapshotstore "github.com/containerd/cri-containerd/pkg/store/snapshot"
) )
const ( // k8sContainerdNamespace is the namespace we use to connect containerd.
// k8sContainerdNamespace is the namespace we use to connect containerd. const k8sContainerdNamespace = "k8s.io"
k8sContainerdNamespace = "k8s.io"
// unixProtocol is the network protocol of unix socket.
unixProtocol = "unix"
)
// grpcServices are all the grpc services provided by cri containerd. // grpcServices are all the grpc services provided by cri containerd.
type grpcServices interface { type grpcServices interface {
@ -64,7 +57,7 @@ type grpcServices interface {
// CRIContainerdService is the interface implement CRI remote service server. // CRIContainerdService is the interface implement CRI remote service server.
type CRIContainerdService interface { type CRIContainerdService interface {
Run(bool) error Run() error
// io.Closer is used by containerd to gracefully stop cri service. // io.Closer is used by containerd to gracefully stop cri service.
io.Closer io.Closer
plugin.Service plugin.Service
@ -74,15 +67,13 @@ type CRIContainerdService interface {
// criContainerdService implements CRIContainerdService. // criContainerdService implements CRIContainerdService.
type criContainerdService struct { type criContainerdService struct {
// config contains all configurations. // config contains all configurations.
config options.Config config criconfig.Config
// imageFSPath is the path to image filesystem. // imageFSPath is the path to image filesystem.
imageFSPath string imageFSPath string
// apparmorEnabled indicates whether apparmor is enabled. // apparmorEnabled indicates whether apparmor is enabled.
apparmorEnabled bool apparmorEnabled bool
// seccompEnabled indicates whether seccomp is enabled. // seccompEnabled indicates whether seccomp is enabled.
seccompEnabled bool seccompEnabled bool
// server is the grpc server.
server *grpc.Server
// os is an interface for all required os operations. // os is an interface for all required os operations.
os osinterface.OS os osinterface.OS
// sandboxStore stores all resources associated with sandboxes. // sandboxStore stores all resources associated with sandboxes.
@ -113,7 +104,7 @@ type criContainerdService struct {
} }
// NewCRIContainerdService returns a new instance of CRIContainerdService // NewCRIContainerdService returns a new instance of CRIContainerdService
func NewCRIContainerdService(config options.Config) (CRIContainerdService, error) { func NewCRIContainerdService(config criconfig.Config) (CRIContainerdService, error) {
var err error var err error
c := &criContainerdService{ c := &criContainerdService{
config: config, config: config,
@ -153,12 +144,6 @@ func NewCRIContainerdService(config options.Config) (CRIContainerdService, error
c.eventMonitor = newEventMonitor(c.containerStore, c.sandboxStore) c.eventMonitor = newEventMonitor(c.containerStore, c.sandboxStore)
// To avoid race condition between `Run` and `Stop`, still create grpc server
// although we may not use it. It's just a small in-memory data structure.
// TODO(random-liu): Get rid of the grpc server when completely switch
// to plugin mode.
c.server = grpc.NewServer()
return c, nil return c, nil
} }
@ -172,11 +157,8 @@ func (c *criContainerdService) Register(s *grpc.Server) error {
return nil return nil
} }
// Run starts the cri-containerd service. startGRPC specifies // Run starts the cri-containerd service.
// whether to start grpc server in this function. func (c *criContainerdService) Run() error {
// TODO(random-liu): Remove `startRPC=true` case when we no longer support cri-containerd
// standalone mode.
func (c *criContainerdService) Run(startGRPC bool) error {
logrus.Info("Start cri-containerd service") logrus.Info("Start cri-containerd service")
// Connect containerd service here, to get rid of the containerd dependency // Connect containerd service here, to get rid of the containerd dependency
@ -226,35 +208,10 @@ func (c *criContainerdService) Run(startGRPC bool) error {
// Set the server as initialized. GRPC services could start serving traffic. // Set the server as initialized. GRPC services could start serving traffic.
c.initialized.Set() c.initialized.Set()
grpcServerCloseCh := make(chan struct{})
if startGRPC {
// Create the grpc server and register runtime and image services.
c.Register(c.server) // nolint: errcheck
// Start grpc server.
// Unlink to cleanup the previous socket file.
logrus.Info("Start grpc server")
err := syscall.Unlink(c.config.SocketPath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to unlink socket file %q: %v", c.config.SocketPath, err)
}
l, err := net.Listen(unixProtocol, c.config.SocketPath)
if err != nil {
return fmt.Errorf("failed to listen on %q: %v", c.config.SocketPath, err)
}
go func() {
if err := c.server.Serve(l); err != nil {
logrus.WithError(err).Error("Failed to serve grpc request")
}
close(grpcServerCloseCh)
}()
}
// Keep grpcServerCloseCh open if grpc server is not started.
// Stop the whole cri-containerd service if any of the critical service exits. // Stop the whole cri-containerd service if any of the critical service exits.
select { select {
case <-eventMonitorCloseCh: case <-eventMonitorCloseCh:
case <-streamServerCloseCh: case <-streamServerCloseCh:
case <-grpcServerCloseCh:
} }
if err := c.Close(); err != nil { if err := c.Close(); err != nil {
return fmt.Errorf("failed to stop cri service: %v", err) return fmt.Errorf("failed to stop cri service: %v", err)
@ -277,11 +234,6 @@ func (c *criContainerdService) Run(startGRPC bool) error {
case <-time.After(streamServerStopTimeout): case <-time.After(streamServerStopTimeout):
logrus.Errorf("Stream server is not stopped in %q", streamServerStopTimeout) logrus.Errorf("Stream server is not stopped in %q", streamServerStopTimeout)
} }
if startGRPC {
// Only wait for grpc server close channel when grpc server is started.
<-grpcServerCloseCh
logrus.Info("GRPC server stopped")
}
return nil return nil
} }
@ -293,7 +245,6 @@ func (c *criContainerdService) Close() error {
if err := c.streamServer.Stop(); err != nil { if err := c.streamServer.Stop(); err != nil {
return fmt.Errorf("failed to stop stream server: %v", err) return fmt.Errorf("failed to stop stream server: %v", err)
} }
c.server.Stop()
return nil return nil
} }

View File

@ -17,32 +17,30 @@ limitations under the License.
package server package server
import ( import (
"fmt"
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"github.com/containerd/cri-containerd/pkg/version"
) )
const ( const (
// For now, containerd and runc are bundled with cri-containerd, cri-containerd containerName = "containerd"
// version is more important to us.
// TODO(random-liu): Figure out how to package cri-containerd and containerd,
// and how to version it. We still prefer calling the container runtime "containerd",
// but we care both the cri-containerd version and containerd version.
containerName = "cri-containerd"
containerdAPIVersion = "0.0.0"
// kubeAPIVersion is the api version of kubernetes. // kubeAPIVersion is the api version of kubernetes.
// TODO(random-liu): Change this to actual CRI version.
kubeAPIVersion = "0.1.0" kubeAPIVersion = "0.1.0"
) )
// Version returns the runtime name, runtime version and runtime API version. // Version returns the runtime name, runtime version and runtime API version.
// TODO(random-liu): Return containerd version since we are going to merge 2 daemons.
func (c *criContainerdService) Version(ctx context.Context, r *runtime.VersionRequest) (*runtime.VersionResponse, error) { func (c *criContainerdService) Version(ctx context.Context, r *runtime.VersionRequest) (*runtime.VersionResponse, error) {
resp, err := c.client.Version(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get containerd version: %v", err)
}
return &runtime.VersionResponse{ return &runtime.VersionResponse{
Version: kubeAPIVersion, Version: kubeAPIVersion,
RuntimeName: containerName, RuntimeName: containerName,
RuntimeVersion: version.CRIContainerdVersion, RuntimeVersion: resp.Version,
// Containerd doesn't have an api version now. // Containerd doesn't have an api version use version instead.
RuntimeApiVersion: containerdAPIVersion, RuntimeApiVersion: resp.Version,
}, nil }, nil
} }

View File

@ -20,28 +20,20 @@ import "sync"
// StopCh is used to propagate the stop information of a container. // StopCh is used to propagate the stop information of a container.
type StopCh struct { type StopCh struct {
mu sync.Mutex
ch chan struct{} ch chan struct{}
closed bool once sync.Once
} }
// NewStopCh creates a stop channel. The channel is open by default. // NewStopCh creates a stop channel. The channel is open by default.
func NewStopCh() *StopCh { func NewStopCh() *StopCh {
return &StopCh{ return &StopCh{ch: make(chan struct{})}
ch: make(chan struct{}),
closed: false,
}
} }
// Stop close stopCh of the container. // Stop close stopCh of the container.
func (s *StopCh) Stop() { func (s *StopCh) Stop() {
s.mu.Lock() s.once.Do(func() {
defer s.mu.Unlock()
if s.closed {
return
}
close(s.ch) close(s.ch)
s.closed = true })
} }
// Stopped return the stopCh of the container as a readonly channel. // Stopped return the stopCh of the container as a readonly channel.

View File

@ -1,43 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package version
import (
"fmt"
"github.com/blang/semver"
)
// CRIContainerdVersion is the version of the cri-containerd.
var CRIContainerdVersion = "UNKNOWN"
func validateSemver(sv string) error {
_, err := semver.Parse(sv)
if err != nil {
return fmt.Errorf("couldn't parse cri-containerd version %q: %v", sv, err)
}
return nil
}
// PrintVersion outputs the release version of cri-containerd
func PrintVersion() {
err := validateSemver(CRIContainerdVersion)
if err != nil {
fmt.Println(err)
}
fmt.Println(CRIContainerdVersion)
}

View File

@ -4,7 +4,7 @@ github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
github.com/containerd/cgroups c0710c92e8b3a44681d1321dcfd1360fc5c6c089 github.com/containerd/cgroups c0710c92e8b3a44681d1321dcfd1360fc5c6c089
github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
github.com/containerd/containerd 129167132c5e0dbd1b031badae201a432d1bd681 github.com/containerd/containerd 25c403415aa99d0f3a609043429f3d24c8b70c0c
github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371 github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371
github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f