diff --git a/Protobuild.toml b/Protobuild.toml index 3bb2e6287..26691afe0 100644 --- a/Protobuild.toml +++ b/Protobuild.toml @@ -77,11 +77,3 @@ ignore_files = [ "google/protobuf/descriptor.proto", "gogoproto/gogo.proto" ] - -[[descriptors]] -prefix = "github.com/containerd/containerd/windows/hcsshimtypes" -target = "windows/hcsshimtypes/next.pb.txt" -ignore_files = [ - "google/protobuf/descriptor.proto", - "gogoproto/gogo.proto" -] diff --git a/client.go b/client.go index 482ac51bf..4bd66578d 100644 --- a/client.go +++ b/client.go @@ -93,7 +93,7 @@ func New(address string, opts ...ClientOpt) (*Client, error) { if copts.defaultRuntime != "" { c.runtime = copts.defaultRuntime } else { - c.runtime = fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS) + c.runtime = defaults.DefaultRuntime } if copts.services != nil { diff --git a/cmd/containerd/builtins_windows.go b/cmd/containerd/builtins_windows.go index 3bbb06fcc..3fdea109d 100644 --- a/cmd/containerd/builtins_windows.go +++ b/cmd/containerd/builtins_windows.go @@ -24,5 +24,4 @@ import ( _ "github.com/containerd/containerd/runtime/v2" _ "github.com/containerd/containerd/snapshots/lcow" _ "github.com/containerd/containerd/snapshots/windows" - _ "github.com/containerd/containerd/windows" ) diff --git a/cmd/ctr/commands/commands.go b/cmd/ctr/commands/commands.go index f748936e0..b9222f872 100644 --- a/cmd/ctr/commands/commands.go +++ b/cmd/ctr/commands/commands.go @@ -21,9 +21,9 @@ import ( "fmt" "os" "path/filepath" - "runtime" "strings" + "github.com/containerd/containerd/defaults" "github.com/urfave/cli" ) @@ -100,7 +100,7 @@ var ( cli.StringFlag{ Name: "runtime", Usage: "runtime name", - Value: fmt.Sprintf("io.containerd.runtime.v1.%s", runtime.GOOS), + Value: defaults.DefaultRuntime, }, cli.BoolFlag{ Name: "tty,t", diff --git a/container_test.go b/container_test.go index c905a389f..773f01cf2 100644 --- a/container_test.go +++ b/container_test.go @@ -40,7 +40,6 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/windows/hcsshimtypes" gogotypes "github.com/gogo/protobuf/types" ) @@ -441,20 +440,13 @@ func TestContainerPids(t *testing.T) { t.Errorf("invalid task pid %d", pid) } processes, err := task.Pids(ctx) - if err != nil { - t.Fatal(err) - } switch runtime.GOOS { case "windows": - if processes[0].Info == nil { - t.Error("expected additional process information but received nil") - } else { - var details hcsshimtypes.ProcessDetails - if err := details.Unmarshal(processes[0].Info.Value); err != nil { - t.Errorf("expected Windows info type hcsshimtypes.ProcessDetails %v", err) - } - } + // TODO: This is currently not implemented on windows default: + if err != nil { + t.Fatal(err) + } if l := len(processes); l != 1 { t.Errorf("expected 1 process but received %d", l) } diff --git a/defaults/defaults_unix.go b/defaults/defaults_unix.go index 30ed42235..319e8777b 100644 --- a/defaults/defaults_unix.go +++ b/defaults/defaults_unix.go @@ -32,4 +32,6 @@ const ( // DefaultFIFODir is the default location used by client-side cio library // to store FIFOs. DefaultFIFODir = "/run/containerd/fifo" + // DefaultRuntime is the default linux runtime + DefaultRuntime = "io.containerd.runc.v2" ) diff --git a/defaults/defaults_windows.go b/defaults/defaults_windows.go index 16f1048ca..5eede8de8 100644 --- a/defaults/defaults_windows.go +++ b/defaults/defaults_windows.go @@ -40,4 +40,6 @@ const ( // DefaultFIFODir is the default location used by client-side cio library // to store FIFOs. Unused on Windows. DefaultFIFODir = "" + // DefaultRuntime is the default windows runtime + DefaultRuntime = "io.containerd.runhcs.v1" ) diff --git a/windows/hcsshim.go b/windows/hcsshim.go deleted file mode 100644 index 3b0167b6a..000000000 --- a/windows/hcsshim.go +++ /dev/null @@ -1,166 +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 windows - -import ( - "context" - "os" - "path/filepath" - "strings" - - "github.com/Microsoft/hcsshim" - "github.com/containerd/containerd/errdefs" - specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" -) - -// newContainerConfig generates a hcsshim container configuration from the -// provided OCI Spec -func newContainerConfig(ctx context.Context, owner, id string, spec *specs.Spec) (*hcsshim.ContainerConfig, error) { - var ( - conf = &hcsshim.ContainerConfig{ - SystemType: "Container", - Name: id, - Owner: owner, - HostName: spec.Hostname, - } - ) - - if spec.Windows.Network != nil { - conf.AllowUnqualifiedDNSQuery = spec.Windows.Network.AllowUnqualifiedDNSQuery - conf.EndpointList = spec.Windows.Network.EndpointList - conf.NetworkSharedContainerName = spec.Windows.Network.NetworkSharedContainerName - if spec.Windows.Network.DNSSearchList != nil { - conf.DNSSearchList = strings.Join(spec.Windows.Network.DNSSearchList, ",") - } - } - - return conf, nil -} - -// newWindowsContainerConfig generates a hcsshim Windows container -// configuration from the provided OCI Spec -func newWindowsContainerConfig(ctx context.Context, owner, id string, spec *specs.Spec) (*hcsshim.ContainerConfig, error) { - conf, err := newContainerConfig(ctx, owner, id, spec) - if err != nil { - return nil, err - } - conf.IgnoreFlushesDuringBoot = spec.Windows.IgnoreFlushesDuringBoot - - if len(spec.Windows.LayerFolders) < 2 { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, - "spec.Windows.LayerFolders must have at least 2 layers") - } - var ( - layerFolderPath = spec.Windows.LayerFolders[0] - layerFolders = spec.Windows.LayerFolders[1:] - layerID = filepath.Base(layerFolderPath) - ) - - // TODO: use the create request Mount for those - for _, layerPath := range layerFolders { - _, filename := filepath.Split(layerPath) - guid, err := hcsshim.NameToGuid(filename) - if err != nil { - return nil, errors.Wrapf(err, "unable to get GUID for %s", filename) - } - conf.Layers = append(conf.Layers, hcsshim.Layer{ - ID: guid.ToString(), - Path: layerPath, - }) - } - conf.LayerFolderPath = layerFolderPath - - var di = hcsshim.DriverInfo{ - HomeDir: filepath.Dir(layerFolderPath), - } - conf.VolumePath, err = hcsshim.GetLayerMountPath(di, layerID) - if err != nil { - return nil, errors.Wrapf(err, "failed to getmount path for layer %s: driverInfo: %#v", id, di) - } - - if spec.Windows.HyperV != nil { - conf.HvPartition = true - for _, layerPath := range layerFolders { - utilityVMPath := spec.Windows.HyperV.UtilityVMPath - _, err := os.Stat(utilityVMPath) - if err == nil { - conf.HvRuntime = &hcsshim.HvRuntime{ImagePath: utilityVMPath} - break - } else if !os.IsNotExist(err) { - return nil, errors.Wrapf(err, "failed to access layer %s", layerPath) - } - } - } - - if spec.Windows.CredentialSpec != nil { - conf.Credentials = spec.Windows.CredentialSpec.(string) - } - - if len(spec.Mounts) > 0 { - mds := make([]hcsshim.MappedDir, len(spec.Mounts)) - for i, mount := range spec.Mounts { - mds[i] = hcsshim.MappedDir{ - HostPath: mount.Source, - ContainerPath: mount.Destination, - ReadOnly: false, - } - for _, o := range mount.Options { - if strings.ToLower(o) == "ro" { - mds[i].ReadOnly = true - } - } - } - conf.MappedDirectories = mds - } - - return conf, nil -} - -func newProcessConfig(processSpec *specs.Process, pset *pipeSet) *hcsshim.ProcessConfig { - conf := &hcsshim.ProcessConfig{ - EmulateConsole: pset.src.Terminal, - CreateStdInPipe: pset.stdin != nil, - CreateStdOutPipe: pset.stdout != nil, - CreateStdErrPipe: pset.stderr != nil, - User: processSpec.User.Username, - Environment: make(map[string]string), - WorkingDirectory: processSpec.Cwd, - } - - if processSpec.ConsoleSize != nil { - conf.ConsoleSize = [2]uint{processSpec.ConsoleSize.Height, processSpec.ConsoleSize.Width} - } - - // Convert OCI Env format to HCS's - for _, s := range processSpec.Env { - arr := strings.SplitN(s, "=", 2) - if len(arr) == 2 { - conf.Environment[arr[0]] = arr[1] - } - } - - return conf -} - -func newWindowsProcessConfig(processSpec *specs.Process, pset *pipeSet) *hcsshim.ProcessConfig { - conf := newProcessConfig(processSpec, pset) - conf.CommandLine = strings.Join(processSpec.Args, " ") - return conf -} diff --git a/windows/hcsshimtypes/1.0.pb.txt b/windows/hcsshimtypes/1.0.pb.txt deleted file mode 100755 index 55b73dee4..000000000 --- a/windows/hcsshimtypes/1.0.pb.txt +++ /dev/null @@ -1,160 +0,0 @@ -file { - name: "google/protobuf/duration.proto" - package: "google.protobuf" - message_type { - name: "Duration" - field { - name: "seconds" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_INT64 - json_name: "seconds" - } - field { - name: "nanos" - number: 2 - label: LABEL_OPTIONAL - type: TYPE_INT32 - json_name: "nanos" - } - } - options { - java_package: "com.google.protobuf" - java_outer_classname: "DurationProto" - java_multiple_files: true - go_package: "github.com/golang/protobuf/ptypes/duration" - cc_enable_arenas: true - objc_class_prefix: "GPB" - csharp_namespace: "Google.Protobuf.WellKnownTypes" - } - syntax: "proto3" -} -file { - name: "google/protobuf/timestamp.proto" - package: "google.protobuf" - message_type { - name: "Timestamp" - field { - name: "seconds" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_INT64 - json_name: "seconds" - } - field { - name: "nanos" - number: 2 - label: LABEL_OPTIONAL - type: TYPE_INT32 - json_name: "nanos" - } - } - options { - java_package: "com.google.protobuf" - java_outer_classname: "TimestampProto" - java_multiple_files: true - go_package: "github.com/golang/protobuf/ptypes/timestamp" - cc_enable_arenas: true - objc_class_prefix: "GPB" - csharp_namespace: "Google.Protobuf.WellKnownTypes" - } - syntax: "proto3" -} -file { - name: "github.com/containerd/containerd/windows/hcsshimtypes/hcsshim.proto" - package: "containerd.windows.hcsshim" - dependency: "gogoproto/gogo.proto" - dependency: "google/protobuf/duration.proto" - dependency: "google/protobuf/timestamp.proto" - message_type { - name: "CreateOptions" - field { - name: "terminate_duration" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_MESSAGE - type_name: ".google.protobuf.Duration" - options { - 65011: 1 - 65001: 0 - } - json_name: "terminateDuration" - } - } - message_type { - name: "ProcessDetails" - field { - name: "image_name" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_STRING - json_name: "imageName" - } - field { - name: "created_at" - number: 2 - label: LABEL_OPTIONAL - type: TYPE_MESSAGE - type_name: ".google.protobuf.Timestamp" - options { - 65010: 1 - 65001: 0 - } - json_name: "createdAt" - } - field { - name: "kernel_time_100_ns" - number: 3 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "kernelTime100Ns" - } - field { - name: "memory_commit_bytes" - number: 4 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "memoryCommitBytes" - } - field { - name: "memory_working_set_private_bytes" - number: 5 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "memoryWorkingSetPrivateBytes" - } - field { - name: "memory_working_set_shared_bytes" - number: 6 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "memoryWorkingSetSharedBytes" - } - field { - name: "process_id" - number: 7 - label: LABEL_OPTIONAL - type: TYPE_UINT32 - json_name: "processId" - } - field { - name: "user_time_100_ns" - number: 8 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "userTime100Ns" - } - field { - name: "exec_id" - number: 9 - label: LABEL_OPTIONAL - type: TYPE_STRING - json_name: "execId" - } - } - options { - go_package: "github.com/containerd/containerd/windows/hcsshimtypes;hcsshimtypes" - } - weak_dependency: 0 - syntax: "proto3" -} diff --git a/windows/hcsshimtypes/doc.go b/windows/hcsshimtypes/doc.go deleted file mode 100644 index 9fe5cd0a4..000000000 --- a/windows/hcsshimtypes/doc.go +++ /dev/null @@ -1,18 +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 hcsshimtypes holds the windows runtime specific types -package hcsshimtypes diff --git a/windows/hcsshimtypes/hcsshim.pb.go b/windows/hcsshimtypes/hcsshim.pb.go deleted file mode 100644 index ca9d54060..000000000 --- a/windows/hcsshimtypes/hcsshim.pb.go +++ /dev/null @@ -1,838 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: github.com/containerd/containerd/windows/hcsshimtypes/hcsshim.proto - -package hcsshimtypes - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - _ "github.com/gogo/protobuf/types" - github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - io "io" - math "math" - reflect "reflect" - strings "strings" - time "time" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf -var _ = time.Kitchen - -// 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 CreateOptions struct { - TerminateDuration time.Duration `protobuf:"bytes,1,opt,name=terminate_duration,json=terminateDuration,proto3,stdduration" json:"terminate_duration"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateOptions) Reset() { *m = CreateOptions{} } -func (*CreateOptions) ProtoMessage() {} -func (*CreateOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_7d909fc5b35cb1de, []int{0} -} -func (m *CreateOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *CreateOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_CreateOptions.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *CreateOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateOptions.Merge(m, src) -} -func (m *CreateOptions) XXX_Size() int { - return m.Size() -} -func (m *CreateOptions) XXX_DiscardUnknown() { - xxx_messageInfo_CreateOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateOptions proto.InternalMessageInfo - -// ProcessDetails contains additional information about a process -// ProcessDetails is made of the same fields as found in hcsshim.ProcessListItem -type ProcessDetails struct { - ImageName string `protobuf:"bytes,1,opt,name=image_name,json=imageName,proto3" json:"image_name,omitempty"` - CreatedAt time.Time `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3,stdtime" json:"created_at"` - KernelTime_100Ns uint64 `protobuf:"varint,3,opt,name=kernel_time_100_ns,json=kernelTime100Ns,proto3" json:"kernel_time_100_ns,omitempty"` - MemoryCommitBytes uint64 `protobuf:"varint,4,opt,name=memory_commit_bytes,json=memoryCommitBytes,proto3" json:"memory_commit_bytes,omitempty"` - MemoryWorkingSetPrivateBytes uint64 `protobuf:"varint,5,opt,name=memory_working_set_private_bytes,json=memoryWorkingSetPrivateBytes,proto3" json:"memory_working_set_private_bytes,omitempty"` - MemoryWorkingSetSharedBytes uint64 `protobuf:"varint,6,opt,name=memory_working_set_shared_bytes,json=memoryWorkingSetSharedBytes,proto3" json:"memory_working_set_shared_bytes,omitempty"` - ProcessID uint32 `protobuf:"varint,7,opt,name=process_id,json=processId,proto3" json:"process_id,omitempty"` - UserTime_100Ns uint64 `protobuf:"varint,8,opt,name=user_time_100_ns,json=userTime100Ns,proto3" json:"user_time_100_ns,omitempty"` - ExecID string `protobuf:"bytes,9,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ProcessDetails) Reset() { *m = ProcessDetails{} } -func (*ProcessDetails) ProtoMessage() {} -func (*ProcessDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_7d909fc5b35cb1de, []int{1} -} -func (m *ProcessDetails) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ProcessDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ProcessDetails.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ProcessDetails) XXX_Merge(src proto.Message) { - xxx_messageInfo_ProcessDetails.Merge(m, src) -} -func (m *ProcessDetails) XXX_Size() int { - return m.Size() -} -func (m *ProcessDetails) XXX_DiscardUnknown() { - xxx_messageInfo_ProcessDetails.DiscardUnknown(m) -} - -var xxx_messageInfo_ProcessDetails proto.InternalMessageInfo - -func init() { - proto.RegisterType((*CreateOptions)(nil), "containerd.windows.hcsshim.CreateOptions") - proto.RegisterType((*ProcessDetails)(nil), "containerd.windows.hcsshim.ProcessDetails") -} - -func init() { - proto.RegisterFile("github.com/containerd/containerd/windows/hcsshimtypes/hcsshim.proto", fileDescriptor_7d909fc5b35cb1de) -} - -var fileDescriptor_7d909fc5b35cb1de = []byte{ - // 507 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x41, 0x6f, 0xd3, 0x3c, - 0x18, 0xc7, 0x9b, 0x77, 0x7b, 0xbb, 0xc5, 0xa8, 0xc0, 0x0c, 0x87, 0x52, 0x20, 0xa9, 0xc6, 0x81, - 0x4a, 0xa0, 0xb4, 0x83, 0x23, 0x27, 0xd2, 0x82, 0xd4, 0xcb, 0x98, 0x32, 0x24, 0x10, 0x42, 0xb2, - 0xdc, 0xe4, 0x21, 0xb5, 0x56, 0xc7, 0x91, 0xed, 0xd2, 0xf5, 0xc6, 0x47, 0xe0, 0xc8, 0x47, 0xea, - 0x91, 0x23, 0x12, 0x52, 0x61, 0xf9, 0x24, 0xc8, 0x76, 0xba, 0x8d, 0xc1, 0x89, 0x9b, 0xed, 0xff, - 0xef, 0xf9, 0x3d, 0xf1, 0x63, 0x05, 0x0d, 0x73, 0xa6, 0xa7, 0xf3, 0x49, 0x94, 0x0a, 0xde, 0x4f, - 0x45, 0xa1, 0x29, 0x2b, 0x40, 0x66, 0x97, 0x97, 0x0b, 0x56, 0x64, 0x62, 0xa1, 0xfa, 0xd3, 0x54, - 0xa9, 0x29, 0xe3, 0x7a, 0x59, 0xc2, 0xf9, 0x26, 0x2a, 0xa5, 0xd0, 0x02, 0x77, 0x2e, 0xf0, 0xa8, - 0xc6, 0xa3, 0x9a, 0xe8, 0xdc, 0xce, 0x45, 0x2e, 0x2c, 0xd6, 0x37, 0x2b, 0x57, 0xd1, 0x09, 0x72, - 0x21, 0xf2, 0x19, 0xf4, 0xed, 0x6e, 0x32, 0xff, 0xd0, 0xcf, 0xe6, 0x92, 0x6a, 0x26, 0x8a, 0x3a, - 0x0f, 0xaf, 0xe6, 0x9a, 0x71, 0x50, 0x9a, 0xf2, 0xd2, 0x01, 0xfb, 0x29, 0x6a, 0x0d, 0x25, 0x50, - 0x0d, 0xaf, 0x4a, 0x53, 0xa6, 0x70, 0x82, 0xb0, 0x06, 0xc9, 0x59, 0x41, 0x35, 0x90, 0x8d, 0xad, - 0xed, 0x75, 0xbd, 0xde, 0xb5, 0x27, 0x77, 0x22, 0xa7, 0x8b, 0x36, 0xba, 0x68, 0x54, 0x03, 0xf1, - 0xee, 0x6a, 0x1d, 0x36, 0xbe, 0xfc, 0x08, 0xbd, 0x64, 0xef, 0xbc, 0x7c, 0x13, 0xee, 0x7f, 0xdf, - 0x42, 0xd7, 0x8f, 0xa4, 0x48, 0x41, 0xa9, 0x11, 0x68, 0xca, 0x66, 0x0a, 0xdf, 0x47, 0x88, 0x71, - 0x9a, 0x03, 0x29, 0x28, 0x07, 0xab, 0xf7, 0x13, 0xdf, 0x9e, 0x1c, 0x52, 0x0e, 0x78, 0x88, 0x50, - 0x6a, 0x3f, 0x2b, 0x23, 0x54, 0xb7, 0xff, 0xb3, 0xdd, 0x3b, 0x7f, 0x74, 0x7f, 0xbd, 0xb9, 0x8c, - 0x6b, 0xff, 0xd9, 0xb4, 0xf7, 0xeb, 0xba, 0xe7, 0x1a, 0x3f, 0x42, 0xf8, 0x04, 0x64, 0x01, 0x33, - 0x62, 0x6e, 0x4d, 0x0e, 0x06, 0x03, 0x52, 0xa8, 0xf6, 0x56, 0xd7, 0xeb, 0x6d, 0x27, 0x37, 0x5c, - 0x62, 0x0c, 0x07, 0x83, 0xc1, 0xa1, 0xc2, 0x11, 0xba, 0xc5, 0x81, 0x0b, 0xb9, 0x24, 0xa9, 0xe0, - 0x9c, 0x69, 0x32, 0x59, 0x6a, 0x50, 0xed, 0x6d, 0x4b, 0xef, 0xb9, 0x68, 0x68, 0x93, 0xd8, 0x04, - 0xf8, 0x25, 0xea, 0xd6, 0xfc, 0x42, 0xc8, 0x13, 0x56, 0xe4, 0x44, 0x81, 0x26, 0xa5, 0x64, 0x1f, - 0xcd, 0xe0, 0x5c, 0xf1, 0xff, 0xb6, 0xf8, 0x9e, 0xe3, 0xde, 0x38, 0xec, 0x18, 0xf4, 0x91, 0x83, - 0x9c, 0x67, 0x84, 0xc2, 0xbf, 0x78, 0xd4, 0x94, 0x4a, 0xc8, 0x6a, 0x4d, 0xd3, 0x6a, 0xee, 0x5e, - 0xd5, 0x1c, 0x5b, 0xc6, 0x59, 0x1e, 0x23, 0x54, 0xba, 0x01, 0x13, 0x96, 0xb5, 0x77, 0xba, 0x5e, - 0xaf, 0x15, 0xb7, 0xaa, 0x75, 0xe8, 0xd7, 0x63, 0x1f, 0x8f, 0x12, 0xbf, 0x06, 0xc6, 0x19, 0x7e, - 0x88, 0x6e, 0xce, 0x15, 0xc8, 0xdf, 0xc6, 0xb2, 0x6b, 0x9b, 0xb4, 0xcc, 0xf9, 0xc5, 0x50, 0x1e, - 0xa0, 0x1d, 0x38, 0x85, 0xd4, 0x38, 0x7d, 0xf3, 0x44, 0x31, 0xaa, 0xd6, 0x61, 0xf3, 0xc5, 0x29, - 0xa4, 0xe3, 0x51, 0xd2, 0x34, 0xd1, 0x38, 0x8b, 0xdf, 0xaf, 0xce, 0x82, 0xc6, 0xb7, 0xb3, 0xa0, - 0xf1, 0xa9, 0x0a, 0xbc, 0x55, 0x15, 0x78, 0x5f, 0xab, 0xc0, 0xfb, 0x59, 0x05, 0xde, 0xbb, 0xf8, - 0x9f, 0x7e, 0x8a, 0x67, 0x97, 0x37, 0x6f, 0x1b, 0x93, 0xa6, 0x7d, 0xef, 0xa7, 0xbf, 0x02, 0x00, - 0x00, 0xff, 0xff, 0x1e, 0xd7, 0x2f, 0xa8, 0x63, 0x03, 0x00, 0x00, -} - -func (m *CreateOptions) 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 *CreateOptions) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.TerminateDuration))) - n1, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TerminateDuration, dAtA[i:]) - if err != nil { - return 0, err - } - i += n1 - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *ProcessDetails) 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 *ProcessDetails) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if len(m.ImageName) > 0 { - dAtA[i] = 0xa - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(len(m.ImageName))) - i += copy(dAtA[i:], m.ImageName) - } - dAtA[i] = 0x12 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt))) - n2, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) - if err != nil { - return 0, err - } - i += n2 - if m.KernelTime_100Ns != 0 { - dAtA[i] = 0x18 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(m.KernelTime_100Ns)) - } - if m.MemoryCommitBytes != 0 { - dAtA[i] = 0x20 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(m.MemoryCommitBytes)) - } - if m.MemoryWorkingSetPrivateBytes != 0 { - dAtA[i] = 0x28 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(m.MemoryWorkingSetPrivateBytes)) - } - if m.MemoryWorkingSetSharedBytes != 0 { - dAtA[i] = 0x30 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(m.MemoryWorkingSetSharedBytes)) - } - if m.ProcessID != 0 { - dAtA[i] = 0x38 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(m.ProcessID)) - } - if m.UserTime_100Ns != 0 { - dAtA[i] = 0x40 - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(m.UserTime_100Ns)) - } - if len(m.ExecID) > 0 { - dAtA[i] = 0x4a - i++ - i = encodeVarintHcsshim(dAtA, i, uint64(len(m.ExecID))) - i += copy(dAtA[i:], m.ExecID) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func encodeVarintHcsshim(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 *CreateOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.TerminateDuration) - n += 1 + l + sovHcsshim(uint64(l)) - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *ProcessDetails) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ImageName) - if l > 0 { - n += 1 + l + sovHcsshim(uint64(l)) - } - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt) - n += 1 + l + sovHcsshim(uint64(l)) - if m.KernelTime_100Ns != 0 { - n += 1 + sovHcsshim(uint64(m.KernelTime_100Ns)) - } - if m.MemoryCommitBytes != 0 { - n += 1 + sovHcsshim(uint64(m.MemoryCommitBytes)) - } - if m.MemoryWorkingSetPrivateBytes != 0 { - n += 1 + sovHcsshim(uint64(m.MemoryWorkingSetPrivateBytes)) - } - if m.MemoryWorkingSetSharedBytes != 0 { - n += 1 + sovHcsshim(uint64(m.MemoryWorkingSetSharedBytes)) - } - if m.ProcessID != 0 { - n += 1 + sovHcsshim(uint64(m.ProcessID)) - } - if m.UserTime_100Ns != 0 { - n += 1 + sovHcsshim(uint64(m.UserTime_100Ns)) - } - l = len(m.ExecID) - if l > 0 { - n += 1 + l + sovHcsshim(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func sovHcsshim(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} -func sozHcsshim(x uint64) (n int) { - return sovHcsshim(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *CreateOptions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&CreateOptions{`, - `TerminateDuration:` + strings.Replace(strings.Replace(this.TerminateDuration.String(), "Duration", "types.Duration", 1), `&`, ``, 1) + `,`, - `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func (this *ProcessDetails) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&ProcessDetails{`, - `ImageName:` + fmt.Sprintf("%v", this.ImageName) + `,`, - `CreatedAt:` + strings.Replace(strings.Replace(this.CreatedAt.String(), "Timestamp", "types.Timestamp", 1), `&`, ``, 1) + `,`, - `KernelTime_100Ns:` + fmt.Sprintf("%v", this.KernelTime_100Ns) + `,`, - `MemoryCommitBytes:` + fmt.Sprintf("%v", this.MemoryCommitBytes) + `,`, - `MemoryWorkingSetPrivateBytes:` + fmt.Sprintf("%v", this.MemoryWorkingSetPrivateBytes) + `,`, - `MemoryWorkingSetSharedBytes:` + fmt.Sprintf("%v", this.MemoryWorkingSetSharedBytes) + `,`, - `ProcessID:` + fmt.Sprintf("%v", this.ProcessID) + `,`, - `UserTime_100Ns:` + fmt.Sprintf("%v", this.UserTime_100Ns) + `,`, - `ExecID:` + fmt.Sprintf("%v", this.ExecID) + `,`, - `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, - `}`, - }, "") - return s -} -func valueToStringHcsshim(v interface{}) string { - rv := reflect.ValueOf(v) - if rv.IsNil() { - return "nil" - } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) -} -func (m *CreateOptions) 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 ErrIntOverflowHcsshim - } - 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: CreateOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CreateOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TerminateDuration", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthHcsshim - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthHcsshim - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.TerminateDuration, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipHcsshim(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthHcsshim - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthHcsshim - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ProcessDetails) 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 ErrIntOverflowHcsshim - } - 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: ProcessDetails: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ProcessDetails: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ImageName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - 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 ErrInvalidLengthHcsshim - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthHcsshim - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ImageName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CreatedAt", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthHcsshim - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthHcsshim - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreatedAt, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field KernelTime_100Ns", wireType) - } - m.KernelTime_100Ns = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.KernelTime_100Ns |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemoryCommitBytes", wireType) - } - m.MemoryCommitBytes = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MemoryCommitBytes |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemoryWorkingSetPrivateBytes", wireType) - } - m.MemoryWorkingSetPrivateBytes = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MemoryWorkingSetPrivateBytes |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MemoryWorkingSetSharedBytes", wireType) - } - m.MemoryWorkingSetSharedBytes = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MemoryWorkingSetSharedBytes |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ProcessID", wireType) - } - m.ProcessID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ProcessID |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field UserTime_100Ns", wireType) - } - m.UserTime_100Ns = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.UserTime_100Ns |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExecID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowHcsshim - } - 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 ErrInvalidLengthHcsshim - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthHcsshim - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ExecID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipHcsshim(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthHcsshim - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthHcsshim - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipHcsshim(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, ErrIntOverflowHcsshim - } - 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, ErrIntOverflowHcsshim - } - 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, ErrIntOverflowHcsshim - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthHcsshim - } - iNdEx += length - if iNdEx < 0 { - return 0, ErrInvalidLengthHcsshim - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowHcsshim - } - 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 := skipHcsshim(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - if iNdEx < 0 { - return 0, ErrInvalidLengthHcsshim - } - } - 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 ( - ErrInvalidLengthHcsshim = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowHcsshim = fmt.Errorf("proto: integer overflow") -) diff --git a/windows/hcsshimtypes/hcsshim.proto b/windows/hcsshimtypes/hcsshim.proto deleted file mode 100644 index 5934fca7c..000000000 --- a/windows/hcsshimtypes/hcsshim.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; - -package containerd.windows.hcsshim; - -import weak "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/containerd/containerd/windows/hcsshimtypes;hcsshimtypes"; - -message CreateOptions { - google.protobuf.Duration terminate_duration = 1 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; -} - -// ProcessDetails contains additional information about a process -// ProcessDetails is made of the same fields as found in hcsshim.ProcessListItem -message ProcessDetails { - string image_name = 1; - google.protobuf.Timestamp created_at = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - uint64 kernel_time_100_ns = 3; - uint64 memory_commit_bytes = 4; - uint64 memory_working_set_private_bytes = 5; - uint64 memory_working_set_shared_bytes = 6; - uint32 process_id = 7; - uint64 user_time_100_ns = 8; - string exec_id = 9; -} diff --git a/windows/hcsshimtypes/next.pb.txt b/windows/hcsshimtypes/next.pb.txt deleted file mode 100755 index 5f7ba451d..000000000 --- a/windows/hcsshimtypes/next.pb.txt +++ /dev/null @@ -1,160 +0,0 @@ -file { - name: "google/protobuf/duration.proto" - package: "google.protobuf" - message_type { - name: "Duration" - field { - name: "seconds" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_INT64 - json_name: "seconds" - } - field { - name: "nanos" - number: 2 - label: LABEL_OPTIONAL - type: TYPE_INT32 - json_name: "nanos" - } - } - options { - java_package: "com.google.protobuf" - java_outer_classname: "DurationProto" - java_multiple_files: true - go_package: "github.com/golang/protobuf/ptypes/duration" - cc_enable_arenas: true - objc_class_prefix: "GPB" - csharp_namespace: "Google.Protobuf.WellKnownTypes" - } - syntax: "proto3" -} -file { - name: "google/protobuf/timestamp.proto" - package: "google.protobuf" - message_type { - name: "Timestamp" - field { - name: "seconds" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_INT64 - json_name: "seconds" - } - field { - name: "nanos" - number: 2 - label: LABEL_OPTIONAL - type: TYPE_INT32 - json_name: "nanos" - } - } - options { - java_package: "com.google.protobuf" - java_outer_classname: "TimestampProto" - java_multiple_files: true - go_package: "github.com/golang/protobuf/ptypes/timestamp" - cc_enable_arenas: true - objc_class_prefix: "GPB" - csharp_namespace: "Google.Protobuf.WellKnownTypes" - } - syntax: "proto3" -} -file { - name: "github.com/containerd/containerd/windows/hcsshimtypes/hcsshim.proto" - package: "containerd.windows.hcsshim" - dependency: "gogoproto/gogo.proto" - dependency: "google/protobuf/duration.proto" - dependency: "google/protobuf/timestamp.proto" - message_type { - name: "CreateOptions" - field { - name: "terminate_duration" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_MESSAGE - type_name: ".google.protobuf.Duration" - options { - 65001: 0 - 65011: 1 - } - json_name: "terminateDuration" - } - } - message_type { - name: "ProcessDetails" - field { - name: "image_name" - number: 1 - label: LABEL_OPTIONAL - type: TYPE_STRING - json_name: "imageName" - } - field { - name: "created_at" - number: 2 - label: LABEL_OPTIONAL - type: TYPE_MESSAGE - type_name: ".google.protobuf.Timestamp" - options { - 65001: 0 - 65010: 1 - } - json_name: "createdAt" - } - field { - name: "kernel_time_100_ns" - number: 3 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "kernelTime100Ns" - } - field { - name: "memory_commit_bytes" - number: 4 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "memoryCommitBytes" - } - field { - name: "memory_working_set_private_bytes" - number: 5 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "memoryWorkingSetPrivateBytes" - } - field { - name: "memory_working_set_shared_bytes" - number: 6 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "memoryWorkingSetSharedBytes" - } - field { - name: "process_id" - number: 7 - label: LABEL_OPTIONAL - type: TYPE_UINT32 - json_name: "processId" - } - field { - name: "user_time_100_ns" - number: 8 - label: LABEL_OPTIONAL - type: TYPE_UINT64 - json_name: "userTime100Ns" - } - field { - name: "exec_id" - number: 9 - label: LABEL_OPTIONAL - type: TYPE_STRING - json_name: "execId" - } - } - options { - go_package: "github.com/containerd/containerd/windows/hcsshimtypes;hcsshimtypes" - } - weak_dependency: 0 - syntax: "proto3" -} diff --git a/windows/io.go b/windows/io.go deleted file mode 100644 index ab0b1ea16..000000000 --- a/windows/io.go +++ /dev/null @@ -1,126 +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 windows - -import ( - "context" - "net" - "sync" - "time" - - "github.com/Microsoft/go-winio" - "github.com/containerd/containerd/runtime" - "github.com/pkg/errors" -) - -type pipeSet struct { - src runtime.IO - stdin net.Conn - stdout net.Conn - stderr net.Conn -} - -// NewIO connects to the provided pipe addresses -func newPipeSet(ctx context.Context, io runtime.IO) (*pipeSet, error) { - var ( - err error - c net.Conn - wg sync.WaitGroup - set = &pipeSet{src: io} - ch = make(chan error) - opened = 0 - ) - - defer func() { - if err != nil { - go func() { - for i := 0; i < opened; i++ { - // Drain the channel to avoid leaking the goroutines - <-ch - } - close(ch) - wg.Wait() - set.Close() - }() - } - }() - - for _, p := range [3]struct { - name string - open bool - conn *net.Conn - }{ - { - name: io.Stdin, - open: io.Stdin != "", - conn: &set.stdin, - }, - { - name: io.Stdout, - open: io.Stdout != "", - conn: &set.stdout, - }, - { - name: io.Stderr, - open: !io.Terminal && io.Stderr != "", - conn: &set.stderr, - }, - } { - if p.open { - wg.Add(1) - opened++ - go func(name string, conn *net.Conn) { - dialTimeout := 3 * time.Second - c, err = winio.DialPipe(name, &dialTimeout) - if err != nil { - ch <- errors.Wrapf(err, "failed to connect to %s", name) - } - *conn = c - ch <- nil - wg.Done() - }(p.name, p.conn) - } - } - - for i := 0; i < opened; i++ { - select { - case <-ctx.Done(): - return nil, ctx.Err() - case e := <-ch: - if e != nil { - if err == nil { - err = e - } else { - err = errors.Wrap(err, e.Error()) - } - } - } - } - - return set, err -} - -// Close terminates all successfully dialed IO connections -func (p *pipeSet) Close() { - for _, cn := range []net.Conn{p.stdin, p.stdout, p.stderr} { - if cn != nil { - cn.Close() - } - } -} diff --git a/windows/pid_pool.go b/windows/pid_pool.go deleted file mode 100644 index 5f2936958..000000000 --- a/windows/pid_pool.go +++ /dev/null @@ -1,63 +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 windows - -import ( - "errors" - "sync" -) - -type pidPool struct { - sync.Mutex - pool map[uint32]struct{} - cur uint32 -} - -func newPidPool() *pidPool { - return &pidPool{ - pool: make(map[uint32]struct{}), - } -} - -func (p *pidPool) Get() (uint32, error) { - p.Lock() - defer p.Unlock() - - pid := p.cur + 1 - for pid != p.cur { - // 0 is reserved and invalid - if pid == 0 { - pid = 1 - } - if _, ok := p.pool[pid]; !ok { - p.cur = pid - p.pool[pid] = struct{}{} - return pid, nil - } - pid++ - } - - return 0, errors.New("pid pool exhausted") -} - -func (p *pidPool) Put(pid uint32) { - p.Lock() - delete(p.pool, pid) - p.Unlock() -} diff --git a/windows/process.go b/windows/process.go deleted file mode 100644 index 3419097fa..000000000 --- a/windows/process.go +++ /dev/null @@ -1,251 +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 windows - -import ( - "context" - "io" - "sync" - "syscall" - "time" - - "github.com/Microsoft/hcsshim" - eventstypes "github.com/containerd/containerd/api/events" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/runtime" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -// process implements containerd.Process and containerd.State -type process struct { - sync.Mutex - - hcs hcsshim.Process - - id string - pid uint32 - io *pipeSet - task *task - - exitCh chan struct{} - exitCode uint32 - exitTime time.Time - conf *hcsshim.ProcessConfig -} - -func (p *process) ID() string { - return p.id -} - -func (p *process) State(ctx context.Context) (runtime.State, error) { - return runtime.State{ - Status: p.Status(), - Pid: p.pid, - Stdin: p.io.src.Stdin, - Stdout: p.io.src.Stdout, - Stderr: p.io.src.Stderr, - Terminal: p.io.src.Terminal, - ExitStatus: p.exitCode, - }, nil -} - -func (p *process) Status() runtime.Status { - p.Lock() - defer p.Unlock() - - if p.task.getStatus() == runtime.PausedStatus { - return runtime.PausedStatus - } - - var status runtime.Status - select { - case <-p.exitCh: - status = runtime.StoppedStatus - default: - if p.hcs == nil { - return runtime.CreatedStatus - } - status = runtime.RunningStatus - } - return status -} - -func (p *process) Kill(ctx context.Context, sig uint32, all bool) error { - // On windows all signals kill the process - if p.Status() == runtime.CreatedStatus { - return errors.Wrap(errdefs.ErrFailedPrecondition, "process was not started") - } - return errors.Wrap(p.hcs.Kill(), "failed to kill process") -} - -func (p *process) ResizePty(ctx context.Context, size runtime.ConsoleSize) error { - if p.Status() == runtime.CreatedStatus { - return errors.Wrap(errdefs.ErrFailedPrecondition, "process was not started") - } - err := p.hcs.ResizeConsole(uint16(size.Width), uint16(size.Height)) - return errors.Wrap(err, "failed to resize process console") -} - -func (p *process) CloseIO(ctx context.Context) error { - if p.Status() == runtime.CreatedStatus { - return errors.Wrap(errdefs.ErrFailedPrecondition, "process was not started") - } - return errors.Wrap(p.hcs.CloseStdin(), "failed to close stdin") -} - -func (p *process) Pid() uint32 { - return p.pid -} - -func (p *process) HcsPid() uint32 { - return uint32(p.hcs.Pid()) -} - -func (p *process) ExitCode() (uint32, time.Time, error) { - if s := p.Status(); s != runtime.StoppedStatus && s != runtime.CreatedStatus { - return 255, time.Time{}, errors.Wrapf(errdefs.ErrFailedPrecondition, "process is not stopped: %d", s) - } - return p.exitCode, p.exitTime, nil -} - -func (p *process) Start(ctx context.Context) (err error) { - p.Lock() - defer p.Unlock() - - if p.hcs != nil { - return errors.Wrap(errdefs.ErrFailedPrecondition, "process already started") - } - - // If we fail, close the io right now - defer func() { - if err != nil { - p.io.Close() - } - }() - - var hp hcsshim.Process - if hp, err = p.task.hcsContainer.CreateProcess(p.conf); err != nil { - return errors.Wrapf(err, "failed to create process") - } - - stdin, stdout, stderr, err := hp.Stdio() - if err != nil { - hp.Kill() - return errors.Wrapf(err, "failed to retrieve init process stdio") - } - - ioCopy := func(name string, dst io.WriteCloser, src io.ReadCloser) { - log.G(ctx).WithFields(logrus.Fields{"id": p.id, "pid": p.pid}). - Debugf("%s: copy started", name) - io.Copy(dst, src) - log.G(ctx).WithFields(logrus.Fields{"id": p.id, "pid": p.pid}). - Debugf("%s: copy done", name) - dst.Close() - src.Close() - } - - if p.io.stdin != nil { - go ioCopy("stdin", stdin, p.io.stdin) - } - - if p.io.stdout != nil { - go ioCopy("stdout", p.io.stdout, stdout) - } - - if p.io.stderr != nil { - go ioCopy("stderr", p.io.stderr, stderr) - } - p.hcs = hp - - // Wait for the process to exit to get the exit status - go func() { - if err := hp.Wait(); err != nil { - herr, ok := err.(*hcsshim.ProcessError) - if ok && herr.Err != syscall.ERROR_BROKEN_PIPE { - log.G(ctx). - WithError(err). - WithFields(logrus.Fields{"id": p.id, "pid": p.pid}). - Warnf("hcsshim wait failed (process may have been killed)") - } - // Try to get the exit code nonetheless - } - p.exitTime = time.Now() - - ec, err := hp.ExitCode() - if err != nil { - log.G(ctx). - WithError(err). - WithFields(logrus.Fields{"id": p.id, "pid": p.pid}). - Warnf("hcsshim could not retrieve exit code") - // Use the unknown exit code - ec = 255 - } - p.exitCode = uint32(ec) - - p.task.publisher.Publish(ctx, - runtime.TaskExitEventTopic, - &eventstypes.TaskExit{ - ContainerID: p.task.id, - ID: p.id, - Pid: p.pid, - ExitStatus: p.exitCode, - ExitedAt: p.exitTime, - }) - - close(p.exitCh) - // Ensure io's are closed - p.io.Close() - // Cleanup HCS resources - hp.Close() - }() - return nil -} - -func (p *process) Wait(ctx context.Context) (*runtime.Exit, error) { - <-p.exitCh - - ec, ea, err := p.ExitCode() - if err != nil { - return nil, err - } - return &runtime.Exit{ - Status: ec, - Timestamp: ea, - }, nil -} - -func (p *process) Delete(ctx context.Context) (*runtime.Exit, error) { - ec, ea, err := p.ExitCode() - if err != nil { - return nil, err - } - // If we never started the process close the pipes - if p.Status() == runtime.CreatedStatus { - p.io.Close() - ea = time.Now() - } - p.task.removeProcess(p.id) - return &runtime.Exit{ - Pid: p.pid, - Status: ec, - Timestamp: ea, - }, nil -} diff --git a/windows/runtime.go b/windows/runtime.go deleted file mode 100644 index 39c0652cc..000000000 --- a/windows/runtime.go +++ /dev/null @@ -1,299 +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 windows - -import ( - "context" - "fmt" - "os" - "sync" - "time" - - "github.com/Microsoft/hcsshim" - eventstypes "github.com/containerd/containerd/api/events" - "github.com/containerd/containerd/api/types" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/platforms" - "github.com/containerd/containerd/plugin" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/windows/hcsshimtypes" - "github.com/containerd/typeurl" - imagespec "github.com/opencontainers/image-spec/specs-go/v1" - runtimespec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" -) - -const ( - runtimeName = "windows" - hcsshimOwner = "containerd" - defaultTerminateDuration = 5 * time.Minute -) - -var ( - pluginID = fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtimeName) -) - -var _ = (runtime.PlatformRuntime)(&windowsRuntime{}) - -func init() { - plugin.Register(&plugin.Registration{ - ID: runtimeName, - Type: plugin.RuntimePlugin, - InitFn: New, - Requires: []plugin.Type{ - plugin.MetadataPlugin, - }, - }) -} - -// New returns a new Windows runtime -func New(ic *plugin.InitContext) (interface{}, error) { - ic.Meta.Platforms = []imagespec.Platform{platforms.DefaultSpec()} - - if err := os.MkdirAll(ic.Root, 0700); err != nil { - return nil, errors.Wrapf(err, "could not create state directory at %s", ic.Root) - } - r := &windowsRuntime{ - root: ic.Root, - pidPool: newPidPool(), - - events: make(chan interface{}, 4096), - publisher: ic.Events, - tasks: runtime.NewTaskList(), - } - - // Load our existing containers and kill/delete them. We don't support - // reattaching to them - r.cleanup(ic.Context) - - return r, nil -} - -type windowsRuntime struct { - sync.Mutex - - root string - pidPool *pidPool - - publisher events.Publisher - events chan interface{} - - tasks *runtime.TaskList -} - -func (r *windowsRuntime) ID() string { - return pluginID -} - -func (r *windowsRuntime) Create(ctx context.Context, id string, opts runtime.CreateOpts) (runtime.Task, error) { - namespace, err := namespaces.NamespaceRequired(ctx) - if err != nil { - return nil, err - } - - s, err := typeurl.UnmarshalAny(opts.Spec) - if err != nil { - return nil, err - } - spec := s.(*runtimespec.Spec) - - var createOpts *hcsshimtypes.CreateOptions - if opts.TaskOptions != nil { - o, err := typeurl.UnmarshalAny(opts.TaskOptions) - if err != nil { - return nil, err - } - createOpts = o.(*hcsshimtypes.CreateOptions) - } else { - createOpts = &hcsshimtypes.CreateOptions{} - } - - if createOpts.TerminateDuration == 0 { - createOpts.TerminateDuration = defaultTerminateDuration - } - - if len(opts.Rootfs) == 0 { - return nil, errors.Wrap(errdefs.ErrInvalidArgument, "rootfs was not provided to container create") - } - spec.Windows.LayerFolders = append(spec.Windows.LayerFolders, opts.Rootfs[0].Source) - parentLayerPaths, err := opts.Rootfs[0].GetParentPaths() - if err != nil { - return nil, err - } - spec.Windows.LayerFolders = append(spec.Windows.LayerFolders, parentLayerPaths...) - - return r.newTask(ctx, namespace, id, opts.Rootfs, spec, opts.IO, createOpts) -} - -func (r *windowsRuntime) Get(ctx context.Context, id string) (runtime.Task, error) { - return r.tasks.Get(ctx, id) -} - -func (r *windowsRuntime) Tasks(ctx context.Context, all bool) ([]runtime.Task, error) { - return r.tasks.GetAll(ctx, all) -} - -func (r *windowsRuntime) Add(ctx context.Context, task runtime.Task) error { - return r.tasks.Add(ctx, task) -} - -func (r *windowsRuntime) Delete(ctx context.Context, id string) { - r.tasks.Delete(ctx, id) -} - -func (r *windowsRuntime) newTask(ctx context.Context, namespace, id string, rootfs []mount.Mount, spec *runtimespec.Spec, io runtime.IO, createOpts *hcsshimtypes.CreateOptions) (*task, error) { - var ( - err error - pset *pipeSet - ) - - if pset, err = newPipeSet(ctx, io); err != nil { - return nil, err - } - defer func() { - if err != nil { - pset.Close() - } - }() - - var pid uint32 - if pid, err = r.pidPool.Get(); err != nil { - return nil, err - } - defer func() { - if err != nil { - r.pidPool.Put(pid) - } - }() - - if err := mount.All(rootfs, ""); err != nil { - return nil, errors.Wrap(err, "failed to mount rootfs") - } - defer func() { - if err != nil { - if err := mount.UnmountAll(rootfs[0].Source, 0); err != nil { - log.G(ctx).WithError(err).WithField("path", rootfs[0].Source). - Warn("failed to unmount rootfs on failure") - } - } - }() - - var ( - conf *hcsshim.ContainerConfig - nsid = namespace + "-" + id - ) - if conf, err = newWindowsContainerConfig(ctx, hcsshimOwner, nsid, spec); err != nil { - return nil, err - } - - ctr, err := hcsshim.CreateContainer(nsid, conf) - if err != nil { - return nil, errors.Wrapf(err, "hcsshim failed to create task") - } - defer func() { - if err != nil { - ctr.Terminate() - ctr.Wait() - ctr.Close() - } - }() - - if err = ctr.Start(); err != nil { - return nil, errors.Wrap(err, "hcsshim failed to spawn task") - } - - t := &task{ - id: id, - namespace: namespace, - pid: pid, - io: pset, - status: runtime.CreatedStatus, - spec: spec, - processes: make(map[string]*process), - hyperV: spec.Windows.HyperV != nil, - publisher: r.publisher, - rwLayer: conf.LayerFolderPath, - rootfs: rootfs, - pidPool: r.pidPool, - hcsContainer: ctr, - terminateDuration: createOpts.TerminateDuration, - tasks: r.tasks, - } - // Create the new process but don't start it - pconf := newWindowsProcessConfig(t.spec.Process, t.io) - if _, err = t.newProcess(ctx, t.id, pconf, t.io); err != nil { - return nil, err - } - r.tasks.Add(ctx, t) - - var eventRootfs []*types.Mount - for _, m := range rootfs { - eventRootfs = append(eventRootfs, &types.Mount{ - Type: m.Type, - Source: m.Source, - Options: m.Options, - }) - } - - r.publisher.Publish(ctx, - runtime.TaskCreateEventTopic, - &eventstypes.TaskCreate{ - ContainerID: id, - IO: &eventstypes.TaskIO{ - Stdin: io.Stdin, - Stdout: io.Stdout, - Stderr: io.Stderr, - Terminal: io.Terminal, - }, - Pid: t.pid, - Rootfs: eventRootfs, - // TODO: what should be in Bundle for windows? - }) - - return t, nil -} - -func (r *windowsRuntime) cleanup(ctx context.Context) { - cp, err := hcsshim.GetContainers(hcsshim.ComputeSystemQuery{ - Types: []string{"Container"}, - Owners: []string{hcsshimOwner}, - }) - if err != nil { - log.G(ctx).Warn("failed to retrieve running containers") - return - } - - for _, p := range cp { - container, err := hcsshim.OpenContainer(p.ID) - if err != nil { - log.G(ctx).Warnf("failed open container %s", p.ID) - continue - } - - err = container.Terminate() - if err == nil || hcsshim.IsPending(err) || hcsshim.IsAlreadyStopped(err) { - container.Wait() - } - container.Close() - } -} diff --git a/windows/task.go b/windows/task.go deleted file mode 100644 index ebcfd789b..000000000 --- a/windows/task.go +++ /dev/null @@ -1,464 +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 windows - -import ( - "context" - "sync" - "time" - - "github.com/Microsoft/hcsshim" - eventstypes "github.com/containerd/containerd/api/events" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/windows/hcsshimtypes" - "github.com/containerd/typeurl" - "github.com/gogo/protobuf/types" - specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" -) - -type task struct { - sync.Mutex - - id string - namespace string - pid uint32 - io *pipeSet - status runtime.Status - spec *specs.Spec - processes map[string]*process - hyperV bool - - publisher events.Publisher - rwLayer string - rootfs []mount.Mount - - pidPool *pidPool - hcsContainer hcsshim.Container - terminateDuration time.Duration - tasks *runtime.TaskList -} - -func (t *task) ID() string { - return t.id -} - -func (t *task) Namespace() string { - return t.namespace -} - -func (t *task) State(ctx context.Context) (runtime.State, error) { - var ( - status runtime.Status - exitStatus uint32 - exitedAt time.Time - ) - - if p := t.getProcess(t.id); p != nil { - status = p.Status() - exitStatus = p.exitCode - exitedAt = p.exitTime - } else { - status = t.getStatus() - } - - return runtime.State{ - Status: status, - Pid: t.pid, - Stdin: t.io.src.Stdin, - Stdout: t.io.src.Stdout, - Stderr: t.io.src.Stderr, - Terminal: t.io.src.Terminal, - ExitStatus: exitStatus, - ExitedAt: exitedAt, - }, nil -} - -func (t *task) Kill(ctx context.Context, signal uint32, all bool) error { - p := t.getProcess(t.id) - if p == nil { - return errors.Wrapf(errdefs.ErrFailedPrecondition, "task is not running") - } - - if p.Status() == runtime.StoppedStatus { - return errors.Wrapf(errdefs.ErrNotFound, "process is stopped") - } - - return p.Kill(ctx, signal, all) -} - -func (t *task) ResizePty(ctx context.Context, size runtime.ConsoleSize) error { - p := t.getProcess(t.id) - if p == nil { - return errors.Wrap(errdefs.ErrFailedPrecondition, "task not started") - } - - return p.ResizePty(ctx, size) -} - -func (t *task) CloseIO(ctx context.Context) error { - p := t.getProcess(t.id) - if p == nil { - return errors.Wrap(errdefs.ErrFailedPrecondition, "task not started") - } - - return p.hcs.CloseStdin() -} - -func (t *task) Info() runtime.TaskInfo { - return runtime.TaskInfo{ - ID: t.id, - Runtime: pluginID, - Namespace: t.namespace, - // TODO(mlaventure): what about Spec? I think this could be removed from the info, the id is enough since it matches the one from the container - } -} - -func (t *task) Start(ctx context.Context) error { - p := t.getProcess(t.id) - if p == nil { - panic("init process is missing") - } - - if p.Status() != runtime.CreatedStatus { - return errors.Wrap(errdefs.ErrFailedPrecondition, "process was already started") - } - - if err := p.Start(ctx); err != nil { - return err - } - t.publisher.Publish(ctx, - runtime.TaskStartEventTopic, - &eventstypes.TaskStart{ - ContainerID: t.id, - Pid: t.pid, - }) - return nil -} - -func (t *task) Pause(ctx context.Context) error { - if t.hyperV { - err := t.hcsContainer.Pause() - if err == nil { - t.Lock() - t.status = runtime.PausedStatus - t.Unlock() - - t.publisher.Publish(ctx, - runtime.TaskPausedEventTopic, - &eventstypes.TaskPaused{ - ContainerID: t.id, - }) - return nil - } - return errors.Wrap(err, "hcsshim failed to pause task") - } - - return errors.Wrap(errdefs.ErrFailedPrecondition, "not an hyperV task") -} - -func (t *task) Resume(ctx context.Context) error { - if t.hyperV { - err := t.hcsContainer.Resume() - if err == nil { - t.Lock() - t.status = runtime.RunningStatus - t.Unlock() - - t.publisher.Publish(ctx, - runtime.TaskResumedEventTopic, - &eventstypes.TaskResumed{ - ContainerID: t.id, - }) - return nil - } - return errors.Wrap(err, "hcsshim failed to resume task") - } - - return errors.Wrap(errdefs.ErrFailedPrecondition, "not an hyperV task") -} - -func (t *task) Exec(ctx context.Context, id string, opts runtime.ExecOpts) (runtime.Process, error) { - if p := t.getProcess(t.id); p == nil { - return nil, errors.Wrap(errdefs.ErrFailedPrecondition, "task not started") - } - - if p := t.getProcess(id); p != nil { - return nil, errors.Wrap(errdefs.ErrAlreadyExists, "id already in use") - } - - s, err := typeurl.UnmarshalAny(opts.Spec) - if err != nil { - return nil, err - } - spec := s.(*specs.Process) - if spec.Cwd == "" { - spec.Cwd = t.spec.Process.Cwd - } - - var pset *pipeSet - if pset, err = newPipeSet(ctx, opts.IO); err != nil { - return nil, err - } - - conf := newWindowsProcessConfig(spec, pset) - p, err := t.newProcess(ctx, id, conf, pset) - if err != nil { - return nil, err - } - - t.publisher.Publish(ctx, - runtime.TaskExecAddedEventTopic, - &eventstypes.TaskExecAdded{ - ContainerID: t.id, - ExecID: id, - }) - - return p, nil -} - -func (t *task) Pids(ctx context.Context) ([]runtime.ProcessInfo, error) { - t.Lock() - defer t.Unlock() - - var processList []runtime.ProcessInfo - hcsProcessList, err := t.hcsContainer.ProcessList() - if err != nil { - return nil, err - } - - for _, hcsProcess := range hcsProcessList { - info := &hcsshimtypes.ProcessDetails{ - ImageName: hcsProcess.ImageName, - CreatedAt: hcsProcess.CreateTimestamp, - KernelTime_100Ns: hcsProcess.KernelTime100ns, - MemoryCommitBytes: hcsProcess.MemoryCommitBytes, - MemoryWorkingSetPrivateBytes: hcsProcess.MemoryWorkingSetPrivateBytes, - MemoryWorkingSetSharedBytes: hcsProcess.MemoryWorkingSetSharedBytes, - ProcessID: hcsProcess.ProcessId, - UserTime_100Ns: hcsProcess.UserTime100ns, - } - for _, p := range t.processes { - if p.HcsPid() == hcsProcess.ProcessId { - info.ExecID = p.ID() - break - } - } - processList = append(processList, runtime.ProcessInfo{ - Pid: hcsProcess.ProcessId, - Info: info, - }) - } - - return processList, nil -} - -func (t *task) Checkpoint(_ context.Context, _ string, _ *types.Any) error { - return errors.Wrap(errdefs.ErrUnavailable, "not supported") -} - -func (t *task) Update(ctx context.Context, resources *types.Any) error { - return errors.Wrap(errdefs.ErrUnavailable, "not supported") -} - -func (t *task) Process(ctx context.Context, id string) (p runtime.Process, err error) { - p = t.getProcess(id) - if p == nil { // nolint: govet - err = errors.Wrapf(errdefs.ErrNotFound, "no such process %s", id) - } - - return p, err -} - -func (t *task) Stats(ctx context.Context) (*types.Any, error) { - return nil, errors.Wrap(errdefs.ErrUnavailable, "not supported") -} - -func (t *task) Wait(ctx context.Context) (*runtime.Exit, error) { - p := t.getProcess(t.id) - if p == nil { - return nil, errors.Wrapf(errdefs.ErrNotFound, "no such process %s", t.id) - } - return p.Wait(ctx) -} - -func (t *task) Delete(ctx context.Context) (*runtime.Exit, error) { - var ( - err error - state, _ = t.State(ctx) - ) - switch state.Status { - case runtime.StoppedStatus: - fallthrough - case runtime.CreatedStatus: - // if it's stopped or in created state, we need to shutdown the - // container before removing it - if err = t.stop(ctx); err != nil { - return nil, err - } - default: - return nil, errors.Wrap(errdefs.ErrFailedPrecondition, - "cannot delete a non-stopped task") - } - - var rtExit *runtime.Exit - if p := t.getProcess(t.ID()); p != nil { - ec, ea, err := p.ExitCode() - if err != nil { - return nil, err - } - rtExit = &runtime.Exit{ - Pid: t.pid, - Status: ec, - Timestamp: ea, - } - } else { - rtExit = &runtime.Exit{ - Pid: t.pid, - Status: 255, - Timestamp: time.Now().UTC(), - } - } - - t.cleanup() - t.tasks.Delete(ctx, t.ID()) - - t.publisher.Publish(ctx, - runtime.TaskDeleteEventTopic, - &eventstypes.TaskDelete{ - ContainerID: t.id, - Pid: t.pid, - ExitStatus: rtExit.Status, - ExitedAt: rtExit.Timestamp, - }) - - if err := mount.UnmountAll(t.rootfs[0].Source, 0); err != nil { - log.G(ctx).WithError(err).WithField("path", t.rootfs[0].Source). - Warn("failed to unmount rootfs on failure") - } - // We were never started, return failure - return rtExit, nil -} - -func (t *task) newProcess(ctx context.Context, id string, conf *hcsshim.ProcessConfig, pset *pipeSet) (*process, error) { - var ( - err error - pid uint32 - ) - - // If we fail, close the io right now - defer func() { - if err != nil { - pset.Close() - } - }() - - t.Lock() - if len(t.processes) == 0 { - pid = t.pid - } else { - if pid, err = t.pidPool.Get(); err != nil { - t.Unlock() - return nil, err - } - defer func() { - if err != nil { - t.pidPool.Put(pid) - } - }() - } - wp := &process{ - id: id, - pid: pid, - io: pset, - task: t, - exitCh: make(chan struct{}), - conf: conf, - } - t.processes[id] = wp - t.Unlock() - - return wp, nil -} - -func (t *task) getProcess(id string) *process { - t.Lock() - p := t.processes[id] - t.Unlock() - - return p -} - -func (t *task) removeProcessNL(id string) { - if p, ok := t.processes[id]; ok { - if p.io != nil { - p.io.Close() - } - t.pidPool.Put(p.pid) - delete(t.processes, id) - } -} - -func (t *task) removeProcess(id string) { - t.Lock() - t.removeProcessNL(id) - t.Unlock() -} - -func (t *task) getStatus() runtime.Status { - t.Lock() - status := t.status - t.Unlock() - - return status -} - -// stop tries to shutdown the task. -// It will do so by first calling Shutdown on the hcsshim.Container and if -// that fails, by resorting to caling Terminate -func (t *task) stop(ctx context.Context) error { - if err := t.hcsStop(ctx, t.hcsContainer.Shutdown); err != nil { - return t.hcsStop(ctx, t.hcsContainer.Terminate) - } - t.hcsContainer.Close() - return nil -} - -func (t *task) hcsStop(ctx context.Context, stop func() error) error { - err := stop() - switch { - case hcsshim.IsPending(err): - err = t.hcsContainer.WaitTimeout(t.terminateDuration) - case hcsshim.IsAlreadyStopped(err): - err = nil - } - return err -} - -func (t *task) cleanup() { - t.Lock() - for _, p := range t.processes { - t.removeProcessNL(p.id) - } - t.Unlock() -}