mirror of https://github.com/docker/cli.git
vendor: bump hcsshim b3f49c06ffaeef24d09c6c08ec8ec8425a0303e2
full diff: https://2226e083fc390003ae5aa8325c3c92789afa0e7a...b3f49c06ffaeef24d09c6c08ec8ec8425a0303e2 includes: - microsoft/hcsshim#718 wclayer: Work around Windows bug when expanding sandbox size - fixes microsoft/hcsshim#708 Windows Host Compute Service bug breaks docker (and other) sandboxes bigger than 20G on Windows 1903 - fixes microsoft/hcsshim#624The hcsshim on Windows 10 1903 always fails to build Docker image - fixes/addresses docker/for-win#3884 An error occurred while attempting to build Docker image (especially this comment and the next comments after: https://github.com/docker/for-win/issues/3884#issuecomment-498939672) - fixes/addresses docker/for-win#4100 Windows 1903 fails when storage-opt used - fixes moby/moby#36831 hcsshim::PrepareLayer failed in Win32: The parameter is incorrect (https://github.com/moby/moby/issues/36831#issuecomment-498612392) - fixes Stannieman/audacity-with-asio-builder#5 Docker won't build container - fixes MicrosoftDocs/visualstudio-docs#3523 Error when running build with storage-opts set - fixes moby/moby#39524 Docker build windows 19.03 --storage-opt size>20G Note that this is a temporary workaround for a bug in the platform, and will be reverted once that is addressed: - microsoft/hcsshim#721 Revert 718 when Windows 19H1 has expand sandbox fix Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
b822062959
commit
dff269b5e4
|
@ -42,7 +42,7 @@ github.com/konsorten/go-windows-terminal-sequences f55edac94c9bbba5d6182a4be46d
|
|||
github.com/mattn/go-shellwords 36a9b3c57cb5caa559ff63fb7e9b585f1c00df75 # v1.0.6
|
||||
github.com/matttproud/golang_protobuf_extensions c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
|
||||
github.com/Microsoft/go-winio 6c72808b55902eae4c5943626030429ff20f3b63 # v0.4.14
|
||||
github.com/Microsoft/hcsshim 2226e083fc390003ae5aa8325c3c92789afa0e7a
|
||||
github.com/Microsoft/hcsshim b3f49c06ffaeef24d09c6c08ec8ec8425a0303e2
|
||||
github.com/miekg/pkcs11 cb39313ec884f2cd77f4762875fe96aecf68f8e3 # v1.0.2
|
||||
github.com/mitchellh/mapstructure f15292f7a699fcc1a38a80977f80a046874ba8ac
|
||||
github.com/moby/buildkit f7042823e340d38d1746aa675b83d1aca431cee3 # v0.6.1-71-gf7042823
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/hcs"
|
||||
|
@ -53,6 +55,9 @@ type ResourceModificationRequestResponse = schema1.ResourceModificationRequestRe
|
|||
|
||||
type container struct {
|
||||
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.CreateProcess(context.Background(), 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)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
module github.com/Microsoft/hcsshim
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
|
||||
github.com/blang/semver v3.1.0+incompatible // indirect
|
||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1
|
||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69
|
||||
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-20190828154514-0e0f228740de
|
||||
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.1.2-0.20190507144316-5b71a03e2700
|
||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/prometheus/procfs v0.0.5 // indirect
|
||||
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-20190916202348-b4ddaad3f8a3
|
||||
google.golang.org/grpc v1.20.1
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
k8s.io/kubernetes v1.13.0
|
||||
)
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package cow
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/schema1"
|
||||
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
|
||||
)
|
||||
|
||||
// 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 targeting a V1 schema container.
|
||||
Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error)
|
||||
// PropertiesV2 returns the requested container properties targeting a V2 schema container.
|
||||
PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, 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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/Microsoft/hcsshim/internal/interop"
|
||||
"github.com/Microsoft/hcsshim/internal/logfields"
|
||||
"github.com/Microsoft/hcsshim/internal/vmcompute"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -88,7 +89,7 @@ type notificationChannel chan error
|
|||
|
||||
type notifcationWatcherContext struct {
|
||||
channels notificationChannels
|
||||
handle hcsCallback
|
||||
handle vmcompute.HcsCallback
|
||||
|
||||
systemID string
|
||||
processID int
|
||||
|
@ -98,21 +99,27 @@ type notificationChannels map[hcsNotification]notificationChannel
|
|||
|
||||
func newSystemChannels() notificationChannels {
|
||||
channels := make(notificationChannels)
|
||||
|
||||
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)
|
||||
|
||||
for _, notif := range []hcsNotification{
|
||||
hcsNotificationServiceDisconnect,
|
||||
hcsNotificationSystemExited,
|
||||
hcsNotificationSystemCreateCompleted,
|
||||
hcsNotificationSystemStartCompleted,
|
||||
hcsNotificationSystemPauseCompleted,
|
||||
hcsNotificationSystemResumeCompleted,
|
||||
} {
|
||||
channels[notif] = make(notificationChannel, 1)
|
||||
}
|
||||
return channels
|
||||
}
|
||||
|
||||
func newProcessChannels() notificationChannels {
|
||||
channels := make(notificationChannels)
|
||||
|
||||
channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
|
||||
|
||||
for _, notif := range []hcsNotification{
|
||||
hcsNotificationServiceDisconnect,
|
||||
hcsNotificationProcessExited,
|
||||
} {
|
||||
channels[notif] = make(notificationChannel, 1)
|
||||
}
|
||||
return channels
|
||||
}
|
||||
|
||||
|
@ -143,18 +150,7 @@ func notificationWatcher(notificationType hcsNotification, callbackNumber uintpt
|
|||
if context.processID != 0 {
|
||||
log.Data[logfields.ProcessID] = context.processID
|
||||
}
|
||||
log.Debug("")
|
||||
|
||||
// The HCS notification system can grow overtime. We explicitly opt-in to
|
||||
// the notifications we would like to handle, all others we simply return.
|
||||
// This means that as it grows we don't have issues associated with new
|
||||
// notification types the code didn't know about.
|
||||
switch notificationType {
|
||||
case hcsNotificationSystemExited, hcsNotificationSystemCreateCompleted, hcsNotificationSystemStartCompleted, hcsNotificationSystemPauseCompleted, hcsNotificationSystemResumeCompleted:
|
||||
case hcsNotificationProcessExited:
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
log.Debug("HCS notification")
|
||||
|
||||
if channel, ok := context.channels[notificationType]; ok {
|
||||
channel <- result
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
@ -292,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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.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?
|
||||
|
||||
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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -1,52 +1,47 @@
|
|||
package hcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"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
|
||||
hasCachedStdio bool
|
||||
stdioLock sync.Mutex
|
||||
stdin io.WriteCloser
|
||||
stdout io.ReadCloser
|
||||
stderr io.ReadCloser
|
||||
callbackNumber uintptr
|
||||
|
||||
logctx logrus.Fields
|
||||
|
||||
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 +57,7 @@ type closeHandle struct {
|
|||
Handle string
|
||||
}
|
||||
|
||||
type ProcessStatus struct {
|
||||
type processStatus struct {
|
||||
ProcessID uint32
|
||||
Exited bool
|
||||
ExitCode uint32
|
||||
|
@ -90,24 +85,32 @@ 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`.
|
||||
|
@ -115,115 +118,120 @@ func (process *Process) logOperationEnd(operation string, err error) {
|
|||
// For LCOW `guestrequest.SignalProcessOptionsLCOW`.
|
||||
//
|
||||
// For WCOW `guestrequest.SignalProcessOptionsWCOW`.
|
||||
func (process *Process) Signal(options interface{}) (err error) {
|
||||
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)
|
||||
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, process.waitError, 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)
|
||||
|
@ -242,11 +250,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)
|
||||
}
|
||||
|
@ -254,109 +259,55 @@ 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
|
||||
}
|
||||
|
||||
if properties.Exited == false {
|
||||
return -1, makeProcessError(process, operation, ErrInvalidProcessState, nil)
|
||||
return process.exitCode, nil
|
||||
default:
|
||||
return -1, makeProcessError(process, "hcsshim::Process::ExitCode", 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. Once returned, these pipes
|
||||
// are the responsibility of the caller to close.
|
||||
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
|
||||
process.stdioLock.Lock()
|
||||
defer process.stdioLock.Unlock()
|
||||
if process.hasCachedStdio {
|
||||
stdin, stdout, stderr := process.stdin, process.stdout, process.stderr
|
||||
process.stdin, process.stdout, process.stderr = nil, nil, nil
|
||||
process.hasCachedStdio = false
|
||||
return stdin, stdout, stderr, nil
|
||||
}
|
||||
|
||||
if process.cachedPipes == nil {
|
||||
var (
|
||||
processInfo hcsProcessInformation
|
||||
resultp *uint16
|
||||
)
|
||||
err = hcsGetProcessInfo(process.handle, &processInfo, &resultp)
|
||||
events := processHcsResult(resultp)
|
||||
processInfo, resultJSON, err := vmcompute.HcsGetProcessInfo(ctx, process.handle)
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -364,15 +315,21 @@ 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) {
|
||||
process.stdioLock.Lock()
|
||||
defer process.stdioLock.Unlock()
|
||||
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)
|
||||
|
@ -390,51 +347,76 @@ 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)
|
||||
}
|
||||
|
||||
process.stdioLock.Lock()
|
||||
if process.stdin != nil {
|
||||
process.stdin.Close()
|
||||
process.stdin = nil
|
||||
}
|
||||
process.stdioLock.Unlock()
|
||||
|
||||
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 {
|
||||
process.stdioLock.Lock()
|
||||
if process.stdin != nil {
|
||||
process.stdin.Close()
|
||||
process.stdin = nil
|
||||
}
|
||||
if process.stdout != nil {
|
||||
process.stdout.Close()
|
||||
process.stdout = nil
|
||||
}
|
||||
if process.stderr != nil {
|
||||
process.stderr.Close()
|
||||
process.stderr = nil
|
||||
}
|
||||
process.stdioLock.Unlock()
|
||||
|
||||
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 := ¬ifcationWatcherContext{
|
||||
func (process *Process) registerCallback(ctx context.Context) error {
|
||||
callbackContext := ¬ifcationWatcherContext{
|
||||
channels: newProcessChannels(),
|
||||
systemID: process.SystemID(),
|
||||
processID: process.processID,
|
||||
|
@ -443,45 +425,44 @@ func (process *Process) registerCallback() error {
|
|||
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)
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
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"
|
||||
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
|
||||
"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,54 +44,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
|
||||
|
||||
os, typ string
|
||||
}
|
||||
|
||||
func newSystem(id string) *System {
|
||||
return &System{
|
||||
id: id,
|
||||
logctx: logrus.Fields{
|
||||
logfields.ContainerID: 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 {
|
||||
|
@ -94,129 +83,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
|
||||
}
|
||||
|
||||
// GetComputeSystems gets a list of the compute systems on the system that match the query
|
||||
func GetComputeSystems(q schema1.ComputeSystemQuery) (_ []schema1.ContainerProperties, err 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"
|
||||
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
|
||||
}
|
||||
|
||||
logOperationEnd(
|
||||
fields,
|
||||
operation+" - End Operation - "+result,
|
||||
err)
|
||||
}()
|
||||
// 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(ctx context.Context, q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) {
|
||||
operation := "hcsshim::GetComputeSystems"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -224,16 +198,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
|
||||
|
@ -262,13 +241,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
|
||||
|
@ -279,273 +255,257 @@ 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 IsAlreadyClosed(err) || 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 IsAlreadyClosed(err) || IsAlreadyStopped(err) || 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)
|
||||
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) {
|
||||
// Properties returns the requested container properties targeting a V1 schema container.
|
||||
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"
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
queryString := string(queryBytes)
|
||||
logrus.WithFields(computeSystem.logctx).
|
||||
WithField(logfields.JSON, queryString).
|
||||
Debug("HCS ComputeSystem Properties Query")
|
||||
|
||||
var resultp, propertiesp *uint16
|
||||
syscallWatcher(computeSystem.logctx, func() {
|
||||
err = hcsGetComputeSystemProperties(computeSystem.handle, string(queryString), &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
|
||||
}
|
||||
|
||||
// PropertiesV2 returns the requested container properties targeting a V2 schema container.
|
||||
func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) {
|
||||
computeSystem.handleLock.RLock()
|
||||
defer computeSystem.handleLock.RUnlock()
|
||||
|
||||
operation := "hcsshim::System::PropertiesV2"
|
||||
|
||||
queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types})
|
||||
if err != nil {
|
||||
return nil, makeSystemError(computeSystem, operation, "", err, nil)
|
||||
}
|
||||
|
||||
propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes))
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
if err != nil {
|
||||
return nil, makeSystemError(computeSystem, operation, "", err, events)
|
||||
}
|
||||
|
||||
if propertiesJSON == "" {
|
||||
return nil, ErrUnexpectedValue
|
||||
}
|
||||
properties := &hcsschema.Properties{}
|
||||
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,
|
||||
// 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()
|
||||
}
|
||||
}()
|
||||
|
||||
if err = process.registerCallback(); err != nil {
|
||||
return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
|
||||
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]
|
||||
process.hasCachedStdio = true
|
||||
|
||||
if err = process.registerCallback(ctx); err != nil {
|
||||
return nil, makeSystemError(computeSystem, operation, "", err, nil)
|
||||
}
|
||||
go process.waitBackground()
|
||||
|
||||
|
@ -553,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()
|
||||
|
||||
|
@ -593,39 +540,40 @@ 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 := ¬ifcationWatcherContext{
|
||||
func (computeSystem *System) registerCallback(ctx context.Context) error {
|
||||
callbackContext := ¬ifcationWatcherContext{
|
||||
channels: newSystemChannels(),
|
||||
systemID: computeSystem.id,
|
||||
}
|
||||
|
@ -633,32 +581,31 @@ func (computeSystem *System) registerCallback() error {
|
|||
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
|
||||
|
@ -666,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)
|
||||
|
@ -683,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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -57,6 +57,7 @@ type OutboundNatPolicy struct {
|
|||
Policy
|
||||
VIP string `json:"VIP,omitempty"`
|
||||
Exceptions []string `json:"ExceptionList,omitempty"`
|
||||
Destinations []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type ActionType string
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Attachment struct {
|
||||
|
||||
Type_ string `json:"Type,omitempty"`
|
||||
|
||||
Path string `json:"Path,omitempty"`
|
||||
|
|
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/cache_query_stats_response.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/cache_query_stats_response.go
generated
vendored
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type CacheQueryStatsResponse struct {
|
||||
|
||||
L3OccupancyBytes int32 `json:"L3OccupancyBytes,omitempty"`
|
||||
|
||||
L3TotalBwBytes int32 `json:"L3TotalBwBytes,omitempty"`
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type CloseHandle struct {
|
||||
|
||||
Handle string `json:"Handle,omitempty"`
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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"`
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type ConsoleSize struct {
|
||||
|
||||
Height int32 `json:"Height,omitempty"`
|
||||
|
||||
Width int32 `json:"Width,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Container struct {
|
||||
|
||||
GuestOs *GuestOs `json:"GuestOs,omitempty"`
|
||||
|
||||
Storage *Storage `json:"Storage,omitempty"`
|
||||
|
|
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/container_memory_information.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/container_memory_information.go
generated
vendored
|
@ -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"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Devices struct {
|
||||
|
||||
ComPorts map[string]ComPort `json:"ComPorts,omitempty"`
|
||||
|
||||
Scsi map[string]Scsi `json:"Scsi,omitempty"`
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type EnhancedModeVideo struct {
|
||||
|
||||
ConnectionOptions *RdpConnectionOptions `json:"ConnectionOptions,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type FlexibleIoDevice struct {
|
||||
|
||||
EmulatorId string `json:"EmulatorId,omitempty"`
|
||||
|
||||
HostingModel string `json:"HostingModel,omitempty"`
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type GuestCrashReporting struct {
|
||||
|
||||
WindowsCrashSettings *WindowsCrashReporting `json:"WindowsCrashSettings,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type GuestOs struct {
|
||||
|
||||
HostName string `json:"HostName,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type HostedSystem struct {
|
||||
|
||||
SchemaVersion *Version `json:"SchemaVersion,omitempty"`
|
||||
|
||||
Container *Container `json:"Container,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type HvSocket struct {
|
||||
|
||||
Config *HvSocketSystemConfig `json:"Config,omitempty"`
|
||||
|
||||
EnablePowerShellDirect bool `json:"EnablePowerShellDirect,omitempty"`
|
||||
|
|
|
@ -11,6 +11,5 @@ package hcsschema
|
|||
|
||||
// HvSocket configuration for a VM
|
||||
type HvSocket2 struct {
|
||||
|
||||
HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Layer struct {
|
||||
|
||||
Id string `json:"Id,omitempty"`
|
||||
|
||||
Path string `json:"Path,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type MappedDirectory struct {
|
||||
|
||||
HostPath string `json:"HostPath,omitempty"`
|
||||
|
||||
HostPathType string `json:"HostPathType,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type MappedPipe struct {
|
||||
|
||||
ContainerPipeName string `json:"ContainerPipeName,omitempty"`
|
||||
|
||||
HostPath string `json:"HostPath,omitempty"`
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type Memory struct {
|
||||
|
||||
SizeInMB int32 `json:"SizeInMB,omitempty"`
|
||||
}
|
||||
|
|
|
@ -22,4 +22,9 @@ type Memory2 struct {
|
|||
|
||||
// EnableDeferredCommit is private in the schema. If regenerated need to add back.
|
||||
EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"`
|
||||
|
||||
// EnableColdDiscardHint if enabled, then the memory cold discard hint feature is exposed
|
||||
// to the VM, allowing it to trim non-zeroed pages from the working set (if supported by
|
||||
// the guest operating system).
|
||||
EnableColdDiscardHint bool `json:"EnableColdDiscardHint,omitempty"`
|
||||
}
|
||||
|
|
3
vendor/github.com/Microsoft/hcsshim/internal/schema2/memory_information_for_vm.go
generated
vendored
3
vendor/github.com/Microsoft/hcsshim/internal/schema2/memory_information_for_vm.go
generated
vendored
|
@ -10,8 +10,7 @@
|
|||
package hcsschema
|
||||
|
||||
type MemoryInformationForVm struct {
|
||||
|
||||
VirtualNodeCount int32 `json:"VirtualNodeCount,omitempty"`
|
||||
VirtualNodeCount uint32 `json:"VirtualNodeCount,omitempty"`
|
||||
|
||||
VirtualMachineMemory *VmMemory `json:"VirtualMachineMemory,omitempty"`
|
||||
|
||||
|
|
|
@ -11,10 +11,9 @@ package hcsschema
|
|||
|
||||
// Memory runtime statistics
|
||||
type MemoryStats struct {
|
||||
MemoryUsageCommitBytes uint64 `json:"MemoryUsageCommitBytes,omitempty"`
|
||||
|
||||
MemoryUsageCommitBytes int32 `json:"MemoryUsageCommitBytes,omitempty"`
|
||||
MemoryUsageCommitPeakBytes uint64 `json:"MemoryUsageCommitPeakBytes,omitempty"`
|
||||
|
||||
MemoryUsageCommitPeakBytes int32 `json:"MemoryUsageCommitPeakBytes,omitempty"`
|
||||
|
||||
MemoryUsagePrivateWorkingSetBytes int32 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
|
||||
MemoryUsagePrivateWorkingSetBytes uint64 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type NetworkAdapter struct {
|
||||
|
||||
EndpointId string `json:"EndpointId,omitempty"`
|
||||
|
||||
MacAddress string `json:"MacAddress,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Networking struct {
|
||||
|
||||
AllowUnqualifiedDnsQuery bool `json:"AllowUnqualifiedDnsQuery,omitempty"`
|
||||
|
||||
DnsSearchList string `json:"DnsSearchList,omitempty"`
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ package hcsschema
|
|||
|
||||
// Options for HcsPauseComputeSystem
|
||||
type PauseOptions struct {
|
||||
|
||||
SuspensionLevel string `json:"SuspensionLevel,omitempty"`
|
||||
|
||||
HostedNotification *PauseNotification `json:"HostedNotification,omitempty"`
|
||||
|
|
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type Plan9 struct {
|
||||
|
||||
Shares []Plan9Share `json:"Shares,omitempty"`
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -11,7 +11,6 @@ package hcsschema
|
|||
|
||||
// Passed to HcsRpc_ModifyProcess
|
||||
type ProcessModifyRequest struct {
|
||||
|
||||
Operation string `json:"Operation,omitempty"`
|
||||
|
||||
ConsoleSize *ConsoleSize `json:"ConsoleSize,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type ProcessParameters struct {
|
||||
|
||||
ApplicationName string `json:"ApplicationName,omitempty"`
|
||||
|
||||
CommandLine string `json:"CommandLine,omitempty"`
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Processor struct {
|
||||
|
||||
Count int32 `json:"Count,omitempty"`
|
||||
|
||||
Maximum int32 `json:"Maximum,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Processor2 struct {
|
||||
|
||||
Count int32 `json:"Count,omitempty"`
|
||||
|
||||
Limit int32 `json:"Limit,omitempty"`
|
||||
|
|
|
@ -11,10 +11,9 @@ package hcsschema
|
|||
|
||||
// CPU runtime statistics
|
||||
type ProcessorStats struct {
|
||||
TotalRuntime100ns uint64 `json:"TotalRuntime100ns,omitempty"`
|
||||
|
||||
TotalRuntime100ns int32 `json:"TotalRuntime100ns,omitempty"`
|
||||
RuntimeUser100ns uint64 `json:"RuntimeUser100ns,omitempty"`
|
||||
|
||||
RuntimeUser100ns int32 `json:"RuntimeUser100ns,omitempty"`
|
||||
|
||||
RuntimeKernel100ns int32 `json:"RuntimeKernel100ns,omitempty"`
|
||||
RuntimeKernel100ns uint64 `json:"RuntimeKernel100ns,omitempty"`
|
||||
}
|
||||
|
|
|
@ -9,8 +9,11 @@
|
|||
|
||||
package hcsschema
|
||||
|
||||
type Properties struct {
|
||||
import (
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
)
|
||||
|
||||
type Properties struct {
|
||||
Id string `json:"Id,omitempty"`
|
||||
|
||||
SystemType string `json:"SystemType,omitempty"`
|
||||
|
@ -44,4 +47,8 @@ type Properties struct {
|
|||
SharedMemoryRegionInfo []SharedMemoryRegionInfo `json:"SharedMemoryRegionInfo,omitempty"`
|
||||
|
||||
GuestConnectionInfo *GuestConnectionInfo `json:"GuestConnectionInfo,omitempty"`
|
||||
|
||||
// Metrics is not part of the API for HCS but this is used for LCOW v2 to
|
||||
// return the full cgroup metrics from the guest.
|
||||
Metrics *v1.Metrics `json:"LCOWMetrics,omitempty"`
|
||||
}
|
||||
|
|
|
@ -11,6 +11,5 @@ package hcsschema
|
|||
|
||||
// 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"`
|
||||
PropertyTypes []PropertyType `json:"PropertyTypes,omitempty"`
|
||||
}
|
||||
|
|
23
vendor/github.com/Microsoft/hcsshim/internal/schema2/property_type.go
generated
vendored
Normal file
23
vendor/github.com/Microsoft/hcsshim/internal/schema2/property_type.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.1
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type PropertyType string
|
||||
|
||||
const (
|
||||
PTMemory PropertyType = "Memory"
|
||||
PTGuestMemory PropertyType = "GuestMemory"
|
||||
PTStatistics PropertyType = "Statistics"
|
||||
PTProcessList PropertyType = "ProcessList"
|
||||
PTTerminateOnLastHandleClosed PropertyType = "TerminateOnLastHandleClosed"
|
||||
PTSharedMemoryRegion PropertyType = "SharedMemoryRegion"
|
||||
PTGuestConnection PropertyType = "GuestConnection"
|
||||
PTICHeartbeatStatus PropertyType = "ICHeartbeatStatus"
|
||||
)
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type RdpConnectionOptions struct {
|
||||
|
||||
AccessSids []string `json:"AccessSids,omitempty"`
|
||||
|
||||
NamedPipe string `json:"NamedPipe,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type RegistryChanges struct {
|
||||
|
||||
AddValues []RegistryValue `json:"AddValues,omitempty"`
|
||||
|
||||
DeleteKeys []RegistryKey `json:"DeleteKeys,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type RegistryKey struct {
|
||||
|
||||
Hive string `json:"Hive,omitempty"`
|
||||
|
||||
Name string `json:"Name,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type RegistryValue struct {
|
||||
|
||||
Key *RegistryKey `json:"Key,omitempty"`
|
||||
|
||||
Name string `json:"Name,omitempty"`
|
||||
|
|
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/shared_memory_configuration.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/shared_memory_configuration.go
generated
vendored
|
@ -10,6 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type SharedMemoryConfiguration struct {
|
||||
|
||||
Regions []SharedMemoryRegion `json:"Regions,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type SharedMemoryRegion struct {
|
||||
|
||||
SectionName string `json:"SectionName,omitempty"`
|
||||
|
||||
StartOffset int32 `json:"StartOffset,omitempty"`
|
||||
|
|
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/shared_memory_region_info.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/shared_memory_region_info.go
generated
vendored
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type SharedMemoryRegionInfo struct {
|
||||
|
||||
SectionName string `json:"SectionName,omitempty"`
|
||||
|
||||
GuestPhysicalAddress int32 `json:"GuestPhysicalAddress,omitempty"`
|
||||
|
|
|
@ -11,7 +11,6 @@ package hcsschema
|
|||
|
||||
// Silo job information
|
||||
type SiloProperties struct {
|
||||
|
||||
Enabled bool `json:"Enabled,omitempty"`
|
||||
|
||||
JobName string `json:"JobName,omitempty"`
|
||||
|
|
|
@ -15,12 +15,11 @@ import (
|
|||
|
||||
// Runtime statistics for a container
|
||||
type Statistics struct {
|
||||
|
||||
Timestamp time.Time `json:"Timestamp,omitempty"`
|
||||
|
||||
ContainerStartTime time.Time `json:"ContainerStartTime,omitempty"`
|
||||
|
||||
Uptime100ns int32 `json:"Uptime100ns,omitempty"`
|
||||
Uptime100ns uint64 `json:"Uptime100ns,omitempty"`
|
||||
|
||||
Processor *ProcessorStats `json:"Processor,omitempty"`
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type StorageQoS struct {
|
||||
|
||||
IopsMaximum int32 `json:"IopsMaximum,omitempty"`
|
||||
|
||||
BandwidthMaximum int32 `json:"BandwidthMaximum,omitempty"`
|
||||
|
|
|
@ -11,12 +11,11 @@ package hcsschema
|
|||
|
||||
// Storage runtime statistics
|
||||
type StorageStats struct {
|
||||
ReadCountNormalized uint64 `json:"ReadCountNormalized,omitempty"`
|
||||
|
||||
ReadCountNormalized int32 `json:"ReadCountNormalized,omitempty"`
|
||||
ReadSizeBytes uint64 `json:"ReadSizeBytes,omitempty"`
|
||||
|
||||
ReadSizeBytes int32 `json:"ReadSizeBytes,omitempty"`
|
||||
WriteCountNormalized uint64 `json:"WriteCountNormalized,omitempty"`
|
||||
|
||||
WriteCountNormalized int32 `json:"WriteCountNormalized,omitempty"`
|
||||
|
||||
WriteSizeBytes int32 `json:"WriteSizeBytes,omitempty"`
|
||||
WriteSizeBytes uint64 `json:"WriteSizeBytes,omitempty"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Topology struct {
|
||||
|
||||
Memory *Memory2 `json:"Memory,omitempty"`
|
||||
|
||||
Processor *Processor2 `json:"Processor,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Uefi struct {
|
||||
|
||||
EnableDebugger bool `json:"EnableDebugger,omitempty"`
|
||||
|
||||
SecureBootTemplateId string `json:"SecureBootTemplateId,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type UefiBootEntry struct {
|
||||
|
||||
DeviceType string `json:"DeviceType,omitempty"`
|
||||
|
||||
DevicePath string `json:"DevicePath,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type Version struct {
|
||||
|
||||
Major int32 `json:"Major,omitempty"`
|
||||
|
||||
Minor int32 `json:"Minor,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type VideoMonitor struct {
|
||||
|
||||
HorizontalResolution int32 `json:"HorizontalResolution,omitempty"`
|
||||
|
||||
VerticalResolution int32 `json:"VerticalResolution,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type VirtualNodeInfo struct {
|
||||
|
||||
VirtualNodeIndex int32 `json:"VirtualNodeIndex,omitempty"`
|
||||
|
||||
PhysicalNodeNumber int32 `json:"PhysicalNodeNumber,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type VirtualPMemDevice struct {
|
||||
|
||||
HostPath string `json:"HostPath,omitempty"`
|
||||
|
||||
ReadOnly bool `json:"ReadOnly,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type VirtualSmb struct {
|
||||
|
||||
Shares []VirtualSmbShare `json:"Shares,omitempty"`
|
||||
|
||||
DirectFileMappingInMB int64 `json:"DirectFileMappingInMB,omitempty"`
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type VirtualSmbShare struct {
|
||||
|
||||
Name string `json:"Name,omitempty"`
|
||||
|
||||
Path string `json:"Path,omitempty"`
|
||||
|
|
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/virtual_smb_share_options.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/virtual_smb_share_options.go
generated
vendored
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type VirtualSmbShareOptions struct {
|
||||
|
||||
ReadOnly bool `json:"ReadOnly,omitempty"`
|
||||
|
||||
// convert exclusive access to shared read access
|
||||
|
|
|
@ -10,14 +10,13 @@
|
|||
package hcsschema
|
||||
|
||||
type VmMemory struct {
|
||||
|
||||
AvailableMemory int32 `json:"AvailableMemory,omitempty"`
|
||||
|
||||
AvailableMemoryBuffer int32 `json:"AvailableMemoryBuffer,omitempty"`
|
||||
|
||||
ReservedMemory int32 `json:"ReservedMemory,omitempty"`
|
||||
ReservedMemory uint64 `json:"ReservedMemory,omitempty"`
|
||||
|
||||
AssignedMemory int32 `json:"AssignedMemory,omitempty"`
|
||||
AssignedMemory uint64 `json:"AssignedMemory,omitempty"`
|
||||
|
||||
SlpActive bool `json:"SlpActive,omitempty"`
|
||||
|
||||
|
|
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/windows_crash_reporting.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/schema2/windows_crash_reporting.go
generated
vendored
|
@ -10,7 +10,6 @@
|
|||
package hcsschema
|
||||
|
||||
type WindowsCrashReporting struct {
|
||||
|
||||
DumpFileName string `json:"DumpFileName,omitempty"`
|
||||
|
||||
MaxDumpSize int64 `json:"MaxDumpSize,omitempty"`
|
||||
|
|
565
vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go
generated
vendored
Normal file
565
vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go
generated
vendored
Normal file
|
@ -0,0 +1,565 @@
|
|||
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))
|
||||
}
|
||||
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 := 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)
|
||||
})
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated mksyscall_windows.exe DO NOT EDIT
|
||||
|
||||
package hcs
|
||||
package vmcompute
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
@ -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,7 +416,7 @@ 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) {
|
||||
func _hcsSignalProcess(process HcsProcess, options *uint16, result **uint16) (hr error) {
|
||||
if hr = procHcsSignalProcess.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
|
@ -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
|
||||
}
|
|
@ -1,7 +1,13 @@
|
|||
package wclayer
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/hcserror"
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -26,5 +32,114 @@ func ExpandScratchSize(path string, size uint64) (err error) {
|
|||
if err != nil {
|
||||
return hcserror.New(err, title+" - failed", "")
|
||||
}
|
||||
|
||||
// Manually expand the volume now in order to work around bugs in 19H1 and
|
||||
// prerelease versions of Vb. Remove once this is fixed in Windows.
|
||||
if build := osversion.Get().Build; build >= osversion.V19H1 && build < 19020 {
|
||||
err = expandSandboxVolume(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type virtualStorageType struct {
|
||||
DeviceID uint32
|
||||
VendorID [16]byte
|
||||
}
|
||||
|
||||
type openVersion2 struct {
|
||||
GetInfoOnly int32 // bool but 4-byte aligned
|
||||
ReadOnly int32 // bool but 4-byte aligned
|
||||
ResiliencyGUID [16]byte // GUID
|
||||
}
|
||||
|
||||
type openVirtualDiskParameters struct {
|
||||
Version uint32 // Must always be set to 2
|
||||
Version2 openVersion2
|
||||
}
|
||||
|
||||
func attachVhd(path string) (syscall.Handle, error) {
|
||||
var (
|
||||
defaultType virtualStorageType
|
||||
handle syscall.Handle
|
||||
)
|
||||
parameters := openVirtualDiskParameters{Version: 2}
|
||||
err := openVirtualDisk(
|
||||
&defaultType,
|
||||
path,
|
||||
0,
|
||||
0,
|
||||
¶meters,
|
||||
&handle)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "OpenVirtualDisk", Path: path, Err: err}
|
||||
}
|
||||
err = attachVirtualDisk(handle, 0, 0, 0, 0, 0)
|
||||
if err != nil {
|
||||
syscall.Close(handle)
|
||||
return 0, &os.PathError{Op: "AttachVirtualDisk", Path: path, Err: err}
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
func expandSandboxVolume(path string) error {
|
||||
// Mount the sandbox VHD temporarily.
|
||||
vhdPath := filepath.Join(path, "sandbox.vhdx")
|
||||
vhd, err := attachVhd(vhdPath)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "OpenVirtualDisk", Path: vhdPath, Err: err}
|
||||
}
|
||||
defer syscall.Close(vhd)
|
||||
|
||||
// Open the volume.
|
||||
volumePath, err := GetLayerMountPath(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if volumePath[len(volumePath)-1] == '\\' {
|
||||
volumePath = volumePath[:len(volumePath)-1]
|
||||
}
|
||||
volume, err := os.OpenFile(volumePath, os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer volume.Close()
|
||||
|
||||
// Get the volume's underlying partition size in NTFS clusters.
|
||||
var (
|
||||
partitionSize int64
|
||||
bytes uint32
|
||||
)
|
||||
const _IOCTL_DISK_GET_LENGTH_INFO = 0x0007405C
|
||||
err = syscall.DeviceIoControl(syscall.Handle(volume.Fd()), _IOCTL_DISK_GET_LENGTH_INFO, nil, 0, (*byte)(unsafe.Pointer(&partitionSize)), 8, &bytes, nil)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "IOCTL_DISK_GET_LENGTH_INFO", Path: volume.Name(), Err: err}
|
||||
}
|
||||
const (
|
||||
clusterSize = 4096
|
||||
sectorSize = 512
|
||||
)
|
||||
targetClusters := partitionSize / clusterSize
|
||||
|
||||
// Get the volume's current size in NTFS clusters.
|
||||
var volumeSize int64
|
||||
err = getDiskFreeSpaceEx(volume.Name()+"\\", nil, &volumeSize, nil)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "GetDiskFreeSpaceEx", Path: volume.Name(), Err: err}
|
||||
}
|
||||
volumeClusters := volumeSize / clusterSize
|
||||
|
||||
// Only resize the volume if there is space to grow, otherwise this will
|
||||
// fail with invalid parameter. NTFS reserves one cluster.
|
||||
if volumeClusters+1 < targetClusters {
|
||||
targetSectors := targetClusters * (clusterSize / sectorSize)
|
||||
const _FSCTL_EXTEND_VOLUME = 0x000900F0
|
||||
err = syscall.DeviceIoControl(syscall.Handle(volume.Fd()), _FSCTL_EXTEND_VOLUME, (*byte)(unsafe.Pointer(&targetSectors)), 8, nil, 0, &bytes, nil)
|
||||
if err != nil {
|
||||
return &os.PathError{Op: "FSCTL_EXTEND_VOLUME", Path: volume.Name(), Err: err}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -24,4 +24,9 @@ import "github.com/Microsoft/hcsshim/internal/guid"
|
|||
|
||||
//sys grantVmAccess(vmid string, filepath string) (hr error) = vmcompute.GrantVmAccess?
|
||||
|
||||
//sys openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk
|
||||
//sys attachVirtualDisk(handle syscall.Handle, sd uintptr, flags uint32, providerFlags uint32, params uintptr, overlapped uintptr) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk
|
||||
|
||||
//sys getDiskFreeSpaceEx(directoryName string, freeBytesAvailableToCaller *int64, totalNumberOfBytes *int64, totalNumberOfFreeBytes *int64) (err error) = GetDiskFreeSpaceExW
|
||||
|
||||
type _guid = guid.GUID
|
||||
|
|
|
@ -38,6 +38,8 @@ func errnoErr(e syscall.Errno) error {
|
|||
|
||||
var (
|
||||
modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
|
||||
modvirtdisk = windows.NewLazySystemDLL("virtdisk.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
|
||||
procActivateLayer = modvmcompute.NewProc("ActivateLayer")
|
||||
procCopyLayer = modvmcompute.NewProc("CopyLayer")
|
||||
|
@ -57,6 +59,9 @@ var (
|
|||
procProcessBaseImage = modvmcompute.NewProc("ProcessBaseImage")
|
||||
procProcessUtilityImage = modvmcompute.NewProc("ProcessUtilityImage")
|
||||
procGrantVmAccess = modvmcompute.NewProc("GrantVmAccess")
|
||||
procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk")
|
||||
procAttachVirtualDisk = modvirtdisk.NewProc("AttachVirtualDisk")
|
||||
procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
|
||||
)
|
||||
|
||||
func activateLayer(info *driverInfo, id string) (hr error) {
|
||||
|
@ -508,3 +513,57 @@ func _grantVmAccess(vmid *uint16, filepath *uint16) (hr error) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, flags, parameters, handle)
|
||||
}
|
||||
|
||||
func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(flags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func attachVirtualDisk(handle syscall.Handle, sd uintptr, flags uint32, providerFlags uint32, params uintptr, overlapped uintptr) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(sd), uintptr(flags), uintptr(providerFlags), uintptr(params), uintptr(overlapped))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getDiskFreeSpaceEx(directoryName string, freeBytesAvailableToCaller *int64, totalNumberOfBytes *int64, totalNumberOfFreeBytes *int64) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(directoryName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _getDiskFreeSpaceEx(_p0, freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes)
|
||||
}
|
||||
|
||||
func _getDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *int64, totalNumberOfBytes *int64, totalNumberOfFreeBytes *int64) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -14,10 +14,14 @@ const (
|
|||
RS3 = 16299
|
||||
|
||||
// RS4 (version 1803, codename "Redstone 4") corresponds to Windows Server
|
||||
// 1809 (Semi-Annual Channel (SAC)), and Windows 10 (April 2018 Update).
|
||||
// 1803 (Semi-Annual Channel (SAC)), and Windows 10 (April 2018 Update).
|
||||
RS4 = 17134
|
||||
|
||||
// RS5 (version 1809, codename "Redstone 5") corresponds to Windows Server
|
||||
// 2019 (ltsc2019), and Windows 10 (October 2018 Update).
|
||||
RS5 = 17763
|
||||
|
||||
// V19H1 (version 1903) corresponds to Windows Server 1903 (semi-annual
|
||||
// channel).
|
||||
V19H1 = 18362
|
||||
)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package hcsshim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/hcs"
|
||||
|
@ -10,6 +12,9 @@ import (
|
|||
// ContainerError is an error encountered in HCS
|
||||
type process struct {
|
||||
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
|
||||
|
|
|
@ -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 84b4ab48a50763fe7b3abcef38e5205c12027fac
|
||||
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
|
Loading…
Reference in New Issue