Update to cri v1.0.0-rc.0
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
88
vendor/github.com/containerd/cri/README.md
generated
vendored
88
vendor/github.com/containerd/cri/README.md
generated
vendored
@@ -1,31 +1,43 @@
|
||||
# cri-containerd
|
||||
# cri
|
||||
<p align="center">
|
||||
<img src="https://github.com/kubernetes/kubernetes/blob/master/logo/logo.png" width="50" height="50">
|
||||
<img src="https://github.com/containerd/containerd/blob/master/docs/images/containerd-dark.png" width="200" >
|
||||
</p>
|
||||
|
||||
[](https://travis-ci.org/containerd/cri-containerd)
|
||||
[](https://goreportcard.com/report/github.com/containerd/cri-containerd)
|
||||
*Note: The standalone `cri-containerd` binary is end-of-life. `cri-containerd` is
|
||||
transitioning from a standalone binary that talks to containerd to a plugin within
|
||||
containerd. This github branch is for the `cri` plugin. See
|
||||
[standalone-cri-containerd branch](https://github.com/containerd/cri/tree/standalone-cri-containerd)
|
||||
for information about the standalone version of `cri-containerd`.*
|
||||
|
||||
`cri-containerd` is a [containerd](https://containerd.io/) based implementation of Kubernetes [container runtime interface (CRI)](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/apis/cri/runtime/v1alpha2/api.proto).
|
||||
*Note: You need to [drain your node](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/) before upgrading from standalone `cri-containerd` to containerd with `cri` plugin.*
|
||||
|
||||
[](https://travis-ci.org/containerd/cri)
|
||||
[](https://goreportcard.com/report/github.com/containerd/cri)
|
||||
|
||||
`cri` is a [containerd](https://containerd.io/) plugin implementation of Kubernetes [container runtime interface (CRI)](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/apis/cri/runtime/v1alpha2/api.proto).
|
||||
|
||||
With it, you could run Kubernetes using containerd as the container runtime.
|
||||

|
||||

|
||||
## Current Status
|
||||
`cri-containerd` is in beta:
|
||||
`cri` is a native plugin of containerd 1.1 and above. It is built into containerd and enabled by default.
|
||||
|
||||
`cri` is in GA:
|
||||
* It is feature complete.
|
||||
* It (the beta version) works with Kubernetes >= 1.9.
|
||||
* It (the GA version) works with Kubernetes 1.10 and above.
|
||||
* It has passed all [CRI validation tests](https://github.com/kubernetes/community/blob/master/contributors/devel/cri-validation.md).
|
||||
* It has passed all regular [node e2e tests](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-node-tests.md).
|
||||
* It has passed all regular [e2e tests](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md).
|
||||
* It has passed all [node e2e tests](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-node-tests.md).
|
||||
* It has passed all [e2e tests](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-tests.md).
|
||||
|
||||
See [test dashboard](https://k8s-testgrid.appspot.com/sig-node-containerd)
|
||||
## Support Metrics
|
||||
| CRI-Containerd Version | Kubernetes Version |
|
||||
|:----------------------:|:------------------:|
|
||||
| v1.0.0-alpha.x | 1.7, 1.8 |
|
||||
| v1.0.0-beta.x | 1.9 |
|
||||
| HEAD | 1.10+ |
|
||||
| CRI-Containerd Version | Containerd Version | Kubernetes Version | CRI Version |
|
||||
|:----------------------:|:------------------:|:------------------:|:-----------:|
|
||||
| v1.0.0-alpha.x | | 1.7, 1.8 | v1alpha1 |
|
||||
| v1.0.0-beta.x | | 1.9 | v1alpha1 |
|
||||
| End-Of-Life | v1.1 | 1.10+ | v1alpha2 |
|
||||
| | HEAD | 1.10+ | v1alpha2 |
|
||||
|
||||
## Production Quality Cluster on GCE
|
||||
For a production quality cluster on GCE brought up with `kube-up.sh` refer [here](docs/kube-up.md).
|
||||
## Installing with Ansible and Kubeadm
|
||||
@@ -35,33 +47,33 @@ For non ansible users, you can download the `cri-containerd` release tarball and
|
||||
kubernetes cluster using kubeadm as described [here](docs/installation.md).
|
||||
## Getting Started for Developers
|
||||
### Binary Dependencies and Specifications
|
||||
The current release of `cri-containerd` has the following dependencies:
|
||||
The current release of the `cri` plugin has the following dependencies:
|
||||
* [containerd](https://github.com/containerd/containerd)
|
||||
* [runc](https://github.com/opencontainers/runc)
|
||||
* [CNI](https://github.com/containernetworking/cni)
|
||||
|
||||
See [versions](./vendor.conf) of these dependencies `cri-containerd` is tested with.
|
||||
See [versions](./vendor.conf) of these dependencies `cri` is tested with.
|
||||
|
||||
As containerd and runc move to their respective general availability releases,
|
||||
we will do our best to rebase/retest `cri-containerd` with these releases on a
|
||||
weekly/monthly basis. Similarly, given that `cri-containerd` uses the Open
|
||||
we will do our best to rebase/retest `cri` with these releases on a
|
||||
weekly/monthly basis. Similarly, given that `cri` uses the Open
|
||||
Container Initiative (OCI) [image](https://github.com/opencontainers/image-spec)
|
||||
and [runtime](https://github.com/opencontainers/runtime-spec) specifications, we
|
||||
will also do our best to update `cri-containerd` to the latest releases of these
|
||||
will also do our best to update `cri` to the latest releases of these
|
||||
specifications as appropriate.
|
||||
### Install Dependencies
|
||||
1. Install development libraries:
|
||||
* **libseccomp development library.** Required by cri-containerd and runc seccomp support. `libseccomp-dev` (Ubuntu, Debian) / `libseccomp-devel`
|
||||
* **libseccomp development library.** Required by `cri` and runc seccomp support. `libseccomp-dev` (Ubuntu, Debian) / `libseccomp-devel`
|
||||
(Fedora, CentOS, RHEL). On releases of Ubuntu <=Trusty and Debian <=jessie a
|
||||
backport version of `libseccomp-dev` is required. See [travis.yml](.travis.yml) for an example on trusty.
|
||||
* **libapparmor development library.** Required by cri-containerd and runc apparmor support. To use apparmor on Debian, Ubuntu, and related distributions the installation of `libapparmor-dev` is required.
|
||||
* **libapparmor development library.** Required by `cri` and runc apparmor support. To use apparmor on Debian, Ubuntu, and related distributions the installation of `libapparmor-dev` is required.
|
||||
* **btrfs development library.** Required by containerd btrfs support. `btrfs-tools`(Ubuntu, Debian) / `btrfs-progs-devel`(Fedora, CentOS, RHEL)
|
||||
2. Install other dependencies:
|
||||
* **`nsenter`**: Required by CNI and portforward.
|
||||
* **`nsenter`**: Required by portforward.
|
||||
* **`socat`**: Required by portforward.
|
||||
3. Install and setup a go 1.10 development environment.
|
||||
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/` project directory:
|
||||
```bash
|
||||
# Note: install.deps installs the above mentioned runc, containerd, and CNI
|
||||
# binary dependencies. install.deps is only provided for general use and ease of
|
||||
@@ -69,15 +81,18 @@ backport version of `libseccomp-dev` is required. See [travis.yml](.travis.yml)
|
||||
# `cni`, please follow instructions in their documents.
|
||||
make install.deps
|
||||
```
|
||||
### Build and Install cri-containerd
|
||||
To build and install `cri-containerd` enter the following commands from your `cri-containerd` project directory:
|
||||
### Build and Install `cri`
|
||||
To build and install a version of containerd with the `cri` plugin, enter the
|
||||
following commands from your `cri` project directory:
|
||||
```bash
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
*NOTE: The version of containerd built and installed from the `Makefile` is only for
|
||||
testing purposes. The version tag carries the suffix "-TEST".*
|
||||
#### Build Tags
|
||||
`cri-containerd` supports optional build tags for compiling support of various features.
|
||||
To add build tags to the make option the `BUILDTAGS` variable must be set.
|
||||
`cri` supports optional build tags for compiling support of various features.
|
||||
To add build tags to the make option the `BUILD_TAGS` variable must be set.
|
||||
|
||||
```bash
|
||||
make BUILD_TAGS='seccomp apparmor'
|
||||
@@ -88,31 +103,28 @@ make BUILD_TAGS='seccomp apparmor'
|
||||
| seccomp | syscall filtering | libseccomp development library |
|
||||
| selinux | selinux process and mount labeling | <none> |
|
||||
| apparmor | apparmor profile support | libapparmor development library |
|
||||
### Validate Your cri-containerd Setup
|
||||
### Validate Your `cri` Setup
|
||||
A Kubernetes incubator project called [cri-tools](https://github.com/kubernetes-incubator/cri-tools)
|
||||
includes programs for exercising CRI implementations such as `cri-containerd`.
|
||||
includes programs for exercising CRI implementations such as the `cri` plugin.
|
||||
More importantly, cri-tools includes the program `critest` which is used for running
|
||||
[CRI Validation Testing](https://github.com/kubernetes/community/blob/master/contributors/devel/cri-validation.md).
|
||||
|
||||
Run the CRI Validation test to validate your installation of `cri-containerd`:
|
||||
Run the CRI Validation test to validate your installation of `containerd` with `cri` built in:
|
||||
```bash
|
||||
make test-cri
|
||||
```
|
||||
### Running a Kubernetes local cluster
|
||||
If you already have a working development environment for supported Kubernetes
|
||||
version, you can try `cri-containerd` in a local cluster:
|
||||
version, you can try `cri` in a local cluster:
|
||||
|
||||
1. Start `containerd` as root in a first terminal:
|
||||
1. Start the version of `containerd` with `cri` plugin that you built and installed
|
||||
above as root in a first terminal:
|
||||
```bash
|
||||
sudo containerd
|
||||
```
|
||||
2. Start `cri-containerd` as root in a second terminal:
|
||||
2. From the Kubernetes project directory startup a local cluster using `containerd`:
|
||||
```bash
|
||||
sudo cri-containerd
|
||||
```
|
||||
3. From the Kubernetes project directory startup a local cluster using `cri-containerd`:
|
||||
```bash
|
||||
CONTAINER_RUNTIME=remote CONTAINER_RUNTIME_ENDPOINT='/var/run/cri-containerd.sock' ./hack/local-up-cluster.sh
|
||||
CONTAINER_RUNTIME=remote CONTAINER_RUNTIME_ENDPOINT='/run/containerd/containerd.sock' ./hack/local-up-cluster.sh
|
||||
```
|
||||
### Test
|
||||
See [here](./docs/testing.md) for information about test.
|
||||
|
||||
4
vendor/github.com/containerd/cri/cli/cli.go
generated
vendored
4
vendor/github.com/containerd/cri/cli/cli.go
generated
vendored
@@ -49,9 +49,9 @@ var loadCommand = cli.Command{
|
||||
timeout = context.GlobalDuration("timeout")
|
||||
cancel gocontext.CancelFunc
|
||||
)
|
||||
cl, err := client.NewCRIContainerdClient(address, timeout)
|
||||
cl, err := client.NewCRIPluginClient(address, timeout)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create grpc client: %v", err)
|
||||
return errors.Wrap(err, "failed to create grpc client")
|
||||
}
|
||||
if timeout > 0 {
|
||||
ctx, cancel = gocontext.WithTimeout(gocontext.Background(), timeout)
|
||||
|
||||
8
vendor/github.com/containerd/cri/cri.go
generated
vendored
8
vendor/github.com/containerd/cri/cri.go
generated
vendored
@@ -63,13 +63,11 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
|
||||
ctx := ic.Context
|
||||
pluginConfig := ic.Config.(*criconfig.PluginConfig)
|
||||
c := criconfig.Config{
|
||||
PluginConfig: *pluginConfig,
|
||||
// This is a hack. We assume that containerd root directory
|
||||
// is one level above plugin directory.
|
||||
// TODO(random-liu): Expose containerd config to plugin.
|
||||
PluginConfig: *pluginConfig,
|
||||
ContainerdRootDir: filepath.Dir(ic.Root),
|
||||
ContainerdEndpoint: ic.Address,
|
||||
RootDir: ic.Root,
|
||||
StateDir: ic.State,
|
||||
}
|
||||
log.G(ctx).Infof("Start cri plugin with config %+v", c)
|
||||
|
||||
@@ -92,7 +90,7 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
|
||||
return nil, errors.Wrap(err, "failed to create containerd client")
|
||||
}
|
||||
|
||||
s, err := server.NewCRIContainerdService(c, client)
|
||||
s, err := server.NewCRIService(c, client)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create CRI service")
|
||||
}
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/annotations/annotations.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/annotations/annotations.go
generated
vendored
@@ -31,4 +31,8 @@ const (
|
||||
|
||||
// SandboxID is the sandbox ID annotation
|
||||
SandboxID = "io.kubernetes.cri.sandbox-id"
|
||||
|
||||
// UntrustedWorkload is the sandbox annotation for untrusted workload. Untrusted
|
||||
// workload can only run on dedicated runtime for untrusted workload.
|
||||
UntrustedWorkload = "io.kubernetes.cri.untrusted-workload"
|
||||
)
|
||||
|
||||
57
vendor/github.com/containerd/cri/pkg/api/v1/api.pb.go
generated
vendored
57
vendor/github.com/containerd/cri/pkg/api/v1/api.pb.go
generated
vendored
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
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.
|
||||
@@ -13,7 +13,6 @@ 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.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// source: api.proto
|
||||
// DO NOT EDIT!
|
||||
@@ -101,66 +100,66 @@ var _ grpc.ClientConn
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// Client API for CRIContainerdService service
|
||||
// Client API for CRIPluginService service
|
||||
|
||||
type CRIContainerdServiceClient interface {
|
||||
type CRIPluginServiceClient interface {
|
||||
// LoadImage loads a image into containerd.
|
||||
LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error)
|
||||
}
|
||||
|
||||
type cRIContainerdServiceClient struct {
|
||||
type cRIPluginServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewCRIContainerdServiceClient(cc *grpc.ClientConn) CRIContainerdServiceClient {
|
||||
return &cRIContainerdServiceClient{cc}
|
||||
func NewCRIPluginServiceClient(cc *grpc.ClientConn) CRIPluginServiceClient {
|
||||
return &cRIPluginServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *cRIContainerdServiceClient) LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error) {
|
||||
func (c *cRIPluginServiceClient) LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error) {
|
||||
out := new(LoadImageResponse)
|
||||
err := grpc.Invoke(ctx, "/api.v1.CRIContainerdService/LoadImage", in, out, c.cc, opts...)
|
||||
err := grpc.Invoke(ctx, "/api.v1.CRIPluginService/LoadImage", in, out, c.cc, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for CRIContainerdService service
|
||||
// Server API for CRIPluginService service
|
||||
|
||||
type CRIContainerdServiceServer interface {
|
||||
type CRIPluginServiceServer interface {
|
||||
// LoadImage loads a image into containerd.
|
||||
LoadImage(context.Context, *LoadImageRequest) (*LoadImageResponse, error)
|
||||
}
|
||||
|
||||
func RegisterCRIContainerdServiceServer(s *grpc.Server, srv CRIContainerdServiceServer) {
|
||||
s.RegisterService(&_CRIContainerdService_serviceDesc, srv)
|
||||
func RegisterCRIPluginServiceServer(s *grpc.Server, srv CRIPluginServiceServer) {
|
||||
s.RegisterService(&_CRIPluginService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _CRIContainerdService_LoadImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _CRIPluginService_LoadImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(LoadImageRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CRIContainerdServiceServer).LoadImage(ctx, in)
|
||||
return srv.(CRIPluginServiceServer).LoadImage(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/api.v1.CRIContainerdService/LoadImage",
|
||||
FullMethod: "/api.v1.CRIPluginService/LoadImage",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CRIContainerdServiceServer).LoadImage(ctx, req.(*LoadImageRequest))
|
||||
return srv.(CRIPluginServiceServer).LoadImage(ctx, req.(*LoadImageRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _CRIContainerdService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "api.v1.CRIContainerdService",
|
||||
HandlerType: (*CRIContainerdServiceServer)(nil),
|
||||
var _CRIPluginService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "api.v1.CRIPluginService",
|
||||
HandlerType: (*CRIPluginServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "LoadImage",
|
||||
Handler: _CRIContainerdService_LoadImage_Handler,
|
||||
Handler: _CRIPluginService_LoadImage_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
@@ -580,7 +579,7 @@ var (
|
||||
func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
|
||||
|
||||
var fileDescriptorApi = []byte{
|
||||
// 223 bytes of a gzipped FileDescriptorProto
|
||||
// 219 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4,
|
||||
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0x31, 0xcb, 0x0c, 0xa5, 0x74, 0xd3, 0x33, 0x4b,
|
||||
0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2, 0x49,
|
||||
@@ -588,11 +587,11 @@ var fileDescriptorApi = []byte{
|
||||
0xa6, 0x78, 0xe6, 0x26, 0xa6, 0xa7, 0x06, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0x49, 0x71,
|
||||
0x71, 0xb8, 0x65, 0xe6, 0xa4, 0x06, 0x24, 0x96, 0x64, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06,
|
||||
0xc1, 0xf9, 0x4a, 0xda, 0x5c, 0x82, 0x48, 0xea, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0xc4,
|
||||
0xb8, 0xd8, 0xc0, 0x02, 0xc5, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x50, 0x9e, 0x51, 0x14,
|
||||
0x97, 0x88, 0x73, 0x90, 0xa7, 0x73, 0x7e, 0x5e, 0x49, 0x62, 0x66, 0x5e, 0x6a, 0x51, 0x4a, 0x70,
|
||||
0x6a, 0x51, 0x59, 0x66, 0x72, 0xaa, 0x90, 0x13, 0x17, 0x27, 0xdc, 0x10, 0x21, 0x09, 0x3d, 0x88,
|
||||
0xcb, 0xf5, 0xd0, 0xdd, 0x21, 0x25, 0x89, 0x45, 0x06, 0x62, 0xa3, 0x12, 0x83, 0x93, 0xcc, 0x89,
|
||||
0x87, 0x72, 0x8c, 0x37, 0x1e, 0xca, 0x31, 0x34, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1,
|
||||
0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xfb,
|
||||
0xce, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x6a, 0xfe, 0x35, 0x81, 0x21, 0x01, 0x00, 0x00,
|
||||
0xb8, 0xd8, 0xc0, 0x02, 0xc5, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x50, 0x9e, 0x51, 0x18,
|
||||
0x97, 0x80, 0x73, 0x90, 0x67, 0x40, 0x4e, 0x69, 0x7a, 0x66, 0x5e, 0x70, 0x6a, 0x51, 0x59, 0x66,
|
||||
0x72, 0xaa, 0x90, 0x13, 0x17, 0x27, 0xdc, 0x00, 0x21, 0x09, 0x3d, 0x88, 0xab, 0xf5, 0xd0, 0xdd,
|
||||
0x20, 0x25, 0x89, 0x45, 0x06, 0x62, 0x9b, 0x12, 0x83, 0x93, 0xcc, 0x89, 0x87, 0x72, 0x8c, 0x37,
|
||||
0x1e, 0xca, 0x31, 0x34, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6,
|
||||
0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xfb, 0xcc, 0x18, 0x10, 0x00,
|
||||
0x00, 0xff, 0xff, 0xfc, 0x6f, 0xec, 0xf4, 0x1d, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/api/v1/api.proto
generated
vendored
4
vendor/github.com/containerd/cri/pkg/api/v1/api.proto
generated
vendored
@@ -13,8 +13,8 @@ option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.goproto_unrecognized_all) = false;
|
||||
|
||||
// CRIContainerdService defines non-CRI APIs for cri-containerd.
|
||||
service CRIContainerdService{
|
||||
// CRIPluginService defines non-CRI APIs for cri plugin.
|
||||
service CRIPluginService{
|
||||
// LoadImage loads a image into containerd.
|
||||
rpc LoadImage(LoadImageRequest) returns (LoadImageResponse) {}
|
||||
}
|
||||
|
||||
12
vendor/github.com/containerd/cri/pkg/client/client.go
generated
vendored
12
vendor/github.com/containerd/cri/pkg/client/client.go
generated
vendored
@@ -17,21 +17,21 @@ limitations under the License.
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util"
|
||||
|
||||
api "github.com/containerd/cri/pkg/api/v1"
|
||||
)
|
||||
|
||||
// NewCRIContainerdClient creates grpc client of cri-containerd
|
||||
// NewCRIPluginClient creates grpc client of cri plugin
|
||||
// TODO(random-liu): Wrap grpc functions.
|
||||
func NewCRIContainerdClient(endpoint string, timeout time.Duration) (api.CRIContainerdServiceClient, error) {
|
||||
func NewCRIPluginClient(endpoint string, timeout time.Duration) (api.CRIPluginServiceClient, error) {
|
||||
addr, dialer, err := util.GetAddressAndDialer(endpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get dialer: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get dialer")
|
||||
}
|
||||
conn, err := grpc.Dial(addr,
|
||||
grpc.WithBlock(),
|
||||
@@ -41,7 +41,7 @@ func NewCRIContainerdClient(endpoint string, timeout time.Duration) (api.CRICont
|
||||
grpc.WithDialer(dialer),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to dial: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to dial")
|
||||
}
|
||||
return api.NewCRIContainerdServiceClient(conn), nil
|
||||
return api.NewCRIPluginServiceClient(conn), nil
|
||||
}
|
||||
|
||||
79
vendor/github.com/containerd/cri/pkg/config/config.go
generated
vendored
79
vendor/github.com/containerd/cri/pkg/config/config.go
generated
vendored
@@ -18,35 +18,40 @@ package config
|
||||
|
||||
import "github.com/containerd/containerd"
|
||||
|
||||
// Runtime struct to contain the type(ID), engine, and root variables for a default runtime
|
||||
// and a runtime for untrusted worload.
|
||||
type Runtime struct {
|
||||
// Type is the runtime type to use in containerd e.g. io.containerd.runtime.v1.linux
|
||||
Type string `toml:"runtime_type" json:"runtimeType"`
|
||||
// Engine is the name of the runtime engine used by containerd.
|
||||
Engine string `toml:"runtime_engine" json:"runtimeEngine"`
|
||||
// Root is the directory used by containerd for runtime state.
|
||||
Root string `toml:"runtime_root" json:"runtimeRoot"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
Snapshotter string `toml:"snapshotter" json:"snapshotter"`
|
||||
// DefaultRuntime is the runtime to use in containerd.
|
||||
DefaultRuntime Runtime `toml:"default_runtime" json:"defaultRuntime"`
|
||||
// UntrustedWorkloadRuntime is a runtime to run untrusted workloads on it.
|
||||
UntrustedWorkloadRuntime Runtime `toml:"untrusted_workload_runtime" json:"untrustedWorkloadRuntime"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
NetworkPluginBinDir string `toml:"bin_dir" json:"binDir"`
|
||||
// NetworkPluginConfDir is the directory in which the admin places a CNI conf.
|
||||
NetworkPluginConfDir string `toml:"conf_dir" json:"confDir,omitempty"`
|
||||
NetworkPluginConfDir string `toml:"conf_dir" json:"confDir"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
Endpoints []string `toml:"endpoint" json:"endpoint"`
|
||||
// TODO (Abhi) We might need to add auth per namespace. Looks like
|
||||
// image auth information is passed by kube itself.
|
||||
}
|
||||
@@ -54,33 +59,30 @@ type Mirror struct {
|
||||
// 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"`
|
||||
Mirrors map[string]Mirror `toml:"mirrors" json:"mirrors"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
ContainerdConfig `toml:"containerd" json:"containerd"`
|
||||
// CniConfig contains config related to cni
|
||||
CniConfig `toml:"cni" json:"cni,omitempty"`
|
||||
CniConfig `toml:"cni" json:"cni"`
|
||||
// Registry contains config related to the registry
|
||||
Registry `toml:"registry" json:"registry,omitempty"`
|
||||
Registry `toml:"registry" json:"registry"`
|
||||
// StreamServerAddress is the ip address streaming server is listening on.
|
||||
StreamServerAddress string `toml:"stream_server_address" json:"streamServerAddress,omitempty"`
|
||||
StreamServerAddress string `toml:"stream_server_address" json:"streamServerAddress"`
|
||||
// StreamServerPort is the port streaming server is listening on.
|
||||
StreamServerPort string `toml:"stream_server_port" json:"streamServerPort,omitempty"`
|
||||
StreamServerPort string `toml:"stream_server_port" json:"streamServerPort"`
|
||||
// EnableSelinux indicates to enable the selinux support.
|
||||
EnableSelinux bool `toml:"enable_selinux" json:"enableSelinux,omitempty"`
|
||||
EnableSelinux bool `toml:"enable_selinux" json:"enableSelinux"`
|
||||
// SandboxImage is the image used by sandbox container.
|
||||
SandboxImage string `toml:"sandbox_image" json:"sandboxImage,omitempty"`
|
||||
SandboxImage string `toml:"sandbox_image" json:"sandboxImage"`
|
||||
// StatsCollectPeriod is the period (in seconds) of snapshots stats collection.
|
||||
StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod,omitempty"`
|
||||
StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod"`
|
||||
// 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"`
|
||||
SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup"`
|
||||
}
|
||||
|
||||
// Config contains all configurations for cri server.
|
||||
@@ -88,12 +90,14 @@ type Config struct {
|
||||
// PluginConfig is the config for CRI plugin.
|
||||
PluginConfig
|
||||
// ContainerdRootDir is the root directory path for containerd.
|
||||
ContainerdRootDir string `json:"containerdRootDir,omitempty"`
|
||||
ContainerdRootDir string `json:"containerdRootDir"`
|
||||
// ContainerdEndpoint is the containerd endpoint path.
|
||||
ContainerdEndpoint string `json:"containerdEndpoint,omitempty"`
|
||||
// RootDir is the root directory path for managing cri-containerd files
|
||||
ContainerdEndpoint string `json:"containerdEndpoint"`
|
||||
// RootDir is the root directory path for managing cri plugin files
|
||||
// (metadata checkpoint etc.)
|
||||
RootDir string `json:"rootDir,omitempty"`
|
||||
RootDir string `json:"rootDir"`
|
||||
// StateDir is the root directory path for managing volatile pod/container data
|
||||
StateDir string `json:"stateDir"`
|
||||
}
|
||||
|
||||
// DefaultConfig returns default configurations of cri plugin.
|
||||
@@ -104,18 +108,19 @@ func DefaultConfig() PluginConfig {
|
||||
NetworkPluginConfDir: "/etc/cni/net.d",
|
||||
},
|
||||
ContainerdConfig: ContainerdConfig{
|
||||
Snapshotter: containerd.DefaultSnapshotter,
|
||||
Runtime: "io.containerd.runtime.v1.linux",
|
||||
RuntimeEngine: "",
|
||||
RuntimeRoot: "",
|
||||
Snapshotter: containerd.DefaultSnapshotter,
|
||||
DefaultRuntime: Runtime{
|
||||
Type: "io.containerd.runtime.v1.linux",
|
||||
Engine: "",
|
||||
Root: "",
|
||||
},
|
||||
},
|
||||
StreamServerAddress: "",
|
||||
StreamServerPort: "10010",
|
||||
EnableSelinux: false,
|
||||
SandboxImage: "gcr.io/google_containers/pause:3.0",
|
||||
SandboxImage: "k8s.gcr.io/pause:3.1",
|
||||
StatsCollectPeriod: 10,
|
||||
SystemdCgroup: false,
|
||||
EnableIPv6DAD: false,
|
||||
Registry: Registry{
|
||||
Mirrors: map[string]Mirror{
|
||||
"docker.io": {
|
||||
|
||||
12
vendor/github.com/containerd/cri/pkg/containerd/importer/importer.go
generated
vendored
12
vendor/github.com/containerd/cri/pkg/containerd/importer/importer.go
generated
vendored
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/leases"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/specs-go"
|
||||
@@ -81,8 +82,15 @@ func Import(ctx context.Context, client *containerd.Client, reader io.Reader) (_
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO(random-liu): Fix this after containerd client is fixed (containerd/containerd#2193)
|
||||
defer done(ctx) // nolint: errcheck
|
||||
defer func() {
|
||||
deferCtx, deferCancel := ctrdutil.DeferContext()
|
||||
defer deferCancel()
|
||||
if err := done(deferCtx); err != nil {
|
||||
// Get lease id from context still works after context is done.
|
||||
leaseID, _ := leases.Lease(ctx)
|
||||
log.G(ctx).WithError(err).Errorf("Failed to release lease %q", leaseID)
|
||||
}
|
||||
}()
|
||||
|
||||
cs := client.ContentStore()
|
||||
is := client.ImageService()
|
||||
|
||||
12
vendor/github.com/containerd/cri/pkg/containerd/resolver/resolver.go
generated
vendored
12
vendor/github.com/containerd/cri/pkg/containerd/resolver/resolver.go
generated
vendored
@@ -271,7 +271,7 @@ func (r *containerdResolver) base(refspec reference.Spec) (*dockerBase, error) {
|
||||
if urls, ok := r.registry[host]; ok {
|
||||
urls, err := r.getV2Urls(urls, prefix)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch v2 urls: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to fetch v2 urls")
|
||||
}
|
||||
base = append(base, urls...)
|
||||
} else if host == "docker.io" {
|
||||
@@ -434,7 +434,7 @@ func (r *dockerBase) setTokenAuth(ctx context.Context, params map[string]string)
|
||||
|
||||
realmURL, err := url.Parse(realm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid token auth challenge realm: %s", err)
|
||||
return errors.Wrap(err, "invalid token auth challenge realm")
|
||||
}
|
||||
|
||||
to := tokenOptions{
|
||||
@@ -444,7 +444,7 @@ func (r *dockerBase) setTokenAuth(ctx context.Context, params map[string]string)
|
||||
|
||||
to.scopes = getTokenScopes(ctx, params)
|
||||
if len(to.scopes) == 0 {
|
||||
return errors.Errorf("no scope specified for token auth challenge")
|
||||
return errors.New("no scope specified for token auth challenge")
|
||||
}
|
||||
if r.secret != "" {
|
||||
// Credential information is provided, use oauth POST endpoint
|
||||
@@ -517,7 +517,7 @@ func (r *dockerBase) fetchTokenWithOAuth(ctx context.Context, to tokenOptions) (
|
||||
|
||||
var tr postTokenResponse
|
||||
if err = decoder.Decode(&tr); err != nil {
|
||||
return "", fmt.Errorf("unable to decode token response: %s", err)
|
||||
return "", errors.Wrap(err, "unable to decode token response")
|
||||
}
|
||||
|
||||
return tr.AccessToken, nil
|
||||
@@ -569,7 +569,7 @@ func (r *dockerBase) getToken(ctx context.Context, to tokenOptions) (string, err
|
||||
|
||||
var tr getTokenResponse
|
||||
if err = decoder.Decode(&tr); err != nil {
|
||||
return "", fmt.Errorf("unable to decode token response: %s", err)
|
||||
return "", errors.Wrap(err, "unable to decode token response")
|
||||
}
|
||||
|
||||
// `access_token` is equivalent to `token` and if both are specified
|
||||
@@ -591,7 +591,7 @@ func (r *containerdResolver) getV2Urls(urls []string, imagePath string) ([]url.U
|
||||
for _, u := range urls {
|
||||
v2Url, err := url.Parse(u)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse url during getv2 urls: %+v, err:%s", u, err)
|
||||
return nil, errors.Wrapf(err, "failed to parse url during getv2 urls: %+v", u)
|
||||
}
|
||||
v2Url.Path = path.Join("/v2", imagePath)
|
||||
v2Urls = append(v2Urls, *v2Url)
|
||||
|
||||
29
vendor/github.com/containerd/cri/pkg/os/os.go
generated
vendored
29
vendor/github.com/containerd/cri/pkg/os/os.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
containerdmount "github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/fifo"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -37,6 +38,7 @@ type OS interface {
|
||||
OpenFifo(ctx context.Context, fn string, flag int, perm os.FileMode) (io.ReadWriteCloser, error)
|
||||
Stat(name string) (os.FileInfo, error)
|
||||
ResolveSymbolicLink(name string) (string, error)
|
||||
FollowSymlinkInScope(path, scope string) (string, error)
|
||||
CopyFile(src, dest string, perm os.FileMode) error
|
||||
WriteFile(filename string, data []byte, perm os.FileMode) error
|
||||
Mount(source string, target string, fstype string, flags uintptr, data string) error
|
||||
@@ -47,7 +49,7 @@ type OS interface {
|
||||
// RealOS is used to dispatch the real system level operations.
|
||||
type RealOS struct{}
|
||||
|
||||
// MkdirAll will will call os.MkdirAll to create a directory.
|
||||
// MkdirAll will call os.MkdirAll to create a directory.
|
||||
func (RealOS) MkdirAll(path string, perm os.FileMode) error {
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
@@ -79,7 +81,12 @@ func (RealOS) ResolveSymbolicLink(path string) (string, error) {
|
||||
return filepath.EvalSymlinks(path)
|
||||
}
|
||||
|
||||
// CopyFile copys src file to dest file
|
||||
// FollowSymlinkInScope will call symlink.FollowSymlinkInScope.
|
||||
func (RealOS) FollowSymlinkInScope(path, scope string) (string, error) {
|
||||
return symlink.FollowSymlinkInScope(path, scope)
|
||||
}
|
||||
|
||||
// CopyFile will copy src file to dest file
|
||||
func (RealOS) CopyFile(src, dest string, perm os.FileMode) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
@@ -107,17 +114,21 @@ func (RealOS) Mount(source string, target string, fstype string, flags uintptr,
|
||||
return unix.Mount(source, target, fstype, flags, data)
|
||||
}
|
||||
|
||||
// Unmount will call unix.Unmount to unmount the file. The function doesn't
|
||||
// return error if target is not mounted.
|
||||
// Unmount will call Unmount to unmount the file.
|
||||
func (RealOS) Unmount(target string, flags int) error {
|
||||
// TODO(random-liu): Follow symlink to make sure the result is correct.
|
||||
if mounted, err := mount.Mounted(target); err != nil || !mounted {
|
||||
return err
|
||||
}
|
||||
return unix.Unmount(target, flags)
|
||||
return Unmount(target, flags)
|
||||
}
|
||||
|
||||
// LookupMount gets mount info of a given path.
|
||||
func (RealOS) LookupMount(path string) (containerdmount.Info, error) {
|
||||
return containerdmount.Lookup(path)
|
||||
}
|
||||
|
||||
// Unmount will call unix.Unmount to unmount the file. The function doesn't
|
||||
// return error if target is not mounted.
|
||||
func Unmount(target string, flags int) error {
|
||||
if mounted, err := mount.Mounted(target); err != nil || !mounted {
|
||||
return err
|
||||
}
|
||||
return unix.Unmount(target, flags)
|
||||
}
|
||||
|
||||
9
vendor/github.com/containerd/cri/pkg/registrar/registrar.go
generated
vendored
9
vendor/github.com/containerd/cri/pkg/registrar/registrar.go
generated
vendored
@@ -17,8 +17,9 @@ limitations under the License.
|
||||
package registrar
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Registrar stores one-to-one name<->key mappings.
|
||||
@@ -49,19 +50,19 @@ func (r *Registrar) Reserve(name, key string) error {
|
||||
defer r.lock.Unlock()
|
||||
|
||||
if name == "" || key == "" {
|
||||
return fmt.Errorf("invalid name %q or key %q", name, key)
|
||||
return errors.Errorf("invalid name %q or key %q", name, key)
|
||||
}
|
||||
|
||||
if k, exists := r.nameToKey[name]; exists {
|
||||
if k != key {
|
||||
return fmt.Errorf("name %q is reserved for %q", name, k)
|
||||
return errors.Errorf("name %q is reserved for %q", name, k)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if n, exists := r.keyToName[key]; exists {
|
||||
if n != name {
|
||||
return fmt.Errorf("key %q is reserved for %q", key, n)
|
||||
return errors.Errorf("key %q is reserved for %q", key, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
16
vendor/github.com/containerd/cri/pkg/server/container_attach.go
generated
vendored
16
vendor/github.com/containerd/cri/pkg/server/container_attach.go
generated
vendored
@@ -17,10 +17,10 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
@@ -30,35 +30,35 @@ import (
|
||||
)
|
||||
|
||||
// Attach prepares a streaming endpoint to attach to a running container, and returns the address.
|
||||
func (c *criContainerdService) Attach(ctx context.Context, r *runtime.AttachRequest) (*runtime.AttachResponse, error) {
|
||||
func (c *criService) Attach(ctx context.Context, r *runtime.AttachRequest) (*runtime.AttachResponse, error) {
|
||||
cntr, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find container in store: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to find container in store")
|
||||
}
|
||||
state := cntr.Status.Get().State()
|
||||
if state != runtime.ContainerState_CONTAINER_RUNNING {
|
||||
return nil, fmt.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
return nil, errors.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
}
|
||||
return c.streamServer.GetAttach(r)
|
||||
}
|
||||
|
||||
func (c *criContainerdService) attachContainer(ctx context.Context, id string, stdin io.Reader, stdout, stderr io.WriteCloser,
|
||||
func (c *criService) attachContainer(ctx context.Context, id string, stdin io.Reader, stdout, stderr io.WriteCloser,
|
||||
tty bool, resize <-chan remotecommand.TerminalSize) error {
|
||||
// Get container from our container store.
|
||||
cntr, err := c.containerStore.Get(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find container %q in store: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to find container %q in store", id)
|
||||
}
|
||||
id = cntr.ID
|
||||
|
||||
state := cntr.Status.Get().State()
|
||||
if state != runtime.ContainerState_CONTAINER_RUNNING {
|
||||
return fmt.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
return errors.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
}
|
||||
|
||||
task, err := cntr.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load task: %v", err)
|
||||
return errors.Wrap(err, "failed to load task")
|
||||
}
|
||||
handleResizing(resize, func(size remotecommand.TerminalSize) {
|
||||
if err := task.Resize(ctx, uint32(size.Width), uint32(size.Height)); err != nil {
|
||||
|
||||
124
vendor/github.com/containerd/cri/pkg/server/container_create.go
generated
vendored
124
vendor/github.com/containerd/cri/pkg/server/container_create.go
generated
vendored
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -38,6 +37,7 @@ import (
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/opencontainers/runtime-tools/validate"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/syndtr/gocapability/capability"
|
||||
"golang.org/x/net/context"
|
||||
@@ -73,17 +73,17 @@ func init() {
|
||||
}
|
||||
|
||||
// CreateContainer creates a new container in the given PodSandbox.
|
||||
func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.CreateContainerRequest) (_ *runtime.CreateContainerResponse, retErr error) {
|
||||
func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateContainerRequest) (_ *runtime.CreateContainerResponse, retErr error) {
|
||||
config := r.GetConfig()
|
||||
sandboxConfig := r.GetSandboxConfig()
|
||||
sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find sandbox id %q: %v", r.GetPodSandboxId(), err)
|
||||
return nil, errors.Wrapf(err, "failed to find sandbox id %q", r.GetPodSandboxId())
|
||||
}
|
||||
sandboxID := sandbox.ID
|
||||
s, err := sandbox.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sandbox container task: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get sandbox container task")
|
||||
}
|
||||
sandboxPid := s.Pid()
|
||||
|
||||
@@ -94,7 +94,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
name := makeContainerName(config.GetMetadata(), sandboxConfig.GetMetadata())
|
||||
logrus.Debugf("Generated id %q for container %q", id, name)
|
||||
if err = c.containerNameIndex.Reserve(name, id); err != nil {
|
||||
return nil, fmt.Errorf("failed to reserve container name %q: %v", name, err)
|
||||
return nil, errors.Wrapf(err, "failed to reserve container name %q", name)
|
||||
}
|
||||
defer func() {
|
||||
// Release the name if the function returns with an error.
|
||||
@@ -116,17 +116,28 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
imageRef := config.GetImage().GetImage()
|
||||
image, err := c.localResolve(ctx, imageRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve image %q: %v", imageRef, err)
|
||||
return nil, errors.Wrapf(err, "failed to resolve image %q", imageRef)
|
||||
}
|
||||
if image == nil {
|
||||
return nil, fmt.Errorf("image %q not found", imageRef)
|
||||
return nil, errors.Errorf("image %q not found", imageRef)
|
||||
}
|
||||
|
||||
// Run container using the same runtime with sandbox.
|
||||
sandboxInfo, err := sandbox.Container.Info(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get sandbox %q info", sandboxID)
|
||||
}
|
||||
ociRuntime, err := getRuntimeConfigFromContainerInfo(sandboxInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get OCI runtime")
|
||||
}
|
||||
logrus.Debugf("Use OCI %+v for container %q", ociRuntime, id)
|
||||
|
||||
// Create container root directory.
|
||||
containerRootDir := getContainerRootDir(c.config.RootDir, id)
|
||||
containerRootDir := c.getContainerRootDir(id)
|
||||
if err = c.os.MkdirAll(containerRootDir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create container root directory %q: %v",
|
||||
containerRootDir, err)
|
||||
return nil, errors.Wrapf(err, "failed to create container root directory %q",
|
||||
containerRootDir)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -137,16 +148,30 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
}
|
||||
}
|
||||
}()
|
||||
volatileContainerRootDir := c.getVolatileContainerRootDir(id)
|
||||
if err = c.os.MkdirAll(volatileContainerRootDir, 0755); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to create volatile container root directory %q",
|
||||
volatileContainerRootDir)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
// Cleanup the volatile container root directory.
|
||||
if err = c.os.RemoveAll(volatileContainerRootDir); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to remove volatile container root directory %q",
|
||||
volatileContainerRootDir)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Create container volumes mounts.
|
||||
volumeMounts := c.generateVolumeMounts(containerRootDir, config.GetMounts(), &image.ImageSpec.Config)
|
||||
|
||||
// Generate container runtime spec.
|
||||
mounts := c.generateContainerMounts(getSandboxRootDir(c.config.RootDir, sandboxID), config)
|
||||
mounts := c.generateContainerMounts(sandboxID, config)
|
||||
|
||||
spec, err := c.generateContainerSpec(id, sandboxID, sandboxPid, config, sandboxConfig, &image.ImageSpec.Config, append(mounts, volumeMounts...))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate container %q spec: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to generate container %q spec", id)
|
||||
}
|
||||
|
||||
logrus.Debugf("Container %q spec: %#+v", id, spew.NewFormatter(spec))
|
||||
@@ -177,9 +202,9 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
}
|
||||
|
||||
containerIO, err := cio.NewContainerIO(id,
|
||||
cio.WithNewFIFOs(containerRootDir, config.GetTty(), config.GetStdin()))
|
||||
cio.WithNewFIFOs(volatileContainerRootDir, config.GetTty(), config.GetStdin()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create container io: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to create container io")
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -206,7 +231,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
securityContext.GetPrivileged(),
|
||||
c.apparmorEnabled)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate apparmor spec opts: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to generate apparmor spec opts")
|
||||
}
|
||||
if apparmorSpecOpts != nil {
|
||||
specOpts = append(specOpts, apparmorSpecOpts)
|
||||
@@ -217,7 +242,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
securityContext.GetPrivileged(),
|
||||
c.seccompEnabled)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate seccomp spec opts: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to generate seccomp spec opts")
|
||||
}
|
||||
if seccompSpecOpts != nil {
|
||||
specOpts = append(specOpts, seccompSpecOpts)
|
||||
@@ -227,16 +252,16 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
opts = append(opts,
|
||||
containerd.WithSpec(spec, specOpts...),
|
||||
containerd.WithRuntime(
|
||||
c.config.ContainerdConfig.Runtime,
|
||||
ociRuntime.Type,
|
||||
&runctypes.RuncOptions{
|
||||
Runtime: c.config.ContainerdConfig.RuntimeEngine,
|
||||
RuntimeRoot: c.config.ContainerdConfig.RuntimeRoot,
|
||||
Runtime: ociRuntime.Engine,
|
||||
RuntimeRoot: ociRuntime.Root,
|
||||
SystemdCgroup: c.config.SystemdCgroup}), // TODO (mikebrow): add CriuPath when we add support for pause
|
||||
containerd.WithContainerLabels(containerLabels),
|
||||
containerd.WithContainerExtension(containerMetadataExtension, &meta))
|
||||
var cntr containerd.Container
|
||||
if cntr, err = c.client.NewContainer(ctx, id, opts...); err != nil {
|
||||
return nil, fmt.Errorf("failed to create containerd container: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to create containerd container")
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -255,8 +280,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
containerstore.WithContainerIO(containerIO),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create internal container object for %q: %v",
|
||||
id, err)
|
||||
return nil, errors.Wrapf(err, "failed to create internal container object for %q", id)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -269,13 +293,13 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
|
||||
// Add container into container store.
|
||||
if err := c.containerStore.Add(container); err != nil {
|
||||
return nil, fmt.Errorf("failed to add container %q into store: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to add container %q into store", id)
|
||||
}
|
||||
|
||||
return &runtime.CreateContainerResponse{ContainerId: id}, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) generateContainerSpec(id string, sandboxID string, sandboxPid uint32, config *runtime.ContainerConfig,
|
||||
func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxPid uint32, config *runtime.ContainerConfig,
|
||||
sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, extraMounts []*runtime.Mount) (*runtimespec.Spec, error) {
|
||||
// Creates a spec Generator with the default spec.
|
||||
spec, err := defaultRuntimeSpec(id)
|
||||
@@ -316,30 +340,30 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxID string
|
||||
selinuxOpt := securityContext.GetSelinuxOptions()
|
||||
processLabel, mountLabel, err := initSelinuxOpts(selinuxOpt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init selinux options %+v: %v", securityContext.GetSelinuxOptions(), err)
|
||||
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
|
||||
}
|
||||
|
||||
// Add extra mounts first so that CRI specified mounts can override.
|
||||
mounts := append(extraMounts, config.GetMounts()...)
|
||||
if err := c.addOCIBindMounts(&g, mounts, mountLabel); err != nil {
|
||||
return nil, fmt.Errorf("failed to set OCI bind mounts %+v: %v", mounts, err)
|
||||
return nil, errors.Wrapf(err, "failed to set OCI bind mounts %+v", mounts)
|
||||
}
|
||||
|
||||
if securityContext.GetPrivileged() {
|
||||
if !sandboxConfig.GetLinux().GetSecurityContext().GetPrivileged() {
|
||||
return nil, fmt.Errorf("no privileged container allowed in sandbox")
|
||||
return nil, errors.New("no privileged container allowed in sandbox")
|
||||
}
|
||||
if err := setOCIPrivileged(&g, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else { // not privileged
|
||||
if err := c.addOCIDevices(&g, config.GetDevices()); err != nil {
|
||||
return nil, fmt.Errorf("failed to set devices mapping %+v: %v", config.GetDevices(), err)
|
||||
return nil, errors.Wrapf(err, "failed to set devices mapping %+v", config.GetDevices())
|
||||
}
|
||||
|
||||
if err := setOCICapabilities(&g, securityContext.GetCapabilities()); err != nil {
|
||||
return nil, fmt.Errorf("failed to set capabilities %+v: %v",
|
||||
securityContext.GetCapabilities(), err)
|
||||
return nil, errors.Wrapf(err, "failed to set capabilities %+v",
|
||||
securityContext.GetCapabilities())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +402,7 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxID string
|
||||
// generateVolumeMounts sets up image volumes for container. Rely on the removal of container
|
||||
// root directory to do cleanup. Note that image volume will be skipped, if there is criMounts
|
||||
// specified with the same destination.
|
||||
func (c *criContainerdService) generateVolumeMounts(containerRootDir string, criMounts []*runtime.Mount, config *imagespec.ImageConfig) []*runtime.Mount {
|
||||
func (c *criService) generateVolumeMounts(containerRootDir string, criMounts []*runtime.Mount, config *imagespec.ImageConfig) []*runtime.Mount {
|
||||
if len(config.Volumes) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -406,13 +430,13 @@ func (c *criContainerdService) generateVolumeMounts(containerRootDir string, cri
|
||||
|
||||
// generateContainerMounts sets up necessary container mounts including /dev/shm, /etc/hosts
|
||||
// and /etc/resolv.conf.
|
||||
func (c *criContainerdService) generateContainerMounts(sandboxRootDir string, config *runtime.ContainerConfig) []*runtime.Mount {
|
||||
func (c *criService) generateContainerMounts(sandboxID string, config *runtime.ContainerConfig) []*runtime.Mount {
|
||||
var mounts []*runtime.Mount
|
||||
securityContext := config.GetLinux().GetSecurityContext()
|
||||
if !isInCRIMounts(etcHosts, config.GetMounts()) {
|
||||
mounts = append(mounts, &runtime.Mount{
|
||||
ContainerPath: etcHosts,
|
||||
HostPath: getSandboxHosts(sandboxRootDir),
|
||||
HostPath: c.getSandboxHosts(sandboxID),
|
||||
Readonly: securityContext.GetReadonlyRootfs(),
|
||||
})
|
||||
}
|
||||
@@ -422,13 +446,13 @@ func (c *criContainerdService) generateContainerMounts(sandboxRootDir string, co
|
||||
if !isInCRIMounts(resolvConfPath, config.GetMounts()) {
|
||||
mounts = append(mounts, &runtime.Mount{
|
||||
ContainerPath: resolvConfPath,
|
||||
HostPath: getResolvPath(sandboxRootDir),
|
||||
HostPath: c.getResolvPath(sandboxID),
|
||||
Readonly: securityContext.GetReadonlyRootfs(),
|
||||
})
|
||||
}
|
||||
|
||||
if !isInCRIMounts(devShm, config.GetMounts()) {
|
||||
sandboxDevShm := getSandboxDevShm(sandboxRootDir)
|
||||
sandboxDevShm := c.getSandboxDevShm(sandboxID)
|
||||
if securityContext.GetNamespaceOptions().GetIpc() == runtime.NamespaceMode_NODE {
|
||||
sandboxDevShm = devShm
|
||||
}
|
||||
@@ -457,7 +481,7 @@ func setOCIProcessArgs(g *generate.Generator, config *runtime.ContainerConfig, i
|
||||
}
|
||||
}
|
||||
if len(command) == 0 && len(args) == 0 {
|
||||
return fmt.Errorf("no command specified")
|
||||
return errors.New("no command specified")
|
||||
}
|
||||
g.SetProcessArgs(append(command, args...))
|
||||
return nil
|
||||
@@ -469,7 +493,7 @@ func addImageEnvs(g *generate.Generator, imageEnvs []string) error {
|
||||
for _, e := range imageEnvs {
|
||||
kv := strings.SplitN(e, "=", 2)
|
||||
if len(kv) != 2 {
|
||||
return fmt.Errorf("invalid environment variable %q", e)
|
||||
return errors.Errorf("invalid environment variable %q", e)
|
||||
}
|
||||
g.AddProcessEnv(kv[0], kv[1])
|
||||
}
|
||||
@@ -481,7 +505,7 @@ func setOCIPrivileged(g *generate.Generator, config *runtime.ContainerConfig) er
|
||||
g.SetupPrivileged(true)
|
||||
setOCIBindMountsPrivileged(g)
|
||||
if err := setOCIDevicesPrivileged(g); err != nil {
|
||||
return fmt.Errorf("failed to set devices mapping %+v: %v", config.GetDevices(), err)
|
||||
return errors.Wrapf(err, "failed to set devices mapping %+v", config.GetDevices())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -497,7 +521,7 @@ func clearReadOnly(m *runtimespec.Mount) {
|
||||
}
|
||||
|
||||
// addDevices set device mapping without privilege.
|
||||
func (c *criContainerdService) addOCIDevices(g *generate.Generator, devs []*runtime.Device) error {
|
||||
func (c *criService) addOCIDevices(g *generate.Generator, devs []*runtime.Device) error {
|
||||
spec := g.Spec()
|
||||
for _, device := range devs {
|
||||
path, err := c.os.ResolveSymbolicLink(device.HostPath)
|
||||
@@ -560,7 +584,7 @@ func setOCIDevicesPrivileged(g *generate.Generator) error {
|
||||
}
|
||||
|
||||
// addOCIBindMounts adds bind mounts.
|
||||
func (c *criContainerdService) addOCIBindMounts(g *generate.Generator, mounts []*runtime.Mount, mountLabel string) error {
|
||||
func (c *criService) addOCIBindMounts(g *generate.Generator, mounts []*runtime.Mount, mountLabel string) error {
|
||||
// Mount cgroup into the container as readonly, which inherits docker's behavior.
|
||||
g.AddCgroupsMount("ro") // nolint: errcheck
|
||||
for _, mount := range mounts {
|
||||
@@ -570,17 +594,17 @@ func (c *criContainerdService) addOCIBindMounts(g *generate.Generator, mounts []
|
||||
// TODO(random-liu): Add CRI validation test for this case.
|
||||
if _, err := c.os.Stat(src); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return fmt.Errorf("failed to stat %q: %v", src, err)
|
||||
return errors.Wrapf(err, "failed to stat %q", src)
|
||||
}
|
||||
if err := c.os.MkdirAll(src, 0755); err != nil {
|
||||
return fmt.Errorf("failed to mkdir %q: %v", src, err)
|
||||
return errors.Wrapf(err, "failed to mkdir %q", src)
|
||||
}
|
||||
}
|
||||
// TODO(random-liu): Add cri-containerd integration test or cri validation test
|
||||
// for this.
|
||||
src, err := c.os.ResolveSymbolicLink(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve symlink %q: %v", src, err)
|
||||
return errors.Wrapf(err, "failed to resolve symlink %q", src)
|
||||
}
|
||||
|
||||
options := []string{"rbind"}
|
||||
@@ -619,7 +643,7 @@ func (c *criContainerdService) addOCIBindMounts(g *generate.Generator, mounts []
|
||||
|
||||
if mount.GetSelinuxRelabel() {
|
||||
if err := label.Relabel(src, mountLabel, true); err != nil && err != unix.ENOTSUP {
|
||||
return fmt.Errorf("relabel %q with %q failed: %v", src, mountLabel, err)
|
||||
return errors.Wrapf(err, "relabel %q with %q failed", src, mountLabel)
|
||||
}
|
||||
}
|
||||
g.AddBindMount(src, dst, options)
|
||||
@@ -773,7 +797,7 @@ func generateSeccompSpecOpts(seccompProf string, privileged, seccompEnabled bool
|
||||
}
|
||||
if !seccompEnabled {
|
||||
if seccompProf != "" && seccompProf != unconfinedProfile {
|
||||
return nil, fmt.Errorf("seccomp is not supported")
|
||||
return nil, errors.New("seccomp is not supported")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -787,7 +811,7 @@ func generateSeccompSpecOpts(seccompProf string, privileged, seccompEnabled bool
|
||||
default:
|
||||
// Require and Trim default profile name prefix
|
||||
if !strings.HasPrefix(seccompProf, profileNamePrefix) {
|
||||
return nil, fmt.Errorf("invalid seccomp profile %q", seccompProf)
|
||||
return nil, errors.Errorf("invalid seccomp profile %q", seccompProf)
|
||||
}
|
||||
return seccomp.WithProfile(strings.TrimPrefix(seccompProf, profileNamePrefix)), nil
|
||||
}
|
||||
@@ -799,7 +823,7 @@ func generateApparmorSpecOpts(apparmorProf string, privileged, apparmorEnabled b
|
||||
// Should fail loudly if user try to specify apparmor profile
|
||||
// but we don't support it.
|
||||
if apparmorProf != "" && apparmorProf != unconfinedProfile {
|
||||
return nil, fmt.Errorf("apparmor is not supported")
|
||||
return nil, errors.New("apparmor is not supported")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -819,7 +843,7 @@ func generateApparmorSpecOpts(apparmorProf string, privileged, apparmorEnabled b
|
||||
default:
|
||||
// Require and Trim default profile name prefix
|
||||
if !strings.HasPrefix(apparmorProf, profileNamePrefix) {
|
||||
return nil, fmt.Errorf("invalid apparmor profile %q", apparmorProf)
|
||||
return nil, errors.Errorf("invalid apparmor profile %q", apparmorProf)
|
||||
}
|
||||
return apparmor.WithProfile(strings.TrimPrefix(apparmorProf, profileNamePrefix)), nil
|
||||
}
|
||||
@@ -840,7 +864,7 @@ func ensureShared(path string, lookupMount func(string) (mount.Info, error)) err
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("path %q is mounted on %q but it is not a shared mount", path, mountInfo.Mountpoint)
|
||||
return errors.Errorf("path %q is mounted on %q but it is not a shared mount", path, mountInfo.Mountpoint)
|
||||
}
|
||||
|
||||
// Ensure mount point on which path is mounted, is either shared or slave.
|
||||
@@ -858,5 +882,5 @@ func ensureSharedOrSlave(path string, lookupMount func(string) (mount.Info, erro
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("path %q is mounted on %q but it is not a shared or slave mount", path, mountInfo.Mountpoint)
|
||||
return errors.Errorf("path %q is mounted on %q but it is not a shared or slave mount", path, mountInfo.Mountpoint)
|
||||
}
|
||||
|
||||
9
vendor/github.com/containerd/cri/pkg/server/container_exec.go
generated
vendored
9
vendor/github.com/containerd/cri/pkg/server/container_exec.go
generated
vendored
@@ -17,21 +17,20 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
// Exec prepares a streaming endpoint to execute a command in the container, and returns the address.
|
||||
func (c *criContainerdService) Exec(ctx context.Context, r *runtime.ExecRequest) (*runtime.ExecResponse, error) {
|
||||
func (c *criService) Exec(ctx context.Context, r *runtime.ExecRequest) (*runtime.ExecResponse, error) {
|
||||
cntr, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find container %q in store: %v", r.GetContainerId(), err)
|
||||
return nil, errors.Wrapf(err, "failed to find container %q in store", r.GetContainerId())
|
||||
}
|
||||
state := cntr.Status.Get().State()
|
||||
if state != runtime.ContainerState_CONTAINER_RUNNING {
|
||||
return nil, fmt.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
return nil, errors.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
}
|
||||
return c.streamServer.GetExec(r)
|
||||
}
|
||||
|
||||
32
vendor/github.com/containerd/cri/pkg/server/container_execsync.go
generated
vendored
32
vendor/github.com/containerd/cri/pkg/server/container_execsync.go
generated
vendored
@@ -18,13 +18,13 @@ package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
containerdio "github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -39,7 +39,7 @@ import (
|
||||
|
||||
// ExecSync executes a command in the container, and returns the stdout output.
|
||||
// If command exits with a non-zero exit code, an error is returned.
|
||||
func (c *criContainerdService) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (*runtime.ExecSyncResponse, error) {
|
||||
func (c *criService) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (*runtime.ExecSyncResponse, error) {
|
||||
var stdout, stderr bytes.Buffer
|
||||
exitCode, err := c.execInContainer(ctx, r.GetContainerId(), execOptions{
|
||||
cmd: r.GetCmd(),
|
||||
@@ -48,7 +48,7 @@ func (c *criContainerdService) ExecSync(ctx context.Context, r *runtime.ExecSync
|
||||
timeout: time.Duration(r.GetTimeout()) * time.Second,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to exec in container: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to exec in container")
|
||||
}
|
||||
|
||||
return &runtime.ExecSyncResponse{
|
||||
@@ -71,7 +71,7 @@ type execOptions struct {
|
||||
|
||||
// execInContainer executes a command inside the container synchronously, and
|
||||
// redirects stdio stream properly.
|
||||
func (c *criContainerdService) execInContainer(ctx context.Context, id string, opts execOptions) (*uint32, error) {
|
||||
func (c *criService) execInContainer(ctx context.Context, id string, opts execOptions) (*uint32, error) {
|
||||
// Cancel the context before returning to ensure goroutines are stopped.
|
||||
// This is important, because if `Start` returns error, `Wait` will hang
|
||||
// forever unless we cancel the context.
|
||||
@@ -81,23 +81,23 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
|
||||
// Get container from our container store.
|
||||
cntr, err := c.containerStore.Get(id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find container %q in store: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to find container %q in store", id)
|
||||
}
|
||||
id = cntr.ID
|
||||
|
||||
state := cntr.Status.Get().State()
|
||||
if state != runtime.ContainerState_CONTAINER_RUNNING {
|
||||
return nil, fmt.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
return nil, errors.Errorf("container is in %s state", criContainerStateToString(state))
|
||||
}
|
||||
|
||||
container := cntr.Container
|
||||
spec, err := container.Spec(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get container spec: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get container spec")
|
||||
}
|
||||
task, err := container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load task: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to load task")
|
||||
}
|
||||
if opts.tty {
|
||||
g := newSpecGenerator(spec)
|
||||
@@ -116,17 +116,17 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
|
||||
}
|
||||
execID := util.GenerateID()
|
||||
logrus.Debugf("Generated exec id %q for container %q", execID, id)
|
||||
rootDir := getContainerRootDir(c.config.RootDir, id)
|
||||
volatileRootDir := c.getVolatileContainerRootDir(id)
|
||||
var execIO *cio.ExecIO
|
||||
process, err := task.Exec(ctx, execID, pspec,
|
||||
func(id string) (containerdio.IO, error) {
|
||||
var err error
|
||||
execIO, err = cio.NewExecIO(id, rootDir, opts.tty, opts.stdin != nil)
|
||||
execIO, err = cio.NewExecIO(id, volatileRootDir, opts.tty, opts.stdin != nil)
|
||||
return execIO, err
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create exec %q: %v", execID, err)
|
||||
return nil, errors.Wrapf(err, "failed to create exec %q", execID)
|
||||
}
|
||||
defer func() {
|
||||
deferCtx, deferCancel := ctrdutil.DeferContext()
|
||||
@@ -138,10 +138,10 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
|
||||
|
||||
exitCh, err := process.Wait(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to wait for process %q: %v", execID, err)
|
||||
return nil, errors.Wrapf(err, "failed to wait for process %q", execID)
|
||||
}
|
||||
if err := process.Start(ctx); err != nil {
|
||||
return nil, fmt.Errorf("failed to start exec %q: %v", execID, err)
|
||||
return nil, errors.Wrapf(err, "failed to start exec %q", execID)
|
||||
}
|
||||
|
||||
handleResizing(opts.resize, func(size remotecommand.TerminalSize) {
|
||||
@@ -173,7 +173,7 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
|
||||
//TODO(Abhi) Use context.WithDeadline instead of timeout.
|
||||
// Ignore the not found error because the process may exit itself before killing.
|
||||
if err := process.Kill(ctx, unix.SIGKILL); err != nil && !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to kill exec %q: %v", execID, err)
|
||||
return nil, errors.Wrapf(err, "failed to kill exec %q", execID)
|
||||
}
|
||||
// Wait for the process to be killed.
|
||||
exitRes := <-exitCh
|
||||
@@ -181,12 +181,12 @@ func (c *criContainerdService) execInContainer(ctx context.Context, id string, o
|
||||
execID, exitRes.ExitCode(), exitRes.Error())
|
||||
<-attachDone
|
||||
logrus.Debugf("Stream pipe for exec process %q done", execID)
|
||||
return nil, fmt.Errorf("timeout %v exceeded", opts.timeout)
|
||||
return nil, errors.Errorf("timeout %v exceeded", opts.timeout)
|
||||
case exitRes := <-exitCh:
|
||||
code, _, err := exitRes.Result()
|
||||
logrus.Infof("Exec process %q exits with exit code %d and error %v", execID, code, err)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed while waiting for exec %q: %v", execID, err)
|
||||
return nil, errors.Wrapf(err, "failed while waiting for exec %q", execID)
|
||||
}
|
||||
<-attachDone
|
||||
logrus.Debugf("Stream pipe for exec process %q done", execID)
|
||||
|
||||
6
vendor/github.com/containerd/cri/pkg/server/container_list.go
generated
vendored
6
vendor/github.com/containerd/cri/pkg/server/container_list.go
generated
vendored
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
// ListContainers lists all containers matching the filter.
|
||||
func (c *criContainerdService) ListContainers(ctx context.Context, r *runtime.ListContainersRequest) (*runtime.ListContainersResponse, error) {
|
||||
func (c *criService) ListContainers(ctx context.Context, r *runtime.ListContainersRequest) (*runtime.ListContainersResponse, error) {
|
||||
// List all containers from store.
|
||||
containersInStore := c.containerStore.List()
|
||||
|
||||
@@ -54,7 +54,7 @@ func toCRIContainer(container containerstore.Container) *runtime.Container {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *criContainerdService) normalizeContainerFilter(filter *runtime.ContainerFilter) {
|
||||
func (c *criService) normalizeContainerFilter(filter *runtime.ContainerFilter) {
|
||||
if cntr, err := c.containerStore.Get(filter.GetId()); err == nil {
|
||||
filter.Id = cntr.ID
|
||||
}
|
||||
@@ -64,7 +64,7 @@ func (c *criContainerdService) normalizeContainerFilter(filter *runtime.Containe
|
||||
}
|
||||
|
||||
// filterCRIContainers filters CRIContainers.
|
||||
func (c *criContainerdService) filterCRIContainers(containers []*runtime.Container, filter *runtime.ContainerFilter) []*runtime.Container {
|
||||
func (c *criService) filterCRIContainers(containers []*runtime.Container, filter *runtime.ContainerFilter) []*runtime.Container {
|
||||
if filter == nil {
|
||||
return containers
|
||||
}
|
||||
|
||||
8
vendor/github.com/containerd/cri/pkg/server/container_log_reopen.go
generated
vendored
8
vendor/github.com/containerd/cri/pkg/server/container_log_reopen.go
generated
vendored
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -25,14 +25,14 @@ import (
|
||||
|
||||
// ReopenContainerLog asks the cri plugin to reopen the stdout/stderr log file for the container.
|
||||
// This is often called after the log file has been rotated.
|
||||
func (c *criContainerdService) ReopenContainerLog(ctx context.Context, r *runtime.ReopenContainerLogRequest) (*runtime.ReopenContainerLogResponse, error) {
|
||||
func (c *criService) ReopenContainerLog(ctx context.Context, r *runtime.ReopenContainerLogRequest) (*runtime.ReopenContainerLogResponse, error) {
|
||||
container, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find container %q: %v", r.GetContainerId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find container %q", r.GetContainerId())
|
||||
}
|
||||
|
||||
if container.Status.Get().State() != runtime.ContainerState_CONTAINER_RUNNING {
|
||||
return nil, fmt.Errorf("container is not running")
|
||||
return nil, errors.New("container is not running")
|
||||
}
|
||||
|
||||
// Create new container logger and replace the existing ones.
|
||||
|
||||
28
vendor/github.com/containerd/cri/pkg/server/container_remove.go
generated
vendored
28
vendor/github.com/containerd/cri/pkg/server/container_remove.go
generated
vendored
@@ -17,11 +17,10 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -33,11 +32,11 @@ import (
|
||||
|
||||
// RemoveContainer removes the container.
|
||||
// TODO(random-liu): Forcibly stop container if it's running.
|
||||
func (c *criContainerdService) RemoveContainer(ctx context.Context, r *runtime.RemoveContainerRequest) (_ *runtime.RemoveContainerResponse, retErr error) {
|
||||
func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveContainerRequest) (_ *runtime.RemoveContainerResponse, retErr error) {
|
||||
container, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
if err != store.ErrNotExist {
|
||||
return nil, fmt.Errorf("an error occurred when try to find container %q: %v", r.GetContainerId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find container %q", r.GetContainerId())
|
||||
}
|
||||
// Do not return error if container metadata doesn't exist.
|
||||
log.Tracef("RemoveContainer called for container %q that does not exist", r.GetContainerId())
|
||||
@@ -48,7 +47,7 @@ func (c *criContainerdService) RemoveContainer(ctx context.Context, r *runtime.R
|
||||
// Set removing state to prevent other start/remove operations against this container
|
||||
// while it's being removed.
|
||||
if err := setContainerRemoving(container); err != nil {
|
||||
return nil, fmt.Errorf("failed to set removing state for container %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to set removing state for container %q", id)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -67,20 +66,25 @@ func (c *criContainerdService) RemoveContainer(ctx context.Context, r *runtime.R
|
||||
// Delete containerd container.
|
||||
if err := container.Container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to delete containerd container %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to delete containerd container %q", id)
|
||||
}
|
||||
log.Tracef("Remove called for containerd container %q that does not exist", id)
|
||||
}
|
||||
|
||||
// Delete container checkpoint.
|
||||
if err := container.Delete(); err != nil {
|
||||
return nil, fmt.Errorf("failed to delete container checkpoint for %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to delete container checkpoint for %q", id)
|
||||
}
|
||||
|
||||
containerRootDir := getContainerRootDir(c.config.RootDir, id)
|
||||
containerRootDir := c.getContainerRootDir(id)
|
||||
if err := system.EnsureRemoveAll(containerRootDir); err != nil {
|
||||
return nil, fmt.Errorf("failed to remove container root directory %q: %v",
|
||||
containerRootDir, err)
|
||||
return nil, errors.Wrapf(err, "failed to remove container root directory %q",
|
||||
containerRootDir)
|
||||
}
|
||||
volatileContainerRootDir := c.getVolatileContainerRootDir(id)
|
||||
if err := system.EnsureRemoveAll(volatileContainerRootDir); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to remove volatile container root directory %q",
|
||||
volatileContainerRootDir)
|
||||
}
|
||||
|
||||
c.containerStore.Delete(id)
|
||||
@@ -96,10 +100,10 @@ func setContainerRemoving(container containerstore.Container) error {
|
||||
return container.Status.Update(func(status containerstore.Status) (containerstore.Status, error) {
|
||||
// Do not remove container if it's still running.
|
||||
if status.State() == runtime.ContainerState_CONTAINER_RUNNING {
|
||||
return status, fmt.Errorf("container is still running")
|
||||
return status, errors.New("container is still running")
|
||||
}
|
||||
if status.Removing {
|
||||
return status, fmt.Errorf("container is already in removing state")
|
||||
return status, errors.New("container is already in removing state")
|
||||
}
|
||||
status.Removing = true
|
||||
return status, nil
|
||||
|
||||
28
vendor/github.com/containerd/cri/pkg/server/container_start.go
generated
vendored
28
vendor/github.com/containerd/cri/pkg/server/container_start.go
generated
vendored
@@ -17,13 +17,13 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
containerdio "github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -35,10 +35,10 @@ import (
|
||||
)
|
||||
|
||||
// StartContainer starts the container.
|
||||
func (c *criContainerdService) StartContainer(ctx context.Context, r *runtime.StartContainerRequest) (retRes *runtime.StartContainerResponse, retErr error) {
|
||||
func (c *criService) StartContainer(ctx context.Context, r *runtime.StartContainerRequest) (retRes *runtime.StartContainerResponse, retErr error) {
|
||||
container, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find container %q: %v", r.GetContainerId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find container %q", r.GetContainerId())
|
||||
}
|
||||
|
||||
var startErr error
|
||||
@@ -51,14 +51,14 @@ func (c *criContainerdService) StartContainer(ctx context.Context, r *runtime.St
|
||||
}); startErr != nil {
|
||||
return nil, startErr
|
||||
} else if err != nil {
|
||||
return nil, fmt.Errorf("failed to update container %q metadata: %v", container.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to update container %q metadata", container.ID)
|
||||
}
|
||||
return &runtime.StartContainerResponse{}, nil
|
||||
}
|
||||
|
||||
// startContainer actually starts the container. The function needs to be run in one transaction. Any updates
|
||||
// to the status passed in will be applied no matter the function returns error or not.
|
||||
func (c *criContainerdService) startContainer(ctx context.Context,
|
||||
func (c *criService) startContainer(ctx context.Context,
|
||||
cntr containerstore.Container,
|
||||
status *containerstore.Status) (retErr error) {
|
||||
id := cntr.ID
|
||||
@@ -68,11 +68,11 @@ func (c *criContainerdService) startContainer(ctx context.Context,
|
||||
|
||||
// Return error if container is not in created state.
|
||||
if status.State() != runtime.ContainerState_CONTAINER_CREATED {
|
||||
return fmt.Errorf("container %q is in %s state", id, criContainerStateToString(status.State()))
|
||||
return errors.Errorf("container %q is in %s state", id, criContainerStateToString(status.State()))
|
||||
}
|
||||
// Do not start the container when there is a removal in progress.
|
||||
if status.Removing {
|
||||
return fmt.Errorf("container %q is in removing state", id)
|
||||
return errors.Errorf("container %q is in removing state", id)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
@@ -89,17 +89,17 @@ func (c *criContainerdService) startContainer(ctx context.Context,
|
||||
// Get sandbox config from sandbox store.
|
||||
sandbox, err := c.sandboxStore.Get(meta.SandboxID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("sandbox %q not found: %v", meta.SandboxID, err)
|
||||
return errors.Wrapf(err, "sandbox %q not found", meta.SandboxID)
|
||||
}
|
||||
sandboxID := meta.SandboxID
|
||||
if sandbox.Status.Get().State != sandboxstore.StateReady {
|
||||
return fmt.Errorf("sandbox container %q is not running", sandboxID)
|
||||
return errors.Errorf("sandbox container %q is not running", sandboxID)
|
||||
}
|
||||
|
||||
ioCreation := func(id string) (_ containerdio.IO, err error) {
|
||||
stdoutWC, stderrWC, err := createContainerLoggers(meta.LogPath, config.GetTty())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create container loggers: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to create container loggers")
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@@ -118,7 +118,7 @@ func (c *criContainerdService) startContainer(ctx context.Context,
|
||||
|
||||
task, err := container.NewTask(ctx, ioCreation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create containerd task: %v", err)
|
||||
return errors.Wrap(err, "failed to create containerd task")
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -133,7 +133,7 @@ func (c *criContainerdService) startContainer(ctx context.Context,
|
||||
|
||||
// Start containerd task.
|
||||
if err := task.Start(ctx); err != nil {
|
||||
return fmt.Errorf("failed to start containerd task %q: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to start containerd task %q", id)
|
||||
}
|
||||
|
||||
// Update container start timestamp.
|
||||
@@ -147,7 +147,7 @@ func createContainerLoggers(logPath string, tty bool) (stdout io.WriteCloser, st
|
||||
if logPath != "" {
|
||||
// Only generate container log when log path is specified.
|
||||
if stdout, err = cio.NewCRILogger(logPath, cio.Stdout); err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to start container stdout logger: %v", err)
|
||||
return nil, nil, errors.Wrap(err, "failed to start container stdout logger")
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@@ -157,7 +157,7 @@ func createContainerLoggers(logPath string, tty bool) (stdout io.WriteCloser, st
|
||||
// Only redirect stderr when there is no tty.
|
||||
if !tty {
|
||||
if stderr, err = cio.NewCRILogger(logPath, cio.Stderr); err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to start container stderr logger: %v", err)
|
||||
return nil, nil, errors.Wrap(err, "failed to start container stderr logger")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
13
vendor/github.com/containerd/cri/pkg/server/container_stats.go
generated
vendored
13
vendor/github.com/containerd/cri/pkg/server/container_stats.go
generated
vendored
@@ -17,32 +17,31 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
tasks "github.com/containerd/containerd/api/services/tasks/v1"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
// ContainerStats returns stats of the container. If the container does not
|
||||
// exist, the call returns an error.
|
||||
func (c *criContainerdService) ContainerStats(ctx context.Context, in *runtime.ContainerStatsRequest) (*runtime.ContainerStatsResponse, error) {
|
||||
func (c *criService) ContainerStats(ctx context.Context, in *runtime.ContainerStatsRequest) (*runtime.ContainerStatsResponse, error) {
|
||||
cntr, err := c.containerStore.Get(in.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find container: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to find container")
|
||||
}
|
||||
request := &tasks.MetricsRequest{Filters: []string{"id==" + cntr.ID}}
|
||||
resp, err := c.client.TaskService().Metrics(ctx, request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch metrics for task: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to fetch metrics for task")
|
||||
}
|
||||
if len(resp.Metrics) != 1 {
|
||||
return nil, fmt.Errorf("unexpected metrics response: %+v", resp.Metrics)
|
||||
return nil, errors.Errorf("unexpected metrics response: %+v", resp.Metrics)
|
||||
}
|
||||
|
||||
cs, err := c.getContainerMetrics(cntr.Metadata, resp.Metrics[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode container metrics: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to decode container metrics")
|
||||
}
|
||||
return &runtime.ContainerStatsResponse{Stats: cs}, nil
|
||||
}
|
||||
|
||||
23
vendor/github.com/containerd/cri/pkg/server/container_stats_list.go
generated
vendored
23
vendor/github.com/containerd/cri/pkg/server/container_stats_list.go
generated
vendored
@@ -17,12 +17,11 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/cgroups"
|
||||
tasks "github.com/containerd/containerd/api/services/tasks/v1"
|
||||
"github.com/containerd/containerd/api/types"
|
||||
"github.com/containerd/typeurl"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
@@ -30,26 +29,26 @@ import (
|
||||
)
|
||||
|
||||
// ListContainerStats returns stats of all running containers.
|
||||
func (c *criContainerdService) ListContainerStats(
|
||||
func (c *criService) ListContainerStats(
|
||||
ctx context.Context,
|
||||
in *runtime.ListContainerStatsRequest,
|
||||
) (*runtime.ListContainerStatsResponse, error) {
|
||||
request, containers, err := c.buildTaskMetricsRequest(in)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to build metrics request: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to build metrics request")
|
||||
}
|
||||
resp, err := c.client.TaskService().Metrics(ctx, &request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch metrics for tasks: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to fetch metrics for tasks")
|
||||
}
|
||||
criStats, err := c.toCRIContainerStats(resp.Metrics, containers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert to cri containerd stats format: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to convert to cri containerd stats format")
|
||||
}
|
||||
return criStats, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) toCRIContainerStats(
|
||||
func (c *criService) toCRIContainerStats(
|
||||
stats []*types.Metric,
|
||||
containers []containerstore.Container,
|
||||
) (*runtime.ListContainerStatsResponse, error) {
|
||||
@@ -61,14 +60,14 @@ func (c *criContainerdService) toCRIContainerStats(
|
||||
for _, cntr := range containers {
|
||||
cs, err := c.getContainerMetrics(cntr.Metadata, statsMap[cntr.ID])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode container metrics for %q: %v", cntr.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to decode container metrics for %q", cntr.ID)
|
||||
}
|
||||
containerStats.Stats = append(containerStats.Stats, cs)
|
||||
}
|
||||
return containerStats, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) getContainerMetrics(
|
||||
func (c *criService) getContainerMetrics(
|
||||
meta containerstore.Metadata,
|
||||
stats *types.Metric,
|
||||
) (*runtime.ContainerStats, error) {
|
||||
@@ -99,7 +98,7 @@ func (c *criContainerdService) getContainerMetrics(
|
||||
if stats != nil {
|
||||
s, err := typeurl.UnmarshalAny(stats.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract container metrics: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to extract container metrics")
|
||||
}
|
||||
metrics := s.(*cgroups.Metrics)
|
||||
if metrics.CPU != nil && metrics.CPU.Usage != nil {
|
||||
@@ -119,7 +118,7 @@ func (c *criContainerdService) getContainerMetrics(
|
||||
return &cs, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) normalizeContainerStatsFilter(filter *runtime.ContainerStatsFilter) {
|
||||
func (c *criService) normalizeContainerStatsFilter(filter *runtime.ContainerStatsFilter) {
|
||||
if cntr, err := c.containerStore.Get(filter.GetId()); err == nil {
|
||||
filter.Id = cntr.ID
|
||||
}
|
||||
@@ -130,7 +129,7 @@ func (c *criContainerdService) normalizeContainerStatsFilter(filter *runtime.Con
|
||||
|
||||
// buildTaskMetricsRequest constructs a tasks.MetricsRequest based on
|
||||
// the information in the stats request and the containerStore
|
||||
func (c *criContainerdService) buildTaskMetricsRequest(
|
||||
func (c *criService) buildTaskMetricsRequest(
|
||||
r *runtime.ListContainerStatsRequest,
|
||||
) (tasks.MetricsRequest, []containerstore.Container, error) {
|
||||
var req tasks.MetricsRequest
|
||||
|
||||
39
vendor/github.com/containerd/cri/pkg/server/container_status.go
generated
vendored
39
vendor/github.com/containerd/cri/pkg/server/container_status.go
generated
vendored
@@ -18,21 +18,21 @@ package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
criconfig "github.com/containerd/cri/pkg/config"
|
||||
containerstore "github.com/containerd/cri/pkg/store/container"
|
||||
)
|
||||
|
||||
// ContainerStatus inspects the container and returns the status.
|
||||
func (c *criContainerdService) ContainerStatus(ctx context.Context, r *runtime.ContainerStatusRequest) (*runtime.ContainerStatusResponse, error) {
|
||||
func (c *criService) ContainerStatus(ctx context.Context, r *runtime.ContainerStatusRequest) (*runtime.ContainerStatusResponse, error) {
|
||||
container, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find container %q: %v", r.GetContainerId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find container %q", r.GetContainerId())
|
||||
}
|
||||
|
||||
// TODO(random-liu): Clean up the following logic in CRI.
|
||||
@@ -44,7 +44,7 @@ func (c *criContainerdService) ContainerStatus(ctx context.Context, r *runtime.C
|
||||
imageRef := container.ImageRef
|
||||
image, err := c.imageStore.Get(imageRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image %q: %v", imageRef, err)
|
||||
return nil, errors.Wrapf(err, "failed to get image %q", imageRef)
|
||||
}
|
||||
if len(image.RepoTags) > 0 {
|
||||
// Based on current behavior of dockershim, this field should be
|
||||
@@ -58,7 +58,7 @@ func (c *criContainerdService) ContainerStatus(ctx context.Context, r *runtime.C
|
||||
status := toCRIContainerStatus(container, spec, imageRef)
|
||||
info, err := toCRIContainerInfo(ctx, container, r.GetVerbose())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get verbose container info: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get verbose container info")
|
||||
}
|
||||
|
||||
return &runtime.ContainerStatusResponse{
|
||||
@@ -106,6 +106,7 @@ type containerInfo struct {
|
||||
Removing bool `json:"removing"`
|
||||
SnapshotKey string `json:"snapshotKey"`
|
||||
Snapshotter string `json:"snapshotter"`
|
||||
Runtime *criconfig.Runtime `json:"runtime"`
|
||||
Config *runtime.ContainerConfig `json:"config"`
|
||||
RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"`
|
||||
}
|
||||
@@ -128,24 +129,28 @@ func toCRIContainerInfo(ctx context.Context, container containerstore.Container,
|
||||
Config: meta.Config,
|
||||
}
|
||||
|
||||
spec, err := container.Container.Spec(ctx)
|
||||
if err == nil {
|
||||
ci.RuntimeSpec = spec
|
||||
} else {
|
||||
logrus.WithError(err).Errorf("Failed to get container %q spec", container.ID)
|
||||
var err error
|
||||
ci.RuntimeSpec, err = container.Container.Spec(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get container runtime spec")
|
||||
}
|
||||
|
||||
ctrInfo, err := container.Container.Info(ctx)
|
||||
if err == nil {
|
||||
ci.SnapshotKey = ctrInfo.SnapshotKey
|
||||
ci.Snapshotter = ctrInfo.Snapshotter
|
||||
} else {
|
||||
logrus.WithError(err).Errorf("Failed to get container %q info", container.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get container info")
|
||||
}
|
||||
ci.SnapshotKey = ctrInfo.SnapshotKey
|
||||
ci.Snapshotter = ctrInfo.Snapshotter
|
||||
|
||||
ociRuntime, err := getRuntimeConfigFromContainerInfo(ctrInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get container runtime config")
|
||||
}
|
||||
ci.Runtime = &ociRuntime
|
||||
|
||||
infoBytes, err := json.Marshal(ci)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal info %v: %v", ci, err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal info %v", ci)
|
||||
}
|
||||
return map[string]string{
|
||||
"info": string(infoBytes),
|
||||
|
||||
30
vendor/github.com/containerd/cri/pkg/server/container_stop.go
generated
vendored
30
vendor/github.com/containerd/cri/pkg/server/container_stop.go
generated
vendored
@@ -17,12 +17,12 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -36,11 +36,11 @@ import (
|
||||
const killContainerTimeout = 2 * time.Minute
|
||||
|
||||
// StopContainer stops a running container with a grace period (i.e., timeout).
|
||||
func (c *criContainerdService) StopContainer(ctx context.Context, r *runtime.StopContainerRequest) (*runtime.StopContainerResponse, error) {
|
||||
func (c *criService) StopContainer(ctx context.Context, r *runtime.StopContainerRequest) (*runtime.StopContainerResponse, error) {
|
||||
// Get container config from container store.
|
||||
container, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find container %q: %v", r.GetContainerId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find container %q", r.GetContainerId())
|
||||
}
|
||||
|
||||
if err := c.stopContainer(ctx, container, time.Duration(r.GetTimeout())*time.Second); err != nil {
|
||||
@@ -51,7 +51,7 @@ func (c *criContainerdService) StopContainer(ctx context.Context, r *runtime.Sto
|
||||
}
|
||||
|
||||
// stopContainer stops a container based on the container metadata.
|
||||
func (c *criContainerdService) stopContainer(ctx context.Context, container containerstore.Container, timeout time.Duration) error {
|
||||
func (c *criService) stopContainer(ctx context.Context, container containerstore.Container, timeout time.Duration) error {
|
||||
id := container.ID
|
||||
|
||||
// Return without error if container is not running. This makes sure that
|
||||
@@ -71,27 +71,27 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
|
||||
// deleted and image is garbage collected before this point. However,
|
||||
// the chance is really slim, even it happens, it's still fine to return
|
||||
// an error here.
|
||||
return fmt.Errorf("failed to get image metadata %q: %v", container.ImageRef, err)
|
||||
return errors.Wrapf(err, "failed to get image metadata %q", container.ImageRef)
|
||||
}
|
||||
if image.ImageSpec.Config.StopSignal != "" {
|
||||
stopSignal, err = signal.ParseSignal(image.ImageSpec.Config.StopSignal)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse stop signal %q: %v",
|
||||
image.ImageSpec.Config.StopSignal, err)
|
||||
return errors.Wrapf(err, "failed to parse stop signal %q",
|
||||
image.ImageSpec.Config.StopSignal)
|
||||
}
|
||||
}
|
||||
logrus.Infof("Stop container %q with signal %v", id, stopSignal)
|
||||
task, err := container.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to stop container, task not found for container %q: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to stop container, task not found for container %q", id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if task != nil {
|
||||
if err = task.Kill(ctx, stopSignal); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to stop container %q: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to stop container %q", id)
|
||||
}
|
||||
// Move on to make sure container status is updated.
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
|
||||
task, err := container.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to stop container, task not found for container %q: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to stop container, task not found for container %q", id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
|
||||
if task != nil {
|
||||
if err = task.Kill(ctx, unix.SIGKILL, containerd.WithKillAll); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to kill container %q: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to kill container %q", id)
|
||||
}
|
||||
// Move on to make sure container status is updated.
|
||||
}
|
||||
@@ -124,20 +124,20 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
|
||||
|
||||
// Wait for a fixed timeout until container stop is observed by event monitor.
|
||||
if err := c.waitContainerStop(ctx, container, killContainerTimeout); err != nil {
|
||||
return fmt.Errorf("an error occurs during waiting for container %q to stop: %v", id, err)
|
||||
return errors.Wrapf(err, "an error occurs during waiting for container %q to stop", id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// waitContainerStop waits for container to be stopped until timeout exceeds or context is cancelled.
|
||||
func (c *criContainerdService) waitContainerStop(ctx context.Context, container containerstore.Container, timeout time.Duration) error {
|
||||
func (c *criService) waitContainerStop(ctx context.Context, container containerstore.Container, timeout time.Duration) error {
|
||||
timeoutTimer := time.NewTimer(timeout)
|
||||
defer timeoutTimer.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("wait container %q is cancelled", container.ID)
|
||||
return errors.Errorf("wait container %q is cancelled", container.ID)
|
||||
case <-timeoutTimer.C:
|
||||
return fmt.Errorf("wait container %q stop timeout", container.ID)
|
||||
return errors.Errorf("wait container %q stop timeout", container.ID)
|
||||
case <-container.Stopped():
|
||||
return nil
|
||||
}
|
||||
|
||||
26
vendor/github.com/containerd/cri/pkg/server/container_update_resources.go
generated
vendored
26
vendor/github.com/containerd/cri/pkg/server/container_update_resources.go
generated
vendored
@@ -18,13 +18,13 @@ package server
|
||||
|
||||
import (
|
||||
gocontext "context"
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/typeurl"
|
||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -35,10 +35,10 @@ import (
|
||||
)
|
||||
|
||||
// UpdateContainerResources updates ContainerConfig of the container.
|
||||
func (c *criContainerdService) UpdateContainerResources(ctx context.Context, r *runtime.UpdateContainerResourcesRequest) (retRes *runtime.UpdateContainerResourcesResponse, retErr error) {
|
||||
func (c *criService) UpdateContainerResources(ctx context.Context, r *runtime.UpdateContainerResourcesRequest) (retRes *runtime.UpdateContainerResourcesResponse, retErr error) {
|
||||
container, err := c.containerStore.Get(r.GetContainerId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find container: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to find container")
|
||||
}
|
||||
// Update resources in status update transaction, so that:
|
||||
// 1) There won't be race condition with container start.
|
||||
@@ -46,19 +46,19 @@ func (c *criContainerdService) UpdateContainerResources(ctx context.Context, r *
|
||||
if err := container.Status.Update(func(status containerstore.Status) (containerstore.Status, error) {
|
||||
return status, c.updateContainerResources(ctx, container, r.GetLinux(), status)
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to update resources: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to update resources")
|
||||
}
|
||||
return &runtime.UpdateContainerResourcesResponse{}, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
func (c *criService) updateContainerResources(ctx context.Context,
|
||||
cntr containerstore.Container,
|
||||
resources *runtime.LinuxContainerResources,
|
||||
status containerstore.Status) (retErr error) {
|
||||
id := cntr.ID
|
||||
// Do not update the container when there is a removal in progress.
|
||||
if status.Removing {
|
||||
return fmt.Errorf("container %q is in removing state", id)
|
||||
return errors.Errorf("container %q is in removing state", id)
|
||||
}
|
||||
|
||||
// Update container spec. If the container is not started yet, updating
|
||||
@@ -67,11 +67,11 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
// the spec will become our source of truth for resource limits.
|
||||
oldSpec, err := cntr.Container.Spec(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get container spec: %v", err)
|
||||
return errors.Wrap(err, "failed to get container spec")
|
||||
}
|
||||
newSpec, err := updateOCILinuxResource(oldSpec, resources)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update resource in spec: %v", err)
|
||||
return errors.Wrap(err, "failed to update resource in spec")
|
||||
}
|
||||
|
||||
if err := updateContainerSpec(ctx, cntr.Container, newSpec); err != nil {
|
||||
@@ -100,7 +100,7 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
// Task exited already.
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to get task: %v", err)
|
||||
return errors.Wrap(err, "failed to get task")
|
||||
}
|
||||
// newSpec.Linux won't be nil
|
||||
if err := task.Update(ctx, containerd.WithResources(newSpec.Linux.Resources)); err != nil {
|
||||
@@ -108,7 +108,7 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
// Task exited already.
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to update resources: %v", err)
|
||||
return errors.Wrap(err, "failed to update resources")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -117,13 +117,13 @@ func (c *criContainerdService) updateContainerResources(ctx context.Context,
|
||||
func updateContainerSpec(ctx context.Context, cntr containerd.Container, spec *runtimespec.Spec) error {
|
||||
any, err := typeurl.MarshalAny(spec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal spec %+v: %v", spec, err)
|
||||
return errors.Wrapf(err, "failed to marshal spec %+v", spec)
|
||||
}
|
||||
if err := cntr.Update(ctx, func(ctx gocontext.Context, client *containerd.Client, c *containers.Container) error {
|
||||
c.Spec = any
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to update container spec: %v", err)
|
||||
return errors.Wrap(err, "failed to update container spec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -133,7 +133,7 @@ func updateOCILinuxResource(spec *runtimespec.Spec, new *runtime.LinuxContainerR
|
||||
// Copy to make sure old spec is not changed.
|
||||
var cloned runtimespec.Spec
|
||||
if err := util.DeepCopy(&cloned, spec); err != nil {
|
||||
return nil, fmt.Errorf("failed to deep copy: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to deep copy")
|
||||
}
|
||||
g := newSpecGenerator(&cloned)
|
||||
|
||||
|
||||
228
vendor/github.com/containerd/cri/pkg/server/events.go
generated
vendored
228
vendor/github.com/containerd/cri/pkg/server/events.go
generated
vendored
@@ -17,15 +17,18 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
eventtypes "github.com/containerd/containerd/api/events"
|
||||
containerdio "github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/typeurl"
|
||||
gogotypes "github.com/gogo/protobuf/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
"github.com/containerd/cri/pkg/store"
|
||||
@@ -33,6 +36,12 @@ import (
|
||||
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
|
||||
)
|
||||
|
||||
const (
|
||||
backOffInitDuration = 1 * time.Second
|
||||
backOffMaxDuration = 5 * time.Minute
|
||||
backOffExpireCheckDuration = 1 * time.Second
|
||||
)
|
||||
|
||||
// eventMonitor monitors containerd event and updates internal state correspondingly.
|
||||
// TODO(random-liu): [P1] Figure out is it possible to drop event during containerd
|
||||
// is running. If it is, we should do periodically list to sync state with containerd.
|
||||
@@ -43,6 +52,23 @@ type eventMonitor struct {
|
||||
errCh <-chan error
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
backOff *backOff
|
||||
}
|
||||
|
||||
type backOff struct {
|
||||
queuePool map[string]*backOffQueue
|
||||
ticker *time.Ticker
|
||||
minDuration time.Duration
|
||||
maxDuration time.Duration
|
||||
checkDuration time.Duration
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
type backOffQueue struct {
|
||||
events []interface{}
|
||||
expireTime time.Time
|
||||
duration time.Duration
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
// Create new event monitor. New event monitor will start subscribing containerd event. All events
|
||||
@@ -55,6 +81,7 @@ func newEventMonitor(c *containerstore.Store, s *sandboxstore.Store) *eventMonit
|
||||
sandboxStore: s,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
backOff: newBackOff(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +94,24 @@ func (em *eventMonitor) subscribe(subscriber events.Subscriber) {
|
||||
em.ch, em.errCh = subscriber.Subscribe(em.ctx, filters...)
|
||||
}
|
||||
|
||||
func convertEvent(e *gogotypes.Any) (string, interface{}, error) {
|
||||
containerID := ""
|
||||
evt, err := typeurl.UnmarshalAny(e)
|
||||
if err != nil {
|
||||
return "", nil, errors.Wrap(err, "failed to unmarshalany")
|
||||
}
|
||||
|
||||
switch evt.(type) {
|
||||
case *eventtypes.TaskExit:
|
||||
containerID = evt.(*eventtypes.TaskExit).ContainerID
|
||||
case *eventtypes.TaskOOM:
|
||||
containerID = evt.(*eventtypes.TaskOOM).ContainerID
|
||||
default:
|
||||
return "", nil, errors.New("unsupported event")
|
||||
}
|
||||
return containerID, evt, nil
|
||||
}
|
||||
|
||||
// start starts the event monitor which monitors and handles all container events. It returns
|
||||
// a channel for the caller to wait for the event monitor to stop. start must be called after
|
||||
// subscribe.
|
||||
@@ -76,15 +121,41 @@ func (em *eventMonitor) start() (<-chan struct{}, error) {
|
||||
}
|
||||
closeCh := make(chan struct{})
|
||||
go func() {
|
||||
backOffCheckCh := em.backOff.start()
|
||||
for {
|
||||
select {
|
||||
case e := <-em.ch:
|
||||
logrus.Debugf("Received containerd event timestamp - %v, namespace - %q, topic - %q", e.Timestamp, e.Namespace, e.Topic)
|
||||
em.handleEvent(e)
|
||||
cID, evt, err := convertEvent(e.Event)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to convert event %+v", e)
|
||||
break
|
||||
}
|
||||
if em.backOff.isInBackOff(cID) {
|
||||
logrus.Infof("Events for container %q is in backoff, enqueue event %+v", cID, evt)
|
||||
em.backOff.enBackOff(cID, evt)
|
||||
break
|
||||
}
|
||||
if err := em.handleEvent(evt); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to handle event %+v for container %s", evt, cID)
|
||||
em.backOff.enBackOff(cID, evt)
|
||||
}
|
||||
case err := <-em.errCh:
|
||||
logrus.WithError(err).Error("Failed to handle event stream")
|
||||
close(closeCh)
|
||||
return
|
||||
case <-backOffCheckCh:
|
||||
cIDs := em.backOff.getExpiredContainers()
|
||||
for _, cID := range cIDs {
|
||||
queue := em.backOff.deBackOff(cID)
|
||||
for i, any := range queue.events {
|
||||
if err := em.handleEvent(any); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to handle backOff event %+v for container %s", any, cID)
|
||||
em.backOff.reBackOff(cID, queue.events[i:], queue.duration)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -94,17 +165,13 @@ func (em *eventMonitor) start() (<-chan struct{}, error) {
|
||||
// stop stops the event monitor. It will close the event channel.
|
||||
// Once event monitor is stopped, it can't be started.
|
||||
func (em *eventMonitor) stop() {
|
||||
em.backOff.stop()
|
||||
em.cancel()
|
||||
}
|
||||
|
||||
// handleEvent handles a containerd event.
|
||||
func (em *eventMonitor) handleEvent(evt *events.Envelope) {
|
||||
func (em *eventMonitor) handleEvent(any interface{}) error {
|
||||
ctx := ctrdutil.NamespacedContext()
|
||||
any, err := typeurl.UnmarshalAny(evt.Event)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to convert event envelope %+v", evt)
|
||||
return
|
||||
}
|
||||
switch any.(type) {
|
||||
// If containerd-shim exits unexpectedly, there will be no corresponding event.
|
||||
// However, containerd could not retrieve container state in that case, so it's
|
||||
@@ -112,51 +179,59 @@ func (em *eventMonitor) handleEvent(evt *events.Envelope) {
|
||||
// TODO(random-liu): [P2] Handle containerd-shim exit.
|
||||
case *eventtypes.TaskExit:
|
||||
e := any.(*eventtypes.TaskExit)
|
||||
logrus.Infof("TaskExit event %+v", e)
|
||||
cntr, err := em.containerStore.Get(e.ContainerID)
|
||||
if err == nil {
|
||||
handleContainerExit(ctx, e, cntr)
|
||||
return
|
||||
if err := handleContainerExit(ctx, e, cntr); err != nil {
|
||||
return errors.Wrap(err, "failed to handle container TaskExit event")
|
||||
}
|
||||
return nil
|
||||
} else if err != store.ErrNotExist {
|
||||
logrus.WithError(err).Errorf("Failed to get container %q", e.ContainerID)
|
||||
return
|
||||
return errors.Wrap(err, "can't find container for TaskExit event")
|
||||
}
|
||||
// Use GetAll to include sandbox in unknown state.
|
||||
sb, err := em.sandboxStore.GetAll(e.ContainerID)
|
||||
if err == nil {
|
||||
handleSandboxExit(ctx, e, sb)
|
||||
return
|
||||
if err := handleSandboxExit(ctx, e, sb); err != nil {
|
||||
return errors.Wrap(err, "failed to handle sandbox TaskExit event")
|
||||
}
|
||||
return nil
|
||||
} else if err != store.ErrNotExist {
|
||||
logrus.WithError(err).Errorf("Failed to get sandbox %q", e.ContainerID)
|
||||
return
|
||||
return errors.Wrap(err, "can't find sandbox for TaskExit event")
|
||||
}
|
||||
return nil
|
||||
case *eventtypes.TaskOOM:
|
||||
e := any.(*eventtypes.TaskOOM)
|
||||
logrus.Infof("TaskOOM event %+v", e)
|
||||
cntr, err := em.containerStore.Get(e.ContainerID)
|
||||
if err != nil {
|
||||
if _, err := em.sandboxStore.Get(e.ContainerID); err == nil {
|
||||
return
|
||||
if err != store.ErrNotExist {
|
||||
return errors.Wrap(err, "can't find container for TaskOOM event")
|
||||
}
|
||||
logrus.WithError(err).Errorf("Failed to get container %q", e.ContainerID)
|
||||
return
|
||||
if _, err = em.sandboxStore.Get(e.ContainerID); err != nil {
|
||||
if err != store.ErrNotExist {
|
||||
return errors.Wrap(err, "can't find sandbox for TaskOOM event")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err = cntr.Status.UpdateSync(func(status containerstore.Status) (containerstore.Status, error) {
|
||||
status.Reason = oomExitReason
|
||||
return status, nil
|
||||
})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to update container %q oom", e.ContainerID)
|
||||
return
|
||||
return errors.Wrap(err, "failed to update container status for TaskOOM event")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleContainerExit handles TaskExit event for container.
|
||||
func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr containerstore.Container) {
|
||||
func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr containerstore.Container) error {
|
||||
if e.Pid != cntr.Status.Get().Pid {
|
||||
// Non-init process died, ignore the event.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
// Attach container IO so that `Delete` could cleanup the stream properly.
|
||||
task, err := cntr.Container.Task(ctx,
|
||||
@@ -166,16 +241,13 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta
|
||||
)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).Errorf("failed to load task for container %q", e.ContainerID)
|
||||
return
|
||||
return errors.Wrapf(err, "failed to load task for container")
|
||||
}
|
||||
} else {
|
||||
// TODO(random-liu): [P1] This may block the loop, we may want to spawn a worker
|
||||
if _, err = task.Delete(ctx); err != nil {
|
||||
// TODO(random-liu): [P0] Enqueue the event and retry.
|
||||
if !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).Errorf("failed to stop container %q", e.ContainerID)
|
||||
return
|
||||
return errors.Wrap(err, "failed to stop container")
|
||||
}
|
||||
// Move on to make sure container status is updated.
|
||||
}
|
||||
@@ -192,34 +264,30 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta
|
||||
return status, nil
|
||||
})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to update container %q state", e.ContainerID)
|
||||
// TODO(random-liu): [P0] Enqueue the event and retry.
|
||||
return
|
||||
return errors.Wrap(err, "failed to update container state")
|
||||
}
|
||||
// Using channel to propagate the information of container stop
|
||||
cntr.Stop()
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleSandboxExit handles TaskExit event for sandbox.
|
||||
func handleSandboxExit(ctx context.Context, e *eventtypes.TaskExit, sb sandboxstore.Sandbox) {
|
||||
func handleSandboxExit(ctx context.Context, e *eventtypes.TaskExit, sb sandboxstore.Sandbox) error {
|
||||
if e.Pid != sb.Status.Get().Pid {
|
||||
// Non-init process died, ignore the event.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
// No stream attached to sandbox container.
|
||||
task, err := sb.Container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).Errorf("failed to load task for sandbox %q", e.ContainerID)
|
||||
return
|
||||
return errors.Wrap(err, "failed to load task for sandbox")
|
||||
}
|
||||
} else {
|
||||
// TODO(random-liu): [P1] This may block the loop, we may want to spawn a worker
|
||||
if _, err = task.Delete(ctx); err != nil {
|
||||
// TODO(random-liu): [P0] Enqueue the event and retry.
|
||||
if !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).Errorf("failed to stop sandbox %q", e.ContainerID)
|
||||
return
|
||||
return errors.Wrap(err, "failed to stop sandbox")
|
||||
}
|
||||
// Move on to make sure container status is updated.
|
||||
}
|
||||
@@ -238,10 +306,84 @@ func handleSandboxExit(ctx context.Context, e *eventtypes.TaskExit, sb sandboxst
|
||||
return status, nil
|
||||
})
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to update sandbox %q state", e.ContainerID)
|
||||
// TODO(random-liu): [P0] Enqueue the event and retry.
|
||||
return
|
||||
return errors.Wrap(err, "failed to update sandbox state")
|
||||
}
|
||||
// Using channel to propagate the information of sandbox stop
|
||||
sb.Stop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func newBackOff() *backOff {
|
||||
return &backOff{
|
||||
queuePool: map[string]*backOffQueue{},
|
||||
minDuration: backOffInitDuration,
|
||||
maxDuration: backOffMaxDuration,
|
||||
checkDuration: backOffExpireCheckDuration,
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
}
|
||||
|
||||
func (b *backOff) getExpiredContainers() []string {
|
||||
var containers []string
|
||||
for c, q := range b.queuePool {
|
||||
if q.isExpire() {
|
||||
containers = append(containers, c)
|
||||
}
|
||||
}
|
||||
return containers
|
||||
}
|
||||
|
||||
func (b *backOff) isInBackOff(key string) bool {
|
||||
if _, ok := b.queuePool[key]; ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// enBackOff start to backOff and put event to the tail of queue
|
||||
func (b *backOff) enBackOff(key string, evt interface{}) {
|
||||
if queue, ok := b.queuePool[key]; ok {
|
||||
queue.events = append(queue.events, evt)
|
||||
return
|
||||
}
|
||||
b.queuePool[key] = newBackOffQueue([]interface{}{evt}, b.minDuration, b.clock)
|
||||
}
|
||||
|
||||
// enBackOff get out the whole queue
|
||||
func (b *backOff) deBackOff(key string) *backOffQueue {
|
||||
queue := b.queuePool[key]
|
||||
delete(b.queuePool, key)
|
||||
return queue
|
||||
}
|
||||
|
||||
// enBackOff start to backOff again and put events to the queue
|
||||
func (b *backOff) reBackOff(key string, events []interface{}, oldDuration time.Duration) {
|
||||
duration := 2 * oldDuration
|
||||
if duration > b.maxDuration {
|
||||
duration = b.maxDuration
|
||||
}
|
||||
b.queuePool[key] = newBackOffQueue(events, duration, b.clock)
|
||||
}
|
||||
|
||||
func (b *backOff) start() <-chan time.Time {
|
||||
b.ticker = time.NewTicker(b.checkDuration)
|
||||
return b.ticker.C
|
||||
}
|
||||
|
||||
func (b *backOff) stop() {
|
||||
b.ticker.Stop()
|
||||
}
|
||||
|
||||
func newBackOffQueue(events []interface{}, init time.Duration, c clock.Clock) *backOffQueue {
|
||||
return &backOffQueue{
|
||||
events: events,
|
||||
duration: init,
|
||||
expireTime: c.Now().Add(init),
|
||||
clock: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (q *backOffQueue) isExpire() bool {
|
||||
// return time.Now >= expireTime
|
||||
return !q.clock.Now().Before(q.expireTime)
|
||||
}
|
||||
|
||||
135
vendor/github.com/containerd/cri/pkg/server/helpers.go
generated
vendored
135
vendor/github.com/containerd/cri/pkg/server/helpers.go
generated
vendored
@@ -19,14 +19,16 @@ package server
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/linux/runctypes"
|
||||
"github.com/containerd/typeurl"
|
||||
"github.com/docker/distribution/reference"
|
||||
imagedigest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
@@ -35,10 +37,11 @@ import (
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/util/sysctl"
|
||||
|
||||
criconfig "github.com/containerd/cri/pkg/config"
|
||||
"github.com/containerd/cri/pkg/store"
|
||||
imagestore "github.com/containerd/cri/pkg/store/image"
|
||||
"github.com/containerd/cri/pkg/util"
|
||||
@@ -109,6 +112,14 @@ const (
|
||||
containerMetadataExtension = criContainerdPrefix + ".container.metadata"
|
||||
)
|
||||
|
||||
const (
|
||||
// defaultIfName is the default network interface for the pods
|
||||
defaultIfName = "eth0"
|
||||
// networkAttachCount is the minimum number of networks the PodSandbox
|
||||
// attaches to
|
||||
networkAttachCount = 2
|
||||
)
|
||||
|
||||
// makeSandboxName generates sandbox name from sandbox metadata. The name
|
||||
// generated is unique as long as sandbox metadata is unique.
|
||||
func makeSandboxName(s *runtime.PodSandboxMetadata) string {
|
||||
@@ -126,9 +137,9 @@ func makeSandboxName(s *runtime.PodSandboxMetadata) string {
|
||||
func makeContainerName(c *runtime.ContainerMetadata, s *runtime.PodSandboxMetadata) string {
|
||||
return strings.Join([]string{
|
||||
c.Name, // 0
|
||||
s.Name, // 1: sandbox name
|
||||
s.Namespace, // 2: sandbox namespace
|
||||
s.Uid, // 3: sandbox uid
|
||||
s.Name, // 1: pod name
|
||||
s.Namespace, // 2: pod namespace
|
||||
s.Uid, // 3: pod uid
|
||||
fmt.Sprintf("%d", c.Attempt), // 4
|
||||
}, nameDelimiter)
|
||||
}
|
||||
@@ -145,29 +156,42 @@ func getCgroupsPath(cgroupsParent, id string, systemdCgroup bool) string {
|
||||
}
|
||||
|
||||
// getSandboxRootDir returns the root directory for managing sandbox files,
|
||||
// e.g. named pipes.
|
||||
func getSandboxRootDir(rootDir, id string) string {
|
||||
return filepath.Join(rootDir, sandboxesDir, id)
|
||||
// e.g. hosts files.
|
||||
func (c *criService) getSandboxRootDir(id string) string {
|
||||
return filepath.Join(c.config.RootDir, sandboxesDir, id)
|
||||
}
|
||||
|
||||
// getContainerRootDir returns the root directory for managing container files.
|
||||
func getContainerRootDir(rootDir, id string) string {
|
||||
return filepath.Join(rootDir, containersDir, id)
|
||||
// getVolatileSandboxRootDir returns the root directory for managing volatile sandbox files,
|
||||
// e.g. named pipes.
|
||||
func (c *criService) getVolatileSandboxRootDir(id string) string {
|
||||
return filepath.Join(c.config.StateDir, sandboxesDir, id)
|
||||
}
|
||||
|
||||
// getContainerRootDir returns the root directory for managing container files,
|
||||
// e.g. state checkpoint.
|
||||
func (c *criService) getContainerRootDir(id string) string {
|
||||
return filepath.Join(c.config.RootDir, containersDir, id)
|
||||
}
|
||||
|
||||
// getVolatileContainerRootDir returns the root directory for managing volatile container files,
|
||||
// e.g. named pipes.
|
||||
func (c *criService) getVolatileContainerRootDir(id string) string {
|
||||
return filepath.Join(c.config.StateDir, containersDir, id)
|
||||
}
|
||||
|
||||
// getSandboxHosts returns the hosts file path inside the sandbox root directory.
|
||||
func getSandboxHosts(sandboxRootDir string) string {
|
||||
return filepath.Join(sandboxRootDir, "hosts")
|
||||
func (c *criService) getSandboxHosts(id string) string {
|
||||
return filepath.Join(c.getSandboxRootDir(id), "hosts")
|
||||
}
|
||||
|
||||
// getResolvPath returns resolv.conf filepath for specified sandbox.
|
||||
func getResolvPath(sandboxRoot string) string {
|
||||
return filepath.Join(sandboxRoot, "resolv.conf")
|
||||
func (c *criService) getResolvPath(id string) string {
|
||||
return filepath.Join(c.getSandboxRootDir(id), "resolv.conf")
|
||||
}
|
||||
|
||||
// getSandboxDevShm returns the shm file path inside the sandbox root directory.
|
||||
func getSandboxDevShm(sandboxRootDir string) string {
|
||||
return filepath.Join(sandboxRootDir, "shm")
|
||||
func (c *criService) getSandboxDevShm(id string) string {
|
||||
return filepath.Join(c.getVolatileSandboxRootDir(id), "shm")
|
||||
}
|
||||
|
||||
// getNetworkNamespace returns the network namespace of a process.
|
||||
@@ -212,7 +236,7 @@ func getRepoDigestAndTag(namedRef reference.Named, digest imagedigest.Digest, sc
|
||||
|
||||
// localResolve resolves image reference locally and returns corresponding image metadata. It returns
|
||||
// nil without error if the reference doesn't exist.
|
||||
func (c *criContainerdService) localResolve(ctx context.Context, refOrID string) (*imagestore.Image, error) {
|
||||
func (c *criService) localResolve(ctx context.Context, refOrID string) (*imagestore.Image, error) {
|
||||
getImageID := func(refOrId string) string {
|
||||
if _, err := imagedigest.Parse(refOrID); err == nil {
|
||||
return refOrID
|
||||
@@ -245,7 +269,7 @@ func (c *criContainerdService) localResolve(ctx context.Context, refOrID string)
|
||||
if err == store.ErrNotExist {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get image %q : %v", imageID, err)
|
||||
return nil, errors.Wrapf(err, "failed to get image %q", imageID)
|
||||
}
|
||||
return &image, nil
|
||||
}
|
||||
@@ -271,10 +295,10 @@ func getUserFromImage(user string) (*int64, string) {
|
||||
|
||||
// ensureImageExists returns corresponding metadata of the image reference, if image is not
|
||||
// pulled yet, the function will pull the image.
|
||||
func (c *criContainerdService) ensureImageExists(ctx context.Context, ref string) (*imagestore.Image, error) {
|
||||
func (c *criService) ensureImageExists(ctx context.Context, ref string) (*imagestore.Image, error) {
|
||||
image, err := c.localResolve(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve image %q: %v", ref, err)
|
||||
return nil, errors.Wrapf(err, "failed to resolve image %q", ref)
|
||||
}
|
||||
if image != nil {
|
||||
return image, nil
|
||||
@@ -282,13 +306,13 @@ func (c *criContainerdService) ensureImageExists(ctx context.Context, ref string
|
||||
// Pull image to ensure the image exists
|
||||
resp, err := c.PullImage(ctx, &runtime.PullImageRequest{Image: &runtime.ImageSpec{Image: ref}})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to pull image %q: %v", ref, err)
|
||||
return nil, errors.Wrapf(err, "failed to pull image %q", ref)
|
||||
}
|
||||
imageID := resp.GetImageRef()
|
||||
newImage, err := c.imageStore.Get(imageID)
|
||||
if err != nil {
|
||||
// It's still possible that someone removed the image right after it is pulled.
|
||||
return nil, fmt.Errorf("failed to get image %q metadata after pulling: %v", imageID, err)
|
||||
return nil, errors.Wrapf(err, "failed to get image %q metadata after pulling", imageID)
|
||||
}
|
||||
return &newImage, nil
|
||||
}
|
||||
@@ -306,28 +330,28 @@ func getImageInfo(ctx context.Context, image containerd.Image) (*imageInfo, erro
|
||||
// Get image information.
|
||||
diffIDs, err := image.RootFS(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image diffIDs: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get image diffIDs")
|
||||
}
|
||||
chainID := identity.ChainID(diffIDs)
|
||||
|
||||
size, err := image.Size(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image compressed resource size: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get image compressed resource size")
|
||||
}
|
||||
|
||||
desc, err := image.Config(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image config descriptor: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get image config descriptor")
|
||||
}
|
||||
id := desc.Digest.String()
|
||||
|
||||
rb, err := content.ReadBlob(ctx, image.ContentStore(), desc.Digest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read image config from content store: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to read image config from content store")
|
||||
}
|
||||
var ociimage imagespec.Image
|
||||
if err := json.Unmarshal(rb, &ociimage); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal image config %s: %v", rb, err)
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal image config %s", rb)
|
||||
}
|
||||
|
||||
return &imageInfo{
|
||||
@@ -392,34 +416,31 @@ func newSpecGenerator(spec *runtimespec.Spec) generate.Generator {
|
||||
return g
|
||||
}
|
||||
|
||||
// disableNetNSDAD disables duplicate address detection in the network namespace.
|
||||
// DAD has a negative affect on sandbox start latency, since we have to wait
|
||||
// a second or more for the addresses to leave the "tentative" state.
|
||||
func disableNetNSDAD(ns string) error {
|
||||
dad := "net/ipv6/conf/default/accept_dad"
|
||||
|
||||
sysctlBin, err := exec.LookPath("sysctl")
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find sysctl binary: %v", err)
|
||||
func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]string {
|
||||
return map[string]string{
|
||||
"K8S_POD_NAMESPACE": config.GetMetadata().GetNamespace(),
|
||||
"K8S_POD_NAME": config.GetMetadata().GetName(),
|
||||
"K8S_POD_INFRA_CONTAINER_ID": id,
|
||||
"IgnoreUnknown": "1",
|
||||
}
|
||||
|
||||
nsenterBin, err := exec.LookPath("nsenter")
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find nsenter binary: %v", err)
|
||||
}
|
||||
|
||||
// If the sysctl doesn't exist, it means ipv6 is disabled.
|
||||
if _, err := sysctl.New().GetSysctl(dad); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
output, err := exec.Command(nsenterBin,
|
||||
fmt.Sprintf("--net=%s", ns), "-F", "--",
|
||||
sysctlBin, "-w", fmt.Sprintf("%s=%s", dad, "0"),
|
||||
).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write sysctl %q - output: %s, error: %s",
|
||||
dad, output, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getRuntimeConfigFromContainerInfo gets runtime configuration from containerd
|
||||
// container info.
|
||||
func getRuntimeConfigFromContainerInfo(c containers.Container) (criconfig.Runtime, error) {
|
||||
r := criconfig.Runtime{
|
||||
Type: c.Runtime.Name,
|
||||
}
|
||||
if c.Runtime.Options == nil {
|
||||
// CRI plugin makes sure that runtime option is always set.
|
||||
return criconfig.Runtime{}, errors.New("runtime options is nil")
|
||||
}
|
||||
data, err := typeurl.UnmarshalAny(c.Runtime.Options)
|
||||
if err != nil {
|
||||
return criconfig.Runtime{}, errors.Wrap(err, "failed to unmarshal runtime options")
|
||||
}
|
||||
runtimeOpts := data.(*runctypes.RuncOptions)
|
||||
r.Engine = runtimeOpts.Runtime
|
||||
r.Root = runtimeOpts.RuntimeRoot
|
||||
return r, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/cri/pkg/server/image_list.go
generated
vendored
2
vendor/github.com/containerd/cri/pkg/server/image_list.go
generated
vendored
@@ -26,7 +26,7 @@ import (
|
||||
// ListImages lists existing images.
|
||||
// TODO(random-liu): Add image list filters after CRI defines this more clear, and kubelet
|
||||
// actually needs it.
|
||||
func (c *criContainerdService) ListImages(ctx context.Context, r *runtime.ListImagesRequest) (*runtime.ListImagesResponse, error) {
|
||||
func (c *criService) ListImages(ctx context.Context, r *runtime.ListImagesRequest) (*runtime.ListImagesResponse, error) {
|
||||
imagesInStore := c.imageStore.List()
|
||||
|
||||
var images []*runtime.Image
|
||||
|
||||
20
vendor/github.com/containerd/cri/pkg/server/image_load.go
generated
vendored
20
vendor/github.com/containerd/cri/pkg/server/image_load.go
generated
vendored
@@ -17,12 +17,12 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/net/context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
api "github.com/containerd/cri/pkg/api/v1"
|
||||
"github.com/containerd/cri/pkg/containerd/importer"
|
||||
@@ -30,23 +30,23 @@ import (
|
||||
)
|
||||
|
||||
// LoadImage loads a image into containerd.
|
||||
func (c *criContainerdService) LoadImage(ctx context.Context, r *api.LoadImageRequest) (*api.LoadImageResponse, error) {
|
||||
func (c *criService) LoadImage(ctx context.Context, r *api.LoadImageRequest) (*api.LoadImageResponse, error) {
|
||||
path := r.GetFilePath()
|
||||
if !filepath.IsAbs(path) {
|
||||
return nil, fmt.Errorf("path %q is not an absolute path", path)
|
||||
return nil, errors.Errorf("path %q is not an absolute path", path)
|
||||
}
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to open file")
|
||||
}
|
||||
repoTags, err := importer.Import(ctx, c.client, f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to import image: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to import image")
|
||||
}
|
||||
for _, repoTag := range repoTags {
|
||||
image, err := c.client.GetImage(ctx, repoTag)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image %q: %v", repoTag, err)
|
||||
return nil, errors.Wrapf(err, "failed to get image %q", repoTag)
|
||||
}
|
||||
if err := image.Unpack(ctx, c.config.ContainerdConfig.Snapshotter); err != nil {
|
||||
logrus.WithError(err).Warnf("Failed to unpack image %q", repoTag)
|
||||
@@ -54,12 +54,12 @@ func (c *criContainerdService) LoadImage(ctx context.Context, r *api.LoadImageRe
|
||||
}
|
||||
info, err := getImageInfo(ctx, image)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image %q info: %v", repoTag, err)
|
||||
return nil, errors.Wrapf(err, "failed to get image %q info", repoTag)
|
||||
}
|
||||
id := info.id
|
||||
|
||||
if err := c.createImageReference(ctx, id, image.Target()); err != nil {
|
||||
return nil, fmt.Errorf("failed to create image reference %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to create image reference %q", id)
|
||||
}
|
||||
|
||||
img := imagestore.Image{
|
||||
@@ -72,7 +72,7 @@ func (c *criContainerdService) LoadImage(ctx context.Context, r *api.LoadImageRe
|
||||
}
|
||||
|
||||
if err := c.imageStore.Add(img); err != nil {
|
||||
return nil, fmt.Errorf("failed to add image %q into store: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to add image %q into store", id)
|
||||
}
|
||||
logrus.Debugf("Imported image with id %q, repo tag %q", id, repoTag)
|
||||
}
|
||||
|
||||
24
vendor/github.com/containerd/cri/pkg/server/image_pull.go
generated
vendored
24
vendor/github.com/containerd/cri/pkg/server/image_pull.go
generated
vendored
@@ -18,7 +18,6 @@ package server
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -26,6 +25,7 @@ import (
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
containerdimages "github.com/containerd/containerd/images"
|
||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -77,11 +77,11 @@ import (
|
||||
// contents are missing but snapshots are ready, is the image still "READY"?
|
||||
|
||||
// PullImage pulls an image with authentication config.
|
||||
func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (*runtime.PullImageResponse, error) {
|
||||
func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (*runtime.PullImageResponse, error) {
|
||||
imageRef := r.GetImage().GetImage()
|
||||
namedRef, err := util.NormalizeImageRef(imageRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse image reference %q: %v", imageRef, err)
|
||||
return nil, errors.Wrapf(err, "failed to parse image reference %q", imageRef)
|
||||
}
|
||||
ref := namedRef.String()
|
||||
if ref != imageRef {
|
||||
@@ -94,7 +94,7 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
})
|
||||
_, desc, err := resolver.Resolve(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve image %q: %v", ref, err)
|
||||
return nil, errors.Wrapf(err, "failed to resolve image %q", ref)
|
||||
}
|
||||
// We have to check schema1 here, because after `Pull`, schema1
|
||||
// image has already been converted.
|
||||
@@ -106,7 +106,7 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
containerd.WithResolver(resolver),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to pull image %q: %v", ref, err)
|
||||
return nil, errors.Wrapf(err, "failed to pull image %q", ref)
|
||||
}
|
||||
|
||||
// Do best effort unpack.
|
||||
@@ -119,7 +119,7 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
// Get image information.
|
||||
info, err := getImageInfo(ctx, image)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image information: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get image information")
|
||||
}
|
||||
imageID := info.id
|
||||
|
||||
@@ -129,7 +129,7 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
continue
|
||||
}
|
||||
if err := c.createImageReference(ctx, r, image.Target()); err != nil {
|
||||
return nil, fmt.Errorf("failed to update image reference %q: %v", r, err)
|
||||
return nil, errors.Wrapf(err, "failed to update image reference %q", r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
}
|
||||
|
||||
if err := c.imageStore.Add(img); err != nil {
|
||||
return nil, fmt.Errorf("failed to add image %q into store: %v", img.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to add image %q into store", img.ID)
|
||||
}
|
||||
|
||||
// NOTE(random-liu): the actual state in containerd is the source of truth, even we maintain
|
||||
@@ -181,20 +181,20 @@ func ParseAuth(auth *runtime.AuthConfig) (string, string, error) {
|
||||
}
|
||||
fields := strings.SplitN(string(decoded), ":", 2)
|
||||
if len(fields) != 2 {
|
||||
return "", "", fmt.Errorf("invalid decoded auth: %q", decoded)
|
||||
return "", "", errors.Errorf("invalid decoded auth: %q", decoded)
|
||||
}
|
||||
user, passwd := fields[0], fields[1]
|
||||
return user, strings.Trim(passwd, "\x00"), nil
|
||||
}
|
||||
// TODO(random-liu): Support RegistryToken.
|
||||
return "", "", fmt.Errorf("invalid auth config")
|
||||
return "", "", errors.New("invalid auth config")
|
||||
}
|
||||
|
||||
// createImageReference creates image reference inside containerd image store.
|
||||
// Note that because create and update are not finished in one transaction, there could be race. E.g.
|
||||
// the image reference is deleted by someone else after create returns already exists, but before update
|
||||
// happens.
|
||||
func (c *criContainerdService) createImageReference(ctx context.Context, name string, desc imagespec.Descriptor) error {
|
||||
func (c *criService) createImageReference(ctx context.Context, name string, desc imagespec.Descriptor) error {
|
||||
img := containerdimages.Image{
|
||||
Name: name,
|
||||
Target: desc,
|
||||
@@ -212,7 +212,7 @@ func (c *criContainerdService) createImageReference(ctx context.Context, name st
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *criContainerdService) getResolverOptions() map[string][]string {
|
||||
func (c *criService) getResolverOptions() map[string][]string {
|
||||
options := make(map[string][]string)
|
||||
for ns, mirror := range c.config.Mirrors {
|
||||
options[ns] = append(options[ns], mirror.Endpoints...)
|
||||
|
||||
13
vendor/github.com/containerd/cri/pkg/server/image_remove.go
generated
vendored
13
vendor/github.com/containerd/cri/pkg/server/image_remove.go
generated
vendored
@@ -17,10 +17,9 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -32,10 +31,10 @@ import (
|
||||
// TODO(random-liu): We should change CRI to distinguish image id and image spec.
|
||||
// Remove the whole image no matter the it's image id or reference. This is the
|
||||
// semantic defined in CRI now.
|
||||
func (c *criContainerdService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (*runtime.RemoveImageResponse, error) {
|
||||
func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (*runtime.RemoveImageResponse, error) {
|
||||
image, err := c.localResolve(ctx, r.GetImage().GetImage())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can not resolve %q locally: %v", r.GetImage().GetImage(), err)
|
||||
return nil, errors.Wrapf(err, "can not resolve %q locally", r.GetImage().GetImage())
|
||||
}
|
||||
if image == nil {
|
||||
// return empty without error when image not found.
|
||||
@@ -49,7 +48,7 @@ func (c *criContainerdService) RemoveImage(ctx context.Context, r *runtime.Remov
|
||||
if errdefs.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get image %q: %v", tag, err)
|
||||
return nil, errors.Wrapf(err, "failed to get image %q", tag)
|
||||
}
|
||||
desc, err := cImage.Config(ctx)
|
||||
if err != nil {
|
||||
@@ -82,12 +81,12 @@ func (c *criContainerdService) RemoveImage(ctx context.Context, r *runtime.Remov
|
||||
if err == nil || errdefs.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to delete image reference %q for image %q: %v", ref, image.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to delete image reference %q for image %q", ref, image.ID)
|
||||
}
|
||||
// Delete image id synchronously to trigger garbage collection.
|
||||
err = c.client.ImageService().Delete(ctx, image.ID, images.SynchronousDelete())
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to delete image id %q: %v", image.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to delete image id %q", image.ID)
|
||||
}
|
||||
c.imageStore.Delete(image.ID)
|
||||
return &runtime.RemoveImageResponse{}, nil
|
||||
|
||||
10
vendor/github.com/containerd/cri/pkg/server/image_status.go
generated
vendored
10
vendor/github.com/containerd/cri/pkg/server/image_status.go
generated
vendored
@@ -18,8 +18,8 @@ package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -31,10 +31,10 @@ import (
|
||||
// ImageStatus returns the status of the image, returns nil if the image isn't present.
|
||||
// TODO(random-liu): We should change CRI to distinguish image id and image spec. (See
|
||||
// kubernetes/kubernetes#46255)
|
||||
func (c *criContainerdService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (*runtime.ImageStatusResponse, error) {
|
||||
func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (*runtime.ImageStatusResponse, error) {
|
||||
image, err := c.localResolve(ctx, r.GetImage().GetImage())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can not resolve %q locally: %v", r.GetImage().GetImage(), err)
|
||||
return nil, errors.Wrapf(err, "can not resolve %q locally", r.GetImage().GetImage())
|
||||
}
|
||||
if image == nil {
|
||||
// return empty without error when image not found.
|
||||
@@ -46,7 +46,7 @@ func (c *criContainerdService) ImageStatus(ctx context.Context, r *runtime.Image
|
||||
runtimeImage := toCRIRuntimeImage(image)
|
||||
info, err := c.toCRIImageInfo(ctx, image, r.GetVerbose())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate image info: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to generate image info")
|
||||
}
|
||||
|
||||
return &runtime.ImageStatusResponse{
|
||||
@@ -79,7 +79,7 @@ type verboseImageInfo struct {
|
||||
}
|
||||
|
||||
// toCRIImageInfo converts internal image object information to CRI image status response info map.
|
||||
func (c *criContainerdService) toCRIImageInfo(ctx context.Context, image *imagestore.Image, verbose bool) (map[string]string, error) {
|
||||
func (c *criService) toCRIImageInfo(ctx context.Context, image *imagestore.Image, verbose bool) (map[string]string, error) {
|
||||
if !verbose {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/cri/pkg/server/imagefs_info.go
generated
vendored
2
vendor/github.com/containerd/cri/pkg/server/imagefs_info.go
generated
vendored
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
// ImageFsInfo returns information of the filesystem that is used to store images.
|
||||
func (c *criContainerdService) ImageFsInfo(ctx context.Context, r *runtime.ImageFsInfoRequest) (*runtime.ImageFsInfoResponse, error) {
|
||||
func (c *criService) ImageFsInfo(ctx context.Context, r *runtime.ImageFsInfoRequest) (*runtime.ImageFsInfoResponse, error) {
|
||||
snapshots := c.snapshotStore.List()
|
||||
timestamp := time.Now().UnixNano()
|
||||
var usedBytes, inodesUsed uint64
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
generated
vendored
@@ -30,10 +30,10 @@ import (
|
||||
|
||||
// instrumentedService wraps service with containerd namespace and logs.
|
||||
type instrumentedService struct {
|
||||
c *criContainerdService
|
||||
c *criService
|
||||
}
|
||||
|
||||
func newInstrumentedService(c *criContainerdService) grpcServices {
|
||||
func newInstrumentedService(c *criService) grpcServices {
|
||||
return &instrumentedService{c: c}
|
||||
}
|
||||
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/server/io/logger.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/server/io/logger.go
generated
vendored
@@ -19,12 +19,12 @@ package io
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
@@ -57,7 +57,7 @@ func NewCRILogger(path string, stream StreamType) (io.WriteCloser, error) {
|
||||
prc, pwc := io.Pipe()
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0640)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open log file: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to open log file")
|
||||
}
|
||||
go redirectLogs(path, prc, f, stream)
|
||||
return pwc, nil
|
||||
|
||||
163
vendor/github.com/containerd/cri/pkg/server/restart.go
generated
vendored
163
vendor/github.com/containerd/cri/pkg/server/restart.go
generated
vendored
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -31,6 +30,7 @@ import (
|
||||
"github.com/containerd/typeurl"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -51,11 +51,11 @@ import (
|
||||
// tolerant tasks being created or started, we prefer that not to happen.
|
||||
|
||||
// recover recovers system state from containerd and status checkpoint.
|
||||
func (c *criContainerdService) recover(ctx context.Context) error {
|
||||
func (c *criService) recover(ctx context.Context) error {
|
||||
// Recover all sandboxes.
|
||||
sandboxes, err := c.client.Containers(ctx, filterLabel(containerKindLabel, containerKindSandbox))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list sandbox containers: %v", err)
|
||||
return errors.Wrap(err, "failed to list sandbox containers")
|
||||
}
|
||||
for _, sandbox := range sandboxes {
|
||||
sb, err := loadSandbox(ctx, sandbox)
|
||||
@@ -65,47 +65,48 @@ func (c *criContainerdService) recover(ctx context.Context) error {
|
||||
}
|
||||
logrus.Debugf("Loaded sandbox %+v", sb)
|
||||
if err := c.sandboxStore.Add(sb); err != nil {
|
||||
return fmt.Errorf("failed to add sandbox %q to store: %v", sandbox.ID(), err)
|
||||
return errors.Wrapf(err, "failed to add sandbox %q to store", sandbox.ID())
|
||||
}
|
||||
if err := c.sandboxNameIndex.Reserve(sb.Name, sb.ID); err != nil {
|
||||
return fmt.Errorf("failed to reserve sandbox name %q: %v", sb.Name, err)
|
||||
return errors.Wrapf(err, "failed to reserve sandbox name %q", sb.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Recover all containers.
|
||||
containers, err := c.client.Containers(ctx, filterLabel(containerKindLabel, containerKindContainer))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list containers: %v", err)
|
||||
return errors.Wrap(err, "failed to list containers")
|
||||
}
|
||||
for _, container := range containers {
|
||||
containerDir := getContainerRootDir(c.config.RootDir, container.ID())
|
||||
cntr, err := loadContainer(ctx, container, containerDir)
|
||||
containerDir := c.getContainerRootDir(container.ID())
|
||||
volatileContainerDir := c.getVolatileContainerRootDir(container.ID())
|
||||
cntr, err := loadContainer(ctx, container, containerDir, volatileContainerDir)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to load container %q", container.ID())
|
||||
continue
|
||||
}
|
||||
logrus.Debugf("Loaded container %+v", cntr)
|
||||
if err := c.containerStore.Add(cntr); err != nil {
|
||||
return fmt.Errorf("failed to add container %q to store: %v", container.ID(), err)
|
||||
return errors.Wrapf(err, "failed to add container %q to store", container.ID())
|
||||
}
|
||||
if err := c.containerNameIndex.Reserve(cntr.Name, cntr.ID); err != nil {
|
||||
return fmt.Errorf("failed to reserve container name %q: %v", cntr.Name, err)
|
||||
return errors.Wrapf(err, "failed to reserve container name %q", cntr.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Recover all images.
|
||||
cImages, err := c.client.ListImages(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list images: %v", err)
|
||||
return errors.Wrap(err, "failed to list images")
|
||||
}
|
||||
images, err := loadImages(ctx, cImages, c.config.ContainerdConfig.Snapshotter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load images: %v", err)
|
||||
return errors.Wrap(err, "failed to load images")
|
||||
}
|
||||
for _, image := range images {
|
||||
logrus.Debugf("Loaded image %+v", image)
|
||||
if err := c.imageStore.Add(image); err != nil {
|
||||
return fmt.Errorf("failed to add image %q to store: %v", image.ID, err)
|
||||
return errors.Wrapf(err, "failed to add image %q to store", image.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,35 +114,56 @@ func (c *criContainerdService) recover(ctx context.Context) error {
|
||||
// we can't even get metadata, we should cleanup orphaned sandbox/container directories
|
||||
// with best effort.
|
||||
|
||||
// Cleanup orphaned sandbox directories without corresponding containerd container.
|
||||
if err := cleanupOrphanedSandboxDirs(sandboxes, filepath.Join(c.config.RootDir, "sandboxes")); err != nil {
|
||||
return fmt.Errorf("failed to cleanup orphaned sandbox directories: %v", err)
|
||||
// Cleanup orphaned sandbox and container directories without corresponding containerd container.
|
||||
for _, cleanup := range []struct {
|
||||
cntrs []containerd.Container
|
||||
base string
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
cntrs: sandboxes,
|
||||
base: filepath.Join(c.config.RootDir, sandboxesDir),
|
||||
errMsg: "failed to cleanup orphaned sandbox directories",
|
||||
},
|
||||
{
|
||||
cntrs: sandboxes,
|
||||
base: filepath.Join(c.config.StateDir, sandboxesDir),
|
||||
errMsg: "failed to cleanup orphaned volatile sandbox directories",
|
||||
},
|
||||
{
|
||||
cntrs: containers,
|
||||
base: filepath.Join(c.config.RootDir, containersDir),
|
||||
errMsg: "failed to cleanup orphaned container directories",
|
||||
},
|
||||
{
|
||||
cntrs: containers,
|
||||
base: filepath.Join(c.config.StateDir, containersDir),
|
||||
errMsg: "failed to cleanup orphaned volatile container directories",
|
||||
},
|
||||
} {
|
||||
if err := cleanupOrphanedIDDirs(cleanup.cntrs, cleanup.base); err != nil {
|
||||
return errors.Wrap(err, cleanup.errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup orphaned container directories without corresponding containerd container.
|
||||
if err := cleanupOrphanedContainerDirs(containers, filepath.Join(c.config.RootDir, "containers")); err != nil {
|
||||
return fmt.Errorf("failed to cleanup orphaned container directories: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadContainer loads container from containerd and status checkpoint.
|
||||
func loadContainer(ctx context.Context, cntr containerd.Container, containerDir string) (containerstore.Container, error) {
|
||||
func loadContainer(ctx context.Context, cntr containerd.Container, containerDir, volatileContainerDir string) (containerstore.Container, error) {
|
||||
id := cntr.ID()
|
||||
var container containerstore.Container
|
||||
// Load container metadata.
|
||||
exts, err := cntr.Extensions(ctx)
|
||||
if err != nil {
|
||||
return container, fmt.Errorf("failed to get container extensions: %v", err)
|
||||
return container, errors.Wrap(err, "failed to get container extensions")
|
||||
}
|
||||
ext, ok := exts[containerMetadataExtension]
|
||||
if !ok {
|
||||
return container, fmt.Errorf("metadata extension %q not found", containerMetadataExtension)
|
||||
return container, errors.Errorf("metadata extension %q not found", containerMetadataExtension)
|
||||
}
|
||||
data, err := typeurl.UnmarshalAny(&ext)
|
||||
if err != nil {
|
||||
return container, fmt.Errorf("failed to unmarshal metadata extension %q: %v", ext, err)
|
||||
return container, errors.Wrapf(err, "failed to unmarshal metadata extension %q", ext)
|
||||
}
|
||||
meta := data.(*containerstore.Metadata)
|
||||
|
||||
@@ -170,7 +192,7 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
|
||||
return containerIO, nil
|
||||
})
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return container, fmt.Errorf("failed to load task: %v", err)
|
||||
return container, errors.Wrap(err, "failed to load task")
|
||||
}
|
||||
var s containerd.Status
|
||||
var notFound bool
|
||||
@@ -183,7 +205,7 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
|
||||
if err != nil {
|
||||
// It's still possible that task is deleted during this window.
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return container, fmt.Errorf("failed to get task status: %v", err)
|
||||
return container, errors.Wrap(err, "failed to get task status")
|
||||
}
|
||||
notFound = true
|
||||
}
|
||||
@@ -197,10 +219,10 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
|
||||
// containerd got restarted during that. In that case, we still
|
||||
// treat the container as `CREATED`.
|
||||
containerIO, err = cio.NewContainerIO(id,
|
||||
cio.WithNewFIFOs(containerDir, meta.Config.GetTty(), meta.Config.GetStdin()),
|
||||
cio.WithNewFIFOs(volatileContainerDir, meta.Config.GetTty(), meta.Config.GetStdin()),
|
||||
)
|
||||
if err != nil {
|
||||
return container, fmt.Errorf("failed to create container io: %v", err)
|
||||
return container, errors.Wrap(err, "failed to create container io")
|
||||
}
|
||||
case runtime.ContainerState_CONTAINER_RUNNING:
|
||||
// Container was in running state, but its task has been deleted,
|
||||
@@ -219,17 +241,17 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
|
||||
// gets restarted during container start.
|
||||
// Container must be in `CREATED` state.
|
||||
if _, err := t.Delete(ctx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) {
|
||||
return container, fmt.Errorf("failed to delete task: %v", err)
|
||||
return container, errors.Wrap(err, "failed to delete task")
|
||||
}
|
||||
if status.State() != runtime.ContainerState_CONTAINER_CREATED {
|
||||
return container, fmt.Errorf("unexpected container state for created task: %q", status.State())
|
||||
return container, errors.Errorf("unexpected container state for created task: %q", status.State())
|
||||
}
|
||||
case containerd.Running:
|
||||
// Task is running. Container must be in `RUNNING` state, based on our assuption that
|
||||
// "task should not be started when containerd is down".
|
||||
switch status.State() {
|
||||
case runtime.ContainerState_CONTAINER_EXITED:
|
||||
return container, fmt.Errorf("unexpected container state for running task: %q", status.State())
|
||||
return container, errors.Errorf("unexpected container state for running task: %q", status.State())
|
||||
case runtime.ContainerState_CONTAINER_RUNNING:
|
||||
default:
|
||||
// This may happen if containerd gets restarted after task is started, but
|
||||
@@ -240,12 +262,12 @@ func loadContainer(ctx context.Context, cntr containerd.Container, containerDir
|
||||
case containerd.Stopped:
|
||||
// Task is stopped. Updata status and delete the task.
|
||||
if _, err := t.Delete(ctx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) {
|
||||
return container, fmt.Errorf("failed to delete task: %v", err)
|
||||
return container, errors.Wrap(err, "failed to delete task")
|
||||
}
|
||||
status.FinishedAt = s.ExitTime.UnixNano()
|
||||
status.ExitCode = int32(s.ExitStatus)
|
||||
default:
|
||||
return container, fmt.Errorf("unexpected task status %q", s.Status)
|
||||
return container, errors.Errorf("unexpected task status %q", s.Status)
|
||||
}
|
||||
}
|
||||
opts := []containerstore.Opts{
|
||||
@@ -282,29 +304,29 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S
|
||||
// Load sandbox metadata.
|
||||
exts, err := cntr.Extensions(ctx)
|
||||
if err != nil {
|
||||
return sandbox, fmt.Errorf("failed to get sandbox container extensions: %v", err)
|
||||
return sandbox, errors.Wrap(err, "failed to get sandbox container extensions")
|
||||
}
|
||||
ext, ok := exts[sandboxMetadataExtension]
|
||||
if !ok {
|
||||
return sandbox, fmt.Errorf("metadata extension %q not found", sandboxMetadataExtension)
|
||||
return sandbox, errors.Errorf("metadata extension %q not found", sandboxMetadataExtension)
|
||||
}
|
||||
data, err := typeurl.UnmarshalAny(&ext)
|
||||
if err != nil {
|
||||
return sandbox, fmt.Errorf("failed to unmarshal metadata extension %q: %v", ext, err)
|
||||
return sandbox, errors.Wrapf(err, "failed to unmarshal metadata extension %q", ext)
|
||||
}
|
||||
meta := data.(*sandboxstore.Metadata)
|
||||
|
||||
// Load sandbox created timestamp.
|
||||
info, err := cntr.Info(ctx)
|
||||
if err != nil {
|
||||
return sandbox, fmt.Errorf("failed to get sandbox container info: %v", err)
|
||||
return sandbox, errors.Wrap(err, "failed to get sandbox container info")
|
||||
}
|
||||
createdAt := info.CreatedAt
|
||||
|
||||
// Load sandbox status.
|
||||
t, err := cntr.Task(ctx, nil)
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return sandbox, fmt.Errorf("failed to load task: %v", err)
|
||||
return sandbox, errors.Wrap(err, "failed to load task")
|
||||
}
|
||||
var s containerd.Status
|
||||
var notFound bool
|
||||
@@ -317,7 +339,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S
|
||||
if err != nil {
|
||||
// It's still possible that task is deleted during this window.
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return sandbox, fmt.Errorf("failed to get task status: %v", err)
|
||||
return sandbox, errors.Wrap(err, "failed to get task status")
|
||||
}
|
||||
notFound = true
|
||||
}
|
||||
@@ -335,7 +357,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S
|
||||
} else {
|
||||
// Task is not running. Delete the task and set sandbox state as NOTREADY.
|
||||
if _, err := t.Delete(ctx, containerd.WithProcessKill); err != nil && !errdefs.IsNotFound(err) {
|
||||
return sandbox, fmt.Errorf("failed to delete task: %v", err)
|
||||
return sandbox, errors.Wrap(err, "failed to delete task")
|
||||
}
|
||||
state = sandboxstore.StateNotReady
|
||||
}
|
||||
@@ -359,7 +381,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S
|
||||
netNS, err := sandboxstore.LoadNetNS(meta.NetNSPath)
|
||||
if err != nil {
|
||||
if err != sandboxstore.ErrClosedNetNS {
|
||||
return sandbox, fmt.Errorf("failed to load netns %q: %v", meta.NetNSPath, err)
|
||||
return sandbox, errors.Wrapf(err, "failed to load netns %q", meta.NetNSPath)
|
||||
}
|
||||
netNS = nil
|
||||
}
|
||||
@@ -448,59 +470,30 @@ func loadImages(ctx context.Context, cImages []containerd.Image,
|
||||
return images, nil
|
||||
}
|
||||
|
||||
func cleanupOrphanedSandboxDirs(cntrs []containerd.Container, sandboxesRoot string) error {
|
||||
// Cleanup orphaned sandbox directories.
|
||||
dirs, err := ioutil.ReadDir(sandboxesRoot)
|
||||
func cleanupOrphanedIDDirs(cntrs []containerd.Container, base string) error {
|
||||
// Cleanup orphaned id directories.
|
||||
dirs, err := ioutil.ReadDir(base)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("failed to read pod sandboxes directory %q: %v", sandboxesRoot, err)
|
||||
return errors.Wrap(err, "failed to read base directory")
|
||||
}
|
||||
cntrsMap := make(map[string]containerd.Container)
|
||||
idsMap := make(map[string]containerd.Container)
|
||||
for _, cntr := range cntrs {
|
||||
cntrsMap[cntr.ID()] = cntr
|
||||
idsMap[cntr.ID()] = cntr
|
||||
}
|
||||
for _, d := range dirs {
|
||||
if !d.IsDir() {
|
||||
logrus.Warnf("Invalid file %q found in pod sandboxes directory", d.Name())
|
||||
logrus.Warnf("Invalid file %q found in base directory %q", d.Name(), base)
|
||||
continue
|
||||
}
|
||||
if _, ok := cntrsMap[d.Name()]; ok {
|
||||
// Do not remove sandbox directory if corresponding container is found.
|
||||
if _, ok := idsMap[d.Name()]; ok {
|
||||
// Do not remove id directory if corresponding container is found.
|
||||
continue
|
||||
}
|
||||
sandboxDir := filepath.Join(sandboxesRoot, d.Name())
|
||||
if err := system.EnsureRemoveAll(sandboxDir); err != nil {
|
||||
logrus.WithError(err).Warnf("Failed to remove pod sandbox directory %q", sandboxDir)
|
||||
dir := filepath.Join(base, d.Name())
|
||||
if err := system.EnsureRemoveAll(dir); err != nil {
|
||||
logrus.WithError(err).Warnf("Failed to remove id directory %q", dir)
|
||||
} else {
|
||||
logrus.Debugf("Cleanup orphaned pod sandbox directory %q", sandboxDir)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupOrphanedContainerDirs(cntrs []containerd.Container, containersRoot string) error {
|
||||
// Cleanup orphaned container directories.
|
||||
dirs, err := ioutil.ReadDir(containersRoot)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("failed to read containers directory %q: %v", containersRoot, err)
|
||||
}
|
||||
cntrsMap := make(map[string]containerd.Container)
|
||||
for _, cntr := range cntrs {
|
||||
cntrsMap[cntr.ID()] = cntr
|
||||
}
|
||||
for _, d := range dirs {
|
||||
if !d.IsDir() {
|
||||
logrus.Warnf("Invalid file %q found in containers directory", d.Name())
|
||||
continue
|
||||
}
|
||||
if _, ok := cntrsMap[d.Name()]; ok {
|
||||
// Do not remove container directory if corresponding container is found.
|
||||
continue
|
||||
}
|
||||
containerDir := filepath.Join(containersRoot, d.Name())
|
||||
if err := system.EnsureRemoveAll(containerDir); err != nil {
|
||||
logrus.WithError(err).Warnf("Failed to remove container directory %q", containerDir)
|
||||
} else {
|
||||
logrus.Debugf("Cleanup orphaned container directory %q", containerDir)
|
||||
logrus.Debugf("Cleanup orphaned id directory %q", dir)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
6
vendor/github.com/containerd/cri/pkg/server/sandbox_list.go
generated
vendored
6
vendor/github.com/containerd/cri/pkg/server/sandbox_list.go
generated
vendored
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// ListPodSandbox returns a list of Sandbox.
|
||||
func (c *criContainerdService) ListPodSandbox(ctx context.Context, r *runtime.ListPodSandboxRequest) (*runtime.ListPodSandboxResponse, error) {
|
||||
func (c *criService) ListPodSandbox(ctx context.Context, r *runtime.ListPodSandboxRequest) (*runtime.ListPodSandboxResponse, error) {
|
||||
// List all sandboxes from store.
|
||||
sandboxesInStore := c.sandboxStore.List()
|
||||
var sandboxes []*runtime.PodSandbox
|
||||
@@ -56,14 +56,14 @@ func toCRISandbox(meta sandboxstore.Metadata, status sandboxstore.Status) *runti
|
||||
}
|
||||
}
|
||||
|
||||
func (c *criContainerdService) normalizePodSandboxFilter(filter *runtime.PodSandboxFilter) {
|
||||
func (c *criService) normalizePodSandboxFilter(filter *runtime.PodSandboxFilter) {
|
||||
if sb, err := c.sandboxStore.Get(filter.GetId()); err == nil {
|
||||
filter.Id = sb.ID
|
||||
}
|
||||
}
|
||||
|
||||
// filterCRISandboxes filters CRISandboxes.
|
||||
func (c *criContainerdService) filterCRISandboxes(sandboxes []*runtime.PodSandbox, filter *runtime.PodSandboxFilter) []*runtime.PodSandbox {
|
||||
func (c *criService) filterCRISandboxes(sandboxes []*runtime.PodSandbox, filter *runtime.PodSandboxFilter) []*runtime.PodSandbox {
|
||||
if filter == nil {
|
||||
return sandboxes
|
||||
}
|
||||
|
||||
20
vendor/github.com/containerd/cri/pkg/server/sandbox_portforward.go
generated
vendored
20
vendor/github.com/containerd/cri/pkg/server/sandbox_portforward.go
generated
vendored
@@ -18,12 +18,12 @@ package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -33,11 +33,11 @@ import (
|
||||
)
|
||||
|
||||
// PortForward prepares a streaming endpoint to forward ports from a PodSandbox, and returns the address.
|
||||
func (c *criContainerdService) PortForward(ctx context.Context, r *runtime.PortForwardRequest) (retRes *runtime.PortForwardResponse, retErr error) {
|
||||
func (c *criService) PortForward(ctx context.Context, r *runtime.PortForwardRequest) (retRes *runtime.PortForwardResponse, retErr error) {
|
||||
// TODO(random-liu): Run a socat container inside the sandbox to do portforward.
|
||||
sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find sandbox %q: %v", r.GetPodSandboxId(), err)
|
||||
return nil, errors.Wrapf(err, "failed to find sandbox %q", r.GetPodSandboxId())
|
||||
}
|
||||
if sandbox.Status.Get().State != sandboxstore.StateReady {
|
||||
return nil, errors.New("sandbox container is not running")
|
||||
@@ -49,20 +49,20 @@ func (c *criContainerdService) PortForward(ctx context.Context, r *runtime.PortF
|
||||
// portForward requires `nsenter` and `socat` on the node, it uses `nsenter` to enter the
|
||||
// sandbox namespace, and run `socat` inside the namespace to forward stream for a specific
|
||||
// port. The `socat` command keeps running until it exits or client disconnect.
|
||||
func (c *criContainerdService) portForward(id string, port int32, stream io.ReadWriteCloser) error {
|
||||
func (c *criService) portForward(id string, port int32, stream io.ReadWriteCloser) error {
|
||||
s, err := c.sandboxStore.Get(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find sandbox %q in store: %v", id, err)
|
||||
return errors.Wrapf(err, "failed to find sandbox %q in store", id)
|
||||
}
|
||||
t, err := s.Container.Task(ctrdutil.NamespacedContext(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get sandbox container task: %v", err)
|
||||
return errors.Wrap(err, "failed to get sandbox container task")
|
||||
}
|
||||
pid := t.Pid()
|
||||
|
||||
socat, err := exec.LookPath("socat")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find socat: %v", err)
|
||||
return errors.Wrap(err, "failed to find socat")
|
||||
}
|
||||
|
||||
// Check following links for meaning of the options:
|
||||
@@ -73,7 +73,7 @@ func (c *criContainerdService) portForward(id string, port int32, stream io.Read
|
||||
|
||||
nsenter, err := exec.LookPath("nsenter")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find nsenter: %v", err)
|
||||
return errors.Wrap(err, "failed to find nsenter")
|
||||
}
|
||||
|
||||
logrus.Infof("Executing port forwarding command: %s %s", nsenter, strings.Join(args, " "))
|
||||
@@ -95,7 +95,7 @@ func (c *criContainerdService) portForward(id string, port int32, stream io.Read
|
||||
// when the command (socat) exits.
|
||||
in, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create stdin pipe: %v", err)
|
||||
return errors.Wrap(err, "failed to create stdin pipe")
|
||||
}
|
||||
go func() {
|
||||
if _, err := io.Copy(in, stream); err != nil {
|
||||
@@ -106,7 +106,7 @@ func (c *criContainerdService) portForward(id string, port int32, stream io.Read
|
||||
}()
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("nsenter command returns error: %v, stderr: %q", err, stderr.String())
|
||||
return errors.Errorf("nsenter command returns error: %v, stderr: %q", err, stderr.String())
|
||||
}
|
||||
|
||||
logrus.Infof("Finish port forwarding for %q port %d", id, port)
|
||||
|
||||
30
vendor/github.com/containerd/cri/pkg/server/sandbox_remove.go
generated
vendored
30
vendor/github.com/containerd/cri/pkg/server/sandbox_remove.go
generated
vendored
@@ -17,11 +17,10 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
@@ -32,12 +31,12 @@ import (
|
||||
|
||||
// RemovePodSandbox removes the sandbox. If there are running containers in the
|
||||
// sandbox, they should be forcibly removed.
|
||||
func (c *criContainerdService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodSandboxRequest) (*runtime.RemovePodSandboxResponse, error) {
|
||||
func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodSandboxRequest) (*runtime.RemovePodSandboxResponse, error) {
|
||||
sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId())
|
||||
if err != nil {
|
||||
if err != store.ErrNotExist {
|
||||
return nil, fmt.Errorf("an error occurred when try to find sandbox %q: %v",
|
||||
r.GetPodSandboxId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find sandbox %q",
|
||||
r.GetPodSandboxId())
|
||||
}
|
||||
// Do not return error if the id doesn't exist.
|
||||
log.Tracef("RemovePodSandbox called for sandbox %q that does not exist",
|
||||
@@ -49,12 +48,12 @@ func (c *criContainerdService) RemovePodSandbox(ctx context.Context, r *runtime.
|
||||
|
||||
// Return error if sandbox container is still running.
|
||||
if sandbox.Status.Get().State == sandboxstore.StateReady {
|
||||
return nil, fmt.Errorf("sandbox container %q is not fully stopped", id)
|
||||
return nil, errors.Errorf("sandbox container %q is not fully stopped", id)
|
||||
}
|
||||
|
||||
// Return error if sandbox network namespace is not closed yet.
|
||||
if sandbox.NetNS != nil && !sandbox.NetNS.Closed() {
|
||||
return nil, fmt.Errorf("sandbox network namespace %q is not fully closed", sandbox.NetNS.GetPath())
|
||||
return nil, errors.Errorf("sandbox network namespace %q is not fully closed", sandbox.NetNS.GetPath())
|
||||
}
|
||||
|
||||
// Remove all containers inside the sandbox.
|
||||
@@ -69,21 +68,26 @@ func (c *criContainerdService) RemovePodSandbox(ctx context.Context, r *runtime.
|
||||
}
|
||||
_, err = c.RemoveContainer(ctx, &runtime.RemoveContainerRequest{ContainerId: cntr.ID})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to remove container %q: %v", cntr.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to remove container %q", cntr.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup the sandbox root directory.
|
||||
sandboxRootDir := getSandboxRootDir(c.config.RootDir, id)
|
||||
// Cleanup the sandbox root directories.
|
||||
sandboxRootDir := c.getSandboxRootDir(id)
|
||||
if err := system.EnsureRemoveAll(sandboxRootDir); err != nil {
|
||||
return nil, fmt.Errorf("failed to remove sandbox root directory %q: %v",
|
||||
sandboxRootDir, err)
|
||||
return nil, errors.Wrapf(err, "failed to remove sandbox root directory %q",
|
||||
sandboxRootDir)
|
||||
}
|
||||
volatileSandboxRootDir := c.getVolatileSandboxRootDir(id)
|
||||
if err := system.EnsureRemoveAll(volatileSandboxRootDir); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to remove volatile sandbox root directory %q",
|
||||
volatileSandboxRootDir)
|
||||
}
|
||||
|
||||
// Delete sandbox container.
|
||||
if err := sandbox.Container.Delete(ctx, containerd.WithSnapshotCleanup); err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to delete sandbox container %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to delete sandbox container %q", id)
|
||||
}
|
||||
log.Tracef("Remove called for sandbox container %q that does not exist", id)
|
||||
}
|
||||
|
||||
234
vendor/github.com/containerd/cri/pkg/server/sandbox_run.go
generated
vendored
234
vendor/github.com/containerd/cri/pkg/server/sandbox_run.go
generated
vendored
@@ -26,16 +26,18 @@ import (
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/linux/runctypes"
|
||||
"github.com/containerd/containerd/oci"
|
||||
cni "github.com/containerd/go-cni"
|
||||
"github.com/containerd/typeurl"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/sys/unix"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
"github.com/containerd/cri/pkg/annotations"
|
||||
criconfig "github.com/containerd/cri/pkg/config"
|
||||
customopts "github.com/containerd/cri/pkg/containerd/opts"
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
"github.com/containerd/cri/pkg/log"
|
||||
@@ -50,7 +52,7 @@ func init() {
|
||||
|
||||
// RunPodSandbox creates and starts a pod-level sandbox. Runtimes should ensure
|
||||
// the sandbox is in ready state.
|
||||
func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandboxRequest) (_ *runtime.RunPodSandboxResponse, retErr error) {
|
||||
func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandboxRequest) (_ *runtime.RunPodSandboxResponse, retErr error) {
|
||||
config := r.GetConfig()
|
||||
|
||||
// Generate unique id and name for the sandbox and reserve the name.
|
||||
@@ -60,7 +62,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
// Reserve the sandbox name to avoid concurrent `RunPodSandbox` request starting the
|
||||
// same sandbox.
|
||||
if err := c.sandboxNameIndex.Reserve(name, id); err != nil {
|
||||
return nil, fmt.Errorf("failed to reserve sandbox name %q: %v", name, err)
|
||||
return nil, errors.Wrapf(err, "failed to reserve sandbox name %q", name)
|
||||
}
|
||||
defer func() {
|
||||
// Release the name if the function returns with an error.
|
||||
@@ -84,7 +86,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
// Ensure sandbox container image snapshot.
|
||||
image, err := c.ensureImageExists(ctx, c.config.SandboxImage)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sandbox image %q: %v", c.config.SandboxImage, err)
|
||||
return nil, errors.Wrapf(err, "failed to get sandbox image %q", c.config.SandboxImage)
|
||||
}
|
||||
securityContext := config.GetLinux().GetSecurityContext()
|
||||
//Create Network Namespace if it is not in host network
|
||||
@@ -96,7 +98,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
// be used.
|
||||
sandbox.NetNS, err = sandboxstore.NewNetNS()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create network namespace for sandbox %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to create network namespace for sandbox %q", id)
|
||||
}
|
||||
sandbox.NetNSPath = sandbox.NetNS.GetPath()
|
||||
defer func() {
|
||||
@@ -107,53 +109,38 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
sandbox.NetNSPath = ""
|
||||
}
|
||||
}()
|
||||
if !c.config.EnableIPv6DAD {
|
||||
// It's a known issue that IPv6 DAD increases sandbox start latency by several seconds.
|
||||
// Disable it when it's not enabled to avoid the latency.
|
||||
// See:
|
||||
// * https://github.com/kubernetes/kubernetes/issues/54651
|
||||
// * https://www.agwa.name/blog/post/beware_the_ipv6_dad_race_condition
|
||||
if err := disableNetNSDAD(sandbox.NetNSPath); err != nil {
|
||||
return nil, fmt.Errorf("failed to disable DAD for sandbox %q: %v", id, err)
|
||||
}
|
||||
}
|
||||
// Setup network for sandbox.
|
||||
podNetwork := ocicni.PodNetwork{
|
||||
Name: config.GetMetadata().GetName(),
|
||||
Namespace: config.GetMetadata().GetNamespace(),
|
||||
ID: id,
|
||||
NetNS: sandbox.NetNSPath,
|
||||
PortMappings: toCNIPortMappings(config.GetPortMappings()),
|
||||
}
|
||||
if _, err = c.netPlugin.SetUpPod(podNetwork); err != nil {
|
||||
return nil, fmt.Errorf("failed to setup network for sandbox %q: %v", id, err)
|
||||
// Certain VM based solutions like clear containers (Issue containerd/cri-containerd#524)
|
||||
// rely on the assumption that CRI shim will not be querying the network namespace to check the
|
||||
// network states such as IP.
|
||||
// In future runtime implementation should avoid relying on CRI shim implementation details.
|
||||
// In this case however caching the IP will add a subtle performance enhancement by avoiding
|
||||
// calls to network namespace of the pod to query the IP of the veth interface on every
|
||||
// SandboxStatus request.
|
||||
sandbox.IP, err = c.setupPod(id, sandbox.NetNSPath, config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to setup network for sandbox %q", id)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
// Teardown network if an error is returned.
|
||||
if err := c.netPlugin.TearDownPod(podNetwork); err != nil {
|
||||
if err := c.teardownPod(id, sandbox.NetNSPath, config); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
||||
}
|
||||
}
|
||||
}()
|
||||
ip, err := c.netPlugin.GetPodNetworkStatus(podNetwork)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get network status for sandbox %q: %v", id, err)
|
||||
}
|
||||
// Certain VM based solutions like clear containers (Issue containerd/cri#524)
|
||||
// rely on the assumption that CRI shim will not be querying the network namespace to check the
|
||||
// network states such as IP.
|
||||
// In furture runtime implementation should avoid relying on CRI shim implementation details.
|
||||
// In this case however caching the IP will add a subtle performance enhancement by avoiding
|
||||
// calls to network namespace of the pod to query the IP of the veth interface on every
|
||||
// SandboxStatus request.
|
||||
sandbox.IP = ip
|
||||
}
|
||||
|
||||
ociRuntime, err := c.getSandboxRuntime(config)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get sandbox runtime")
|
||||
}
|
||||
logrus.Debugf("Use OCI %+v for sandbox %q", ociRuntime, id)
|
||||
|
||||
// Create sandbox container.
|
||||
spec, err := c.generateSandboxContainerSpec(id, config, &image.ImageSpec.Config, sandbox.NetNSPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate sandbox container spec: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to generate sandbox container spec")
|
||||
}
|
||||
logrus.Debugf("Sandbox container spec: %+v", spec)
|
||||
|
||||
@@ -167,7 +154,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
securityContext.GetPrivileged(),
|
||||
c.seccompEnabled)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate seccomp spec opts: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to generate seccomp spec opts")
|
||||
}
|
||||
if seccompSpecOpts != nil {
|
||||
specOpts = append(specOpts, seccompSpecOpts)
|
||||
@@ -182,15 +169,15 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
containerd.WithContainerLabels(sandboxLabels),
|
||||
containerd.WithContainerExtension(sandboxMetadataExtension, &sandbox.Metadata),
|
||||
containerd.WithRuntime(
|
||||
c.config.ContainerdConfig.Runtime,
|
||||
ociRuntime.Type,
|
||||
&runctypes.RuncOptions{
|
||||
Runtime: c.config.ContainerdConfig.RuntimeEngine,
|
||||
RuntimeRoot: c.config.ContainerdConfig.RuntimeRoot,
|
||||
Runtime: ociRuntime.Engine,
|
||||
RuntimeRoot: ociRuntime.Root,
|
||||
SystemdCgroup: c.config.SystemdCgroup})} // TODO (mikebrow): add CriuPath when we add support for pause
|
||||
|
||||
container, err := c.client.NewContainer(ctx, id, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create containerd container: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to create containerd container")
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -202,11 +189,11 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
}
|
||||
}()
|
||||
|
||||
// Create sandbox container root directory.
|
||||
sandboxRootDir := getSandboxRootDir(c.config.RootDir, id)
|
||||
// Create sandbox container root directories.
|
||||
sandboxRootDir := c.getSandboxRootDir(id)
|
||||
if err := c.os.MkdirAll(sandboxRootDir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create sandbox root directory %q: %v",
|
||||
sandboxRootDir, err)
|
||||
return nil, errors.Wrapf(err, "failed to create sandbox root directory %q",
|
||||
sandboxRootDir)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -217,14 +204,28 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Setup sandbox /dev/shm, /etc/hosts and /etc/resolv.conf.
|
||||
if err = c.setupSandboxFiles(sandboxRootDir, config); err != nil {
|
||||
return nil, fmt.Errorf("failed to setup sandbox files: %v", err)
|
||||
volatileSandboxRootDir := c.getVolatileSandboxRootDir(id)
|
||||
if err := c.os.MkdirAll(volatileSandboxRootDir, 0755); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to create volatile sandbox root directory %q",
|
||||
volatileSandboxRootDir)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
if err = c.unmountSandboxFiles(sandboxRootDir, config); err != nil {
|
||||
// Cleanup the volatile sandbox root directory.
|
||||
if err := c.os.RemoveAll(volatileSandboxRootDir); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to remove volatile sandbox root directory %q",
|
||||
volatileSandboxRootDir)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Setup sandbox /dev/shm, /etc/hosts and /etc/resolv.conf.
|
||||
if err = c.setupSandboxFiles(id, config); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to setup sandbox files")
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
if err = c.unmountSandboxFiles(id, config); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to unmount sandbox files in %q",
|
||||
sandboxRootDir)
|
||||
}
|
||||
@@ -234,19 +235,19 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
// Update sandbox created timestamp.
|
||||
info, err := container.Info(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sandbox container info: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get sandbox container info")
|
||||
}
|
||||
if err := sandbox.Status.Update(func(status sandboxstore.Status) (sandboxstore.Status, error) {
|
||||
status.CreatedAt = info.CreatedAt
|
||||
return status, nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to update sandbox created timestamp: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to update sandbox created timestamp")
|
||||
}
|
||||
|
||||
// Add sandbox into sandbox store in UNKNOWN state.
|
||||
sandbox.Container = container
|
||||
if err := c.sandboxStore.Add(sandbox); err != nil {
|
||||
return nil, fmt.Errorf("failed to add sandbox %+v into store: %v", sandbox, err)
|
||||
return nil, errors.Wrapf(err, "failed to add sandbox %+v into store", sandbox)
|
||||
}
|
||||
defer func() {
|
||||
// Delete sandbox from sandbox store if there is an error.
|
||||
@@ -287,7 +288,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
// We don't need stdio for sandbox container.
|
||||
task, err := container.NewTask(ctx, containerdio.NullIO)
|
||||
if err != nil {
|
||||
return status, fmt.Errorf("failed to create containerd task: %v", err)
|
||||
return status, errors.Wrap(err, "failed to create containerd task")
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
@@ -302,8 +303,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
}()
|
||||
|
||||
if err := task.Start(ctx); err != nil {
|
||||
return status, fmt.Errorf("failed to start sandbox container task %q: %v",
|
||||
id, err)
|
||||
return status, errors.Wrapf(err, "failed to start sandbox container task %q", id)
|
||||
}
|
||||
|
||||
// Set the pod sandbox as ready after successfully start sandbox container.
|
||||
@@ -311,13 +311,13 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
status.State = sandboxstore.StateReady
|
||||
return status, nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to start sandbox container: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to start sandbox container")
|
||||
}
|
||||
|
||||
return &runtime.RunPodSandboxResponse{PodSandboxId: id}, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) generateSandboxContainerSpec(id string, config *runtime.PodSandboxConfig,
|
||||
func (c *criService) generateSandboxContainerSpec(id string, config *runtime.PodSandboxConfig,
|
||||
imageConfig *imagespec.ImageConfig, nsPath string) (*runtimespec.Spec, error) {
|
||||
// Creates a spec Generator with the default spec.
|
||||
// TODO(random-liu): [P1] Compare the default settings with docker and containerd default.
|
||||
@@ -338,7 +338,7 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
|
||||
|
||||
if len(imageConfig.Entrypoint) == 0 {
|
||||
// Pause image must have entrypoint.
|
||||
return nil, fmt.Errorf("invalid empty entrypoint in image config %+v", imageConfig)
|
||||
return nil, errors.Errorf("invalid empty entrypoint in image config %+v", imageConfig)
|
||||
}
|
||||
// Set process commands.
|
||||
g.SetProcessArgs(append(imageConfig.Entrypoint, imageConfig.Cmd...))
|
||||
@@ -383,7 +383,7 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
|
||||
selinuxOpt := securityContext.GetSelinuxOptions()
|
||||
processLabel, mountLabel, err := initSelinuxOpts(selinuxOpt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init selinux options %+v: %v", securityContext.GetSelinuxOptions(), err)
|
||||
return nil, errors.Wrapf(err, "failed to init selinux options %+v", securityContext.GetSelinuxOptions())
|
||||
}
|
||||
g.SetProcessSelinuxLabel(processLabel)
|
||||
g.SetLinuxMountLabel(mountLabel)
|
||||
@@ -412,11 +412,11 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
|
||||
|
||||
// setupSandboxFiles sets up necessary sandbox files including /dev/shm, /etc/hosts
|
||||
// and /etc/resolv.conf.
|
||||
func (c *criContainerdService) setupSandboxFiles(rootDir string, config *runtime.PodSandboxConfig) error {
|
||||
func (c *criService) setupSandboxFiles(id string, config *runtime.PodSandboxConfig) error {
|
||||
// TODO(random-liu): Consider whether we should maintain /etc/hosts and /etc/resolv.conf in kubelet.
|
||||
sandboxEtcHosts := getSandboxHosts(rootDir)
|
||||
sandboxEtcHosts := c.getSandboxHosts(id)
|
||||
if err := c.os.CopyFile(etcHosts, sandboxEtcHosts, 0644); err != nil {
|
||||
return fmt.Errorf("failed to generate sandbox hosts file %q: %v", sandboxEtcHosts, err)
|
||||
return errors.Wrapf(err, "failed to generate sandbox hosts file %q", sandboxEtcHosts)
|
||||
}
|
||||
|
||||
// Set DNS options. Maintain a resolv.conf for the sandbox.
|
||||
@@ -425,36 +425,36 @@ func (c *criContainerdService) setupSandboxFiles(rootDir string, config *runtime
|
||||
if dnsConfig := config.GetDnsConfig(); dnsConfig != nil {
|
||||
resolvContent, err = parseDNSOptions(dnsConfig.Servers, dnsConfig.Searches, dnsConfig.Options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse sandbox DNSConfig %+v: %v", dnsConfig, err)
|
||||
return errors.Wrapf(err, "failed to parse sandbox DNSConfig %+v", dnsConfig)
|
||||
}
|
||||
}
|
||||
resolvPath := getResolvPath(rootDir)
|
||||
resolvPath := c.getResolvPath(id)
|
||||
if resolvContent == "" {
|
||||
// copy host's resolv.conf to resolvPath
|
||||
err = c.os.CopyFile(resolvConfPath, resolvPath, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy host's resolv.conf to %q: %v", resolvPath, err)
|
||||
return errors.Wrapf(err, "failed to copy host's resolv.conf to %q", resolvPath)
|
||||
}
|
||||
} else {
|
||||
err = c.os.WriteFile(resolvPath, []byte(resolvContent), 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write resolv content to %q: %v", resolvPath, err)
|
||||
return errors.Wrapf(err, "failed to write resolv content to %q", resolvPath)
|
||||
}
|
||||
}
|
||||
|
||||
// Setup sandbox /dev/shm.
|
||||
if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetIpc() == runtime.NamespaceMode_NODE {
|
||||
if _, err := c.os.Stat(devShm); err != nil {
|
||||
return fmt.Errorf("host %q is not available for host ipc: %v", devShm, err)
|
||||
return errors.Wrapf(err, "host %q is not available for host ipc", devShm)
|
||||
}
|
||||
} else {
|
||||
sandboxDevShm := getSandboxDevShm(rootDir)
|
||||
sandboxDevShm := c.getSandboxDevShm(id)
|
||||
if err := c.os.MkdirAll(sandboxDevShm, 0700); err != nil {
|
||||
return fmt.Errorf("failed to create sandbox shm: %v", err)
|
||||
return errors.Wrap(err, "failed to create sandbox shm")
|
||||
}
|
||||
shmproperty := fmt.Sprintf("mode=1777,size=%d", defaultShmSize)
|
||||
if err := c.os.Mount("shm", sandboxDevShm, "tmpfs", uintptr(unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV), shmproperty); err != nil {
|
||||
return fmt.Errorf("failed to mount sandbox shm: %v", err)
|
||||
return errors.Wrap(err, "failed to mount sandbox shm")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ func parseDNSOptions(servers, searches, options []string) (string, error) {
|
||||
resolvContent := ""
|
||||
|
||||
if len(searches) > maxDNSSearches {
|
||||
return "", fmt.Errorf("DNSOption.Searches has more than 6 domains")
|
||||
return "", errors.New("DNSOption.Searches has more than 6 domains")
|
||||
}
|
||||
|
||||
if len(searches) > 0 {
|
||||
@@ -489,23 +489,52 @@ func parseDNSOptions(servers, searches, options []string) (string, error) {
|
||||
// remove these files. Unmount should *NOT* return error when:
|
||||
// 1) The mount point is already unmounted.
|
||||
// 2) The mount point doesn't exist.
|
||||
func (c *criContainerdService) unmountSandboxFiles(rootDir string, config *runtime.PodSandboxConfig) error {
|
||||
func (c *criService) unmountSandboxFiles(id string, config *runtime.PodSandboxConfig) error {
|
||||
if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetIpc() != runtime.NamespaceMode_NODE {
|
||||
if err := c.os.Unmount(getSandboxDevShm(rootDir), unix.MNT_DETACH); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
path, err := c.os.FollowSymlinkInScope(c.getSandboxDevShm(id), "/")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to follow symlink")
|
||||
}
|
||||
if err := c.os.Unmount(path, unix.MNT_DETACH); err != nil && !os.IsNotExist(err) {
|
||||
return errors.Wrapf(err, "failed to unmount %q", path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setupPod setups up the network for a pod
|
||||
func (c *criService) setupPod(id string, path string, config *runtime.PodSandboxConfig) (string, error) {
|
||||
if c.netPlugin == nil {
|
||||
return "", errors.New("cni config not intialized")
|
||||
}
|
||||
|
||||
labels := getPodCNILabels(id, config)
|
||||
result, err := c.netPlugin.Setup(id,
|
||||
path,
|
||||
cni.WithLabels(labels),
|
||||
cni.WithCapabilityPortMap(toCNIPortMappings(config.GetPortMappings())))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// Check if the default interface has IP config
|
||||
if configs, ok := result.Interfaces[defaultIfName]; ok && len(configs.IPConfigs) > 0 {
|
||||
return configs.IPConfigs[0].IP.String(), nil
|
||||
}
|
||||
// If it comes here then the result was invalid so destroy the pod network and return error
|
||||
if err := c.teardownPod(id, path, config); err != nil {
|
||||
logrus.WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
||||
}
|
||||
return "", errors.Errorf("failed to find network info for sandbox %q", id)
|
||||
}
|
||||
|
||||
// toCNIPortMappings converts CRI port mappings to CNI.
|
||||
func toCNIPortMappings(criPortMappings []*runtime.PortMapping) []ocicni.PortMapping {
|
||||
var portMappings []ocicni.PortMapping
|
||||
func toCNIPortMappings(criPortMappings []*runtime.PortMapping) []cni.PortMapping {
|
||||
var portMappings []cni.PortMapping
|
||||
for _, mapping := range criPortMappings {
|
||||
if mapping.HostPort <= 0 {
|
||||
continue
|
||||
}
|
||||
portMappings = append(portMappings, ocicni.PortMapping{
|
||||
portMappings = append(portMappings, cni.PortMapping{
|
||||
HostPort: mapping.HostPort,
|
||||
ContainerPort: mapping.ContainerPort,
|
||||
Protocol: strings.ToLower(mapping.Protocol.String()),
|
||||
@@ -514,3 +543,48 @@ func toCNIPortMappings(criPortMappings []*runtime.PortMapping) []ocicni.PortMapp
|
||||
}
|
||||
return portMappings
|
||||
}
|
||||
|
||||
// untrustedWorkload returns true if the sandbox contains untrusted workload.
|
||||
func untrustedWorkload(config *runtime.PodSandboxConfig) bool {
|
||||
return config.GetAnnotations()[annotations.UntrustedWorkload] == "true"
|
||||
}
|
||||
|
||||
// hostPrivilegedSandbox returns true if the sandbox configuration
|
||||
// requires additional host privileges for the sandbox.
|
||||
func hostPrivilegedSandbox(config *runtime.PodSandboxConfig) bool {
|
||||
securityContext := config.GetLinux().GetSecurityContext()
|
||||
if securityContext.GetPrivileged() {
|
||||
return true
|
||||
}
|
||||
|
||||
namespaceOptions := securityContext.GetNamespaceOptions()
|
||||
if namespaceOptions.GetNetwork() == runtime.NamespaceMode_NODE ||
|
||||
namespaceOptions.GetPid() == runtime.NamespaceMode_NODE ||
|
||||
namespaceOptions.GetIpc() == runtime.NamespaceMode_NODE {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// getSandboxRuntime returns the runtime configuration for sandbox.
|
||||
// If the sandbox contains untrusted workload, runtime for untrusted workload will be returned,
|
||||
// or else default runtime will be returned.
|
||||
func (c *criService) getSandboxRuntime(config *runtime.PodSandboxConfig) (criconfig.Runtime, error) {
|
||||
untrusted := false
|
||||
if untrustedWorkload(config) {
|
||||
// TODO(random-liu): Figure out we should return error or not.
|
||||
if hostPrivilegedSandbox(config) {
|
||||
return criconfig.Runtime{}, errors.New("untrusted workload with host privilege is not allowed")
|
||||
}
|
||||
untrusted = true
|
||||
}
|
||||
|
||||
if untrusted {
|
||||
if c.config.ContainerdConfig.UntrustedWorkloadRuntime.Type == "" {
|
||||
return criconfig.Runtime{}, errors.New("no runtime for untrusted workload is configured")
|
||||
}
|
||||
return c.config.ContainerdConfig.UntrustedWorkloadRuntime, nil
|
||||
}
|
||||
return c.config.ContainerdConfig.DefaultRuntime, nil
|
||||
}
|
||||
|
||||
28
vendor/github.com/containerd/cri/pkg/server/sandbox_status.go
generated
vendored
28
vendor/github.com/containerd/cri/pkg/server/sandbox_status.go
generated
vendored
@@ -18,22 +18,23 @@ package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
|
||||
criconfig "github.com/containerd/cri/pkg/config"
|
||||
sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
|
||||
)
|
||||
|
||||
// PodSandboxStatus returns the status of the PodSandbox.
|
||||
func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandboxStatusRequest) (*runtime.PodSandboxStatusResponse, error) {
|
||||
func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandboxStatusRequest) (*runtime.PodSandboxStatusResponse, error) {
|
||||
sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find sandbox: %v", err)
|
||||
return nil, errors.Wrap(err, "an error occurred when try to find sandbox")
|
||||
}
|
||||
|
||||
ip := c.getIP(sandbox)
|
||||
@@ -45,7 +46,7 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime.
|
||||
// Generate verbose information.
|
||||
info, err := toCRISandboxInfo(ctx, sandbox)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get verbose sandbox container info: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get verbose sandbox container info")
|
||||
}
|
||||
|
||||
return &runtime.PodSandboxStatusResponse{
|
||||
@@ -54,7 +55,7 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime.
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *criContainerdService) getIP(sandbox sandboxstore.Sandbox) string {
|
||||
func (c *criService) getIP(sandbox sandboxstore.Sandbox) string {
|
||||
config := sandbox.Config
|
||||
|
||||
if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
||||
@@ -107,6 +108,7 @@ type sandboxInfo struct {
|
||||
Image string `json:"image"`
|
||||
SnapshotKey string `json:"snapshotKey"`
|
||||
Snapshotter string `json:"snapshotter"`
|
||||
Runtime *criconfig.Runtime `json:"runtime"`
|
||||
Config *runtime.PodSandboxConfig `json:"config"`
|
||||
RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"`
|
||||
}
|
||||
@@ -116,14 +118,14 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
|
||||
container := sandbox.Container
|
||||
task, err := container.Task(ctx, nil)
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return nil, fmt.Errorf("failed to get sandbox container task: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get sandbox container task")
|
||||
}
|
||||
|
||||
var processStatus containerd.ProcessStatus
|
||||
if task != nil {
|
||||
taskStatus, err := task.Status(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get task status: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get task status")
|
||||
}
|
||||
|
||||
processStatus = taskStatus.Status
|
||||
@@ -148,13 +150,13 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
|
||||
|
||||
spec, err := container.Spec(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sandbox container runtime spec: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get sandbox container runtime spec")
|
||||
}
|
||||
si.RuntimeSpec = spec
|
||||
|
||||
ctrInfo, err := container.Info(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get sandbox container info: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get sandbox container info")
|
||||
}
|
||||
// Do not use config.SandboxImage because the configuration might
|
||||
// be changed during restart. It may not reflect the actual image
|
||||
@@ -163,9 +165,15 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
|
||||
si.SnapshotKey = ctrInfo.SnapshotKey
|
||||
si.Snapshotter = ctrInfo.Snapshotter
|
||||
|
||||
ociRuntime, err := getRuntimeConfigFromContainerInfo(ctrInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get sandbox container runtime config")
|
||||
}
|
||||
si.Runtime = &ociRuntime
|
||||
|
||||
infoBytes, err := json.Marshal(si)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal info %v: %v", si, err)
|
||||
return nil, errors.Wrapf(err, "failed to marshal info %v", si)
|
||||
}
|
||||
return map[string]string{
|
||||
"info": string(infoBytes),
|
||||
|
||||
58
vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go
generated
vendored
58
vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go
generated
vendored
@@ -17,13 +17,13 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
cni "github.com/containerd/go-cni"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -33,11 +33,11 @@ import (
|
||||
|
||||
// StopPodSandbox stops the sandbox. If there are any running containers in the
|
||||
// sandbox, they should be forcibly terminated.
|
||||
func (c *criContainerdService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandboxRequest) (*runtime.StopPodSandboxResponse, error) {
|
||||
func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandboxRequest) (*runtime.StopPodSandboxResponse, error) {
|
||||
sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("an error occurred when try to find sandbox %q: %v",
|
||||
r.GetPodSandboxId(), err)
|
||||
return nil, errors.Wrapf(err, "an error occurred when try to find sandbox %q",
|
||||
r.GetPodSandboxId())
|
||||
}
|
||||
// Use the full sandbox id.
|
||||
id := sandbox.ID
|
||||
@@ -54,7 +54,7 @@ func (c *criContainerdService) StopPodSandbox(ctx context.Context, r *runtime.St
|
||||
// Forcibly stop the container. Do not use `StopContainer`, because it introduces a race
|
||||
// if a container is removed after list.
|
||||
if err = c.stopContainer(ctx, container, 0); err != nil {
|
||||
return nil, fmt.Errorf("failed to stop container %q: %v", container.ID, err)
|
||||
return nil, errors.Wrapf(err, "failed to stop container %q", container.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,17 +62,11 @@ func (c *criContainerdService) StopPodSandbox(ctx context.Context, r *runtime.St
|
||||
if sandbox.NetNSPath != "" && sandbox.NetNS != nil {
|
||||
if _, err := os.Stat(sandbox.NetNSPath); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("failed to stat network namespace path %s :%v", sandbox.NetNSPath, err)
|
||||
return nil, errors.Wrapf(err, "failed to stat network namespace path %s", sandbox.NetNSPath)
|
||||
}
|
||||
} else {
|
||||
if teardownErr := c.netPlugin.TearDownPod(ocicni.PodNetwork{
|
||||
Name: sandbox.Config.GetMetadata().GetName(),
|
||||
Namespace: sandbox.Config.GetMetadata().GetNamespace(),
|
||||
ID: id,
|
||||
NetNS: sandbox.NetNSPath,
|
||||
PortMappings: toCNIPortMappings(sandbox.Config.GetPortMappings()),
|
||||
}); teardownErr != nil {
|
||||
return nil, fmt.Errorf("failed to destroy network for sandbox %q: %v", id, teardownErr)
|
||||
if teardownErr := c.teardownPod(id, sandbox.NetNSPath, sandbox.Config); teardownErr != nil {
|
||||
return nil, errors.Wrapf(teardownErr, "failed to destroy network for sandbox %q", id)
|
||||
}
|
||||
}
|
||||
/*TODO:It is still possible that containerd crashes after we teardown the network, but before we remove the network namespace.
|
||||
@@ -81,56 +75,68 @@ func (c *criContainerdService) StopPodSandbox(ctx context.Context, r *runtime.St
|
||||
|
||||
//Close the sandbox network namespace if it was created
|
||||
if err = sandbox.NetNS.Remove(); err != nil {
|
||||
return nil, fmt.Errorf("failed to remove network namespace for sandbox %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Infof("TearDown network for sandbox %q successfully", id)
|
||||
|
||||
sandboxRoot := getSandboxRootDir(c.config.RootDir, id)
|
||||
if err := c.unmountSandboxFiles(sandboxRoot, sandbox.Config); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmount sandbox files in %q: %v", sandboxRoot, err)
|
||||
if err := c.unmountSandboxFiles(id, sandbox.Config); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmount sandbox files")
|
||||
}
|
||||
|
||||
// Only stop sandbox container when it's running.
|
||||
if sandbox.Status.Get().State == sandboxstore.StateReady {
|
||||
if err := c.stopSandboxContainer(ctx, sandbox); err != nil {
|
||||
return nil, fmt.Errorf("failed to stop sandbox container %q: %v", id, err)
|
||||
return nil, errors.Wrapf(err, "failed to stop sandbox container %q", id)
|
||||
}
|
||||
}
|
||||
return &runtime.StopPodSandboxResponse{}, nil
|
||||
}
|
||||
|
||||
// stopSandboxContainer kills and deletes sandbox container.
|
||||
func (c *criContainerdService) stopSandboxContainer(ctx context.Context, sandbox sandboxstore.Sandbox) error {
|
||||
func (c *criService) stopSandboxContainer(ctx context.Context, sandbox sandboxstore.Sandbox) error {
|
||||
container := sandbox.Container
|
||||
task, err := container.Task(ctx, nil)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to get sandbox container: %v", err)
|
||||
return errors.Wrap(err, "failed to get sandbox container")
|
||||
}
|
||||
|
||||
// Delete the sandbox container from containerd.
|
||||
_, err = task.Delete(ctx, containerd.WithProcessKill)
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to delete sandbox container: %v", err)
|
||||
return errors.Wrap(err, "failed to delete sandbox container")
|
||||
}
|
||||
|
||||
return c.waitSandboxStop(ctx, sandbox, killContainerTimeout)
|
||||
}
|
||||
|
||||
// waitSandboxStop waits for sandbox to be stopped until timeout exceeds or context is cancelled.
|
||||
func (c *criContainerdService) waitSandboxStop(ctx context.Context, sandbox sandboxstore.Sandbox, timeout time.Duration) error {
|
||||
func (c *criService) waitSandboxStop(ctx context.Context, sandbox sandboxstore.Sandbox, timeout time.Duration) error {
|
||||
timeoutTimer := time.NewTimer(timeout)
|
||||
defer timeoutTimer.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("wait sandbox container %q is cancelled", sandbox.ID)
|
||||
return errors.Errorf("wait sandbox container %q is cancelled", sandbox.ID)
|
||||
case <-timeoutTimer.C:
|
||||
return fmt.Errorf("wait sandbox container %q stop timeout", sandbox.ID)
|
||||
return errors.Errorf("wait sandbox container %q stop timeout", sandbox.ID)
|
||||
case <-sandbox.Stopped():
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// teardownPod removes the network from the pod
|
||||
func (c *criService) teardownPod(id string, path string, config *runtime.PodSandboxConfig) error {
|
||||
if c.netPlugin == nil {
|
||||
return errors.New("cni config not intialized")
|
||||
}
|
||||
|
||||
labels := getPodCNILabels(id, config)
|
||||
return c.netPlugin.Remove(id,
|
||||
path,
|
||||
cni.WithLabels(labels),
|
||||
cni.WithCapabilityPortMap(toCNIPortMappings(config.GetPortMappings())))
|
||||
}
|
||||
|
||||
62
vendor/github.com/containerd/cri/pkg/server/service.go
generated
vendored
62
vendor/github.com/containerd/cri/pkg/server/service.go
generated
vendored
@@ -24,10 +24,11 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
cni "github.com/containerd/go-cni"
|
||||
runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor"
|
||||
runcseccomp "github.com/opencontainers/runc/libcontainer/seccomp"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
@@ -49,11 +50,11 @@ import (
|
||||
type grpcServices interface {
|
||||
runtime.RuntimeServiceServer
|
||||
runtime.ImageServiceServer
|
||||
api.CRIContainerdServiceServer
|
||||
api.CRIPluginServiceServer
|
||||
}
|
||||
|
||||
// CRIContainerdService is the interface implement CRI remote service server.
|
||||
type CRIContainerdService interface {
|
||||
// CRIService is the interface implement CRI remote service server.
|
||||
type CRIService interface {
|
||||
Run() error
|
||||
// io.Closer is used by containerd to gracefully stop cri service.
|
||||
io.Closer
|
||||
@@ -61,8 +62,8 @@ type CRIContainerdService interface {
|
||||
grpcServices
|
||||
}
|
||||
|
||||
// criContainerdService implements CRIContainerdService.
|
||||
type criContainerdService struct {
|
||||
// criService implements CRIService.
|
||||
type criService struct {
|
||||
// config contains all configurations.
|
||||
config criconfig.Config
|
||||
// imageFSPath is the path to image filesystem.
|
||||
@@ -88,7 +89,7 @@ type criContainerdService struct {
|
||||
// snapshotStore stores information of all snapshots.
|
||||
snapshotStore *snapshotstore.Store
|
||||
// netPlugin is used to setup and teardown network when run/stop pod sandbox.
|
||||
netPlugin ocicni.CNIPlugin
|
||||
netPlugin cni.CNI
|
||||
// client is an instance of the containerd client
|
||||
client *containerd.Client
|
||||
// streamServer is the streaming server serves container streaming request.
|
||||
@@ -100,10 +101,10 @@ type criContainerdService struct {
|
||||
initialized atomic.Bool
|
||||
}
|
||||
|
||||
// NewCRIContainerdService returns a new instance of CRIContainerdService
|
||||
func NewCRIContainerdService(config criconfig.Config, client *containerd.Client) (CRIContainerdService, error) {
|
||||
// NewCRIService returns a new instance of CRIService
|
||||
func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIService, error) {
|
||||
var err error
|
||||
c := &criContainerdService{
|
||||
c := &criService{
|
||||
config: config,
|
||||
client: client,
|
||||
apparmorEnabled: runcapparmor.IsEnabled(),
|
||||
@@ -129,15 +130,26 @@ func NewCRIContainerdService(config criconfig.Config, client *containerd.Client)
|
||||
c.imageFSPath = imageFSPath(config.ContainerdRootDir, config.ContainerdConfig.Snapshotter)
|
||||
logrus.Infof("Get image filesystem path %q", c.imageFSPath)
|
||||
|
||||
c.netPlugin, err = ocicni.InitCNI(config.NetworkPluginConfDir, config.NetworkPluginBinDir)
|
||||
// Pod needs to attach to atleast loopback network and a non host network,
|
||||
// hence networkAttachCount is 2. If there are more network configs the
|
||||
// pod will be attached to all the networks but we will only use the ip
|
||||
// of the default network interface as the pod IP.
|
||||
c.netPlugin, err = cni.New(cni.WithMinNetworkCount(networkAttachCount),
|
||||
cni.WithPluginConfDir(config.NetworkPluginConfDir),
|
||||
cni.WithPluginDir([]string{config.NetworkPluginBinDir}))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize cni plugin: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to initialize cni")
|
||||
}
|
||||
|
||||
// Try to load the config if it exists. Just log the error if load fails
|
||||
// This is not disruptive for containerd to panic
|
||||
if err := c.netPlugin.Load(cni.WithLoNetwork(), cni.WithDefaultConf()); err != nil {
|
||||
logrus.WithError(err).Error("Failed to load cni during init, please check CRI plugin status before setting up network for pods")
|
||||
}
|
||||
// prepare streaming server
|
||||
c.streamServer, err = newStreamServer(c, config.StreamServerAddress, config.StreamServerPort)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create stream server: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to create stream server")
|
||||
}
|
||||
|
||||
c.eventMonitor = newEventMonitor(c.containerStore, c.sandboxStore)
|
||||
@@ -147,29 +159,29 @@ func NewCRIContainerdService(config criconfig.Config, client *containerd.Client)
|
||||
|
||||
// Register registers all required services onto a specific grpc server.
|
||||
// This is used by containerd cri plugin.
|
||||
func (c *criContainerdService) Register(s *grpc.Server) error {
|
||||
func (c *criService) Register(s *grpc.Server) error {
|
||||
instrumented := newInstrumentedService(c)
|
||||
runtime.RegisterRuntimeServiceServer(s, instrumented)
|
||||
runtime.RegisterImageServiceServer(s, instrumented)
|
||||
api.RegisterCRIContainerdServiceServer(s, instrumented)
|
||||
api.RegisterCRIPluginServiceServer(s, instrumented)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run starts the cri-containerd service.
|
||||
func (c *criContainerdService) Run() error {
|
||||
// Run starts the CRI service.
|
||||
func (c *criService) Run() error {
|
||||
logrus.Info("Start subscribing containerd event")
|
||||
c.eventMonitor.subscribe(c.client)
|
||||
|
||||
logrus.Infof("Start recovering state")
|
||||
if err := c.recover(ctrdutil.NamespacedContext()); err != nil {
|
||||
return fmt.Errorf("failed to recover state: %v", err)
|
||||
return errors.Wrap(err, "failed to recover state")
|
||||
}
|
||||
|
||||
// Start event handler.
|
||||
logrus.Info("Start event monitor")
|
||||
eventMonitorCloseCh, err := c.eventMonitor.start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start event monitor: %v", err)
|
||||
return errors.Wrap(err, "failed to start event monitor")
|
||||
}
|
||||
|
||||
// Start snapshot stats syncer, it doesn't need to be stopped.
|
||||
@@ -194,13 +206,13 @@ func (c *criContainerdService) Run() error {
|
||||
// Set the server as initialized. GRPC services could start serving traffic.
|
||||
c.initialized.Set()
|
||||
|
||||
// Stop the whole cri-containerd service if any of the critical service exits.
|
||||
// Stop the whole CRI service if any of the critical service exits.
|
||||
select {
|
||||
case <-eventMonitorCloseCh:
|
||||
case <-streamServerCloseCh:
|
||||
}
|
||||
if err := c.Close(); err != nil {
|
||||
return fmt.Errorf("failed to stop cri service: %v", err)
|
||||
return errors.Wrap(err, "failed to stop cri service")
|
||||
}
|
||||
|
||||
<-eventMonitorCloseCh
|
||||
@@ -223,13 +235,13 @@ func (c *criContainerdService) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop stops the cri-containerd service.
|
||||
func (c *criContainerdService) Close() error {
|
||||
logrus.Info("Stop cri-containerd service")
|
||||
// Stop stops the CRI service.
|
||||
func (c *criService) Close() error {
|
||||
logrus.Info("Stop CRI service")
|
||||
// TODO(random-liu): Make event monitor stop synchronous.
|
||||
c.eventMonitor.stop()
|
||||
if err := c.streamServer.Stop(); err != nil {
|
||||
return fmt.Errorf("failed to stop stream server: %v", err)
|
||||
return errors.Wrap(err, "failed to stop stream server")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/server/snapshots.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/server/snapshots.go
generated
vendored
@@ -18,11 +18,11 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
snapshot "github.com/containerd/containerd/snapshots"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
@@ -80,7 +80,7 @@ func (s *snapshotsSyncer) sync() error {
|
||||
snapshots = append(snapshots, info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("walk all snapshots failed: %v", err)
|
||||
return errors.Wrap(err, "walk all snapshots failed")
|
||||
}
|
||||
for _, info := range snapshots {
|
||||
sn, err := s.store.Get(info.Name)
|
||||
|
||||
13
vendor/github.com/containerd/cri/pkg/server/status.go
generated
vendored
13
vendor/github.com/containerd/cri/pkg/server/status.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
"fmt"
|
||||
goruntime "runtime"
|
||||
|
||||
cni "github.com/containerd/go-cni"
|
||||
"golang.org/x/net/context"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
@@ -29,7 +30,7 @@ import (
|
||||
const networkNotReadyReason = "NetworkPluginNotReady"
|
||||
|
||||
// Status returns the status of the runtime.
|
||||
func (c *criContainerdService) Status(ctx context.Context, r *runtime.StatusRequest) (*runtime.StatusResponse, error) {
|
||||
func (c *criService) Status(ctx context.Context, r *runtime.StatusRequest) (*runtime.StatusResponse, error) {
|
||||
// As a containerd plugin, if CRI plugin is serving request,
|
||||
// containerd must be ready.
|
||||
runtimeCondition := &runtime.RuntimeCondition{
|
||||
@@ -40,10 +41,14 @@ func (c *criContainerdService) Status(ctx context.Context, r *runtime.StatusRequ
|
||||
Type: runtime.NetworkReady,
|
||||
Status: true,
|
||||
}
|
||||
// Check the status of the cni initialization
|
||||
if err := c.netPlugin.Status(); err != nil {
|
||||
networkCondition.Status = false
|
||||
networkCondition.Reason = networkNotReadyReason
|
||||
networkCondition.Message = fmt.Sprintf("Network plugin returns error: %v", err)
|
||||
// If it is not initialized, then load the config and retry
|
||||
if err = c.netPlugin.Load(cni.WithLoNetwork(), cni.WithDefaultConf()); err != nil {
|
||||
networkCondition.Status = false
|
||||
networkCondition.Reason = networkNotReadyReason
|
||||
networkCondition.Message = fmt.Sprintf("Network plugin returns error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
resp := &runtime.StatusResponse{
|
||||
|
||||
124
vendor/github.com/containerd/cri/pkg/server/streaming.go
generated
vendored
124
vendor/github.com/containerd/cri/pkg/server/streaming.go
generated
vendored
@@ -17,39 +17,65 @@ limitations under the License.
|
||||
package server
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
k8snet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
k8scert "k8s.io/client-go/util/cert"
|
||||
"k8s.io/kubernetes/pkg/kubelet/server/streaming"
|
||||
"k8s.io/utils/exec"
|
||||
|
||||
ctrdutil "github.com/containerd/cri/pkg/containerd/util"
|
||||
)
|
||||
|
||||
func newStreamServer(c *criContainerdService, addr, port string) (streaming.Server, error) {
|
||||
const (
|
||||
// certOrganizationName is the name of this organization, used for certificates etc.
|
||||
certOrganizationName = "containerd"
|
||||
// certCommonName is the common name of the CRI plugin
|
||||
certCommonName = "cri"
|
||||
)
|
||||
|
||||
func newStreamServer(c *criService, addr, port string) (streaming.Server, error) {
|
||||
if addr == "" {
|
||||
a, err := k8snet.ChooseBindAddress(nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get stream server address: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to get stream server address")
|
||||
}
|
||||
addr = a.String()
|
||||
}
|
||||
config := streaming.DefaultConfig
|
||||
config.Addr = net.JoinHostPort(addr, port)
|
||||
runtime := newStreamRuntime(c)
|
||||
tlsCert, err := newTLSCert()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to generate tls certificate for stream server")
|
||||
}
|
||||
config.TLSConfig = &tls.Config{
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
return streaming.NewServer(config, runtime)
|
||||
}
|
||||
|
||||
type streamRuntime struct {
|
||||
c *criContainerdService
|
||||
c *criService
|
||||
}
|
||||
|
||||
func newStreamRuntime(c *criContainerdService) streaming.Runtime {
|
||||
func newStreamRuntime(c *criService) streaming.Runtime {
|
||||
return &streamRuntime{c: c}
|
||||
}
|
||||
|
||||
@@ -66,13 +92,13 @@ func (s *streamRuntime) Exec(containerID string, cmd []string, stdin io.Reader,
|
||||
resize: resize,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to exec in container: %v", err)
|
||||
return errors.Wrap(err, "failed to exec in container")
|
||||
}
|
||||
if *exitCode == 0 {
|
||||
return nil
|
||||
}
|
||||
return &exec.CodeExitError{
|
||||
Err: fmt.Errorf("error executing command %v, exit code %d", cmd, *exitCode),
|
||||
Err: errors.Errorf("error executing command %v, exit code %d", cmd, *exitCode),
|
||||
Code: int(*exitCode),
|
||||
}
|
||||
}
|
||||
@@ -84,7 +110,7 @@ func (s *streamRuntime) Attach(containerID string, in io.Reader, out, err io.Wri
|
||||
|
||||
func (s *streamRuntime) PortForward(podSandboxID string, port int32, stream io.ReadWriteCloser) error {
|
||||
if port <= 0 || port > math.MaxUint16 {
|
||||
return fmt.Errorf("invalid port %d", port)
|
||||
return errors.Errorf("invalid port %d", port)
|
||||
}
|
||||
return s.c.portForward(podSandboxID, port, stream)
|
||||
}
|
||||
@@ -112,3 +138,87 @@ func handleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(si
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// newTLSCert returns a tls.certificate loaded from a newly generated
|
||||
// x509certificate from a newly generated rsa public/private key pair. The
|
||||
// x509certificate is self signed.
|
||||
// TODO (mikebrow): replace / rewrite this function to support using CA
|
||||
// signing of the cetificate. Requires a security plan for kubernetes regarding
|
||||
// CRI connections / streaming, etc. For example, kubernetes could configure or
|
||||
// require a CA service and pass a configuration down through CRI.
|
||||
func newTLSCert() (tls.Certificate, error) {
|
||||
fail := func(err error) (tls.Certificate, error) { return tls.Certificate{}, err }
|
||||
var years = 1 // duration of certificate
|
||||
|
||||
// Generate new private key
|
||||
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "private key cannot be created"))
|
||||
}
|
||||
|
||||
// Generate pem block using the private key
|
||||
keyPem := pem.EncodeToMemory(&pem.Block{
|
||||
Type: k8scert.RSAPrivateKeyBlockType,
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(privKey),
|
||||
})
|
||||
|
||||
// Generate a new random serial number for certificate
|
||||
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "failed to generate serial number"))
|
||||
}
|
||||
hostName, err := os.Hostname()
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "failed to get hostname"))
|
||||
}
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "failed to get host IP addresses"))
|
||||
}
|
||||
|
||||
// Configure and create new certificate
|
||||
tml := x509.Certificate{
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(years, 0, 0),
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
CommonName: fmt.Sprintf("%s:%s:%s", certOrganizationName, certCommonName, hostName),
|
||||
Organization: []string{certOrganizationName},
|
||||
},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
tml.IPAddresses = append(tml.IPAddresses, ip)
|
||||
tml.DNSNames = append(tml.DNSNames, ip.String())
|
||||
}
|
||||
|
||||
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &privKey.PublicKey, privKey)
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "certificate cannot be created"))
|
||||
}
|
||||
|
||||
// Generate a pem block with the certificate
|
||||
certPem := pem.EncodeToMemory(&pem.Block{
|
||||
Type: k8scert.CertificateBlockType,
|
||||
Bytes: cert,
|
||||
})
|
||||
|
||||
// Load the tls certificate
|
||||
tlsCert, err := tls.X509KeyPair(certPem, keyPem)
|
||||
if err != nil {
|
||||
return fail(errors.Wrap(err, "certificate could not be loaded"))
|
||||
}
|
||||
|
||||
return tlsCert, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/cri/pkg/server/update_runtime_config.go
generated
vendored
2
vendor/github.com/containerd/cri/pkg/server/update_runtime_config.go
generated
vendored
@@ -24,6 +24,6 @@ import (
|
||||
|
||||
// UpdateRuntimeConfig updates the runtime config. Currently only handles podCIDR updates.
|
||||
// TODO(random-liu): Figure out how to handle pod cidr in the cri plugin.
|
||||
func (c *criContainerdService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateRuntimeConfigRequest) (*runtime.UpdateRuntimeConfigResponse, error) {
|
||||
func (c *criService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateRuntimeConfigRequest) (*runtime.UpdateRuntimeConfigResponse, error) {
|
||||
return &runtime.UpdateRuntimeConfigResponse{}, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/containerd/cri/pkg/server/version.go
generated
vendored
2
vendor/github.com/containerd/cri/pkg/server/version.go
generated
vendored
@@ -32,7 +32,7 @@ const (
|
||||
)
|
||||
|
||||
// Version returns the runtime name, runtime version and runtime API version.
|
||||
func (c *criContainerdService) Version(ctx context.Context, r *runtime.VersionRequest) (*runtime.VersionResponse, error) {
|
||||
func (c *criService) Version(ctx context.Context, r *runtime.VersionRequest) (*runtime.VersionResponse, error) {
|
||||
return &runtime.VersionResponse{
|
||||
Version: kubeAPIVersion,
|
||||
RuntimeName: containerName,
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/store/container/metadata.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/store/container/metadata.go
generated
vendored
@@ -18,8 +18,8 @@ package container
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
@@ -80,5 +80,5 @@ func (c *Metadata) UnmarshalJSON(data []byte) error {
|
||||
*c = Metadata(versioned.Metadata)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unsupported version: %q", versioned.Version)
|
||||
return errors.Errorf("unsupported version: %q", versioned.Version)
|
||||
}
|
||||
|
||||
16
vendor/github.com/containerd/cri/pkg/store/container/status.go
generated
vendored
16
vendor/github.com/containerd/cri/pkg/store/container/status.go
generated
vendored
@@ -18,13 +18,13 @@ package container
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/pkg/errors"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
@@ -95,7 +95,7 @@ func (s *Status) decode(data []byte) error {
|
||||
*s = versioned.Status
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unsupported version")
|
||||
return errors.New("unsupported version")
|
||||
}
|
||||
|
||||
// UpdateFunc is function used to update the container status. If there
|
||||
@@ -125,11 +125,11 @@ type StatusStorage interface {
|
||||
func StoreStatus(root, id string, status Status) (StatusStorage, error) {
|
||||
data, err := status.encode()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encode status: %v", err)
|
||||
return nil, errors.Wrap(err, "failed to encode status")
|
||||
}
|
||||
path := filepath.Join(root, "status")
|
||||
if err := ioutils.AtomicWriteFile(path, data, 0600); err != nil {
|
||||
return nil, fmt.Errorf("failed to checkpoint status to %q: %v", path, err)
|
||||
return nil, errors.Wrapf(err, "failed to checkpoint status to %q", path)
|
||||
}
|
||||
return &statusStorage{
|
||||
path: path,
|
||||
@@ -143,11 +143,11 @@ func LoadStatus(root, id string) (Status, error) {
|
||||
path := filepath.Join(root, "status")
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return Status{}, fmt.Errorf("failed to read status from %q: %v", path, err)
|
||||
return Status{}, errors.Wrapf(err, "failed to read status from %q", path)
|
||||
}
|
||||
var status Status
|
||||
if err := status.decode(data); err != nil {
|
||||
return Status{}, fmt.Errorf("failed to decode status %q: %v", data, err)
|
||||
return Status{}, errors.Wrapf(err, "failed to decode status %q", data)
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
@@ -175,10 +175,10 @@ func (s *statusStorage) UpdateSync(u UpdateFunc) error {
|
||||
}
|
||||
data, err := newStatus.encode()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode status: %v", err)
|
||||
return errors.Wrap(err, "failed to encode status")
|
||||
}
|
||||
if err := ioutils.AtomicWriteFile(s.path, data, 0600); err != nil {
|
||||
return fmt.Errorf("failed to checkpoint status to %q: %v", s.path, err)
|
||||
return errors.Wrapf(err, "failed to checkpoint status to %q", s.path)
|
||||
}
|
||||
s.status = newStatus
|
||||
return nil
|
||||
|
||||
4
vendor/github.com/containerd/cri/pkg/store/sandbox/metadata.go
generated
vendored
4
vendor/github.com/containerd/cri/pkg/store/sandbox/metadata.go
generated
vendored
@@ -18,8 +18,8 @@ package sandbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
@@ -76,5 +76,5 @@ func (c *Metadata) UnmarshalJSON(data []byte) error {
|
||||
*c = Metadata(versioned.Metadata)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unsupported version: %q", versioned.Version)
|
||||
return errors.Errorf("unsupported version: %q", versioned.Version)
|
||||
}
|
||||
|
||||
30
vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go
generated
vendored
30
vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go
generated
vendored
@@ -17,15 +17,15 @@ limitations under the License.
|
||||
package sandbox
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
cnins "github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
osinterface "github.com/containerd/cri/pkg/os"
|
||||
)
|
||||
|
||||
// ErrClosedNetNS is the error returned when network namespace is closed.
|
||||
@@ -43,7 +43,7 @@ type NetNS struct {
|
||||
func NewNetNS() (*NetNS, error) {
|
||||
netns, err := cnins.NewNS()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup network namespace %v", err)
|
||||
return nil, errors.Wrap(err, "failed to setup network namespace")
|
||||
}
|
||||
n := new(NetNS)
|
||||
n.ns = netns
|
||||
@@ -63,7 +63,7 @@ func LoadNetNS(path string) (*NetNS, error) {
|
||||
os.RemoveAll(path) // nolint: errcheck
|
||||
return nil, ErrClosedNetNS
|
||||
}
|
||||
return nil, fmt.Errorf("failed to load network namespace %v", err)
|
||||
return nil, errors.Wrap(err, "failed to load network namespace")
|
||||
}
|
||||
return &NetNS{ns: ns, restored: true}, nil
|
||||
}
|
||||
@@ -76,36 +76,28 @@ func (n *NetNS) Remove() error {
|
||||
if !n.closed {
|
||||
err := n.ns.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to close network namespace: %v", err)
|
||||
return errors.Wrap(err, "failed to close network namespace")
|
||||
}
|
||||
n.closed = true
|
||||
}
|
||||
if n.restored {
|
||||
path := n.ns.Path()
|
||||
// TODO(random-liu): Add util function for unmount.
|
||||
// Check netns existence.
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to stat netns: %v", err)
|
||||
return errors.Wrap(err, "failed to stat netns")
|
||||
}
|
||||
path, err := symlink.FollowSymlinkInScope(path, "/")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to follow symlink: %v", err)
|
||||
return errors.Wrap(err, "failed to follow symlink")
|
||||
}
|
||||
mounted, err := mount.Mounted(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check netns mounted: %v", err)
|
||||
}
|
||||
if mounted {
|
||||
err := unix.Unmount(path, unix.MNT_DETACH)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("failed to umount netns: %v", err)
|
||||
}
|
||||
if err := osinterface.Unmount(path, unix.MNT_DETACH); err != nil && !os.IsNotExist(err) {
|
||||
return errors.Wrap(err, "failed to umount netns")
|
||||
}
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return fmt.Errorf("failed to remove netns: %v", err)
|
||||
return errors.Wrap(err, "failed to remove netns")
|
||||
}
|
||||
n.restored = false
|
||||
}
|
||||
|
||||
11
vendor/github.com/containerd/cri/pkg/util/deep_copy.go
generated
vendored
11
vendor/github.com/containerd/cri/pkg/util/deep_copy.go
generated
vendored
@@ -18,24 +18,25 @@ package util
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// DeepCopy makes a deep copy from src into dst.
|
||||
func DeepCopy(dst interface{}, src interface{}) error {
|
||||
if dst == nil {
|
||||
return fmt.Errorf("dst cannot be nil")
|
||||
return errors.New("dst cannot be nil")
|
||||
}
|
||||
if src == nil {
|
||||
return fmt.Errorf("src cannot be nil")
|
||||
return errors.New("src cannot be nil")
|
||||
}
|
||||
bytes, err := json.Marshal(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to marshal src: %s", err)
|
||||
return errors.Wrap(err, "unable to marshal src")
|
||||
}
|
||||
err = json.Unmarshal(bytes, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to unmarshal into dst: %s", err)
|
||||
return errors.Wrap(err, "unable to unmarshal into dst")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
31
vendor/github.com/containerd/cri/vendor.conf
generated
vendored
31
vendor/github.com/containerd/cri/vendor.conf
generated
vendored
@@ -3,16 +3,16 @@ github.com/blang/semver v3.1.0
|
||||
github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
|
||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||
github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130
|
||||
github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
|
||||
github.com/containerd/containerd 3013762fc58941e33ba70e8f8d9256911f134124
|
||||
github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371
|
||||
github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
|
||||
github.com/containerd/go-runc 4f6e87ae043f859a38255247b49c9abc262d002f
|
||||
github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925
|
||||
github.com/containerd/containerd 8a7e17ef96678507a4b23d2bc66e5bbe5b50ad37
|
||||
github.com/containerd/continuity 3e8f2ea4b190484acb976a5b378d373429639a1a
|
||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||
github.com/containerd/go-runc bcb223a061a3dd7de1a89c0b402a60f4dd9bd307
|
||||
github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7
|
||||
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
|
||||
github.com/containernetworking/cni v0.6.0
|
||||
github.com/containernetworking/plugins v0.6.0
|
||||
github.com/containernetworking/plugins v0.7.0
|
||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||
github.com/cri-o/ocicni 9b451e26eb7c694d564991fbf44f77d0afb9b03c
|
||||
github.com/davecgh/go-spew v1.1.0
|
||||
github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621
|
||||
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
|
||||
@@ -21,7 +21,6 @@ github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
||||
github.com/docker/go-units v0.3.1
|
||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||
github.com/emicklei/go-restful ff4f55a206334ef123e4f79bbf348980da81ca46
|
||||
github.com/fsnotify/fsnotify 7d7316ed6e1ed2de075aab8dfc76de5d158d66e1
|
||||
github.com/ghodss/yaml 73d445a93680fa1a78ae23a5839bad48f32ba1ee
|
||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
github.com/gogo/protobuf v0.5
|
||||
@@ -31,14 +30,13 @@ github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||
github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55
|
||||
github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||
github.com/json-iterator/go 1.0.4
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.0
|
||||
github.com/Microsoft/go-winio v0.4.5
|
||||
github.com/Microsoft/hcsshim v0.6.7
|
||||
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc a618ab5a0186905949ee463dbb762c3d23e12a80
|
||||
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
|
||||
github.com/opencontainers/runtime-spec v1.0.1
|
||||
github.com/opencontainers/runtime-tools 6073aff4ac61897f75895123f7e24135204a404d
|
||||
github.com/opencontainers/selinux 4a2974bf1ee960774ffd517717f1f45325af0206
|
||||
@@ -48,10 +46,8 @@ github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
||||
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
||||
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
|
||||
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
||||
github.com/renstrom/dedent 020d11c3b9c0c7a3c2efcc8e5cf5b9ef7bcea21f
|
||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||
github.com/sirupsen/logrus v1.0.0
|
||||
github.com/spf13/cobra v0.0.1
|
||||
github.com/spf13/pflag v1.0.0
|
||||
github.com/stevvooe/ttrpc d4528379866b0ce7e9d71f3eb96f0582fc374577
|
||||
github.com/stretchr/testify v1.1.4
|
||||
@@ -63,13 +59,14 @@ golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
||||
golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 https://github.com/golang/sys
|
||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
||||
golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
|
||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||
google.golang.org/grpc v1.7.4
|
||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||
gopkg.in/yaml.v2 53feefa2559fb8dfa8d81baad31be332c97d6c77
|
||||
k8s.io/api a1d6dce6736a6c75929bb75111e89077e35a5856
|
||||
k8s.io/apimachinery 8259d997cf059cd83dc47e5f8074b7a7d7967c09
|
||||
k8s.io/apiserver 8e45eac9dff86447a5c2effe6a3d2cba70121ebf
|
||||
k8s.io/client-go 33bd23f75b6de861994706a322b0afab824b2171
|
||||
k8s.io/kubernetes 05944b1d2ca7f60b09762a330425108f48f6b603
|
||||
k8s.io/api 5584376ceeffeb13a2e98b5e9f0e9dab37de4bab
|
||||
k8s.io/apimachinery fcb9a12f7875d01f8390b28faedc37dcf2e713b9
|
||||
k8s.io/apiserver 837069aa36757a586e4a8165f1ff5ca06170aa4a
|
||||
k8s.io/client-go 484f27892430b961df38fe6715cc396409207d9f
|
||||
k8s.io/kubernetes v1.10.0-rc.1
|
||||
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e
|
||||
|
||||
201
vendor/github.com/containerd/go-cni/LICENSE
generated
vendored
Normal file
201
vendor/github.com/containerd/go-cni/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
46
vendor/github.com/containerd/go-cni/README.md
generated
vendored
Normal file
46
vendor/github.com/containerd/go-cni/README.md
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# go-cni
|
||||
|
||||
A generic CNI library to provide APIs for CNI plugin interactions. The library provides APIs to:
|
||||
|
||||
- Setup networks for container namespace
|
||||
- Remove networks from container namespace
|
||||
- Query status of CNI network plugin initialization
|
||||
|
||||
go-cni aims to support plugins that implement [Container Network Interface](https://github.com/containernetworking/cni)
|
||||
|
||||
## Usage
|
||||
```
|
||||
func main() {
|
||||
id := "123456"
|
||||
netns := "/proc/9999/ns/net"
|
||||
defaultIfName := "eth0"
|
||||
// Initialize library
|
||||
l = gocni.New(gocni.WithMinNetworkCount(2),
|
||||
gocni.WithLoNetwork(),
|
||||
gocni.WithPluginConfDir("/etc/mycni/net.d"),
|
||||
gocni.WithPluginDir([]string{"/opt/mycni/bin", "/opt/cni/bin"}),
|
||||
gocni.WithDefaultIfName(defaultIfName))
|
||||
|
||||
// Setup network for namespace.
|
||||
labels := map[string]string{
|
||||
"K8S_POD_NAMESPACE": "namespace1",
|
||||
"K8S_POD_NAME": "pod1",
|
||||
"K8S_POD_INFRA_CONTAINER_ID": id,
|
||||
}
|
||||
result, err := l.Setup(id, netns, gocni.WithLabels(labels))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup network for namespace %q: %v", id, err)
|
||||
}
|
||||
defer func() {
|
||||
if retErr != nil {
|
||||
// Teardown network if an error is returned.
|
||||
if err := l.Remove(id, netns, gocni.WithLabels(labels)); err != nil {
|
||||
fmt.Errorf("Failed to destroy network for namespace %q", id)
|
||||
}
|
||||
}
|
||||
}()
|
||||
// Get IP of the default interface
|
||||
IP := result.Interfaces[defaultIfName].IPConfigs[0].IP.String()
|
||||
fmt.Printf("IP of the default interface %s:%s", defaultIfName, IP)
|
||||
}
|
||||
```
|
||||
141
vendor/github.com/containerd/go-cni/cni.go
generated
vendored
Normal file
141
vendor/github.com/containerd/go-cni/cni.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
cnilibrary "github.com/containernetworking/cni/libcni"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type CNI interface {
|
||||
// Setup setup the network for the namespace
|
||||
Setup(id string, path string, opts ...NamespaceOpts) (*CNIResult, error)
|
||||
// Remove tears down the network of the namespace.
|
||||
Remove(id string, path string, opts ...NamespaceOpts) error
|
||||
// Load loads the cni network config
|
||||
Load(opts ...LoadOption) error
|
||||
// Status checks the status of the cni initialization
|
||||
Status() error
|
||||
}
|
||||
|
||||
type libcni struct {
|
||||
config
|
||||
|
||||
cniConfig cnilibrary.CNI
|
||||
networkCount int // minimum network plugin configurations needed to initialize cni
|
||||
networks []*Network
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
func defaultCNIConfig() *libcni {
|
||||
return &libcni{
|
||||
config: config{
|
||||
pluginDirs: []string{DefaultCNIDir},
|
||||
pluginConfDir: DefaultNetDir,
|
||||
prefix: DefaultPrefix,
|
||||
},
|
||||
cniConfig: &cnilibrary.CNIConfig{
|
||||
Path: []string{DefaultCNIDir},
|
||||
},
|
||||
networkCount: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func New(config ...ConfigOption) (CNI, error) {
|
||||
cni := defaultCNIConfig()
|
||||
var err error
|
||||
for _, c := range config {
|
||||
if err = c(cni); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return cni, nil
|
||||
}
|
||||
|
||||
func (c *libcni) Load(opts ...LoadOption) error {
|
||||
var err error
|
||||
// Reset the networks on a load operation to ensure
|
||||
// config happens on a clean slate
|
||||
c.reset()
|
||||
|
||||
for _, o := range opts {
|
||||
if err = o(c); err != nil {
|
||||
return errors.Wrapf(ErrLoad, fmt.Sprintf("cni config load failed: %v", err))
|
||||
}
|
||||
}
|
||||
return c.Status()
|
||||
}
|
||||
|
||||
func (c *libcni) Status() error {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
if len(c.networks) < c.networkCount {
|
||||
return ErrCNINotInitialized
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setup setups the network in the namespace
|
||||
func (c *libcni) Setup(id string, path string, opts ...NamespaceOpts) (*CNIResult, error) {
|
||||
if err:=c.Status();err!=nil{
|
||||
return nil,err
|
||||
}
|
||||
ns, err := newNamespace(id, path, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var results []*current.Result
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
for _, network := range c.networks {
|
||||
r, err := network.Attach(ns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, r)
|
||||
}
|
||||
return c.GetCNIResultFromResults(results)
|
||||
}
|
||||
|
||||
// Remove removes the network config from the namespace
|
||||
func (c *libcni) Remove(id string, path string, opts ...NamespaceOpts) error {
|
||||
if err:=c.Status();err!=nil{
|
||||
return err
|
||||
}
|
||||
ns, err := newNamespace(id, path, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
for _, network := range c.networks {
|
||||
if err := network.Remove(ns); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *libcni) reset() {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.networks = nil
|
||||
}
|
||||
39
vendor/github.com/containerd/go-cni/errors.go
generated
vendored
Normal file
39
vendor/github.com/containerd/go-cni/errors.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package cni
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCNINotInitialized = errors.New("cni plugin not initialized")
|
||||
ErrInvalidConfig = errors.New("invalid cni config")
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrRead = errors.New("failed to read config file")
|
||||
ErrInvalidResult = errors.New("invalid result")
|
||||
ErrLoad = errors.New("failed to load cni config")
|
||||
)
|
||||
|
||||
// IsCNINotInitialized returns true if the error is due cni config not being intialized
|
||||
func IsCNINotInitialized(err error) bool {
|
||||
return errors.Cause(err) == ErrCNINotInitialized
|
||||
}
|
||||
|
||||
// IsInvalidConfig returns true if the error is invalid cni config
|
||||
func IsInvalidConfig(err error) bool {
|
||||
return errors.Cause(err) == ErrInvalidConfig
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error is due to a missing config or result
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Cause(err) == ErrNotFound
|
||||
}
|
||||
|
||||
// IsReadFailure return true if the error is a config read failure
|
||||
func IsReadFailure(err error) bool {
|
||||
return errors.Cause(err) == ErrRead
|
||||
}
|
||||
|
||||
// IsInvalidResult return true if the error is due to invalid cni result
|
||||
func IsInvalidResult(err error) bool {
|
||||
return errors.Cause(err) == ErrInvalidResult
|
||||
}
|
||||
41
vendor/github.com/containerd/go-cni/helper.go
generated
vendored
Normal file
41
vendor/github.com/containerd/go-cni/helper.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
)
|
||||
|
||||
func validateInterfaceConfig(ipConf *current.IPConfig, ifs int) error {
|
||||
if ipConf == nil {
|
||||
return fmt.Errorf("invalid IP configuration")
|
||||
}
|
||||
if ipConf.Interface != nil && *ipConf.Interface > ifs {
|
||||
return fmt.Errorf("invalid IP configuration with invalid interface %d", *ipConf.Interface)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getIfName(prefix string, i int) string {
|
||||
return fmt.Sprintf("%s%d", prefix, i)
|
||||
}
|
||||
|
||||
func defaultInterface(prefix string) string {
|
||||
return getIfName(prefix, 0)
|
||||
}
|
||||
75
vendor/github.com/containerd/go-cni/namespace.go
generated
vendored
Normal file
75
vendor/github.com/containerd/go-cni/namespace.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
import (
|
||||
cnilibrary "github.com/containernetworking/cni/libcni"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
)
|
||||
|
||||
type Network struct {
|
||||
cni cnilibrary.CNI
|
||||
config *cnilibrary.NetworkConfigList
|
||||
ifName string
|
||||
}
|
||||
|
||||
func (n *Network) Attach(ns *Namespace) (*current.Result, error) {
|
||||
r, err := n.cni.AddNetworkList(n.config, ns.config(n.ifName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return current.NewResultFromResult(r)
|
||||
}
|
||||
|
||||
func (n *Network) Remove(ns *Namespace) error {
|
||||
return n.cni.DelNetworkList(n.config, ns.config(n.ifName))
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
id string
|
||||
path string
|
||||
capabilityArgs map[string]interface{}
|
||||
args map[string]string
|
||||
}
|
||||
|
||||
func newNamespace(id, path string, opts ...NamespaceOpts) (*Namespace, error) {
|
||||
ns := &Namespace{
|
||||
id: id,
|
||||
path: path,
|
||||
capabilityArgs: make(map[string]interface{}),
|
||||
args: make(map[string]string),
|
||||
}
|
||||
for _, o := range opts {
|
||||
if err := o(ns); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func (ns *Namespace) config(ifName string) *cnilibrary.RuntimeConf {
|
||||
c := &cnilibrary.RuntimeConf{
|
||||
ContainerID: ns.id,
|
||||
NetNS: ns.path,
|
||||
IfName: ifName,
|
||||
}
|
||||
for k, v := range ns.args {
|
||||
c.Args = append(c.Args, [2]string{k, v})
|
||||
}
|
||||
c.CapabilityArgs = ns.capabilityArgs
|
||||
return c
|
||||
}
|
||||
58
vendor/github.com/containerd/go-cni/namespace_opts.go
generated
vendored
Normal file
58
vendor/github.com/containerd/go-cni/namespace_opts.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
type NamespaceOpts func(s *Namespace) error
|
||||
|
||||
// Capabilities
|
||||
func WithCapabilityPortMap(portMapping []PortMapping) NamespaceOpts {
|
||||
return func(c *Namespace) error {
|
||||
c.capabilityArgs["portMappings"] = portMapping
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithCapabilityIPRanges(ipRanges []IPRanges) NamespaceOpts {
|
||||
return func(c *Namespace) error {
|
||||
c.capabilityArgs["ipRanges"] = ipRanges
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithCapability(name string, capability interface{}) NamespaceOpts {
|
||||
return func(c *Namespace) error {
|
||||
c.capabilityArgs[name] = capability
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Args
|
||||
func WithLabels(labels map[string]string) NamespaceOpts {
|
||||
return func(c *Namespace) error {
|
||||
for k, v := range labels {
|
||||
c.args[k] = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithArgs(k, v string) NamespaceOpts {
|
||||
return func(c *Namespace) error {
|
||||
c.args[k] = v
|
||||
return nil
|
||||
}
|
||||
}
|
||||
226
vendor/github.com/containerd/go-cni/opts.go
generated
vendored
Normal file
226
vendor/github.com/containerd/go-cni/opts.go
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
cnilibrary "github.com/containernetworking/cni/libcni"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type ConfigOption func(c *libcni) error
|
||||
|
||||
// WithInterfacePrefix sets the prefix for network interfaces
|
||||
// e.g. eth or wlan
|
||||
func WithInterfacePrefix(prefix string) ConfigOption {
|
||||
return func(c *libcni) error {
|
||||
c.prefix = prefix
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPluginDir can be used to set the locations of
|
||||
// the cni plugin binaries
|
||||
func WithPluginDir(dirs []string) ConfigOption {
|
||||
return func(c *libcni) error {
|
||||
c.pluginDirs = dirs
|
||||
c.cniConfig = &cnilibrary.CNIConfig{Path: dirs}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPluginConfDir can be used to configure the
|
||||
// cni configuration directory.
|
||||
func WithPluginConfDir(dir string) ConfigOption {
|
||||
return func(c *libcni) error {
|
||||
c.pluginConfDir = dir
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithMinNetworkCount can be used to configure the
|
||||
// minimum networks to be configured and initalized
|
||||
// for the status to report success. By default its 1.
|
||||
func WithMinNetworkCount(count int) ConfigOption {
|
||||
return func(c *libcni) error {
|
||||
c.networkCount = count
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// LoadOption can be used with Load API
|
||||
// to load network configuration from different
|
||||
// sources.
|
||||
type LoadOption func(c *libcni) error
|
||||
|
||||
// WithLoNetwork can be used to load the loopback
|
||||
// network config.
|
||||
func WithLoNetwork() LoadOption {
|
||||
return func(c *libcni) error {
|
||||
loConfig, _ := cnilibrary.ConfListFromBytes([]byte(`{
|
||||
"cniVersion": "0.3.1",
|
||||
"name": "cni-loopback",
|
||||
"plugins": [{
|
||||
"type": "loopback"
|
||||
}]
|
||||
}`))
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.networks = append(c.networks,&Network{
|
||||
cni: c.cniConfig,
|
||||
config: loConfig,
|
||||
ifName: "lo",
|
||||
})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithConf can be used to load config directly
|
||||
// from byte.
|
||||
func WithConf(bytes []byte) LoadOption {
|
||||
return func(c *libcni) error {
|
||||
conf, err := cnilibrary.ConfFromBytes(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
confList, err := cnilibrary.ConfListFromConf(conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.networks = append(c.networks, &Network{
|
||||
cni: c.cniConfig,
|
||||
config: confList,
|
||||
ifName: getIfName(c.prefix, 0),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithConfFile can be used to load network config
|
||||
// from an .conf file. Supported with absolute fileName
|
||||
// with path only.
|
||||
func WithConfFile(fileName string) LoadOption {
|
||||
return func(c *libcni) error {
|
||||
conf, err := cnilibrary.ConfFromFile(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// upconvert to conf list
|
||||
confList, err := cnilibrary.ConfListFromConf(conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.networks = append(c.networks, &Network{
|
||||
cni: c.cniConfig,
|
||||
config: confList,
|
||||
ifName: getIfName(c.prefix, 0),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithConfListFile can be used to load network config
|
||||
// from an .conflist file. Supported with absolute fileName
|
||||
// with path only.
|
||||
func WithConfListFile(fileName string) LoadOption {
|
||||
return func(c *libcni) error {
|
||||
confList, err := cnilibrary.ConfListFromFile(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.networks = append(c.networks,&Network{
|
||||
cni: c.cniConfig,
|
||||
config: confList,
|
||||
ifName: getIfName(c.prefix, 0),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDefaultConf can be used to detect network config
|
||||
// files from the configured cni config directory and load
|
||||
// them.
|
||||
func WithDefaultConf() LoadOption {
|
||||
return func(c *libcni) error {
|
||||
files, err := cnilibrary.ConfFiles(c.pluginConfDir, []string{".conf", ".conflist", ".json"})
|
||||
switch {
|
||||
case err != nil:
|
||||
return errors.Wrapf(ErrRead, "failed to read config file: %v", err)
|
||||
case len(files) == 0:
|
||||
return errors.Wrapf(ErrCNINotInitialized, "no network config found in %s", c.pluginConfDir)
|
||||
}
|
||||
|
||||
// files contains the network config files associated with cni network.
|
||||
// Use lexicographical way as a defined order for network config files.
|
||||
sort.Strings(files)
|
||||
// Since the CNI spec does not specify a way to detect default networks,
|
||||
// the convention chosen is - the first network configuration in the sorted
|
||||
// list of network conf files as the default network and choose the default
|
||||
// interface provided during init as the network interface for this default
|
||||
// network. For every other network use a generated interface id.
|
||||
i := 0
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
for _, confFile := range files {
|
||||
var confList *cnilibrary.NetworkConfigList
|
||||
if strings.HasSuffix(confFile, ".conflist") {
|
||||
confList, err = cnilibrary.ConfListFromFile(confFile)
|
||||
if err != nil {
|
||||
return errors.Wrapf(ErrInvalidConfig, "failed to load CNI config list file %s: %v", confFile, err)
|
||||
}
|
||||
} else {
|
||||
conf, err := cnilibrary.ConfFromFile(confFile)
|
||||
if err != nil {
|
||||
return errors.Wrapf(ErrInvalidConfig, "failed to load CNI config file %s: %v", confFile, err)
|
||||
}
|
||||
// Ensure the config has a "type" so we know what plugin to run.
|
||||
// Also catches the case where somebody put a conflist into a conf file.
|
||||
if conf.Network.Type == "" {
|
||||
return errors.Wrapf(ErrInvalidConfig, "network type not found in %s", confFile)
|
||||
}
|
||||
|
||||
confList, err = cnilibrary.ConfListFromConf(conf)
|
||||
if err != nil {
|
||||
return errors.Wrapf(ErrInvalidConfig, "failed to convert CNI config file %s to list: %v", confFile, err)
|
||||
}
|
||||
}
|
||||
if len(confList.Plugins) == 0 {
|
||||
return errors.Wrapf(ErrInvalidConfig, "CNI config list %s has no networks, skipping", confFile)
|
||||
|
||||
}
|
||||
c.networks = append(c.networks, &Network{
|
||||
cni: c.cniConfig,
|
||||
config: confList,
|
||||
ifName: getIfName(c.prefix, i),
|
||||
})
|
||||
i++
|
||||
}
|
||||
if len(c.networks) == 0 {
|
||||
return errors.Wrapf(ErrCNINotInitialized, "no valid networks found in %s", c.pluginDirs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
103
vendor/github.com/containerd/go-cni/result.go
generated
vendored
Normal file
103
vendor/github.com/containerd/go-cni/result.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/current"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type IPConfig struct {
|
||||
IP net.IP
|
||||
Gateway net.IP
|
||||
}
|
||||
|
||||
type CNIResult struct {
|
||||
Interfaces map[string]*Config
|
||||
DNS []types.DNS
|
||||
Routes []*types.Route
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
IPConfigs []*IPConfig
|
||||
Mac string
|
||||
Sandbox string
|
||||
}
|
||||
|
||||
// GetCNIResultFromResults returns a structured data containing the
|
||||
// interface configuration for each of the interfaces created in the namespace.
|
||||
// Conforms with
|
||||
// Result:
|
||||
// a) Interfaces list. Depending on the plugin, this can include the sandbox
|
||||
// (eg, container or hypervisor) interface name and/or the host interface
|
||||
// name, the hardware addresses of each interface, and details about the
|
||||
// sandbox (if any) the interface is in.
|
||||
// b) IP configuration assigned to each interface. The IPv4 and/or IPv6 addresses,
|
||||
// gateways, and routes assigned to sandbox and/or host interfaces.
|
||||
// c) DNS information. Dictionary that includes DNS information for nameservers,
|
||||
// domain, search domains and options.
|
||||
func (c *libcni) GetCNIResultFromResults(results []*current.Result) (*CNIResult, error) {
|
||||
r := &CNIResult{
|
||||
Interfaces: make(map[string]*Config),
|
||||
}
|
||||
|
||||
// Plugins may not need to return Interfaces in result if
|
||||
// if there are no multiple interfaces created. In that case
|
||||
// all configs should be applied against default interface
|
||||
r.Interfaces[defaultInterface(c.prefix)] = &Config{}
|
||||
|
||||
// Walk through all the results
|
||||
for _, result := range results {
|
||||
// Walk through all the interface in each result
|
||||
for _, intf := range result.Interfaces {
|
||||
r.Interfaces[intf.Name] = &Config{
|
||||
Mac: intf.Mac,
|
||||
Sandbox: intf.Sandbox,
|
||||
}
|
||||
}
|
||||
// Walk through all the IPs in the result and attach it to corresponding
|
||||
// interfaces
|
||||
for _, ipConf := range result.IPs {
|
||||
if err := validateInterfaceConfig(ipConf, len(result.Interfaces)); err != nil {
|
||||
return nil, errors.Wrapf(ErrInvalidResult, "failed to valid interface config: %v", err)
|
||||
}
|
||||
name := c.getInterfaceName(result.Interfaces, ipConf)
|
||||
r.Interfaces[name].IPConfigs = append(r.Interfaces[name].IPConfigs,
|
||||
&IPConfig{IP: ipConf.Address.IP, Gateway: ipConf.Gateway})
|
||||
}
|
||||
r.DNS = append(r.DNS, result.DNS)
|
||||
r.Routes = append(r.Routes, result.Routes...)
|
||||
}
|
||||
if _, ok := r.Interfaces[defaultInterface(c.prefix)]; !ok {
|
||||
return nil, errors.Wrapf(ErrNotFound, "default network not found")
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// getInterfaceName returns the interface name if the plugins
|
||||
// return the result with associated interfaces. If interface
|
||||
// is not present then default interface name is used
|
||||
func (c *libcni) getInterfaceName(interfaces []*current.Interface,
|
||||
ipConf *current.IPConfig) string {
|
||||
if ipConf.Interface != nil {
|
||||
return interfaces[*ipConf.Interface].Name
|
||||
}
|
||||
return defaultInterface(c.prefix)
|
||||
}
|
||||
78
vendor/github.com/containerd/go-cni/testutils.go
generated
vendored
Normal file
78
vendor/github.com/containerd/go-cni/testutils.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func makeTmpDir(prefix string) (string, error) {
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), prefix)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tmpDir, nil
|
||||
}
|
||||
|
||||
func makeFakeCNIConfig(t *testing.T) (string, string) {
|
||||
cniDir, err := makeTmpDir("fakecni")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create plugin config dir: %v", err)
|
||||
}
|
||||
|
||||
cniConfDir := path.Join(cniDir, "net.d")
|
||||
err = os.MkdirAll(cniConfDir, 0777)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create network config dir: %v", err)
|
||||
}
|
||||
|
||||
networkConfig1 := path.Join(cniConfDir, "mocknetwork1.conf")
|
||||
f1, err := os.Create(networkConfig1)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create network config %v: %v", f1, err)
|
||||
}
|
||||
networkConfig2 := path.Join(cniConfDir, "mocknetwork2.conf")
|
||||
f2, err := os.Create(networkConfig2)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create network config %v: %v", f2, err)
|
||||
}
|
||||
|
||||
cfg1 := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true} }`, "plugin1", "fakecni")
|
||||
_, err = f1.WriteString(cfg1)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write network config file %v: %v", f1, err)
|
||||
}
|
||||
f1.Close()
|
||||
cfg2 := fmt.Sprintf(`{ "name": "%s", "type": "%s", "capabilities": {"portMappings": true} }`, "plugin2", "fakecni")
|
||||
_, err = f2.WriteString(cfg2)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to write network config file %v: %v", f2, err)
|
||||
}
|
||||
f2.Close()
|
||||
return cniDir, cniConfDir
|
||||
}
|
||||
|
||||
func tearDownCNIConfig(t *testing.T, confDir string) {
|
||||
err := os.RemoveAll(confDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cleanup CNI configs: %v", err)
|
||||
}
|
||||
}
|
||||
45
vendor/github.com/containerd/go-cni/types.go
generated
vendored
Normal file
45
vendor/github.com/containerd/go-cni/types.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 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 cni
|
||||
|
||||
const (
|
||||
CNIPluginName = "cni"
|
||||
DefaultNetDir = "/etc/cni/net.d"
|
||||
DefaultCNIDir = "/opt/cni/bin"
|
||||
VendorCNIDirTemplate = "%s/opt/%s/bin"
|
||||
DefaultPrefix = "eth"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
pluginDirs []string
|
||||
pluginConfDir string
|
||||
prefix string
|
||||
}
|
||||
|
||||
type PortMapping struct {
|
||||
HostPort int32
|
||||
ContainerPort int32
|
||||
Protocol string
|
||||
HostIP string
|
||||
}
|
||||
|
||||
type IPRanges struct {
|
||||
Subnet string
|
||||
RangeStart string
|
||||
RangeEnd string
|
||||
Gateway string
|
||||
}
|
||||
6
vendor/github.com/containerd/go-cni/vendor.conf
generated
vendored
Normal file
6
vendor/github.com/containerd/go-cni/vendor.conf
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
github.com/stretchr/testify b89eecf5ca5db6d3ba60b237ffe3df7bafb7662f
|
||||
github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff78260e27b9ab7c73
|
||||
github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2
|
||||
github.com/stretchr/objx 8a3f7159479fbc75b30357fbc48f380b7320f08e
|
||||
github.com/containernetworking/cni 142cde0c766cd6055cc7fdfdcb44579c0c9c35bf
|
||||
github.com/pkg/errors v0.8.0
|
||||
Reference in New Issue
Block a user