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",
|
"google/protobuf/descriptor.proto",
|
||||||
"gogoproto/gogo.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 != "" {
|
if copts.defaultRuntime != "" {
|
||||||
c.runtime = copts.defaultRuntime
|
c.runtime = copts.defaultRuntime
|
||||||
} else {
|
} else {
|
||||||
c.runtime = fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS)
|
c.runtime = defaults.DefaultRuntime
|
||||||
}
|
}
|
||||||
|
|
||||||
if copts.services != nil {
|
if copts.services != nil {
|
||||||
|
@ -24,5 +24,4 @@ import (
|
|||||||
_ "github.com/containerd/containerd/runtime/v2"
|
_ "github.com/containerd/containerd/runtime/v2"
|
||||||
_ "github.com/containerd/containerd/snapshots/lcow"
|
_ "github.com/containerd/containerd/snapshots/lcow"
|
||||||
_ "github.com/containerd/containerd/snapshots/windows"
|
_ "github.com/containerd/containerd/snapshots/windows"
|
||||||
_ "github.com/containerd/containerd/windows"
|
|
||||||
)
|
)
|
||||||
|
@ -21,9 +21,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/defaults"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ var (
|
|||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "runtime",
|
Name: "runtime",
|
||||||
Usage: "runtime name",
|
Usage: "runtime name",
|
||||||
Value: fmt.Sprintf("io.containerd.runtime.v1.%s", runtime.GOOS),
|
Value: defaults.DefaultRuntime,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "tty,t",
|
Name: "tty,t",
|
||||||
|
@ -40,7 +40,6 @@ import (
|
|||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/windows/hcsshimtypes"
|
|
||||||
gogotypes "github.com/gogo/protobuf/types"
|
gogotypes "github.com/gogo/protobuf/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -441,20 +440,13 @@ func TestContainerPids(t *testing.T) {
|
|||||||
t.Errorf("invalid task pid %d", pid)
|
t.Errorf("invalid task pid %d", pid)
|
||||||
}
|
}
|
||||||
processes, err := task.Pids(ctx)
|
processes, err := task.Pids(ctx)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
if processes[0].Info == nil {
|
// TODO: This is currently not implemented on windows
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
if l := len(processes); l != 1 {
|
if l := len(processes); l != 1 {
|
||||||
t.Errorf("expected 1 process but received %d", l)
|
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
|
// DefaultFIFODir is the default location used by client-side cio library
|
||||||
// to store FIFOs.
|
// to store FIFOs.
|
||||||
DefaultFIFODir = "/run/containerd/fifo"
|
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
|
// DefaultFIFODir is the default location used by client-side cio library
|
||||||
// to store FIFOs. Unused on Windows.
|
// to store FIFOs. Unused on Windows.
|
||||||
DefaultFIFODir = ""
|
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