Remove windows v1 runtime
Closes #3094 Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
f7761411b8
commit
f055bdb0aa
@ -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"
|
||||
]
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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"
|
||||
)
|
||||
|
@ -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
|
||||
}
|
@ -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"
|
||||
}
|
@ -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
|
@ -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")
|
||||
)
|
@ -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;
|
||||
}
|
@ -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"
|
||||
}
|
126
windows/io.go
126
windows/io.go
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
@ -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
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
464
windows/task.go
464
windows/task.go
@ -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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user