Revendor github.com/Microsoft/hcsshim

1. Revendors github.com/Microsoft/hcsshim to the latest known good commit.
This includes numerous bug fixes and improvements.

2. Vendors indirect dependency on go.opencensus.io since hcsshim now uses trace
correlation.

Signed-off-by: Justin Terry (VM) <juterry@microsoft.com>
This commit is contained in:
Justin Terry (VM) 2019-08-14 08:55:38 -07:00
parent 640860a042
commit 041e9debb1
121 changed files with 4894 additions and 1206 deletions

View File

@ -34,7 +34,7 @@ golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
github.com/BurntSushi/toml v0.3.1
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
github.com/Microsoft/go-winio v0.4.14
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
github.com/Microsoft/hcsshim 9e921883ac929bbe515b39793ece99ce3a9d7706
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
github.com/containerd/ttrpc 1fb3814edf44a76e0ccf503decf726d994919a9a
@ -44,6 +44,8 @@ github.com/google/go-cmp v0.2.0
go.etcd.io/bbolt v1.3.3
github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55
github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
github.com/hashicorp/golang-lru v0.5.1
go.opencensus.io v0.22.0
# cri dependencies
github.com/containerd/cri f1d492b0cdd14e76476ee4dd024696ce3634e501 # master

View File

@ -1,33 +1,19 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto
/*
Package options is a generated protocol buffer package.
It is generated from these files:
github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto
It has these top-level messages:
Options
ProcessDetails
*/
package options
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
// skipping weak import gogoproto "github.com/gogo/protobuf/gogoproto"
import _ "github.com/gogo/protobuf/types"
import time "time"
import types "github.com/gogo/protobuf/types"
import strings "strings"
import reflect "reflect"
import io "io"
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
@ -54,6 +40,7 @@ var Options_DebugType_name = map[int32]string{
1: "FILE",
2: "ETW",
}
var Options_DebugType_value = map[string]int32{
"NPIPE": 0,
"FILE": 1,
@ -63,7 +50,10 @@ var Options_DebugType_value = map[string]int32{
func (x Options_DebugType) String() string {
return proto.EnumName(Options_DebugType_name, int32(x))
}
func (Options_DebugType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRunhcs, []int{0, 0} }
func (Options_DebugType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_b643df6839c75082, []int{0, 0}
}
type Options_SandboxIsolation int32
@ -76,6 +66,7 @@ var Options_SandboxIsolation_name = map[int32]string{
0: "PROCESS",
1: "HYPERVISOR",
}
var Options_SandboxIsolation_value = map[string]int32{
"PROCESS": 0,
"HYPERVISOR": 1,
@ -84,8 +75,9 @@ var Options_SandboxIsolation_value = map[string]int32{
func (x Options_SandboxIsolation) String() string {
return proto.EnumName(Options_SandboxIsolation_name, int32(x))
}
func (Options_SandboxIsolation) EnumDescriptor() ([]byte, []int) {
return fileDescriptorRunhcs, []int{0, 1}
return fileDescriptor_b643df6839c75082, []int{0, 1}
}
// Options are the set of customizations that can be passed at Create time.
@ -109,18 +101,49 @@ type Options struct {
SandboxIsolation Options_SandboxIsolation `protobuf:"varint,6,opt,name=sandbox_isolation,json=sandboxIsolation,proto3,enum=containerd.runhcs.v1.Options_SandboxIsolation" json:"sandbox_isolation,omitempty"`
// boot_files_root_path is the path to the directory containing the LCOW
// kernel and root FS files.
BootFilesRootPath string `protobuf:"bytes,7,opt,name=boot_files_root_path,json=bootFilesRootPath,proto3" json:"boot_files_root_path,omitempty"`
BootFilesRootPath string `protobuf:"bytes,7,opt,name=boot_files_root_path,json=bootFilesRootPath,proto3" json:"boot_files_root_path,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Options) Reset() { *m = Options{} }
func (*Options) ProtoMessage() {}
func (*Options) Descriptor() ([]byte, []int) { return fileDescriptorRunhcs, []int{0} }
func (m *Options) Reset() { *m = Options{} }
func (*Options) ProtoMessage() {}
func (*Options) Descriptor() ([]byte, []int) {
return fileDescriptor_b643df6839c75082, []int{0}
}
func (m *Options) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Options) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Options.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 *Options) XXX_Merge(src proto.Message) {
xxx_messageInfo_Options.Merge(m, src)
}
func (m *Options) XXX_Size() int {
return m.Size()
}
func (m *Options) XXX_DiscardUnknown() {
xxx_messageInfo_Options.DiscardUnknown(m)
}
var xxx_messageInfo_Options proto.InternalMessageInfo
// ProcessDetails contains additional information about a process. This is the additional
// info returned in the Pids query.
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,stdtime" json:"created_at"`
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"`
@ -128,18 +151,102 @@ type ProcessDetails struct {
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 fileDescriptorRunhcs, []int{1} }
func (m *ProcessDetails) Reset() { *m = ProcessDetails{} }
func (*ProcessDetails) ProtoMessage() {}
func (*ProcessDetails) Descriptor() ([]byte, []int) {
return fileDescriptor_b643df6839c75082, []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((*Options)(nil), "containerd.runhcs.v1.Options")
proto.RegisterType((*ProcessDetails)(nil), "containerd.runhcs.v1.ProcessDetails")
proto.RegisterEnum("containerd.runhcs.v1.Options_DebugType", Options_DebugType_name, Options_DebugType_value)
proto.RegisterEnum("containerd.runhcs.v1.Options_SandboxIsolation", Options_SandboxIsolation_name, Options_SandboxIsolation_value)
proto.RegisterType((*Options)(nil), "containerd.runhcs.v1.Options")
proto.RegisterType((*ProcessDetails)(nil), "containerd.runhcs.v1.ProcessDetails")
}
func init() {
proto.RegisterFile("github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto", fileDescriptor_b643df6839c75082)
}
var fileDescriptor_b643df6839c75082 = []byte{
// 704 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xda, 0x48,
0x18, 0xc6, 0xe1, 0xd3, 0x6f, 0x96, 0xc4, 0x99, 0xe5, 0x80, 0xb2, 0xbb, 0x80, 0xc8, 0x21, 0x89,
0x76, 0x63, 0x43, 0xf6, 0xd8, 0x53, 0x09, 0xa0, 0xba, 0x6a, 0x83, 0x65, 0xa2, 0xa6, 0x1f, 0x07,
0xcb, 0xd8, 0x83, 0xb1, 0x82, 0x3d, 0xd6, 0xcc, 0x90, 0x86, 0x5b, 0x7f, 0x42, 0x7f, 0x55, 0x95,
0x63, 0x8f, 0x95, 0x2a, 0xa5, 0x0d, 0xbf, 0xa4, 0x9a, 0xb1, 0x49, 0xd4, 0x28, 0xea, 0xa5, 0x27,
0xc6, 0xcf, 0xf3, 0xbc, 0xcf, 0xfb, 0x29, 0x60, 0x14, 0x84, 0x7c, 0xb6, 0x98, 0xe8, 0x1e, 0x89,
0x8c, 0x97, 0xa1, 0x47, 0x09, 0x23, 0x53, 0x6e, 0xcc, 0x3c, 0xc6, 0x66, 0x61, 0x64, 0x78, 0x91,
0x6f, 0x78, 0x24, 0xe6, 0x6e, 0x18, 0x63, 0xea, 0x1f, 0x09, 0xec, 0x88, 0x2e, 0xe2, 0x99, 0xc7,
0x8e, 0x2e, 0xbb, 0x06, 0x49, 0x78, 0x48, 0x62, 0x66, 0xa4, 0x88, 0x9e, 0x50, 0xc2, 0x09, 0xaa,
0xdd, 0xeb, 0xf5, 0x8c, 0xb8, 0xec, 0xee, 0xd6, 0x02, 0x12, 0x10, 0x29, 0x30, 0xc4, 0x2b, 0xd5,
0xee, 0x36, 0x03, 0x42, 0x82, 0x39, 0x36, 0xe4, 0xd7, 0x64, 0x31, 0x35, 0x78, 0x18, 0x61, 0xc6,
0xdd, 0x28, 0x49, 0x05, 0xed, 0x4f, 0x79, 0x28, 0x8f, 0xd2, 0x2c, 0xa8, 0x06, 0x45, 0x1f, 0x4f,
0x16, 0x41, 0x5d, 0x69, 0x29, 0x07, 0x15, 0x3b, 0xfd, 0x40, 0x43, 0x00, 0xf9, 0x70, 0xf8, 0x32,
0xc1, 0xf5, 0x8d, 0x96, 0x72, 0xb0, 0x75, 0xbc, 0xaf, 0x3f, 0x56, 0x83, 0x9e, 0x19, 0xe9, 0x7d,
0xa1, 0x3f, 0x5b, 0x26, 0xd8, 0x56, 0xfd, 0xf5, 0x13, 0xed, 0x41, 0x95, 0xe2, 0x20, 0x64, 0x9c,
0x2e, 0x1d, 0x4a, 0x08, 0xaf, 0xe7, 0x5b, 0xca, 0x81, 0x6a, 0xff, 0xb1, 0x06, 0x6d, 0x42, 0xb8,
0x10, 0x31, 0x37, 0xf6, 0x27, 0xe4, 0xca, 0x09, 0x23, 0x37, 0xc0, 0xf5, 0x42, 0x2a, 0xca, 0x40,
0x53, 0x60, 0xe8, 0x10, 0xb4, 0xb5, 0x28, 0x99, 0xbb, 0x7c, 0x4a, 0x68, 0x54, 0x2f, 0x4a, 0xdd,
0x76, 0x86, 0x5b, 0x19, 0x8c, 0xde, 0xc1, 0xce, 0x9d, 0x1f, 0x23, 0x73, 0x57, 0xd4, 0x57, 0x2f,
0xc9, 0x1e, 0xf4, 0x5f, 0xf7, 0x30, 0xce, 0x32, 0xae, 0xa3, 0xec, 0x75, 0xce, 0x3b, 0x04, 0x19,
0x50, 0x9b, 0x10, 0xc2, 0x9d, 0x69, 0x38, 0xc7, 0x4c, 0xf6, 0xe4, 0x24, 0x2e, 0x9f, 0xd5, 0xcb,
0xb2, 0x96, 0x1d, 0xc1, 0x0d, 0x05, 0x25, 0x3a, 0xb3, 0x5c, 0x3e, 0x6b, 0x1f, 0x82, 0x7a, 0x37,
0x1a, 0xa4, 0x42, 0xf1, 0xd4, 0x32, 0xad, 0x81, 0x96, 0x43, 0x15, 0x28, 0x0c, 0xcd, 0x17, 0x03,
0x4d, 0x41, 0x65, 0xc8, 0x0f, 0xce, 0xce, 0xb5, 0x8d, 0xb6, 0x01, 0xda, 0xc3, 0x0a, 0xd0, 0x26,
0x94, 0x2d, 0x7b, 0x74, 0x32, 0x18, 0x8f, 0xb5, 0x1c, 0xda, 0x02, 0x78, 0xf6, 0xc6, 0x1a, 0xd8,
0xaf, 0xcc, 0xf1, 0xc8, 0xd6, 0x94, 0xf6, 0xd7, 0x3c, 0x6c, 0x59, 0x94, 0x78, 0x98, 0xb1, 0x3e,
0xe6, 0x6e, 0x38, 0x67, 0xe8, 0x1f, 0x00, 0x39, 0x44, 0x27, 0x76, 0x23, 0x2c, 0x97, 0xaa, 0xda,
0xaa, 0x44, 0x4e, 0xdd, 0x08, 0xa3, 0x13, 0x00, 0x8f, 0x62, 0x97, 0x63, 0xdf, 0x71, 0xb9, 0x5c,
0xec, 0xe6, 0xf1, 0xae, 0x9e, 0x1e, 0x8c, 0xbe, 0x3e, 0x18, 0xfd, 0x6c, 0x7d, 0x30, 0xbd, 0xca,
0xf5, 0x4d, 0x33, 0xf7, 0xf1, 0x5b, 0x53, 0xb1, 0xd5, 0x2c, 0xee, 0x29, 0x47, 0xff, 0x02, 0xba,
0xc0, 0x34, 0xc6, 0x73, 0x47, 0x5c, 0x96, 0xd3, 0xed, 0x74, 0x9c, 0x98, 0xc9, 0xd5, 0x16, 0xec,
0xed, 0x94, 0x11, 0x0e, 0xdd, 0x4e, 0xe7, 0x94, 0x21, 0x1d, 0xfe, 0x8c, 0x70, 0x44, 0xe8, 0xd2,
0xf1, 0x48, 0x14, 0x85, 0xdc, 0x99, 0x2c, 0x39, 0x66, 0x72, 0xc7, 0x05, 0x7b, 0x27, 0xa5, 0x4e,
0x24, 0xd3, 0x13, 0x04, 0x1a, 0x42, 0x2b, 0xd3, 0xbf, 0x27, 0xf4, 0x22, 0x8c, 0x03, 0x87, 0x61,
0xee, 0x24, 0x34, 0xbc, 0x74, 0x39, 0xce, 0x82, 0x8b, 0x32, 0xf8, 0xef, 0x54, 0x77, 0x9e, 0xca,
0xc6, 0x98, 0x5b, 0xa9, 0x28, 0xf5, 0xe9, 0x43, 0xf3, 0x11, 0x1f, 0x36, 0x73, 0x29, 0xf6, 0x33,
0x9b, 0x92, 0xb4, 0xf9, 0xeb, 0xa1, 0xcd, 0x58, 0x6a, 0x52, 0x97, 0xff, 0x00, 0x92, 0x74, 0xc0,
0x4e, 0xe8, 0xcb, 0x25, 0x57, 0x7b, 0xd5, 0xd5, 0x4d, 0x53, 0xcd, 0xc6, 0x6e, 0xf6, 0x6d, 0x35,
0x13, 0x98, 0x3e, 0xda, 0x07, 0x6d, 0xc1, 0x30, 0xfd, 0x69, 0x2c, 0x15, 0x99, 0xa4, 0x2a, 0xf0,
0xfb, 0xa1, 0xec, 0x41, 0x19, 0x5f, 0x61, 0x4f, 0x78, 0xaa, 0x62, 0x45, 0x3d, 0x58, 0xdd, 0x34,
0x4b, 0x83, 0x2b, 0xec, 0x99, 0x7d, 0xbb, 0x24, 0x28, 0xd3, 0xef, 0xf9, 0xd7, 0xb7, 0x8d, 0xdc,
0x97, 0xdb, 0x46, 0xee, 0xc3, 0xaa, 0xa1, 0x5c, 0xaf, 0x1a, 0xca, 0xe7, 0x55, 0x43, 0xf9, 0xbe,
0x6a, 0x28, 0x6f, 0x9f, 0xff, 0xfe, 0xdf, 0xcb, 0x93, 0xec, 0xf7, 0x75, 0x6e, 0x52, 0x92, 0x7b,
0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x9a, 0x54, 0x17, 0xb5, 0x04, 0x00, 0x00,
}
func (m *Options) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -199,6 +306,9 @@ func (m *Options) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintRunhcs(dAtA, i, uint64(len(m.BootFilesRootPath)))
i += copy(dAtA[i:], m.BootFilesRootPath)
}
if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized)
}
return i, nil
}
@ -225,8 +335,8 @@ func (m *ProcessDetails) MarshalTo(dAtA []byte) (int, error) {
}
dAtA[i] = 0x12
i++
i = encodeVarintRunhcs(dAtA, i, uint64(types.SizeOfStdTime(m.CreatedAt)))
n1, err := types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:])
i = encodeVarintRunhcs(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt)))
n1, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:])
if err != nil {
return 0, err
}
@ -267,6 +377,9 @@ func (m *ProcessDetails) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintRunhcs(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
}
@ -280,6 +393,9 @@ func encodeVarintRunhcs(dAtA []byte, offset int, v uint64) int {
return offset + 1
}
func (m *Options) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Debug {
@ -307,17 +423,23 @@ func (m *Options) Size() (n int) {
if l > 0 {
n += 1 + l + sovRunhcs(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 + sovRunhcs(uint64(l))
}
l = types.SizeOfStdTime(m.CreatedAt)
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt)
n += 1 + l + sovRunhcs(uint64(l))
if m.KernelTime_100Ns != 0 {
n += 1 + sovRunhcs(uint64(m.KernelTime_100Ns))
@ -341,6 +463,9 @@ func (m *ProcessDetails) Size() (n int) {
if l > 0 {
n += 1 + l + sovRunhcs(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
@ -369,6 +494,7 @@ func (this *Options) String() string {
`SandboxPlatform:` + fmt.Sprintf("%v", this.SandboxPlatform) + `,`,
`SandboxIsolation:` + fmt.Sprintf("%v", this.SandboxIsolation) + `,`,
`BootFilesRootPath:` + fmt.Sprintf("%v", this.BootFilesRootPath) + `,`,
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
@ -379,7 +505,7 @@ func (this *ProcessDetails) String() string {
}
s := strings.Join([]string{`&ProcessDetails{`,
`ImageName:` + fmt.Sprintf("%v", this.ImageName) + `,`,
`CreatedAt:` + strings.Replace(strings.Replace(this.CreatedAt.String(), "Timestamp", "google_protobuf1.Timestamp", 1), `&`, ``, 1) + `,`,
`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) + `,`,
@ -387,6 +513,7 @@ func (this *ProcessDetails) String() string {
`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
@ -414,7 +541,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -442,7 +569,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
v |= (int(b) & 0x7F) << shift
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -462,7 +589,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.DebugType |= (Options_DebugType(b) & 0x7F) << shift
m.DebugType |= Options_DebugType(b&0x7F) << shift
if b < 0x80 {
break
}
@ -481,7 +608,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -491,6 +618,9 @@ func (m *Options) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -510,7 +640,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -520,6 +650,9 @@ func (m *Options) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -539,7 +672,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -549,6 +682,9 @@ func (m *Options) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -568,7 +704,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.SandboxIsolation |= (Options_SandboxIsolation(b) & 0x7F) << shift
m.SandboxIsolation |= Options_SandboxIsolation(b&0x7F) << shift
if b < 0x80 {
break
}
@ -587,7 +723,7 @@ func (m *Options) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -597,6 +733,9 @@ func (m *Options) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -611,9 +750,13 @@ func (m *Options) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthRunhcs
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRunhcs
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
@ -638,7 +781,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -666,7 +809,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -676,6 +819,9 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -695,7 +841,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@ -704,10 +850,13 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := types.StdTimeUnmarshal(&m.CreatedAt, dAtA[iNdEx:postIndex]); err != nil {
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreatedAt, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
@ -725,7 +874,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.KernelTime_100Ns |= (uint64(b) & 0x7F) << shift
m.KernelTime_100Ns |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -744,7 +893,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.MemoryCommitBytes |= (uint64(b) & 0x7F) << shift
m.MemoryCommitBytes |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -763,7 +912,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.MemoryWorkingSetPrivateBytes |= (uint64(b) & 0x7F) << shift
m.MemoryWorkingSetPrivateBytes |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -782,7 +931,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.MemoryWorkingSetSharedBytes |= (uint64(b) & 0x7F) << shift
m.MemoryWorkingSetSharedBytes |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -801,7 +950,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.ProcessID |= (uint32(b) & 0x7F) << shift
m.ProcessID |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
@ -820,7 +969,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.UserTime_100Ns |= (uint64(b) & 0x7F) << shift
m.UserTime_100Ns |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -839,7 +988,7 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@ -849,6 +998,9 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthRunhcs
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRunhcs
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@ -863,9 +1015,13 @@ func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthRunhcs
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRunhcs
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
@ -929,10 +1085,13 @@ func skipRunhcs(dAtA []byte) (n int, err error) {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthRunhcs
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthRunhcs
}
return iNdEx, nil
case 3:
for {
@ -961,6 +1120,9 @@ func skipRunhcs(dAtA []byte) (n int, err error) {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthRunhcs
}
}
return iNdEx, nil
case 4:
@ -979,55 +1141,3 @@ var (
ErrInvalidLengthRunhcs = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRunhcs = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto", fileDescriptorRunhcs)
}
var fileDescriptorRunhcs = []byte{
// 704 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xda, 0x48,
0x18, 0xc6, 0xe1, 0xd3, 0x6f, 0x96, 0xc4, 0x99, 0xe5, 0x80, 0xb2, 0xbb, 0x80, 0xc8, 0x21, 0x89,
0x76, 0x63, 0x43, 0xf6, 0xd8, 0x53, 0x09, 0xa0, 0xba, 0x6a, 0x83, 0x65, 0xa2, 0xa6, 0x1f, 0x07,
0xcb, 0xd8, 0x83, 0xb1, 0x82, 0x3d, 0xd6, 0xcc, 0x90, 0x86, 0x5b, 0x7f, 0x42, 0x7f, 0x55, 0x95,
0x63, 0x8f, 0x95, 0x2a, 0xa5, 0x0d, 0xbf, 0xa4, 0x9a, 0xb1, 0x49, 0xd4, 0x28, 0xea, 0xa5, 0x27,
0xc6, 0xcf, 0xf3, 0xbc, 0xcf, 0xfb, 0x29, 0x60, 0x14, 0x84, 0x7c, 0xb6, 0x98, 0xe8, 0x1e, 0x89,
0x8c, 0x97, 0xa1, 0x47, 0x09, 0x23, 0x53, 0x6e, 0xcc, 0x3c, 0xc6, 0x66, 0x61, 0x64, 0x78, 0x91,
0x6f, 0x78, 0x24, 0xe6, 0x6e, 0x18, 0x63, 0xea, 0x1f, 0x09, 0xec, 0x88, 0x2e, 0xe2, 0x99, 0xc7,
0x8e, 0x2e, 0xbb, 0x06, 0x49, 0x78, 0x48, 0x62, 0x66, 0xa4, 0x88, 0x9e, 0x50, 0xc2, 0x09, 0xaa,
0xdd, 0xeb, 0xf5, 0x8c, 0xb8, 0xec, 0xee, 0xd6, 0x02, 0x12, 0x10, 0x29, 0x30, 0xc4, 0x2b, 0xd5,
0xee, 0x36, 0x03, 0x42, 0x82, 0x39, 0x36, 0xe4, 0xd7, 0x64, 0x31, 0x35, 0x78, 0x18, 0x61, 0xc6,
0xdd, 0x28, 0x49, 0x05, 0xed, 0x4f, 0x79, 0x28, 0x8f, 0xd2, 0x2c, 0xa8, 0x06, 0x45, 0x1f, 0x4f,
0x16, 0x41, 0x5d, 0x69, 0x29, 0x07, 0x15, 0x3b, 0xfd, 0x40, 0x43, 0x00, 0xf9, 0x70, 0xf8, 0x32,
0xc1, 0xf5, 0x8d, 0x96, 0x72, 0xb0, 0x75, 0xbc, 0xaf, 0x3f, 0x56, 0x83, 0x9e, 0x19, 0xe9, 0x7d,
0xa1, 0x3f, 0x5b, 0x26, 0xd8, 0x56, 0xfd, 0xf5, 0x13, 0xed, 0x41, 0x95, 0xe2, 0x20, 0x64, 0x9c,
0x2e, 0x1d, 0x4a, 0x08, 0xaf, 0xe7, 0x5b, 0xca, 0x81, 0x6a, 0xff, 0xb1, 0x06, 0x6d, 0x42, 0xb8,
0x10, 0x31, 0x37, 0xf6, 0x27, 0xe4, 0xca, 0x09, 0x23, 0x37, 0xc0, 0xf5, 0x42, 0x2a, 0xca, 0x40,
0x53, 0x60, 0xe8, 0x10, 0xb4, 0xb5, 0x28, 0x99, 0xbb, 0x7c, 0x4a, 0x68, 0x54, 0x2f, 0x4a, 0xdd,
0x76, 0x86, 0x5b, 0x19, 0x8c, 0xde, 0xc1, 0xce, 0x9d, 0x1f, 0x23, 0x73, 0x57, 0xd4, 0x57, 0x2f,
0xc9, 0x1e, 0xf4, 0x5f, 0xf7, 0x30, 0xce, 0x32, 0xae, 0xa3, 0xec, 0x75, 0xce, 0x3b, 0x04, 0x19,
0x50, 0x9b, 0x10, 0xc2, 0x9d, 0x69, 0x38, 0xc7, 0x4c, 0xf6, 0xe4, 0x24, 0x2e, 0x9f, 0xd5, 0xcb,
0xb2, 0x96, 0x1d, 0xc1, 0x0d, 0x05, 0x25, 0x3a, 0xb3, 0x5c, 0x3e, 0x6b, 0x1f, 0x82, 0x7a, 0x37,
0x1a, 0xa4, 0x42, 0xf1, 0xd4, 0x32, 0xad, 0x81, 0x96, 0x43, 0x15, 0x28, 0x0c, 0xcd, 0x17, 0x03,
0x4d, 0x41, 0x65, 0xc8, 0x0f, 0xce, 0xce, 0xb5, 0x8d, 0xb6, 0x01, 0xda, 0xc3, 0x0a, 0xd0, 0x26,
0x94, 0x2d, 0x7b, 0x74, 0x32, 0x18, 0x8f, 0xb5, 0x1c, 0xda, 0x02, 0x78, 0xf6, 0xc6, 0x1a, 0xd8,
0xaf, 0xcc, 0xf1, 0xc8, 0xd6, 0x94, 0xf6, 0xd7, 0x3c, 0x6c, 0x59, 0x94, 0x78, 0x98, 0xb1, 0x3e,
0xe6, 0x6e, 0x38, 0x67, 0xe8, 0x1f, 0x00, 0x39, 0x44, 0x27, 0x76, 0x23, 0x2c, 0x97, 0xaa, 0xda,
0xaa, 0x44, 0x4e, 0xdd, 0x08, 0xa3, 0x13, 0x00, 0x8f, 0x62, 0x97, 0x63, 0xdf, 0x71, 0xb9, 0x5c,
0xec, 0xe6, 0xf1, 0xae, 0x9e, 0x1e, 0x8c, 0xbe, 0x3e, 0x18, 0xfd, 0x6c, 0x7d, 0x30, 0xbd, 0xca,
0xf5, 0x4d, 0x33, 0xf7, 0xf1, 0x5b, 0x53, 0xb1, 0xd5, 0x2c, 0xee, 0x29, 0x47, 0xff, 0x02, 0xba,
0xc0, 0x34, 0xc6, 0x73, 0x47, 0x5c, 0x96, 0xd3, 0xed, 0x74, 0x9c, 0x98, 0xc9, 0xd5, 0x16, 0xec,
0xed, 0x94, 0x11, 0x0e, 0xdd, 0x4e, 0xe7, 0x94, 0x21, 0x1d, 0xfe, 0x8c, 0x70, 0x44, 0xe8, 0xd2,
0xf1, 0x48, 0x14, 0x85, 0xdc, 0x99, 0x2c, 0x39, 0x66, 0x72, 0xc7, 0x05, 0x7b, 0x27, 0xa5, 0x4e,
0x24, 0xd3, 0x13, 0x04, 0x1a, 0x42, 0x2b, 0xd3, 0xbf, 0x27, 0xf4, 0x22, 0x8c, 0x03, 0x87, 0x61,
0xee, 0x24, 0x34, 0xbc, 0x74, 0x39, 0xce, 0x82, 0x8b, 0x32, 0xf8, 0xef, 0x54, 0x77, 0x9e, 0xca,
0xc6, 0x98, 0x5b, 0xa9, 0x28, 0xf5, 0xe9, 0x43, 0xf3, 0x11, 0x1f, 0x36, 0x73, 0x29, 0xf6, 0x33,
0x9b, 0x92, 0xb4, 0xf9, 0xeb, 0xa1, 0xcd, 0x58, 0x6a, 0x52, 0x97, 0xff, 0x00, 0x92, 0x74, 0xc0,
0x4e, 0xe8, 0xcb, 0x25, 0x57, 0x7b, 0xd5, 0xd5, 0x4d, 0x53, 0xcd, 0xc6, 0x6e, 0xf6, 0x6d, 0x35,
0x13, 0x98, 0x3e, 0xda, 0x07, 0x6d, 0xc1, 0x30, 0xfd, 0x69, 0x2c, 0x15, 0x99, 0xa4, 0x2a, 0xf0,
0xfb, 0xa1, 0xec, 0x41, 0x19, 0x5f, 0x61, 0x4f, 0x78, 0xaa, 0x62, 0x45, 0x3d, 0x58, 0xdd, 0x34,
0x4b, 0x83, 0x2b, 0xec, 0x99, 0x7d, 0xbb, 0x24, 0x28, 0xd3, 0xef, 0xf9, 0xd7, 0xb7, 0x8d, 0xdc,
0x97, 0xdb, 0x46, 0xee, 0xc3, 0xaa, 0xa1, 0x5c, 0xaf, 0x1a, 0xca, 0xe7, 0x55, 0x43, 0xf9, 0xbe,
0x6a, 0x28, 0x6f, 0x9f, 0xff, 0xfe, 0xdf, 0xcb, 0x93, 0xec, 0xf7, 0x75, 0x6e, 0x52, 0x92, 0x7b,
0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x9a, 0x54, 0x17, 0xb5, 0x04, 0x00, 0x00,
}

View File

@ -1,8 +1,10 @@
package hcsshim
import (
"context"
"fmt"
"os"
"sync"
"time"
"github.com/Microsoft/hcsshim/internal/hcs"
@ -52,7 +54,10 @@ const (
type ResourceModificationRequestResponse = schema1.ResourceModificationRequestResponse
type container struct {
system *hcs.System
system *hcs.System
waitOnce sync.Once
waitErr error
waitCh chan struct{}
}
// createComputeSystemAdditionalJSON is read from the environment at initialisation
@ -71,61 +76,87 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
return nil, fmt.Errorf("failed to merge additional JSON '%s': %s", createContainerAdditionalJSON, err)
}
system, err := hcs.CreateComputeSystem(id, fullConfig)
system, err := hcs.CreateComputeSystem(context.Background(), id, fullConfig)
if err != nil {
return nil, err
}
return &container{system}, err
return &container{system: system}, err
}
// OpenContainer opens an existing container by ID.
func OpenContainer(id string) (Container, error) {
system, err := hcs.OpenComputeSystem(id)
system, err := hcs.OpenComputeSystem(context.Background(), id)
if err != nil {
return nil, err
}
return &container{system}, err
return &container{system: system}, err
}
// GetContainers gets a list of the containers on the system that match the query
func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) {
return hcs.GetComputeSystems(q)
return hcs.GetComputeSystems(context.Background(), q)
}
// Start synchronously starts the container.
func (container *container) Start() error {
return convertSystemError(container.system.Start(), container)
return convertSystemError(container.system.Start(context.Background()), container)
}
// Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds.
func (container *container) Shutdown() error {
return convertSystemError(container.system.Shutdown(), container)
err := container.system.Shutdown(context.Background())
if err != nil {
return convertSystemError(err, container)
}
return &ContainerError{Container: container, Err: ErrVmcomputeOperationPending, Operation: "hcsshim::ComputeSystem::Shutdown"}
}
// Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds.
func (container *container) Terminate() error {
return convertSystemError(container.system.Terminate(), container)
err := container.system.Terminate(context.Background())
if err != nil {
return convertSystemError(err, container)
}
return &ContainerError{Container: container, Err: ErrVmcomputeOperationPending, Operation: "hcsshim::ComputeSystem::Terminate"}
}
// Waits synchronously waits for the container to shutdown or terminate.
func (container *container) Wait() error {
return convertSystemError(container.system.Wait(), container)
err := container.system.Wait()
if err == nil {
err = container.system.ExitError()
}
return convertSystemError(err, container)
}
// WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It
// returns false if timeout occurs.
func (container *container) WaitTimeout(t time.Duration) error {
return convertSystemError(container.system.WaitTimeout(t), container)
func (container *container) WaitTimeout(timeout time.Duration) error {
container.waitOnce.Do(func() {
container.waitCh = make(chan struct{})
go func() {
container.waitErr = container.Wait()
close(container.waitCh)
}()
})
t := time.NewTimer(timeout)
defer t.Stop()
select {
case <-t.C:
return &ContainerError{Container: container, Err: ErrTimeout, Operation: "hcsshim::ComputeSystem::Wait"}
case <-container.waitCh:
return container.waitErr
}
}
// Pause pauses the execution of a container.
func (container *container) Pause() error {
return convertSystemError(container.system.Pause(), container)
return convertSystemError(container.system.Pause(context.Background()), container)
}
// Resume resumes the execution of a container.
func (container *container) Resume() error {
return convertSystemError(container.system.Resume(), container)
return convertSystemError(container.system.Resume(context.Background()), container)
}
// HasPendingUpdates returns true if the container has updates pending to install
@ -135,7 +166,7 @@ func (container *container) HasPendingUpdates() (bool, error) {
// Statistics returns statistics for the container. This is a legacy v1 call
func (container *container) Statistics() (Statistics, error) {
properties, err := container.system.Properties(schema1.PropertyTypeStatistics)
properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeStatistics)
if err != nil {
return Statistics{}, convertSystemError(err, container)
}
@ -145,7 +176,7 @@ func (container *container) Statistics() (Statistics, error) {
// ProcessList returns an array of ProcessListItems for the container. This is a legacy v1 call
func (container *container) ProcessList() ([]ProcessListItem, error) {
properties, err := container.system.Properties(schema1.PropertyTypeProcessList)
properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeProcessList)
if err != nil {
return nil, convertSystemError(err, container)
}
@ -155,7 +186,7 @@ func (container *container) ProcessList() ([]ProcessListItem, error) {
// This is a legacy v1 call
func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
properties, err := container.system.Properties(schema1.PropertyTypeMappedVirtualDisk)
properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeMappedVirtualDisk)
if err != nil {
return nil, convertSystemError(err, container)
}
@ -165,20 +196,20 @@ func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskContr
// CreateProcess launches a new process within the container.
func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
p, err := container.system.CreateProcess(c)
p, err := container.system.CreateProcessNoStdio(c)
if err != nil {
return nil, convertSystemError(err, container)
}
return &process{p}, nil
return &process{p: p.(*hcs.Process)}, nil
}
// OpenProcess gets an interface to an existing process within the container.
func (container *container) OpenProcess(pid int) (Process, error) {
p, err := container.system.OpenProcess(pid)
p, err := container.system.OpenProcess(context.Background(), pid)
if err != nil {
return nil, convertSystemError(err, container)
}
return &process{p}, nil
return &process{p: p}, nil
}
// Close cleans up any state associated with the container but does not terminate or wait for it.
@ -188,5 +219,5 @@ func (container *container) Close() error {
// Modify the System
func (container *container) Modify(config *ResourceModificationRequestResponse) error {
return convertSystemError(container.system.Modify(config), container)
return convertSystemError(container.system.Modify(context.Background(), config), container)
}

35
vendor/github.com/Microsoft/hcsshim/go.mod generated vendored Normal file
View File

@ -0,0 +1,35 @@
module github.com/Microsoft/hcsshim
go 1.12
require (
github.com/Microsoft/go-winio v0.4.14
github.com/blang/semver v3.1.0+incompatible // indirect
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1
github.com/containerd/containerd v0.0.0-20190214164719-faec567304bb
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 // indirect
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3
github.com/containerd/ttrpc v0.0.0-20180920185216-2a805f718635
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
github.com/gogo/protobuf v1.2.1
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce // indirect
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874 // indirect
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 // indirect
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f // indirect
github.com/opencontainers/runtime-spec v0.0.0-20190207185410-29686dbc5559
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.4.1
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8 // indirect
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f // indirect
go.opencensus.io v0.22.0
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b
google.golang.org/grpc v1.20.1
gotest.tools v2.2.0+incompatible // indirect
k8s.io/kubernetes v1.13.0
)

View File

@ -39,11 +39,21 @@ func HNSListEndpointRequest() ([]HNSEndpoint, error) {
// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
func HotAttachEndpoint(containerID string, endpointID string) error {
endpoint, err := GetHNSEndpointByID(endpointID)
isAttached, err := endpoint.IsAttached(containerID)
if isAttached {
return err
}
return modifyNetworkEndpoint(containerID, endpointID, Add)
}
// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
func HotDetachEndpoint(containerID string, endpointID string) error {
endpoint, err := GetHNSEndpointByID(endpointID)
isAttached, err := endpoint.IsAttached(containerID)
if !isAttached {
return err
}
return modifyNetworkEndpoint(containerID, endpointID, Remove)
}

View File

@ -0,0 +1,80 @@
package cow
import (
"context"
"io"
"github.com/Microsoft/hcsshim/internal/schema1"
)
// Process is the interface for an OS process running in a container or utility VM.
type Process interface {
// Close releases resources associated with the process and closes the
// writer and readers returned by Stdio. Depending on the implementation,
// this may also terminate the process.
Close() error
// CloseStdin causes the process's stdin handle to receive EOF/EPIPE/whatever
// is appropriate to indicate that no more data is available.
CloseStdin(ctx context.Context) error
// Pid returns the process ID.
Pid() int
// Stdio returns the stdio streams for a process. These may be nil if a stream
// was not requested during CreateProcess.
Stdio() (_ io.Writer, _ io.Reader, _ io.Reader)
// ResizeConsole resizes the virtual terminal associated with the process.
ResizeConsole(ctx context.Context, width, height uint16) error
// Kill sends a SIGKILL or equivalent signal to the process and returns whether
// the signal was delivered. It does not wait for the process to terminate.
Kill(ctx context.Context) (bool, error)
// Signal sends a signal to the process and returns whether the signal was
// delivered. The input is OS specific (either
// guestrequest.SignalProcessOptionsWCOW or
// guestrequest.SignalProcessOptionsLCOW). It does not wait for the process
// to terminate.
Signal(ctx context.Context, options interface{}) (bool, error)
// Wait waits for the process to complete, or for a connection to the process to be
// terminated by some error condition (including calling Close).
Wait() error
// ExitCode returns the exit code of the process. Returns an error if the process is
// not running.
ExitCode() (int, error)
}
// ProcessHost is the interface for creating processes.
type ProcessHost interface {
// CreateProcess creates a process. The configuration is host specific
// (either hcsschema.ProcessParameters or lcow.ProcessParameters).
CreateProcess(ctx context.Context, config interface{}) (Process, error)
// OS returns the host's operating system, "linux" or "windows".
OS() string
// IsOCI specifies whether this is an OCI-compliant process host. If true,
// then the configuration passed to CreateProcess should have an OCI process
// spec (or nil if this is the initial process in an OCI container).
// Otherwise, it should have the HCS-specific process parameters.
IsOCI() bool
}
// Container is the interface for container objects, either running on the host or
// in a utility VM.
type Container interface {
ProcessHost
// Close releases the resources associated with the container. Depending on
// the implementation, this may also terminate the container.
Close() error
// ID returns the container ID.
ID() string
// Properties returns the requested container properties.
Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error)
// Start starts a container.
Start(ctx context.Context) error
// Shutdown sends a shutdown request to the container (but does not wait for
// the shutdown to complete).
Shutdown(ctx context.Context) error
// Terminate sends a terminate request to the container (but does not wait
// for the terminate to complete).
Terminate(ctx context.Context) error
// Wait waits for the container to terminate, or for the connection to the
// container to be terminated by some error condition (including calling
// Close).
Wait() error
}

View File

@ -1,100 +0,0 @@
package guestrequest
import (
"github.com/Microsoft/hcsshim/internal/schema2"
)
// Arguably, many of these (at least CombinedLayers) should have been generated
// by swagger.
//
// This will also change package name due to an inbound breaking change.
// This class is used by a modify request to add or remove a combined layers
// structure in the guest. For windows, the GCS applies a filter in ContainerRootPath
// using the specified layers as the parent content. Ignores property ScratchPath
// since the container path is already the scratch path. For linux, the GCS unions
// the specified layers and ScratchPath together, placing the resulting union
// filesystem at ContainerRootPath.
type CombinedLayers struct {
ContainerRootPath string `json:"ContainerRootPath,omitempty"`
Layers []hcsschema.Layer `json:"Layers,omitempty"`
ScratchPath string `json:"ScratchPath,omitempty"`
}
// Defines the schema for hosted settings passed to GCS and/or OpenGCS
// SCSI. Scratch space for remote file-system commands, or R/W layer for containers
type LCOWMappedVirtualDisk struct {
MountPath string `json:"MountPath,omitempty"` // /tmp/scratch for an LCOW utility VM being used as a service VM
Lun uint8 `json:"Lun,omitempty"`
Controller uint8 `json:"Controller,omitempty"`
ReadOnly bool `json:"ReadOnly,omitempty"`
}
type WCOWMappedVirtualDisk struct {
ContainerPath string `json:"ContainerPath,omitempty"`
Lun int32 `json:"Lun,omitempty"`
}
type LCOWMappedDirectory struct {
MountPath string `json:"MountPath,omitempty"`
Port int32 `json:"Port,omitempty"`
ShareName string `json:"ShareName,omitempty"` // If empty not using ANames (not currently supported)
ReadOnly bool `json:"ReadOnly,omitempty"`
}
// Read-only layers over VPMem
type LCOWMappedVPMemDevice struct {
DeviceNumber uint32 `json:"DeviceNumber,omitempty"`
MountPath string `json:"MountPath,omitempty"` // /tmp/pN
}
type LCOWNetworkAdapter struct {
NamespaceID string `json:",omitempty"`
ID string `json:",omitempty"`
MacAddress string `json:",omitempty"`
IPAddress string `json:",omitempty"`
PrefixLength uint8 `json:",omitempty"`
GatewayAddress string `json:",omitempty"`
DNSSuffix string `json:",omitempty"`
DNSServerList string `json:",omitempty"`
EnableLowMetric bool `json:",omitempty"`
EncapOverhead uint16 `json:",omitempty"`
}
type ResourceType string
const (
// These are constants for v2 schema modify guest requests.
ResourceTypeMappedDirectory ResourceType = "MappedDirectory"
ResourceTypeMappedVirtualDisk ResourceType = "MappedVirtualDisk"
ResourceTypeNetwork ResourceType = "Network"
ResourceTypeNetworkNamespace ResourceType = "NetworkNamespace"
ResourceTypeCombinedLayers ResourceType = "CombinedLayers"
ResourceTypeVPMemDevice ResourceType = "VPMemDevice"
)
// GuestRequest is for modify commands passed to the guest.
type GuestRequest struct {
RequestType string `json:"RequestType,omitempty"`
ResourceType ResourceType `json:"ResourceType,omitempty"`
Settings interface{} `json:"Settings,omitempty"`
}
type NetworkModifyRequest struct {
AdapterId string `json:"AdapterId,omitempty"`
RequestType string `json:"RequestType,omitempty"`
Settings interface{} `json:"Settings,omitempty"`
}
type RS4NetworkModifyRequest struct {
AdapterInstanceId string `json:"AdapterInstanceId,omitempty"`
RequestType string `json:"RequestType,omitempty"`
Settings interface{} `json:"Settings,omitempty"`
}
// SignalProcessOptions is the options passed to either WCOW or LCOW
// to signal a given process.
type SignalProcessOptions struct {
Signal int `json:,omitempty`
}

View File

@ -1,69 +0,0 @@
package guid
import (
"crypto/rand"
"encoding/json"
"fmt"
"io"
"strconv"
"strings"
)
var _ = (json.Marshaler)(&GUID{})
var _ = (json.Unmarshaler)(&GUID{})
type GUID [16]byte
func New() GUID {
g := GUID{}
_, err := io.ReadFull(rand.Reader, g[:])
if err != nil {
panic(err)
}
return g
}
func (g GUID) String() string {
return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x", g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], g[8:10], g[10:])
}
func FromString(s string) GUID {
if len(s) != 36 {
panic(fmt.Sprintf("invalid GUID length: %d", len(s)))
}
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
panic("invalid GUID format")
}
indexOrder := [16]int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34,
}
byteOrder := [16]int{
3, 2, 1, 0,
5, 4,
7, 6,
8, 9,
10, 11, 12, 13, 14, 15,
}
var g GUID
for i, x := range indexOrder {
b, err := strconv.ParseInt(s[x:x+2], 16, 16)
if err != nil {
panic(err)
}
g[byteOrder[i]] = byte(b)
}
return g
}
func (g GUID) MarshalJSON() ([]byte, error) {
return json.Marshal(g.String())
}
func (g *GUID) UnmarshalJSON(data []byte) error {
*g = FromString(strings.Trim(string(data), "\""))
return nil
}

View File

@ -1,10 +1,13 @@
package hcs
import (
"fmt"
"sync"
"syscall"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/vmcompute"
"github.com/sirupsen/logrus"
)
@ -40,35 +43,83 @@ var (
)
type hcsNotification uint32
func (hn hcsNotification) String() string {
switch hn {
case hcsNotificationSystemExited:
return "SystemExited"
case hcsNotificationSystemCreateCompleted:
return "SystemCreateCompleted"
case hcsNotificationSystemStartCompleted:
return "SystemStartCompleted"
case hcsNotificationSystemPauseCompleted:
return "SystemPauseCompleted"
case hcsNotificationSystemResumeCompleted:
return "SystemResumeCompleted"
case hcsNotificationSystemCrashReport:
return "SystemCrashReport"
case hcsNotificationSystemSiloJobCreated:
return "SystemSiloJobCreated"
case hcsNotificationSystemSaveCompleted:
return "SystemSaveCompleted"
case hcsNotificationSystemRdpEnhancedModeStateChanged:
return "SystemRdpEnhancedModeStateChanged"
case hcsNotificationSystemShutdownFailed:
return "SystemShutdownFailed"
case hcsNotificationSystemGetPropertiesCompleted:
return "SystemGetPropertiesCompleted"
case hcsNotificationSystemModifyCompleted:
return "SystemModifyCompleted"
case hcsNotificationSystemCrashInitiated:
return "SystemCrashInitiated"
case hcsNotificationSystemGuestConnectionClosed:
return "SystemGuestConnectionClosed"
case hcsNotificationProcessExited:
return "ProcessExited"
case hcsNotificationInvalid:
return "Invalid"
case hcsNotificationServiceDisconnect:
return "ServiceDisconnect"
default:
return fmt.Sprintf("Unknown: %d", hn)
}
}
type notificationChannel chan error
type notifcationWatcherContext struct {
channels notificationChannels
handle hcsCallback
handle vmcompute.HcsCallback
systemID string
processID int
}
type notificationChannels map[hcsNotification]notificationChannel
func newChannels() notificationChannels {
func newSystemChannels() notificationChannels {
channels := make(notificationChannels)
for _, notif := range []hcsNotification{
hcsNotificationServiceDisconnect,
hcsNotificationSystemExited,
hcsNotificationSystemCreateCompleted,
hcsNotificationSystemStartCompleted,
hcsNotificationSystemPauseCompleted,
hcsNotificationSystemResumeCompleted,
} {
channels[notif] = make(notificationChannel, 1)
}
return channels
}
channels[hcsNotificationSystemExited] = make(notificationChannel, 1)
channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1)
channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
channels[hcsNotificationServiceDisconnect] = make(notificationChannel, 1)
channels[hcsNotificationSystemCrashReport] = make(notificationChannel, 1)
channels[hcsNotificationSystemSiloJobCreated] = make(notificationChannel, 1)
channels[hcsNotificationSystemSaveCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemRdpEnhancedModeStateChanged] = make(notificationChannel, 1)
channels[hcsNotificationSystemShutdownFailed] = make(notificationChannel, 1)
channels[hcsNotificationSystemGetPropertiesCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemModifyCompleted] = make(notificationChannel, 1)
channels[hcsNotificationSystemCrashInitiated] = make(notificationChannel, 1)
channels[hcsNotificationSystemGuestConnectionClosed] = make(notificationChannel, 1)
func newProcessChannels() notificationChannels {
channels := make(notificationChannels)
for _, notif := range []hcsNotification{
hcsNotificationServiceDisconnect,
hcsNotificationProcessExited,
} {
channels[notif] = make(notificationChannel, 1)
}
return channels
}
@ -92,12 +143,17 @@ func notificationWatcher(notificationType hcsNotification, callbackNumber uintpt
return 0
}
log := logrus.WithFields(logrus.Fields{
"notification-type": notificationType.String(),
"system-id": context.systemID,
})
if context.processID != 0 {
log.Data[logfields.ProcessID] = context.processID
}
log.Debug("HCS notification")
if channel, ok := context.channels[notificationType]; ok {
channel <- result
} else {
logrus.WithFields(logrus.Fields{
"notification-type": notificationType,
}).Warn("Received a callback of an unsupported type")
}
return 0

View File

@ -1,14 +1,14 @@
package hcs
import (
"context"
"encoding/json"
"errors"
"fmt"
"net"
"syscall"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/sirupsen/logrus"
"github.com/Microsoft/hcsshim/internal/log"
)
var (
@ -117,17 +117,11 @@ func (ev *ErrorEvent) String() string {
return evs
}
func processHcsResult(resultp *uint16) []ErrorEvent {
if resultp != nil {
resultj := interop.ConvertAndFreeCoTaskMemString(resultp)
logrus.WithField(logfields.JSON, resultj).
Debug("HCS Result")
func processHcsResult(ctx context.Context, resultJSON string) []ErrorEvent {
if resultJSON != "" {
result := &hcsResult{}
if err := json.Unmarshal([]byte(resultj), result); err != nil {
logrus.WithFields(logrus.Fields{
logfields.JSON: resultj,
logrus.ErrorKey: err,
}).Warning("Could not unmarshal HCS result")
if err := json.Unmarshal([]byte(resultJSON), result); err != nil {
log.G(ctx).WithError(err).Warning("Could not unmarshal HCS result")
return nil
}
return result.ErrorEvents
@ -141,6 +135,8 @@ type HcsError struct {
Events []ErrorEvent
}
var _ net.Error = &HcsError{}
func (e *HcsError) Error() string {
s := e.Op + ": " + e.Err.Error()
for _, ev := range e.Events {
@ -149,6 +145,16 @@ func (e *HcsError) Error() string {
return s
}
func (e *HcsError) Temporary() bool {
err, ok := e.Err.(net.Error)
return ok && err.Temporary()
}
func (e *HcsError) Timeout() bool {
err, ok := e.Err.(net.Error)
return ok && err.Timeout()
}
// ProcessError is an error encountered in HCS during an operation on a Process object
type ProcessError struct {
SystemID string
@ -158,6 +164,8 @@ type ProcessError struct {
Events []ErrorEvent
}
var _ net.Error = &ProcessError{}
// SystemError is an error encountered in HCS during an operation on a Container object
type SystemError struct {
ID string
@ -167,6 +175,8 @@ type SystemError struct {
Events []ErrorEvent
}
var _ net.Error = &SystemError{}
func (e *SystemError) Error() string {
s := e.Op + " " + e.ID + ": " + e.Err.Error()
for _, ev := range e.Events {
@ -178,6 +188,16 @@ func (e *SystemError) Error() string {
return s
}
func (e *SystemError) Temporary() bool {
err, ok := e.Err.(net.Error)
return ok && err.Temporary()
}
func (e *SystemError) Timeout() bool {
err, ok := e.Err.(net.Error)
return ok && err.Timeout()
}
func makeSystemError(system *System, op string, extra string, err error, events []ErrorEvent) error {
// Don't double wrap errors
if _, ok := err.(*SystemError); ok {
@ -200,6 +220,16 @@ func (e *ProcessError) Error() string {
return s
}
func (e *ProcessError) Temporary() bool {
err, ok := e.Err.(net.Error)
return ok && err.Temporary()
}
func (e *ProcessError) Timeout() bool {
err, ok := e.Err.(net.Error)
return ok && err.Timeout()
}
func makeProcessError(process *Process, op string, err error, events []ErrorEvent) error {
// Don't double wrap errors
if _, ok := err.(*ProcessError); ok {
@ -242,6 +272,9 @@ func IsPending(err error) bool {
// IsTimeout returns a boolean indicating whether the error is caused by
// a timeout waiting for the operation to complete.
func IsTimeout(err error) bool {
if err, ok := err.(net.Error); ok && err.Timeout() {
return true
}
err = getInnerError(err)
return err == ErrTimeout
}
@ -272,6 +305,13 @@ func IsNotSupported(err error) bool {
err == ErrVmcomputeUnknownMessage
}
// IsOperationInvalidState returns true when err is caused by
// `ErrVmcomputeOperationInvalidState`.
func IsOperationInvalidState(err error) bool {
err = getInnerError(err)
return err == ErrVmcomputeOperationInvalidState
}
func getInnerError(err error) error {
switch pe := err.(type) {
case nil:
@ -285,3 +325,12 @@ func getInnerError(err error) error {
}
return err
}
func getOperationLogResult(err error) (string, error) {
switch err {
case nil:
return "Success", nil
default:
return "Error", err
}
}

View File

@ -1,48 +0,0 @@
// Shim for the Host Compute Service (HCS) to manage Windows Server
// containers and Hyper-V containers.
package hcs
import (
"syscall"
)
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go hcs.go
//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
//sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
//sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
//sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
//sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
//sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
//sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
//sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
//sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
//sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
//sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
//sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
//sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
//sys hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
//sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
//sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
type hcsSystem syscall.Handle
type hcsProcess syscall.Handle
type hcsCallback syscall.Handle
type hcsProcessInformation struct {
ProcessId uint32
Reserved uint32
StdInput syscall.Handle
StdOutput syscall.Handle
StdError syscall.Handle
}

View File

@ -1,20 +0,0 @@
package hcs
import "github.com/sirupsen/logrus"
func logOperationBegin(ctx logrus.Fields, msg string) {
logrus.WithFields(ctx).Debug(msg)
}
func logOperationEnd(ctx logrus.Fields, msg string, err error) {
// Copy the log and fields first.
log := logrus.WithFields(ctx)
if err == nil {
log.Debug(msg)
} else {
// Edit only the copied field data to avoid race conditions on the
// write.
log.Data[logrus.ErrorKey] = err
log.Error(msg)
}
}

View File

@ -1,52 +1,45 @@
package hcs
import (
"context"
"encoding/json"
"io"
"sync"
"syscall"
"time"
"github.com/Microsoft/hcsshim/internal/guestrequest"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/sirupsen/logrus"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/vmcompute"
"go.opencensus.io/trace"
)
// ContainerError is an error encountered in HCS
type Process struct {
handleLock sync.RWMutex
handle hcsProcess
handle vmcompute.HcsProcess
processID int
system *System
cachedPipes *cachedPipes
stdin io.WriteCloser
stdout io.ReadCloser
stderr io.ReadCloser
callbackNumber uintptr
logctx logrus.Fields
waitBlock chan struct{}
waitError error
closedWaitOnce sync.Once
waitBlock chan struct{}
exitCode int
waitError error
}
func newProcess(process hcsProcess, processID int, computeSystem *System) *Process {
func newProcess(process vmcompute.HcsProcess, processID int, computeSystem *System) *Process {
return &Process{
handle: process,
processID: processID,
system: computeSystem,
logctx: logrus.Fields{
logfields.ContainerID: computeSystem.ID(),
logfields.ProcessID: processID,
},
waitBlock: make(chan struct{}),
}
}
type cachedPipes struct {
stdIn syscall.Handle
stdOut syscall.Handle
stdErr syscall.Handle
}
type processModifyRequest struct {
Operation string
ConsoleSize *consoleSize `json:",omitempty"`
@ -62,7 +55,7 @@ type closeHandle struct {
Handle string
}
type ProcessStatus struct {
type processStatus struct {
ProcessID uint32
Exited bool
ExitCode uint32
@ -90,134 +83,153 @@ func (process *Process) SystemID() string {
return process.system.ID()
}
func (process *Process) logOperationBegin(operation string) {
logOperationBegin(
process.logctx,
operation+" - Begin Operation")
}
func (process *Process) logOperationEnd(operation string, err error) {
var result string
if err == nil {
result = "Success"
} else {
result = "Error"
func (process *Process) processSignalResult(ctx context.Context, err error) (bool, error) {
switch err {
case nil:
return true, nil
case ErrVmcomputeOperationInvalidState, ErrComputeSystemDoesNotExist, ErrElementNotFound:
select {
case <-process.waitBlock:
// The process exit notification has already arrived.
default:
// The process should be gone, but we have not received the notification.
// After a second, force unblock the process wait to work around a possible
// deadlock in the HCS.
go func() {
time.Sleep(time.Second)
process.closedWaitOnce.Do(func() {
log.G(ctx).WithError(err).Warn("force unblocking process waits")
process.exitCode = -1
process.waitError = err
close(process.waitBlock)
})
}()
}
return false, nil
default:
return false, err
}
logOperationEnd(
process.logctx,
operation+" - End Operation - "+result,
err)
}
// Signal signals the process with `options`.
func (process *Process) Signal(options guestrequest.SignalProcessOptions) (err error) {
//
// For LCOW `guestrequest.SignalProcessOptionsLCOW`.
//
// For WCOW `guestrequest.SignalProcessOptionsWCOW`.
func (process *Process) Signal(ctx context.Context, options interface{}) (bool, error) {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Signal"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil)
return false, makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
optionsb, err := json.Marshal(options)
if err != nil {
return err
return false, err
}
optionsStr := string(optionsb)
var resultp *uint16
syscallWatcher(process.logctx, func() {
err = hcsSignalProcess(process.handle, optionsStr, &resultp)
})
events := processHcsResult(resultp)
resultJSON, err := vmcompute.HcsSignalProcess(ctx, process.handle, string(optionsb))
events := processHcsResult(ctx, resultJSON)
delivered, err := process.processSignalResult(ctx, err)
if err != nil {
return makeProcessError(process, operation, err, events)
err = makeProcessError(process, operation, err, events)
}
return nil
return delivered, err
}
// Kill signals the process to terminate but does not wait for it to finish terminating.
func (process *Process) Kill() (err error) {
func (process *Process) Kill(ctx context.Context) (bool, error) {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Kill"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil)
return false, makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
var resultp *uint16
syscallWatcher(process.logctx, func() {
err = hcsTerminateProcess(process.handle, &resultp)
})
events := processHcsResult(resultp)
resultJSON, err := vmcompute.HcsTerminateProcess(ctx, process.handle)
events := processHcsResult(ctx, resultJSON)
delivered, err := process.processSignalResult(ctx, err)
if err != nil {
return makeProcessError(process, operation, err, events)
err = makeProcessError(process, operation, err, events)
}
return nil
return delivered, err
}
// waitBackground waits for the process exit notification. Once received sets
// `process.waitError` (if any) and unblocks all `Wait` and `WaitTimeout` calls.
// `process.waitError` (if any) and unblocks all `Wait` calls.
//
// This MUST be called exactly once per `process.handle` but `Wait` and
// `WaitTimeout` are safe to call multiple times.
// This MUST be called exactly once per `process.handle` but `Wait` is safe to
// call multiple times.
func (process *Process) waitBackground() {
process.waitError = waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
close(process.waitBlock)
operation := "hcsshim::Process::waitBackground"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
var (
err error
exitCode = -1
)
err = waitForNotification(ctx, process.callbackNumber, hcsNotificationProcessExited, nil)
if err != nil {
err = makeProcessError(process, operation, err, nil)
log.G(ctx).WithError(err).Error("failed wait")
} else {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
// Make sure we didnt race with Close() here
if process.handle != 0 {
propertiesJSON, resultJSON, err := vmcompute.HcsGetProcessProperties(ctx, process.handle)
events := processHcsResult(ctx, resultJSON)
if err != nil {
err = makeProcessError(process, operation, err, events)
} else {
properties := &processStatus{}
err = json.Unmarshal([]byte(propertiesJSON), properties)
if err != nil {
err = makeProcessError(process, operation, err, nil)
} else {
if properties.LastWaitResult != 0 {
log.G(ctx).WithField("wait-result", properties.LastWaitResult).Warning("non-zero last wait result")
} else {
exitCode = int(properties.ExitCode)
}
}
}
}
}
log.G(ctx).WithField("exitCode", exitCode).Debug("process exited")
process.closedWaitOnce.Do(func() {
process.exitCode = exitCode
process.waitError = err
close(process.waitBlock)
})
oc.SetSpanStatus(span, err)
}
// Wait waits for the process to exit. If the process has already exited returns
// the pervious error (if any).
func (process *Process) Wait() (err error) {
operation := "hcsshim::Process::Wait"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
func (process *Process) Wait() error {
<-process.waitBlock
if process.waitError != nil {
return makeProcessError(process, operation, err, nil)
}
return nil
}
// WaitTimeout waits for the process to exit or the duration to elapse. If the
// process has already exited returns the pervious error (if any). If a timeout
// occurs returns `ErrTimeout`.
func (process *Process) WaitTimeout(timeout time.Duration) (err error) {
operation := "hcssshim::Process::WaitTimeout"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
select {
case <-process.waitBlock:
if process.waitError != nil {
return makeProcessError(process, operation, process.waitError, nil)
}
return nil
case <-time.After(timeout):
return makeProcessError(process, operation, ErrTimeout, nil)
}
return process.waitError
}
// ResizeConsole resizes the console of the process.
func (process *Process) ResizeConsole(width, height uint16) (err error) {
func (process *Process) ResizeConsole(ctx context.Context, width, height uint16) error {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::ResizeConsole"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil)
@ -236,11 +248,8 @@ func (process *Process) ResizeConsole(width, height uint16) (err error) {
return err
}
modifyRequestStr := string(modifyRequestb)
var resultp *uint16
err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
events := processHcsResult(resultp)
resultJSON, err := vmcompute.HcsModifyProcess(ctx, process.handle, string(modifyRequestb))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return makeProcessError(process, operation, err, events)
}
@ -248,109 +257,46 @@ func (process *Process) ResizeConsole(width, height uint16) (err error) {
return nil
}
func (process *Process) Properties() (_ *ProcessStatus, err error) {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Properties"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
var (
resultp *uint16
propertiesp *uint16
)
syscallWatcher(process.logctx, func() {
err = hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
})
events := processHcsResult(resultp)
if err != nil {
return nil, makeProcessError(process, operation, err, events)
}
if propertiesp == nil {
return nil, ErrUnexpectedValue
}
propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
properties := &ProcessStatus{}
if err := json.Unmarshal(propertiesRaw, properties); err != nil {
return nil, makeProcessError(process, operation, err, nil)
}
return properties, nil
}
// ExitCode returns the exit code of the process. The process must have
// already terminated.
func (process *Process) ExitCode() (_ int, err error) {
operation := "hcsshim::Process::ExitCode"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
properties, err := process.Properties()
if err != nil {
return -1, makeProcessError(process, operation, err, nil)
func (process *Process) ExitCode() (int, error) {
select {
case <-process.waitBlock:
if process.waitError != nil {
return -1, process.waitError
}
return process.exitCode, nil
default:
return -1, makeProcessError(process, "hcsshim::Process::ExitCode", ErrInvalidProcessState, nil)
}
if properties.Exited == false {
return -1, makeProcessError(process, operation, ErrInvalidProcessState, nil)
}
if properties.LastWaitResult != 0 {
logrus.WithFields(logrus.Fields{
logfields.ContainerID: process.SystemID(),
logfields.ProcessID: process.processID,
"wait-result": properties.LastWaitResult,
}).Warn("hcsshim::Process::ExitCode - Non-zero last wait result")
return -1, nil
}
return int(properties.ExitCode), nil
}
// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
// these pipes does not close the underlying pipes; it should be possible to
// call this multiple times to get multiple interfaces.
func (process *Process) Stdio() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
// StdioLegacy returns the stdin, stdout, and stderr pipes, respectively. Closing
// these pipes does not close the underlying pipes; but this function can only
// be called once on each Process.
func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
operation := "hcsshim::Process::StdioLegacy"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Stdio"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return nil, nil, nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
var stdIn, stdOut, stdErr syscall.Handle
if process.cachedPipes == nil {
var (
processInfo hcsProcessInformation
resultp *uint16
)
err = hcsGetProcessInfo(process.handle, &processInfo, &resultp)
events := processHcsResult(resultp)
if err != nil {
return nil, nil, nil, makeProcessError(process, operation, err, events)
}
stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError
} else {
// Use cached pipes
stdIn, stdOut, stdErr = process.cachedPipes.stdIn, process.cachedPipes.stdOut, process.cachedPipes.stdErr
// Invalidate the cache
process.cachedPipes = nil
processInfo, resultJSON, err := vmcompute.HcsGetProcessInfo(ctx, process.handle)
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, nil, nil, makeProcessError(process, operation, err, events)
}
pipes, err := makeOpenFiles([]syscall.Handle{stdIn, stdOut, stdErr})
pipes, err := makeOpenFiles([]syscall.Handle{processInfo.StdInput, processInfo.StdOutput, processInfo.StdError})
if err != nil {
return nil, nil, nil, makeProcessError(process, operation, err, nil)
}
@ -358,15 +304,19 @@ func (process *Process) Stdio() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadClo
return pipes[0], pipes[1], pipes[2], nil
}
// Stdio returns the stdin, stdout, and stderr pipes, respectively.
// To close them, close the process handle.
func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) {
return process.stdin, process.stdout, process.stderr
}
// CloseStdin closes the write side of the stdin pipe so that the process is
// notified on the read side that there is no more data in stdin.
func (process *Process) CloseStdin() (err error) {
func (process *Process) CloseStdin(ctx context.Context) error {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::CloseStdin"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil)
@ -384,93 +334,113 @@ func (process *Process) CloseStdin() (err error) {
return err
}
modifyRequestStr := string(modifyRequestb)
var resultp *uint16
err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
events := processHcsResult(resultp)
resultJSON, err := vmcompute.HcsModifyProcess(ctx, process.handle, string(modifyRequestb))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return makeProcessError(process, operation, err, events)
}
if process.stdin != nil {
process.stdin.Close()
}
return nil
}
// Close cleans up any state associated with the process but does not kill
// or wait on it.
func (process *Process) Close() (err error) {
operation := "hcsshim::Process::Close"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
process.handleLock.Lock()
defer process.handleLock.Unlock()
operation := "hcsshim::Process::Close"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
// Don't double free this
if process.handle == 0 {
return nil
}
if err = process.unregisterCallback(); err != nil {
if process.stdin != nil {
process.stdin.Close()
}
if process.stdout != nil {
process.stdout.Close()
}
if process.stderr != nil {
process.stderr.Close()
}
if err = process.unregisterCallback(ctx); err != nil {
return makeProcessError(process, operation, err, nil)
}
if err = hcsCloseProcess(process.handle); err != nil {
if err = vmcompute.HcsCloseProcess(ctx, process.handle); err != nil {
return makeProcessError(process, operation, err, nil)
}
process.handle = 0
process.closedWaitOnce.Do(func() {
process.exitCode = -1
process.waitError = ErrAlreadyClosed
close(process.waitBlock)
})
return nil
}
func (process *Process) registerCallback() error {
context := &notifcationWatcherContext{
channels: newChannels(),
func (process *Process) registerCallback(ctx context.Context) error {
callbackContext := &notifcationWatcherContext{
channels: newProcessChannels(),
systemID: process.SystemID(),
processID: process.processID,
}
callbackMapLock.Lock()
callbackNumber := nextCallback
nextCallback++
callbackMap[callbackNumber] = context
callbackMap[callbackNumber] = callbackContext
callbackMapLock.Unlock()
var callbackHandle hcsCallback
err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
callbackHandle, err := vmcompute.HcsRegisterProcessCallback(ctx, process.handle, notificationWatcherCallback, callbackNumber)
if err != nil {
return err
}
context.handle = callbackHandle
callbackContext.handle = callbackHandle
process.callbackNumber = callbackNumber
return nil
}
func (process *Process) unregisterCallback() error {
func (process *Process) unregisterCallback(ctx context.Context) error {
callbackNumber := process.callbackNumber
callbackMapLock.RLock()
context := callbackMap[callbackNumber]
callbackContext := callbackMap[callbackNumber]
callbackMapLock.RUnlock()
if context == nil {
if callbackContext == nil {
return nil
}
handle := context.handle
handle := callbackContext.handle
if handle == 0 {
return nil
}
// hcsUnregisterProcessCallback has its own syncronization
// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
err := hcsUnregisterProcessCallback(handle)
// vmcompute.HcsUnregisterProcessCallback has its own synchronization to
// wait for all callbacks to complete. We must NOT hold the callbackMapLock.
err := vmcompute.HcsUnregisterProcessCallback(ctx, handle)
if err != nil {
return err
}
closeChannels(context.channels)
closeChannels(callbackContext.channels)
callbackMapLock.Lock()
delete(callbackMap, callbackNumber)

View File

@ -1,18 +1,23 @@
package hcs
import (
"context"
"encoding/json"
"errors"
"os"
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/cow"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/schema1"
"github.com/Microsoft/hcsshim/internal/timeout"
"github.com/sirupsen/logrus"
"github.com/Microsoft/hcsshim/internal/vmcompute"
"go.opencensus.io/trace"
)
// currentContainerStarts is used to limit the number of concurrent container
@ -38,53 +43,37 @@ func init() {
type System struct {
handleLock sync.RWMutex
handle hcsSystem
handle vmcompute.HcsSystem
id string
callbackNumber uintptr
logctx logrus.Fields
closedWaitOnce sync.Once
waitBlock chan struct{}
waitError error
exitError error
waitBlock chan struct{}
waitError error
os, typ string
}
func newSystem(id string) *System {
return &System{
id: id,
logctx: logrus.Fields{
logfields.ContainerID: id,
},
id: id,
waitBlock: make(chan struct{}),
}
}
func (computeSystem *System) logOperationBegin(operation string) {
logOperationBegin(
computeSystem.logctx,
operation+" - Begin Operation")
}
func (computeSystem *System) logOperationEnd(operation string, err error) {
var result string
if err == nil {
result = "Success"
} else {
result = "Error"
}
logOperationEnd(
computeSystem.logctx,
operation+" - End Operation - "+result,
err)
}
// CreateComputeSystem creates a new compute system with the given configuration but does not start it.
func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (_ *System, err error) {
func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface interface{}) (_ *System, err error) {
operation := "hcsshim::CreateComputeSystem"
// hcsCreateComputeSystemContext is an async operation. Start the outer span
// here to measure the full create time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", id))
computeSystem := newSystem(id)
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
hcsDocumentB, err := json.Marshal(hcsDocumentInterface)
if err != nil {
@ -93,129 +82,114 @@ func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (_ *System
hcsDocument := string(hcsDocumentB)
logrus.WithFields(computeSystem.logctx).
WithField(logfields.JSON, hcsDocument).
Debug("HCS ComputeSystem Document")
var (
resultp *uint16
identity syscall.Handle
resultJSON string
createError error
)
syscallWatcher(computeSystem.logctx, func() {
createError = hcsCreateComputeSystem(id, hcsDocument, identity, &computeSystem.handle, &resultp)
})
computeSystem.handle, resultJSON, createError = vmcompute.HcsCreateComputeSystem(ctx, id, hcsDocument, identity)
if createError == nil || IsPending(createError) {
if err = computeSystem.registerCallback(); err != nil {
defer func() {
if err != nil {
computeSystem.Close()
}
}()
if err = computeSystem.registerCallback(ctx); err != nil {
// Terminate the compute system if it still exists. We're okay to
// ignore a failure here.
computeSystem.Terminate()
computeSystem.Terminate(ctx)
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
}
events, err := processAsyncHcsResult(createError, resultp, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.SystemCreate)
events, err := processAsyncHcsResult(ctx, createError, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.SystemCreate)
if err != nil {
if err == ErrTimeout {
// Terminate the compute system if it still exists. We're okay to
// ignore a failure here.
computeSystem.Terminate()
computeSystem.Terminate(ctx)
}
return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events)
}
go computeSystem.waitBackground()
if err = computeSystem.getCachedProperties(ctx); err != nil {
return nil, err
}
return computeSystem, nil
}
// OpenComputeSystem opens an existing compute system by ID.
func OpenComputeSystem(id string) (_ *System, err error) {
func OpenComputeSystem(ctx context.Context, id string) (*System, error) {
operation := "hcsshim::OpenComputeSystem"
computeSystem := newSystem(id)
computeSystem.logOperationBegin(operation)
defer func() {
if IsNotExist(err) {
computeSystem.logOperationEnd(operation, nil)
} else {
computeSystem.logOperationEnd(operation, err)
}
}()
var (
handle hcsSystem
resultp *uint16
)
err = hcsOpenComputeSystem(id, &handle, &resultp)
events := processHcsResult(resultp)
handle, resultJSON, err := vmcompute.HcsOpenComputeSystem(ctx, id)
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, events)
}
computeSystem.handle = handle
if err = computeSystem.registerCallback(); err != nil {
defer func() {
if err != nil {
computeSystem.Close()
}
}()
if err = computeSystem.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
go computeSystem.waitBackground()
if err = computeSystem.getCachedProperties(ctx); err != nil {
return nil, err
}
return computeSystem, nil
}
func (computeSystem *System) getCachedProperties(ctx context.Context) error {
props, err := computeSystem.Properties(ctx)
if err != nil {
return err
}
computeSystem.typ = strings.ToLower(props.SystemType)
computeSystem.os = strings.ToLower(props.RuntimeOSType)
if computeSystem.os == "" && computeSystem.typ == "container" {
// Pre-RS5 HCS did not return the OS, but it only supported containers
// that ran Windows.
computeSystem.os = "windows"
}
return nil
}
// OS returns the operating system of the compute system, "linux" or "windows".
func (computeSystem *System) OS() string {
return computeSystem.os
}
// IsOCI returns whether processes in the compute system should be created via
// OCI.
func (computeSystem *System) IsOCI() bool {
return computeSystem.os == "linux" && computeSystem.typ == "container"
}
// GetComputeSystems gets a list of the compute systems on the system that match the query
func GetComputeSystems(q schema1.ComputeSystemQuery) (_ []schema1.ContainerProperties, err error) {
func GetComputeSystems(ctx context.Context, q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) {
operation := "hcsshim::GetComputeSystems"
fields := logrus.Fields{}
logOperationBegin(
fields,
operation+" - Begin Operation")
defer func() {
var result string
if err == nil {
result = "Success"
} else {
result = "Error"
}
logOperationEnd(
fields,
operation+" - End Operation - "+result,
err)
}()
queryb, err := json.Marshal(q)
if err != nil {
return nil, err
}
query := string(queryb)
logrus.WithFields(fields).
WithField(logfields.JSON, query).
Debug("HCS ComputeSystem Query")
var (
resultp *uint16
computeSystemsp *uint16
)
syscallWatcher(fields, func() {
err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
})
events := processHcsResult(resultp)
computeSystemsJSON, resultJSON, err := vmcompute.HcsEnumerateComputeSystems(ctx, string(queryb))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, &HcsError{Op: operation, Err: err, Events: events}
}
if computeSystemsp == nil {
if computeSystemsJSON == "" {
return nil, ErrUnexpectedValue
}
computeSystemsRaw := interop.ConvertAndFreeCoTaskMemBytes(computeSystemsp)
computeSystems := []schema1.ContainerProperties{}
if err = json.Unmarshal(computeSystemsRaw, &computeSystems); err != nil {
if err = json.Unmarshal([]byte(computeSystemsJSON), &computeSystems); err != nil {
return nil, err
}
@ -223,16 +197,21 @@ func GetComputeSystems(q schema1.ComputeSystemQuery) (_ []schema1.ContainerPrope
}
// Start synchronously starts the computeSystem.
func (computeSystem *System) Start() (err error) {
func (computeSystem *System) Start(ctx context.Context) (err error) {
operation := "hcsshim::System::Start"
// hcsStartComputeSystemContext is an async operation. Start the outer span
// here to measure the full start time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Start"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Start", "", ErrAlreadyClosed, nil)
return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
}
// This is a very simple backoff-retry loop to limit the number
@ -261,13 +240,10 @@ func (computeSystem *System) Start() (err error) {
}()
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsStartComputeSystem(computeSystem.handle, "", &resultp)
})
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart)
resultJSON, err := vmcompute.HcsStartComputeSystem(ctx, computeSystem.handle, "")
events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart)
if err != nil {
return makeSystemError(computeSystem, "Start", "", err, events)
return makeSystemError(computeSystem, operation, "", err, events)
}
return nil
@ -278,270 +254,258 @@ func (computeSystem *System) ID() string {
return computeSystem.id
}
// Shutdown requests a compute system shutdown, if IsPending() on the error returned is true,
// it may not actually be shut down until Wait() succeeds.
func (computeSystem *System) Shutdown() (err error) {
// Shutdown requests a compute system shutdown.
func (computeSystem *System) Shutdown(ctx context.Context) error {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Shutdown"
computeSystem.logOperationBegin(operation)
defer func() {
if IsAlreadyStopped(err) || IsPending(err) {
computeSystem.logOperationEnd(operation, nil)
} else {
computeSystem.logOperationEnd(operation, err)
}
}()
operation := "hcsshim::System::Shutdown"
if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Shutdown", "", ErrAlreadyClosed, nil)
return nil
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsShutdownComputeSystem(computeSystem.handle, "", &resultp)
})
events := processHcsResult(resultp)
if err != nil {
return makeSystemError(computeSystem, "Shutdown", "", err, events)
resultJSON, err := vmcompute.HcsShutdownComputeSystem(ctx, computeSystem.handle, "")
events := processHcsResult(ctx, resultJSON)
switch err {
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
default:
return makeSystemError(computeSystem, operation, "", err, events)
}
return nil
}
// Terminate requests a compute system terminate, if IsPending() on the error returned is true,
// it may not actually be shut down until Wait() succeeds.
func (computeSystem *System) Terminate() (err error) {
// Terminate requests a compute system terminate.
func (computeSystem *System) Terminate(ctx context.Context) error {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Terminate"
computeSystem.logOperationBegin(operation)
defer func() {
if IsPending(err) {
computeSystem.logOperationEnd(operation, nil)
} else {
computeSystem.logOperationEnd(operation, err)
}
}()
operation := "hcsshim::System::Terminate"
if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Terminate", "", ErrAlreadyClosed, nil)
return nil
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsTerminateComputeSystem(computeSystem.handle, "", &resultp)
})
events := processHcsResult(resultp)
if err != nil && err != ErrVmcomputeAlreadyStopped {
return makeSystemError(computeSystem, "Terminate", "", err, events)
resultJSON, err := vmcompute.HcsTerminateComputeSystem(ctx, computeSystem.handle, "")
events := processHcsResult(ctx, resultJSON)
switch err {
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
default:
return makeSystemError(computeSystem, operation, "", err, events)
}
return nil
}
// waitBackground waits for the compute system exit notification. Once received
// sets `computeSystem.waitError` (if any) and unblocks all `Wait`,
// `WaitExpectedError`, and `WaitTimeout` calls.
// sets `computeSystem.waitError` (if any) and unblocks all `Wait` calls.
//
// This MUST be called exactly once per `computeSystem.handle` but `Wait`,
// `WaitExpectedError`, and `WaitTimeout` are safe to call multiple times.
// This MUST be called exactly once per `computeSystem.handle` but `Wait` is
// safe to call multiple times.
func (computeSystem *System) waitBackground() {
computeSystem.waitError = waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
close(computeSystem.waitBlock)
operation := "hcsshim::System::waitBackground"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
switch err {
case nil:
log.G(ctx).Debug("system exited")
case ErrVmcomputeUnexpectedExit:
log.G(ctx).Debug("unexpected system exit")
computeSystem.exitError = makeSystemError(computeSystem, operation, "", err, nil)
err = nil
default:
err = makeSystemError(computeSystem, operation, "", err, nil)
}
computeSystem.closedWaitOnce.Do(func() {
computeSystem.waitError = err
close(computeSystem.waitBlock)
})
oc.SetSpanStatus(span, err)
}
// Wait synchronously waits for the compute system to shutdown or terminate. If
// the compute system has already exited returns the previous error (if any).
func (computeSystem *System) Wait() (err error) {
operation := "hcsshim::ComputeSystem::Wait"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
func (computeSystem *System) Wait() error {
<-computeSystem.waitBlock
if computeSystem.waitError != nil {
return makeSystemError(computeSystem, "Wait", "", computeSystem.waitError, nil)
}
return nil
return computeSystem.waitError
}
// WaitExpectedError synchronously waits for the compute system to shutdown or
// terminate and returns the error (if any) as long as it does not match
// `expected`. If the compute system has already exited returns the previous
// error (if any) as long as it does not match `expected`.
func (computeSystem *System) WaitExpectedError(expected error) (err error) {
operation := "hcsshim::ComputeSystem::WaitExpectedError"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
<-computeSystem.waitBlock
if computeSystem.waitError != nil && getInnerError(computeSystem.waitError) != expected {
return makeSystemError(computeSystem, "WaitExpectedError", "", computeSystem.waitError, nil)
}
return nil
}
// WaitTimeout synchronously waits for the compute system to terminate or the
// duration to elapse. If the timeout expires, `IsTimeout(err) == true`. If
// the compute system has already exited returns the previous error (if any).
func (computeSystem *System) WaitTimeout(timeout time.Duration) (err error) {
operation := "hcsshim::ComputeSystem::WaitTimeout"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
// ExitError returns an error describing the reason the compute system terminated.
func (computeSystem *System) ExitError() error {
select {
case <-computeSystem.waitBlock:
if computeSystem.waitError != nil {
return makeSystemError(computeSystem, "WaitTimeout", "", computeSystem.waitError, nil)
return computeSystem.waitError
}
return nil
case <-time.After(timeout):
return makeSystemError(computeSystem, "WaitTimeout", "", ErrTimeout, nil)
return computeSystem.exitError
default:
return errors.New("container not exited")
}
}
func (computeSystem *System) Properties(types ...schema1.PropertyType) (_ *schema1.ContainerProperties, err error) {
func (computeSystem *System) Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error) {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Properties"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
operation := "hcsshim::System::Properties"
queryj, err := json.Marshal(schema1.PropertyQuery{types})
queryBytes, err := json.Marshal(schema1.PropertyQuery{PropertyTypes: types})
if err != nil {
return nil, makeSystemError(computeSystem, "Properties", "", err, nil)
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
logrus.WithFields(computeSystem.logctx).
WithField(logfields.JSON, queryj).
Debug("HCS ComputeSystem Properties Query")
var resultp, propertiesp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsGetComputeSystemProperties(computeSystem.handle, string(queryj), &propertiesp, &resultp)
})
events := processHcsResult(resultp)
propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, makeSystemError(computeSystem, "Properties", "", err, events)
return nil, makeSystemError(computeSystem, operation, "", err, events)
}
if propertiesp == nil {
if propertiesJSON == "" {
return nil, ErrUnexpectedValue
}
propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
properties := &schema1.ContainerProperties{}
if err := json.Unmarshal(propertiesRaw, properties); err != nil {
return nil, makeSystemError(computeSystem, "Properties", "", err, nil)
if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
return properties, nil
}
// Pause pauses the execution of the computeSystem. This feature is not enabled in TP5.
func (computeSystem *System) Pause() (err error) {
func (computeSystem *System) Pause(ctx context.Context) (err error) {
operation := "hcsshim::System::Pause"
// hcsPauseComputeSystemContext is an async peration. Start the outer span
// here to measure the full pause time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Pause"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Pause", "", ErrAlreadyClosed, nil)
return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsPauseComputeSystem(computeSystem.handle, "", &resultp)
})
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause)
resultJSON, err := vmcompute.HcsPauseComputeSystem(ctx, computeSystem.handle, "")
events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause)
if err != nil {
return makeSystemError(computeSystem, "Pause", "", err, events)
return makeSystemError(computeSystem, operation, "", err, events)
}
return nil
}
// Resume resumes the execution of the computeSystem. This feature is not enabled in TP5.
func (computeSystem *System) Resume() (err error) {
func (computeSystem *System) Resume(ctx context.Context) (err error) {
operation := "hcsshim::System::Resume"
// hcsResumeComputeSystemContext is an async operation. Start the outer span
// here to measure the full restore time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Resume"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Resume", "", ErrAlreadyClosed, nil)
return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsResumeComputeSystem(computeSystem.handle, "", &resultp)
})
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume)
resultJSON, err := vmcompute.HcsResumeComputeSystem(ctx, computeSystem.handle, "")
events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume)
if err != nil {
return makeSystemError(computeSystem, "Resume", "", err, events)
return makeSystemError(computeSystem, operation, "", err, events)
}
return nil
}
// CreateProcess launches a new process within the computeSystem.
func (computeSystem *System) CreateProcess(c interface{}) (_ *Process, err error) {
func (computeSystem *System) createProcess(ctx context.Context, operation string, c interface{}) (*Process, *vmcompute.HcsProcessInformation, error) {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::CreateProcess"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
var (
processInfo hcsProcessInformation
processHandle hcsProcess
resultp *uint16
)
if computeSystem.handle == 0 {
return nil, makeSystemError(computeSystem, "CreateProcess", "", ErrAlreadyClosed, nil)
return nil, nil, makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
}
configurationb, err := json.Marshal(c)
if err != nil {
return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
return nil, nil, makeSystemError(computeSystem, operation, "", err, nil)
}
configuration := string(configurationb)
logrus.WithFields(computeSystem.logctx).
WithField(logfields.JSON, configuration).
Debug("HCS ComputeSystem Process Document")
syscallWatcher(computeSystem.logctx, func() {
err = hcsCreateProcess(computeSystem.handle, configuration, &processInfo, &processHandle, &resultp)
})
events := processHcsResult(resultp)
processInfo, processHandle, resultJSON, err := vmcompute.HcsCreateProcess(ctx, computeSystem.handle, configuration)
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, makeSystemError(computeSystem, "CreateProcess", configuration, err, events)
return nil, nil, makeSystemError(computeSystem, operation, configuration, err, events)
}
logrus.WithFields(computeSystem.logctx).
WithField(logfields.ProcessID, processInfo.ProcessId).
Debug("HCS ComputeSystem CreateProcess PID")
log.G(ctx).WithField("pid", processInfo.ProcessId).Debug("created process pid")
return newProcess(processHandle, int(processInfo.ProcessId), computeSystem), &processInfo, nil
}
process := newProcess(processHandle, int(processInfo.ProcessId), computeSystem)
process.cachedPipes = &cachedPipes{
stdIn: processInfo.StdInput,
stdOut: processInfo.StdOutput,
stdErr: processInfo.StdError,
// CreateProcessNoStdio launches a new process within the computeSystem. The
// Stdio handles are not cached on the process struct.
func (computeSystem *System) CreateProcessNoStdio(c interface{}) (_ cow.Process, err error) {
operation := "hcsshim::System::CreateProcessNoStdio"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
process, processInfo, err := computeSystem.createProcess(ctx, operation, c)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
process.Close()
}
}()
if err = process.registerCallback(); err != nil {
return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
// We don't do anything with these handles. Close them so they don't leak.
syscall.Close(processInfo.StdInput)
syscall.Close(processInfo.StdOutput)
syscall.Close(processInfo.StdError)
if err = process.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
go process.waitBackground()
return process, nil
}
// CreateProcess launches a new process within the computeSystem.
func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (cow.Process, error) {
operation := "hcsshim::System::CreateProcess"
process, processInfo, err := computeSystem.createProcess(ctx, operation, c)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
process.Close()
}
}()
pipes, err := makeOpenFiles([]syscall.Handle{processInfo.StdInput, processInfo.StdOutput, processInfo.StdError})
if err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
process.stdin = pipes[0]
process.stdout = pipes[1]
process.stderr = pipes[2]
if err = process.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
go process.waitBackground()
@ -549,38 +513,25 @@ func (computeSystem *System) CreateProcess(c interface{}) (_ *Process, err error
}
// OpenProcess gets an interface to an existing process within the computeSystem.
func (computeSystem *System) OpenProcess(pid int) (_ *Process, err error) {
func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process, error) {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
// Add PID for the context of this operation
computeSystem.logctx[logfields.ProcessID] = pid
defer delete(computeSystem.logctx, logfields.ProcessID)
operation := "hcsshim::ComputeSystem::OpenProcess"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
var (
processHandle hcsProcess
resultp *uint16
)
operation := "hcsshim::System::OpenProcess"
if computeSystem.handle == 0 {
return nil, makeSystemError(computeSystem, "OpenProcess", "", ErrAlreadyClosed, nil)
return nil, makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
}
syscallWatcher(computeSystem.logctx, func() {
err = hcsOpenProcess(computeSystem.handle, uint32(pid), &processHandle, &resultp)
})
events := processHcsResult(resultp)
processHandle, resultJSON, err := vmcompute.HcsOpenProcess(ctx, computeSystem.handle, uint32(pid))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, makeSystemError(computeSystem, "OpenProcess", "", err, events)
return nil, makeSystemError(computeSystem, operation, "", err, events)
}
process := newProcess(processHandle, pid, computeSystem)
if err = process.registerCallback(); err != nil {
return nil, makeSystemError(computeSystem, "OpenProcess", "", err, nil)
if err = process.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
go process.waitBackground()
@ -589,68 +540,72 @@ func (computeSystem *System) OpenProcess(pid int) (_ *Process, err error) {
// Close cleans up any state associated with the compute system but does not terminate or wait for it.
func (computeSystem *System) Close() (err error) {
operation := "hcsshim::System::Close"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.Lock()
defer computeSystem.handleLock.Unlock()
operation := "hcsshim::ComputeSystem::Close"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
// Don't double free this
if computeSystem.handle == 0 {
return nil
}
if err = computeSystem.unregisterCallback(); err != nil {
return makeSystemError(computeSystem, "Close", "", err, nil)
if err = computeSystem.unregisterCallback(ctx); err != nil {
return makeSystemError(computeSystem, operation, "", err, nil)
}
syscallWatcher(computeSystem.logctx, func() {
err = hcsCloseComputeSystem(computeSystem.handle)
})
err = vmcompute.HcsCloseComputeSystem(ctx, computeSystem.handle)
if err != nil {
return makeSystemError(computeSystem, "Close", "", err, nil)
return makeSystemError(computeSystem, operation, "", err, nil)
}
computeSystem.handle = 0
computeSystem.closedWaitOnce.Do(func() {
computeSystem.waitError = ErrAlreadyClosed
close(computeSystem.waitBlock)
})
return nil
}
func (computeSystem *System) registerCallback() error {
context := &notifcationWatcherContext{
channels: newChannels(),
func (computeSystem *System) registerCallback(ctx context.Context) error {
callbackContext := &notifcationWatcherContext{
channels: newSystemChannels(),
systemID: computeSystem.id,
}
callbackMapLock.Lock()
callbackNumber := nextCallback
nextCallback++
callbackMap[callbackNumber] = context
callbackMap[callbackNumber] = callbackContext
callbackMapLock.Unlock()
var callbackHandle hcsCallback
err := hcsRegisterComputeSystemCallback(computeSystem.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
callbackHandle, err := vmcompute.HcsRegisterComputeSystemCallback(ctx, computeSystem.handle, notificationWatcherCallback, callbackNumber)
if err != nil {
return err
}
context.handle = callbackHandle
callbackContext.handle = callbackHandle
computeSystem.callbackNumber = callbackNumber
return nil
}
func (computeSystem *System) unregisterCallback() error {
func (computeSystem *System) unregisterCallback(ctx context.Context) error {
callbackNumber := computeSystem.callbackNumber
callbackMapLock.RLock()
context := callbackMap[callbackNumber]
callbackContext := callbackMap[callbackNumber]
callbackMapLock.RUnlock()
if context == nil {
if callbackContext == nil {
return nil
}
handle := context.handle
handle := callbackContext.handle
if handle == 0 {
return nil
@ -658,12 +613,12 @@ func (computeSystem *System) unregisterCallback() error {
// hcsUnregisterComputeSystemCallback has its own syncronization
// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
err := hcsUnregisterComputeSystemCallback(handle)
err := vmcompute.HcsUnregisterComputeSystemCallback(ctx, handle)
if err != nil {
return err
}
closeChannels(context.channels)
closeChannels(callbackContext.channels)
callbackMapLock.Lock()
delete(callbackMap, callbackNumber)
@ -675,36 +630,26 @@ func (computeSystem *System) unregisterCallback() error {
}
// Modify the System by sending a request to HCS
func (computeSystem *System) Modify(config interface{}) (err error) {
func (computeSystem *System) Modify(ctx context.Context, config interface{}) error {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Modify"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
operation := "hcsshim::System::Modify"
if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Modify", "", ErrAlreadyClosed, nil)
return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
}
requestJSON, err := json.Marshal(config)
requestBytes, err := json.Marshal(config)
if err != nil {
return err
}
requestString := string(requestJSON)
logrus.WithFields(computeSystem.logctx).
WithField(logfields.JSON, requestString).
Debug("HCS ComputeSystem Modify Document")
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsModifyComputeSystem(computeSystem.handle, requestString, &resultp)
})
events := processHcsResult(resultp)
requestJSON := string(requestBytes)
resultJSON, err := vmcompute.HcsModifyComputeSystem(ctx, computeSystem.handle, requestJSON)
events := processHcsResult(ctx, resultJSON)
if err != nil {
return makeSystemError(computeSystem, "Modify", requestString, err, events)
return makeSystemError(computeSystem, operation, requestJSON, err, events)
}
return nil

View File

@ -1,25 +1,26 @@
package hcs
import (
"context"
"time"
"github.com/sirupsen/logrus"
"github.com/Microsoft/hcsshim/internal/log"
)
func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
events := processHcsResult(resultp)
func processAsyncHcsResult(ctx context.Context, err error, resultJSON string, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
events := processHcsResult(ctx, resultJSON)
if IsPending(err) {
return nil, waitForNotification(callbackNumber, expectedNotification, timeout)
return nil, waitForNotification(ctx, callbackNumber, expectedNotification, timeout)
}
return events, err
}
func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
func waitForNotification(ctx context.Context, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
callbackMapLock.RLock()
if _, ok := callbackMap[callbackNumber]; !ok {
callbackMapLock.RUnlock()
logrus.Errorf("failed to waitForNotification: callbackNumber %d does not exist in callbackMap", callbackNumber)
log.G(ctx).WithField("callbackNumber", callbackNumber).Error("failed to waitForNotification: callbackNumber does not exist in callbackMap")
return ErrHandleClose
}
channels := callbackMap[callbackNumber].channels
@ -27,7 +28,7 @@ func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotific
expectedChannel := channels[expectedNotification]
if expectedChannel == nil {
logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification)
log.G(ctx).WithField("type", expectedNotification).Error("unknown notification type in waitForNotification")
return ErrInvalidNotificationType
}

View File

@ -1,41 +0,0 @@
package hcs
import (
"context"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/timeout"
"github.com/sirupsen/logrus"
)
// syscallWatcher is used as a very simple goroutine around calls into
// the platform. In some cases, we have seen HCS APIs not returning due to
// various bugs, and the goroutine making the syscall ends up not returning,
// prior to its async callback. By spinning up a syscallWatcher, it allows
// us to at least log a warning if a syscall doesn't complete in a reasonable
// amount of time.
//
// Usage is:
//
// syscallWatcher(logContext, func() {
// err = <syscall>(args...)
// })
//
func syscallWatcher(logContext logrus.Fields, syscallLambda func()) {
ctx, cancel := context.WithTimeout(context.Background(), timeout.SyscallWatcher)
defer cancel()
go watchFunc(ctx, logContext)
syscallLambda()
}
func watchFunc(ctx context.Context, logContext logrus.Fields) {
select {
case <-ctx.Done():
if ctx.Err() != context.Canceled {
logrus.WithFields(logContext).
WithField(logfields.Timeout, timeout.SyscallWatcher).
Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see if there is a syscall stuck in the platform API for a significant length of time.")
}
}
}

View File

@ -3,6 +3,7 @@ package hns
import (
"encoding/json"
"net"
"strings"
"github.com/sirupsen/logrus"
)
@ -94,6 +95,27 @@ func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
return nil, EndpointNotFoundError{EndpointName: endpointName}
}
type endpointAttachInfo struct {
SharedContainers json.RawMessage `json:",omitempty"`
}
func (endpoint *HNSEndpoint) IsAttached(vID string) (bool, error) {
attachInfo := endpointAttachInfo{}
err := hnsCall("GET", "/endpoints/"+endpoint.Id, "", &attachInfo)
// Return false allows us to just return the err
if err != nil {
return false, err
}
if strings.Contains(strings.ToLower(string(attachInfo.SharedContainers)), strings.ToLower(vID)) {
return true, nil
}
return false, nil
}
// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
operation := "Create"

View File

@ -9,23 +9,30 @@ import (
"github.com/sirupsen/logrus"
)
func hnsCall(method, path, request string, returnResponse interface{}) error {
func hnsCallRawResponse(method, path, request string) (*hnsResponse, error) {
var responseBuffer *uint16
logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
err := _hnsCall(method, path, request, &responseBuffer)
if err != nil {
return hcserror.New(err, "hnsCall ", "")
return nil, hcserror.New(err, "hnsCall ", "")
}
response := interop.ConvertAndFreeCoTaskMemString(responseBuffer)
hnsresponse := &hnsResponse{}
if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
return err
return nil, err
}
return hnsresponse, nil
}
func hnsCall(method, path, request string, returnResponse interface{}) error {
hnsresponse, err := hnsCallRawResponse(method, path, request)
if err != nil {
return fmt.Errorf("failed during hnsCallRawResponse: %v", err)
}
if !hnsresponse.Success {
return fmt.Errorf("HNS failed with error : %s", hnsresponse.Error)
return fmt.Errorf("hns failed with error : %s", hnsresponse.Error)
}
if len(hnsresponse.Output) == 0 {

View File

@ -15,10 +15,6 @@ func ConvertAndFreeCoTaskMemString(buffer *uint16) string {
return str
}
func ConvertAndFreeCoTaskMemBytes(buffer *uint16) []byte {
return []byte(ConvertAndFreeCoTaskMemString(buffer))
}
func Win32FromHresult(hr uintptr) syscall.Errno {
if hr&0x1fff0000 == 0x00070000 {
return syscall.Errno(hr & 0xffff)

23
vendor/github.com/Microsoft/hcsshim/internal/log/g.go generated vendored Normal file
View File

@ -0,0 +1,23 @@
package log
import (
"context"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// G returns a `logrus.Entry` with the `TraceID, SpanID` from `ctx` if `ctx`
// contains an OpenCensus `trace.Span`.
func G(ctx context.Context) *logrus.Entry {
span := trace.FromContext(ctx)
if span != nil {
sctx := span.SpanContext()
return logrus.WithFields(logrus.Fields{
"traceID": sctx.TraceID.String(),
"spanID": sctx.SpanID.String(),
// "parentSpanID": TODO: JTERRY75 - Try to convince OC to export this?
})
}
return logrus.NewEntry(logrus.StandardLogger())
}

View File

@ -0,0 +1,43 @@
package oc
import (
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
var _ = (trace.Exporter)(&LogrusExporter{})
// LogrusExporter is an OpenCensus `trace.Exporter` that exports
// `trace.SpanData` to logrus output.
type LogrusExporter struct {
}
// ExportSpan exports `s` based on the the following rules:
//
// 1. All output will contain `s.Attributes`, `s.TraceID`, `s.SpanID`,
// `s.ParentSpanID` for correlation
//
// 2. Any calls to .Annotate will not be supported.
//
// 3. The span itself will be written at `logrus.InfoLevel` unless
// `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel`
// providing `s.Status.Message` as the error value.
func (le *LogrusExporter) ExportSpan(s *trace.SpanData) {
// Combine all span annotations with traceID, spanID, parentSpanID
baseEntry := logrus.WithFields(logrus.Fields(s.Attributes))
baseEntry.Data["traceID"] = s.TraceID.String()
baseEntry.Data["spanID"] = s.SpanID.String()
baseEntry.Data["parentSpanID"] = s.ParentSpanID.String()
baseEntry.Data["startTime"] = s.StartTime
baseEntry.Data["endTime"] = s.EndTime
baseEntry.Data["duration"] = s.EndTime.Sub(s.StartTime).String()
baseEntry.Data["name"] = s.Name
baseEntry.Time = s.StartTime
level := logrus.InfoLevel
if s.Status.Code != 0 {
level = logrus.ErrorLevel
baseEntry.Data[logrus.ErrorKey] = s.Status.Message
}
baseEntry.Log(level, "Span")
}

View File

@ -0,0 +1,17 @@
package oc
import (
"go.opencensus.io/trace"
)
// SetSpanStatus sets `span.SetStatus` to the proper status depending on `err`. If
// `err` is `nil` assumes `trace.StatusCodeOk`.
func SetSpanStatus(span *trace.Span, err error) {
status := trace.Status{}
if err != nil {
// TODO: JTERRY75 - Handle errors in a non-generic way
status.Code = trace.StatusCodeUnknown
status.Message = err.Error()
}
span.SetStatus(status)
}

View File

@ -10,7 +10,7 @@ import (
"syscall"
"time"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
)
// ContainerState represents the platform agnostic pieces relating to a

View File

@ -4,7 +4,8 @@ import (
"encoding/json"
"time"
"github.com/Microsoft/hcsshim/internal/schema2"
"github.com/Microsoft/go-winio/pkg/guid"
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
)
// ProcessConfig is used as both the input of Container.CreateProcess
@ -62,7 +63,7 @@ type MappedVirtualDisk struct {
CreateInUtilityVM bool `json:",omitempty"`
ReadOnly bool `json:",omitempty"`
Cache string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
AttachOnly bool `json:",omitempty:`
AttachOnly bool `json:",omitempty"`
}
// AssignedDevice represents a device that has been directly assigned to a container
@ -133,9 +134,10 @@ type ContainerProperties struct {
State string
Name string
SystemType string
RuntimeOSType string `json:"RuntimeOsType,omitempty"`
Owner string
SiloGUID string `json:"SiloGuid,omitempty"`
RuntimeID string `json:"RuntimeId,omitempty"`
RuntimeID guid.GUID `json:"RuntimeId,omitempty"`
IsRuntimeTemplate bool `json:",omitempty"`
RuntimeImagePath string `json:",omitempty"`
Stopped bool `json:",omitempty"`
@ -214,6 +216,7 @@ type MappedVirtualDiskController struct {
type GuestDefinedCapabilities struct {
NamespaceAddRequestSupported bool `json:",omitempty"`
SignalProcessSupported bool `json:",omitempty"`
DumpStacksSupported bool `json:",omitempty"`
}
// GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM

View File

@ -10,7 +10,6 @@
package hcsschema
type Attachment struct {
Type_ string `json:"Type,omitempty"`
Path string `json:"Path,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type CacheQueryStatsResponse struct {
L3OccupancyBytes int32 `json:"L3OccupancyBytes,omitempty"`
L3TotalBwBytes int32 `json:"L3TotalBwBytes,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema
type CloseHandle struct {
Handle string `json:"Handle,omitempty"`
}

View File

@ -11,7 +11,6 @@ package hcsschema
// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port.
type ComPort struct {
NamedPipe string `json:"NamedPipe,omitempty"`
OptimizeForDebugger bool `json:"OptimizeForDebugger,omitempty"`

View File

@ -10,14 +10,13 @@
package hcsschema
type ComputeSystem struct {
Owner string `json:"Owner,omitempty"`
SchemaVersion *Version `json:"SchemaVersion,omitempty"`
HostingSystemId string `json:"HostingSystemId,omitempty"`
HostedSystem *HostedSystem `json:"HostedSystem,omitempty"`
HostedSystem interface{} `json:"HostedSystem,omitempty"`
Container *Container `json:"Container,omitempty"`

View File

@ -25,37 +25,37 @@ func (c contextKey) String() string {
var (
// ContextOAuth2 takes a oauth2.TokenSource as authentication for the request.
ContextOAuth2 = contextKey("token")
ContextOAuth2 = contextKey("token")
// ContextBasicAuth takes BasicAuth as authentication for the request.
ContextBasicAuth = contextKey("basic")
ContextBasicAuth = contextKey("basic")
// ContextAccessToken takes a string oauth2 access token as authentication for the request.
ContextAccessToken = contextKey("accesstoken")
ContextAccessToken = contextKey("accesstoken")
// ContextAPIKey takes an APIKey as authentication for the request
ContextAPIKey = contextKey("apikey")
ContextAPIKey = contextKey("apikey")
)
// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
type BasicAuth struct {
UserName string `json:"userName,omitempty"`
Password string `json:"password,omitempty"`
UserName string `json:"userName,omitempty"`
Password string `json:"password,omitempty"`
}
// APIKey provides API key based authentication to a request passed via context using ContextAPIKey
type APIKey struct {
Key string
Prefix string
Key string
Prefix string
}
type Configuration struct {
BasePath string `json:"basePath,omitempty"`
Host string `json:"host,omitempty"`
Scheme string `json:"scheme,omitempty"`
DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
UserAgent string `json:"userAgent,omitempty"`
HTTPClient *http.Client
BasePath string `json:"basePath,omitempty"`
Host string `json:"host,omitempty"`
Scheme string `json:"scheme,omitempty"`
DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
UserAgent string `json:"userAgent,omitempty"`
HTTPClient *http.Client
}
func NewConfiguration() *Configuration {
@ -69,4 +69,4 @@ func NewConfiguration() *Configuration {
func (c *Configuration) AddDefaultHeader(key string, value string) {
c.DefaultHeader[key] = value
}
}

View File

@ -10,7 +10,6 @@
package hcsschema
type ConsoleSize struct {
Height int32 `json:"Height,omitempty"`
Width int32 `json:"Width,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Container struct {
GuestOs *GuestOs `json:"GuestOs,omitempty"`
Storage *Storage `json:"Storage,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// memory usage as viewed from within the container
type ContainerMemoryInformation struct {
TotalPhysicalBytes int32 `json:"TotalPhysicalBytes,omitempty"`
TotalUsage int32 `json:"TotalUsage,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Devices struct {
ComPorts map[string]ComPort `json:"ComPorts,omitempty"`
Scsi map[string]Scsi `json:"Scsi,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema
type EnhancedModeVideo struct {
ConnectionOptions *RdpConnectionOptions `json:"ConnectionOptions,omitempty"`
}

View File

@ -10,7 +10,6 @@
package hcsschema
type FlexibleIoDevice struct {
EmulatorId string `json:"EmulatorId,omitempty"`
HostingModel string `json:"HostingModel,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema
type GuestCrashReporting struct {
WindowsCrashSettings *WindowsCrashReporting `json:"WindowsCrashSettings,omitempty"`
}

View File

@ -10,6 +10,5 @@
package hcsschema
type GuestOs struct {
HostName string `json:"HostName,omitempty"`
}

View File

@ -10,7 +10,6 @@
package hcsschema
type HostedSystem struct {
SchemaVersion *Version `json:"SchemaVersion,omitempty"`
Container *Container `json:"Container,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type HvSocket struct {
Config *HvSocketSystemConfig `json:"Config,omitempty"`
EnablePowerShellDirect bool `json:"EnablePowerShellDirect,omitempty"`

View File

@ -11,6 +11,5 @@ package hcsschema
// HvSocket configuration for a VM
type HvSocket2 struct {
HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"`
}

View File

@ -10,7 +10,6 @@
package hcsschema
type Layer struct {
Id string `json:"Id,omitempty"`
Path string `json:"Path,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type MappedDirectory struct {
HostPath string `json:"HostPath,omitempty"`
HostPathType string `json:"HostPathType,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type MappedPipe struct {
ContainerPipeName string `json:"ContainerPipeName,omitempty"`
HostPath string `json:"HostPath,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema
type Memory struct {
SizeInMB int32 `json:"SizeInMB,omitempty"`
}

View File

@ -10,7 +10,6 @@
package hcsschema
type MemoryInformationForVm struct {
VirtualNodeCount int32 `json:"VirtualNodeCount,omitempty"`
VirtualMachineMemory *VmMemory `json:"VirtualMachineMemory,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Memory runtime statistics
type MemoryStats struct {
MemoryUsageCommitBytes int32 `json:"MemoryUsageCommitBytes,omitempty"`
MemoryUsageCommitPeakBytes int32 `json:"MemoryUsageCommitPeakBytes,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type NetworkAdapter struct {
EndpointId string `json:"EndpointId,omitempty"`
MacAddress string `json:"MacAddress,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Networking struct {
AllowUnqualifiedDnsQuery bool `json:"AllowUnqualifiedDnsQuery,omitempty"`
DnsSearchList string `json:"DnsSearchList,omitempty"`

View File

@ -11,6 +11,5 @@ package hcsschema
// Notification data that is indicated to components running in the Virtual Machine.
type PauseNotification struct {
Reason string `json:"Reason,omitempty"`
}

View File

@ -11,7 +11,6 @@ package hcsschema
// Options for HcsPauseComputeSystem
type PauseOptions struct {
SuspensionLevel string `json:"SuspensionLevel,omitempty"`
HostedNotification *PauseNotification `json:"HostedNotification,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema
type Plan9 struct {
Shares []Plan9Share `json:"Shares,omitempty"`
}

View File

@ -15,7 +15,6 @@ import (
// Information about a process running in a container
type ProcessDetails struct {
ProcessId int32 `json:"ProcessId,omitempty"`
ImageName string `json:"ImageName,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Passed to HcsRpc_ModifyProcess
type ProcessModifyRequest struct {
Operation string `json:"Operation,omitempty"`
ConsoleSize *ConsoleSize `json:"ConsoleSize,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type ProcessParameters struct {
ApplicationName string `json:"ApplicationName,omitempty"`
CommandLine string `json:"CommandLine,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Status of a process running in a container
type ProcessStatus struct {
ProcessId int32 `json:"ProcessId,omitempty"`
Exited bool `json:"Exited,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Processor struct {
Count int32 `json:"Count,omitempty"`
Maximum int32 `json:"Maximum,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Processor2 struct {
Count int32 `json:"Count,omitempty"`
Limit int32 `json:"Limit,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// CPU runtime statistics
type ProcessorStats struct {
TotalRuntime100ns int32 `json:"TotalRuntime100ns,omitempty"`
RuntimeUser100ns int32 `json:"RuntimeUser100ns,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Properties struct {
Id string `json:"Id,omitempty"`
SystemType string `json:"SystemType,omitempty"`

View File

@ -9,8 +9,7 @@
package hcsschema
// By default the basic properties will be returned. This query provides a way to request specific properties.
// By default the basic properties will be returned. This query provides a way to request specific properties.
type PropertyQuery struct {
PropertyTypes []string `json:"PropertyTypes,omitempty"`
}

View File

@ -10,7 +10,6 @@
package hcsschema
type RdpConnectionOptions struct {
AccessSids []string `json:"AccessSids,omitempty"`
NamedPipe string `json:"NamedPipe,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type RegistryChanges struct {
AddValues []RegistryValue `json:"AddValues,omitempty"`
DeleteKeys []RegistryKey `json:"DeleteKeys,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type RegistryKey struct {
Hive string `json:"Hive,omitempty"`
Name string `json:"Name,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type RegistryValue struct {
Key *RegistryKey `json:"Key,omitempty"`
Name string `json:"Name,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema
type SharedMemoryConfiguration struct {
Regions []SharedMemoryRegion `json:"Regions,omitempty"`
}

View File

@ -10,7 +10,6 @@
package hcsschema
type SharedMemoryRegion struct {
SectionName string `json:"SectionName,omitempty"`
StartOffset int32 `json:"StartOffset,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type SharedMemoryRegionInfo struct {
SectionName string `json:"SectionName,omitempty"`
GuestPhysicalAddress int32 `json:"GuestPhysicalAddress,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Silo job information
type SiloProperties struct {
Enabled bool `json:"Enabled,omitempty"`
JobName string `json:"JobName,omitempty"`

View File

@ -15,7 +15,6 @@ import (
// Runtime statistics for a container
type Statistics struct {
Timestamp time.Time `json:"Timestamp,omitempty"`
ContainerStartTime time.Time `json:"ContainerStartTime,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type StorageQoS struct {
IopsMaximum int32 `json:"IopsMaximum,omitempty"`
BandwidthMaximum int32 `json:"BandwidthMaximum,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Storage runtime statistics
type StorageStats struct {
ReadCountNormalized int32 `json:"ReadCountNormalized,omitempty"`
ReadSizeBytes int32 `json:"ReadSizeBytes,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Topology struct {
Memory *Memory2 `json:"Memory,omitempty"`
Processor *Processor2 `json:"Processor,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Uefi struct {
EnableDebugger bool `json:"EnableDebugger,omitempty"`
SecureBootTemplateId string `json:"SecureBootTemplateId,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type UefiBootEntry struct {
DeviceType string `json:"DeviceType,omitempty"`
DevicePath string `json:"DevicePath,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type Version struct {
Major int32 `json:"Major,omitempty"`
Minor int32 `json:"Minor,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type VideoMonitor struct {
HorizontalResolution int32 `json:"HorizontalResolution,omitempty"`
VerticalResolution int32 `json:"VerticalResolution,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type VirtualNodeInfo struct {
VirtualNodeIndex int32 `json:"VirtualNodeIndex,omitempty"`
PhysicalNodeNumber int32 `json:"PhysicalNodeNumber,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type VirtualPMemDevice struct {
HostPath string `json:"HostPath,omitempty"`
ReadOnly bool `json:"ReadOnly,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type VirtualSmb struct {
Shares []VirtualSmbShare `json:"Shares,omitempty"`
DirectFileMappingInMB int64 `json:"DirectFileMappingInMB,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type VirtualSmbShare struct {
Name string `json:"Name,omitempty"`
Path string `json:"Path,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type VirtualSmbShareOptions struct {
ReadOnly bool `json:"ReadOnly,omitempty"`
// convert exclusive access to shared read access

View File

@ -10,7 +10,6 @@
package hcsschema
type VmMemory struct {
AvailableMemory int32 `json:"AvailableMemory,omitempty"`
AvailableMemoryBuffer int32 `json:"AvailableMemoryBuffer,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema
type WindowsCrashReporting struct {
DumpFileName string `json:"DumpFileName,omitempty"`
MaxDumpSize int64 `json:"MaxDumpSize,omitempty"`

View File

@ -0,0 +1,563 @@
package vmcompute
import (
gcontext "context"
"syscall"
"time"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/timeout"
"go.opencensus.io/trace"
)
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go vmcompute.go
//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *HcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
//sys hcsOpenComputeSystem(id string, computeSystem *HcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
//sys hcsCloseComputeSystem(computeSystem HcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
//sys hcsStartComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
//sys hcsShutdownComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
//sys hcsTerminateComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
//sys hcsPauseComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
//sys hcsResumeComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
//sys hcsGetComputeSystemProperties(computeSystem HcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
//sys hcsModifyComputeSystem(computeSystem HcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
//sys hcsRegisterComputeSystemCallback(computeSystem HcsSystem, callback uintptr, context uintptr, callbackHandle *HcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
//sys hcsUnregisterComputeSystemCallback(callbackHandle HcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
//sys hcsCreateProcess(computeSystem HcsSystem, processParameters string, processInformation *HcsProcessInformation, process *HcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
//sys hcsOpenProcess(computeSystem HcsSystem, pid uint32, process *HcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
//sys hcsCloseProcess(process HcsProcess) (hr error) = vmcompute.HcsCloseProcess?
//sys hcsTerminateProcess(process HcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
//sys hcsSignalProcess(process HcsProcess, options string, result **uint16) (hr error) = vmcompute.HcsSignalProcess?
//sys hcsGetProcessInfo(process HcsProcess, processInformation *HcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
//sys hcsGetProcessProperties(process HcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
//sys hcsModifyProcess(process HcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
//sys hcsRegisterProcessCallback(process HcsProcess, callback uintptr, context uintptr, callbackHandle *HcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
//sys hcsUnregisterProcessCallback(callbackHandle HcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
// errVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
const errVmcomputeOperationPending = syscall.Errno(0xC0370103)
// HcsSystem is the handle associated with a created compute system.
type HcsSystem syscall.Handle
// HcsProcess is the handle associated with a created process in a compute
// system.
type HcsProcess syscall.Handle
// HcsCallback is the handle associated with the function to call when events
// occur.
type HcsCallback syscall.Handle
// HcsProcessInformation is the structure used when creating or getting process
// info.
type HcsProcessInformation struct {
// ProcessId is the pid of the created process.
ProcessId uint32
reserved uint32
// StdInput is the handle associated with the stdin of the process.
StdInput syscall.Handle
// StdOutput is the handle associated with the stdout of the process.
StdOutput syscall.Handle
// StdError is the handle associated with the stderr of the process.
StdError syscall.Handle
}
func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error {
if timeout > 0 {
var cancel gcontext.CancelFunc
ctx, cancel = gcontext.WithTimeout(ctx, timeout)
defer cancel()
}
done := make(chan error, 1)
go func() {
done <- f()
}()
select {
case <-ctx.Done():
if ctx.Err() == gcontext.DeadlineExceeded {
log.G(ctx).WithField(logfields.Timeout, timeout).
Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see if there is a syscall stuck in the platform API for a significant length of time.")
}
return ctx.Err()
case err := <-done:
return err
}
}
func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSystems, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsEnumerateComputeSystems")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("query", query))
return computeSystems, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
computeSystemsp *uint16
resultp *uint16
)
err := hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
if computeSystemsp != nil {
computeSystems = interop.ConvertAndFreeCoTaskMemString(computeSystemsp)
}
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration string, identity syscall.Handle) (computeSystem HcsSystem, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsCreateComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
if hr != errVmcomputeOperationPending {
oc.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(
trace.StringAttribute("id", id),
trace.StringAttribute("configuration", configuration))
return computeSystem, result, execute(ctx, timeout.SystemCreate, func() error {
var resultp *uint16
err := hcsCreateComputeSystem(id, configuration, identity, &computeSystem, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSystem, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsOpenComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
return computeSystem, result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsOpenComputeSystem(id, &computeSystem, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr error) {
ctx, span := trace.StartSpan(ctx, "HcsCloseComputeSystem")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsCloseComputeSystem(computeSystem)
})
}
func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsStartComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
if hr != errVmcomputeOperationPending {
oc.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
return result, execute(ctx, timeout.SystemStart, func() error {
var resultp *uint16
err := hcsStartComputeSystem(computeSystem, options, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsShutdownComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("options", options))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsShutdownComputeSystem(computeSystem, options, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsTerminateComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
if hr != errVmcomputeOperationPending {
oc.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsTerminateComputeSystem(computeSystem, options, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsPauseComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
if hr != errVmcomputeOperationPending {
oc.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
return result, execute(ctx, timeout.SystemPause, func() error {
var resultp *uint16
err := hcsPauseComputeSystem(computeSystem, options, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsResumeComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
if hr != errVmcomputeOperationPending {
oc.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
return result, execute(ctx, timeout.SystemResume, func() error {
var resultp *uint16
err := hcsResumeComputeSystem(computeSystem, options, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem, propertyQuery string) (properties, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsGetComputeSystemProperties")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("propertyQuery", propertyQuery))
return properties, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
propertiesp *uint16
resultp *uint16
)
err := hcsGetComputeSystemProperties(computeSystem, propertyQuery, &propertiesp, &resultp)
if propertiesp != nil {
properties = interop.ConvertAndFreeCoTaskMemString(propertiesp)
}
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, configuration string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsModifyComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("configuration", configuration))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsModifyComputeSystem(computeSystem, configuration, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSystem, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsRegisterComputeSystemCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
return callbackHandle, execute(ctx, timeout.SyscallWatcher, func() error {
return hcsRegisterComputeSystemCallback(computeSystem, callback, context, &callbackHandle)
})
}
func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) {
ctx, span := trace.StartSpan(ctx, "HcsUnregisterComputeSystemCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsUnregisterComputeSystemCallback(callbackHandle)
})
}
func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processParameters string) (processInformation HcsProcessInformation, process HcsProcess, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsCreateProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("processParameters", processParameters))
return processInformation, process, result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsCreateProcess(computeSystem, processParameters, &processInformation, &process, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) (process HcsProcess, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsOpenProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.Int64Attribute("pid", int64(pid)))
return process, result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsOpenProcess(computeSystem, pid, &process, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) {
ctx, span := trace.StartSpan(ctx, "HcsCloseProcess")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsCloseProcess(process)
})
}
func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsTerminateProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsTerminateProcess(process, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsSignalProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("options", options))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsSignalProcess(process, options, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInformation HcsProcessInformation, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsGetProcessInfo")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
return processInformation, result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsGetProcessInfo(process, &processInformation, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processProperties, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsGetProcessProperties")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
return processProperties, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
processPropertiesp *uint16
resultp *uint16
)
err := hcsGetProcessProperties(process, &processPropertiesp, &resultp)
if processPropertiesp != nil {
processProperties = interop.ConvertAndFreeCoTaskMemString(processPropertiesp)
}
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) (result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsModifyProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("settings", settings))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
err := hcsModifyProcess(process, settings, &resultp)
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (properties, result string, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsGetServiceProperties")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
}
oc.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("propertyQuery", propertyQuery))
return properties, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
propertiesp *uint16
resultp *uint16
)
err := hcsGetServiceProperties(propertyQuery, &propertiesp, &resultp)
if propertiesp != nil {
properties = interop.ConvertAndFreeCoTaskMemString(propertiesp)
}
if resultp != nil {
result = interop.ConvertAndFreeCoTaskMemString(resultp)
}
return err
})
}
func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) {
ctx, span := trace.StartSpan(ctx, "HcsRegisterProcessCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
return callbackHandle, execute(ctx, timeout.SyscallWatcher, func() error {
return hcsRegisterProcessCallback(process, callback, context, &callbackHandle)
})
}
func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) {
ctx, span := trace.StartSpan(ctx, "HcsUnregisterProcessCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsUnregisterProcessCallback(callbackHandle)
})
}

View File

@ -1,6 +1,6 @@
// Code generated mksyscall_windows.exe DO NOT EDIT
package hcs
package vmcompute
import (
"syscall"
@ -56,13 +56,13 @@ var (
procHcsOpenProcess = modvmcompute.NewProc("HcsOpenProcess")
procHcsCloseProcess = modvmcompute.NewProc("HcsCloseProcess")
procHcsTerminateProcess = modvmcompute.NewProc("HcsTerminateProcess")
procHcsGetProcessInfo = modvmcompute.NewProc("HcsGetProcessInfo")
procHcsGetProcessProperties = modvmcompute.NewProc("HcsGetProcessProperties")
procHcsModifyProcess = modvmcompute.NewProc("HcsModifyProcess")
procHcsGetServiceProperties = modvmcompute.NewProc("HcsGetServiceProperties")
procHcsRegisterProcessCallback = modvmcompute.NewProc("HcsRegisterProcessCallback")
procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
procHcsSignalProcess = modvmcompute.NewProc("HcsSignalProcess")
procHcsGetProcessInfo = modvmcompute.NewProc("HcsGetProcessInfo")
procHcsGetProcessProperties = modvmcompute.NewProc("HcsGetProcessProperties")
procHcsModifyProcess = modvmcompute.NewProc("HcsModifyProcess")
procHcsGetServiceProperties = modvmcompute.NewProc("HcsGetServiceProperties")
procHcsRegisterProcessCallback = modvmcompute.NewProc("HcsRegisterProcessCallback")
procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
)
func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) {
@ -88,7 +88,7 @@ func _hcsEnumerateComputeSystems(query *uint16, computeSystems **uint16, result
return
}
func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *HcsSystem, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(id)
if hr != nil {
@ -102,7 +102,7 @@ func hcsCreateComputeSystem(id string, configuration string, identity syscall.Ha
return _hcsCreateComputeSystem(_p0, _p1, identity, computeSystem, result)
}
func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *HcsSystem, result **uint16) (hr error) {
if hr = procHcsCreateComputeSystem.Find(); hr != nil {
return
}
@ -116,7 +116,7 @@ func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall
return
}
func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) {
func hcsOpenComputeSystem(id string, computeSystem *HcsSystem, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(id)
if hr != nil {
@ -125,7 +125,7 @@ func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16)
return _hcsOpenComputeSystem(_p0, computeSystem, result)
}
func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
func _hcsOpenComputeSystem(id *uint16, computeSystem *HcsSystem, result **uint16) (hr error) {
if hr = procHcsOpenComputeSystem.Find(); hr != nil {
return
}
@ -139,7 +139,7 @@ func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16
return
}
func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
func hcsCloseComputeSystem(computeSystem HcsSystem) (hr error) {
if hr = procHcsCloseComputeSystem.Find(); hr != nil {
return
}
@ -153,7 +153,7 @@ func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
return
}
func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
func hcsStartComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
@ -162,7 +162,7 @@ func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uin
return _hcsStartComputeSystem(computeSystem, _p0, result)
}
func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
func _hcsStartComputeSystem(computeSystem HcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsStartComputeSystem.Find(); hr != nil {
return
}
@ -176,7 +176,7 @@ func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **u
return
}
func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
func hcsShutdownComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
@ -185,7 +185,7 @@ func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **
return _hcsShutdownComputeSystem(computeSystem, _p0, result)
}
func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
func _hcsShutdownComputeSystem(computeSystem HcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
return
}
@ -199,7 +199,7 @@ func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result
return
}
func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
func hcsTerminateComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
@ -208,7 +208,7 @@ func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result *
return _hcsTerminateComputeSystem(computeSystem, _p0, result)
}
func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
func _hcsTerminateComputeSystem(computeSystem HcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
return
}
@ -222,7 +222,7 @@ func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result
return
}
func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
func hcsPauseComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
@ -231,7 +231,7 @@ func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uin
return _hcsPauseComputeSystem(computeSystem, _p0, result)
}
func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
func _hcsPauseComputeSystem(computeSystem HcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsPauseComputeSystem.Find(); hr != nil {
return
}
@ -245,7 +245,7 @@ func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **u
return
}
func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
func hcsResumeComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
@ -254,7 +254,7 @@ func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **ui
return _hcsResumeComputeSystem(computeSystem, _p0, result)
}
func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
func _hcsResumeComputeSystem(computeSystem HcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsResumeComputeSystem.Find(); hr != nil {
return
}
@ -268,7 +268,7 @@ func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **
return
}
func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
func hcsGetComputeSystemProperties(computeSystem HcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
if hr != nil {
@ -277,7 +277,7 @@ func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string
return _hcsGetComputeSystemProperties(computeSystem, _p0, properties, result)
}
func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
func _hcsGetComputeSystemProperties(computeSystem HcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
if hr = procHcsGetComputeSystemProperties.Find(); hr != nil {
return
}
@ -291,7 +291,7 @@ func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint
return
}
func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) {
func hcsModifyComputeSystem(computeSystem HcsSystem, configuration string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(configuration)
if hr != nil {
@ -300,7 +300,7 @@ func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, resul
return _hcsModifyComputeSystem(computeSystem, _p0, result)
}
func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, result **uint16) (hr error) {
func _hcsModifyComputeSystem(computeSystem HcsSystem, configuration *uint16, result **uint16) (hr error) {
if hr = procHcsModifyComputeSystem.Find(); hr != nil {
return
}
@ -314,7 +314,7 @@ func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, res
return
}
func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
func hcsRegisterComputeSystemCallback(computeSystem HcsSystem, callback uintptr, context uintptr, callbackHandle *HcsCallback) (hr error) {
if hr = procHcsRegisterComputeSystemCallback.Find(); hr != nil {
return
}
@ -328,7 +328,7 @@ func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr,
return
}
func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
func hcsUnregisterComputeSystemCallback(callbackHandle HcsCallback) (hr error) {
if hr = procHcsUnregisterComputeSystemCallback.Find(); hr != nil {
return
}
@ -342,7 +342,7 @@ func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
return
}
func hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
func hcsCreateProcess(computeSystem HcsSystem, processParameters string, processInformation *HcsProcessInformation, process *HcsProcess, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(processParameters)
if hr != nil {
@ -351,7 +351,7 @@ func hcsCreateProcess(computeSystem hcsSystem, processParameters string, process
return _hcsCreateProcess(computeSystem, _p0, processInformation, process, result)
}
func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
func _hcsCreateProcess(computeSystem HcsSystem, processParameters *uint16, processInformation *HcsProcessInformation, process *HcsProcess, result **uint16) (hr error) {
if hr = procHcsCreateProcess.Find(); hr != nil {
return
}
@ -365,7 +365,7 @@ func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, proce
return
}
func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) {
func hcsOpenProcess(computeSystem HcsSystem, pid uint32, process *HcsProcess, result **uint16) (hr error) {
if hr = procHcsOpenProcess.Find(); hr != nil {
return
}
@ -379,7 +379,7 @@ func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, re
return
}
func hcsCloseProcess(process hcsProcess) (hr error) {
func hcsCloseProcess(process HcsProcess) (hr error) {
if hr = procHcsCloseProcess.Find(); hr != nil {
return
}
@ -393,7 +393,7 @@ func hcsCloseProcess(process hcsProcess) (hr error) {
return
}
func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
func hcsTerminateProcess(process HcsProcess, result **uint16) (hr error) {
if hr = procHcsTerminateProcess.Find(); hr != nil {
return
}
@ -407,7 +407,7 @@ func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
return
}
func hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) {
func hcsSignalProcess(process HcsProcess, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
@ -416,11 +416,11 @@ func hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr e
return _hcsSignalProcess(process, _p0, result)
}
func _hcsSignalProcess(process hcsProcess, options *uint16, result **uint16) (hr error) {
if hr = procHcsTerminateProcess.Find(); hr != nil {
func _hcsSignalProcess(process HcsProcess, options *uint16, result **uint16) (hr error) {
if hr = procHcsSignalProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
r0, _, _ := syscall.Syscall(procHcsSignalProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
@ -430,7 +430,7 @@ func _hcsSignalProcess(process hcsProcess, options *uint16, result **uint16) (hr
return
}
func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) {
func hcsGetProcessInfo(process HcsProcess, processInformation *HcsProcessInformation, result **uint16) (hr error) {
if hr = procHcsGetProcessInfo.Find(); hr != nil {
return
}
@ -444,7 +444,7 @@ func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInforma
return
}
func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) {
func hcsGetProcessProperties(process HcsProcess, processProperties **uint16, result **uint16) (hr error) {
if hr = procHcsGetProcessProperties.Find(); hr != nil {
return
}
@ -458,7 +458,7 @@ func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, res
return
}
func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) {
func hcsModifyProcess(process HcsProcess, settings string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(settings)
if hr != nil {
@ -467,7 +467,7 @@ func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr
return _hcsModifyProcess(process, _p0, result)
}
func _hcsModifyProcess(process hcsProcess, settings *uint16, result **uint16) (hr error) {
func _hcsModifyProcess(process HcsProcess, settings *uint16, result **uint16) (hr error) {
if hr = procHcsModifyProcess.Find(); hr != nil {
return
}
@ -504,7 +504,7 @@ func _hcsGetServiceProperties(propertyQuery *uint16, properties **uint16, result
return
}
func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
func hcsRegisterProcessCallback(process HcsProcess, callback uintptr, context uintptr, callbackHandle *HcsCallback) (hr error) {
if hr = procHcsRegisterProcessCallback.Find(); hr != nil {
return
}
@ -518,7 +518,7 @@ func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context ui
return
}
func hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) {
func hcsUnregisterProcessCallback(callbackHandle HcsCallback) (hr error) {
if hr = procHcsUnregisterProcessCallback.Find(); hr != nil {
return
}

View File

@ -3,7 +3,7 @@ package wclayer
import (
"path/filepath"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
)
// LayerID returns the layer ID of a layer on disk.

View File

@ -6,7 +6,7 @@ package wclayer
import (
"syscall"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/sirupsen/logrus"
)

View File

@ -1,7 +1,7 @@
package wclayer
import (
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/sirupsen/logrus"
)

View File

@ -1,6 +1,6 @@
package wclayer
import "github.com/Microsoft/hcsshim/internal/guid"
import "github.com/Microsoft/go-winio/pkg/guid"
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go wclayer.go

View File

@ -4,7 +4,7 @@ import (
"crypto/sha1"
"path/filepath"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/wclayer"
)
@ -77,7 +77,7 @@ type GUID [16]byte
func NameToGuid(name string) (id GUID, err error) {
g, err := wclayer.NameToGuid(name)
return GUID(g), err
return g.ToWindowsArray(), err
}
func NewGUID(source string) *GUID {
@ -88,7 +88,7 @@ func NewGUID(source string) *GUID {
}
func (g *GUID) ToString() string {
return (guid.GUID)(*g).String()
return guid.FromWindowsArray(*g).String()
}
type LayerReader = wclayer.LayerReader

View File

@ -2,9 +2,53 @@ package runhcs
import (
"context"
"errors"
"path/filepath"
"strconv"
)
// CreateScratch creates a scratch vhdx at 'destpath' that is ext4 formatted.
func (r *Runhcs) CreateScratch(context context.Context, destpath string) error {
return r.runOrError(r.command(context, "create-scratch", "--destpath", destpath))
return r.CreateScratchWithOpts(context, destpath, nil)
}
// CreateScratchOpts is the set of options that can be used with the
// `CreateScratchWithOpts` command.
type CreateScratchOpts struct {
// SizeGB is the size in GB of the scratch file to create.
SizeGB int
// CacheFile is the path to an existing `scratch.vhx` to copy. If
// `CacheFile` does not exit the scratch will be created.
CacheFile string
}
func (opt *CreateScratchOpts) args() ([]string, error) {
var out []string
if opt.SizeGB < 0 {
return nil, errors.New("sizeGB must be >= 0")
} else if opt.SizeGB > 0 {
out = append(out, "--sizeGB", strconv.Itoa(opt.SizeGB))
}
if opt.CacheFile != "" {
abs, err := filepath.Abs(opt.CacheFile)
if err != nil {
return nil, err
}
out = append(out, "--cache-path", abs)
}
return out, nil
}
// CreateScratchWithOpts creates a scratch vhdx at 'destpath' that is ext4
// formatted based on `opts`.
func (r *Runhcs) CreateScratchWithOpts(context context.Context, destpath string, opts *CreateScratchOpts) error {
args := []string{"create-scratch", "--destpath", destpath}
if opts != nil {
oargs, err := opts.args()
if err != nil {
return err
}
args = append(args, oargs...)
}
return r.runOrError(r.command(context, args...))
}

View File

@ -1,7 +1,9 @@
package hcsshim
import (
"context"
"io"
"sync"
"time"
"github.com/Microsoft/hcsshim/internal/hcs"
@ -9,7 +11,10 @@ import (
// ContainerError is an error encountered in HCS
type process struct {
p *hcs.Process
p *hcs.Process
waitOnce sync.Once
waitCh chan struct{}
waitErr error
}
// Pid returns the process ID of the process within the container.
@ -19,7 +24,14 @@ func (process *process) Pid() int {
// Kill signals the process to terminate but does not wait for it to finish terminating.
func (process *process) Kill() error {
return convertProcessError(process.p.Kill(), process)
found, err := process.p.Kill(context.Background())
if err != nil {
return convertProcessError(err, process)
}
if !found {
return &ProcessError{Process: process, Err: ErrElementNotFound, Operation: "hcsshim::Process::Kill"}
}
return nil
}
// Wait waits for the process to exit.
@ -30,7 +42,21 @@ func (process *process) Wait() error {
// WaitTimeout waits for the process to exit or the duration to elapse. It returns
// false if timeout occurs.
func (process *process) WaitTimeout(timeout time.Duration) error {
return convertProcessError(process.p.WaitTimeout(timeout), process)
process.waitOnce.Do(func() {
process.waitCh = make(chan struct{})
go func() {
process.waitErr = process.Wait()
close(process.waitCh)
}()
})
t := time.NewTimer(timeout)
defer t.Stop()
select {
case <-t.C:
return &ProcessError{Process: process, Err: ErrTimeout, Operation: "hcsshim::Process::Wait"}
case <-process.waitCh:
return process.waitErr
}
}
// ExitCode returns the exit code of the process. The process must have
@ -45,14 +71,14 @@ func (process *process) ExitCode() (int, error) {
// ResizeConsole resizes the console of the process.
func (process *process) ResizeConsole(width, height uint16) error {
return convertProcessError(process.p.ResizeConsole(width, height), process)
return convertProcessError(process.p.ResizeConsole(context.Background(), width, height), process)
}
// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
// these pipes does not close the underlying pipes; it should be possible to
// call this multiple times to get multiple interfaces.
func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
stdin, stdout, stderr, err := process.p.Stdio()
stdin, stdout, stderr, err := process.p.StdioLegacy()
if err != nil {
err = convertProcessError(err, process)
}
@ -62,7 +88,7 @@ func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, e
// CloseStdin closes the write side of the stdin pipe so that the process is
// notified on the read side that there is no more data in stdin.
func (process *process) CloseStdin() error {
return convertProcessError(process.p.CloseStdin(), process)
return convertProcessError(process.p.CloseStdin(context.Background()), process)
}
// Close cleans up any state associated with the process but does not kill

View File

@ -1,33 +0,0 @@
github.com/blang/semver v3.1.0
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
github.com/containerd/containerd faec567304bbdf6864b1663d4f813641b5880a4a
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
github.com/gogo/protobuf v1.0.0
github.com/golang/protobuf v1.1.0
github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55
github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/linuxkit/virtsock 8e79449dea0735c1c056d814934dd035734cc97c
github.com/Microsoft/go-winio c599b533b43b1363d7d7c6cfda5ede70ed73ff13
github.com/Microsoft/opengcs v0.3.9
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
github.com/opencontainers/runc 12f6a991201fdb8f82579582d5e00e28fba06d0a
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4
github.com/opencontainers/runtime-tools 1d69bd0f9c39677d0630e50664fbc3154ae61b88
github.com/pkg/errors v0.8.1
github.com/sirupsen/logrus v1.3.0
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
github.com/xeipuuv/gojsonpointer 4e3ac2762d5f479393488629ee9370b50873b3a6
github.com/xeipuuv/gojsonreference bd5ef7bd5415a7ac448318e64f11a24cd21e594b
github.com/xeipuuv/gojsonschema 1d523034197ff1f222f6429836dd36a2457a1874
golang.org/x/crypto ff983b9c42bc9fbf91556e191cc8efb585c16908
golang.org/x/net ed066c81e75eba56dd9bd2139ade88125b855585
golang.org/x/sync 37e7f081c4d4c64e13b10787722085407fe5d15f
golang.org/x/sys e5ecc2a6747ce8d4af18ed98b3de5ae30eb3a5bb
golang.org/x/text d14c52b222ee852cdba8b07206ca0c614b389876
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
google.golang.org/grpc v1.12.0
k8s.io/kubernetes v1.13.0

362
vendor/github.com/hashicorp/golang-lru/LICENSE generated vendored Normal file
View File

@ -0,0 +1,362 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. "Contributor"
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. "Incompatible With Secondary Licenses"
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the terms of
a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in a
separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, whether
at the time of the initial grant or subsequently, any and all of the
rights conveyed by this License.
1.10. "Modifications"
means any of the following:
a. any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the License,
by the making, using, selling, offering for sale, having made, import,
or transfer of either its Contributions or its Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, "control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights to
grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter the
recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty, or
limitations of liability) contained within the Source Code Form of the
Covered Software, except that You may alter any license notices to the
extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute,
judicial order, or regulation then You must: (a) comply with the terms of
this License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be placed in a
text file included with all distributions of the Covered Software under
this License. Except to the extent prohibited by statute or regulation,
such description must be sufficiently detailed for a recipient of ordinary
skill to be able to understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing
basis, if such Contributor fails to notify You of the non-compliance by
some reasonable means prior to 60 days after You have come back into
compliance. Moreover, Your grants from a particular Contributor are
reinstated on an ongoing basis if such Contributor notifies You of the
non-compliance by some reasonable means, this is the first time You have
received notice of non-compliance with this License from such
Contributor, and You become compliant prior to 30 days after Your receipt
of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an "as is" basis,
without warranty of any kind, either expressed, implied, or statutory,
including, without limitation, warranties that the Covered Software is free
of defects, merchantable, fit for a particular purpose or non-infringing.
The entire risk as to the quality and performance of the Covered Software
is with You. Should any Covered Software prove defective in any respect,
You (not any Contributor) assume the cost of any necessary servicing,
repair, or correction. This disclaimer of warranty constitutes an essential
part of this License. No use of any Covered Software is authorized under
this License except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from
such party's negligence to the extent applicable law prohibits such
limitation. Some jurisdictions do not allow the exclusion or limitation of
incidental or consequential damages, so this exclusion and limitation may
not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts
of a jurisdiction where the defendant maintains its principal place of
business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions. Nothing
in this Section shall prevent a party's ability to bring cross-claims or
counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides that
the language of a contract shall be construed against the drafter shall not
be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses If You choose to distribute Source Code Form that is
Incompatible With Secondary Licenses under the terms of this version of
the License, the notice described in Exhibit B of this License must be
attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file,
then You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a
notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible
With Secondary Licenses", as defined by
the Mozilla Public License, v. 2.0.

25
vendor/github.com/hashicorp/golang-lru/README.md generated vendored Normal file
View File

@ -0,0 +1,25 @@
golang-lru
==========
This provides the `lru` package which implements a fixed-size
thread safe LRU cache. It is based on the cache in Groupcache.
Documentation
=============
Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru)
Example
=======
Using the LRU is very simple:
```go
l, _ := New(128)
for i := 0; i < 256; i++ {
l.Add(i, nil)
}
if l.Len() != 128 {
panic(fmt.Sprintf("bad len: %v", l.Len()))
}
```

1
vendor/github.com/hashicorp/golang-lru/go.mod generated vendored Normal file
View File

@ -0,0 +1 @@
module github.com/hashicorp/golang-lru

161
vendor/github.com/hashicorp/golang-lru/simplelru/lru.go generated vendored Normal file
View File

@ -0,0 +1,161 @@
package simplelru
import (
"container/list"
"errors"
)
// EvictCallback is used to get a callback when a cache entry is evicted
type EvictCallback func(key interface{}, value interface{})
// LRU implements a non-thread safe fixed size LRU cache
type LRU struct {
size int
evictList *list.List
items map[interface{}]*list.Element
onEvict EvictCallback
}
// entry is used to hold a value in the evictList
type entry struct {
key interface{}
value interface{}
}
// NewLRU constructs an LRU of the given size
func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
if size <= 0 {
return nil, errors.New("Must provide a positive size")
}
c := &LRU{
size: size,
evictList: list.New(),
items: make(map[interface{}]*list.Element),
onEvict: onEvict,
}
return c, nil
}
// Purge is used to completely clear the cache.
func (c *LRU) Purge() {
for k, v := range c.items {
if c.onEvict != nil {
c.onEvict(k, v.Value.(*entry).value)
}
delete(c.items, k)
}
c.evictList.Init()
}
// Add adds a value to the cache. Returns true if an eviction occurred.
func (c *LRU) Add(key, value interface{}) (evicted bool) {
// Check for existing item
if ent, ok := c.items[key]; ok {
c.evictList.MoveToFront(ent)
ent.Value.(*entry).value = value
return false
}
// Add new item
ent := &entry{key, value}
entry := c.evictList.PushFront(ent)
c.items[key] = entry
evict := c.evictList.Len() > c.size
// Verify size not exceeded
if evict {
c.removeOldest()
}
return evict
}
// Get looks up a key's value from the cache.
func (c *LRU) Get(key interface{}) (value interface{}, ok bool) {
if ent, ok := c.items[key]; ok {
c.evictList.MoveToFront(ent)
return ent.Value.(*entry).value, true
}
return
}
// Contains checks if a key is in the cache, without updating the recent-ness
// or deleting it for being stale.
func (c *LRU) Contains(key interface{}) (ok bool) {
_, ok = c.items[key]
return ok
}
// Peek returns the key value (or undefined if not found) without updating
// the "recently used"-ness of the key.
func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) {
var ent *list.Element
if ent, ok = c.items[key]; ok {
return ent.Value.(*entry).value, true
}
return nil, ok
}
// Remove removes the provided key from the cache, returning if the
// key was contained.
func (c *LRU) Remove(key interface{}) (present bool) {
if ent, ok := c.items[key]; ok {
c.removeElement(ent)
return true
}
return false
}
// RemoveOldest removes the oldest item from the cache.
func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) {
ent := c.evictList.Back()
if ent != nil {
c.removeElement(ent)
kv := ent.Value.(*entry)
return kv.key, kv.value, true
}
return nil, nil, false
}
// GetOldest returns the oldest entry
func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) {
ent := c.evictList.Back()
if ent != nil {
kv := ent.Value.(*entry)
return kv.key, kv.value, true
}
return nil, nil, false
}
// Keys returns a slice of the keys in the cache, from oldest to newest.
func (c *LRU) Keys() []interface{} {
keys := make([]interface{}, len(c.items))
i := 0
for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() {
keys[i] = ent.Value.(*entry).key
i++
}
return keys
}
// Len returns the number of items in the cache.
func (c *LRU) Len() int {
return c.evictList.Len()
}
// removeOldest removes the oldest item from the cache.
func (c *LRU) removeOldest() {
ent := c.evictList.Back()
if ent != nil {
c.removeElement(ent)
}
}
// removeElement is used to remove a given list element from the cache
func (c *LRU) removeElement(e *list.Element) {
c.evictList.Remove(e)
kv := e.Value.(*entry)
delete(c.items, kv.key)
if c.onEvict != nil {
c.onEvict(kv.key, kv.value)
}
}

View File

@ -0,0 +1,36 @@
package simplelru
// LRUCache is the interface for simple LRU cache.
type LRUCache interface {
// Adds a value to the cache, returns true if an eviction occurred and
// updates the "recently used"-ness of the key.
Add(key, value interface{}) bool
// Returns key's value from the cache and
// updates the "recently used"-ness of the key. #value, isFound
Get(key interface{}) (value interface{}, ok bool)
// Check if a key exsists in cache without updating the recent-ness.
Contains(key interface{}) (ok bool)
// Returns key's value without updating the "recently used"-ness of the key.
Peek(key interface{}) (value interface{}, ok bool)
// Removes a key from the cache.
Remove(key interface{}) bool
// Removes the oldest entry from cache.
RemoveOldest() (interface{}, interface{}, bool)
// Returns the oldest entry from the cache. #key, value, isFound
GetOldest() (interface{}, interface{}, bool)
// Returns a slice of the keys in the cache, from oldest to newest.
Keys() []interface{}
// Returns the number of items in the cache.
Len() int
// Clear all cache entries
Purge()
}

202
vendor/go.opencensus.io/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

Some files were not shown because too many files have changed in this diff Show More