diff --git a/Makefile b/Makefile index 560dd2ff6..25ac021c4 100644 --- a/Makefile +++ b/Makefile @@ -39,10 +39,8 @@ help: @echo "Usage: make " @echo @echo " * 'install' - Install binaries to system locations" - @echo " * 'binaries' - Build containerd and ctr" - @echo " * 'static-binaries - Build static containerd and ctr" - @echo " * 'ctr' - Build ctr" - @echo " * 'install-ctr' - Install ctr" + @echo " * 'binaries' - Build containerd" + @echo " * 'static-binaries - Build static containerd" @echo " * 'containerd' - Build a customized containerd with CRI plugin for testing" @echo " * 'install-containerd' - Install customized containerd to system location" @echo " * 'release' - Build release tarball" @@ -93,13 +91,6 @@ sync-vendor: update-vendor: sync-vendor sort-vendor -$(BUILD_DIR)/ctr: $(SOURCES) - $(GO) build -o $@ \ - -tags '$(BUILD_TAGS)' \ - -ldflags '$(GO_LDFLAGS)' \ - -gcflags '$(GO_GCFLAGS)' \ - $(PROJECT)/cmd/ctr - $(BUILD_DIR)/containerd: $(SOURCES) $(PLUGIN_SOURCES) $(GO) build -o $@ \ -tags '$(BUILD_TAGS)' \ @@ -128,26 +119,20 @@ test-e2e-node: binaries clean: rm -rf $(BUILD_DIR)/* -binaries: $(BUILD_DIR)/containerd $(BUILD_DIR)/ctr +binaries: $(BUILD_DIR)/containerd static-binaries: GO_LDFLAGS += -extldflags "-fno-PIC -static" -static-binaries: $(BUILD_DIR)/containerd $(BUILD_DIR)/ctr - -ctr: $(BUILD_DIR)/ctr - -install-ctr: ctr - install -D -m 755 $(BUILD_DIR)/ctr $(BINDIR)/ctr +static-binaries: $(BUILD_DIR)/containerd containerd: $(BUILD_DIR)/containerd install-containerd: containerd install -D -m 755 $(BUILD_DIR)/containerd $(BINDIR)/containerd -install: install-ctr install-containerd +install: install-containerd uninstall: rm -f $(BINDIR)/containerd - rm -f $(BINDIR)/ctr $(BUILD_DIR)/$(TARBALL): static-binaries vendor.conf @BUILD_DIR=$(BUILD_DIR) TARBALL=$(TARBALL) VERSION=$(VERSION) ./hack/release.sh @@ -193,8 +178,6 @@ install.tools: .install.gitvalidation .install.gometalinter .install.vndr .PHONY: \ binaries \ static-binaries \ - ctr \ - install-ctr \ containerd \ install-containerd \ release \ diff --git a/cli/cli.go b/cli/cli.go deleted file mode 100644 index e43180cad..000000000 --- a/cli/cli.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2018 The containerd Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cli - -import ( - gocontext "context" - "fmt" - "path/filepath" - - api "github.com/containerd/cri/pkg/api/v1" - "github.com/containerd/cri/pkg/client" - "github.com/pkg/errors" - "github.com/urfave/cli" -) - -// Command is the cli command for cri plugin. -var Command = cli.Command{ - Name: "cri", - Usage: "interact with cri plugin", - Subcommands: cli.Commands{ - loadCommand, - }, -} - -var loadCommand = cli.Command{ - Name: "load", - Usage: "load one or more images from tar archives.", - ArgsUsage: "[flags] TAR [TAR, ...]", - Description: "load one or more images from tar archives.", - Flags: []cli.Flag{}, - Action: func(context *cli.Context) error { - var ( - ctx = gocontext.Background() - address = context.GlobalString("address") - timeout = context.GlobalDuration("timeout") - cancel gocontext.CancelFunc - ) - if timeout > 0 { - ctx, cancel = gocontext.WithTimeout(gocontext.Background(), timeout) - } else { - ctx, cancel = gocontext.WithCancel(ctx) - } - defer cancel() - cl, err := client.NewCRIPluginClient(ctx, address) - if err != nil { - return errors.Wrap(err, "failed to create grpc client") - } - for _, path := range context.Args() { - absPath, err := filepath.Abs(path) - if err != nil { - return errors.Wrap(err, "failed to get absolute path") - } - res, err := cl.LoadImage(ctx, &api.LoadImageRequest{FilePath: absPath}) - if err != nil { - return errors.Wrap(err, "failed to load image") - } - images := res.GetImages() - for _, image := range images { - fmt.Println("Loaded image:", image) - } - } - return nil - }, -} diff --git a/cmd/ctr/main.go b/cmd/ctr/main.go deleted file mode 100644 index 81e58efdf..000000000 --- a/cmd/ctr/main.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2018 The containerd Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "fmt" - "math/rand" - "os" - "time" - - ctrapp "github.com/containerd/containerd/cmd/ctr/app" - - cricli "github.com/containerd/cri/cli" -) - -func init() { - rand.Seed(time.Now().UnixNano()) -} - -func main() { - app := ctrapp.New() - app.Commands = append(app.Commands, cricli.Command) - if err := app.Run(os.Args); err != nil { - fmt.Fprintf(os.Stderr, "ctr: %s\n", err) - os.Exit(1) - } -} diff --git a/hack/test-integration.sh b/hack/test-integration.sh index 565cd0e77..0f55c8ebf 100755 --- a/hack/test-integration.sh +++ b/hack/test-integration.sh @@ -27,7 +27,7 @@ REPORT_DIR=${REPORT_DIR:-"/tmp/test-integration"} # RUNTIME is the runtime handler to use in the test. RUNTIME=${RUNTIME:-""} -CRI_ROOT="/var/lib/containerd/io.containerd.grpc.v1.cri" +CRI_ROOT="${CONTAINERD_ROOT}/io.containerd.grpc.v1.cri" mkdir -p ${REPORT_DIR} test_setup ${REPORT_DIR} diff --git a/hack/test-utils.sh b/hack/test-utils.sh index e6e806b25..6ba52584c 100755 --- a/hack/test-utils.sh +++ b/hack/test-utils.sh @@ -23,13 +23,23 @@ CONTAINERD_FLAGS="--log-level=debug " # Use a configuration file for containerd. CONTAINERD_CONFIG_FILE=${CONTAINERD_CONFIG_FILE:-""} +# CONTAINERD_TEST_SUFFIX is the suffix appended to the root/state directory used +# by test containerd. +CONTAINERD_TEST_SUFFIX=${CONTAINERD_TEST_SUFFIX:-"-test"} +# The containerd root directory. +CONTAINERD_ROOT=${CONTAINERD_ROOT:-"/var/lib/containerd${CONTAINERD_TEST_SUFFIX}"} +# The containerd state directory. +CONTAINERD_STATE=${CONTAINERD_STATE:-"/run/containerd${CONTAINERD_TEST_SUFFIX}"} +# The containerd socket address. +CONTAINERD_SOCK=${CONTAINERD_SOCK:-unix://${CONTAINERD_STATE}/containerd.sock} if [ -f "${CONTAINERD_CONFIG_FILE}" ]; then CONTAINERD_FLAGS+="--config ${CONTAINERD_CONFIG_FILE} " fi +CONTAINERD_FLAGS+="--address ${CONTAINERD_SOCK#"unix://"} \ + --state ${CONTAINERD_STATE} \ + --root ${CONTAINERD_ROOT}" -CONTAINERD_SOCK=unix:///run/containerd/containerd.sock - -containerd_pid= +containerd_groupid= # test_setup starts containerd. test_setup() { @@ -39,10 +49,14 @@ test_setup() { echo "containerd is not built" exit 1 fi - sudo pkill -x containerd + set -m + # Create containerd in a different process group + # so that we can easily clean them up. keepalive "sudo PATH=${PATH} ${ROOT}/_output/containerd ${CONTAINERD_FLAGS}" \ ${RESTART_WAIT_PERIOD} &> ${report_dir}/containerd.log & - containerd_pid=$! + pid=$! + set +m + containerd_groupid=$(ps -o pgid= -p ${pid}) # Wait for containerd to be running by using the containerd client ctr to check the version # of the containerd server. Wait an increasing amount of time after each of five attempts local -r ctr_path=$(which ctr) @@ -61,10 +75,9 @@ test_setup() { # test_teardown kills containerd. test_teardown() { - if [ -n "${containerd_pid}" ]; then - kill ${containerd_pid} + if [ -n "${containerd_groupid}" ]; then + sudo pkill -g ${containerd_groupid} fi - sudo pkill -x containerd } # keepalive runs a command and keeps it alive. diff --git a/integration/image_load_test.go b/integration/image_load_test.go index aaf855dbf..c13e12792 100644 --- a/integration/image_load_test.go +++ b/integration/image_load_test.go @@ -17,17 +17,15 @@ limitations under the License. package integration import ( - "golang.org/x/net/context" "io/ioutil" "os" "os/exec" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" - - api "github.com/containerd/cri/pkg/api/v1" ) // Test to load an image from tarball. @@ -58,14 +56,22 @@ func TestImageLoad(t *testing.T) { } t.Logf("load image in cri") - res, err := criPluginClient.LoadImage(context.Background(), &api.LoadImageRequest{FilePath: tar}) - require.NoError(t, err) - require.Equal(t, []string{loadedImage}, res.GetImages()) + ctr, err := exec.LookPath("ctr") + require.NoError(t, err, "ctr should be installed, make sure you've run `make install.deps`") + output, err = exec.Command(ctr, "-address="+containerdEndpoint, + "-n=k8s.io", "images", "import", tar).CombinedOutput() + require.NoError(t, err, "output: %q", output) t.Logf("make sure image is loaded") - img, err = imageService.ImageStatus(&runtime.ImageSpec{Image: testImage}) - require.NoError(t, err) - require.NotNil(t, img) + // Use Eventually because the cri plugin needs a short period of time + // to pick up images imported into containerd directly. + require.NoError(t, Eventually(func() (bool, error) { + img, err = imageService.ImageStatus(&runtime.ImageSpec{Image: testImage}) + if err != nil { + return false, err + } + return img != nil, nil + }, 100*time.Millisecond, 10*time.Second)) require.Equal(t, []string{loadedImage}, img.RepoTags) t.Logf("create a container with the loaded image") diff --git a/integration/test_utils.go b/integration/test_utils.go index c24853e5d..12d2b92fe 100644 --- a/integration/test_utils.go +++ b/integration/test_utils.go @@ -38,8 +38,6 @@ import ( "k8s.io/kubernetes/pkg/kubelet/remote" kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" - api "github.com/containerd/cri/pkg/api/v1" - "github.com/containerd/cri/pkg/client" criconfig "github.com/containerd/cri/pkg/config" "github.com/containerd/cri/pkg/constants" "github.com/containerd/cri/pkg/server" @@ -47,17 +45,16 @@ import ( ) const ( - timeout = 1 * time.Minute - pauseImage = "k8s.gcr.io/pause:3.1" // This is the same with default sandbox image. - k8sNamespace = constants.K8sContainerdNamespace - containerdEndpoint = "/run/containerd/containerd.sock" + timeout = 1 * time.Minute + pauseImage = "k8s.gcr.io/pause:3.1" // This is the same with default sandbox image. + k8sNamespace = constants.K8sContainerdNamespace ) var ( - runtimeService cri.RuntimeService - imageService cri.ImageManagerService - containerdClient *containerd.Client - criPluginClient api.CRIPluginServiceClient + runtimeService cri.RuntimeService + imageService cri.ImageManagerService + containerdClient *containerd.Client + containerdEndpoint string ) var criEndpoint = flag.String("cri-endpoint", "unix:///run/containerd/containerd.sock", "The endpoint of cri plugin.") @@ -93,16 +90,12 @@ func ConnectDaemons() error { if err != nil { return errors.Wrap(err, "failed to list images") } + // containerdEndpoint is the same with criEndpoint now + containerdEndpoint = strings.TrimPrefix(*criEndpoint, "unix://") containerdClient, err = containerd.New(containerdEndpoint, containerd.WithDefaultNamespace(k8sNamespace)) if err != nil { return errors.Wrap(err, "failed to connect containerd") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - criPluginClient, err = client.NewCRIPluginClient(ctx, *criEndpoint) - if err != nil { - return errors.Wrap(err, "failed to connect cri plugin") - } return nil } diff --git a/pkg/api/v1/api.pb.go b/pkg/api/v1/api.pb.go deleted file mode 100644 index cf8e9845b..000000000 --- a/pkg/api/v1/api.pb.go +++ /dev/null @@ -1,578 +0,0 @@ -/* -Copyright 2019 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. -*/ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: api.proto - -/* -Package api_v1 is a generated protocol buffer package. - -It is generated from these files: - api.proto - -It has these top-level messages: - LoadImageRequest - LoadImageResponse -*/ -package api_v1 - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" -import _ "github.com/gogo/protobuf/gogoproto" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -import strings "strings" -import reflect "reflect" - -import io "io" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package - -type LoadImageRequest struct { - // FilePath is the absolute path of docker image tarball. - FilePath string `protobuf:"bytes,1,opt,name=FilePath,proto3" json:"FilePath,omitempty"` -} - -func (m *LoadImageRequest) Reset() { *m = LoadImageRequest{} } -func (*LoadImageRequest) ProtoMessage() {} -func (*LoadImageRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} } - -func (m *LoadImageRequest) GetFilePath() string { - if m != nil { - return m.FilePath - } - return "" -} - -type LoadImageResponse struct { - // Images have been loaded. - Images []string `protobuf:"bytes,1,rep,name=Images" json:"Images,omitempty"` -} - -func (m *LoadImageResponse) Reset() { *m = LoadImageResponse{} } -func (*LoadImageResponse) ProtoMessage() {} -func (*LoadImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} } - -func (m *LoadImageResponse) GetImages() []string { - if m != nil { - return m.Images - } - return nil -} - -func init() { - proto.RegisterType((*LoadImageRequest)(nil), "api.v1.LoadImageRequest") - proto.RegisterType((*LoadImageResponse)(nil), "api.v1.LoadImageResponse") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// Client API for CRIPluginService service - -type CRIPluginServiceClient interface { - // LoadImage loads a image into containerd. - LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error) -} - -type cRIPluginServiceClient struct { - cc *grpc.ClientConn -} - -func NewCRIPluginServiceClient(cc *grpc.ClientConn) CRIPluginServiceClient { - return &cRIPluginServiceClient{cc} -} - -func (c *cRIPluginServiceClient) LoadImage(ctx context.Context, in *LoadImageRequest, opts ...grpc.CallOption) (*LoadImageResponse, error) { - out := new(LoadImageResponse) - 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 CRIPluginService service - -type CRIPluginServiceServer interface { - // LoadImage loads a image into containerd. - LoadImage(context.Context, *LoadImageRequest) (*LoadImageResponse, error) -} - -func RegisterCRIPluginServiceServer(s *grpc.Server, srv CRIPluginServiceServer) { - s.RegisterService(&_CRIPluginService_serviceDesc, srv) -} - -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.(CRIPluginServiceServer).LoadImage(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/api.v1.CRIPluginService/LoadImage", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(CRIPluginServiceServer).LoadImage(ctx, req.(*LoadImageRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _CRIPluginService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "api.v1.CRIPluginService", - HandlerType: (*CRIPluginServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "LoadImage", - Handler: _CRIPluginService_LoadImage_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "api.proto", -} - -func (m *LoadImageRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *LoadImageRequest) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.FilePath) > 0 { - dAtA[i] = 0xa - i++ - i = encodeVarintApi(dAtA, i, uint64(len(m.FilePath))) - i += copy(dAtA[i:], m.FilePath) - } - return i, nil -} - -func (m *LoadImageResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *LoadImageResponse) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.Images) > 0 { - for _, s := range m.Images { - dAtA[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - return i, nil -} - -func encodeVarintApi(dAtA []byte, offset int, v uint64) int { - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return offset + 1 -} -func (m *LoadImageRequest) Size() (n int) { - var l int - _ = l - l = len(m.FilePath) - if l > 0 { - n += 1 + l + sovApi(uint64(l)) - } - return n -} - -func (m *LoadImageResponse) Size() (n int) { - var l int - _ = l - if len(m.Images) > 0 { - for _, s := range m.Images { - l = len(s) - n += 1 + l + sovApi(uint64(l)) - } - } - return n -} - -func sovApi(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} -func sozApi(x uint64) (n int) { - return sovApi(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *LoadImageRequest) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&LoadImageRequest{`, - `FilePath:` + fmt.Sprintf("%v", this.FilePath) + `,`, - `}`, - }, "") - return s -} -func (this *LoadImageResponse) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&LoadImageResponse{`, - `Images:` + fmt.Sprintf("%v", this.Images) + `,`, - `}`, - }, "") - return s -} -func valueToStringApi(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *LoadImageRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApi - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: LoadImageRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: LoadImageRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FilePath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApi - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthApi - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.FilePath = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipApi(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthApi - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *LoadImageResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApi - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: LoadImageResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: LoadImageResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Images", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowApi - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthApi - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Images = append(m.Images, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipApi(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthApi - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipApi(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowApi - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowApi - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - return iNdEx, nil - case 1: - iNdEx += 8 - return iNdEx, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowApi - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - iNdEx += length - if length < 0 { - return 0, ErrInvalidLengthApi - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowApi - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipApi(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - } - return iNdEx, nil - case 4: - return iNdEx, nil - case 5: - iNdEx += 4 - return iNdEx, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} - -var ( - ErrInvalidLengthApi = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowApi = fmt.Errorf("proto: integer overflow") -) - -func init() { proto.RegisterFile("api.proto", fileDescriptorApi) } - -var fileDescriptorApi = []byte{ - // 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, - 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0xe9, 0x71, 0x09, 0xf8, 0xe4, 0x27, - 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, 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, -} diff --git a/pkg/api/v1/api.proto b/pkg/api/v1/api.proto deleted file mode 100644 index e5fafc8f6..000000000 --- a/pkg/api/v1/api.proto +++ /dev/null @@ -1,30 +0,0 @@ -// To regenerate api.pb.go run `make proto` -syntax = 'proto3'; - -package api.v1; - -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; - -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.stringer_all) = true; -option (gogoproto.goproto_getters_all) = true; -option (gogoproto.marshaler_all) = true; -option (gogoproto.sizer_all) = true; -option (gogoproto.unmarshaler_all) = true; -option (gogoproto.goproto_unrecognized_all) = false; - -// CRIPluginService defines non-CRI APIs for cri plugin. -service CRIPluginService{ - // LoadImage loads a image into containerd. - rpc LoadImage(LoadImageRequest) returns (LoadImageResponse) {} -} - -message LoadImageRequest { - // FilePath is the absolute path of docker image tarball. - string FilePath = 1; -} - -message LoadImageResponse { - // Images have been loaded. - repeated string Images = 1; -} diff --git a/pkg/client/client.go b/pkg/client/client.go deleted file mode 100644 index ab1a0fc55..000000000 --- a/pkg/client/client.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package client - -import ( - "context" - "net" - "time" - - "github.com/pkg/errors" - "google.golang.org/grpc" - "k8s.io/kubernetes/pkg/kubelet/util" - - api "github.com/containerd/cri/pkg/api/v1" -) - -// NewCRIPluginClient creates grpc client of cri plugin -// TODO(random-liu): Wrap grpc functions. -func NewCRIPluginClient(ctx context.Context, endpoint string) (api.CRIPluginServiceClient, error) { - addr, dialer, err := util.GetAddressAndDialer(endpoint) - if err != nil { - return nil, errors.Wrap(err, "failed to get dialer") - } - conn, err := grpc.DialContext(ctx, addr, - grpc.WithBlock(), - grpc.WithInsecure(), - grpc.WithContextDialer( - func(ctx context.Context, addr string) (net.Conn, error) { - if deadline, ok := ctx.Deadline(); ok { - return dialer(addr, time.Until(deadline)) - } - return dialer(addr, 0) - }), - ) - if err != nil { - return nil, errors.Wrap(err, "failed to dial") - } - return api.NewCRIPluginServiceClient(conn), nil -} diff --git a/pkg/containerd/importer/importer.go b/pkg/containerd/importer/importer.go deleted file mode 100644 index 3ac38752f..000000000 --- a/pkg/containerd/importer/importer.go +++ /dev/null @@ -1,356 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package importer - -import ( - "archive/tar" - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "strings" - - "github.com/containerd/containerd" - "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/docker/distribution/reference" - "github.com/opencontainers/go-digest" - "github.com/opencontainers/image-spec/specs-go" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - - ctrdutil "github.com/containerd/cri/pkg/containerd/util" -) - -// This code reuses the docker import code from containerd/containerd#1602. -// It has been simplified a bit and garbage collection support was added. -// If a library/helper is added to containerd in the future, we should switch to it. - -// manifestDotJSON is an entry in manifest.json. -type manifestDotJSON struct { - Config string - RepoTags []string - Layers []string - // Parent is unsupported - Parent string -} - -// isLayerTar returns true if name is like "foobar/layer.tar" -func isLayerTar(name string) bool { - slashes := len(strings.Split(name, "/")) - return slashes == 2 && strings.HasSuffix(name, "/layer.tar") -} - -// followSymlinkLayer returns actual layer name of the symlink layer. -// It returns "foobar/layer.tar" if the name is like -// "../foobar/layer.tar", and returns error if the name -// is not in "../foobar/layer.tar" format. -func followSymlinkLayer(name string) (string, error) { - parts := strings.Split(name, "/") - if len(parts) != 3 || parts[0] != ".." { - return "", errors.New("invalid symlink layer") - } - name = strings.TrimPrefix(name, "../") - if !isLayerTar(name) { - return "", errors.New("invalid layer tar") - } - return name, nil -} - -// isDotJSON returns true if name is like "foobar.json" -func isDotJSON(name string) bool { - slashes := len(strings.Split(name, "/")) - return slashes == 1 && strings.HasSuffix(name, ".json") -} - -type imageConfig struct { - desc ocispec.Descriptor - img ocispec.Image -} - -type importConfig struct { - unpack bool - snapshotter string -} - -// ImportOption configures import behavior. -type ImportOption func(*importConfig) - -// WithUnpack is used to unpack image after import. -func WithUnpack(snapshotter string) ImportOption { - return func(c *importConfig) { - c.unpack = true - c.snapshotter = snapshotter - } -} - -// Import implements Docker Image Spec v1.1. -// An image MUST have `manifest.json`. -// `repositories` file in Docker Image Spec v1.0 is not supported (yet). -// Also, the current implementation assumes the implicit file name convention, -// which is not explicitly documented in the spec. (e.g. foobar/layer.tar) -// It returns a group of image references successfully loaded. -func Import(ctx context.Context, client *containerd.Client, reader io.Reader, opts ...ImportOption) (_ []string, retErr error) { - c := &importConfig{} - for _, o := range opts { - o(c) - } - ctx, done, err := client.WithLease(ctx) - if err != nil { - return nil, err - } - 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.FromContext(ctx) - log.G(ctx).WithError(err).Errorf("Failed to release lease %q", leaseID) - } - }() - - cs := client.ContentStore() - is := client.ImageService() - - tr := tar.NewReader(reader) - var ( - mfsts []manifestDotJSON - symlinkLayers = make(map[string]string) // key: filename (foobar/layer.tar), value: linkname (targetlayerid/layer.tar) - layers = make(map[string]ocispec.Descriptor) // key: filename (foobar/layer.tar) - configs = make(map[string]imageConfig) // key: filename (foobar.json) - ) - for { - hdr, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - return nil, errors.Wrap(err, "get next file") - } - if hdr.Typeflag == tar.TypeSymlink && isLayerTar(hdr.Name) { - linkname, err := followSymlinkLayer(hdr.Linkname) - if err != nil { - return nil, errors.Wrapf(err, "follow symlink layer from %q to %q", hdr.Name, hdr.Linkname) - } - symlinkLayers[hdr.Name] = linkname - continue - } - if hdr.Typeflag != tar.TypeReg && hdr.Typeflag != tar.TypeRegA { - continue - } - if hdr.Name == "manifest.json" { - mfsts, err = onUntarManifestJSON(tr) - if err != nil { - return nil, errors.Wrapf(err, "untar manifest %q", hdr.Name) - } - continue - } - if isLayerTar(hdr.Name) { - desc, err := onUntarLayerTar(ctx, tr, cs, hdr.Name, hdr.Size) - if err != nil { - return nil, errors.Wrapf(err, "untar layer %q", hdr.Name) - } - layers[hdr.Name] = *desc - continue - } - if isDotJSON(hdr.Name) { - c, err := onUntarDotJSON(ctx, tr, cs, hdr.Name, hdr.Size) - if err != nil { - return nil, errors.Wrapf(err, "untar config %q", hdr.Name) - } - configs[hdr.Name] = *c - continue - } - } - for name, linkname := range symlinkLayers { - desc, ok := layers[linkname] - if !ok { - return nil, errors.Errorf("no target for symlink layer from %q to %q", name, linkname) - } - layers[name] = desc - } - var refs []string - defer func() { - if retErr == nil { - return - } - // TODO(random-liu): Consider whether we should keep images already imported - // even when there is an error. - for _, ref := range refs { - func() { - deferCtx, deferCancel := ctrdutil.DeferContext() - defer deferCancel() - if err := is.Delete(deferCtx, ref); err != nil { - log.G(ctx).WithError(err).Errorf("Failed to remove image %q", ref) - } - }() - } - }() - for _, mfst := range mfsts { - config, ok := configs[mfst.Config] - if !ok { - return refs, errors.Errorf("image config %q not found", mfst.Config) - } - schema2Manifest, err := makeDockerSchema2Manifest(mfst, config, layers) - if err != nil { - return refs, errors.Wrap(err, "create docker manifest") - } - desc, err := writeDockerSchema2Manifest(ctx, cs, *schema2Manifest, config.img.Architecture, config.img.OS) - if err != nil { - return refs, errors.Wrap(err, "write docker manifest") - } - - for _, ref := range mfst.RepoTags { - normalized, err := reference.ParseDockerRef(ref) - if err != nil { - return refs, errors.Wrapf(err, "normalize image ref %q", ref) - } - ref = normalized.String() - imgrec := images.Image{ - Name: ref, - Target: *desc, - } - if c.unpack { - img := containerd.NewImage(client, imgrec) - if err := img.Unpack(ctx, c.snapshotter); err != nil { - return refs, errors.Wrapf(err, "unpack image %q", ref) - } - } - if _, err := is.Create(ctx, imgrec); err != nil { - if !errdefs.IsAlreadyExists(err) { - return refs, errors.Wrapf(err, "create image ref %+v", imgrec) - } - - _, err := is.Update(ctx, imgrec) - if err != nil { - return refs, errors.Wrapf(err, "update image ref %+v", imgrec) - } - } - refs = append(refs, ref) - } - } - return refs, nil -} - -func makeDockerSchema2Manifest(mfst manifestDotJSON, config imageConfig, layers map[string]ocispec.Descriptor) (*ocispec.Manifest, error) { - manifest := ocispec.Manifest{ - Versioned: specs.Versioned{ - SchemaVersion: 2, - }, - Config: config.desc, - } - for _, f := range mfst.Layers { - desc, ok := layers[f] - if !ok { - return nil, errors.Errorf("layer %q not found", f) - } - manifest.Layers = append(manifest.Layers, desc) - } - return &manifest, nil -} - -func writeDockerSchema2Manifest(ctx context.Context, cs content.Ingester, manifest ocispec.Manifest, arch, os string) (*ocispec.Descriptor, error) { - manifestBytes, err := json.Marshal(manifest) - if err != nil { - return nil, err - } - manifestBytesR := bytes.NewReader(manifestBytes) - manifestDigest := digest.FromBytes(manifestBytes) - labels := map[string]string{} - labels["containerd.io/gc.ref.content.0"] = manifest.Config.Digest.String() - for i, ch := range manifest.Layers { - labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i+1)] = ch.Digest.String() - } - - desc := ocispec.Descriptor{ - MediaType: images.MediaTypeDockerSchema2Manifest, - Digest: manifestDigest, - Size: int64(len(manifestBytes)), - } - if err := content.WriteBlob(ctx, cs, "manifest-"+manifestDigest.String(), manifestBytesR, - desc, content.WithLabels(labels)); err != nil { - return nil, err - } - - if arch != "" || os != "" { - desc.Platform = &ocispec.Platform{ - Architecture: arch, - OS: os, - } - } - return &desc, nil -} - -func onUntarManifestJSON(r io.Reader) ([]manifestDotJSON, error) { - // name: "manifest.json" - b, err := ioutil.ReadAll(r) - if err != nil { - return nil, err - } - var mfsts []manifestDotJSON - if err := json.Unmarshal(b, &mfsts); err != nil { - return nil, err - } - return mfsts, nil -} - -func onUntarLayerTar(ctx context.Context, r io.Reader, cs content.Ingester, name string, size int64) (*ocispec.Descriptor, error) { - // name is like "foobar/layer.tar" ( guaranteed by isLayerTar() ) - split := strings.Split(name, "/") - // note: split[0] is not expected digest here - cw, err := cs.Writer(ctx, content.WithRef("layer-"+split[0]), content.WithDescriptor(ocispec.Descriptor{Size: size})) - if err != nil { - return nil, err - } - defer cw.Close() - if err := content.Copy(ctx, cw, r, size, ""); err != nil { - return nil, err - } - return &ocispec.Descriptor{ - MediaType: images.MediaTypeDockerSchema2Layer, - Size: size, - Digest: cw.Digest(), - }, nil -} - -func onUntarDotJSON(ctx context.Context, r io.Reader, cs content.Ingester, name string, size int64) (*imageConfig, error) { - config := imageConfig{} - config.desc.MediaType = images.MediaTypeDockerSchema2Config - config.desc.Size = size - // name is like "foobar.json" ( guaranteed by is DotJSON() ) - split := strings.Split(name, ".") - cw, err := cs.Writer(ctx, content.WithRef("config-"+split[0]), content.WithDescriptor(ocispec.Descriptor{Size: size})) - if err != nil { - return nil, err - } - defer cw.Close() - var buf bytes.Buffer - tr := io.TeeReader(r, &buf) - if err := content.Copy(ctx, cw, tr, size, ""); err != nil { - return nil, err - } - config.desc.Digest = cw.Digest() - if err := json.Unmarshal(buf.Bytes(), &config.img); err != nil { - return nil, err - } - return &config, nil -} diff --git a/pkg/server/image_load.go b/pkg/server/image_load.go deleted file mode 100644 index f286048d3..000000000 --- a/pkg/server/image_load.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package server - -import ( - "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" -) - -// LoadImage loads a image into containerd. -func (c *criService) LoadImage(ctx context.Context, r *api.LoadImageRequest) (*api.LoadImageResponse, error) { - path := r.GetFilePath() - if !filepath.IsAbs(path) { - return nil, errors.Errorf("path %q is not an absolute path", path) - } - f, err := os.Open(path) - if err != nil { - return nil, errors.Wrap(err, "failed to open file") - } - repoTags, err := importer.Import(ctx, c.client, f, importer.WithUnpack(c.config.ContainerdConfig.Snapshotter)) - if err != nil { - return nil, errors.Wrap(err, "failed to import image") - } - for _, repoTag := range repoTags { - // Update image store to reflect the newest state in containerd. - // Image imported by importer.Import is not treated as managed - // by the cri plugin, call `updateImage` to make it managed. - // TODO(random-liu): Replace this with the containerd library (issue #909). - if err := c.updateImage(ctx, repoTag); err != nil { - return nil, errors.Wrapf(err, "update image store %q", repoTag) - } - logrus.Debugf("Imported image %q", repoTag) - } - return &api.LoadImageResponse{Images: repoTags}, nil -} diff --git a/pkg/server/instrumented_service.go b/pkg/server/instrumented_service.go index 88e05f266..8ccc79a7d 100644 --- a/pkg/server/instrumented_service.go +++ b/pkg/server/instrumented_service.go @@ -23,7 +23,6 @@ import ( "golang.org/x/net/context" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" - api "github.com/containerd/cri/pkg/api/v1" ctrdutil "github.com/containerd/cri/pkg/containerd/util" "github.com/containerd/cri/pkg/log" ) @@ -448,21 +447,6 @@ func (in *instrumentedService) UpdateRuntimeConfig(ctx context.Context, r *runti return in.c.UpdateRuntimeConfig(ctrdutil.WithNamespace(ctx), r) } -func (in *instrumentedService) LoadImage(ctx context.Context, r *api.LoadImageRequest) (res *api.LoadImageResponse, err error) { - if err := in.checkInitialized(); err != nil { - return nil, err - } - logrus.Debugf("LoadImage from file %q", r.GetFilePath()) - defer func() { - if err != nil { - logrus.WithError(err).Error("LoadImage failed") - } else { - logrus.Debugf("LoadImage returns images %+v", res.GetImages()) - } - }() - return in.c.LoadImage(ctrdutil.WithNamespace(ctx), r) -} - func (in *instrumentedService) ReopenContainerLog(ctx context.Context, r *runtime.ReopenContainerLogRequest) (res *runtime.ReopenContainerLogResponse, err error) { if err := in.checkInitialized(); err != nil { return nil, err diff --git a/pkg/server/service.go b/pkg/server/service.go index 6c35d810d..ab22ddf1c 100644 --- a/pkg/server/service.go +++ b/pkg/server/service.go @@ -36,7 +36,6 @@ import ( runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "k8s.io/kubernetes/pkg/kubelet/server/streaming" - api "github.com/containerd/cri/pkg/api/v1" "github.com/containerd/cri/pkg/atomic" criconfig "github.com/containerd/cri/pkg/config" ctrdutil "github.com/containerd/cri/pkg/containerd/util" @@ -52,7 +51,6 @@ import ( type grpcServices interface { runtime.RuntimeServiceServer runtime.ImageServiceServer - api.CRIPluginServiceServer } // CRIService is the interface implement CRI remote service server. @@ -176,7 +174,6 @@ func (c *criService) Register(s *grpc.Server) error { instrumented := newInstrumentedService(c) runtime.RegisterRuntimeServiceServer(s, instrumented) runtime.RegisterImageServiceServer(s, instrumented) - api.RegisterCRIPluginServiceServer(s, instrumented) return nil } diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/app/main.go b/vendor/github.com/containerd/containerd/cmd/ctr/app/main.go deleted file mode 100644 index 9c33216b3..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/app/main.go +++ /dev/null @@ -1,116 +0,0 @@ -/* - 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 app - -import ( - "fmt" - "io/ioutil" - - "github.com/containerd/containerd/cmd/ctr/commands/containers" - "github.com/containerd/containerd/cmd/ctr/commands/content" - "github.com/containerd/containerd/cmd/ctr/commands/events" - "github.com/containerd/containerd/cmd/ctr/commands/images" - "github.com/containerd/containerd/cmd/ctr/commands/install" - "github.com/containerd/containerd/cmd/ctr/commands/leases" - namespacesCmd "github.com/containerd/containerd/cmd/ctr/commands/namespaces" - "github.com/containerd/containerd/cmd/ctr/commands/plugins" - "github.com/containerd/containerd/cmd/ctr/commands/pprof" - "github.com/containerd/containerd/cmd/ctr/commands/run" - "github.com/containerd/containerd/cmd/ctr/commands/snapshots" - "github.com/containerd/containerd/cmd/ctr/commands/tasks" - versionCmd "github.com/containerd/containerd/cmd/ctr/commands/version" - "github.com/containerd/containerd/defaults" - "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/version" - "github.com/sirupsen/logrus" - "github.com/urfave/cli" - "google.golang.org/grpc/grpclog" -) - -var extraCmds = []cli.Command{} - -func init() { - // Discard grpc logs so that they don't mess with our stdio - grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard)) - - cli.VersionPrinter = func(c *cli.Context) { - fmt.Println(c.App.Name, version.Package, c.App.Version) - } -} - -// New returns a *cli.App instance. -func New() *cli.App { - app := cli.NewApp() - app.Name = "ctr" - app.Version = version.Version - app.Usage = ` - __ - _____/ /______ - / ___/ __/ ___/ -/ /__/ /_/ / -\___/\__/_/ - -containerd CLI -` - app.Flags = []cli.Flag{ - cli.BoolFlag{ - Name: "debug", - Usage: "enable debug output in logs", - }, - cli.StringFlag{ - Name: "address, a", - Usage: "address for containerd's GRPC server", - Value: defaults.DefaultAddress, - }, - cli.DurationFlag{ - Name: "timeout", - Usage: "total timeout for ctr commands", - }, - cli.DurationFlag{ - Name: "connect-timeout", - Usage: "timeout for connecting to containerd", - }, - cli.StringFlag{ - Name: "namespace, n", - Usage: "namespace to use with commands", - Value: namespaces.Default, - EnvVar: namespaces.NamespaceEnvVar, - }, - } - app.Commands = append([]cli.Command{ - plugins.Command, - versionCmd.Command, - containers.Command, - content.Command, - events.Command, - images.Command, - leases.Command, - namespacesCmd.Command, - pprof.Command, - run.Command, - snapshots.Command, - tasks.Command, - install.Command, - }, extraCmds...) - app.Before = func(context *cli.Context) error { - if context.GlobalBool("debug") { - logrus.SetLevel(logrus.DebugLevel) - } - return nil - } - return app -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/app/main_unix.go b/vendor/github.com/containerd/containerd/cmd/ctr/app/main_unix.go deleted file mode 100644 index c0eb1b6e1..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/app/main_unix.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build !windows - -/* - 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 app - -import "github.com/containerd/containerd/cmd/ctr/commands/shim" - -func init() { - extraCmds = append(extraCmds, shim.Command) -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/client.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/client.go deleted file mode 100644 index b436186b2..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/client.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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 commands - -import ( - gocontext "context" - - "github.com/containerd/containerd" - "github.com/containerd/containerd/namespaces" - "github.com/urfave/cli" -) - -// AppContext returns the context for a command. Should only be called once per -// command, near the start. -// -// This will ensure the namespace is picked up and set the timeout, if one is -// defined. -func AppContext(context *cli.Context) (gocontext.Context, gocontext.CancelFunc) { - var ( - ctx = gocontext.Background() - timeout = context.GlobalDuration("timeout") - namespace = context.GlobalString("namespace") - cancel gocontext.CancelFunc - ) - ctx = namespaces.WithNamespace(ctx, namespace) - if timeout > 0 { - ctx, cancel = gocontext.WithTimeout(ctx, timeout) - } else { - ctx, cancel = gocontext.WithCancel(ctx) - } - return ctx, cancel -} - -// NewClient returns a new containerd client -func NewClient(context *cli.Context, opts ...containerd.ClientOpt) (*containerd.Client, gocontext.Context, gocontext.CancelFunc, error) { - client, err := containerd.New(context.GlobalString("address"), opts...) - if err != nil { - return nil, nil, nil, err - } - ctx, cancel := AppContext(context) - return client, ctx, cancel, nil -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands.go deleted file mode 100644 index 6d9fb5488..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands.go +++ /dev/null @@ -1,187 +0,0 @@ -/* - 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 commands - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "runtime" - "strings" - - "github.com/containerd/containerd" - "github.com/urfave/cli" -) - -var ( - // SnapshotterFlags are cli flags specifying snapshotter names - SnapshotterFlags = []cli.Flag{ - cli.StringFlag{ - Name: "snapshotter", - Usage: "snapshotter name. Empty value stands for the default value.", - Value: containerd.DefaultSnapshotter, - EnvVar: "CONTAINERD_SNAPSHOTTER", - }, - } - - // LabelFlag is a cli flag specifying labels - LabelFlag = cli.StringSliceFlag{ - Name: "label", - Usage: "labels to attach to the image", - } - - // RegistryFlags are cli flags specifying registry options - RegistryFlags = []cli.Flag{ - cli.BoolFlag{ - Name: "skip-verify,k", - Usage: "skip SSL certificate validation", - }, - cli.BoolFlag{ - Name: "plain-http", - Usage: "allow connections using plain HTTP", - }, - cli.StringFlag{ - Name: "user,u", - Usage: "user[:password] Registry user and password", - }, - cli.StringFlag{ - Name: "refresh", - Usage: "refresh token for authorization server", - }, - } - - // ContainerFlags are cli flags specifying container options - ContainerFlags = []cli.Flag{ - cli.StringFlag{ - Name: "config,c", - Usage: "path to the runtime-specific spec config file", - }, - cli.StringFlag{ - Name: "cwd", - Usage: "specify the working directory of the process", - }, - cli.StringSliceFlag{ - Name: "env", - Usage: "specify additional container environment variables (i.e. FOO=bar)", - }, - cli.StringSliceFlag{ - Name: "label", - Usage: "specify additional labels (i.e. foo=bar)", - }, - cli.StringSliceFlag{ - Name: "mount", - Usage: "specify additional container mount (ex: type=bind,src=/tmp,dst=/host,options=rbind:ro)", - }, - cli.BoolFlag{ - Name: "net-host", - Usage: "enable host networking for the container", - }, - cli.BoolFlag{ - Name: "privileged", - Usage: "run privileged container", - }, - cli.BoolFlag{ - Name: "read-only", - Usage: "set the containers filesystem as readonly", - }, - cli.StringFlag{ - Name: "runtime", - Usage: "runtime name", - Value: fmt.Sprintf("io.containerd.runtime.v1.%s", runtime.GOOS), - }, - cli.BoolFlag{ - Name: "tty,t", - Usage: "allocate a TTY for the container", - }, - cli.StringSliceFlag{ - Name: "with-ns", - Usage: "specify existing Linux namespaces to join at container runtime (format ':')", - }, - cli.StringFlag{ - Name: "pid-file", - Usage: "file path to write the task's pid", - }, - cli.IntFlag{ - Name: "gpus", - Usage: "add gpus to the container", - }, - cli.BoolFlag{ - Name: "allow-new-privs", - Usage: "turn off OCI spec's NoNewPrivileges feature flag", - }, - cli.Uint64Flag{ - Name: "memory-limit", - Usage: "memory limit (in bytes) for the container", - }, - } -) - -// ObjectWithLabelArgs returns the first arg and a LabelArgs object -func ObjectWithLabelArgs(clicontext *cli.Context) (string, map[string]string) { - var ( - first = clicontext.Args().First() - labelStrings = clicontext.Args().Tail() - ) - - return first, LabelArgs(labelStrings) -} - -// LabelArgs returns a map of label key,value pairs -func LabelArgs(labelStrings []string) map[string]string { - labels := make(map[string]string, len(labelStrings)) - for _, label := range labelStrings { - parts := strings.SplitN(label, "=", 2) - key := parts[0] - value := "true" - if len(parts) > 1 { - value = parts[1] - } - - labels[key] = value - } - - return labels -} - -// PrintAsJSON prints input in JSON format -func PrintAsJSON(x interface{}) { - b, err := json.MarshalIndent(x, "", " ") - if err != nil { - fmt.Fprintf(os.Stderr, "can't marshal %+v as a JSON string: %v\n", x, err) - } - fmt.Println(string(b)) -} - -// WritePidFile writes the pid atomically to a file -func WritePidFile(path string, pid int) error { - path, err := filepath.Abs(path) - if err != nil { - return err - } - tempPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path))) - f, err := os.OpenFile(tempPath, os.O_RDWR|os.O_CREATE|os.O_EXCL|os.O_SYNC, 0666) - if err != nil { - return err - } - _, err = fmt.Fprintf(f, "%d", pid) - f.Close() - if err != nil { - return err - } - return os.Rename(tempPath, path) -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands_unix.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands_unix.go deleted file mode 100644 index a67fa8f6a..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands_unix.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build !windows - -/* - 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 commands - -import ( - "github.com/urfave/cli" -) - -func init() { - ContainerFlags = append(ContainerFlags, cli.BoolFlag{ - Name: "rootfs", - Usage: "use custom rootfs that is not managed by containerd snapshotter", - }, cli.BoolFlag{ - Name: "no-pivot", - Usage: "disable use of pivot-root (linux only)", - }) -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands_windows.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands_windows.go deleted file mode 100644 index 4bd3d2596..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/commands_windows.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build windows - -/* - 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 commands - -import ( - "github.com/urfave/cli" -) - -func init() { - ContainerFlags = append(ContainerFlags, cli.Uint64Flag{ - Name: "cpu-count", - Usage: "number of CPUs available to the container", - }) -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/checkpoint.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/checkpoint.go deleted file mode 100644 index 53bf70b3c..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/checkpoint.go +++ /dev/null @@ -1,102 +0,0 @@ -/* - 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 containers - -import ( - "fmt" - - "github.com/containerd/containerd" - "github.com/containerd/containerd/cmd/ctr/commands" - "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" - "github.com/urfave/cli" -) - -var checkpointCommand = cli.Command{ - Name: "checkpoint", - Usage: "checkpoint a container", - ArgsUsage: "CONTAINER REF", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "rw", - Usage: "include the rw layer in the checkpoint", - }, - cli.BoolFlag{ - Name: "image", - Usage: "include the image in the checkpoint", - }, - cli.BoolFlag{ - Name: "task", - Usage: "checkpoint container task", - }, - }, - Action: func(context *cli.Context) error { - id := context.Args().First() - if id == "" { - return errors.New("container id must be provided") - } - ref := context.Args().Get(1) - if ref == "" { - return errors.New("ref must be provided") - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - opts := []containerd.CheckpointOpts{ - containerd.WithCheckpointRuntime, - } - - if context.Bool("image") { - opts = append(opts, containerd.WithCheckpointImage) - } - if context.Bool("rw") { - opts = append(opts, containerd.WithCheckpointRW) - } - if context.Bool("task") { - opts = append(opts, containerd.WithCheckpointTask) - } - container, err := client.LoadContainer(ctx, id) - if err != nil { - return err - } - task, err := container.Task(ctx, nil) - if err != nil { - if !errdefs.IsNotFound(err) { - return err - } - } - // pause if running - if task != nil { - if err := task.Pause(ctx); err != nil { - return err - } - defer func() { - if err := task.Resume(ctx); err != nil { - fmt.Println(errors.Wrap(err, "error resuming task")) - } - }() - } - - if _, err := container.Checkpoint(ctx, ref, opts...); err != nil { - return err - } - - return nil - }, -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go deleted file mode 100644 index fa0201064..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go +++ /dev/null @@ -1,286 +0,0 @@ -/* - 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 containers - -import ( - "context" - "fmt" - "os" - "strings" - "text/tabwriter" - - "github.com/containerd/containerd" - "github.com/containerd/containerd/cio" - "github.com/containerd/containerd/cmd/ctr/commands" - "github.com/containerd/containerd/cmd/ctr/commands/run" - "github.com/containerd/containerd/containers" - "github.com/containerd/containerd/log" - "github.com/containerd/typeurl" - "github.com/pkg/errors" - "github.com/urfave/cli" -) - -// Command is the cli command for managing containers -var Command = cli.Command{ - Name: "containers", - Usage: "manage containers", - Aliases: []string{"c", "container"}, - Subcommands: []cli.Command{ - createCommand, - deleteCommand, - infoCommand, - listCommand, - setLabelsCommand, - checkpointCommand, - restoreCommand, - }, -} - -var createCommand = cli.Command{ - Name: "create", - Usage: "create container", - ArgsUsage: "[flags] Image|RootFS CONTAINER [COMMAND] [ARG...]", - Flags: append(commands.SnapshotterFlags, commands.ContainerFlags...), - Action: func(context *cli.Context) error { - var ( - id string - ref string - config = context.IsSet("config") - ) - - if config { - id = context.Args().First() - if context.NArg() > 1 { - return errors.New("with spec config file, only container id should be provided") - } - } else { - id = context.Args().Get(1) - ref = context.Args().First() - if ref == "" { - return errors.New("image ref must be provided") - } - } - if id == "" { - return errors.New("container id must be provided") - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - _, err = run.NewContainer(ctx, client, context) - if err != nil { - return err - } - return nil - }, -} - -var listCommand = cli.Command{ - Name: "list", - Aliases: []string{"ls"}, - Usage: "list containers", - ArgsUsage: "[flags] [, ...]", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "quiet, q", - Usage: "print only the container id", - }, - }, - Action: func(context *cli.Context) error { - var ( - filters = context.Args() - quiet = context.Bool("quiet") - ) - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - containers, err := client.Containers(ctx, filters...) - if err != nil { - return err - } - if quiet { - for _, c := range containers { - fmt.Printf("%s\n", c.ID()) - } - return nil - } - w := tabwriter.NewWriter(os.Stdout, 4, 8, 4, ' ', 0) - fmt.Fprintln(w, "CONTAINER\tIMAGE\tRUNTIME\t") - for _, c := range containers { - info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata) - if err != nil { - return err - } - imageName := info.Image - if imageName == "" { - imageName = "-" - } - if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t\n", - c.ID(), - imageName, - info.Runtime.Name, - ); err != nil { - return err - } - } - return w.Flush() - }, -} - -var deleteCommand = cli.Command{ - Name: "delete", - Usage: "delete one or more existing containers", - ArgsUsage: "[flags] CONTAINER [CONTAINER, ...]", - Aliases: []string{"del", "rm"}, - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "keep-snapshot", - Usage: "do not clean up snapshot with container", - }, - }, - Action: func(context *cli.Context) error { - var exitErr error - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - deleteOpts := []containerd.DeleteOpts{} - if !context.Bool("keep-snapshot") { - deleteOpts = append(deleteOpts, containerd.WithSnapshotCleanup) - } - - if context.NArg() == 0 { - return errors.New("must specify at least one container to delete") - } - for _, arg := range context.Args() { - if err := deleteContainer(ctx, client, arg, deleteOpts...); err != nil { - if exitErr == nil { - exitErr = err - } - log.G(ctx).WithError(err).Errorf("failed to delete container %q", arg) - } - } - return exitErr - }, -} - -func deleteContainer(ctx context.Context, client *containerd.Client, id string, opts ...containerd.DeleteOpts) error { - container, err := client.LoadContainer(ctx, id) - if err != nil { - return err - } - task, err := container.Task(ctx, cio.Load) - if err != nil { - return container.Delete(ctx, opts...) - } - status, err := task.Status(ctx) - if err != nil { - return err - } - if status.Status == containerd.Stopped || status.Status == containerd.Created { - if _, err := task.Delete(ctx); err != nil { - return err - } - return container.Delete(ctx, opts...) - } - return fmt.Errorf("cannot delete a non stopped container: %v", status) - -} - -var setLabelsCommand = cli.Command{ - Name: "label", - Usage: "set and clear labels for a container", - ArgsUsage: "[flags] CONTAINER [=, ...]", - Description: "set and clear labels for a container", - Flags: []cli.Flag{}, - Action: func(context *cli.Context) error { - containerID, labels := commands.ObjectWithLabelArgs(context) - if containerID == "" { - return errors.New("container id must be provided") - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - - container, err := client.LoadContainer(ctx, containerID) - if err != nil { - return err - } - - setlabels, err := container.SetLabels(ctx, labels) - if err != nil { - return err - } - - var labelStrings []string - for k, v := range setlabels { - labelStrings = append(labelStrings, fmt.Sprintf("%s=%s", k, v)) - } - - fmt.Println(strings.Join(labelStrings, ",")) - - return nil - }, -} - -var infoCommand = cli.Command{ - Name: "info", - Usage: "get info about a container", - ArgsUsage: "CONTAINER", - Action: func(context *cli.Context) error { - id := context.Args().First() - if id == "" { - return errors.New("container id must be provided") - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - container, err := client.LoadContainer(ctx, id) - if err != nil { - return err - } - info, err := container.Info(ctx, containerd.WithoutRefreshedMetadata) - if err != nil { - return err - } - - if info.Spec != nil && info.Spec.Value != nil { - v, err := typeurl.UnmarshalAny(info.Spec) - if err != nil { - return err - } - commands.PrintAsJSON(struct { - containers.Container - Spec interface{} `json:"Spec,omitempty"` - }{ - Container: info, - Spec: v, - }) - return nil - } - commands.PrintAsJSON(info) - return nil - }, -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/restore.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/restore.go deleted file mode 100644 index 85337b34d..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/restore.go +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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 containers - -import ( - "github.com/containerd/containerd" - "github.com/containerd/containerd/cio" - "github.com/containerd/containerd/cmd/ctr/commands" - "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" - "github.com/urfave/cli" -) - -var restoreCommand = cli.Command{ - Name: "restore", - Usage: "restore a container from checkpoint", - ArgsUsage: "CONTAINER REF", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "rw", - Usage: "restore the rw layer from the checkpoint", - }, - cli.BoolFlag{ - Name: "live", - Usage: "restore the runtime and memory data from the checkpoint", - }, - }, - Action: func(context *cli.Context) error { - id := context.Args().First() - if id == "" { - return errors.New("container id must be provided") - } - ref := context.Args().Get(1) - if ref == "" { - return errors.New("ref must be provided") - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - - checkpoint, err := client.GetImage(ctx, ref) - if err != nil { - if !errdefs.IsNotFound(err) { - return err - } - // TODO (ehazlett): consider other options (always/never fetch) - ck, err := client.Fetch(ctx, ref) - if err != nil { - return err - } - checkpoint = containerd.NewImage(client, ck) - } - - opts := []containerd.RestoreOpts{ - containerd.WithRestoreImage, - containerd.WithRestoreSpec, - containerd.WithRestoreRuntime, - } - if context.Bool("rw") { - opts = append(opts, containerd.WithRestoreRW) - } - - ctr, err := client.Restore(ctx, id, checkpoint, opts...) - if err != nil { - return err - } - - topts := []containerd.NewTaskOpts{} - if context.Bool("live") { - topts = append(topts, containerd.WithTaskCheckpoint(checkpoint)) - } - - task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...) - if err != nil { - return err - } - - return task.Start(ctx) - }, -} diff --git a/vendor/github.com/containerd/containerd/cmd/ctr/commands/content/content.go b/vendor/github.com/containerd/containerd/cmd/ctr/commands/content/content.go deleted file mode 100644 index 737fc1672..000000000 --- a/vendor/github.com/containerd/containerd/cmd/ctr/commands/content/content.go +++ /dev/null @@ -1,570 +0,0 @@ -/* - 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 content - -import ( - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "strings" - "text/tabwriter" - "time" - - "github.com/containerd/containerd/cmd/ctr/commands" - "github.com/containerd/containerd/content" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/log" - units "github.com/docker/go-units" - digest "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - "github.com/urfave/cli" -) - -var ( - // Command is the cli command for managing content - Command = cli.Command{ - Name: "content", - Usage: "manage content", - Subcommands: cli.Commands{ - activeIngestCommand, - deleteCommand, - editCommand, - fetchCommand, - fetchObjectCommand, - getCommand, - ingestCommand, - listCommand, - pushObjectCommand, - setLabelsCommand, - }, - } - - getCommand = cli.Command{ - Name: "get", - Usage: "get the data for an object", - ArgsUsage: "[, ...]", - Description: "display the image object", - Action: func(context *cli.Context) error { - dgst, err := digest.Parse(context.Args().First()) - if err != nil { - return err - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - cs := client.ContentStore() - ra, err := cs.ReaderAt(ctx, ocispec.Descriptor{Digest: dgst}) - if err != nil { - return err - } - defer ra.Close() - - _, err = io.Copy(os.Stdout, content.NewReader(ra)) - return err - }, - } - - ingestCommand = cli.Command{ - Name: "ingest", - Usage: "accept content into the store", - ArgsUsage: "[flags] ", - Description: "ingest objects into the local content store", - Flags: []cli.Flag{ - cli.Int64Flag{ - Name: "expected-size", - Usage: "validate against provided size", - }, - cli.StringFlag{ - Name: "expected-digest", - Usage: "verify content against expected digest", - }, - }, - Action: func(context *cli.Context) error { - var ( - ref = context.Args().First() - expectedSize = context.Int64("expected-size") - expectedDigest = digest.Digest(context.String("expected-digest")) - ) - if err := expectedDigest.Validate(); expectedDigest != "" && err != nil { - return err - } - if ref == "" { - return errors.New("must specify a transaction reference") - } - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - - cs := client.ContentStore() - - // TODO(stevvooe): Allow ingest to be reentrant. Currently, we expect - // all data to be written in a single invocation. Allow multiple writes - // to the same transaction key followed by a commit. - return content.WriteBlob(ctx, cs, ref, os.Stdin, ocispec.Descriptor{Size: expectedSize, Digest: expectedDigest}) - }, - } - - activeIngestCommand = cli.Command{ - Name: "active", - Usage: "display active transfers", - ArgsUsage: "[flags] []", - Description: "display the ongoing transfers", - Flags: []cli.Flag{ - cli.DurationFlag{ - Name: "timeout, t", - Usage: "total timeout for fetch", - EnvVar: "CONTAINERD_FETCH_TIMEOUT", - }, - cli.StringFlag{ - Name: "root", - Usage: "path to content store root", - Value: "/tmp/content", // TODO(stevvooe): for now, just use the PWD/.content - }, - }, - Action: func(context *cli.Context) error { - match := context.Args().First() - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - cs := client.ContentStore() - active, err := cs.ListStatuses(ctx, match) - if err != nil { - return err - } - tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, '\t', 0) - fmt.Fprintln(tw, "REF\tSIZE\tAGE\t") - for _, active := range active { - fmt.Fprintf(tw, "%s\t%s\t%s\t\n", - active.Ref, - units.HumanSize(float64(active.Offset)), - units.HumanDuration(time.Since(active.StartedAt))) - } - - return tw.Flush() - }, - } - - listCommand = cli.Command{ - Name: "list", - Aliases: []string{"ls"}, - Usage: "list all blobs in the store", - ArgsUsage: "[flags]", - Description: "list blobs in the content store", - Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "quiet, q", - Usage: "print only the blob digest", - }, - }, - Action: func(context *cli.Context) error { - var ( - quiet = context.Bool("quiet") - args = []string(context.Args()) - ) - client, ctx, cancel, err := commands.NewClient(context) - if err != nil { - return err - } - defer cancel() - cs := client.ContentStore() - - var walkFn content.WalkFunc - if quiet { - walkFn = func(info content.Info) error { - fmt.Println(info.Digest) - return nil - } - } else { - tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, '\t', 0) - defer tw.Flush() - - fmt.Fprintln(tw, "DIGEST\tSIZE\tAGE\tLABELS") - walkFn = func(info content.Info) error { - var labelStrings []string - for k, v := range info.Labels { - labelStrings = append(labelStrings, strings.Join([]string{k, v}, "=")) - } - labels := strings.Join(labelStrings, ",") - if labels == "" { - labels = "-" - } - - fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n", - info.Digest, - units.HumanSize(float64(info.Size)), - units.HumanDuration(time.Since(info.CreatedAt)), - labels) - return nil - } - - } - - return cs.Walk(ctx, walkFn, args...) - }, - } - - setLabelsCommand = cli.Command{ - Name: "label", - Usage: "add labels to content", - ArgsUsage: " [