Merge component 'engine' from git@github.com:docker/engine 18.09

This commit is contained in:
GordonTheTurtle
2018-11-27 21:00:40 +00:00
163 changed files with 5140 additions and 1042 deletions

View File

@ -6,12 +6,14 @@ import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"io"
"net/http"
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
gddohttputil "github.com/golang/gddo/httputil"
)
@ -37,7 +39,10 @@ func (s *containerRouter) postContainersCopy(ctx context.Context, w http.Respons
cfg := types.CopyConfig{}
if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
if cfg.Resource == "" {

View File

@ -3,6 +3,7 @@ package container // import "github.com/docker/docker/api/server/router/containe
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
@ -44,7 +45,10 @@ func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.Re
execConfig := &types.ExecConfig{}
if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
if len(execConfig.Cmd) == 0 {
@ -84,7 +88,10 @@ func (s *containerRouter) postContainerExecStart(ctx context.Context, w http.Res
execStartCheck := &types.ExecStartCheck{}
if err := json.NewDecoder(r.Body).Decode(execStartCheck); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
if exists, err := s.backend.ExecExists(execName); !exists {

View File

@ -3,6 +3,7 @@ package network // import "github.com/docker/docker/api/server/router/network"
import (
"context"
"encoding/json"
"io"
"net/http"
"strconv"
"strings"
@ -215,7 +216,10 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr
}
if err := json.NewDecoder(r.Body).Decode(&create); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
if nws, err := n.cluster.GetNetworksByName(create.Name); err == nil && len(nws) > 0 {
@ -261,7 +265,10 @@ func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseW
}
if err := json.NewDecoder(r.Body).Decode(&connect); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
// Unlike other operations, we does not check ambiguity of the name/ID here.
@ -282,7 +289,10 @@ func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.Respon
}
if err := json.NewDecoder(r.Body).Decode(&disconnect); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
return n.backend.DisconnectContainerFromNetwork(disconnect.Container, vars["id"], disconnect.Force)

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/base64"
"encoding/json"
"io"
"net/http"
"strconv"
"strings"
@ -12,6 +13,7 @@ import (
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/streamformatter"
"github.com/pkg/errors"
@ -276,7 +278,10 @@ func (pr *pluginRouter) pushPlugin(ctx context.Context, w http.ResponseWriter, r
func (pr *pluginRouter) setPlugin(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var args []string
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
if err := pr.backend.Set(vars["name"], args); err != nil {
return err

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
@ -21,7 +22,16 @@ import (
func (sr *swarmRouter) initCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var req types.InitRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
version := httputils.VersionFromContext(ctx)
// DefaultAddrPool and SubnetSize were added in API 1.39. Ignore on older API versions.
if versions.LessThan(version, "1.39") {
req.DefaultAddrPool = nil
req.SubnetSize = 0
}
nodeID, err := sr.backend.Init(req)
if err != nil {
@ -34,7 +44,10 @@ func (sr *swarmRouter) initCluster(ctx context.Context, w http.ResponseWriter, r
func (sr *swarmRouter) joinCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var req types.JoinRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
return sr.backend.Join(req)
}
@ -61,7 +74,10 @@ func (sr *swarmRouter) inspectCluster(ctx context.Context, w http.ResponseWriter
func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var swarm types.Spec
if err := json.NewDecoder(r.Body).Decode(&swarm); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
rawVersion := r.URL.Query().Get("version")
@ -112,7 +128,10 @@ func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter,
func (sr *swarmRouter) unlockCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var req types.UnlockRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
if err := sr.backend.UnlockSwarm(req); err != nil {
@ -175,7 +194,10 @@ func (sr *swarmRouter) getService(ctx context.Context, w http.ResponseWriter, r
func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var service types.ServiceSpec
if err := json.NewDecoder(r.Body).Decode(&service); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
// Get returns "" if the header does not exist
@ -198,7 +220,10 @@ func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter,
func (sr *swarmRouter) updateService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var service types.ServiceSpec
if err := json.NewDecoder(r.Body).Decode(&service); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
rawVersion := r.URL.Query().Get("version")
@ -291,7 +316,10 @@ func (sr *swarmRouter) getNode(ctx context.Context, w http.ResponseWriter, r *ht
func (sr *swarmRouter) updateNode(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var node types.NodeSpec
if err := json.NewDecoder(r.Body).Decode(&node); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
rawVersion := r.URL.Query().Get("version")
@ -370,7 +398,10 @@ func (sr *swarmRouter) getSecrets(ctx context.Context, w http.ResponseWriter, r
func (sr *swarmRouter) createSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var secret types.SecretSpec
if err := json.NewDecoder(r.Body).Decode(&secret); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
version := httputils.VersionFromContext(ctx)
if secret.Templating != nil && versions.LessThan(version, "1.37") {
@ -408,6 +439,9 @@ func (sr *swarmRouter) getSecret(ctx context.Context, w http.ResponseWriter, r *
func (sr *swarmRouter) updateSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var secret types.SecretSpec
if err := json.NewDecoder(r.Body).Decode(&secret); err != nil {
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
@ -441,7 +475,10 @@ func (sr *swarmRouter) getConfigs(ctx context.Context, w http.ResponseWriter, r
func (sr *swarmRouter) createConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var config types.ConfigSpec
if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
return err
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}
version := httputils.VersionFromContext(ctx)
@ -480,6 +517,9 @@ func (sr *swarmRouter) getConfig(ctx context.Context, w http.ResponseWriter, r *
func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var config types.ConfigSpec
if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return errdefs.InvalidParameter(err)
}

View File

@ -56,7 +56,7 @@ func (v *volumeRouter) postVolumesCreate(ctx context.Context, w http.ResponseWri
if err == io.EOF {
return errdefs.InvalidParameter(errors.New("got EOF while reading request body"))
}
return err
return errdefs.InvalidParameter(err)
}
volume, err := v.backend.Create(ctx, req.Name, req.Driver, opts.WithCreateOptions(req.DriverOpts), opts.WithCreateLabels(req.Labels))

View File

@ -2459,6 +2459,22 @@ definitions:
description: "Whether there is currently a root CA rotation in progress for the swarm"
type: "boolean"
example: false
DefaultAddrPool:
description: |
Default Address Pool specifies default subnet pools for global scope networks.
type: "array"
items:
type: "string"
format: "CIDR"
example: ["10.10.0.0/16", "20.20.0.0/16"]
SubnetSize:
description: |
SubnetSize specifies the subnet size of the networks created from the default subnet pool
type: "integer"
format: "uint32"
maximum: 29
default: 24
example: 24
JoinTokens:
description: |

View File

@ -195,10 +195,18 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
return nil
}
body, err := ioutil.ReadAll(serverResp.body)
bodyMax := 1 * 1024 * 1024 // 1 MiB
bodyR := &io.LimitedReader{
R: serverResp.body,
N: int64(bodyMax),
}
body, err := ioutil.ReadAll(bodyR)
if err != nil {
return err
}
if bodyR.N == 0 {
return fmt.Errorf("request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), bodyMax, serverResp.reqURL)
}
if len(body) == 0 {
return fmt.Errorf("request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL)
}

View File

@ -5,12 +5,14 @@ import (
"context"
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"strings"
"testing"
"github.com/docker/docker/api/types"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
)
// TestSetHostHeader should set fake host for local communications, set real host
@ -87,3 +89,18 @@ func TestPlainTextError(t *testing.T) {
t.Fatalf("expected a Server Error, got %v", err)
}
}
func TestInfiniteError(t *testing.T) {
infinitR := rand.New(rand.NewSource(42))
client := &Client{
client: newMockClient(func(req *http.Request) (*http.Response, error) {
resp := &http.Response{StatusCode: http.StatusInternalServerError}
resp.Header = http.Header{}
resp.Body = ioutil.NopCloser(infinitR)
return resp, nil
}),
}
_, err := client.Ping(context.Background())
assert.Check(t, is.ErrorContains(err, "request returned Internal Server Error"))
}

View File

@ -265,8 +265,11 @@ flags=(
CGROUP_HUGETLB
NET_CLS_CGROUP $netprio
CFS_BANDWIDTH FAIR_GROUP_SCHED RT_GROUP_SCHED
IP_NF_TARGET_REDIRECT
IP_VS
IP_VS_NFCT
IP_VS_PROTO_TCP
IP_VS_PROTO_UDP
IP_VS_RR
)
check_flags "${flags[@]}"

View File

@ -193,12 +193,15 @@ func verifyContainerResources(resources *containertypes.Resources, isHyperv bool
// hostconfig and config structures.
func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
warnings := []string{}
osv := system.GetOSVersion()
hyperv := daemon.runAsHyperVContainer(hostConfig)
if !hyperv && system.IsWindowsClient() && !system.IsIoTCore() {
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping @jhowardmsft if there are concerns or PRs to change this.
return warnings, fmt.Errorf("Windows client operating systems only support Hyper-V containers")
// On RS5, we allow (but don't strictly support) process isolation on Client SKUs.
// Prior to RS5, we don't allow process isolation on Client SKUs.
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping @jhowardmsft if there are concerns or PRs to change this.
if !hyperv && system.IsWindowsClient() && osv.Build < 17763 {
return warnings, fmt.Errorf("Windows client operating systems earlier than version 1809 can only run Hyper-V containers")
}
w, err := verifyContainerResources(&hostConfig.Resources, hyperv)
@ -592,9 +595,12 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
// daemon to run in. This is only applicable on Windows
func (daemon *Daemon) setDefaultIsolation() error {
daemon.defaultIsolation = containertypes.Isolation("process")
// On client SKUs, default to Hyper-V. Note that IoT reports as a client SKU
// but it should not be treated as such.
if system.IsWindowsClient() && !system.IsIoTCore() {
osv := system.GetOSVersion()
// On client SKUs, default to Hyper-V. @engine maintainers. This
// should not be removed. Ping @jhowardmsft is there are PRs to
// to change this.
if system.IsWindowsClient() {
daemon.defaultIsolation = containertypes.Isolation("hyperv")
}
for _, option := range daemon.configStore.ExecOptions {
@ -613,10 +619,11 @@ func (daemon *Daemon) setDefaultIsolation() error {
daemon.defaultIsolation = containertypes.Isolation("hyperv")
}
if containertypes.Isolation(val).IsProcess() {
if system.IsWindowsClient() && !system.IsIoTCore() {
if system.IsWindowsClient() && osv.Build < 17763 {
// On RS5, we allow (but don't strictly support) process isolation on Client SKUs.
// @engine maintainers. This block should not be removed. It partially enforces licensing
// restrictions on Windows. Ping @jhowardmsft if there are concerns or PRs to change this.
return fmt.Errorf("Windows client operating systems only support Hyper-V containers")
return fmt.Errorf("Windows client operating systems earlier than version 1809 can only run Hyper-V containers")
}
daemon.defaultIsolation = containertypes.Isolation("process")
}

View File

@ -195,6 +195,7 @@ type Options struct {
func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
if name != "" {
logrus.Debugf("[graphdriver] trying provided driver: %s", name) // so the logs show specified driver
logDeprecatedWarning(name)
return GetDriver(name, pg, config)
}
@ -232,6 +233,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
}
logrus.Infof("[graphdriver] using prior storage driver: %s", name)
logDeprecatedWarning(name)
return driver, nil
}
}
@ -245,6 +247,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
}
return nil, err
}
logDeprecatedWarning(name)
return driver, nil
}
@ -257,6 +260,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
}
return nil, err
}
logDeprecatedWarning(name)
return driver, nil
}
return nil, fmt.Errorf("No supported storage backend found")
@ -305,3 +309,20 @@ func isEmptyDir(name string) bool {
}
return false
}
// isDeprecated checks if a storage-driver is marked "deprecated"
func isDeprecated(name string) bool {
switch name {
// NOTE: when deprecating a driver, update daemon.fillDriverInfo() accordingly
case "devicemapper", "overlay":
return true
}
return false
}
// logDeprecatedWarning logs a warning if the given storage-driver is marked "deprecated"
func logDeprecatedWarning(name string) {
if isDeprecated(name) {
logrus.Warnf("[graphdriver] WARNING: the %s storage-driver is deprecated, and will be removed in a future release", name)
}
}

View File

@ -71,20 +71,33 @@ import (
"time"
"github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/ext4/tar2ext4"
"github.com/Microsoft/opengcs/client"
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/containerfs"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/reexec"
"github.com/docker/docker/pkg/system"
"github.com/sirupsen/logrus"
)
// noreexec controls reexec functionality. Off by default, on for debugging purposes.
var noreexec = false
// init registers this driver to the register. It gets initialised by the
// function passed in the second parameter, implemented in this file.
func init() {
graphdriver.Register("lcow", InitDriver)
// DOCKER_LCOW_NOREEXEC allows for inline processing which makes
// debugging issues in the re-exec codepath significantly easier.
if os.Getenv("DOCKER_LCOW_NOREEXEC") != "" {
logrus.Warnf("LCOW Graphdriver is set to not re-exec. This is intended for debugging purposes only.")
noreexec = true
} else {
reexec.Register("docker-lcow-tar2ext4", tar2ext4Reexec)
}
}
const (
@ -846,32 +859,72 @@ func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
func (d *Driver) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
logrus.Debugf("lcowdriver: applydiff: id %s", id)
svm, err := d.startServiceVMIfNotRunning(id, nil, fmt.Sprintf("applydiff %s", id))
// Log failures here as it's undiagnosable sometimes, due to a possible panic.
// See https://github.com/moby/moby/issues/37955 for more information.
dest := filepath.Join(d.dataRoot, id, layerFilename)
if !noreexec {
cmd := reexec.Command([]string{"docker-lcow-tar2ext4", dest}...)
stdout := bytes.NewBuffer(nil)
stderr := bytes.NewBuffer(nil)
cmd.Stdin = diff
cmd.Stdout = stdout
cmd.Stderr = stderr
if err := cmd.Start(); err != nil {
logrus.Warnf("lcowdriver: applydiff: id %s failed to start re-exec: %s", id, err)
return 0, err
}
if err := cmd.Wait(); err != nil {
logrus.Warnf("lcowdriver: applydiff: id %s failed %s", id, err)
return 0, fmt.Errorf("re-exec error: %v: stderr: %s", err, stderr)
}
return strconv.ParseInt(stdout.String(), 10, 64)
}
// The inline case
size, err := tar2ext4Actual(dest, diff)
if err != nil {
logrus.Warnf("lcowdriver: applydiff: id %s failed %s", id, err)
}
return size, err
}
// tar2ext4Reexec is the re-exec entry point for writing a layer from a tar file
func tar2ext4Reexec() {
size, err := tar2ext4Actual(os.Args[1], os.Stdin)
if err != nil {
fmt.Fprint(os.Stderr, err)
os.Exit(1)
}
fmt.Fprint(os.Stdout, size)
}
// tar2ext4Actual is the implementation of tar2ext to write a layer from a tar file.
// It can be called through re-exec (default), or inline for debugging.
func tar2ext4Actual(dest string, diff io.Reader) (int64, error) {
// maxDiskSize is not relating to the sandbox size - this is the
// maximum possible size a layer VHD generated can be from an EXT4
// layout perspective.
const maxDiskSize = 128 * 1024 * 1024 * 1024 // 128GB
out, err := os.Create(dest)
if err != nil {
return 0, err
}
defer d.terminateServiceVM(id, fmt.Sprintf("applydiff %s", id), false)
logrus.Debugf("lcowdriver: applydiff: waiting for svm to finish booting")
err = svm.getStartError()
defer out.Close()
if err := tar2ext4.Convert(
diff,
out,
tar2ext4.AppendVhdFooter,
tar2ext4.ConvertWhiteout,
tar2ext4.MaximumDiskSize(maxDiskSize)); err != nil {
return 0, err
}
fi, err := os.Stat(dest)
if err != nil {
return 0, fmt.Errorf("lcowdriver: applydiff: svm failed to boot: %s", err)
}
// TODO @jhowardmsft - the retries are temporary to overcome platform reliability issues.
// Obviously this will be removed as platform bugs are fixed.
retries := 0
for {
retries++
size, err := svm.config.TarToVhd(filepath.Join(d.dataRoot, id, layerFilename), diff)
if err != nil {
if retries <= 10 {
continue
}
return 0, err
}
return size, err
return 0, err
}
return fi.Size(), nil
}
// Changes produces a list of changes between the specified layer

View File

@ -6,7 +6,6 @@ import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -23,6 +22,7 @@ import (
"github.com/Microsoft/go-winio"
"github.com/Microsoft/go-winio/archive/tar"
"github.com/Microsoft/go-winio/backuptar"
"github.com/Microsoft/go-winio/vhd"
"github.com/Microsoft/hcsshim"
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/pkg/archive"
@ -33,6 +33,7 @@ import (
"github.com/docker/docker/pkg/reexec"
"github.com/docker/docker/pkg/system"
units "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
)
@ -331,7 +332,18 @@ func (d *Driver) Remove(id string) error {
tmpID := fmt.Sprintf("%s-removing", rID)
tmpLayerPath := filepath.Join(d.info.HomeDir, tmpID)
if err := os.Rename(layerPath, tmpLayerPath); err != nil && !os.IsNotExist(err) {
return err
if !os.IsPermission(err) {
return err
}
// If permission denied, it's possible that the scratch is still mounted, an
// artifact after a hard daemon crash for example. Worth a shot to try detaching it
// before retrying the rename.
if detachErr := vhd.DetachVhd(filepath.Join(layerPath, "sandbox.vhdx")); detachErr != nil {
return errors.Wrapf(err, "failed to detach VHD: %s", detachErr)
}
if renameErr := os.Rename(layerPath, tmpLayerPath); renameErr != nil && !os.IsNotExist(renameErr) {
return errors.Wrapf(err, "second rename attempt following detach failed: %s", renameErr)
}
}
if err := hcsshim.DestroyLayer(d.info, tmpID); err != nil {
logrus.Errorf("Failed to DestroyLayer %s: %s", id, err)

View File

@ -131,6 +131,10 @@ func (daemon *Daemon) fillDriverInfo(v *types.Info) {
if len(daemon.graphDrivers) > 1 {
drivers += fmt.Sprintf(" (%s) ", os)
}
switch gd {
case "devicemapper", "overlay":
v.Warnings = append(v.Warnings, fmt.Sprintf("WARNING: the %s storage-driver is deprecated, and will be removed in a future release.", gd))
}
}
drivers = strings.TrimSpace(drivers)

View File

@ -11,6 +11,7 @@ import (
"strings"
"sync"
"time"
"unicode/utf8"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
@ -46,6 +47,10 @@ const (
maximumLogEventsPerPut = 10000
// See: http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/cloudwatch_limits.html
// Because the events are interpreted as UTF-8 encoded Unicode, invalid UTF-8 byte sequences are replaced with the
// Unicode replacement character (U+FFFD), which is a 3-byte sequence in UTF-8. To compensate for that and to avoid
// splitting valid UTF-8 characters into invalid byte sequences, we calculate the length of each event assuming that
// this replacement happens.
maximumBytesPerEvent = 262144 - perEventBytes
resourceAlreadyExistsCode = "ResourceAlreadyExistsException"
@ -495,15 +500,16 @@ func (l *logStream) collectBatch(created chan bool) {
}
line := msg.Line
if l.multilinePattern != nil {
if l.multilinePattern.Match(line) || len(eventBuffer)+len(line) > maximumBytesPerEvent {
lineEffectiveLen := effectiveLen(string(line))
if l.multilinePattern.Match(line) || effectiveLen(string(eventBuffer))+lineEffectiveLen > maximumBytesPerEvent {
// This is a new log event or we will exceed max bytes per event
// so flush the current eventBuffer to events and reset timestamp
l.processEvent(batch, eventBuffer, eventBufferTimestamp)
eventBufferTimestamp = msg.Timestamp.UnixNano() / int64(time.Millisecond)
eventBuffer = eventBuffer[:0]
}
// Append new line if event is less than max event size
if len(line) < maximumBytesPerEvent {
// Append newline if event is less than max event size
if lineEffectiveLen < maximumBytesPerEvent {
line = append(line, "\n"...)
}
eventBuffer = append(eventBuffer, line...)
@ -524,16 +530,17 @@ func (l *logStream) collectBatch(created chan bool) {
// batch (defined in maximumBytesPerPut). Log messages are split by the maximum
// bytes per event (defined in maximumBytesPerEvent). There is a fixed per-event
// byte overhead (defined in perEventBytes) which is accounted for in split- and
// batch-calculations.
func (l *logStream) processEvent(batch *eventBatch, events []byte, timestamp int64) {
for len(events) > 0 {
// batch-calculations. Because the events are interpreted as UTF-8 encoded
// Unicode, invalid UTF-8 byte sequences are replaced with the Unicode
// replacement character (U+FFFD), which is a 3-byte sequence in UTF-8. To
// compensate for that and to avoid splitting valid UTF-8 characters into
// invalid byte sequences, we calculate the length of each event assuming that
// this replacement happens.
func (l *logStream) processEvent(batch *eventBatch, bytes []byte, timestamp int64) {
for len(bytes) > 0 {
// Split line length so it does not exceed the maximum
lineBytes := len(events)
if lineBytes > maximumBytesPerEvent {
lineBytes = maximumBytesPerEvent
}
line := events[:lineBytes]
splitOffset, lineBytes := findValidSplit(string(bytes), maximumBytesPerEvent)
line := bytes[:splitOffset]
event := wrappedEvent{
inputLogEvent: &cloudwatchlogs.InputLogEvent{
Message: aws.String(string(line)),
@ -544,7 +551,7 @@ func (l *logStream) processEvent(batch *eventBatch, events []byte, timestamp int
added := batch.add(event, lineBytes)
if added {
events = events[lineBytes:]
bytes = bytes[splitOffset:]
} else {
l.publishBatch(batch)
batch.reset()
@ -552,6 +559,37 @@ func (l *logStream) processEvent(batch *eventBatch, events []byte, timestamp int
}
}
// effectiveLen counts the effective number of bytes in the string, after
// UTF-8 normalization. UTF-8 normalization includes replacing bytes that do
// not constitute valid UTF-8 encoded Unicode codepoints with the Unicode
// replacement codepoint U+FFFD (a 3-byte UTF-8 sequence, represented in Go as
// utf8.RuneError)
func effectiveLen(line string) int {
effectiveBytes := 0
for _, rune := range line {
effectiveBytes += utf8.RuneLen(rune)
}
return effectiveBytes
}
// findValidSplit finds the byte offset to split a string without breaking valid
// Unicode codepoints given a maximum number of total bytes. findValidSplit
// returns the byte offset for splitting a string or []byte, as well as the
// effective number of bytes if the string were normalized to replace invalid
// UTF-8 encoded bytes with the Unicode replacement character (a 3-byte UTF-8
// sequence, represented in Go as utf8.RuneError)
func findValidSplit(line string, maxBytes int) (splitOffset, effectiveBytes int) {
for offset, rune := range line {
splitOffset = offset
if effectiveBytes+utf8.RuneLen(rune) > maxBytes {
return splitOffset, effectiveBytes
}
effectiveBytes += utf8.RuneLen(rune)
}
splitOffset = len(line)
return
}
// publishBatch calls PutLogEvents for a given set of InputLogEvents,
// accounting for sequencing requirements (each request must reference the
// sequence token returned by the previous request).

View File

@ -938,6 +938,62 @@ func TestCollectBatchClose(t *testing.T) {
}
}
func TestEffectiveLen(t *testing.T) {
tests := []struct {
str string
effectiveBytes int
}{
{"Hello", 5},
{string([]byte{1, 2, 3, 4}), 4},
{"🙃", 4},
{string([]byte{0xFF, 0xFF, 0xFF, 0xFF}), 12},
{"He\xff\xffo", 9},
{"", 0},
}
for i, tc := range tests {
t.Run(fmt.Sprintf("%d/%s", i, tc.str), func(t *testing.T) {
assert.Equal(t, tc.effectiveBytes, effectiveLen(tc.str))
})
}
}
func TestFindValidSplit(t *testing.T) {
tests := []struct {
str string
maxEffectiveBytes int
splitOffset int
effectiveBytes int
}{
{"", 10, 0, 0},
{"Hello", 6, 5, 5},
{"Hello", 2, 2, 2},
{"Hello", 0, 0, 0},
{"🙃", 3, 0, 0},
{"🙃", 4, 4, 4},
{string([]byte{'a', 0xFF}), 2, 1, 1},
{string([]byte{'a', 0xFF}), 4, 2, 4},
}
for i, tc := range tests {
t.Run(fmt.Sprintf("%d/%s", i, tc.str), func(t *testing.T) {
splitOffset, effectiveBytes := findValidSplit(tc.str, tc.maxEffectiveBytes)
assert.Equal(t, tc.splitOffset, splitOffset, "splitOffset")
assert.Equal(t, tc.effectiveBytes, effectiveBytes, "effectiveBytes")
t.Log(tc.str[:tc.splitOffset])
t.Log(tc.str[tc.splitOffset:])
})
}
}
func TestProcessEventEmoji(t *testing.T) {
stream := &logStream{}
batch := &eventBatch{}
bytes := []byte(strings.Repeat("🙃", maximumBytesPerEvent/4+1))
stream.processEvent(batch, bytes, 0)
assert.Equal(t, 2, len(batch.batch), "should be two events in the batch")
assert.Equal(t, strings.Repeat("🙃", maximumBytesPerEvent/4), aws.StringValue(batch.batch[0].inputLogEvent.Message))
assert.Equal(t, "🙃", aws.StringValue(batch.batch[1].inputLogEvent.Message))
}
func TestCollectBatchLineSplit(t *testing.T) {
mockClient := newMockClient()
stream := &logStream{
@ -987,6 +1043,55 @@ func TestCollectBatchLineSplit(t *testing.T) {
}
}
func TestCollectBatchLineSplitWithBinary(t *testing.T) {
mockClient := newMockClient()
stream := &logStream{
client: mockClient,
logGroupName: groupName,
logStreamName: streamName,
sequenceToken: aws.String(sequenceToken),
messages: make(chan *logger.Message),
}
mockClient.putLogEventsResult <- &putLogEventsResult{
successResult: &cloudwatchlogs.PutLogEventsOutput{
NextSequenceToken: aws.String(nextSequenceToken),
},
}
var ticks = make(chan time.Time)
newTicker = func(_ time.Duration) *time.Ticker {
return &time.Ticker{
C: ticks,
}
}
d := make(chan bool)
close(d)
go stream.collectBatch(d)
longline := strings.Repeat("\xFF", maximumBytesPerEvent/3) // 0xFF is counted as the 3-byte utf8.RuneError
stream.Log(&logger.Message{
Line: []byte(longline + "\xFD"),
Timestamp: time.Time{},
})
// no ticks
stream.Close()
argument := <-mockClient.putLogEventsArgument
if argument == nil {
t.Fatal("Expected non-nil PutLogEventsInput")
}
if len(argument.LogEvents) != 2 {
t.Errorf("Expected LogEvents to contain 2 elements, but contains %d", len(argument.LogEvents))
}
if *argument.LogEvents[0].Message != longline {
t.Errorf("Expected message to be %s but was %s", longline, *argument.LogEvents[0].Message)
}
if *argument.LogEvents[1].Message != "\xFD" {
t.Errorf("Expected message to be %s but was %s", "\xFD", *argument.LogEvents[1].Message)
}
}
func TestCollectBatchMaxEvents(t *testing.T) {
mockClient := newMockClientBuffered(1)
stream := &logStream{
@ -1125,6 +1230,83 @@ func TestCollectBatchMaxTotalBytes(t *testing.T) {
}
}
func TestCollectBatchMaxTotalBytesWithBinary(t *testing.T) {
expectedPuts := 2
mockClient := newMockClientBuffered(expectedPuts)
stream := &logStream{
client: mockClient,
logGroupName: groupName,
logStreamName: streamName,
sequenceToken: aws.String(sequenceToken),
messages: make(chan *logger.Message),
}
for i := 0; i < expectedPuts; i++ {
mockClient.putLogEventsResult <- &putLogEventsResult{
successResult: &cloudwatchlogs.PutLogEventsOutput{
NextSequenceToken: aws.String(nextSequenceToken),
},
}
}
var ticks = make(chan time.Time)
newTicker = func(_ time.Duration) *time.Ticker {
return &time.Ticker{
C: ticks,
}
}
d := make(chan bool)
close(d)
go stream.collectBatch(d)
// maxline is the maximum line that could be submitted after
// accounting for its overhead.
maxline := strings.Repeat("\xFF", (maximumBytesPerPut-perEventBytes)/3) // 0xFF is counted as the 3-byte utf8.RuneError
// This will be split and batched up to the `maximumBytesPerPut'
// (+/- `maximumBytesPerEvent'). This /should/ be aligned, but
// should also tolerate an offset within that range.
stream.Log(&logger.Message{
Line: []byte(maxline),
Timestamp: time.Time{},
})
stream.Log(&logger.Message{
Line: []byte("B"),
Timestamp: time.Time{},
})
// no ticks, guarantee batch by size (and chan close)
stream.Close()
argument := <-mockClient.putLogEventsArgument
if argument == nil {
t.Fatal("Expected non-nil PutLogEventsInput")
}
// Should total to the maximum allowed bytes.
eventBytes := 0
for _, event := range argument.LogEvents {
eventBytes += effectiveLen(*event.Message)
}
eventsOverhead := len(argument.LogEvents) * perEventBytes
payloadTotal := eventBytes + eventsOverhead
// lowestMaxBatch allows the payload to be offset if the messages
// don't lend themselves to align with the maximum event size.
lowestMaxBatch := maximumBytesPerPut - maximumBytesPerEvent
if payloadTotal > maximumBytesPerPut {
t.Errorf("Expected <= %d bytes but was %d", maximumBytesPerPut, payloadTotal)
}
if payloadTotal < lowestMaxBatch {
t.Errorf("Batch to be no less than %d but was %d", lowestMaxBatch, payloadTotal)
}
argument = <-mockClient.putLogEventsArgument
message := *argument.LogEvents[len(argument.LogEvents)-1].Message
if message[len(message)-1:] != "B" {
t.Errorf("Expected message to be %s but was %s", "B", message[len(message)-1:])
}
}
func TestCollectBatchWithDuplicateTimestamps(t *testing.T) {
mockClient := newMockClient()
stream := &logStream{

View File

@ -4,7 +4,7 @@
# containerd is also pinned in vendor.conf. When updating the binary
# version you may also need to update the vendor version to pick up bug
# fixes or new APIs.
CONTAINERD_COMMIT=468a545b9edcd5932818eb9de8e72413e616e86e # v1.1.2
CONTAINERD_COMMIT=de1f167ab96338a9f5c2b17347abf84bdf1dd411 # v1.2.1-rc.0
install_containerd() {
echo "Install containerd version $CONTAINERD_COMMIT"

View File

@ -3,7 +3,7 @@
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
# updating the binary version, consider updating github.com/docker/libnetwork
# in vendor.conf accordingly
LIBNETWORK_COMMIT=6da50d1978302f04c3e2089e29112ea24812f05b
LIBNETWORK_COMMIT=8bc51fd276b549b106dbc7bf8ab18b3a01d66e64 # bump_18.09 branch
install_proxy() {
case "$1" in

View File

@ -1,13 +1,21 @@
#!/bin/sh
# When updating RUNC_COMMIT, also update runc in vendor.conf accordingly
RUNC_COMMIT=69663f0bd4b60df09991c08812a60108003fa340
# The version of runc should match the version that is used by the containerd
# version that is used. If you need to update runc, open a pull request in
# the containerd project first, and update both after that is merged.
RUNC_COMMIT=10d38b660a77168360df3522881e2dc2be5056bd
install_runc() {
# Do not build with ambient capabilities support
RUNC_BUILDTAGS="${RUNC_BUILDTAGS:-"seccomp apparmor selinux"}"
# If using RHEL7 kernels (3.10.0 el7), disable kmem accounting/limiting
if uname -r | grep -q '^3\.10\.0.*\.el7\.'; then
: ${RUNC_NOKMEM='nokmem'}
fi
echo "Install runc version $RUNC_COMMIT"
# Do not build with ambient capabilities support
RUNC_BUILDTAGS="${RUNC_BUILDTAGS:-"seccomp apparmor selinux $RUNC_NOKMEM"}"
echo "Install runc version $RUNC_COMMIT (build tags: $RUNC_BUILDTAGS)"
git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc"
cd "$GOPATH/src/github.com/opencontainers/runc"
git checkout -q "$RUNC_COMMIT"

View File

@ -0,0 +1,42 @@
package container // import "github.com/docker/docker/integration/container"
import (
"net/http"
"testing"
"github.com/docker/docker/internal/test/request"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
)
func TestContainerInvalidJSON(t *testing.T) {
defer setupTest(t)()
endpoints := []string{
"/containers/foobar/copy",
"/containers/foobar/exec",
"/exec/foobar/start",
}
for _, ep := range endpoints {
t.Run(ep, func(t *testing.T) {
t.Parallel()
res, body, err := request.Post(ep, request.RawString("{invalid json"), request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err := request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "invalid character 'i' looking for beginning of object key string"))
res, body, err = request.Post(ep, request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err = request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "got EOF while reading request body"))
})
}
}

View File

@ -3,6 +3,7 @@ package network // import "github.com/docker/docker/integration/network"
import (
"bytes"
"context"
"net/http"
"os/exec"
"strings"
"testing"
@ -10,6 +11,7 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/integration/internal/container"
"github.com/docker/docker/internal/test/daemon"
"github.com/docker/docker/internal/test/request"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
"gotest.tools/skip"
@ -56,3 +58,35 @@ func TestRunContainerWithBridgeNone(t *testing.T) {
assert.NilError(t, err)
assert.Check(t, is.Equal(stdout.String(), result.Combined()), "The network namspace of container should be the same with host when --net=host and bridge network is disabled")
}
func TestNetworkInvalidJSON(t *testing.T) {
defer setupTest(t)()
endpoints := []string{
"/networks/create",
"/networks/bridge/connect",
"/networks/bridge/disconnect",
}
for _, ep := range endpoints {
t.Run(ep, func(t *testing.T) {
t.Parallel()
res, body, err := request.Post(ep, request.RawString("{invalid json"), request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err := request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "invalid character 'i' looking for beginning of object key string"))
res, body, err = request.Post(ep, request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err = request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "got EOF while reading request body"))
})
}
}

View File

@ -0,0 +1,27 @@
package common // import "github.com/docker/docker/integration/plugin/common"
import (
"fmt"
"os"
"testing"
"github.com/docker/docker/internal/test/environment"
)
var testEnv *environment.Execution
func TestMain(m *testing.M) {
var err error
testEnv, err = environment.New()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
testEnv.Print()
os.Exit(m.Run())
}
func setupTest(t *testing.T) func() {
environment.ProtectAll(t, testEnv)
return func() { testEnv.Clean(t) }
}

View File

@ -0,0 +1,38 @@
package common // import "github.com/docker/docker/integration/plugin/common"
import (
"net/http"
"testing"
"github.com/docker/docker/internal/test/request"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
)
func TestPluginInvalidJSON(t *testing.T) {
defer setupTest(t)()
endpoints := []string{"/plugins/foobar/set"}
for _, ep := range endpoints {
t.Run(ep, func(t *testing.T) {
t.Parallel()
res, body, err := request.Post(ep, request.RawString("{invalid json"), request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err := request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "invalid character 'i' looking for beginning of object key string"))
res, body, err = request.Post(ep, request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err = request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "got EOF while reading request body"))
})
}
}

View File

@ -2,6 +2,7 @@ package volume
import (
"context"
"net/http"
"path/filepath"
"strings"
"testing"
@ -95,6 +96,34 @@ func TestVolumesInspect(t *testing.T) {
assert.Check(t, createdAt.Truncate(time.Minute).Equal(now.Truncate(time.Minute)), "CreatedAt (%s) not equal to creation time (%s)", createdAt, now)
}
func TestVolumesInvalidJSON(t *testing.T) {
defer setupTest(t)()
endpoints := []string{"/volumes/create"}
for _, ep := range endpoints {
t.Run(ep, func(t *testing.T) {
t.Parallel()
res, body, err := request.Post(ep, request.RawString("{invalid json"), request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err := request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "invalid character 'i' looking for beginning of object key string"))
res, body, err = request.Post(ep, request.JSON)
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusBadRequest)
buf, err = request.ReadBody(body)
assert.NilError(t, err)
assert.Check(t, is.Contains(string(buf), "got EOF while reading request body"))
})
}
}
func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) {
if testEnv.OSType == "windows" {
return "c:", `\`

View File

@ -15,7 +15,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/containerd/containerd"
"github.com/containerd/containerd/services/server"
"github.com/containerd/containerd/services/server/config"
"github.com/docker/docker/pkg/system"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -37,7 +37,7 @@ type pluginConfigs struct {
type remote struct {
sync.RWMutex
server.Config
config.Config
daemonPid int
logger *logrus.Entry
@ -65,7 +65,7 @@ func Start(ctx context.Context, rootDir, stateDir string, opts ...DaemonOpt) (Da
r := &remote{
rootDir: rootDir,
stateDir: stateDir,
Config: server.Config{
Config: config.Config{
Root: filepath.Join(rootDir, "daemon"),
State: filepath.Join(stateDir, "daemon"),
},

View File

@ -23,6 +23,8 @@ var (
type profileData struct {
// Name is profile name.
Name string
// DaemonProfile is the profile name of our daemon.
DaemonProfile string
// Imports defines the apparmor functions to import, before defining the profile.
Imports []string
// InnerImports defines the apparmor functions to import in the profile.
@ -70,6 +72,25 @@ func InstallDefault(name string) error {
Name: name,
}
// Figure out the daemon profile.
currentProfile, err := ioutil.ReadFile("/proc/self/attr/current")
if err != nil {
// If we couldn't get the daemon profile, assume we are running
// unconfined which is generally the default.
currentProfile = nil
}
daemonProfile := string(currentProfile)
// Normally profiles are suffixed by " (enforcing)" or similar. AppArmor
// profiles cannot contain spaces so this doesn't restrict daemon profile
// names.
if parts := strings.SplitN(daemonProfile, " ", 2); len(parts) >= 1 {
daemonProfile = parts[0]
}
if daemonProfile == "" {
daemonProfile = "unconfined"
}
p.DaemonProfile = daemonProfile
// Install to a temporary directory.
f, err := ioutil.TempFile("", name)
if err != nil {

View File

@ -17,6 +17,12 @@ profile {{.Name}} flags=(attach_disconnected,mediate_deleted) {
capability,
file,
umount,
{{if ge .Version 208096}}
{{/* Allow 'docker kill' to actually send signals to container processes. */}}
signal (receive) peer={{.DaemonProfile}},
{{/* Allow container processes to send signals amongst themselves. */}}
signal (send,receive) peer={{.Name}},
{{end}}
deny @{PROC}/* w, # deny write for all files directly in /proc (not in a subdir)
# deny write to files not in /proc/<number>/** or /proc/sys/**

View File

@ -1,6 +1,6 @@
# the following lines are in sorted order, FYI
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
github.com/Microsoft/hcsshim v0.7.6
github.com/Microsoft/hcsshim v0.7.12
github.com/Microsoft/go-winio v0.4.11
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
@ -37,7 +37,7 @@ github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b
#get libnetwork packages
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
github.com/docker/libnetwork 6da50d1978302f04c3e2089e29112ea24812f05b
github.com/docker/libnetwork 8bc51fd276b549b106dbc7bf8ab18b3a01d66e64 # bump_18.09 branch
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
@ -74,9 +74,13 @@ github.com/pborman/uuid v1.0
google.golang.org/grpc v1.12.0
# This does not need to match RUNC_COMMIT as it is used for helper packages but should be newer or equal
github.com/opencontainers/runc 00dc70017d222b178a002ed30e9321b12647af2d
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
# The version of runc should match the version that is used by the containerd
# version that is used. If you need to update runc, open a pull request in
# the containerd project first, and update both after that is merged.
# This commit does not need to match RUNC_COMMIT as it is used for helper
# packages but should be newer or equal.
github.com/opencontainers/runc 10d38b660a77168360df3522881e2dc2be5056bd
github.com/opencontainers/runtime-spec 5684b8af48c1ac3b1451fa499724e30e3c20a294 # v1.0.1-49-g5684b8a
github.com/opencontainers/image-spec v1.0.1
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
@ -114,12 +118,12 @@ github.com/googleapis/gax-go v2.0.0
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
# containerd
github.com/containerd/containerd 0c5f8f63c3368856c320ae8a1c125e703b73b51d # v1.2.0-rc.1
github.com/containerd/containerd de1f167ab96338a9f5c2b17347abf84bdf1dd411 # v1.2.1-rc.0
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
github.com/containerd/cri 9f39e3289533fc228c5e5fcac0a6dbdd60c6047b # release/1.2 branch
github.com/containerd/cri f913714917d2456d7e65a0be84962b1ce8acb487 # release/1.2 branch
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,411 @@
package format
type SuperBlock struct {
InodesCount uint32
BlocksCountLow uint32
RootBlocksCountLow uint32
FreeBlocksCountLow uint32
FreeInodesCount uint32
FirstDataBlock uint32
LogBlockSize uint32
LogClusterSize uint32
BlocksPerGroup uint32
ClustersPerGroup uint32
InodesPerGroup uint32
Mtime uint32
Wtime uint32
MountCount uint16
MaxMountCount uint16
Magic uint16
State uint16
Errors uint16
MinorRevisionLevel uint16
LastCheck uint32
CheckInterval uint32
CreatorOS uint32
RevisionLevel uint32
DefaultReservedUid uint16
DefaultReservedGid uint16
FirstInode uint32
InodeSize uint16
BlockGroupNr uint16
FeatureCompat CompatFeature
FeatureIncompat IncompatFeature
FeatureRoCompat RoCompatFeature
UUID [16]uint8
VolumeName [16]byte
LastMounted [64]byte
AlgorithmUsageBitmap uint32
PreallocBlocks uint8
PreallocDirBlocks uint8
ReservedGdtBlocks uint16
JournalUUID [16]uint8
JournalInum uint32
JournalDev uint32
LastOrphan uint32
HashSeed [4]uint32
DefHashVersion uint8
JournalBackupType uint8
DescSize uint16
DefaultMountOpts uint32
FirstMetaBg uint32
MkfsTime uint32
JournalBlocks [17]uint32
BlocksCountHigh uint32
RBlocksCountHigh uint32
FreeBlocksCountHigh uint32
MinExtraIsize uint16
WantExtraIsize uint16
Flags uint32
RaidStride uint16
MmpInterval uint16
MmpBlock uint64
RaidStripeWidth uint32
LogGroupsPerFlex uint8
ChecksumType uint8
ReservedPad uint16
KbytesWritten uint64
SnapshotInum uint32
SnapshotID uint32
SnapshotRBlocksCount uint64
SnapshotList uint32
ErrorCount uint32
FirstErrorTime uint32
FirstErrorInode uint32
FirstErrorBlock uint64
FirstErrorFunc [32]uint8
FirstErrorLine uint32
LastErrorTime uint32
LastErrorInode uint32
LastErrorLine uint32
LastErrorBlock uint64
LastErrorFunc [32]uint8
MountOpts [64]uint8
UserQuotaInum uint32
GroupQuotaInum uint32
OverheadBlocks uint32
BackupBgs [2]uint32
EncryptAlgos [4]uint8
EncryptPwSalt [16]uint8
LpfInode uint32
ProjectQuotaInum uint32
ChecksumSeed uint32
WtimeHigh uint8
MtimeHigh uint8
MkfsTimeHigh uint8
LastcheckHigh uint8
FirstErrorTimeHigh uint8
LastErrorTimeHigh uint8
Pad [2]uint8
Reserved [96]uint32
Checksum uint32
}
const SuperBlockMagic uint16 = 0xef53
type CompatFeature uint32
type IncompatFeature uint32
type RoCompatFeature uint32
const (
CompatDirPrealloc CompatFeature = 0x1
CompatImagicInodes CompatFeature = 0x2
CompatHasJournal CompatFeature = 0x4
CompatExtAttr CompatFeature = 0x8
CompatResizeInode CompatFeature = 0x10
CompatDirIndex CompatFeature = 0x20
CompatLazyBg CompatFeature = 0x40
CompatExcludeInode CompatFeature = 0x80
CompatExcludeBitmap CompatFeature = 0x100
CompatSparseSuper2 CompatFeature = 0x200
IncompatCompression IncompatFeature = 0x1
IncompatFiletype IncompatFeature = 0x2
IncompatRecover IncompatFeature = 0x4
IncompatJournalDev IncompatFeature = 0x8
IncompatMetaBg IncompatFeature = 0x10
IncompatExtents IncompatFeature = 0x40
Incompat_64Bit IncompatFeature = 0x80
IncompatMmp IncompatFeature = 0x100
IncompatFlexBg IncompatFeature = 0x200
IncompatEaInode IncompatFeature = 0x400
IncompatDirdata IncompatFeature = 0x1000
IncompatCsumSeed IncompatFeature = 0x2000
IncompatLargedir IncompatFeature = 0x4000
IncompatInlineData IncompatFeature = 0x8000
IncompatEncrypt IncompatFeature = 0x10000
RoCompatSparseSuper RoCompatFeature = 0x1
RoCompatLargeFile RoCompatFeature = 0x2
RoCompatBtreeDir RoCompatFeature = 0x4
RoCompatHugeFile RoCompatFeature = 0x8
RoCompatGdtCsum RoCompatFeature = 0x10
RoCompatDirNlink RoCompatFeature = 0x20
RoCompatExtraIsize RoCompatFeature = 0x40
RoCompatHasSnapshot RoCompatFeature = 0x80
RoCompatQuota RoCompatFeature = 0x100
RoCompatBigalloc RoCompatFeature = 0x200
RoCompatMetadataCsum RoCompatFeature = 0x400
RoCompatReplica RoCompatFeature = 0x800
RoCompatReadonly RoCompatFeature = 0x1000
RoCompatProject RoCompatFeature = 0x2000
)
type BlockGroupFlag uint16
const (
BlockGroupInodeUninit BlockGroupFlag = 0x1
BlockGroupBlockUninit BlockGroupFlag = 0x2
BlockGroupInodeZeroed BlockGroupFlag = 0x4
)
type GroupDescriptor struct {
BlockBitmapLow uint32
InodeBitmapLow uint32
InodeTableLow uint32
FreeBlocksCountLow uint16
FreeInodesCountLow uint16
UsedDirsCountLow uint16
Flags BlockGroupFlag
ExcludeBitmapLow uint32
BlockBitmapCsumLow uint16
InodeBitmapCsumLow uint16
ItableUnusedLow uint16
Checksum uint16
}
type GroupDescriptor64 struct {
GroupDescriptor
BlockBitmapHigh uint32
InodeBitmapHigh uint32
InodeTableHigh uint32
FreeBlocksCountHigh uint16
FreeInodesCountHigh uint16
UsedDirsCountHigh uint16
ItableUnusedHigh uint16
ExcludeBitmapHigh uint32
BlockBitmapCsumHigh uint16
InodeBitmapCsumHigh uint16
Reserved uint32
}
const (
S_IXOTH = 0x1
S_IWOTH = 0x2
S_IROTH = 0x4
S_IXGRP = 0x8
S_IWGRP = 0x10
S_IRGRP = 0x20
S_IXUSR = 0x40
S_IWUSR = 0x80
S_IRUSR = 0x100
S_ISVTX = 0x200
S_ISGID = 0x400
S_ISUID = 0x800
S_IFIFO = 0x1000
S_IFCHR = 0x2000
S_IFDIR = 0x4000
S_IFBLK = 0x6000
S_IFREG = 0x8000
S_IFLNK = 0xA000
S_IFSOCK = 0xC000
TypeMask uint16 = 0xF000
)
type InodeNumber uint32
const (
InodeRoot = 2
)
type Inode struct {
Mode uint16
Uid uint16
SizeLow uint32
Atime uint32
Ctime uint32
Mtime uint32
Dtime uint32
Gid uint16
LinksCount uint16
BlocksLow uint32
Flags InodeFlag
Version uint32
Block [60]byte
Generation uint32
XattrBlockLow uint32
SizeHigh uint32
ObsoleteFragmentAddr uint32
BlocksHigh uint16
XattrBlockHigh uint16
UidHigh uint16
GidHigh uint16
ChecksumLow uint16
Reserved uint16
ExtraIsize uint16
ChecksumHigh uint16
CtimeExtra uint32
MtimeExtra uint32
AtimeExtra uint32
Crtime uint32
CrtimeExtra uint32
VersionHigh uint32
Projid uint32
}
type InodeFlag uint32
const (
InodeFlagSecRm InodeFlag = 0x1
InodeFlagUnRm InodeFlag = 0x2
InodeFlagCompressed InodeFlag = 0x4
InodeFlagSync InodeFlag = 0x8
InodeFlagImmutable InodeFlag = 0x10
InodeFlagAppend InodeFlag = 0x20
InodeFlagNoDump InodeFlag = 0x40
InodeFlagNoAtime InodeFlag = 0x80
InodeFlagDirtyCompressed InodeFlag = 0x100
InodeFlagCompressedClusters InodeFlag = 0x200
InodeFlagNoCompress InodeFlag = 0x400
InodeFlagEncrypted InodeFlag = 0x800
InodeFlagHashedIndex InodeFlag = 0x1000
InodeFlagMagic InodeFlag = 0x2000
InodeFlagJournalData InodeFlag = 0x4000
InodeFlagNoTail InodeFlag = 0x8000
InodeFlagDirSync InodeFlag = 0x10000
InodeFlagTopDir InodeFlag = 0x20000
InodeFlagHugeFile InodeFlag = 0x40000
InodeFlagExtents InodeFlag = 0x80000
InodeFlagEaInode InodeFlag = 0x200000
InodeFlagEOFBlocks InodeFlag = 0x400000
InodeFlagSnapfile InodeFlag = 0x01000000
InodeFlagSnapfileDeleted InodeFlag = 0x04000000
InodeFlagSnapfileShrunk InodeFlag = 0x08000000
InodeFlagInlineData InodeFlag = 0x10000000
InodeFlagProjectIDInherit InodeFlag = 0x20000000
InodeFlagReserved InodeFlag = 0x80000000
)
const (
MaxLinks = 65000
)
type ExtentHeader struct {
Magic uint16
Entries uint16
Max uint16
Depth uint16
Generation uint32
}
const ExtentHeaderMagic uint16 = 0xf30a
type ExtentIndexNode struct {
Block uint32
LeafLow uint32
LeafHigh uint16
Unused uint16
}
type ExtentLeafNode struct {
Block uint32
Length uint16
StartHigh uint16
StartLow uint32
}
type ExtentTail struct {
Checksum uint32
}
type DirectoryEntry struct {
Inode InodeNumber
RecordLength uint16
NameLength uint8
FileType FileType
//Name []byte
}
type FileType uint8
const (
FileTypeUnknown FileType = 0x0
FileTypeRegular FileType = 0x1
FileTypeDirectory FileType = 0x2
FileTypeCharacter FileType = 0x3
FileTypeBlock FileType = 0x4
FileTypeFIFO FileType = 0x5
FileTypeSocket FileType = 0x6
FileTypeSymbolicLink FileType = 0x7
)
type DirectoryEntryTail struct {
ReservedZero1 uint32
RecordLength uint16
ReservedZero2 uint8
FileType uint8
Checksum uint32
}
type DirectoryTreeRoot struct {
Dot DirectoryEntry
DotName [4]byte
DotDot DirectoryEntry
DotDotName [4]byte
ReservedZero uint32
HashVersion uint8
InfoLength uint8
IndirectLevels uint8
UnusedFlags uint8
Limit uint16
Count uint16
Block uint32
//Entries []DirectoryTreeEntry
}
type DirectoryTreeNode struct {
FakeInode uint32
FakeRecordLength uint16
NameLength uint8
FileType uint8
Limit uint16
Count uint16
Block uint32
//Entries []DirectoryTreeEntry
}
type DirectoryTreeEntry struct {
Hash uint32
Block uint32
}
type DirectoryTreeTail struct {
Reserved uint32
Checksum uint32
}
type XAttrInodeBodyHeader struct {
Magic uint32
}
type XAttrHeader struct {
Magic uint32
ReferenceCount uint32
Blocks uint32
Hash uint32
Checksum uint32
Reserved [3]uint32
}
const XAttrHeaderMagic uint32 = 0xea020000
type XAttrEntry struct {
NameLength uint8
NameIndex uint8
ValueOffset uint16
ValueInum uint32
ValueSize uint32
Hash uint32
//Name []byte
}

View File

@ -0,0 +1,174 @@
package tar2ext4
import (
"archive/tar"
"bufio"
"encoding/binary"
"io"
"path"
"strings"
"github.com/Microsoft/hcsshim/ext4/internal/compactext4"
)
type params struct {
convertWhiteout bool
appendVhdFooter bool
ext4opts []compactext4.Option
}
// Option is the type for optional parameters to Convert.
type Option func(*params)
// ConvertWhiteout instructs the converter to convert OCI-style whiteouts
// (beginning with .wh.) to overlay-style whiteouts.
func ConvertWhiteout(p *params) {
p.convertWhiteout = true
}
// AppendVhdFooter instructs the converter to add a fixed VHD footer to the
// file.
func AppendVhdFooter(p *params) {
p.appendVhdFooter = true
}
// InlineData instructs the converter to write small files into the inode
// structures directly. This creates smaller images but currently is not
// compatible with DAX.
func InlineData(p *params) {
p.ext4opts = append(p.ext4opts, compactext4.InlineData)
}
// MaximumDiskSize instructs the writer to limit the disk size to the specified
// value. This also reserves enough metadata space for the specified disk size.
// If not provided, then 16GB is the default.
func MaximumDiskSize(size int64) Option {
return func(p *params) {
p.ext4opts = append(p.ext4opts, compactext4.MaximumDiskSize(size))
}
}
const (
whiteoutPrefix = ".wh."
opaqueWhiteout = ".wh..wh..opq"
)
// Convert writes a compact ext4 file system image that contains the files in the
// input tar stream.
func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
var p params
for _, opt := range options {
opt(&p)
}
t := tar.NewReader(bufio.NewReader(r))
fs := compactext4.NewWriter(w, p.ext4opts...)
for {
hdr, err := t.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
if p.convertWhiteout {
dir, name := path.Split(hdr.Name)
if strings.HasPrefix(name, whiteoutPrefix) {
if name == opaqueWhiteout {
// Update the directory with the appropriate xattr.
f, err := fs.Stat(dir)
if err != nil {
return err
}
f.Xattrs["trusted.overlay.opaque"] = []byte("y")
err = fs.Create(dir, f)
if err != nil {
return err
}
} else {
// Create an overlay-style whiteout.
f := &compactext4.File{
Mode: compactext4.S_IFCHR,
Devmajor: 0,
Devminor: 0,
}
err = fs.Create(path.Join(dir, name[len(whiteoutPrefix):]), f)
if err != nil {
return err
}
}
continue
}
}
if hdr.Typeflag == tar.TypeLink {
err = fs.Link(hdr.Linkname, hdr.Name)
if err != nil {
return err
}
} else {
f := &compactext4.File{
Mode: uint16(hdr.Mode),
Atime: hdr.AccessTime,
Mtime: hdr.ModTime,
Ctime: hdr.ChangeTime,
Crtime: hdr.ModTime,
Size: hdr.Size,
Uid: uint32(hdr.Uid),
Gid: uint32(hdr.Gid),
Linkname: hdr.Linkname,
Devmajor: uint32(hdr.Devmajor),
Devminor: uint32(hdr.Devminor),
Xattrs: make(map[string][]byte),
}
for key, value := range hdr.PAXRecords {
const xattrPrefix = "SCHILY.xattr."
if strings.HasPrefix(key, xattrPrefix) {
f.Xattrs[key[len(xattrPrefix):]] = []byte(value)
}
}
var typ uint16
switch hdr.Typeflag {
case tar.TypeReg, tar.TypeRegA:
typ = compactext4.S_IFREG
case tar.TypeSymlink:
typ = compactext4.S_IFLNK
case tar.TypeChar:
typ = compactext4.S_IFCHR
case tar.TypeBlock:
typ = compactext4.S_IFBLK
case tar.TypeDir:
typ = compactext4.S_IFDIR
case tar.TypeFifo:
typ = compactext4.S_IFIFO
}
f.Mode &= ^compactext4.TypeMask
f.Mode |= typ
err = fs.Create(hdr.Name, f)
if err != nil {
return err
}
_, err = io.Copy(fs, t)
if err != nil {
return err
}
}
}
err := fs.Close()
if err != nil {
return err
}
if p.appendVhdFooter {
size, err := w.Seek(0, io.SeekEnd)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, makeFixedVHDFooter(size))
if err != nil {
return err
}
}
return nil
}

View File

@ -0,0 +1,76 @@
package tar2ext4
import (
"bytes"
"crypto/rand"
"encoding/binary"
)
// Constants for the VHD footer
const (
cookieMagic = "conectix"
featureMask = 0x2
fileFormatVersionMagic = 0x00010000
fixedDataOffset = -1
creatorVersionMagic = 0x000a0000
diskTypeFixed = 2
)
type vhdFooter struct {
Cookie [8]byte
Features uint32
FileFormatVersion uint32
DataOffset int64
TimeStamp uint32
CreatorApplication [4]byte
CreatorVersion uint32
CreatorHostOS [4]byte
OriginalSize int64
CurrentSize int64
DiskGeometry uint32
DiskType uint32
Checksum uint32
UniqueID [16]uint8
SavedState uint8
Reserved [427]uint8
}
func makeFixedVHDFooter(size int64) *vhdFooter {
footer := &vhdFooter{
Features: featureMask,
FileFormatVersion: fileFormatVersionMagic,
DataOffset: fixedDataOffset,
CreatorVersion: creatorVersionMagic,
OriginalSize: size,
CurrentSize: size,
DiskType: diskTypeFixed,
UniqueID: generateUUID(),
}
copy(footer.Cookie[:], cookieMagic)
footer.Checksum = calculateCheckSum(footer)
return footer
}
func calculateCheckSum(footer *vhdFooter) uint32 {
oldchk := footer.Checksum
footer.Checksum = 0
buf := &bytes.Buffer{}
binary.Write(buf, binary.BigEndian, footer)
var chk uint32
bufBytes := buf.Bytes()
for i := 0; i < len(bufBytes); i++ {
chk += uint32(bufBytes[i])
}
footer.Checksum = oldchk
return uint32(^chk)
}
func generateUUID() [16]byte {
res := [16]byte{}
if _, err := rand.Read(res[:]); err != nil {
panic(err)
}
return res
}

View File

@ -6,6 +6,7 @@ import (
// HNSEndpoint represents a network endpoint in HNS
type HNSEndpoint = hns.HNSEndpoint
// Namespace represents a Compartment.
type Namespace = hns.Namespace

View File

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

View File

@ -27,6 +27,7 @@ import (
//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
//sys hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?

View File

@ -8,6 +8,7 @@ import (
"syscall"
"time"
"github.com/Microsoft/hcsshim/internal/guestrequest"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus"
)
@ -71,6 +72,39 @@ func (process *Process) SystemID() string {
return process.system.ID()
}
// Signal signals the process with `options`.
func (process *Process) Signal(options guestrequest.SignalProcessOptions) error {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "Signal"
title := "hcsshim::Process::" + operation
logrus.Debugf(title+" processid=%d", process.processID)
if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
optionsb, err := json.Marshal(options)
if err != nil {
return err
}
optionsStr := string(optionsb)
var resultp *uint16
completed := false
go syscallWatcher(fmt.Sprintf("SignalProcess %s: %d", process.SystemID(), process.Pid()), &completed)
err = hcsSignalProcess(process.handle, optionsStr, &resultp)
completed = true
events := processHcsResult(resultp)
if err != nil {
return makeProcessError(process, operation, err, events)
}
logrus.Debugf(title+" succeeded processid=%d", process.processID)
return nil
}
// Kill signals the process to terminate but does not wait for it to finish terminating.
func (process *Process) Kill() error {
process.handleLock.RLock()

View File

@ -57,12 +57,13 @@ var (
procHcsOpenProcess = modvmcompute.NewProc("HcsOpenProcess")
procHcsCloseProcess = modvmcompute.NewProc("HcsCloseProcess")
procHcsTerminateProcess = modvmcompute.NewProc("HcsTerminateProcess")
procHcsGetProcessInfo = modvmcompute.NewProc("HcsGetProcessInfo")
procHcsGetProcessProperties = modvmcompute.NewProc("HcsGetProcessProperties")
procHcsModifyProcess = modvmcompute.NewProc("HcsModifyProcess")
procHcsGetServiceProperties = modvmcompute.NewProc("HcsGetServiceProperties")
procHcsRegisterProcessCallback = modvmcompute.NewProc("HcsRegisterProcessCallback")
procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
procHcsGetProcessInfo = modvmcompute.NewProc("HcsGetProcessInfo")
procHcsGetProcessProperties = modvmcompute.NewProc("HcsGetProcessProperties")
procHcsModifyProcess = modvmcompute.NewProc("HcsModifyProcess")
procHcsGetServiceProperties = modvmcompute.NewProc("HcsGetServiceProperties")
procHcsRegisterProcessCallback = modvmcompute.NewProc("HcsRegisterProcessCallback")
procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
)
func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) {
@ -356,6 +357,26 @@ func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
return
}
func hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsSignalProcess(process, _p0, result)
}
func _hcsSignalProcess(process hcsProcess, options *uint16, result **uint16) (hr error) {
if hr = procHcsTerminateProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
hr = interop.Win32FromHresult(r0)
}
return
}
func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) {
if hr = procHcsGetProcessInfo.Find(); hr != nil {
return

View File

@ -3,6 +3,8 @@ package schema1
import (
"encoding/json"
"time"
"github.com/Microsoft/hcsshim/internal/schema2"
)
// ProcessConfig is used as both the input of Container.CreateProcess
@ -115,9 +117,10 @@ type ComputeSystemQuery struct {
type PropertyType string
const (
PropertyTypeStatistics PropertyType = "Statistics"
PropertyTypeProcessList = "ProcessList"
PropertyTypeMappedVirtualDisk = "MappedVirtualDisk"
PropertyTypeStatistics PropertyType = "Statistics" // V1 and V2
PropertyTypeProcessList = "ProcessList" // V1 and V2
PropertyTypeMappedVirtualDisk = "MappedVirtualDisk" // Not supported in V2 schema call
PropertyTypeGuestConnection = "GuestConnection" // V1 and V2. Nil return from HCS before RS5
)
type PropertyQuery struct {
@ -142,6 +145,7 @@ type ContainerProperties struct {
Statistics Statistics `json:",omitempty"`
ProcessList []ProcessListItem `json:",omitempty"`
MappedVirtualDiskControllers map[int]MappedVirtualDiskController `json:",omitempty"`
GuestConnectionInfo GuestConnectionInfo `json:",omitempty"`
}
// MemoryStats holds the memory statistics for a container
@ -206,6 +210,19 @@ type MappedVirtualDiskController struct {
MappedVirtualDisks map[int]MappedVirtualDisk `json:",omitempty"`
}
// GuestDefinedCapabilities is part of the GuestConnectionInfo returned by a GuestConnection call on a utility VM
type GuestDefinedCapabilities struct {
NamespaceAddRequestSupported bool `json:",omitempty"`
SignalProcessSupported bool `json:",omitempty"`
}
// GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM
type GuestConnectionInfo struct {
SupportedSchemaVersions []hcsschema.Version `json:",omitempty"`
ProtocolVersion uint32 `json:",omitempty"`
GuestDefinedCapabilities GuestDefinedCapabilities `json:",omitempty"`
}
// Type of Request Support in ModifySystem
type RequestType string

View File

@ -0,0 +1,31 @@
/*
* 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 Attachment struct {
Type_ string `json:"Type,omitempty"`
Path string `json:"Path,omitempty"`
IgnoreFlushes bool `json:"IgnoreFlushes,omitempty"`
CachingMode string `json:"CachingMode,omitempty"`
NoWriteHardening bool `json:"NoWriteHardening,omitempty"`
DisableExpansionOptimization bool `json:"DisableExpansionOptimization,omitempty"`
IgnoreRelativeLocator bool `json:"IgnoreRelativeLocator,omitempty"`
CaptureIoAttributionContext bool `json:"CaptureIoAttributionContext,omitempty"`
ReadOnly bool `json:"ReadOnly,omitempty"`
}

View File

@ -0,0 +1,13 @@
/*
* 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 Battery struct {
}

View File

@ -0,0 +1,19 @@
/*
* 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 CacheQueryStatsResponse struct {
L3OccupancyBytes int32 `json:"L3OccupancyBytes,omitempty"`
L3TotalBwBytes int32 `json:"L3TotalBwBytes,omitempty"`
L3LocalBwBytes int32 `json:"L3LocalBwBytes,omitempty"`
}

View File

@ -0,0 +1,25 @@
/*
* 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 Chipset struct {
Uefi *Uefi `json:"Uefi,omitempty"`
IsNumLockDisabled bool `json:"IsNumLockDisabled,omitempty"`
BaseBoardSerialNumber string `json:"BaseBoardSerialNumber,omitempty"`
ChassisSerialNumber string `json:"ChassisSerialNumber,omitempty"`
ChassisAssetTag string `json:"ChassisAssetTag,omitempty"`
UseUtc bool `json:"UseUtc,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 CloseHandle struct {
Handle string `json:"Handle,omitempty"`
}

View File

@ -0,0 +1,18 @@
/*
* 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
// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port.
type ComPort struct {
NamedPipe string `json:"NamedPipe,omitempty"`
OptimizeForDebugger bool `json:"OptimizeForDebugger,omitempty"`
}

View File

@ -0,0 +1,27 @@
/*
* 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 ComputeSystem struct {
Owner string `json:"Owner,omitempty"`
SchemaVersion *Version `json:"SchemaVersion,omitempty"`
HostingSystemId string `json:"HostingSystemId,omitempty"`
HostedSystem *HostedSystem `json:"HostedSystem,omitempty"`
Container *Container `json:"Container,omitempty"`
VirtualMachine *VirtualMachine `json:"VirtualMachine,omitempty"`
ShouldTerminateOnLastHandleClosed bool `json:"ShouldTerminateOnLastHandleClosed,omitempty"`
}

View File

@ -0,0 +1,72 @@
/*
* 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
import (
"net/http"
)
// contextKeys are used to identify the type of value in the context.
// Since these are string, it is possible to get a short description of the
// context key for logging and debugging using key.String().
type contextKey string
func (c contextKey) String() string {
return "auth " + string(c)
}
var (
// ContextOAuth2 takes a oauth2.TokenSource as authentication for the request.
ContextOAuth2 = contextKey("token")
// ContextBasicAuth takes BasicAuth as authentication for the request.
ContextBasicAuth = contextKey("basic")
// ContextAccessToken takes a string oauth2 access token as authentication for the request.
ContextAccessToken = contextKey("accesstoken")
// ContextAPIKey takes an APIKey as authentication for the request
ContextAPIKey = contextKey("apikey")
)
// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth
type BasicAuth struct {
UserName string `json:"userName,omitempty"`
Password string `json:"password,omitempty"`
}
// APIKey provides API key based authentication to a request passed via context using ContextAPIKey
type APIKey struct {
Key string
Prefix string
}
type Configuration struct {
BasePath string `json:"basePath,omitempty"`
Host string `json:"host,omitempty"`
Scheme string `json:"scheme,omitempty"`
DefaultHeader map[string]string `json:"defaultHeader,omitempty"`
UserAgent string `json:"userAgent,omitempty"`
HTTPClient *http.Client
}
func NewConfiguration() *Configuration {
cfg := &Configuration{
BasePath: "https://localhost",
DefaultHeader: make(map[string]string),
UserAgent: "Swagger-Codegen/2.1.0/go",
}
return cfg
}
func (c *Configuration) AddDefaultHeader(key string, value string) {
c.DefaultHeader[key] = value
}

View File

@ -0,0 +1,17 @@
/*
* 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 ConsoleSize struct {
Height int32 `json:"Height,omitempty"`
Width int32 `json:"Width,omitempty"`
}

View File

@ -0,0 +1,35 @@
/*
* 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 Container struct {
GuestOs *GuestOs `json:"GuestOs,omitempty"`
Storage *Storage `json:"Storage,omitempty"`
MappedDirectories []MappedDirectory `json:"MappedDirectories,omitempty"`
MappedPipes []MappedPipe `json:"MappedPipes,omitempty"`
Memory *Memory `json:"Memory,omitempty"`
Processor *Processor `json:"Processor,omitempty"`
Networking *Networking `json:"Networking,omitempty"`
HvSocket *HvSocket `json:"HvSocket,omitempty"`
ContainerCredentialGuard *ContainerCredentialGuardState `json:"ContainerCredentialGuard,omitempty"`
RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"`
AssignedDevices []Device `json:"AssignedDevices,omitempty"`
}

View File

@ -0,0 +1,25 @@
/*
* 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 ContainerCredentialGuardState struct {
// Authentication cookie for calls to a Container Credential Guard instance.
Cookie string `json:"Cookie,omitempty"`
// Name of the RPC endpoint of the Container Credential Guard instance.
RpcEndpoint string `json:"RpcEndpoint,omitempty"`
// Transport used for the configured Container Credential Guard instance.
Transport string `json:"Transport,omitempty"`
// Credential spec used for the configured Container Credential Guard instance.
CredentialSpec string `json:"CredentialSpec,omitempty"`
}

View File

@ -0,0 +1,26 @@
/*
* 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
// memory usage as viewed from within the container
type ContainerMemoryInformation struct {
TotalPhysicalBytes int32 `json:"TotalPhysicalBytes,omitempty"`
TotalUsage int32 `json:"TotalUsage,omitempty"`
CommittedBytes int32 `json:"CommittedBytes,omitempty"`
SharedCommittedBytes int32 `json:"SharedCommittedBytes,omitempty"`
CommitLimitBytes int32 `json:"CommitLimitBytes,omitempty"`
PeakCommitmentBytes int32 `json:"PeakCommitmentBytes,omitempty"`
}

View File

@ -0,0 +1,16 @@
/*
* 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 Device struct {
// The interface class guid of the device to assign to container.
InterfaceClassGuid string `json:"InterfaceClassGuid,omitempty"`
}

View File

@ -0,0 +1,43 @@
/*
* 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 Devices struct {
ComPorts map[string]ComPort `json:"ComPorts,omitempty"`
Scsi map[string]Scsi `json:"Scsi,omitempty"`
VirtualPMem *VirtualPMemController `json:"VirtualPMem,omitempty"`
NetworkAdapters map[string]NetworkAdapter `json:"NetworkAdapters,omitempty"`
VideoMonitor *VideoMonitor `json:"VideoMonitor,omitempty"`
Keyboard *Keyboard `json:"Keyboard,omitempty"`
Mouse *Mouse `json:"Mouse,omitempty"`
HvSocket *HvSocket2 `json:"HvSocket,omitempty"`
EnhancedModeVideo *EnhancedModeVideo `json:"EnhancedModeVideo,omitempty"`
GuestCrashReporting *GuestCrashReporting `json:"GuestCrashReporting,omitempty"`
VirtualSmb *VirtualSmb `json:"VirtualSmb,omitempty"`
Plan9 *Plan9 `json:"Plan9,omitempty"`
Battery *Battery `json:"Battery,omitempty"`
FlexibleIov map[string]FlexibleIoDevice `json:"FlexibleIov,omitempty"`
SharedMemory *SharedMemoryConfiguration `json:"SharedMemory,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 EnhancedModeVideo struct {
ConnectionOptions *RdpConnectionOptions `json:"ConnectionOptions,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 FlexibleIoDevice struct {
EmulatorId string `json:"EmulatorId,omitempty"`
HostingModel string `json:"HostingModel,omitempty"`
Configuration []string `json:"Configuration,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 GuestConnection struct {
// Use Vsock rather than Hyper-V sockets to communicate with the guest service.
UseVsock bool `json:"UseVsock,omitempty"`
// Don't disconnect the guest connection when pausing the virtual machine.
UseConnectedSuspend bool `json:"UseConnectedSuspend,omitempty"`
}

View File

@ -0,0 +1,21 @@
/*
* 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
// Information about the guest.
type GuestConnectionInfo struct {
// Each schema version x.y stands for the range of versions a.b where a==x and b<=y. This list comes from the SupportedSchemaVersions field in GcsCapabilities.
SupportedSchemaVersions []Version `json:"SupportedSchemaVersions,omitempty"`
ProtocolVersion int32 `json:"ProtocolVersion,omitempty"`
GuestDefinedCapabilities *interface{} `json:"GuestDefinedCapabilities,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 GuestCrashReporting struct {
WindowsCrashSettings *WindowsCrashReporting `json:"WindowsCrashSettings,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 GuestOs struct {
HostName string `json:"HostName,omitempty"`
}

View File

@ -0,0 +1,22 @@
/*
* 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 GuestState struct {
// The path to an existing file uses for persistent guest state storage. An empty string indicates the system should initialize new transient, in-memory guest state.
GuestStateFilePath string `json:"GuestStateFilePath,omitempty"`
// The path to an existing file for persistent runtime state storage. An empty string indicates the system should initialize new transient, in-memory runtime state.
RuntimeStateFilePath string `json:"RuntimeStateFilePath,omitempty"`
// If true, the guest state and runtime state files will be used as templates to populate transient, in-memory state instead of using the files as persistent backing store.
ForceTransientState bool `json:"ForceTransientState,omitempty"`
}

View File

@ -0,0 +1,17 @@
/*
* 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 HostedSystem struct {
SchemaVersion *Version `json:"SchemaVersion,omitempty"`
Container *Container `json:"Container,omitempty"`
}

View File

@ -0,0 +1,17 @@
/*
* 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 HvSocket struct {
Config *HvSocketSystemConfig `json:"Config,omitempty"`
EnablePowerShellDirect bool `json:"EnablePowerShellDirect,omitempty"`
}

View File

@ -0,0 +1,16 @@
/*
* 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
// HvSocket configuration for a VM
type HvSocket2 struct {
HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"`
}

View File

@ -0,0 +1,22 @@
/*
* 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 HvSocketServiceConfig struct {
// SDDL string that HvSocket will check before allowing a host process to bind to this specific service. If not specified, defaults to the system DefaultBindSecurityDescriptor, defined in HvSocketSystemWpConfig in V1.
BindSecurityDescriptor string `json:"BindSecurityDescriptor,omitempty"`
// SDDL string that HvSocket will check before allowing a host process to connect to this specific service. If not specified, defaults to the system DefaultConnectSecurityDescriptor, defined in HvSocketSystemWpConfig in V1.
ConnectSecurityDescriptor string `json:"ConnectSecurityDescriptor,omitempty"`
// If true, HvSocket will process wildcard binds for this service/system combination. Wildcard binds are secured in the registry at SOFTWARE/Microsoft/Windows NT/CurrentVersion/Virtualization/HvSocket/WildcardDescriptors
AllowWildcardBinds bool `json:"AllowWildcardBinds,omitempty"`
}

View File

@ -0,0 +1,22 @@
/*
* 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
// This is the HCS Schema version of the HvSocket configuration. The VMWP version is located in Config.Devices.IC in V1.
type HvSocketSystemConfig struct {
// SDDL string that HvSocket will check before allowing a host process to bind to an unlisted service for this specific container/VM (not wildcard binds).
DefaultBindSecurityDescriptor string `json:"DefaultBindSecurityDescriptor,omitempty"`
// SDDL string that HvSocket will check before allowing a host process to connect to an unlisted service in the VM/container.
DefaultConnectSecurityDescriptor string `json:"DefaultConnectSecurityDescriptor,omitempty"`
ServiceTable map[string]HvSocketServiceConfig `json:"ServiceTable,omitempty"`
}

View File

@ -0,0 +1,13 @@
/*
* 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 Keyboard struct {
}

View File

@ -0,0 +1,22 @@
/*
* 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 Layer struct {
Id string `json:"Id,omitempty"`
Path string `json:"Path,omitempty"`
PathType string `json:"PathType,omitempty"`
// Unspecified defaults to Enabled
Cache string `json:"Cache,omitempty"`
}

View File

@ -0,0 +1,21 @@
/*
* 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 MappedDirectory struct {
HostPath string `json:"HostPath,omitempty"`
HostPathType string `json:"HostPathType,omitempty"`
ContainerPath string `json:"ContainerPath,omitempty"`
ReadOnly bool `json:"ReadOnly,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 MappedPipe struct {
ContainerPipeName string `json:"ContainerPipeName,omitempty"`
HostPath string `json:"HostPath,omitempty"`
HostPathType string `json:"HostPathType,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 Memory struct {
SizeInMB int32 `json:"SizeInMB,omitempty"`
}

View 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 Memory2 struct {
SizeInMB int32 `json:"SizeInMB,omitempty"`
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
EnableHotHint bool `json:"EnableHotHint,omitempty"`
EnableColdHint bool `json:"EnableColdHint,omitempty"`
EnableEpf bool `json:"EnableEpf,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 MemoryInformationForVm struct {
VirtualNodeCount int32 `json:"VirtualNodeCount,omitempty"`
VirtualMachineMemory *VmMemory `json:"VirtualMachineMemory,omitempty"`
VirtualNodes []VirtualNodeInfo `json:"VirtualNodes,omitempty"`
}

View File

@ -0,0 +1,20 @@
/*
* 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
// Memory runtime statistics
type MemoryStats struct {
MemoryUsageCommitBytes int32 `json:"MemoryUsageCommitBytes,omitempty"`
MemoryUsageCommitPeakBytes int32 `json:"MemoryUsageCommitPeakBytes,omitempty"`
MemoryUsagePrivateWorkingSetBytes int32 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
}

View File

@ -0,0 +1,20 @@
/*
* 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 ModifySettingRequest struct {
ResourcePath string `json:"ResourcePath,omitempty"`
RequestType string `json:"RequestType,omitempty"`
Settings interface{} `json:"Settings,omitempty"` // NOTE: Swagger generated as *interface{}. Locally updated
GuestRequest interface{} `json:"GuestRequest,omitempty"` // NOTE: Swagger generated as *interface{}. Locally updated
}

View File

@ -0,0 +1,13 @@
/*
* 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 Mouse struct {
}

View File

@ -0,0 +1,17 @@
/*
* 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 NetworkAdapter struct {
EndpointId string `json:"EndpointId,omitempty"`
MacAddress string `json:"MacAddress,omitempty"`
}

View File

@ -0,0 +1,24 @@
/*
* 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 Networking struct {
AllowUnqualifiedDnsQuery bool `json:"AllowUnqualifiedDnsQuery,omitempty"`
DnsSearchList string `json:"DnsSearchList,omitempty"`
NetworkSharedContainerName string `json:"NetworkSharedContainerName,omitempty"`
// Guid in windows; string in linux
Namespace string `json:"Namespace,omitempty"`
NetworkAdapters []string `json:"NetworkAdapters,omitempty"`
}

View File

@ -0,0 +1,16 @@
/*
* 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
// Notification data that is indicated to components running in the Virtual Machine.
type PauseNotification struct {
Reason string `json:"Reason,omitempty"`
}

View File

@ -0,0 +1,18 @@
/*
* 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
// Options for HcsPauseComputeSystem
type PauseOptions struct {
SuspensionLevel string `json:"SuspensionLevel,omitempty"`
HostedNotification *PauseNotification `json:"HostedNotification,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 Plan9 struct {
Shares []Plan9Share `json:"Shares,omitempty"`
}

View File

@ -0,0 +1,26 @@
/*
* 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 Plan9Share struct {
Name string `json:"Name,omitempty"`
// The name by which the guest operation system can access this share, via the aname parameter in the Plan9 protocol.
AccessName string `json:"AccessName,omitempty"`
Path string `json:"Path,omitempty"`
Port int32 `json:"Port,omitempty"`
ReadOnly bool `json:"ReadOnly,omitempty"`
UseShareRootIdentity bool `json:"UseShareRootIdentity,omitempty"`
}

View File

@ -0,0 +1,34 @@
/*
* 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
import (
"time"
)
// Information about a process running in a container
type ProcessDetails struct {
ProcessId int32 `json:"ProcessId,omitempty"`
ImageName string `json:"ImageName,omitempty"`
CreateTimestamp time.Time `json:"CreateTimestamp,omitempty"`
UserTime100ns int32 `json:"UserTime100ns,omitempty"`
KernelTime100ns int32 `json:"KernelTime100ns,omitempty"`
MemoryCommitBytes int32 `json:"MemoryCommitBytes,omitempty"`
MemoryWorkingSetPrivateBytes int32 `json:"MemoryWorkingSetPrivateBytes,omitempty"`
MemoryWorkingSetSharedBytes int32 `json:"MemoryWorkingSetSharedBytes,omitempty"`
}

View File

@ -0,0 +1,20 @@
/*
* 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
// Passed to HcsRpc_ModifyProcess
type ProcessModifyRequest struct {
Operation string `json:"Operation,omitempty"`
ConsoleSize *ConsoleSize `json:"ConsoleSize,omitempty"`
CloseHandle *CloseHandle `json:"CloseHandle,omitempty"`
}

View File

@ -0,0 +1,47 @@
/*
* 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 ProcessParameters struct {
ApplicationName string `json:"ApplicationName,omitempty"`
CommandLine string `json:"CommandLine,omitempty"`
// optional alternative to CommandLine, currently only supported by Linux GCS
CommandArgs []string `json:"CommandArgs,omitempty"`
User string `json:"User,omitempty"`
WorkingDirectory string `json:"WorkingDirectory,omitempty"`
Environment map[string]string `json:"Environment,omitempty"`
// if set, will run as low-privilege process
RestrictedToken bool `json:"RestrictedToken,omitempty"`
// if set, ignore StdErrPipe
EmulateConsole bool `json:"EmulateConsole,omitempty"`
CreateStdInPipe bool `json:"CreateStdInPipe,omitempty"`
CreateStdOutPipe bool `json:"CreateStdOutPipe,omitempty"`
CreateStdErrPipe bool `json:"CreateStdErrPipe,omitempty"`
// height then width
ConsoleSize []int32 `json:"ConsoleSize,omitempty"`
// if set, find an existing session for the user and create the process in it
UseExistingLogin bool `json:"UseExistingLogin,omitempty"`
// if set, use the legacy console instead of conhost
UseLegacyConsole bool `json:"UseLegacyConsole,omitempty"`
}

View File

@ -0,0 +1,22 @@
/*
* 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
// Status of a process running in a container
type ProcessStatus struct {
ProcessId int32 `json:"ProcessId,omitempty"`
Exited bool `json:"Exited,omitempty"`
ExitCode int32 `json:"ExitCode,omitempty"`
LastWaitResult int32 `json:"LastWaitResult,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 Processor struct {
Count int32 `json:"Count,omitempty"`
Maximum int32 `json:"Maximum,omitempty"`
Weight int32 `json:"Weight,omitempty"`
}

View File

@ -0,0 +1,21 @@
/*
* 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 Processor2 struct {
Count int32 `json:"Count,omitempty"`
Limit int32 `json:"Limit,omitempty"`
Weight int32 `json:"Weight,omitempty"`
ExposeVirtualizationExtensions bool `json:"ExposeVirtualizationExtensions,omitempty"`
}

View File

@ -0,0 +1,20 @@
/*
* 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
// CPU runtime statistics
type ProcessorStats struct {
TotalRuntime100ns int32 `json:"TotalRuntime100ns,omitempty"`
RuntimeUser100ns int32 `json:"RuntimeUser100ns,omitempty"`
RuntimeKernel100ns int32 `json:"RuntimeKernel100ns,omitempty"`
}

View File

@ -0,0 +1,47 @@
/*
* 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 Properties struct {
Id string `json:"Id,omitempty"`
SystemType string `json:"SystemType,omitempty"`
RuntimeOsType string `json:"RuntimeOsType,omitempty"`
Name string `json:"Name,omitempty"`
Owner string `json:"Owner,omitempty"`
RuntimeId string `json:"RuntimeId,omitempty"`
RuntimeTemplateId string `json:"RuntimeTemplateId,omitempty"`
State string `json:"State,omitempty"`
Stopped bool `json:"Stopped,omitempty"`
ExitType string `json:"ExitType,omitempty"`
Memory *MemoryInformationForVm `json:"Memory,omitempty"`
Statistics *Statistics `json:"Statistics,omitempty"`
ProcessList []ProcessDetails `json:"ProcessList,omitempty"`
TerminateOnLastHandleClosed bool `json:"TerminateOnLastHandleClosed,omitempty"`
HostingSystemId string `json:"HostingSystemId,omitempty"`
SharedMemoryRegionInfo []SharedMemoryRegionInfo `json:"SharedMemoryRegionInfo,omitempty"`
GuestConnectionInfo *GuestConnectionInfo `json:"GuestConnectionInfo,omitempty"`
}

View File

@ -0,0 +1,16 @@
/*
* 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
// By default the basic properties will be returned. This query provides a way to request specific properties.
type PropertyQuery struct {
PropertyTypes []string `json:"PropertyTypes,omitempty"`
}

View File

@ -0,0 +1,17 @@
/*
* 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 RdpConnectionOptions struct {
AccessSids []string `json:"AccessSids,omitempty"`
NamedPipe string `json:"NamedPipe,omitempty"`
}

View File

@ -0,0 +1,17 @@
/*
* 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 RegistryChanges struct {
AddValues []RegistryValue `json:"AddValues,omitempty"`
DeleteKeys []RegistryKey `json:"DeleteKeys,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 RegistryKey struct {
Hive string `json:"Hive,omitempty"`
Name string `json:"Name,omitempty"`
Volatile bool `json:"Volatile,omitempty"`
}

View File

@ -0,0 +1,31 @@
/*
* 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 RegistryValue struct {
Key *RegistryKey `json:"Key,omitempty"`
Name string `json:"Name,omitempty"`
Type_ string `json:"Type,omitempty"`
// One and only one value type must be set.
StringValue string `json:"StringValue,omitempty"`
BinaryValue string `json:"BinaryValue,omitempty"`
DWordValue int32 `json:"DWordValue,omitempty"`
QWordValue int32 `json:"QWordValue,omitempty"`
// Only used if RegistryValueType is CustomType The data is in BinaryValue
CustomType int32 `json:"CustomType,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 RestoreState struct {
// The path to the save state file to restore the system from.
SaveStateFilePath string `json:"SaveStateFilePath,omitempty"`
// The ID of the template system to clone this new system off of. An empty string indicates the system should not be cloned from a template.
TemplateSystemId string `json:"TemplateSystemId,omitempty"`
}

View File

@ -0,0 +1,19 @@
/*
* 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 SaveOptions struct {
// The type of save operation to be performed.
SaveType string `json:"SaveType,omitempty"`
// The path to the file that will container the saved state.
SaveStateFilePath string `json:"SaveStateFilePath,omitempty"`
}

View File

@ -0,0 +1,16 @@
/*
* 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 Scsi struct {
// Map of attachments, where the key is the integer LUN number on the controller.
Attachments map[string]Attachment `json:"Attachments,omitempty"`
}

View File

@ -0,0 +1,15 @@
/*
* 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 SharedMemoryConfiguration struct {
Regions []SharedMemoryRegion `json:"Regions,omitempty"`
}

View 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 SharedMemoryRegion struct {
SectionName string `json:"SectionName,omitempty"`
StartOffset int32 `json:"StartOffset,omitempty"`
Length int32 `json:"Length,omitempty"`
AllowGuestWrite bool `json:"AllowGuestWrite,omitempty"`
HiddenFromGuest bool `json:"HiddenFromGuest,omitempty"`
}

View File

@ -0,0 +1,17 @@
/*
* 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 SharedMemoryRegionInfo struct {
SectionName string `json:"SectionName,omitempty"`
GuestPhysicalAddress int32 `json:"GuestPhysicalAddress,omitempty"`
}

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