Remove load image support
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
78b4a39f5b
commit
322cd48965
27
Makefile
27
Makefile
@ -39,10 +39,8 @@ help:
|
||||
@echo "Usage: make <target>"
|
||||
@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 \
|
||||
|
78
cli/cli.go
78
cli/cli.go
@ -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
|
||||
},
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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,
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user