diff --git a/cmd/containerd-shim/main_unix.go b/cmd/containerd-shim/main_unix.go index a392cc2cf..8e449bf20 100644 --- a/cmd/containerd-shim/main_unix.go +++ b/cmd/containerd-shim/main_unix.go @@ -66,6 +66,19 @@ func main() { Name: "workdir,w", Usage: "path used to store large temporary data", }, + cli.StringFlag{ + Name: "runtime-root", + Usage: "root directory for the runtime", + Value: shim.RuncRoot, + }, + cli.StringFlag{ + Name: "criu,c", + Usage: "path to criu", + }, + cli.BoolFlag{ + Name: "systemd-cgroup", + Usage: "set runtime to use systemd-cgroup", + }, } app.Before = func(context *cli.Context) error { if context.GlobalBool("debug") { @@ -90,9 +103,14 @@ func main() { return err } sv, err := shim.NewService( - path, - context.GlobalString("namespace"), - context.GlobalString("workdir"), + shim.Config{ + Path: path, + Namespace: context.GlobalString("namespace"), + WorkDir: context.GlobalString("workdir"), + Criu: context.GlobalString("criu"), + SystemdCgroup: context.GlobalBool("systemd-cgroup"), + RuntimeRoot: context.GlobalString("runtime-root"), + }, &remoteEventsPublisher{client: e}, ) if err != nil { diff --git a/container_linux_test.go b/container_linux_test.go index d6d7550fb..f70fb5bb3 100644 --- a/container_linux_test.go +++ b/container_linux_test.go @@ -851,3 +851,48 @@ func TestDaemonRestartWithRunningShim(t *testing.T) { t.Errorf("pid %d still exists", pid) } } + +func TestContainerRuntimeOptions(t *testing.T) { + t.Parallel() + + client, err := newClient(t, address) + if err != nil { + t.Fatal(err) + } + defer client.Close() + + var ( + image Image + ctx, cancel = testContext() + id = t.Name() + ) + defer cancel() + + image, err = client.GetImage(ctx, testImage) + if err != nil { + t.Error(err) + return + } + + container, err := client.NewContainer( + ctx, id, + WithNewSpec(withImageConfig(image), withExitStatus(7)), + withNewSnapshot(id, image), + WithRuntime("io.containerd.runtime.v1.linux", &runcopts.RuncOptions{Runtime: "no-runc"}), + ) + if err != nil { + t.Error(err) + return + } + defer container.Delete(ctx, WithSnapshotCleanup) + + task, err := container.NewTask(ctx, empty()) + if err == nil { + t.Errorf("task creation should have failed") + task.Delete(ctx) + return + } + if !strings.Contains(err.Error(), `"no-runc"`) { + t.Errorf("task creation should have failed because of lack of executable. Instead failed with: %v", err.Error()) + } +} diff --git a/linux/bundle.go b/linux/bundle.go index f05da157c..242761504 100644 --- a/linux/bundle.go +++ b/linux/bundle.go @@ -12,23 +12,19 @@ import ( "github.com/containerd/containerd/events" "github.com/containerd/containerd/linux/runcopts" client "github.com/containerd/containerd/linux/shim" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/typeurl" "github.com/pkg/errors" ) -func loadBundle(path, workdir, namespace, id string, events *events.Exchange) *bundle { +func loadBundle(id, path, workdir string) *bundle { return &bundle{ - path: path, - namespace: namespace, - id: id, - events: events, - workDir: workdir, + id: id, + path: path, + workDir: workdir, } } // newBundle creates a new bundle on disk at the provided path for the given id -func newBundle(namespace, id, path, workDir string, spec []byte, events *events.Exchange) (b *bundle, err error) { +func newBundle(id, path, workDir string, spec []byte) (b *bundle, err error) { if err := os.MkdirAll(path, 0711); err != nil { return nil, err } @@ -61,56 +57,43 @@ func newBundle(namespace, id, path, workDir string, spec []byte, events *events. defer f.Close() _, err = io.Copy(f, bytes.NewReader(spec)) return &bundle{ - id: id, - path: path, - workDir: workDir, - namespace: namespace, - events: events, + id: id, + path: path, + workDir: workDir, }, err } type bundle struct { - id string - path string - workDir string - namespace string - events *events.Exchange + id string + path string + workDir string } -// NewShim connects to the shim managing the bundle and tasks -func (b *bundle) NewShim(ctx context.Context, binary, grpcAddress string, remote, debug bool, createOpts runtime.CreateOpts, exitHandler func()) (*client.Client, error) { - opt := client.WithStart(binary, grpcAddress, debug, exitHandler) - if !remote { - opt = client.WithLocal(b.events) +type shimOpt func(*bundle, string, *runcopts.RuncOptions) (client.Config, client.ClientOpt) + +func ShimRemote(shim, daemonAddress, cgroup string, debug bool, exitHandler func()) shimOpt { + return func(b *bundle, ns string, ropts *runcopts.RuncOptions) (client.Config, client.ClientOpt) { + return b.shimConfig(ns, ropts), + client.WithStart(shim, b.shimAddress(ns), daemonAddress, cgroup, debug, exitHandler) } - var options runcopts.CreateOptions - if createOpts.Options != nil { - v, err := typeurl.UnmarshalAny(createOpts.Options) - if err != nil { - return nil, err - } - options = *v.(*runcopts.CreateOptions) - } - return client.New(ctx, client.Config{ - Address: b.shimAddress(), - Path: b.path, - Namespace: b.namespace, - CgroupPath: options.ShimCgroup, - WorkDir: b.workDir, - }, opt) } -// Connect reconnects to an existing shim -func (b *bundle) Connect(ctx context.Context, remote bool) (*client.Client, error) { - opt := client.WithConnect - if !remote { - opt = client.WithLocal(b.events) +func ShimLocal(exchange *events.Exchange) shimOpt { + return func(b *bundle, ns string, ropts *runcopts.RuncOptions) (client.Config, client.ClientOpt) { + return b.shimConfig(ns, ropts), client.WithLocal(exchange) } - return client.New(ctx, client.Config{ - Address: b.shimAddress(), - Path: b.path, - Namespace: b.namespace, - }, opt) +} + +func ShimConnect() shimOpt { + return func(b *bundle, ns string, ropts *runcopts.RuncOptions) (client.Config, client.ClientOpt) { + return b.shimConfig(ns, ropts), client.WithConnect(b.shimAddress(ns)) + } +} + +// NewShimClient connects to the shim managing the bundle and tasks creating it if needed +func (b *bundle) NewShimClient(ctx context.Context, namespace string, getClientOpts shimOpt, runcOpts *runcopts.RuncOptions) (*client.Client, error) { + cfg, opt := getClientOpts(b, namespace, runcOpts) + return client.New(ctx, cfg, opt) } // Delete deletes the bundle from disk @@ -127,7 +110,28 @@ func (b *bundle) Delete() error { return errors.Wrapf(err, "Failed to remove both bundle and workdir locations: %v", err2) } -func (b *bundle) shimAddress() string { - return filepath.Join(string(filepath.Separator), "containerd-shim", b.namespace, b.id, "shim.sock") +func (b *bundle) shimAddress(namespace string) string { + return filepath.Join(string(filepath.Separator), "containerd-shim", namespace, b.id, "shim.sock") } + +func (b *bundle) shimConfig(namespace string, runcOptions *runcopts.RuncOptions) client.Config { + var ( + criuPath string + runtimeRoot string + systemdCgroup bool + ) + if runcOptions != nil { + criuPath = runcOptions.CriuPath + systemdCgroup = runcOptions.SystemdCgroup + runtimeRoot = runcOptions.RuntimeRoot + } + return client.Config{ + Path: b.path, + WorkDir: b.workDir, + Namespace: namespace, + Criu: criuPath, + RuntimeRoot: runtimeRoot, + SystemdCgroup: systemdCgroup, + } +} diff --git a/linux/runcopts/runc.pb.go b/linux/runcopts/runc.pb.go index 4d642fc68..0a5c3b72f 100644 --- a/linux/runcopts/runc.pb.go +++ b/linux/runcopts/runc.pb.go @@ -37,8 +37,10 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package type RuncOptions struct { - CriuPath string `protobuf:"bytes,1,opt,name=criu_path,json=criuPath,proto3" json:"criu_path,omitempty"` - SystemdCgroup string `protobuf:"bytes,2,opt,name=systemd_cgroup,json=systemdCgroup,proto3" json:"systemd_cgroup,omitempty"` + Runtime string `protobuf:"bytes,1,opt,name=runtime,proto3" json:"runtime,omitempty"` + RuntimeRoot string `protobuf:"bytes,2,opt,name=runtime_root,json=runtimeRoot,proto3" json:"runtime_root,omitempty"` + CriuPath string `protobuf:"bytes,3,opt,name=criu_path,json=criuPath,proto3" json:"criu_path,omitempty"` + SystemdCgroup bool `protobuf:"varint,4,opt,name=systemd_cgroup,json=systemdCgroup,proto3" json:"systemd_cgroup,omitempty"` } func (m *RuncOptions) Reset() { *m = RuncOptions{} } @@ -95,17 +97,33 @@ func (m *RuncOptions) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.CriuPath) > 0 { + if len(m.Runtime) > 0 { dAtA[i] = 0xa i++ + i = encodeVarintRunc(dAtA, i, uint64(len(m.Runtime))) + i += copy(dAtA[i:], m.Runtime) + } + if len(m.RuntimeRoot) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRunc(dAtA, i, uint64(len(m.RuntimeRoot))) + i += copy(dAtA[i:], m.RuntimeRoot) + } + if len(m.CriuPath) > 0 { + dAtA[i] = 0x1a + i++ i = encodeVarintRunc(dAtA, i, uint64(len(m.CriuPath))) i += copy(dAtA[i:], m.CriuPath) } - if len(m.SystemdCgroup) > 0 { - dAtA[i] = 0x12 + if m.SystemdCgroup { + dAtA[i] = 0x20 + i++ + if m.SystemdCgroup { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } i++ - i = encodeVarintRunc(dAtA, i, uint64(len(m.SystemdCgroup))) - i += copy(dAtA[i:], m.SystemdCgroup) } return i, nil } @@ -334,13 +352,20 @@ func encodeVarintRunc(dAtA []byte, offset int, v uint64) int { func (m *RuncOptions) Size() (n int) { var l int _ = l + l = len(m.Runtime) + if l > 0 { + n += 1 + l + sovRunc(uint64(l)) + } + l = len(m.RuntimeRoot) + if l > 0 { + n += 1 + l + sovRunc(uint64(l)) + } l = len(m.CriuPath) if l > 0 { n += 1 + l + sovRunc(uint64(l)) } - l = len(m.SystemdCgroup) - if l > 0 { - n += 1 + l + sovRunc(uint64(l)) + if m.SystemdCgroup { + n += 2 } return n } @@ -432,6 +457,8 @@ func (this *RuncOptions) String() string { return "nil" } s := strings.Join([]string{`&RuncOptions{`, + `Runtime:` + fmt.Sprintf("%v", this.Runtime) + `,`, + `RuntimeRoot:` + fmt.Sprintf("%v", this.RuntimeRoot) + `,`, `CriuPath:` + fmt.Sprintf("%v", this.CriuPath) + `,`, `SystemdCgroup:` + fmt.Sprintf("%v", this.SystemdCgroup) + `,`, `}`, @@ -510,6 +537,64 @@ func (m *RuncOptions) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Runtime", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRunc + } + 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 ErrInvalidLengthRunc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Runtime = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RuntimeRoot", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRunc + } + 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 ErrInvalidLengthRunc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RuntimeRoot = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CriuPath", wireType) } @@ -538,11 +623,11 @@ func (m *RuncOptions) Unmarshal(dAtA []byte) error { } m.CriuPath = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { + case 4: + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SystemdCgroup", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowRunc @@ -552,21 +637,12 @@ func (m *RuncOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift + v |= (int(b) & 0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRunc - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SystemdCgroup = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex + m.SystemdCgroup = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRunc(dAtA[iNdEx:]) @@ -1163,33 +1239,35 @@ func init() { } var fileDescriptorRunc = []byte{ - // 438 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x93, 0xb1, 0x6f, 0xd4, 0x30, - 0x18, 0xc5, 0x9b, 0xb6, 0xb4, 0x89, 0xaf, 0x57, 0xc0, 0x50, 0x29, 0x14, 0x11, 0xca, 0x09, 0xa4, - 0xb2, 0xdc, 0x49, 0xb0, 0x20, 0xd8, 0xb8, 0x11, 0x28, 0x25, 0xc0, 0xc2, 0x62, 0xa5, 0xbe, 0x8f, - 0xc4, 0xba, 0xe4, 0xfb, 0x2c, 0xdb, 0xa1, 0xb9, 0x8d, 0x3f, 0xaf, 0x23, 0x62, 0x62, 0xa4, 0xf9, - 0x47, 0x40, 0x71, 0x2e, 0x85, 0x95, 0x95, 0xed, 0xf9, 0xf7, 0x9e, 0x9e, 0xa5, 0x27, 0x7d, 0xec, - 0x79, 0xae, 0x5c, 0x51, 0x9f, 0x4d, 0x25, 0x55, 0x33, 0x49, 0xe8, 0x32, 0x85, 0x60, 0x16, 0x7f, - 0xcb, 0x52, 0x61, 0xdd, 0xcc, 0x4c, 0x8d, 0x92, 0xb4, 0xb3, 0x5e, 0x4c, 0xb5, 0x21, 0x47, 0xfc, - 0xe0, 0x4f, 0x6a, 0xea, 0x53, 0xd3, 0xce, 0x3c, 0xbc, 0x9d, 0x53, 0x4e, 0x3e, 0x31, 0xeb, 0x54, - 0x1f, 0x9e, 0xbc, 0x63, 0xa3, 0xb4, 0x46, 0xf9, 0x56, 0x3b, 0x45, 0x68, 0xf9, 0x5d, 0x16, 0x49, - 0xa3, 0x6a, 0xa1, 0x33, 0x57, 0xc4, 0xc1, 0x51, 0x70, 0x1c, 0xa5, 0x61, 0x07, 0x4e, 0x33, 0x57, - 0xf0, 0x47, 0x6c, 0xdf, 0xae, 0xac, 0x83, 0x6a, 0x21, 0x64, 0x6e, 0xa8, 0xd6, 0xf1, 0xa6, 0x4f, - 0x8c, 0xd7, 0x74, 0xee, 0xe1, 0xe4, 0xfb, 0x26, 0x1b, 0xcf, 0x0d, 0x64, 0x0e, 0x86, 0xd6, 0x09, - 0x1b, 0x23, 0x09, 0xad, 0xbe, 0x90, 0x13, 0x86, 0xc8, 0xf9, 0xe6, 0x30, 0x1d, 0x21, 0x9d, 0x76, - 0x2c, 0x25, 0x72, 0xfc, 0x0e, 0x0b, 0x49, 0x03, 0x0a, 0x27, 0xfb, 0xda, 0x30, 0xdd, 0xed, 0xde, - 0x1f, 0xa4, 0xe6, 0x4f, 0xd8, 0x01, 0x34, 0x0e, 0x0c, 0x66, 0xa5, 0xa8, 0x51, 0x35, 0xc2, 0x92, - 0x5c, 0x82, 0xb3, 0xf1, 0x96, 0xcf, 0xdd, 0x1a, 0xcc, 0x8f, 0xa8, 0x9a, 0xf7, 0xbd, 0xc5, 0x0f, - 0x59, 0xe8, 0xc0, 0x54, 0x0a, 0xb3, 0x32, 0xde, 0xf6, 0xb1, 0xab, 0x37, 0xbf, 0xc7, 0xd8, 0x67, - 0x55, 0x82, 0x28, 0x49, 0x2e, 0x6d, 0x7c, 0xcd, 0xbb, 0x51, 0x47, 0x5e, 0x77, 0x80, 0x3f, 0x66, - 0x37, 0xa0, 0xd2, 0x6e, 0x25, 0x30, 0xab, 0xc0, 0xea, 0x4c, 0x82, 0x8d, 0x77, 0x8e, 0xb6, 0x8e, - 0xa3, 0xf4, 0xba, 0xe7, 0x27, 0x57, 0x98, 0x3f, 0x60, 0x7b, 0xfd, 0x12, 0x56, 0x54, 0xb4, 0x80, - 0x78, 0xd7, 0xef, 0x31, 0x5a, 0xb3, 0x37, 0xb4, 0x00, 0xfe, 0x90, 0xed, 0x23, 0x09, 0x84, 0x73, - 0xb1, 0x84, 0x95, 0x51, 0x98, 0xc7, 0xa1, 0xff, 0x70, 0x0f, 0xe9, 0x04, 0xce, 0x5f, 0xf5, 0x8c, - 0xdf, 0x67, 0x23, 0x5b, 0xa8, 0x6a, 0xd8, 0x35, 0xf2, 0x3d, 0xac, 0x43, 0xeb, 0x51, 0x7f, 0x05, - 0xec, 0xe6, 0xbc, 0x00, 0xb9, 0xd4, 0xa4, 0xd0, 0x0d, 0xc3, 0x72, 0xb6, 0x0d, 0x8d, 0x1a, 0xf6, - 0xf4, 0xfa, 0x7f, 0x1d, 0xf2, 0x65, 0x7a, 0x71, 0x99, 0x6c, 0xfc, 0xb8, 0x4c, 0x36, 0xbe, 0xb6, - 0x49, 0x70, 0xd1, 0x26, 0xc1, 0xb7, 0x36, 0x09, 0x7e, 0xb6, 0x49, 0xf0, 0xe9, 0xd9, 0x3f, 0x1e, - 0xcb, 0x8b, 0x41, 0x9c, 0xed, 0xf8, 0x23, 0x78, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x19, - 0xba, 0x8f, 0x6f, 0x03, 0x00, 0x00, + // 467 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x93, 0x41, 0x6f, 0xd3, 0x40, + 0x10, 0x85, 0xbb, 0x6d, 0x69, 0x9d, 0x4d, 0x53, 0x60, 0xa1, 0x92, 0x29, 0xc2, 0x84, 0x08, 0xa4, + 0x70, 0x49, 0x24, 0xb8, 0x20, 0xb8, 0x91, 0x23, 0x50, 0x2a, 0x03, 0x17, 0x2e, 0x2b, 0x77, 0x33, + 0x24, 0xab, 0xd8, 0x33, 0xab, 0xdd, 0x35, 0x75, 0x6e, 0xfc, 0x02, 0x7e, 0x57, 0x8f, 0x88, 0x13, + 0x47, 0x9a, 0x3f, 0x02, 0xf2, 0xda, 0x2e, 0x5c, 0xb9, 0x72, 0x7b, 0xf3, 0xbd, 0xb1, 0xe7, 0xe9, + 0x49, 0xcb, 0x9f, 0x2f, 0xb4, 0x5f, 0x96, 0x67, 0x13, 0x45, 0xc5, 0x54, 0x11, 0xfa, 0x4c, 0x23, + 0xd8, 0xf9, 0xdf, 0x32, 0xd7, 0x58, 0x56, 0x53, 0x5b, 0xa2, 0x22, 0xe3, 0x5d, 0x10, 0x13, 0x63, + 0xc9, 0x93, 0x38, 0xfa, 0xb3, 0x35, 0x09, 0x5b, 0x93, 0xda, 0x3c, 0xbe, 0xbd, 0xa0, 0x05, 0x85, + 0x8d, 0x69, 0xad, 0x9a, 0xe5, 0xd1, 0x57, 0xc6, 0xfb, 0x69, 0x89, 0xea, 0xad, 0xf1, 0x9a, 0xd0, + 0x89, 0x98, 0xef, 0xdb, 0x12, 0xbd, 0x2e, 0x20, 0x66, 0x43, 0x36, 0xee, 0xa5, 0xdd, 0x28, 0x1e, + 0xf0, 0x83, 0x56, 0x4a, 0x4b, 0xe4, 0xe3, 0xed, 0x60, 0xf7, 0x5b, 0x96, 0x12, 0x79, 0x71, 0x97, + 0xf7, 0x94, 0xd5, 0xa5, 0x34, 0x99, 0x5f, 0xc6, 0x3b, 0xc1, 0x8f, 0x6a, 0x70, 0x9a, 0xf9, 0xa5, + 0x78, 0xc4, 0x0f, 0xdd, 0xda, 0x79, 0x28, 0xe6, 0x52, 0x2d, 0x2c, 0x95, 0x26, 0xde, 0x1d, 0xb2, + 0x71, 0x94, 0x0e, 0x5a, 0x3a, 0x0b, 0x70, 0xf4, 0x7d, 0x9b, 0x0f, 0x66, 0x16, 0x32, 0x0f, 0x5d, + 0xa4, 0x11, 0x1f, 0x20, 0x49, 0xa3, 0x3f, 0x93, 0x6f, 0x2e, 0xb3, 0xf0, 0x5d, 0x1f, 0xe9, 0xb4, + 0x66, 0xe1, 0xf2, 0x1d, 0x1e, 0x91, 0x01, 0x94, 0x5e, 0x99, 0x10, 0x2c, 0x4a, 0xf7, 0xeb, 0xf9, + 0xbd, 0x32, 0xe2, 0x09, 0x3f, 0x82, 0xca, 0x83, 0xc5, 0x2c, 0x97, 0x25, 0xea, 0x4a, 0x3a, 0x52, + 0x2b, 0xf0, 0x2e, 0x04, 0x8c, 0xd2, 0x5b, 0x9d, 0xf9, 0x01, 0x75, 0xf5, 0xae, 0xb1, 0xc4, 0x31, + 0x8f, 0x3c, 0xd8, 0x42, 0x63, 0x96, 0xb7, 0x29, 0xaf, 0x66, 0x71, 0x8f, 0xf3, 0x4f, 0x3a, 0x07, + 0x99, 0x93, 0x5a, 0xb9, 0xf8, 0x5a, 0x70, 0x7b, 0x35, 0x79, 0x5d, 0x03, 0xf1, 0x98, 0xdf, 0x80, + 0xc2, 0xf8, 0xb5, 0xc4, 0xac, 0x00, 0x67, 0x32, 0x05, 0x2e, 0xde, 0x1b, 0xee, 0x8c, 0x7b, 0xe9, + 0xf5, 0xc0, 0x4f, 0xae, 0x70, 0xdd, 0x68, 0xd3, 0x84, 0x93, 0x05, 0xcd, 0x21, 0xde, 0x6f, 0x1a, + 0x6d, 0xd9, 0x1b, 0x9a, 0x83, 0x78, 0xc8, 0x0f, 0x91, 0x24, 0xc2, 0xb9, 0x5c, 0xc1, 0xda, 0x6a, + 0x5c, 0xc4, 0x51, 0x38, 0x78, 0x80, 0x74, 0x02, 0xe7, 0xaf, 0x1a, 0x26, 0xee, 0xf3, 0xbe, 0x5b, + 0xea, 0xa2, 0xeb, 0xb5, 0x17, 0xfe, 0xc3, 0x6b, 0xd4, 0x96, 0xfa, 0x8b, 0xf1, 0x9b, 0xb3, 0x25, + 0xa8, 0x95, 0x21, 0x8d, 0xbe, 0x2b, 0x56, 0xf0, 0x5d, 0xa8, 0x74, 0xd7, 0x67, 0xd0, 0xff, 0x6b, + 0x91, 0x2f, 0xd3, 0x8b, 0xcb, 0x64, 0xeb, 0xc7, 0x65, 0xb2, 0xf5, 0x65, 0x93, 0xb0, 0x8b, 0x4d, + 0xc2, 0xbe, 0x6d, 0x12, 0xf6, 0x73, 0x93, 0xb0, 0x8f, 0xcf, 0xfe, 0xf1, 0xa9, 0xbd, 0xe8, 0xc4, + 0xd9, 0x5e, 0x78, 0x42, 0x4f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x26, 0x29, 0x60, 0xad, + 0x03, 0x00, 0x00, } diff --git a/linux/runcopts/runc.proto b/linux/runcopts/runc.proto index a47f6b21d..bf31d2bb5 100644 --- a/linux/runcopts/runc.proto +++ b/linux/runcopts/runc.proto @@ -7,8 +7,10 @@ import "gogoproto/gogo.proto"; option go_package = "github.com/containerd/containerd/linux/runcopts;runcopts"; message RuncOptions { - string criu_path = 1; - string systemd_cgroup = 2; + string runtime = 1; + string runtime_root = 2; + string criu_path = 3; + bool systemd_cgroup = 4; } message CreateOptions { diff --git a/linux/runtime.go b/linux/runtime.go index f3638a149..6f6567aaa 100644 --- a/linux/runtime.go +++ b/linux/runtime.go @@ -13,9 +13,11 @@ import ( "github.com/boltdb/bolt" eventsapi "github.com/containerd/containerd/api/services/events/v1" "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/containers" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/events" "github.com/containerd/containerd/identifiers" + "github.com/containerd/containerd/linux/runcopts" client "github.com/containerd/containerd/linux/shim" shim "github.com/containerd/containerd/linux/shim/v1" "github.com/containerd/containerd/log" @@ -25,6 +27,7 @@ import ( "github.com/containerd/containerd/reaper" "github.com/containerd/containerd/runtime" "github.com/containerd/containerd/sys" + "github.com/containerd/containerd/typeurl" runc "github.com/containerd/go-runc" google_protobuf "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" @@ -67,6 +70,8 @@ type Config struct { Shim string `toml:"shim,omitempty"` // Runtime is a path or name of an OCI runtime used by the shim Runtime string `toml:"runtime,omitempty"` + // RuntimeRoot is the path that shall be used by the OCI runtime for its data + RuntimeRoot string `toml:"runtime_root,omitempty"` // NoShim calls runc directly from within the pkg NoShim bool `toml:"no_shim,omitempty"` // Debug enable debug on the shim @@ -90,17 +95,14 @@ func New(ic *plugin.InitContext) (interface{}, error) { } cfg := ic.Config.(*Config) r := &Runtime{ - root: ic.Root, - state: ic.State, - remote: !cfg.NoShim, - shim: cfg.Shim, - shimDebug: cfg.ShimDebug, - runtime: cfg.Runtime, - monitor: monitor.(runtime.TaskMonitor), - tasks: runtime.NewTaskList(), - db: m.(*bolt.DB), - address: ic.Address, - events: ic.Events, + root: ic.Root, + state: ic.State, + monitor: monitor.(runtime.TaskMonitor), + tasks: runtime.NewTaskList(), + db: m.(*bolt.DB), + address: ic.Address, + events: ic.Events, + config: cfg, } tasks, err := r.restoreTasks(ic.Context) if err != nil { @@ -116,18 +118,16 @@ func New(ic *plugin.InitContext) (interface{}, error) { } type Runtime struct { - root string - state string - shim string - shimDebug bool - runtime string - remote bool - address string + root string + state string + address string monitor runtime.TaskMonitor tasks *runtime.TaskList db *bolt.DB events *events.Exchange + + config *Config } func (r *Runtime) ID() string { @@ -144,14 +144,18 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts return nil, errors.Wrapf(err, "invalid task id") } + ropts, err := r.getRuncOptions(ctx, id) + if err != nil { + return nil, err + } + ec := reaper.Default.Subscribe() defer reaper.Default.Unsubscribe(ec) - bundle, err := newBundle( - namespace, id, + bundle, err := newBundle(id, filepath.Join(r.state, namespace), filepath.Join(r.root, namespace), - opts.Spec.Value, r.events) + opts.Spec.Value) if err != nil { return nil, err } @@ -160,36 +164,50 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts bundle.Delete() } }() - s, err := bundle.NewShim(ctx, r.shim, r.address, r.remote, r.shimDebug, opts, func() { - t, err := r.tasks.Get(ctx, id) - if err != nil { - // Task was never started or was already sucessfully deleted - return - } - lc := t.(*Task) - // Stop the monitor - if err := r.monitor.Stop(lc); err != nil { - log.G(ctx).WithError(err).WithFields(logrus.Fields{ + shimopt := ShimLocal(r.events) + if !r.config.NoShim { + var cgroup string + if opts.Options != nil { + v, err := typeurl.UnmarshalAny(opts.Options) + if err != nil { + return nil, err + } + cgroup = v.(*runcopts.CreateOptions).ShimCgroup + } + shimopt = ShimRemote(r.config.Shim, r.address, cgroup, r.config.ShimDebug, func() { + t, err := r.tasks.Get(ctx, id) + if err != nil { + // Task was never started or was already sucessfully deleted + return + } + lc := t.(*Task) + + // Stop the monitor + if err := r.monitor.Stop(lc); err != nil { + log.G(ctx).WithError(err).WithFields(logrus.Fields{ + "id": id, + "namespace": namespace, + }).Warn("failed to stop monitor") + } + + log.G(ctx).WithFields(logrus.Fields{ "id": id, "namespace": namespace, - }).Warn("failed to stop monitor") - } + }).Warn("cleaning up after killed shim") + err = r.cleanupAfterDeadShim(context.Background(), bundle, namespace, id, lc.pid, ec) + if err == nil { + r.tasks.Delete(ctx, lc) + } else { + log.G(ctx).WithError(err).WithFields(logrus.Fields{ + "id": id, + "namespace": namespace, + }).Warn("failed to clen up after killed shim") + } + }) + } - log.G(ctx).WithFields(logrus.Fields{ - "id": id, - "namespace": namespace, - }).Warn("cleaning up after killed shim") - err = r.cleanupAfterDeadShim(context.Background(), bundle, namespace, id, lc.pid, ec) - if err == nil { - r.tasks.Delete(ctx, lc) - } else { - log.G(ctx).WithError(err).WithFields(logrus.Fields{ - "id": id, - "namespace": namespace, - }).Warn("failed to clen up after killed shim") - } - }) + s, err := bundle.NewShimClient(ctx, namespace, shimopt, ropts) if err != nil { return nil, err } @@ -200,10 +218,15 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts } } }() + + runtime := r.config.Runtime + if ropts != nil && ropts.Runtime != "" { + runtime = ropts.Runtime + } sopts := &shim.CreateTaskRequest{ ID: id, Bundle: bundle.path, - Runtime: r.runtime, + Runtime: runtime, Stdin: opts.IO.Stdin, Stdout: opts.IO.Stdout, Stderr: opts.IO.Stderr, @@ -256,11 +279,9 @@ func (r *Runtime) Delete(ctx context.Context, c runtime.Task) (*runtime.Exit, er } bundle := loadBundle( + lc.id, filepath.Join(r.state, namespace, lc.id), filepath.Join(r.root, namespace, lc.id), - namespace, - lc.id, - r.events, ) if err := bundle.Delete(); err != nil { log.G(ctx).WithError(err).Error("failed to delete bundle") @@ -313,10 +334,11 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) { } id := path.Name() bundle := loadBundle( + id, filepath.Join(r.state, ns, id), filepath.Join(r.root, ns, id), - ns, id, r.events) - s, err := bundle.Connect(ctx, r.remote) + ) + s, err := bundle.NewShimClient(ctx, ns, ShimConnect(), nil) if err != nil { log.G(ctx).WithError(err).WithFields(logrus.Fields{ "id": id, @@ -386,6 +408,7 @@ func (r *Runtime) terminate(ctx context.Context, bundle *bundle, ns, id string) if err != nil { return err } + if err := rt.Delete(ctx, id, &runc.DeleteOpts{ Force: true, }); err != nil { @@ -401,18 +424,56 @@ func (r *Runtime) terminate(ctx context.Context, bundle *bundle, ns, id string) } func (r *Runtime) getRuntime(ctx context.Context, ns, id string) (*runc.Runc, error) { + ropts, err := r.getRuncOptions(ctx, id) + if err != nil { + return nil, err + } + + var ( + cmd = r.config.Runtime + root = client.RuncRoot + ) + if ropts != nil { + if ropts.Runtime != "" { + cmd = ropts.Runtime + } + if ropts.RuntimeRoot != "" { + root = ropts.RuntimeRoot + } + } + + return &runc.Runc{ + Command: cmd, + LogFormat: runc.JSON, + PdeathSignal: unix.SIGKILL, + Root: filepath.Join(root, ns), + }, nil +} + +func (r *Runtime) getRuncOptions(ctx context.Context, id string) (*runcopts.RuncOptions, error) { + var container containers.Container + if err := r.db.View(func(tx *bolt.Tx) error { store := metadata.NewContainerStore(tx) var err error - _, err = store.Get(ctx, id) + container, err = store.Get(ctx, id) return err }); err != nil { return nil, err } - return &runc.Runc{ - Command: r.runtime, - LogFormat: runc.JSON, - PdeathSignal: unix.SIGKILL, - Root: filepath.Join(client.RuncRoot, ns), - }, nil + + if container.Runtime.Options != nil { + v, err := typeurl.UnmarshalAny(container.Runtime.Options) + if err != nil { + return nil, err + } + ropts, ok := v.(*runcopts.RuncOptions) + if !ok { + return nil, errors.New("invalid runtime options format") + } + + return ropts, nil + } + + return nil, nil } diff --git a/linux/shim/client.go b/linux/shim/client.go index 5ff0461b5..42231b2ea 100644 --- a/linux/shim/client.go +++ b/linux/shim/client.go @@ -30,20 +30,20 @@ import ( type ClientOpt func(context.Context, Config) (shim.ShimClient, io.Closer, error) // WithStart executes a new shim process -func WithStart(binary, address string, debug bool, exitHandler func()) ClientOpt { +func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHandler func()) ClientOpt { return func(ctx context.Context, config Config) (_ shim.ShimClient, _ io.Closer, err error) { - socket, err := newSocket(config) + socket, err := newSocket(address) if err != nil { return nil, nil, err } defer socket.Close() f, err := socket.File() if err != nil { - return nil, nil, errors.Wrapf(err, "failed to get fd for socket %s", config.Address) + return nil, nil, errors.Wrapf(err, "failed to get fd for socket %s", address) } defer f.Close() - cmd := newCommand(binary, address, debug, config, f) + cmd := newCommand(binary, daemonAddress, debug, config, f) ec, err := reaper.Default.Start(cmd) if err != nil { return nil, nil, errors.Wrapf(err, "failed to start shim") @@ -59,19 +59,23 @@ func WithStart(binary, address string, debug bool, exitHandler func()) ClientOpt }() log.G(ctx).WithFields(logrus.Fields{ "pid": cmd.Process.Pid, - "address": config.Address, + "address": address, "debug": debug, }).Infof("shim %s started", binary) // set shim in cgroup if it is provided - if config.CgroupPath != "" { - if err := setCgroup(ctx, config, cmd); err != nil { + if cgroup != "" { + if err := setCgroup(cgroup, cmd); err != nil { return nil, nil, err } + log.G(ctx).WithFields(logrus.Fields{ + "pid": cmd.Process.Pid, + "address": address, + }).Infof("shim placed in cgroup %s", cgroup) } if err = sys.SetOOMScore(cmd.Process.Pid, sys.OOMScoreMaxKillable); err != nil { return nil, nil, errors.Wrap(err, "failed to set OOM Score on shim") } - c, clo, err := WithConnect(ctx, config) + c, clo, err := WithConnect(address)(ctx, config) if err != nil { return nil, nil, errors.Wrap(err, "failed to connect") } @@ -79,15 +83,26 @@ func WithStart(binary, address string, debug bool, exitHandler func()) ClientOpt } } -func newCommand(binary, address string, debug bool, config Config, socket *os.File) *exec.Cmd { +func newCommand(binary, daemonAddress string, debug bool, config Config, socket *os.File) *exec.Cmd { args := []string{ "--namespace", config.Namespace, - "--address", address, "--workdir", config.WorkDir, + "--address", daemonAddress, + } + + if config.Criu != "" { + args = append(args, "--criu-path", config.Criu) + } + if config.RuntimeRoot != "" { + args = append(args, "--runtime-root", config.RuntimeRoot) + } + if config.SystemdCgroup { + args = append(args, "--systemd-cgroup") } if debug { args = append(args, "--debug") } + cmd := exec.Command(binary, args...) cmd.Dir = config.Path // make sure the shim can be re-parented to system init @@ -102,13 +117,13 @@ func newCommand(binary, address string, debug bool, config Config, socket *os.Fi return cmd } -func newSocket(config Config) (*net.UnixListener, error) { - if len(config.Address) > 106 { - return nil, errors.Errorf("%q: unix socket path too long (limit 106)", config.Address) +func newSocket(address string) (*net.UnixListener, error) { + if len(address) > 106 { + return nil, errors.Errorf("%q: unix socket path too long (limit 106)", address) } - l, err := net.Listen("unix", "\x00"+config.Address) + l, err := net.Listen("unix", "\x00"+address) if err != nil { - return nil, errors.Wrapf(err, "failed to listen to abstract unix socket %q", config.Address) + return nil, errors.Wrapf(err, "failed to listen to abstract unix socket %q", address) } return l.(*net.UnixListener), nil @@ -144,18 +159,20 @@ func dialAddress(address string) string { } // WithConnect connects to an existing shim -func WithConnect(ctx context.Context, config Config) (shim.ShimClient, io.Closer, error) { - conn, err := connect(config.Address, annonDialer) - if err != nil { - return nil, nil, err +func WithConnect(address string) ClientOpt { + return func(ctx context.Context, config Config) (shim.ShimClient, io.Closer, error) { + conn, err := connect(address, annonDialer) + if err != nil { + return nil, nil, err + } + return shim.NewShimClient(conn), conn, nil } - return shim.NewShimClient(conn), conn, nil } // WithLocal uses an in process shim func WithLocal(publisher events.Publisher) func(context.Context, Config) (shim.ShimClient, io.Closer, error) { return func(ctx context.Context, config Config) (shim.ShimClient, io.Closer, error) { - service, err := NewService(config.Path, config.Namespace, config.WorkDir, publisher) + service, err := NewService(config, publisher) if err != nil { return nil, nil, err } @@ -164,11 +181,12 @@ func WithLocal(publisher events.Publisher) func(context.Context, Config) (shim.S } type Config struct { - Address string - Path string - Namespace string - CgroupPath string - WorkDir string + Path string + Namespace string + WorkDir string + Criu string + RuntimeRoot string + SystemdCgroup bool } // New returns a new shim client diff --git a/linux/shim/client_linux.go b/linux/shim/client_linux.go index 4442a3125..de1dba0c2 100644 --- a/linux/shim/client_linux.go +++ b/linux/shim/client_linux.go @@ -3,14 +3,11 @@ package shim import ( - "context" "os/exec" "syscall" "github.com/containerd/cgroups" - "github.com/containerd/containerd/log" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) var atter = syscall.SysProcAttr{ @@ -18,19 +15,15 @@ var atter = syscall.SysProcAttr{ Setpgid: true, } -func setCgroup(ctx context.Context, config Config, cmd *exec.Cmd) error { - cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(config.CgroupPath)) +func setCgroup(cgroupPath string, cmd *exec.Cmd) error { + cg, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroupPath)) if err != nil { - return errors.Wrapf(err, "failed to load cgroup %s", config.CgroupPath) + return errors.Wrapf(err, "failed to load cgroup %s", cgroupPath) } if err := cg.Add(cgroups.Process{ Pid: cmd.Process.Pid, }); err != nil { - return errors.Wrapf(err, "failed to join cgroup %s", config.CgroupPath) + return errors.Wrapf(err, "failed to join cgroup %s", cgroupPath) } - log.G(ctx).WithFields(logrus.Fields{ - "pid": cmd.Process.Pid, - "address": config.Address, - }).Infof("shim placed in cgroup %s", config.CgroupPath) return nil } diff --git a/linux/shim/client_unix.go b/linux/shim/client_unix.go index 17f65d60a..719b3e6be 100644 --- a/linux/shim/client_unix.go +++ b/linux/shim/client_unix.go @@ -3,7 +3,6 @@ package shim import ( - "context" "os/exec" "syscall" ) @@ -12,6 +11,6 @@ var atter = syscall.SysProcAttr{ Setpgid: true, } -func setCgroup(ctx context.Context, config Config, cmd *exec.Cmd) error { +func setCgroup(cgroupPath string, cmd *exec.Cmd) error { return nil } diff --git a/linux/shim/init.go b/linux/shim/init.go index 314375cd4..34aee992b 100644 --- a/linux/shim/init.go +++ b/linux/shim/init.go @@ -56,7 +56,7 @@ type initProcess struct { rootfs string } -func newInitProcess(context context.Context, plat platform, path, namespace, workDir string, r *shimapi.CreateTaskRequest) (*initProcess, error) { +func (s *Service) newInitProcess(context context.Context, r *shimapi.CreateTaskRequest) (*initProcess, error) { var success bool if err := identifiers.Validate(r.ID); err != nil { @@ -71,7 +71,7 @@ func newInitProcess(context context.Context, plat platform, path, namespace, wor options = *v.(*runcopts.CreateOptions) } - rootfs := filepath.Join(path, "rootfs") + rootfs := filepath.Join(s.config.Path, "rootfs") // count the number of successful mounts so we can undo // what was actually done rather than what should have been // done. @@ -94,17 +94,19 @@ func newInitProcess(context context.Context, plat platform, path, namespace, wor } } runtime := &runc.Runc{ - Command: r.Runtime, - Log: filepath.Join(path, "log.json"), - LogFormat: runc.JSON, - PdeathSignal: syscall.SIGKILL, - Root: filepath.Join(RuncRoot, namespace), + Command: r.Runtime, + Log: filepath.Join(s.config.Path, "log.json"), + LogFormat: runc.JSON, + PdeathSignal: syscall.SIGKILL, + Root: filepath.Join(s.config.RuntimeRoot, s.config.Namespace), + Criu: s.config.Criu, + SystemdCgroup: s.config.SystemdCgroup, } p := &initProcess{ id: r.ID, bundle: r.Bundle, runtime: runtime, - platform: plat, + platform: s.platform, stdio: stdio{ stdin: r.Stdin, stdout: r.Stdout, @@ -112,7 +114,7 @@ func newInitProcess(context context.Context, plat platform, path, namespace, wor terminal: r.Terminal, }, rootfs: rootfs, - workDir: workDir, + workDir: s.config.WorkDir, } p.initState = &createdState{p: p} var ( @@ -133,7 +135,7 @@ func newInitProcess(context context.Context, plat platform, path, namespace, wor return nil, errors.Wrap(err, "failed to create OCI runtime io pipes") } } - pidFile := filepath.Join(path, InitPidFile) + pidFile := filepath.Join(s.config.Path, InitPidFile) if r.Checkpoint != "" { opts := &runc.RestoreOpts{ CheckpointOpts: runc.CheckpointOpts{ @@ -178,7 +180,7 @@ func newInitProcess(context context.Context, plat platform, path, namespace, wor if err != nil { return nil, errors.Wrap(err, "failed to retrieve console master") } - console, err = plat.copyConsole(context, console, r.Stdin, r.Stdout, r.Stderr, &p.WaitGroup, ©WaitGroup) + console, err = s.platform.copyConsole(context, console, r.Stdin, r.Stdout, r.Stderr, &p.WaitGroup, ©WaitGroup) if err != nil { return nil, errors.Wrap(err, "failed to start console copy") } diff --git a/linux/shim/local.go b/linux/shim/local.go index 7e993a3d2..09759969d 100644 --- a/linux/shim/local.go +++ b/linux/shim/local.go @@ -33,7 +33,7 @@ func (c *local) Start(ctx context.Context, in *shimapi.StartRequest, opts ...grp func (c *local) Delete(ctx context.Context, in *google_protobuf.Empty, opts ...grpc.CallOption) (*shimapi.DeleteResponse, error) { // make sure we unmount the containers rootfs for this local - if err := unix.Unmount(filepath.Join(c.s.path, "rootfs"), 0); err != nil { + if err := unix.Unmount(filepath.Join(c.s.config.Path, "rootfs"), 0); err != nil { return nil, err } return c.s.Delete(ctx, in) diff --git a/linux/shim/service.go b/linux/shim/service.go index 0168c8fc6..874babb9e 100644 --- a/linux/shim/service.go +++ b/linux/shim/service.go @@ -32,23 +32,21 @@ var empty = &google_protobuf.Empty{} const RuncRoot = "/run/containerd/runc" // NewService returns a new shim service that can be used via GRPC -func NewService(path, namespace, workDir string, publisher events.Publisher) (*Service, error) { - if namespace == "" { +func NewService(config Config, publisher events.Publisher) (*Service, error) { + if config.Namespace == "" { return nil, fmt.Errorf("shim namespace cannot be empty") } - context := namespaces.WithNamespace(context.Background(), namespace) + context := namespaces.WithNamespace(context.Background(), config.Namespace) context = log.WithLogger(context, logrus.WithFields(logrus.Fields{ - "namespace": namespace, + "namespace": config.Namespace, + "path": config.Path, "pid": os.Getpid(), - "path": path, })) s := &Service{ - path: path, + config: config, + context: context, processes: make(map[string]process), events: make(chan interface{}, 4096), - namespace: namespace, - context: context, - workDir: workDir, ec: reaper.Default.Subscribe(), } go s.processExits() @@ -67,25 +65,24 @@ type platform interface { } type Service struct { - path string - id string - bundle string - mu sync.Mutex - processes map[string]process - events chan interface{} - deferredEvent interface{} - namespace string - context context.Context - ec chan runc.Exit + mu sync.Mutex - workDir string - platform platform + config Config + context context.Context + processes map[string]process + events chan interface{} + platform platform + ec chan runc.Exit + + // Filled by Create() + id string + bundle string } func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (*shimapi.CreateTaskResponse, error) { s.mu.Lock() defer s.mu.Unlock() - process, err := newInitProcess(ctx, s.platform, s.path, s.namespace, s.workDir, r) + process, err := s.newInitProcess(ctx, r) if err != nil { return nil, errdefs.ToGRPC(err) } @@ -194,7 +191,7 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*goo return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created") } - process, err := newExecProcess(ctx, s.path, r, p.(*initProcess), r.ID) + process, err := newExecProcess(ctx, s.config.Path, r, p.(*initProcess), r.ID) if err != nil { return nil, errdefs.ToGRPC(err) } diff --git a/metadata/containers.go b/metadata/containers.go index 7e0e7a68a..f525ebab4 100644 --- a/metadata/containers.go +++ b/metadata/containers.go @@ -335,18 +335,13 @@ func writeContainer(bkt *bolt.Bucket, container *containers.Container) error { return err } - obkt, err := rbkt.CreateBucket(bucketKeyOptions) - if err != nil { - return err - } - if container.Runtime.Options != nil { data, err := proto.Marshal(container.Runtime.Options) if err != nil { return err } - if err := obkt.Put(bucketKeyOptions, data); err != nil { + if err := rbkt.Put(bucketKeyOptions, data); err != nil { return err } }