Sfoglia il codice sorgente

Merge pull request #42 from tiborvass/18.09-cp-buildkit

[18.09] Buildkit cherry-picks
Andrew Hsu 6 anni fa
parent
commit
00a9cf39ed
100 ha cambiato i file con 5106 aggiunte e 3608 eliminazioni
  1. 4 3
      api/server/backend/build/backend.go
  2. 1 1
      api/server/router/build/backend.go
  3. 25 6
      api/server/router/build/build.go
  4. 23 2
      api/server/router/build/build_routes.go
  5. 13 14
      api/server/router/system/system.go
  6. 3 1
      api/server/router/system/system_routes.go
  7. 57 0
      api/swagger.yaml
  8. 15 7
      api/types/types.go
  9. 9 0
      builder/builder-next/adapters/containerimage/pull.go
  10. 4 0
      builder/builder-next/adapters/snapshot/snapshot.go
  11. 72 11
      builder/builder-next/builder.go
  12. 14 2
      builder/builder-next/controller.go
  13. 96 0
      builder/builder-next/imagerefchecker/checker.go
  14. 17 2
      client/build_prune.go
  15. 1 1
      client/interface.go
  16. 4 13
      cmd/dockerd/daemon.go
  17. 5 0
      daemon/daemon.go
  18. 11 0
      daemon/reload.go
  19. 2 1
      integration/build/build_session_test.go
  20. 6 6
      vendor.conf
  21. 1 1
      vendor/github.com/Microsoft/go-winio/backuptar/tar.go
  22. 2 1
      vendor/github.com/Microsoft/go-winio/fileinfo.go
  23. 13 5
      vendor/github.com/Microsoft/hcsshim/README.md
  24. 0 28
      vendor/github.com/Microsoft/hcsshim/activatelayer.go
  25. 70 678
      vendor/github.com/Microsoft/hcsshim/container.go
  26. 0 27
      vendor/github.com/Microsoft/hcsshim/createlayer.go
  27. 0 35
      vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
  28. 0 26
      vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
  29. 0 27
      vendor/github.com/Microsoft/hcsshim/destroylayer.go
  30. 62 66
      vendor/github.com/Microsoft/hcsshim/errors.go
  31. 0 26
      vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
  32. 0 19
      vendor/github.com/Microsoft/hcsshim/guid.go
  33. 4 142
      vendor/github.com/Microsoft/hcsshim/hcsshim.go
  34. 8 240
      vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
  35. 16 0
      vendor/github.com/Microsoft/hcsshim/hnsglobals.go
  36. 8 113
      vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
  37. 43 80
      vendor/github.com/Microsoft/hcsshim/hnspolicy.go
  38. 11 164
      vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
  39. 13 0
      vendor/github.com/Microsoft/hcsshim/hnssupport.go
  40. 10 100
      vendor/github.com/Microsoft/hcsshim/interface.go
  41. 22 0
      vendor/github.com/Microsoft/hcsshim/internal/guid/guid.go
  42. 4 2
      vendor/github.com/Microsoft/hcsshim/internal/hcs/callback.go
  43. 1 1
      vendor/github.com/Microsoft/hcsshim/internal/hcs/cgo.go
  44. 279 0
      vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go
  45. 47 0
      vendor/github.com/Microsoft/hcsshim/internal/hcs/hcs.go
  46. 386 0
      vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
  47. 547 0
      vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
  48. 1 1
      vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go
  49. 5 5
      vendor/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go
  50. 441 0
      vendor/github.com/Microsoft/hcsshim/internal/hcs/zsyscall_windows.go
  51. 51 0
      vendor/github.com/Microsoft/hcsshim/internal/hcserror/hcserror.go
  52. 23 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hns.go
  53. 260 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnsendpoint.go
  54. 5 3
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnsfuncs.go
  55. 28 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnsglobals.go
  56. 141 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnsnetwork.go
  57. 98 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go
  58. 200 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicylist.go
  59. 49 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/hnssupport.go
  60. 110 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/namespace.go
  61. 74 0
      vendor/github.com/Microsoft/hcsshim/internal/hns/zsyscall_windows.go
  62. 27 0
      vendor/github.com/Microsoft/hcsshim/internal/interop/interop.go
  63. 48 0
      vendor/github.com/Microsoft/hcsshim/internal/interop/zsyscall_windows.go
  64. 24 0
      vendor/github.com/Microsoft/hcsshim/internal/longpath/longpath.go
  65. 52 0
      vendor/github.com/Microsoft/hcsshim/internal/mergemaps/merge.go
  66. 53 49
      vendor/github.com/Microsoft/hcsshim/internal/safefile/safeopen.go
  67. 79 0
      vendor/github.com/Microsoft/hcsshim/internal/safefile/zsyscall_windows.go
  68. 228 0
      vendor/github.com/Microsoft/hcsshim/internal/schema1/schema1.go
  69. 26 0
      vendor/github.com/Microsoft/hcsshim/internal/timeout/timeout.go
  70. 25 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go
  71. 10 8
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayer.go
  72. 23 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go
  73. 31 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go
  74. 22 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go
  75. 23 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go
  76. 22 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go
  77. 19 28
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go
  78. 12 18
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go
  79. 8 4
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go
  80. 24 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go
  81. 24 40
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go
  82. 25 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go
  83. 13 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go
  84. 8 23
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go
  85. 51 63
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go
  86. 24 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go
  87. 8 14
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go
  88. 1 1
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go
  89. 23 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go
  90. 37 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go
  91. 597 0
      vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go
  92. 108 0
      vendor/github.com/Microsoft/hcsshim/layer.go
  93. 0 30
      vendor/github.com/Microsoft/hcsshim/layerexists.go
  94. 0 7
      vendor/github.com/Microsoft/hcsshim/legacy18.go
  95. 0 7
      vendor/github.com/Microsoft/hcsshim/legacy19.go
  96. 0 20
      vendor/github.com/Microsoft/hcsshim/nametoguid.go
  97. 15 327
      vendor/github.com/Microsoft/hcsshim/process.go
  98. 0 27
      vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
  99. 1 2
      vendor/github.com/Microsoft/hcsshim/version.go
  100. 0 1080
      vendor/github.com/Microsoft/hcsshim/zhcsshim.go

+ 4 - 3
api/server/backend/build/backend.go

@@ -88,7 +88,7 @@ func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string
 }
 
 // PruneCache removes all cached build sources
-func (b *Backend) PruneCache(ctx context.Context) (*types.BuildCachePruneReport, error) {
+func (b *Backend) PruneCache(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {
 	eg, ctx := errgroup.WithContext(ctx)
 
 	var fsCacheSize uint64
@@ -102,9 +102,10 @@ func (b *Backend) PruneCache(ctx context.Context) (*types.BuildCachePruneReport,
 	})
 
 	var buildCacheSize int64
+	var cacheIDs []string
 	eg.Go(func() error {
 		var err error
-		buildCacheSize, err = b.buildkit.Prune(ctx)
+		buildCacheSize, cacheIDs, err = b.buildkit.Prune(ctx, opts)
 		if err != nil {
 			return errors.Wrap(err, "failed to prune build cache")
 		}
@@ -115,7 +116,7 @@ func (b *Backend) PruneCache(ctx context.Context) (*types.BuildCachePruneReport,
 		return nil, err
 	}
 
-	return &types.BuildCachePruneReport{SpaceReclaimed: fsCacheSize + uint64(buildCacheSize)}, nil
+	return &types.BuildCachePruneReport{SpaceReclaimed: fsCacheSize + uint64(buildCacheSize), CachesDeleted: cacheIDs}, nil
 }
 
 // Cancel cancels the build by ID

+ 1 - 1
api/server/router/build/backend.go

@@ -14,7 +14,7 @@ type Backend interface {
 	Build(context.Context, backend.BuildConfig) (string, error)
 
 	// Prune build cache
-	PruneCache(context.Context) (*types.BuildCachePruneReport, error)
+	PruneCache(context.Context, types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error)
 
 	Cancel(context.Context, string) error
 }

+ 25 - 6
api/server/router/build/build.go

@@ -7,15 +7,19 @@ import (
 
 // buildRouter is a router to talk with the build controller
 type buildRouter struct {
-	backend        Backend
-	daemon         experimentalProvider
-	routes         []router.Route
-	builderVersion types.BuilderVersion
+	backend  Backend
+	daemon   experimentalProvider
+	routes   []router.Route
+	features *map[string]bool
 }
 
 // NewRouter initializes a new build router
-func NewRouter(b Backend, d experimentalProvider, bv types.BuilderVersion) router.Router {
-	r := &buildRouter{backend: b, daemon: d, builderVersion: bv}
+func NewRouter(b Backend, d experimentalProvider, features *map[string]bool) router.Router {
+	r := &buildRouter{
+		backend:  b,
+		daemon:   d,
+		features: features,
+	}
 	r.initRoutes()
 	return r
 }
@@ -32,3 +36,18 @@ func (r *buildRouter) initRoutes() {
 		router.NewPostRoute("/build/cancel", r.postCancel),
 	}
 }
+
+// BuilderVersion derives the default docker builder version from the config
+// Note: it is valid to have BuilderVersion unset which means it is up to the
+// client to choose which builder to use.
+func BuilderVersion(features map[string]bool) types.BuilderVersion {
+	var bv types.BuilderVersion
+	if v, ok := features["buildkit"]; ok {
+		if v {
+			bv = types.BuilderBuildKit
+		} else {
+			bv = types.BuilderV1
+		}
+	}
+	return bv
+}

+ 23 - 2
api/server/router/build/build_routes.go

@@ -18,6 +18,7 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/pkg/ioutils"
@@ -161,7 +162,26 @@ func parseVersion(s string) (types.BuilderVersion, error) {
 }
 
 func (br *buildRouter) postPrune(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	report, err := br.backend.PruneCache(ctx)
+	if err := httputils.ParseForm(r); err != nil {
+		return err
+	}
+	filters, err := filters.FromJSON(r.Form.Get("filters"))
+	if err != nil {
+		return errors.Wrap(err, "could not parse filters")
+	}
+	ksfv := r.FormValue("keep-storage")
+	ks, err := strconv.Atoi(ksfv)
+	if err != nil {
+		return errors.Wrapf(err, "keep-storage is in bytes and expects an integer, got %v", ksfv)
+	}
+
+	opts := types.BuildCachePruneOptions{
+		All:         httputils.BoolValue(r, "all"),
+		Filters:     filters,
+		KeepStorage: int64(ks),
+	}
+
+	report, err := br.backend.PruneCache(ctx, opts)
 	if err != nil {
 		return err
 	}
@@ -230,8 +250,9 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
 		return errdefs.InvalidParameter(errors.New("squash is only supported with experimental mode"))
 	}
 
+	builderVersion := BuilderVersion(*br.features)
 	// check if the builder feature has been enabled from daemon as well.
-	if buildOptions.Version == types.BuilderBuildKit && br.builderVersion != "" && br.builderVersion != types.BuilderBuildKit {
+	if buildOptions.Version == types.BuilderBuildKit && builderVersion != "" && builderVersion != types.BuilderBuildKit {
 		return errdefs.InvalidParameter(errors.New("buildkit is not enabled on daemon"))
 	}
 

+ 13 - 14
api/server/router/system/system.go

@@ -2,30 +2,29 @@ package system // import "github.com/docker/docker/api/server/router/system"
 
 import (
 	"github.com/docker/docker/api/server/router"
-	"github.com/docker/docker/api/types"
-	buildkit "github.com/docker/docker/builder/builder-next"
+	"github.com/docker/docker/builder/builder-next"
 	"github.com/docker/docker/builder/fscache"
 )
 
 // systemRouter provides information about the Docker system overall.
 // It gathers information about host, daemon and container events.
 type systemRouter struct {
-	backend        Backend
-	cluster        ClusterBackend
-	routes         []router.Route
-	fscache        *fscache.FSCache // legacy
-	builder        *buildkit.Builder
-	builderVersion types.BuilderVersion
+	backend  Backend
+	cluster  ClusterBackend
+	routes   []router.Route
+	fscache  *fscache.FSCache // legacy
+	builder  *buildkit.Builder
+	features *map[string]bool
 }
 
 // NewRouter initializes a new system router
-func NewRouter(b Backend, c ClusterBackend, fscache *fscache.FSCache, builder *buildkit.Builder, bv types.BuilderVersion) router.Router {
+func NewRouter(b Backend, c ClusterBackend, fscache *fscache.FSCache, builder *buildkit.Builder, features *map[string]bool) router.Router {
 	r := &systemRouter{
-		backend:        b,
-		cluster:        c,
-		fscache:        fscache,
-		builder:        builder,
-		builderVersion: bv,
+		backend:  b,
+		cluster:  c,
+		fscache:  fscache,
+		builder:  builder,
+		features: features,
 	}
 
 	r.routes = []router.Route{

+ 3 - 1
api/server/router/system/system_routes.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/docker/docker/api/server/httputils"
+	"github.com/docker/docker/api/server/router/build"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/filters"
@@ -26,7 +27,8 @@ func optionsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request,
 }
 
 func (s *systemRouter) pingHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	if bv := s.builderVersion; bv != "" {
+	builderVersion := build.BuilderVersion(*s.features)
+	if bv := builderVersion; bv != "" {
 		w.Header().Set("Builder-Version", string(bv))
 	}
 	_, err := w.Write([]byte{'O', 'K'})

+ 57 - 0
api/swagger.yaml

@@ -1513,6 +1513,31 @@ definitions:
       aux:
         $ref: "#/definitions/ImageID"
 
+  BuildCache:
+    type: "object"
+    properties:
+      ID:
+        type: "string"
+      Parent:
+        type: "string"
+      Type:
+        type: "string"
+      Description:
+        type: "string"
+      InUse:
+        type: "boolean"
+      Shared:
+        type: "boolean"
+      Size:
+        type: "integer"
+      CreatedAt:
+        type: "integer"
+      LastUsedAt:
+        type: "integer"
+        x-nullable: true
+      UsageCount:
+        type: "integer"
+
   ImageID:
     type: "object"
     description: "Image ID or Digest"
@@ -6358,6 +6383,29 @@ paths:
       produces:
         - "application/json"
       operationId: "BuildPrune"
+      parameters:
+        - name: "keep-storage"
+          in: "query"
+          description: "Amount of disk space in bytes to keep for cache"
+          type: "integer"
+          format: "int64"
+        - name: "all"
+          in: "query"
+          type: "boolean"
+          description: "Remove all types of build cache"
+        - name: "filters"
+          in: "query"
+          type: "string"
+          description: |
+            A JSON encoded value of the filters (a `map[string][]string`) to process on the list of build cache objects. Available filters:
+            - `unused-for=<duration>`: duration relative to daemon's time, during which build cache was not used, in Go's duration format (e.g., '24h')
+            - `id=<id>`
+            - `parent=<id>`
+            - `type=<string>`
+            - `description=<string>`
+            - `inuse`
+            - `shared`
+            - `private`
       responses:
         200:
           description: "No error"
@@ -6365,6 +6413,11 @@ paths:
             type: "object"
             title: "BuildPruneResponse"
             properties:
+              CachesDeleted:
+                type: "array"
+                items:
+                  description: "ID of build cache object"
+                  type: "string"
               SpaceReclaimed:
                 description: "Disk space reclaimed in bytes"
                 type: "integer"
@@ -7199,6 +7252,10 @@ paths:
                 type: "array"
                 items:
                   $ref: "#/definitions/Volume"
+              BuildCache:
+                type: "array"
+                items:
+                  $ref: "#/definitions/BuildCache"
             example:
               LayersSize: 1092588
               Images:

+ 15 - 7
api/types/types.go

@@ -543,6 +543,7 @@ type ImagesPruneReport struct {
 // BuildCachePruneReport contains the response for Engine API:
 // POST "/build/prune"
 type BuildCachePruneReport struct {
+	CachesDeleted  []string
 	SpaceReclaimed uint64
 }
 
@@ -592,14 +593,21 @@ type BuildResult struct {
 
 // BuildCache contains information about a build cache record
 type BuildCache struct {
-	ID      string
-	Mutable bool
-	InUse   bool
-	Size    int64
-
+	ID          string
+	Parent      string
+	Type        string
+	Description string
+	InUse       bool
+	Shared      bool
+	Size        int64
 	CreatedAt   time.Time
 	LastUsedAt  *time.Time
 	UsageCount  int
-	Parent      string
-	Description string
+}
+
+// BuildCachePruneOptions hold parameters to prune the build cache
+type BuildCachePruneOptions struct {
+	All         bool
+	KeepStorage int64
+	Filters     filters.Args
 }

+ 9 - 0
builder/builder-next/adapters/containerimage/pull.go

@@ -516,6 +516,15 @@ func (p *puller) Snapshot(ctx context.Context) (cache.ImmutableRef, error) {
 		return nil, err
 	}
 
+	// TODO: handle windows layers for cross platform builds
+
+	if p.src.RecordType != "" && cache.GetRecordType(ref) == "" {
+		if err := cache.SetRecordType(ref, p.src.RecordType); err != nil {
+			ref.Release(context.TODO())
+			return nil, err
+		}
+	}
+
 	return ref, nil
 }
 

+ 4 - 0
builder/builder-next/adapters/snapshot/snapshot.go

@@ -110,6 +110,10 @@ func (s *snapshotter) chainID(key string) (layer.ChainID, bool) {
 	return "", false
 }
 
+func (s *snapshotter) GetLayer(key string) (layer.Layer, error) {
+	return s.getLayer(key, true)
+}
+
 func (s *snapshotter) getLayer(key string, withCommitted bool) (layer.Layer, error) {
 	s.mu.Lock()
 	l, ok := s.refs[key]

+ 72 - 11
builder/builder-next/builder.go

@@ -29,6 +29,21 @@ import (
 	grpcmetadata "google.golang.org/grpc/metadata"
 )
 
+var errMultipleFilterValues = errors.New("filters expect only one value")
+
+var cacheFields = map[string]bool{
+	"id":          true,
+	"parent":      true,
+	"type":        true,
+	"description": true,
+	"inuse":       true,
+	"shared":      true,
+	"private":     true,
+	// fields from buildkit that are not exposed
+	"mutable":   false,
+	"immutable": false,
+}
+
 func init() {
 	llbsolver.AllowNetworkHostUnstable = true
 }
@@ -87,48 +102,94 @@ func (b *Builder) DiskUsage(ctx context.Context) ([]*types.BuildCache, error) {
 	var items []*types.BuildCache
 	for _, r := range duResp.Record {
 		items = append(items, &types.BuildCache{
-			ID:      r.ID,
-			Mutable: r.Mutable,
-			InUse:   r.InUse,
-			Size:    r.Size_,
-
+			ID:          r.ID,
+			Parent:      r.Parent,
+			Type:        r.RecordType,
+			Description: r.Description,
+			InUse:       r.InUse,
+			Shared:      r.Shared,
+			Size:        r.Size_,
 			CreatedAt:   r.CreatedAt,
 			LastUsedAt:  r.LastUsedAt,
 			UsageCount:  int(r.UsageCount),
-			Parent:      r.Parent,
-			Description: r.Description,
 		})
 	}
 	return items, nil
 }
 
 // Prune clears all reclaimable build cache
-func (b *Builder) Prune(ctx context.Context) (int64, error) {
+func (b *Builder) Prune(ctx context.Context, opts types.BuildCachePruneOptions) (int64, []string, error) {
 	ch := make(chan *controlapi.UsageRecord)
 
 	eg, ctx := errgroup.WithContext(ctx)
 
+	validFilters := make(map[string]bool, 1+len(cacheFields))
+	validFilters["unused-for"] = true
+	for k, v := range cacheFields {
+		validFilters[k] = v
+	}
+	if err := opts.Filters.Validate(validFilters); err != nil {
+		return 0, nil, err
+	}
+
+	var unusedFor time.Duration
+	unusedForValues := opts.Filters.Get("unused-for")
+
+	switch len(unusedForValues) {
+	case 0:
+
+	case 1:
+		var err error
+		unusedFor, err = time.ParseDuration(unusedForValues[0])
+		if err != nil {
+			return 0, nil, errors.Wrap(err, "unused-for filter expects a duration (e.g., '24h')")
+		}
+
+	default:
+		return 0, nil, errMultipleFilterValues
+	}
+
+	bkFilter := make([]string, 0, opts.Filters.Len())
+	for cacheField := range cacheFields {
+		values := opts.Filters.Get(cacheField)
+		switch len(values) {
+		case 0:
+			bkFilter = append(bkFilter, cacheField)
+		case 1:
+			bkFilter = append(bkFilter, cacheField+"=="+values[0])
+		default:
+			return 0, nil, errMultipleFilterValues
+		}
+	}
+
 	eg.Go(func() error {
 		defer close(ch)
-		return b.controller.Prune(&controlapi.PruneRequest{}, &pruneProxy{
+		return b.controller.Prune(&controlapi.PruneRequest{
+			All:          opts.All,
+			KeepDuration: int64(unusedFor),
+			KeepBytes:    opts.KeepStorage,
+			Filter:       bkFilter,
+		}, &pruneProxy{
 			streamProxy: streamProxy{ctx: ctx},
 			ch:          ch,
 		})
 	})
 
 	var size int64
+	var cacheIDs []string
 	eg.Go(func() error {
 		for r := range ch {
 			size += r.Size_
+			cacheIDs = append(cacheIDs, r.ID)
 		}
 		return nil
 	})
 
 	if err := eg.Wait(); err != nil {
-		return 0, err
+		return 0, nil, err
 	}
 
-	return size, nil
+	return size, cacheIDs, nil
 }
 
 // Build executes a build request

+ 14 - 2
builder/builder-next/controller.go

@@ -9,6 +9,7 @@ import (
 	"github.com/docker/docker/builder/builder-next/adapters/containerimage"
 	"github.com/docker/docker/builder/builder-next/adapters/snapshot"
 	containerimageexp "github.com/docker/docker/builder/builder-next/exporter"
+	"github.com/docker/docker/builder/builder-next/imagerefchecker"
 	mobyworker "github.com/docker/docker/builder/builder-next/worker"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/moby/buildkit/cache"
@@ -69,9 +70,20 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
 		MetadataStore: md,
 	})
 
+	layerGetter, ok := sbase.(imagerefchecker.LayerGetter)
+	if !ok {
+		return nil, errors.Errorf("snapshotter does not implement layergetter")
+	}
+
+	refChecker := imagerefchecker.New(imagerefchecker.Opt{
+		ImageStore:  dist.ImageStore,
+		LayerGetter: layerGetter,
+	})
+
 	cm, err := cache.NewManager(cache.ManagerOpt{
-		Snapshotter:   snapshotter,
-		MetadataStore: md,
+		Snapshotter:     snapshotter,
+		MetadataStore:   md,
+		PruneRefChecker: refChecker,
 	})
 	if err != nil {
 		return nil, err

+ 96 - 0
builder/builder-next/imagerefchecker/checker.go

@@ -0,0 +1,96 @@
+package imagerefchecker
+
+import (
+	"sync"
+
+	"github.com/docker/docker/image"
+	"github.com/docker/docker/layer"
+	"github.com/moby/buildkit/cache"
+)
+
+// LayerGetter abstracts away the snapshotter
+type LayerGetter interface {
+	GetLayer(string) (layer.Layer, error)
+}
+
+// Opt represents the options needed to create a refchecker
+type Opt struct {
+	LayerGetter LayerGetter
+	ImageStore  image.Store
+}
+
+// New creates new image reference checker that can be used to see if a reference
+// is being used by any of the images in the image store
+func New(opt Opt) cache.ExternalRefCheckerFunc {
+	return func() (cache.ExternalRefChecker, error) {
+		return &checker{opt: opt, layers: lchain{}, cache: map[string]bool{}}, nil
+	}
+}
+
+type lchain map[layer.DiffID]lchain
+
+func (c lchain) add(ids []layer.DiffID) {
+	if len(ids) == 0 {
+		return
+	}
+	id := ids[0]
+	ch, ok := c[id]
+	if !ok {
+		ch = lchain{}
+		c[id] = ch
+	}
+	ch.add(ids[1:])
+}
+
+func (c lchain) has(ids []layer.DiffID) bool {
+	if len(ids) == 0 {
+		return true
+	}
+	ch, ok := c[ids[0]]
+	return ok && ch.has(ids[1:])
+}
+
+type checker struct {
+	opt    Opt
+	once   sync.Once
+	layers lchain
+	cache  map[string]bool
+}
+
+func (c *checker) Exists(key string) bool {
+	if c.opt.ImageStore == nil {
+		return false
+	}
+
+	c.once.Do(c.init)
+
+	if b, ok := c.cache[key]; ok {
+		return b
+	}
+
+	l, err := c.opt.LayerGetter.GetLayer(key)
+	if err != nil || l == nil {
+		c.cache[key] = false
+		return false
+	}
+
+	ok := c.layers.has(diffIDs(l))
+	c.cache[key] = ok
+	return ok
+}
+
+func (c *checker) init() {
+	imgs := c.opt.ImageStore.Map()
+
+	for _, img := range imgs {
+		c.layers.add(img.RootFS.DiffIDs)
+	}
+}
+
+func diffIDs(l layer.Layer) []layer.DiffID {
+	p := l.Parent()
+	if p == nil {
+		return []layer.DiffID{l.DiffID()}
+	}
+	return append(diffIDs(p), l.DiffID())
+}

+ 17 - 2
client/build_prune.go

@@ -4,19 +4,34 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"net/url"
 
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/pkg/errors"
 )
 
 // BuildCachePrune requests the daemon to delete unused cache data
-func (cli *Client) BuildCachePrune(ctx context.Context) (*types.BuildCachePruneReport, error) {
+func (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {
 	if err := cli.NewVersionError("1.31", "build prune"); err != nil {
 		return nil, err
 	}
 
 	report := types.BuildCachePruneReport{}
 
-	serverResp, err := cli.post(ctx, "/build/prune", nil, nil, nil)
+	query := url.Values{}
+	if opts.All {
+		query.Set("all", "1")
+	}
+	query.Set("keep-storage", fmt.Sprintf("%d", opts.KeepStorage))
+	filters, err := filters.ToJSON(opts.Filters)
+	if err != nil {
+		return nil, errors.Wrap(err, "prune could not marshal filters option")
+	}
+	query.Set("filters", filters)
+
+	serverResp, err := cli.post(ctx, "/build/prune", query, nil, nil)
+
 	if err != nil {
 		return nil, err
 	}

+ 1 - 1
client/interface.go

@@ -86,7 +86,7 @@ type DistributionAPIClient interface {
 // ImageAPIClient defines API client methods for the images
 type ImageAPIClient interface {
 	ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
-	BuildCachePrune(ctx context.Context) (*types.BuildCachePruneReport, error)
+	BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error)
 	BuildCancel(ctx context.Context, id string) error
 	ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
 	ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error)

+ 4 - 13
cmd/dockerd/daemon.go

@@ -27,7 +27,6 @@ import (
 	swarmrouter "github.com/docker/docker/api/server/router/swarm"
 	systemrouter "github.com/docker/docker/api/server/router/system"
 	"github.com/docker/docker/api/server/router/volume"
-	"github.com/docker/docker/api/types"
 	buildkit "github.com/docker/docker/builder/builder-next"
 	"github.com/docker/docker/builder/dockerfile"
 	"github.com/docker/docker/builder/fscache"
@@ -253,8 +252,8 @@ type routerOptions struct {
 	sessionManager *session.Manager
 	buildBackend   *buildbackend.Backend
 	buildCache     *fscache.FSCache // legacy
+	features       *map[string]bool
 	buildkit       *buildkit.Builder
-	builderVersion types.BuilderVersion
 	daemon         *daemon.Daemon
 	api            *apiserver.Server
 	cluster        *cluster.Cluster
@@ -300,20 +299,12 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
 	if err != nil {
 		return opts, errors.Wrap(err, "failed to create buildmanager")
 	}
-	var bv types.BuilderVersion
-	if v, ok := config.Features["buildkit"]; ok {
-		if v {
-			bv = types.BuilderBuildKit
-		} else {
-			bv = types.BuilderV1
-		}
-	}
 	return routerOptions{
 		sessionManager: sm,
 		buildBackend:   bb,
 		buildCache:     buildCache,
 		buildkit:       bk,
-		builderVersion: bv,
+		features:       daemon.Features(),
 		daemon:         daemon,
 	}, nil
 }
@@ -487,9 +478,9 @@ func initRouter(opts routerOptions) {
 		checkpointrouter.NewRouter(opts.daemon, decoder),
 		container.NewRouter(opts.daemon, decoder),
 		image.NewRouter(opts.daemon.ImageService()),
-		systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildCache, opts.buildkit, opts.builderVersion),
+		systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildCache, opts.buildkit, opts.features),
 		volume.NewRouter(opts.daemon.VolumesService()),
-		build.NewRouter(opts.buildBackend, opts.daemon, opts.builderVersion),
+		build.NewRouter(opts.buildBackend, opts.daemon, opts.features),
 		sessionrouter.NewRouter(opts.sessionManager),
 		swarmrouter.NewRouter(opts.cluster),
 		pluginrouter.NewRouter(opts.daemon.PluginManager()),

+ 5 - 0
daemon/daemon.go

@@ -136,6 +136,11 @@ func (daemon *Daemon) HasExperimental() bool {
 	return daemon.configStore != nil && daemon.configStore.Experimental
 }
 
+// Features returns the features map from configStore
+func (daemon *Daemon) Features() *map[string]bool {
+	return &daemon.configStore.Features
+}
+
 func (daemon *Daemon) restore() error {
 	containers := make(map[string]*container.Container)
 

+ 11 - 0
daemon/reload.go

@@ -45,6 +45,7 @@ func (daemon *Daemon) Reload(conf *config.Config) (err error) {
 	daemon.reloadDebug(conf, attributes)
 	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
 	daemon.reloadShutdownTimeout(conf, attributes)
+	daemon.reloadFeatures(conf, attributes)
 
 	if err := daemon.reloadClusterDiscovery(conf, attributes); err != nil {
 		return err
@@ -322,3 +323,13 @@ func (daemon *Daemon) reloadNetworkDiagnosticPort(conf *config.Config, attribute
 
 	return nil
 }
+
+// reloadFeatures updates configuration with enabled/disabled features
+func (daemon *Daemon) reloadFeatures(conf *config.Config, attributes map[string]string) {
+	// update corresponding configuration
+	// note that we allow features option to be entirely unset
+	daemon.configStore.Features = conf.Features
+
+	// prepare reload event attributes with updatable configurations
+	attributes["features"] = fmt.Sprintf("%v", daemon.configStore.Features)
+}

+ 2 - 1
integration/build/build_session_test.go

@@ -7,6 +7,7 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/docker/docker/api/types"
 	dclient "github.com/docker/docker/client"
 	"github.com/docker/docker/internal/test/fakecontext"
 	"github.com/docker/docker/internal/test/request"
@@ -76,7 +77,7 @@ func TestBuildWithSession(t *testing.T) {
 	assert.Check(t, is.Contains(string(outBytes), "Successfully built"))
 	assert.Check(t, is.Equal(strings.Count(string(outBytes), "Using cache"), 4))
 
-	_, err = client.BuildCachePrune(context.TODO())
+	_, err = client.BuildCachePrune(context.TODO(), types.BuildCachePruneOptions{All: true})
 	assert.Check(t, err)
 
 	du, err = client.DiskUsage(context.TODO())

+ 6 - 6
vendor.conf

@@ -1,7 +1,7 @@
 # the following lines are in sorted order, FYI
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
-github.com/Microsoft/hcsshim v0.6.12
-github.com/Microsoft/go-winio v0.4.9
+github.com/Microsoft/hcsshim 44c060121b68e8bdc40b411beba551f3b4ee9e55
+github.com/Microsoft/go-winio v0.4.10
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
 github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a
@@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.6
 golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
 
 # buildkit
-github.com/moby/buildkit e1cd06ad6b74e4b747306c4408c451b3b6d87a89
+github.com/moby/buildkit 6812dac65e0440bb75affce1fb2175e640edc15d
 github.com/tonistiigi/fsutil b19464cd1b6a00773b4f2eb7acf9c30426f9df42
 github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
@@ -75,7 +75,7 @@ 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 ad0f5255060d36872be04de22f8731f38ef2d7b1
+github.com/opencontainers/runc 20aff4f0488c6d4b8df4d85b4f63f1f704c11abd
 github.com/opencontainers/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce # v1.0.1-43-gd810dbc
 github.com/opencontainers/image-spec v1.0.1
 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
@@ -114,11 +114,11 @@ github.com/googleapis/gax-go v2.0.0
 google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
 
 # containerd
-github.com/containerd/containerd v1.2.0-beta.0
+github.com/containerd/containerd v1.2.0-beta.2
 github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
 github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
-github.com/containerd/console 4d8a41f4ce5b9bae77c41786ea2458330f43f081
+github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
 github.com/containerd/go-runc edcf3de1f4971445c42d61f20d506b30612aa031
 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 github.com/containerd/ttrpc 94dde388801693c54f88a6596f713b51a8b30b2d

+ 1 - 1
vendor/github.com/Microsoft/go-winio/backuptar/tar.go

@@ -303,7 +303,7 @@ func FileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *win
 		if err != nil {
 			return "", 0, nil, err
 		}
-		fileInfo.FileAttributes = uintptr(attr)
+		fileInfo.FileAttributes = uint32(attr)
 	} else {
 		if hdr.Typeflag == tar.TypeDir {
 			fileInfo.FileAttributes |= syscall.FILE_ATTRIBUTE_DIRECTORY

+ 2 - 1
vendor/github.com/Microsoft/go-winio/fileinfo.go

@@ -20,7 +20,8 @@ const (
 // FileBasicInfo contains file access time and file attributes information.
 type FileBasicInfo struct {
 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
-	FileAttributes                                          uintptr // includes padding
+	FileAttributes                                          uint32
+	pad                                                     uint32 // padding
 }
 
 // GetFileBasicInfo retrieves times and attributes for a file.

+ 13 - 5
vendor/github.com/Microsoft/hcsshim/README.md

@@ -1,12 +1,13 @@
 # hcsshim
 
-This package supports launching Windows Server containers from Go. It is
-primarily used in the [Docker Engine](https://github.com/docker/docker) project,
-but it can be freely used by other projects as well.
+[![Build status](https://ci.appveyor.com/api/projects/status/nbcw28mnkqml0loa/branch/master?svg=true)](https://ci.appveyor.com/project/WindowsVirtualization/hcsshim/branch/master)
 
+This package contains the Golang interface for using the Windows [Host Compute Service](https://blogs.technet.microsoft.com/virtualization/2017/01/27/introducing-the-host-compute-service-hcs/) (HCS) to launch and manage [Windows Containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/). It also contains other helpers and functions for managing Windows Containers such as the Golang interface for the Host Network Service (HNS).
+
+It is primarily used in the [Moby Project](https://github.com/moby/moby), but it can be freely used by other projects as well.
 
 ## Contributing
----------------
+
 This project welcomes contributions and suggestions.  Most contributions require you to agree to a
 Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
 the rights to use your contribution. For details, visit https://cla.microsoft.com.
@@ -19,6 +20,11 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
 For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
 contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
 
+## Dependencies
+
+This project requires Golang 1.9 or newer to build.
+
+For system requirements to run this project, see the Microsoft docs on [Windows Container requirements](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/system-requirements).
 
 ## Reporting Security Issues
 
@@ -29,5 +35,7 @@ email to ensure we received your original message. Further information, includin
 [MSRC PGP](https://technet.microsoft.com/en-us/security/dn606155) key, can be found in
 the [Security TechCenter](https://technet.microsoft.com/en-us/security/default).
 
--------------------------------------------
+For additional details, see [Report a Computer Security Vulnerability](https://technet.microsoft.com/en-us/security/ff852094.aspx) on Technet
+
+---------------
 Copyright (c) 2018 Microsoft Corp.  All rights reserved.

+ 0 - 28
vendor/github.com/Microsoft/hcsshim/activatelayer.go

@@ -1,28 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// ActivateLayer will find the layer with the given id and mount it's filesystem.
-// For a read/write layer, the mounted filesystem will appear as a volume on the
-// host, while a read-only layer is generally expected to be a no-op.
-// An activated layer must later be deactivated via DeactivateLayer.
-func ActivateLayer(info DriverInfo, id string) error {
-	title := "hcsshim::ActivateLayer "
-	logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
-
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = activateLayer(&infop, id)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+" - succeeded id=%s flavour=%d", id, info.Flavour)
-	return nil
-}

+ 70 - 678
vendor/github.com/Microsoft/hcsshim/container.go

@@ -1,800 +1,192 @@
 package hcsshim
 
 import (
-	"encoding/json"
 	"fmt"
 	"os"
-	"sync"
-	"syscall"
 	"time"
 
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hcs"
+	"github.com/Microsoft/hcsshim/internal/mergemaps"
+	"github.com/Microsoft/hcsshim/internal/schema1"
 )
 
-var (
-	defaultTimeout = time.Minute * 4
-)
-
-const (
-	pendingUpdatesQuery    = `{ "PropertyTypes" : ["PendingUpdates"]}`
-	statisticsQuery        = `{ "PropertyTypes" : ["Statistics"]}`
-	processListQuery       = `{ "PropertyTypes" : ["ProcessList"]}`
-	mappedVirtualDiskQuery = `{ "PropertyTypes" : ["MappedVirtualDisk"]}`
-)
-
-type container struct {
-	handleLock     sync.RWMutex
-	handle         hcsSystem
-	id             string
-	callbackNumber uintptr
-}
-
 // ContainerProperties holds the properties for a container and the processes running in that container
-type ContainerProperties struct {
-	ID                           string `json:"Id"`
-	Name                         string
-	SystemType                   string
-	Owner                        string
-	SiloGUID                     string                              `json:"SiloGuid,omitempty"`
-	RuntimeID                    string                              `json:"RuntimeId,omitempty"`
-	IsRuntimeTemplate            bool                                `json:",omitempty"`
-	RuntimeImagePath             string                              `json:",omitempty"`
-	Stopped                      bool                                `json:",omitempty"`
-	ExitType                     string                              `json:",omitempty"`
-	AreUpdatesPending            bool                                `json:",omitempty"`
-	ObRoot                       string                              `json:",omitempty"`
-	Statistics                   Statistics                          `json:",omitempty"`
-	ProcessList                  []ProcessListItem                   `json:",omitempty"`
-	MappedVirtualDiskControllers map[int]MappedVirtualDiskController `json:",omitempty"`
-}
+type ContainerProperties = schema1.ContainerProperties
 
 // MemoryStats holds the memory statistics for a container
-type MemoryStats struct {
-	UsageCommitBytes            uint64 `json:"MemoryUsageCommitBytes,omitempty"`
-	UsageCommitPeakBytes        uint64 `json:"MemoryUsageCommitPeakBytes,omitempty"`
-	UsagePrivateWorkingSetBytes uint64 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
-}
+type MemoryStats = schema1.MemoryStats
 
 // ProcessorStats holds the processor statistics for a container
-type ProcessorStats struct {
-	TotalRuntime100ns  uint64 `json:",omitempty"`
-	RuntimeUser100ns   uint64 `json:",omitempty"`
-	RuntimeKernel100ns uint64 `json:",omitempty"`
-}
+type ProcessorStats = schema1.ProcessorStats
 
 // StorageStats holds the storage statistics for a container
-type StorageStats struct {
-	ReadCountNormalized  uint64 `json:",omitempty"`
-	ReadSizeBytes        uint64 `json:",omitempty"`
-	WriteCountNormalized uint64 `json:",omitempty"`
-	WriteSizeBytes       uint64 `json:",omitempty"`
-}
+type StorageStats = schema1.StorageStats
 
 // NetworkStats holds the network statistics for a container
-type NetworkStats struct {
-	BytesReceived          uint64 `json:",omitempty"`
-	BytesSent              uint64 `json:",omitempty"`
-	PacketsReceived        uint64 `json:",omitempty"`
-	PacketsSent            uint64 `json:",omitempty"`
-	DroppedPacketsIncoming uint64 `json:",omitempty"`
-	DroppedPacketsOutgoing uint64 `json:",omitempty"`
-	EndpointId             string `json:",omitempty"`
-	InstanceId             string `json:",omitempty"`
-}
+type NetworkStats = schema1.NetworkStats
 
 // Statistics is the structure returned by a statistics call on a container
-type Statistics struct {
-	Timestamp          time.Time      `json:",omitempty"`
-	ContainerStartTime time.Time      `json:",omitempty"`
-	Uptime100ns        uint64         `json:",omitempty"`
-	Memory             MemoryStats    `json:",omitempty"`
-	Processor          ProcessorStats `json:",omitempty"`
-	Storage            StorageStats   `json:",omitempty"`
-	Network            []NetworkStats `json:",omitempty"`
-}
+type Statistics = schema1.Statistics
 
 // ProcessList is the structure of an item returned by a ProcessList call on a container
-type ProcessListItem struct {
-	CreateTimestamp              time.Time `json:",omitempty"`
-	ImageName                    string    `json:",omitempty"`
-	KernelTime100ns              uint64    `json:",omitempty"`
-	MemoryCommitBytes            uint64    `json:",omitempty"`
-	MemoryWorkingSetPrivateBytes uint64    `json:",omitempty"`
-	MemoryWorkingSetSharedBytes  uint64    `json:",omitempty"`
-	ProcessId                    uint32    `json:",omitempty"`
-	UserTime100ns                uint64    `json:",omitempty"`
-}
+type ProcessListItem = schema1.ProcessListItem
 
 // MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
-type MappedVirtualDiskController struct {
-	MappedVirtualDisks map[int]MappedVirtualDisk `json:",omitempty"`
-}
+type MappedVirtualDiskController = schema1.MappedVirtualDiskController
 
 // Type of Request Support in ModifySystem
-type RequestType string
+type RequestType = schema1.RequestType
 
 // Type of Resource Support in ModifySystem
-type ResourceType string
+type ResourceType = schema1.ResourceType
 
 // RequestType const
 const (
-	Add     RequestType  = "Add"
-	Remove  RequestType  = "Remove"
-	Network ResourceType = "Network"
+	Add     = schema1.Add
+	Remove  = schema1.Remove
+	Network = schema1.Network
 )
 
 // ResourceModificationRequestResponse is the structure used to send request to the container to modify the system
 // Supported resource types are Network and Request Types are Add/Remove
-type ResourceModificationRequestResponse struct {
-	Resource ResourceType `json:"ResourceType"`
-	Data     interface{}  `json:"Settings"`
-	Request  RequestType  `json:"RequestType,omitempty"`
+type ResourceModificationRequestResponse = schema1.ResourceModificationRequestResponse
+
+type container struct {
+	system *hcs.System
 }
 
-// createContainerAdditionalJSON is read from the environment at initialisation
+// createComputeSystemAdditionalJSON is read from the environment at initialisation
 // time. It allows an environment variable to define additional JSON which
-// is merged in the CreateContainer call to HCS.
-var createContainerAdditionalJSON string
+// is merged in the CreateComputeSystem call to HCS.
+var createContainerAdditionalJSON []byte
 
 func init() {
-	createContainerAdditionalJSON = os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON")
+	createContainerAdditionalJSON = ([]byte)(os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON"))
 }
 
 // CreateContainer creates a new container with the given configuration but does not start it.
 func CreateContainer(id string, c *ContainerConfig) (Container, error) {
-	return createContainerWithJSON(id, c, "")
-}
-
-// CreateContainerWithJSON creates a new container with the given configuration but does not start it.
-// It is identical to CreateContainer except that optional additional JSON can be merged before passing to HCS.
-func CreateContainerWithJSON(id string, c *ContainerConfig, additionalJSON string) (Container, error) {
-	return createContainerWithJSON(id, c, additionalJSON)
-}
-
-func createContainerWithJSON(id string, c *ContainerConfig, additionalJSON string) (Container, error) {
-	operation := "CreateContainer"
-	title := "HCSShim::" + operation
-
-	container := &container{
-		id: id,
-	}
-
-	configurationb, err := json.Marshal(c)
+	fullConfig, err := mergemaps.MergeJSON(c, createContainerAdditionalJSON)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to merge additional JSON '%s': %s", createContainerAdditionalJSON, err)
 	}
 
-	configuration := string(configurationb)
-	logrus.Debugf(title+" id=%s config=%s", id, configuration)
-
-	// Merge any additional JSON. Priority is given to what is passed in explicitly,
-	// falling back to what's set in the environment.
-	if additionalJSON == "" && createContainerAdditionalJSON != "" {
-		additionalJSON = createContainerAdditionalJSON
-	}
-	if additionalJSON != "" {
-		configurationMap := map[string]interface{}{}
-		if err := json.Unmarshal([]byte(configuration), &configurationMap); err != nil {
-			return nil, fmt.Errorf("failed to unmarshal %s: %s", configuration, err)
-		}
-
-		additionalMap := map[string]interface{}{}
-		if err := json.Unmarshal([]byte(additionalJSON), &additionalMap); err != nil {
-			return nil, fmt.Errorf("failed to unmarshal %s: %s", additionalJSON, err)
-		}
-
-		mergedMap := mergeMaps(additionalMap, configurationMap)
-		mergedJSON, err := json.Marshal(mergedMap)
-		if err != nil {
-			return nil, fmt.Errorf("failed to marshal merged configuration map %+v: %s", mergedMap, err)
-		}
-
-		configuration = string(mergedJSON)
-		logrus.Debugf(title+" id=%s merged config=%s", id, configuration)
-	}
-
-	var (
-		resultp  *uint16
-		identity syscall.Handle
-	)
-	createError := hcsCreateComputeSystem(id, configuration, identity, &container.handle, &resultp)
-
-	if createError == nil || IsPending(createError) {
-		if err := container.registerCallback(); err != nil {
-			// Terminate the container if it still exists. We're okay to ignore a failure here.
-			container.Terminate()
-			return nil, makeContainerError(container, operation, "", err)
-		}
-	}
-
-	err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
+	system, err := hcs.CreateComputeSystem(id, fullConfig)
 	if err != nil {
-		if err == ErrTimeout {
-			// Terminate the container if it still exists. We're okay to ignore a failure here.
-			container.Terminate()
-		}
-		return nil, makeContainerError(container, operation, configuration, err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s handle=%d", id, container.handle)
-	return container, nil
-}
-
-// mergeMaps recursively merges map `fromMap` into map `ToMap`. Any pre-existing values
-// in ToMap are overwritten. Values in fromMap are added to ToMap.
-// From http://stackoverflow.com/questions/40491438/merging-two-json-strings-in-golang
-func mergeMaps(fromMap, ToMap interface{}) interface{} {
-	switch fromMap := fromMap.(type) {
-	case map[string]interface{}:
-		ToMap, ok := ToMap.(map[string]interface{})
-		if !ok {
-			return fromMap
-		}
-		for keyToMap, valueToMap := range ToMap {
-			if valueFromMap, ok := fromMap[keyToMap]; ok {
-				fromMap[keyToMap] = mergeMaps(valueFromMap, valueToMap)
-			} else {
-				fromMap[keyToMap] = valueToMap
-			}
-		}
-	case nil:
-		// merge(nil, map[string]interface{...}) -> map[string]interface{...}
-		ToMap, ok := ToMap.(map[string]interface{})
-		if ok {
-			return ToMap
-		}
+		return nil, err
 	}
-	return fromMap
+	return &container{system}, err
 }
 
 // OpenContainer opens an existing container by ID.
 func OpenContainer(id string) (Container, error) {
-	operation := "OpenContainer"
-	title := "HCSShim::" + operation
-	logrus.Debugf(title+" id=%s", id)
-
-	container := &container{
-		id: id,
-	}
-
-	var (
-		handle  hcsSystem
-		resultp *uint16
-	)
-	err := hcsOpenComputeSystem(id, &handle, &resultp)
-	err = processHcsResult(err, resultp)
+	system, err := hcs.OpenComputeSystem(id)
 	if err != nil {
-		return nil, makeContainerError(container, operation, "", err)
-	}
-
-	container.handle = handle
-
-	if err := container.registerCallback(); err != nil {
-		return nil, makeContainerError(container, operation, "", err)
+		return nil, err
 	}
-
-	logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
-	return container, nil
+	return &container{system}, err
 }
 
 // GetContainers gets a list of the containers on the system that match the query
 func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) {
-	operation := "GetContainers"
-	title := "HCSShim::" + operation
-
-	queryb, err := json.Marshal(q)
-	if err != nil {
-		return nil, err
-	}
-
-	query := string(queryb)
-	logrus.Debugf(title+" query=%s", query)
-
-	var (
-		resultp         *uint16
-		computeSystemsp *uint16
-	)
-	err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return nil, err
-	}
-
-	if computeSystemsp == nil {
-		return nil, ErrUnexpectedValue
-	}
-	computeSystemsRaw := convertAndFreeCoTaskMemBytes(computeSystemsp)
-	computeSystems := []ContainerProperties{}
-	if err := json.Unmarshal(computeSystemsRaw, &computeSystems); err != nil {
-		return nil, err
-	}
-
-	logrus.Debugf(title + " succeeded")
-	return computeSystems, nil
+	return hcs.GetComputeSystems(q)
 }
 
 // Start synchronously starts the container.
 func (container *container) Start() error {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Start"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	var resultp *uint16
-	err := hcsStartComputeSystem(container.handle, "", &resultp)
-	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
+	return convertSystemError(container.system.Start(), container)
 }
 
-// Shutdown requests a container shutdown, if IsPending() on the error returned is true,
-// it may not actually be shut down until Wait() succeeds.
+// Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds.
 func (container *container) Shutdown() error {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Shutdown"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	var resultp *uint16
-	err := hcsShutdownComputeSystem(container.handle, "", &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
+	return convertSystemError(container.system.Shutdown(), container)
 }
 
-// Terminate requests a container terminate, if IsPending() on the error returned is true,
-// it may not actually be shut down until Wait() succeeds.
+// Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds.
 func (container *container) Terminate() error {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Terminate"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	var resultp *uint16
-	err := hcsTerminateComputeSystem(container.handle, "", &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
+	return convertSystemError(container.system.Terminate(), container)
 }
 
-// Wait synchronously waits for the container to shutdown or terminate.
+// Waits synchronously waits for the container to shutdown or terminate.
 func (container *container) Wait() error {
-	operation := "Wait"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, nil)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
+	return convertSystemError(container.system.Wait(), container)
 }
 
-// WaitTimeout synchronously waits for the container to terminate or the duration to elapse.
-// If the timeout expires, IsTimeout(err) == true
-func (container *container) WaitTimeout(timeout time.Duration) error {
-	operation := "WaitTimeout"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, &timeout)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
+// WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It
+// returns false if timeout occurs.
+func (container *container) WaitTimeout(t time.Duration) error {
+	return convertSystemError(container.system.WaitTimeout(t), container)
 }
 
-func (container *container) properties(query string) (*ContainerProperties, error) {
-	var (
-		resultp     *uint16
-		propertiesp *uint16
-	)
-	err := hcsGetComputeSystemProperties(container.handle, query, &propertiesp, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return nil, err
-	}
+// Pause pauses the execution of a container.
+func (container *container) Pause() error {
+	return convertSystemError(container.system.Pause(), container)
+}
 
-	if propertiesp == nil {
-		return nil, ErrUnexpectedValue
-	}
-	propertiesRaw := convertAndFreeCoTaskMemBytes(propertiesp)
-	properties := &ContainerProperties{}
-	if err := json.Unmarshal(propertiesRaw, properties); err != nil {
-		return nil, err
-	}
-	return properties, nil
+// Resume resumes the execution of a container.
+func (container *container) Resume() error {
+	return convertSystemError(container.system.Resume(), container)
 }
 
 // HasPendingUpdates returns true if the container has updates pending to install
 func (container *container) HasPendingUpdates() (bool, error) {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "HasPendingUpdates"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return false, makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	properties, err := container.properties(pendingUpdatesQuery)
-	if err != nil {
-		return false, makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return properties.AreUpdatesPending, nil
+	return false, nil
 }
 
-// Statistics returns statistics for the container
+// Statistics returns statistics for the container. This is a legacy v1 call
 func (container *container) Statistics() (Statistics, error) {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Statistics"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return Statistics{}, makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	properties, err := container.properties(statisticsQuery)
+	properties, err := container.system.Properties(schema1.PropertyTypeStatistics)
 	if err != nil {
-		return Statistics{}, makeContainerError(container, operation, "", err)
+		return Statistics{}, convertSystemError(err, container)
 	}
 
-	logrus.Debugf(title+" succeeded id=%s", container.id)
 	return properties.Statistics, nil
 }
 
-// ProcessList returns an array of ProcessListItems for the container
+// ProcessList returns an array of ProcessListItems for the container. This is a legacy v1 call
 func (container *container) ProcessList() ([]ProcessListItem, error) {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "ProcessList"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	properties, err := container.properties(processListQuery)
+	properties, err := container.system.Properties(schema1.PropertyTypeProcessList)
 	if err != nil {
-		return nil, makeContainerError(container, operation, "", err)
+		return nil, convertSystemError(err, container)
 	}
 
-	logrus.Debugf(title+" succeeded id=%s", container.id)
 	return properties.ProcessList, nil
 }
 
-// MappedVirtualDisks returns a map of the controllers and the disks mapped
-// to a container.
-//
-// Example of JSON returned by the query.
-//{
-//   "Id":"1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3_svm",
-//   "SystemType":"Container",
-//   "RuntimeOsType":"Linux",
-//   "RuntimeId":"00000000-0000-0000-0000-000000000000",
-//   "State":"Running",
-//   "MappedVirtualDiskControllers":{
-//      "0":{
-//         "MappedVirtualDisks":{
-//            "2":{
-//               "HostPath":"C:\\lcow\\lcow\\scratch\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3.vhdx",
-//               "ContainerPath":"/mnt/gcs/LinuxServiceVM/scratch",
-//               "Lun":2,
-//               "CreateInUtilityVM":true
-//            },
-//            "3":{
-//               "HostPath":"C:\\lcow\\lcow\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3\\sandbox.vhdx",
-//               "Lun":3,
-//               "CreateInUtilityVM":true,
-//               "AttachOnly":true
-//            }
-//         }
-//      }
-//   }
-//}
+// This is a legacy v1 call
 func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "MappedVirtualDiskList"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	properties, err := container.properties(mappedVirtualDiskQuery)
+	properties, err := container.system.Properties(schema1.PropertyTypeMappedVirtualDisk)
 	if err != nil {
-		return nil, makeContainerError(container, operation, "", err)
+		return nil, convertSystemError(err, container)
 	}
 
-	logrus.Debugf(title+" succeeded id=%s", container.id)
 	return properties.MappedVirtualDiskControllers, nil
 }
 
-// Pause pauses the execution of the container. This feature is not enabled in TP5.
-func (container *container) Pause() error {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Pause"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	var resultp *uint16
-	err := hcsPauseComputeSystem(container.handle, "", &resultp)
-	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemPauseCompleted, &defaultTimeout)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
-}
-
-// Resume resumes the execution of the container. This feature is not enabled in TP5.
-func (container *container) Resume() error {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Resume"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	if container.handle == 0 {
-		return makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	var resultp *uint16
-	err := hcsResumeComputeSystem(container.handle, "", &resultp)
-	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemResumeCompleted, &defaultTimeout)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
-}
-
 // CreateProcess launches a new process within the container.
 func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "CreateProcess"
-	title := "HCSShim::Container::" + operation
-	var (
-		processInfo   hcsProcessInformation
-		processHandle hcsProcess
-		resultp       *uint16
-	)
-
-	if container.handle == 0 {
-		return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	// If we are not emulating a console, ignore any console size passed to us
-	if !c.EmulateConsole {
-		c.ConsoleSize[0] = 0
-		c.ConsoleSize[1] = 0
-	}
-
-	configurationb, err := json.Marshal(c)
+	p, err := container.system.CreateProcess(c)
 	if err != nil {
-		return nil, makeContainerError(container, operation, "", err)
+		return nil, convertSystemError(err, container)
 	}
-
-	configuration := string(configurationb)
-	logrus.Debugf(title+" id=%s config=%s", container.id, configuration)
-
-	err = hcsCreateProcess(container.handle, configuration, &processInfo, &processHandle, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return nil, makeContainerError(container, operation, configuration, err)
-	}
-
-	process := &process{
-		handle:    processHandle,
-		processID: int(processInfo.ProcessId),
-		container: container,
-		cachedPipes: &cachedPipes{
-			stdIn:  processInfo.StdInput,
-			stdOut: processInfo.StdOutput,
-			stdErr: processInfo.StdError,
-		},
-	}
-
-	if err := process.registerCallback(); err != nil {
-		return nil, makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s processid=%d", container.id, process.processID)
-	return process, nil
+	return &process{p}, nil
 }
 
 // OpenProcess gets an interface to an existing process within the container.
 func (container *container) OpenProcess(pid int) (Process, error) {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "OpenProcess"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s, processid=%d", container.id, pid)
-	var (
-		processHandle hcsProcess
-		resultp       *uint16
-	)
-
-	if container.handle == 0 {
-		return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	err := hcsOpenProcess(container.handle, uint32(pid), &processHandle, &resultp)
-	err = processHcsResult(err, resultp)
+	p, err := container.system.OpenProcess(pid)
 	if err != nil {
-		return nil, makeContainerError(container, operation, "", err)
+		return nil, convertSystemError(err, container)
 	}
-
-	process := &process{
-		handle:    processHandle,
-		processID: pid,
-		container: container,
-	}
-
-	if err := process.registerCallback(); err != nil {
-		return nil, makeContainerError(container, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
-	return process, nil
+	return &process{p}, nil
 }
 
 // Close cleans up any state associated with the container but does not terminate or wait for it.
 func (container *container) Close() error {
-	container.handleLock.Lock()
-	defer container.handleLock.Unlock()
-	operation := "Close"
-	title := "HCSShim::Container::" + operation
-	logrus.Debugf(title+" id=%s", container.id)
-
-	// Don't double free this
-	if container.handle == 0 {
-		return nil
-	}
-
-	if err := container.unregisterCallback(); err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	if err := hcsCloseComputeSystem(container.handle); err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-
-	container.handle = 0
-
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
-}
-
-func (container *container) registerCallback() error {
-	context := &notifcationWatcherContext{
-		channels: newChannels(),
-	}
-
-	callbackMapLock.Lock()
-	callbackNumber := nextCallback
-	nextCallback++
-	callbackMap[callbackNumber] = context
-	callbackMapLock.Unlock()
-
-	var callbackHandle hcsCallback
-	err := hcsRegisterComputeSystemCallback(container.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
-	if err != nil {
-		return err
-	}
-	context.handle = callbackHandle
-	container.callbackNumber = callbackNumber
-
-	return nil
-}
-
-func (container *container) unregisterCallback() error {
-	callbackNumber := container.callbackNumber
-
-	callbackMapLock.RLock()
-	context := callbackMap[callbackNumber]
-	callbackMapLock.RUnlock()
-
-	if context == nil {
-		return nil
-	}
-
-	handle := context.handle
-
-	if handle == 0 {
-		return nil
-	}
-
-	// hcsUnregisterComputeSystemCallback has its own syncronization
-	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
-	err := hcsUnregisterComputeSystemCallback(handle)
-	if err != nil {
-		return err
-	}
-
-	closeChannels(context.channels)
-
-	callbackMapLock.Lock()
-	callbackMap[callbackNumber] = nil
-	callbackMapLock.Unlock()
-
-	handle = 0
-
-	return nil
+	return convertSystemError(container.system.Close(), container)
 }
 
-// Modifies the System by sending a request to HCS
+// Modify the System
 func (container *container) Modify(config *ResourceModificationRequestResponse) error {
-	container.handleLock.RLock()
-	defer container.handleLock.RUnlock()
-	operation := "Modify"
-	title := "HCSShim::Container::" + operation
-
-	if container.handle == 0 {
-		return makeContainerError(container, operation, "", ErrAlreadyClosed)
-	}
-
-	requestJSON, err := json.Marshal(config)
-	if err != nil {
-		return err
-	}
-
-	requestString := string(requestJSON)
-	logrus.Debugf(title+" id=%s request=%s", container.id, requestString)
-
-	var resultp *uint16
-	err = hcsModifyComputeSystem(container.handle, requestString, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return makeContainerError(container, operation, "", err)
-	}
-	logrus.Debugf(title+" succeeded id=%s", container.id)
-	return nil
+	return convertSystemError(container.system.Modify(config), container)
 }

+ 0 - 27
vendor/github.com/Microsoft/hcsshim/createlayer.go

@@ -1,27 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// CreateLayer creates a new, empty, read-only layer on the filesystem based on
-// the parent layer provided.
-func CreateLayer(info DriverInfo, id, parent string) error {
-	title := "hcsshim::CreateLayer "
-	logrus.Debugf(title+"Flavour %d ID %s parent %s", info.Flavour, id, parent)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = createLayer(&infop, id, parent)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s parent=%s flavour=%d", id, parent, info.Flavour)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+" - succeeded id=%s parent=%s flavour=%d", id, parent, info.Flavour)
-	return nil
-}

+ 0 - 35
vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go

@@ -1,35 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// CreateSandboxLayer creates and populates new read-write layer for use by a container.
-// This requires both the id of the direct parent layer, as well as the full list
-// of paths to all parent layers up to the base (and including the direct parent
-// whose id was provided).
-func CreateSandboxLayer(info DriverInfo, layerId, parentId string, parentLayerPaths []string) error {
-	title := "hcsshim::CreateSandboxLayer "
-	logrus.Debugf(title+"layerId %s parentId %s", layerId, parentId)
-
-	// Generate layer descriptors
-	layers, err := layerPathsToDescriptors(parentLayerPaths)
-	if err != nil {
-		return err
-	}
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = createSandboxLayer(&infop, layerId, parentId, layers)
-	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s parentId=%s", layerId, parentId)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"- succeeded layerId=%s parentId=%s", layerId, parentId)
-	return nil
-}

+ 0 - 26
vendor/github.com/Microsoft/hcsshim/deactivatelayer.go

@@ -1,26 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
-func DeactivateLayer(info DriverInfo, id string) error {
-	title := "hcsshim::DeactivateLayer "
-	logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = deactivateLayer(&infop, id)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"succeeded flavour=%d id=%s", info.Flavour, id)
-	return nil
-}

+ 0 - 27
vendor/github.com/Microsoft/hcsshim/destroylayer.go

@@ -1,27 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// DestroyLayer will remove the on-disk files representing the layer with the given
-// id, including that layer's containing folder, if any.
-func DestroyLayer(info DriverInfo, id string) error {
-	title := "hcsshim::DestroyLayer "
-	logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = destroyLayer(&infop, id)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"succeeded flavour=%d id=%s", info.Flavour, id)
-	return nil
-}

+ 62 - 66
vendor/github.com/Microsoft/hcsshim/errors.go

@@ -1,92 +1,83 @@
 package hcsshim
 
 import (
-	"errors"
 	"fmt"
 	"syscall"
+
+	"github.com/Microsoft/hcsshim/internal/hns"
+
+	"github.com/Microsoft/hcsshim/internal/hcs"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 )
 
 var (
-	// ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists
-	ErrComputeSystemDoesNotExist = syscall.Errno(0xc037010e)
+	// ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists = hcs.exist
+	ErrComputeSystemDoesNotExist = hcs.ErrComputeSystemDoesNotExist
 
 	// ErrElementNotFound is an error encountered when the object being referenced does not exist
-	ErrElementNotFound = syscall.Errno(0x490)
+	ErrElementNotFound = hcs.ErrElementNotFound
 
 	// ErrElementNotFound is an error encountered when the object being referenced does not exist
-	ErrNotSupported = syscall.Errno(0x32)
+	ErrNotSupported = hcs.ErrNotSupported
 
 	// ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
 	// decimal -2147024883 / hex 0x8007000d
-	ErrInvalidData = syscall.Errno(0xd)
+	ErrInvalidData = hcs.ErrInvalidData
 
 	// ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
-	ErrHandleClose = errors.New("hcsshim: the handle generating this notification has been closed")
+	ErrHandleClose = hcs.ErrHandleClose
 
 	// ErrAlreadyClosed is an error encountered when using a handle that has been closed by the Close method
-	ErrAlreadyClosed = errors.New("hcsshim: the handle has already been closed")
+	ErrAlreadyClosed = hcs.ErrAlreadyClosed
 
 	// ErrInvalidNotificationType is an error encountered when an invalid notification type is used
-	ErrInvalidNotificationType = errors.New("hcsshim: invalid notification type")
+	ErrInvalidNotificationType = hcs.ErrInvalidNotificationType
 
 	// ErrInvalidProcessState is an error encountered when the process is not in a valid state for the requested operation
-	ErrInvalidProcessState = errors.New("the process is in an invalid state for the attempted operation")
+	ErrInvalidProcessState = hcs.ErrInvalidProcessState
 
 	// ErrTimeout is an error encountered when waiting on a notification times out
-	ErrTimeout = errors.New("hcsshim: timeout waiting for notification")
+	ErrTimeout = hcs.ErrTimeout
 
 	// ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
 	// a different expected notification
-	ErrUnexpectedContainerExit = errors.New("unexpected container exit")
+	ErrUnexpectedContainerExit = hcs.ErrUnexpectedContainerExit
 
 	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
 	// is lost while waiting for a notification
-	ErrUnexpectedProcessAbort = errors.New("lost communication with compute service")
+	ErrUnexpectedProcessAbort = hcs.ErrUnexpectedProcessAbort
 
 	// ErrUnexpectedValue is an error encountered when hcs returns an invalid value
-	ErrUnexpectedValue = errors.New("unexpected value returned from hcs")
+	ErrUnexpectedValue = hcs.ErrUnexpectedValue
 
 	// ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
-	ErrVmcomputeAlreadyStopped = syscall.Errno(0xc0370110)
+	ErrVmcomputeAlreadyStopped = hcs.ErrVmcomputeAlreadyStopped
 
 	// ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
-	ErrVmcomputeOperationPending = syscall.Errno(0xC0370103)
+	ErrVmcomputeOperationPending = hcs.ErrVmcomputeOperationPending
 
 	// ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation
-	ErrVmcomputeOperationInvalidState = syscall.Errno(0xc0370105)
+	ErrVmcomputeOperationInvalidState = hcs.ErrVmcomputeOperationInvalidState
 
 	// ErrProcNotFound is an error encountered when the the process cannot be found
-	ErrProcNotFound = syscall.Errno(0x7f)
+	ErrProcNotFound = hcs.ErrProcNotFound
 
 	// ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
 	// builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
-	ErrVmcomputeOperationAccessIsDenied = syscall.Errno(0x5)
+	ErrVmcomputeOperationAccessIsDenied = hcs.ErrVmcomputeOperationAccessIsDenied
 
 	// ErrVmcomputeInvalidJSON is an error encountered when the compute system does not support/understand the messages sent by management
-	ErrVmcomputeInvalidJSON = syscall.Errno(0xc037010d)
+	ErrVmcomputeInvalidJSON = hcs.ErrVmcomputeInvalidJSON
 
 	// ErrVmcomputeUnknownMessage is an error encountered guest compute system doesn't support the message
-	ErrVmcomputeUnknownMessage = syscall.Errno(0xc037010b)
+	ErrVmcomputeUnknownMessage = hcs.ErrVmcomputeUnknownMessage
 
 	// ErrNotSupported is an error encountered when hcs doesn't support the request
-	ErrPlatformNotSupported = errors.New("unsupported platform request")
+	ErrPlatformNotSupported = hcs.ErrPlatformNotSupported
 )
 
-type EndpointNotFoundError struct {
-	EndpointName string
-}
-
-func (e EndpointNotFoundError) Error() string {
-	return fmt.Sprintf("Endpoint %s not found", e.EndpointName)
-}
-
-type NetworkNotFoundError struct {
-	NetworkName string
-}
-
-func (e NetworkNotFoundError) Error() string {
-	return fmt.Sprintf("Network %s not found", e.NetworkName)
-}
+type EndpointNotFoundError = hns.EndpointNotFoundError
+type NetworkNotFoundError = hns.NetworkNotFoundError
 
 // ProcessError is an error encountered in HCS during an operation on a Process object
 type ProcessError struct {
@@ -94,6 +85,7 @@ type ProcessError struct {
 	Operation string
 	ExtraInfo string
 	Err       error
+	Events    []hcs.ErrorEvent
 }
 
 // ContainerError is an error encountered in HCS during an operation on a Container object
@@ -102,6 +94,7 @@ type ContainerError struct {
 	Operation string
 	ExtraInfo string
 	Err       error
+	Events    []hcs.ErrorEvent
 }
 
 func (e *ContainerError) Error() string {
@@ -113,7 +106,7 @@ func (e *ContainerError) Error() string {
 		return "unexpected nil container for error: " + e.Err.Error()
 	}
 
-	s := "container " + e.Container.id
+	s := "container " + e.Container.system.ID()
 
 	if e.Operation != "" {
 		s += " encountered an error during " + e.Operation
@@ -123,11 +116,15 @@ func (e *ContainerError) Error() string {
 	case nil:
 		break
 	case syscall.Errno:
-		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, win32FromError(e.Err))
+		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, hcserror.Win32FromError(e.Err))
 	default:
 		s += fmt.Sprintf(": %s", e.Err.Error())
 	}
 
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+
 	if e.ExtraInfo != "" {
 		s += " extra info: " + e.ExtraInfo
 	}
@@ -153,12 +150,7 @@ func (e *ProcessError) Error() string {
 		return "Unexpected nil process for error: " + e.Err.Error()
 	}
 
-	s := fmt.Sprintf("process %d", e.Process.processID)
-
-	if e.Process.container != nil {
-		s += " in container " + e.Process.container.id
-	}
-
+	s := fmt.Sprintf("process %d in container %s", e.Process.p.Pid(), e.Process.p.SystemID())
 	if e.Operation != "" {
 		s += " encountered an error during " + e.Operation
 	}
@@ -167,11 +159,15 @@ func (e *ProcessError) Error() string {
 	case nil:
 		break
 	case syscall.Errno:
-		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, win32FromError(e.Err))
+		s += fmt.Sprintf(": failure in a Windows system call: %s (0x%x)", e.Err, hcserror.Win32FromError(e.Err))
 	default:
 		s += fmt.Sprintf(": %s", e.Err.Error())
 	}
 
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+
 	return s
 }
 
@@ -189,37 +185,31 @@ func makeProcessError(process *process, operation string, extraInfo string, err
 // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 func IsNotExist(err error) bool {
-	err = getInnerError(err)
 	if _, ok := err.(EndpointNotFoundError); ok {
 		return true
 	}
 	if _, ok := err.(NetworkNotFoundError); ok {
 		return true
 	}
-	return err == ErrComputeSystemDoesNotExist ||
-		err == ErrElementNotFound ||
-		err == ErrProcNotFound
+	return hcs.IsNotExist(getInnerError(err))
 }
 
 // IsAlreadyClosed checks if an error is caused by the Container or Process having been
 // already closed by a call to the Close() method.
 func IsAlreadyClosed(err error) bool {
-	err = getInnerError(err)
-	return err == ErrAlreadyClosed
+	return hcs.IsAlreadyClosed(getInnerError(err))
 }
 
 // IsPending returns a boolean indicating whether the error is that
 // the requested operation is being completed in the background.
 func IsPending(err error) bool {
-	err = getInnerError(err)
-	return err == ErrVmcomputeOperationPending
+	return hcs.IsPending(getInnerError(err))
 }
 
 // IsTimeout returns a boolean indicating whether the error is caused by
 // a timeout waiting for the operation to complete.
 func IsTimeout(err error) bool {
-	err = getInnerError(err)
-	return err == ErrTimeout
+	return hcs.IsTimeout(getInnerError(err))
 }
 
 // IsAlreadyStopped returns a boolean indicating whether the error is caused by
@@ -228,10 +218,7 @@ func IsTimeout(err error) bool {
 // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 func IsAlreadyStopped(err error) bool {
-	err = getInnerError(err)
-	return err == ErrVmcomputeAlreadyStopped ||
-		err == ErrElementNotFound ||
-		err == ErrProcNotFound
+	return hcs.IsAlreadyStopped(getInnerError(err))
 }
 
 // IsNotSupported returns a boolean indicating whether the error is caused by
@@ -240,12 +227,7 @@ func IsAlreadyStopped(err error) bool {
 // ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
 // is thrown from the Platform
 func IsNotSupported(err error) bool {
-	err = getInnerError(err)
-	// If Platform doesn't recognize or support the request sent, below errors are seen
-	return err == ErrVmcomputeInvalidJSON ||
-		err == ErrInvalidData ||
-		err == ErrNotSupported ||
-		err == ErrVmcomputeUnknownMessage
+	return hcs.IsNotSupported(getInnerError(err))
 }
 
 func getInnerError(err error) error {
@@ -259,3 +241,17 @@ func getInnerError(err error) error {
 	}
 	return err
 }
+
+func convertSystemError(err error, c *container) error {
+	if serr, ok := err.(*hcs.SystemError); ok {
+		return &ContainerError{Container: c, Operation: serr.Op, ExtraInfo: serr.Extra, Err: serr.Err, Events: serr.Events}
+	}
+	return err
+}
+
+func convertProcessError(err error, p *process) error {
+	if perr, ok := err.(*hcs.ProcessError); ok {
+		return &ProcessError{Process: p, Operation: perr.Op, Err: perr.Err, Events: perr.Events}
+	}
+	return err
+}

+ 0 - 26
vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go

@@ -1,26 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// ExpandSandboxSize expands the size of a layer to at least size bytes.
-func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
-	title := "hcsshim::ExpandSandboxSize "
-	logrus.Debugf(title+"layerId=%s size=%d", layerId, size)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = expandSandboxSize(&infop, layerId, size)
-	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s  size=%d", layerId, size)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"- succeeded layerId=%s size=%d", layerId, size)
-	return nil
-}

+ 0 - 19
vendor/github.com/Microsoft/hcsshim/guid.go

@@ -1,19 +0,0 @@
-package hcsshim
-
-import (
-	"crypto/sha1"
-	"fmt"
-)
-
-type GUID [16]byte
-
-func NewGUID(source string) *GUID {
-	h := sha1.Sum([]byte(source))
-	var g GUID
-	copy(g[0:], h[0:16])
-	return &g
-}
-
-func (g *GUID) ToString() string {
-	return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x", g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], g[8:10], g[10:])
-}

+ 4 - 142
vendor/github.com/Microsoft/hcsshim/hcsshim.go

@@ -4,80 +4,20 @@
 package hcsshim
 
 import (
-	"fmt"
 	"syscall"
-	"unsafe"
 
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 )
 
-//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go safeopen.go
+//go:generate go run mksyscall_windows.go -output zsyscall_windows.go hcsshim.go
 
-//sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
 //sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId
 
-//sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer?
-//sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer?
-//sys createLayer(info *driverInfo, id string, parent string) (hr error) = vmcompute.CreateLayer?
-//sys createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CreateSandboxLayer?
-//sys expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) = vmcompute.ExpandSandboxSize?
-//sys deactivateLayer(info *driverInfo, id string) (hr error) = vmcompute.DeactivateLayer?
-//sys destroyLayer(info *driverInfo, id string) (hr error) = vmcompute.DestroyLayer?
-//sys exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ExportLayer?
-//sys getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) = vmcompute.GetLayerMountPath?
-//sys getBaseImages(buffer **uint16) (hr error) = vmcompute.GetBaseImages?
-//sys importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ImportLayer?
-//sys layerExists(info *driverInfo, id string, exists *uint32) (hr error) = vmcompute.LayerExists?
-//sys nameToGuid(name string, guid *GUID) (hr error) = vmcompute.NameToGuid?
-//sys prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.PrepareLayer?
-//sys unprepareLayer(info *driverInfo, id string) (hr error) = vmcompute.UnprepareLayer?
-//sys processBaseImage(path string) (hr error) = vmcompute.ProcessBaseImage?
-//sys processUtilityImage(path string) (hr error) = vmcompute.ProcessUtilityImage?
-
-//sys importLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ImportLayerBegin?
-//sys importLayerNext(context uintptr, fileName string, fileInfo *winio.FileBasicInfo) (hr error) = vmcompute.ImportLayerNext?
-//sys importLayerWrite(context uintptr, buffer []byte) (hr error) = vmcompute.ImportLayerWrite?
-//sys importLayerEnd(context uintptr) (hr error) = vmcompute.ImportLayerEnd?
-
-//sys exportLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ExportLayerBegin?
-//sys exportLayerNext(context uintptr, fileName **uint16, fileInfo *winio.FileBasicInfo, fileSize *int64, deleted *uint32) (hr error) = vmcompute.ExportLayerNext?
-//sys exportLayerRead(context uintptr, buffer []byte, bytesRead *uint32) (hr error) = vmcompute.ExportLayerRead?
-//sys exportLayerEnd(context uintptr) (hr error) = vmcompute.ExportLayerEnd?
-
-//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
-//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
-//sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
-//sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
-//sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
-//sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
-//sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
-//sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
-//sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
-//sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
-//sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
-//sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
-//sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
-
-//sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
-//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
-//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
-//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
-//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
-//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
-//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
-//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
-//sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
-//sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
-
-//sys hcsModifyServiceSettings(settings string, result **uint16) (hr error) = vmcompute.HcsModifyServiceSettings?
-
-//sys _hnsCall(method string, path string, object string, response **uint16) (hr error) = vmcompute.HNSCall?
-
 const (
 	// Specific user-visible exit codes
 	WaitErrExecFailed = 32767
 
-	ERROR_GEN_FAILURE          = syscall.Errno(31)
+	ERROR_GEN_FAILURE          = hcserror.ERROR_GEN_FAILURE
 	ERROR_SHUTDOWN_IN_PROGRESS = syscall.Errno(1115)
 	WSAEINVAL                  = syscall.Errno(10022)
 
@@ -85,82 +25,4 @@ const (
 	TimeoutInfinite = 0xFFFFFFFF
 )
 
-type HcsError struct {
-	title string
-	rest  string
-	Err   error
-}
-
-type hcsSystem syscall.Handle
-type hcsProcess syscall.Handle
-type hcsCallback syscall.Handle
-
-type hcsProcessInformation struct {
-	ProcessId uint32
-	Reserved  uint32
-	StdInput  syscall.Handle
-	StdOutput syscall.Handle
-	StdError  syscall.Handle
-}
-
-func makeError(err error, title, rest string) error {
-	// Pass through DLL errors directly since they do not originate from HCS.
-	if _, ok := err.(*syscall.DLLError); ok {
-		return err
-	}
-	return &HcsError{title, rest, err}
-}
-
-func makeErrorf(err error, title, format string, a ...interface{}) error {
-	return makeError(err, title, fmt.Sprintf(format, a...))
-}
-
-func win32FromError(err error) uint32 {
-	if herr, ok := err.(*HcsError); ok {
-		return win32FromError(herr.Err)
-	}
-	if code, ok := err.(syscall.Errno); ok {
-		return uint32(code)
-	}
-	return uint32(ERROR_GEN_FAILURE)
-}
-
-func win32FromHresult(hr uintptr) uintptr {
-	if hr&0x1fff0000 == 0x00070000 {
-		return hr & 0xffff
-	}
-	return hr
-}
-
-func (e *HcsError) Error() string {
-	s := e.title
-	if len(s) > 0 && s[len(s)-1] != ' ' {
-		s += " "
-	}
-	s += fmt.Sprintf("failed in Win32: %s (0x%x)", e.Err, win32FromError(e.Err))
-	if e.rest != "" {
-		if e.rest[0] != ' ' {
-			s += " "
-		}
-		s += e.rest
-	}
-	return s
-}
-
-func convertAndFreeCoTaskMemString(buffer *uint16) string {
-	str := syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(buffer))[:])
-	coTaskMemFree(unsafe.Pointer(buffer))
-	return str
-}
-
-func convertAndFreeCoTaskMemBytes(buffer *uint16) []byte {
-	return []byte(convertAndFreeCoTaskMemString(buffer))
-}
-
-func processHcsResult(err error, resultp *uint16) error {
-	if resultp != nil {
-		result := convertAndFreeCoTaskMemString(resultp)
-		logrus.Debugf("Result: %s", result)
-	}
-	return err
-}
+type HcsError = hcserror.HcsError

+ 8 - 240
vendor/github.com/Microsoft/hcsshim/hnsendpoint.go

@@ -1,29 +1,11 @@
 package hcsshim
 
 import (
-	"encoding/json"
-	"net"
-
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hns"
 )
 
 // HNSEndpoint represents a network endpoint in HNS
-type HNSEndpoint struct {
-	Id                 string            `json:"ID,omitempty"`
-	Name               string            `json:",omitempty"`
-	VirtualNetwork     string            `json:",omitempty"`
-	VirtualNetworkName string            `json:",omitempty"`
-	Policies           []json.RawMessage `json:",omitempty"`
-	MacAddress         string            `json:",omitempty"`
-	IPAddress          net.IP            `json:",omitempty"`
-	DNSSuffix          string            `json:",omitempty"`
-	DNSServerList      string            `json:",omitempty"`
-	GatewayAddress     string            `json:",omitempty"`
-	EnableInternalDNS  bool              `json:",omitempty"`
-	DisableICC         bool              `json:",omitempty"`
-	PrefixLength       uint8             `json:",omitempty"`
-	IsRemoteEndpoint   bool              `json:",omitempty"`
-}
+type HNSEndpoint = hns.HNSEndpoint
 
 //SystemType represents the type of the system on which actions are done
 type SystemType string
@@ -37,39 +19,19 @@ const (
 
 // EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
 // Supported resource types are Network and Request Types are Add/Remove
-type EndpointAttachDetachRequest struct {
-	ContainerID    string     `json:"ContainerId,omitempty"`
-	SystemType     SystemType `json:"SystemType"`
-	CompartmentID  uint16     `json:"CompartmentId,omitempty"`
-	VirtualNICName string     `json:"VirtualNicName,omitempty"`
-}
+type EndpointAttachDetachRequest = hns.EndpointAttachDetachRequest
 
 // EndpointResquestResponse is object to get the endpoint request response
-type EndpointResquestResponse struct {
-	Success bool
-	Error   string
-}
+type EndpointResquestResponse = hns.EndpointResquestResponse
 
 // HNSEndpointRequest makes a HNS call to modify/query a network endpoint
 func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
-	endpoint := &HNSEndpoint{}
-	err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return endpoint, nil
+	return hns.HNSEndpointRequest(method, path, request)
 }
 
 // HNSListEndpointRequest makes a HNS call to query the list of available endpoints
 func HNSListEndpointRequest() ([]HNSEndpoint, error) {
-	var endpoint []HNSEndpoint
-	err := hnsCall("GET", "/endpoints/", "", &endpoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return endpoint, nil
+	return hns.HNSListEndpointRequest()
 }
 
 // HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
@@ -120,204 +82,10 @@ func modifyNetworkEndpoint(containerID string, endpointID string, request Reques
 
 // GetHNSEndpointByID get the Endpoint by ID
 func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
-	return HNSEndpointRequest("GET", endpointID, "")
+	return hns.GetHNSEndpointByID(endpointID)
 }
 
 // GetHNSEndpointByName gets the endpoint filtered by Name
 func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
-	hnsResponse, err := HNSListEndpointRequest()
-	if err != nil {
-		return nil, err
-	}
-	for _, hnsEndpoint := range hnsResponse {
-		if hnsEndpoint.Name == endpointName {
-			return &hnsEndpoint, nil
-		}
-	}
-	return nil, EndpointNotFoundError{EndpointName: endpointName}
-}
-
-// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
-func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
-	operation := "Create"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-
-	jsonString, err := json.Marshal(endpoint)
-	if err != nil {
-		return nil, err
-	}
-	return HNSEndpointRequest("POST", "", string(jsonString))
-}
-
-// Delete Endpoint by sending EndpointRequest to HNS
-func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
-	operation := "Delete"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-
-	return HNSEndpointRequest("DELETE", endpoint.Id, "")
-}
-
-// Update Endpoint
-func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
-	operation := "Update"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-	jsonString, err := json.Marshal(endpoint)
-	if err != nil {
-		return nil, err
-	}
-	err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
-
-	return endpoint, err
-}
-
-// ContainerHotAttach attaches an endpoint to a running container
-func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {
-	operation := "ContainerHotAttach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
-
-	return modifyNetworkEndpoint(containerID, endpoint.Id, Add)
-}
-
-// ContainerHotDetach detaches an endpoint from a running container
-func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
-	operation := "ContainerHotDetach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
-
-	return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
-}
-
-// ApplyACLPolicy applies a set of ACL Policies on the Endpoint
-func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
-	operation := "ApplyACLPolicy"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-
-	for _, policy := range policies {
-		if policy == nil {
-			continue
-		}
-		jsonString, err := json.Marshal(policy)
-		if err != nil {
-			return err
-		}
-		endpoint.Policies = append(endpoint.Policies, jsonString)
-	}
-
-	_, err := endpoint.Update()
-	return err
-}
-
-// ContainerAttach attaches an endpoint to container
-func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
-	operation := "ContainerAttach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-
-	requestMessage := &EndpointAttachDetachRequest{
-		ContainerID:   containerID,
-		CompartmentID: compartmentID,
-		SystemType:    ContainerType,
-	}
-	response := &EndpointResquestResponse{}
-	jsonString, err := json.Marshal(requestMessage)
-	if err != nil {
-		return err
-	}
-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
-}
-
-// ContainerDetach detaches an endpoint from container
-func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
-	operation := "ContainerDetach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-
-	requestMessage := &EndpointAttachDetachRequest{
-		ContainerID: containerID,
-		SystemType:  ContainerType,
-	}
-	response := &EndpointResquestResponse{}
-
-	jsonString, err := json.Marshal(requestMessage)
-	if err != nil {
-		return err
-	}
-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
-}
-
-// HostAttach attaches a nic on the host
-func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
-	operation := "HostAttach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-	requestMessage := &EndpointAttachDetachRequest{
-		CompartmentID: compartmentID,
-		SystemType:    HostType,
-	}
-	response := &EndpointResquestResponse{}
-
-	jsonString, err := json.Marshal(requestMessage)
-	if err != nil {
-		return err
-	}
-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
-
-}
-
-// HostDetach detaches a nic on the host
-func (endpoint *HNSEndpoint) HostDetach() error {
-	operation := "HostDetach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-	requestMessage := &EndpointAttachDetachRequest{
-		SystemType: HostType,
-	}
-	response := &EndpointResquestResponse{}
-
-	jsonString, err := json.Marshal(requestMessage)
-	if err != nil {
-		return err
-	}
-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
-}
-
-// VirtualMachineNICAttach attaches a endpoint to a virtual machine
-func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
-	operation := "VirtualMachineNicAttach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-	requestMessage := &EndpointAttachDetachRequest{
-		VirtualNICName: virtualMachineNICName,
-		SystemType:     VirtualMachineType,
-	}
-	response := &EndpointResquestResponse{}
-
-	jsonString, err := json.Marshal(requestMessage)
-	if err != nil {
-		return err
-	}
-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
-}
-
-// VirtualMachineNICDetach detaches a endpoint  from a virtual machine
-func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
-	operation := "VirtualMachineNicDetach"
-	title := "HCSShim::HNSEndpoint::" + operation
-	logrus.Debugf(title+" id=%s", endpoint.Id)
-
-	requestMessage := &EndpointAttachDetachRequest{
-		SystemType: VirtualMachineType,
-	}
-	response := &EndpointResquestResponse{}
-
-	jsonString, err := json.Marshal(requestMessage)
-	if err != nil {
-		return err
-	}
-	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+	return hns.GetHNSEndpointByName(endpointName)
 }

+ 16 - 0
vendor/github.com/Microsoft/hcsshim/hnsglobals.go

@@ -0,0 +1,16 @@
+package hcsshim
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hns"
+)
+
+type HNSGlobals = hns.HNSGlobals
+type HNSVersion = hns.HNSVersion
+
+var (
+	HNSVersion1803 = hns.HNSVersion1803
+)
+
+func GetHNSGlobals() (*HNSGlobals, error) {
+	return hns.GetHNSGlobals()
+}

+ 8 - 113
vendor/github.com/Microsoft/hcsshim/hnsnetwork.go

@@ -1,141 +1,36 @@
 package hcsshim
 
 import (
-	"encoding/json"
-	"net"
-
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hns"
 )
 
 // Subnet is assoicated with a network and represents a list
 // of subnets available to the network
-type Subnet struct {
-	AddressPrefix  string            `json:",omitempty"`
-	GatewayAddress string            `json:",omitempty"`
-	Policies       []json.RawMessage `json:",omitempty"`
-}
+type Subnet = hns.Subnet
 
 // MacPool is assoicated with a network and represents a list
 // of macaddresses available to the network
-type MacPool struct {
-	StartMacAddress string `json:",omitempty"`
-	EndMacAddress   string `json:",omitempty"`
-}
+type MacPool = hns.MacPool
 
 // HNSNetwork represents a network in HNS
-type HNSNetwork struct {
-	Id                   string            `json:"ID,omitempty"`
-	Name                 string            `json:",omitempty"`
-	Type                 string            `json:",omitempty"`
-	NetworkAdapterName   string            `json:",omitempty"`
-	SourceMac            string            `json:",omitempty"`
-	Policies             []json.RawMessage `json:",omitempty"`
-	MacPools             []MacPool         `json:",omitempty"`
-	Subnets              []Subnet          `json:",omitempty"`
-	DNSSuffix            string            `json:",omitempty"`
-	DNSServerList        string            `json:",omitempty"`
-	DNSServerCompartment uint32            `json:",omitempty"`
-	ManagementIP         string            `json:",omitempty"`
-	AutomaticDNS         bool              `json:",omitempty"`
-}
-
-type hnsNetworkResponse struct {
-	Success bool
-	Error   string
-	Output  HNSNetwork
-}
-
-type hnsResponse struct {
-	Success bool
-	Error   string
-	Output  json.RawMessage
-}
+type HNSNetwork = hns.HNSNetwork
 
 // HNSNetworkRequest makes a call into HNS to update/query a single network
 func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
-	var network HNSNetwork
-	err := hnsCall(method, "/networks/"+path, request, &network)
-	if err != nil {
-		return nil, err
-	}
-
-	return &network, nil
+	return hns.HNSNetworkRequest(method, path, request)
 }
 
 // HNSListNetworkRequest makes a HNS call to query the list of available networks
 func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
-	var network []HNSNetwork
-	err := hnsCall(method, "/networks/"+path, request, &network)
-	if err != nil {
-		return nil, err
-	}
-
-	return network, nil
+	return hns.HNSListNetworkRequest(method, path, request)
 }
 
 // GetHNSNetworkByID
 func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
-	return HNSNetworkRequest("GET", networkID, "")
+	return hns.GetHNSNetworkByID(networkID)
 }
 
 // GetHNSNetworkName filtered by Name
 func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
-	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
-	if err != nil {
-		return nil, err
-	}
-	for _, hnsnetwork := range hsnnetworks {
-		if hnsnetwork.Name == networkName {
-			return &hnsnetwork, nil
-		}
-	}
-	return nil, NetworkNotFoundError{NetworkName: networkName}
-}
-
-// Create Network by sending NetworkRequest to HNS.
-func (network *HNSNetwork) Create() (*HNSNetwork, error) {
-	operation := "Create"
-	title := "HCSShim::HNSNetwork::" + operation
-	logrus.Debugf(title+" id=%s", network.Id)
-
-	jsonString, err := json.Marshal(network)
-	if err != nil {
-		return nil, err
-	}
-	return HNSNetworkRequest("POST", "", string(jsonString))
-}
-
-// Delete Network by sending NetworkRequest to HNS
-func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
-	operation := "Delete"
-	title := "HCSShim::HNSNetwork::" + operation
-	logrus.Debugf(title+" id=%s", network.Id)
-
-	return HNSNetworkRequest("DELETE", network.Id, "")
-}
-
-// Creates an endpoint on the Network.
-func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
-	return &HNSEndpoint{
-		VirtualNetwork: network.Id,
-		IPAddress:      ipAddress,
-		MacAddress:     string(macAddress),
-	}
-}
-
-func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
-	operation := "CreateEndpoint"
-	title := "HCSShim::HNSNetwork::" + operation
-	logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
-
-	endpoint.VirtualNetwork = network.Id
-	return endpoint.Create()
-}
-
-func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
-	operation := "CreateRemoteEndpoint"
-	title := "HCSShim::HNSNetwork::" + operation
-	logrus.Debugf(title+" id=%s", network.Id)
-	endpoint.IsRemoteEndpoint = true
-	return network.CreateEndpoint(endpoint)
+	return hns.GetHNSNetworkByName(networkName)
 }

+ 43 - 80
vendor/github.com/Microsoft/hcsshim/hnspolicy.go

@@ -1,94 +1,57 @@
 package hcsshim
 
+import (
+	"github.com/Microsoft/hcsshim/internal/hns"
+)
+
 // Type of Request Support in ModifySystem
-type PolicyType string
+type PolicyType = hns.PolicyType
 
 // RequestType const
 const (
-	Nat                  PolicyType = "NAT"
-	ACL                  PolicyType = "ACL"
-	PA                   PolicyType = "PA"
-	VLAN                 PolicyType = "VLAN"
-	VSID                 PolicyType = "VSID"
-	VNet                 PolicyType = "VNET"
-	L2Driver             PolicyType = "L2Driver"
-	Isolation            PolicyType = "Isolation"
-	QOS                  PolicyType = "QOS"
-	OutboundNat          PolicyType = "OutBoundNAT"
-	ExternalLoadBalancer PolicyType = "ELB"
-	Route                PolicyType = "ROUTE"
+	Nat                  = hns.Nat
+	ACL                  = hns.ACL
+	PA                   = hns.PA
+	VLAN                 = hns.VLAN
+	VSID                 = hns.VSID
+	VNet                 = hns.VNet
+	L2Driver             = hns.L2Driver
+	Isolation            = hns.Isolation
+	QOS                  = hns.QOS
+	OutboundNat          = hns.OutboundNat
+	ExternalLoadBalancer = hns.ExternalLoadBalancer
+	Route                = hns.Route
 )
 
-type NatPolicy struct {
-	Type         PolicyType `json:"Type"`
-	Protocol     string
-	InternalPort uint16
-	ExternalPort uint16
-}
-
-type QosPolicy struct {
-	Type                            PolicyType `json:"Type"`
-	MaximumOutgoingBandwidthInBytes uint64
-}
-
-type IsolationPolicy struct {
-	Type               PolicyType `json:"Type"`
-	VLAN               uint
-	VSID               uint
-	InDefaultIsolation bool
-}
-
-type VlanPolicy struct {
-	Type PolicyType `json:"Type"`
-	VLAN uint
-}
-
-type VsidPolicy struct {
-	Type PolicyType `json:"Type"`
-	VSID uint
-}
-
-type PaPolicy struct {
-	Type PolicyType `json:"Type"`
-	PA   string     `json:"PA"`
-}
-
-type OutboundNatPolicy struct {
-	Policy
-	VIP        string   `json:"VIP,omitempty"`
-	Exceptions []string `json:"ExceptionList,omitempty"`
-}
-
-type ActionType string
-type DirectionType string
-type RuleType string
+type NatPolicy = hns.NatPolicy
+
+type QosPolicy = hns.QosPolicy
+
+type IsolationPolicy = hns.IsolationPolicy
+
+type VlanPolicy = hns.VlanPolicy
+
+type VsidPolicy = hns.VsidPolicy
+
+type PaPolicy = hns.PaPolicy
+
+type OutboundNatPolicy = hns.OutboundNatPolicy
+
+type ActionType = hns.ActionType
+type DirectionType = hns.DirectionType
+type RuleType = hns.RuleType
 
 const (
-	Allow ActionType = "Allow"
-	Block ActionType = "Block"
+	Allow = hns.Allow
+	Block = hns.Block
 
-	In  DirectionType = "In"
-	Out DirectionType = "Out"
+	In  = hns.In
+	Out = hns.Out
 
-	Host   RuleType = "Host"
-	Switch RuleType = "Switch"
+	Host   = hns.Host
+	Switch = hns.Switch
 )
 
-type ACLPolicy struct {
-	Type            PolicyType `json:"Type"`
-	Protocol        uint16
-	InternalPort    uint16
-	Action          ActionType
-	Direction       DirectionType
-	LocalAddresses  string
-	RemoteAddresses string
-	LocalPort       uint16
-	RemotePort      uint16
-	RuleType        RuleType `json:"RuleType,omitempty"`
-	Priority        uint16
-	ServiceName     string
-}
-
-type Policy struct {
-	Type PolicyType `json:"Type"`
-}
+type ACLPolicy = hns.ACLPolicy
+
+type Policy = hns.Policy

+ 11 - 164
vendor/github.com/Microsoft/hcsshim/hnspolicylist.go

@@ -1,200 +1,47 @@
 package hcsshim
 
 import (
-	"encoding/json"
-
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hns"
 )
 
 // RoutePolicy is a structure defining schema for Route based Policy
-type RoutePolicy struct {
-	Policy
-	DestinationPrefix string `json:"DestinationPrefix,omitempty"`
-	NextHop           string `json:"NextHop,omitempty"`
-	EncapEnabled      bool   `json:"NeedEncap,omitempty"`
-}
+type RoutePolicy = hns.RoutePolicy
 
 // ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy
-type ELBPolicy struct {
-	LBPolicy
-	SourceVIP string   `json:"SourceVIP,omitempty"`
-	VIPs      []string `json:"VIPs,omitempty"`
-	ILB       bool     `json:"ILB,omitempty"`
-}
+type ELBPolicy = hns.ELBPolicy
 
 // LBPolicy is a structure defining schema for LoadBalancing based Policy
-type LBPolicy struct {
-	Policy
-	Protocol     uint16 `json:"Protocol,omitempty"`
-	InternalPort uint16
-	ExternalPort uint16
-}
+type LBPolicy = hns.LBPolicy
 
 // PolicyList is a structure defining schema for Policy list request
-type PolicyList struct {
-	ID                 string            `json:"ID,omitempty"`
-	EndpointReferences []string          `json:"References,omitempty"`
-	Policies           []json.RawMessage `json:"Policies,omitempty"`
-}
+type PolicyList = hns.PolicyList
 
 // HNSPolicyListRequest makes a call into HNS to update/query a single network
 func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
-	var policy PolicyList
-	err := hnsCall(method, "/policylists/"+path, request, &policy)
-	if err != nil {
-		return nil, err
-	}
-
-	return &policy, nil
+	return hns.HNSPolicyListRequest(method, path, request)
 }
 
 // HNSListPolicyListRequest gets all the policy list
 func HNSListPolicyListRequest() ([]PolicyList, error) {
-	var plist []PolicyList
-	err := hnsCall("GET", "/policylists/", "", &plist)
-	if err != nil {
-		return nil, err
-	}
-
-	return plist, nil
+	return hns.HNSListPolicyListRequest()
 }
 
 // PolicyListRequest makes a HNS call to modify/query a network policy list
 func PolicyListRequest(method, path, request string) (*PolicyList, error) {
-	policylist := &PolicyList{}
-	err := hnsCall(method, "/policylists/"+path, request, &policylist)
-	if err != nil {
-		return nil, err
-	}
-
-	return policylist, nil
+	return hns.PolicyListRequest(method, path, request)
 }
 
 // GetPolicyListByID get the policy list by ID
 func GetPolicyListByID(policyListID string) (*PolicyList, error) {
-	return PolicyListRequest("GET", policyListID, "")
-}
-
-// Create PolicyList by sending PolicyListRequest to HNS.
-func (policylist *PolicyList) Create() (*PolicyList, error) {
-	operation := "Create"
-	title := "HCSShim::PolicyList::" + operation
-	logrus.Debugf(title+" id=%s", policylist.ID)
-	jsonString, err := json.Marshal(policylist)
-	if err != nil {
-		return nil, err
-	}
-	return PolicyListRequest("POST", "", string(jsonString))
-}
-
-// Delete deletes PolicyList
-func (policylist *PolicyList) Delete() (*PolicyList, error) {
-	operation := "Delete"
-	title := "HCSShim::PolicyList::" + operation
-	logrus.Debugf(title+" id=%s", policylist.ID)
-
-	return PolicyListRequest("DELETE", policylist.ID, "")
-}
-
-// AddEndpoint add an endpoint to a Policy List
-func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
-	operation := "AddEndpoint"
-	title := "HCSShim::PolicyList::" + operation
-	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
-
-	_, err := policylist.Delete()
-	if err != nil {
-		return nil, err
-	}
-
-	// Add Endpoint to the Existing List
-	policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
-
-	return policylist.Create()
-}
-
-// RemoveEndpoint removes an endpoint from the Policy List
-func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
-	operation := "RemoveEndpoint"
-	title := "HCSShim::PolicyList::" + operation
-	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
-
-	_, err := policylist.Delete()
-	if err != nil {
-		return nil, err
-	}
-
-	elementToRemove := "/endpoints/" + endpoint.Id
-
-	var references []string
-
-	for _, endpointReference := range policylist.EndpointReferences {
-		if endpointReference == elementToRemove {
-			continue
-		}
-		references = append(references, endpointReference)
-	}
-	policylist.EndpointReferences = references
-	return policylist.Create()
+	return hns.GetPolicyListByID(policyListID)
 }
 
 // AddLoadBalancer policy list for the specified endpoints
 func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
-	operation := "AddLoadBalancer"
-	title := "HCSShim::PolicyList::" + operation
-	logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
-
-	policylist := &PolicyList{}
-
-	elbPolicy := &ELBPolicy{
-		SourceVIP: sourceVIP,
-		ILB:       isILB,
-	}
-
-	if len(vip) > 0 {
-		elbPolicy.VIPs = []string{vip}
-	}
-	elbPolicy.Type = ExternalLoadBalancer
-	elbPolicy.Protocol = protocol
-	elbPolicy.InternalPort = internalPort
-	elbPolicy.ExternalPort = externalPort
-
-	for _, endpoint := range endpoints {
-		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
-	}
-
-	jsonString, err := json.Marshal(elbPolicy)
-	if err != nil {
-		return nil, err
-	}
-	policylist.Policies = append(policylist.Policies, jsonString)
-	return policylist.Create()
+	return hns.AddLoadBalancer(endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
 }
 
 // AddRoute adds route policy list for the specified endpoints
 func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
-	operation := "AddRoute"
-	title := "HCSShim::PolicyList::" + operation
-	logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
-
-	policylist := &PolicyList{}
-
-	rPolicy := &RoutePolicy{
-		DestinationPrefix: destinationPrefix,
-		NextHop:           nextHop,
-		EncapEnabled:      encapEnabled,
-	}
-	rPolicy.Type = Route
-
-	for _, endpoint := range endpoints {
-		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
-	}
-
-	jsonString, err := json.Marshal(rPolicy)
-	if err != nil {
-		return nil, err
-	}
-
-	policylist.Policies = append(policylist.Policies, jsonString)
-	return policylist.Create()
+	return hns.AddRoute(endpoints, destinationPrefix, nextHop, encapEnabled)
 }

+ 13 - 0
vendor/github.com/Microsoft/hcsshim/hnssupport.go

@@ -0,0 +1,13 @@
+package hcsshim
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hns"
+)
+
+type HNSSupportedFeatures = hns.HNSSupportedFeatures
+
+type HNSAclFeatures = hns.HNSAclFeatures
+
+func GetHNSSupportedFeatures() HNSSupportedFeatures {
+	return hns.GetHNSSupportedFeatures()
+}

+ 10 - 100
vendor/github.com/Microsoft/hcsshim/interface.go

@@ -1,117 +1,27 @@
 package hcsshim
 
 import (
-	"encoding/json"
 	"io"
 	"time"
+
+	"github.com/Microsoft/hcsshim/internal/schema1"
 )
 
 // ProcessConfig is used as both the input of Container.CreateProcess
 // and to convert the parameters to JSON for passing onto the HCS
-type ProcessConfig struct {
-	ApplicationName   string            `json:",omitempty"`
-	CommandLine       string            `json:",omitempty"`
-	CommandArgs       []string          `json:",omitempty"` // Used by Linux Containers on Windows
-	User              string            `json:",omitempty"`
-	WorkingDirectory  string            `json:",omitempty"`
-	Environment       map[string]string `json:",omitempty"`
-	EmulateConsole    bool              `json:",omitempty"`
-	CreateStdInPipe   bool              `json:",omitempty"`
-	CreateStdOutPipe  bool              `json:",omitempty"`
-	CreateStdErrPipe  bool              `json:",omitempty"`
-	ConsoleSize       [2]uint           `json:",omitempty"`
-	CreateInUtilityVm bool              `json:",omitempty"` // Used by Linux Containers on Windows
-	OCISpecification  *json.RawMessage  `json:",omitempty"` // Used by Linux Containers on Windows
-}
-
-type Layer struct {
-	ID   string
-	Path string
-}
+type ProcessConfig = schema1.ProcessConfig
 
-type MappedDir struct {
-	HostPath          string
-	ContainerPath     string
-	ReadOnly          bool
-	BandwidthMaximum  uint64
-	IOPSMaximum       uint64
-	CreateInUtilityVM bool
-	// LinuxMetadata - Support added in 1803/RS4+.
-	LinuxMetadata bool `json:",omitempty"`
-}
-
-type MappedPipe struct {
-	HostPath          string
-	ContainerPipeName string
-}
-
-type HvRuntime struct {
-	ImagePath           string `json:",omitempty"`
-	SkipTemplate        bool   `json:",omitempty"`
-	LinuxInitrdFile     string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM
-	LinuxKernelFile     string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM
-	LinuxBootParameters string `json:",omitempty"` // Additional boot parameters for starting a Linux Utility VM in initrd mode
-	BootSource          string `json:",omitempty"` // "Vhd" for Linux Utility VM booting from VHD
-	WritableBootSource  bool   `json:",omitempty"` // Linux Utility VM booting from VHD
-}
-
-type MappedVirtualDisk struct {
-	HostPath          string `json:",omitempty"` // Path to VHD on the host
-	ContainerPath     string // Platform-specific mount point path in the container
-	CreateInUtilityVM bool   `json:",omitempty"`
-	ReadOnly          bool   `json:",omitempty"`
-	Cache             string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
-	AttachOnly        bool   `json:",omitempty:`
-}
-
-// AssignedDevice represents a device that has been directly assigned to a container
-//
-// NOTE: Support added in RS5
-type AssignedDevice struct {
-	//  InterfaceClassGUID of the device to assign to container.
-	InterfaceClassGUID string `json:"InterfaceClassGuid,omitempty"`
-}
+type Layer = schema1.Layer
+type MappedDir = schema1.MappedDir
+type MappedPipe = schema1.MappedPipe
+type HvRuntime = schema1.HvRuntime
+type MappedVirtualDisk = schema1.MappedVirtualDisk
 
 // ContainerConfig is used as both the input of CreateContainer
 // and to convert the parameters to JSON for passing onto the HCS
-type ContainerConfig struct {
-	SystemType                  string              // HCS requires this to be hard-coded to "Container"
-	Name                        string              // Name of the container. We use the docker ID.
-	Owner                       string              `json:",omitempty"` // The management platform that created this container
-	VolumePath                  string              `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
-	IgnoreFlushesDuringBoot     bool                `json:",omitempty"` // Optimization hint for container startup in Windows
-	LayerFolderPath             string              `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format  %root%\windowsfilter\containerID
-	Layers                      []Layer             // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
-	Credentials                 string              `json:",omitempty"` // Credentials information
-	ProcessorCount              uint32              `json:",omitempty"` // Number of processors to assign to the container.
-	ProcessorWeight             uint64              `json:",omitempty"` // CPU shares (relative weight to other containers with cpu shares). Range is from 1 to 10000. A value of 0 results in default shares.
-	ProcessorMaximum            int64               `json:",omitempty"` // Specifies the portion of processor cycles that this container can use as a percentage times 100. Range is from 1 to 10000. A value of 0 results in no limit.
-	StorageIOPSMaximum          uint64              `json:",omitempty"` // Maximum Storage IOPS
-	StorageBandwidthMaximum     uint64              `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
-	StorageSandboxSize          uint64              `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
-	MemoryMaximumInMB           int64               `json:",omitempty"` // Maximum memory available to the container in Megabytes
-	HostName                    string              `json:",omitempty"` // Hostname
-	MappedDirectories           []MappedDir         `json:",omitempty"` // List of mapped directories (volumes/mounts)
-	MappedPipes                 []MappedPipe        `json:",omitempty"` // List of mapped Windows named pipes
-	HvPartition                 bool                // True if it a Hyper-V Container
-	NetworkSharedContainerName  string              `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
-	EndpointList                []string            `json:",omitempty"` // List of networking endpoints to be attached to container
-	HvRuntime                   *HvRuntime          `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
-	Servicing                   bool                `json:",omitempty"` // True if this container is for servicing
-	AllowUnqualifiedDNSQuery    bool                `json:",omitempty"` // True to allow unqualified DNS name resolution
-	DNSSearchList               string              `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
-	ContainerType               string              `json:",omitempty"` // "Linux" for Linux containers on Windows. Omitted otherwise.
-	TerminateOnLastHandleClosed bool                `json:",omitempty"` // Should HCS terminate the container once all handles have been closed
-	MappedVirtualDisks          []MappedVirtualDisk `json:",omitempty"` // Array of virtual disks to mount at start
-	AssignedDevices             []AssignedDevice    `json:",omitempty"` // Array of devices to assign. NOTE: Support added in RS5
-}
+type ContainerConfig = schema1.ContainerConfig
 
-type ComputeSystemQuery struct {
-	IDs    []string `json:"Ids,omitempty"`
-	Types  []string `json:",omitempty"`
-	Names  []string `json:",omitempty"`
-	Owners []string `json:",omitempty"`
-}
+type ComputeSystemQuery = schema1.ComputeSystemQuery
 
 // Container represents a created (but not necessarily running) container.
 type Container interface {

+ 22 - 0
vendor/github.com/Microsoft/hcsshim/internal/guid/guid.go

@@ -0,0 +1,22 @@
+package guid
+
+import (
+	"crypto/rand"
+	"fmt"
+	"io"
+)
+
+type GUID [16]byte
+
+func New() GUID {
+	g := GUID{}
+	_, err := io.ReadFull(rand.Reader, g[:])
+	if err != nil {
+		panic(err)
+	}
+	return g
+}
+
+func (g GUID) String() string {
+	return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x", g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], g[8:10], g[10:])
+}

+ 4 - 2
vendor/github.com/Microsoft/hcsshim/callback.go → vendor/github.com/Microsoft/hcsshim/internal/hcs/callback.go

@@ -1,8 +1,10 @@
-package hcsshim
+package hcs
 
 import (
 	"sync"
 	"syscall"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
 )
 
 var (
@@ -62,7 +64,7 @@ func closeChannels(channels notificationChannels) {
 func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
 	var result error
 	if int32(notificationStatus) < 0 {
-		result = syscall.Errno(win32FromHresult(notificationStatus))
+		result = interop.Win32FromHresult(notificationStatus)
 	}
 
 	callbackMapLock.RLock()

+ 1 - 1
vendor/github.com/Microsoft/hcsshim/cgo.go → vendor/github.com/Microsoft/hcsshim/internal/hcs/cgo.go

@@ -1,4 +1,4 @@
-package hcsshim
+package hcs
 
 import "C"
 

+ 279 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go

@@ -0,0 +1,279 @@
+package hcs
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"syscall"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"github.com/sirupsen/logrus"
+)
+
+var (
+	// ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists
+	ErrComputeSystemDoesNotExist = syscall.Errno(0xc037010e)
+
+	// ErrElementNotFound is an error encountered when the object being referenced does not exist
+	ErrElementNotFound = syscall.Errno(0x490)
+
+	// ErrElementNotFound is an error encountered when the object being referenced does not exist
+	ErrNotSupported = syscall.Errno(0x32)
+
+	// ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
+	// decimal -2147024883 / hex 0x8007000d
+	ErrInvalidData = syscall.Errno(0xd)
+
+	// ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
+	ErrHandleClose = errors.New("hcsshim: the handle generating this notification has been closed")
+
+	// ErrAlreadyClosed is an error encountered when using a handle that has been closed by the Close method
+	ErrAlreadyClosed = errors.New("hcsshim: the handle has already been closed")
+
+	// ErrInvalidNotificationType is an error encountered when an invalid notification type is used
+	ErrInvalidNotificationType = errors.New("hcsshim: invalid notification type")
+
+	// ErrInvalidProcessState is an error encountered when the process is not in a valid state for the requested operation
+	ErrInvalidProcessState = errors.New("the process is in an invalid state for the attempted operation")
+
+	// ErrTimeout is an error encountered when waiting on a notification times out
+	ErrTimeout = errors.New("hcsshim: timeout waiting for notification")
+
+	// ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
+	// a different expected notification
+	ErrUnexpectedContainerExit = errors.New("unexpected container exit")
+
+	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
+	// is lost while waiting for a notification
+	ErrUnexpectedProcessAbort = errors.New("lost communication with compute service")
+
+	// ErrUnexpectedValue is an error encountered when hcs returns an invalid value
+	ErrUnexpectedValue = errors.New("unexpected value returned from hcs")
+
+	// ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
+	ErrVmcomputeAlreadyStopped = syscall.Errno(0xc0370110)
+
+	// ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
+	ErrVmcomputeOperationPending = syscall.Errno(0xC0370103)
+
+	// ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation
+	ErrVmcomputeOperationInvalidState = syscall.Errno(0xc0370105)
+
+	// ErrProcNotFound is an error encountered when the the process cannot be found
+	ErrProcNotFound = syscall.Errno(0x7f)
+
+	// ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
+	// builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
+	ErrVmcomputeOperationAccessIsDenied = syscall.Errno(0x5)
+
+	// ErrVmcomputeInvalidJSON is an error encountered when the compute system does not support/understand the messages sent by management
+	ErrVmcomputeInvalidJSON = syscall.Errno(0xc037010d)
+
+	// ErrVmcomputeUnknownMessage is an error encountered guest compute system doesn't support the message
+	ErrVmcomputeUnknownMessage = syscall.Errno(0xc037010b)
+
+	// ErrNotSupported is an error encountered when hcs doesn't support the request
+	ErrPlatformNotSupported = errors.New("unsupported platform request")
+)
+
+type ErrorEvent struct {
+	Message    string `json:"Message,omitempty"`    // Fully formated error message
+	StackTrace string `json:"StackTrace,omitempty"` // Stack trace in string form
+	Provider   string `json:"Provider,omitempty"`
+	EventID    uint16 `json:"EventId,omitempty"`
+	Flags      uint32 `json:"Flags,omitempty"`
+	Source     string `json:"Source,omitempty"`
+	//Data       []EventData `json:"Data,omitempty"`  // Omit this as HCS doesn't encode this well. It's more confusing to include. It is however logged in debug mode (see processHcsResult function)
+}
+
+type hcsResult struct {
+	Error        int32
+	ErrorMessage string
+	ErrorEvents  []ErrorEvent `json:"ErrorEvents,omitempty"`
+}
+
+func (ev *ErrorEvent) String() string {
+	evs := "[Event Detail: " + ev.Message
+	if ev.StackTrace != "" {
+		evs += " Stack Trace: " + ev.StackTrace
+	}
+	if ev.Provider != "" {
+		evs += " Provider: " + ev.Provider
+	}
+	if ev.EventID != 0 {
+		evs = fmt.Sprintf("%s EventID: %d", evs, ev.EventID)
+	}
+	if ev.Flags != 0 {
+		evs = fmt.Sprintf("%s flags: %d", evs, ev.Flags)
+	}
+	if ev.Source != "" {
+		evs += " Source: " + ev.Source
+	}
+	evs += "]"
+	return evs
+}
+
+func processHcsResult(resultp *uint16) []ErrorEvent {
+	if resultp != nil {
+		resultj := interop.ConvertAndFreeCoTaskMemString(resultp)
+		logrus.Debugf("Result: %s", resultj)
+		result := &hcsResult{}
+		if err := json.Unmarshal([]byte(resultj), result); err != nil {
+			logrus.Warnf("Could not unmarshal HCS result %s: %s", resultj, err)
+			return nil
+		}
+		return result.ErrorEvents
+	}
+	return nil
+}
+
+type HcsError struct {
+	Op     string
+	Err    error
+	Events []ErrorEvent
+}
+
+func (e *HcsError) Error() string {
+	s := e.Op + ": " + e.Err.Error()
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+	return s
+}
+
+// ProcessError is an error encountered in HCS during an operation on a Process object
+type ProcessError struct {
+	SystemID string
+	Pid      int
+	Op       string
+	Err      error
+	Events   []ErrorEvent
+}
+
+// SystemError is an error encountered in HCS during an operation on a Container object
+type SystemError struct {
+	ID     string
+	Op     string
+	Err    error
+	Extra  string
+	Events []ErrorEvent
+}
+
+func (e *SystemError) Error() string {
+	s := e.Op + " " + e.ID + ": " + e.Err.Error()
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+	if e.Extra != "" {
+		s += "\n(extra info: " + e.Extra + ")"
+	}
+	return s
+}
+
+func makeSystemError(system *System, op string, extra string, err error, events []ErrorEvent) error {
+	// Don't double wrap errors
+	if _, ok := err.(*SystemError); ok {
+		return err
+	}
+	return &SystemError{
+		ID:     system.ID(),
+		Op:     op,
+		Extra:  extra,
+		Err:    err,
+		Events: events,
+	}
+}
+
+func (e *ProcessError) Error() string {
+	s := fmt.Sprintf("%s %s:%d: %s", e.Op, e.SystemID, e.Pid, e.Err.Error())
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+	return s
+}
+
+func makeProcessError(process *Process, op string, err error, events []ErrorEvent) error {
+	// Don't double wrap errors
+	if _, ok := err.(*ProcessError); ok {
+		return err
+	}
+	return &ProcessError{
+		Pid:      process.Pid(),
+		SystemID: process.SystemID(),
+		Op:       op,
+		Err:      err,
+		Events:   events,
+	}
+}
+
+// IsNotExist checks if an error is caused by the Container or Process not existing.
+// Note: Currently, ErrElementNotFound can mean that a Process has either
+// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
+// will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
+func IsNotExist(err error) bool {
+	err = getInnerError(err)
+	return err == ErrComputeSystemDoesNotExist ||
+		err == ErrElementNotFound ||
+		err == ErrProcNotFound
+}
+
+// IsAlreadyClosed checks if an error is caused by the Container or Process having been
+// already closed by a call to the Close() method.
+func IsAlreadyClosed(err error) bool {
+	err = getInnerError(err)
+	return err == ErrAlreadyClosed
+}
+
+// IsPending returns a boolean indicating whether the error is that
+// the requested operation is being completed in the background.
+func IsPending(err error) bool {
+	err = getInnerError(err)
+	return err == ErrVmcomputeOperationPending
+}
+
+// IsTimeout returns a boolean indicating whether the error is caused by
+// a timeout waiting for the operation to complete.
+func IsTimeout(err error) bool {
+	err = getInnerError(err)
+	return err == ErrTimeout
+}
+
+// IsAlreadyStopped returns a boolean indicating whether the error is caused by
+// a Container or Process being already stopped.
+// Note: Currently, ErrElementNotFound can mean that a Process has either
+// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
+// will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
+func IsAlreadyStopped(err error) bool {
+	err = getInnerError(err)
+	return err == ErrVmcomputeAlreadyStopped ||
+		err == ErrElementNotFound ||
+		err == ErrProcNotFound
+}
+
+// IsNotSupported returns a boolean indicating whether the error is caused by
+// unsupported platform requests
+// Note: Currently Unsupported platform requests can be mean either
+// ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
+// is thrown from the Platform
+func IsNotSupported(err error) bool {
+	err = getInnerError(err)
+	// If Platform doesn't recognize or support the request sent, below errors are seen
+	return err == ErrVmcomputeInvalidJSON ||
+		err == ErrInvalidData ||
+		err == ErrNotSupported ||
+		err == ErrVmcomputeUnknownMessage
+}
+
+func getInnerError(err error) error {
+	switch pe := err.(type) {
+	case nil:
+		return nil
+	case *HcsError:
+		err = pe.Err
+	case *SystemError:
+		err = pe.Err
+	case *ProcessError:
+		err = pe.Err
+	}
+	return err
+}

+ 47 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/hcs.go

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

+ 386 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go

@@ -0,0 +1,386 @@
+package hcs
+
+import (
+	"encoding/json"
+	"io"
+	"sync"
+	"syscall"
+	"time"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"github.com/sirupsen/logrus"
+)
+
+// ContainerError is an error encountered in HCS
+type Process struct {
+	handleLock     sync.RWMutex
+	handle         hcsProcess
+	processID      int
+	system         *System
+	cachedPipes    *cachedPipes
+	callbackNumber uintptr
+}
+
+type cachedPipes struct {
+	stdIn  syscall.Handle
+	stdOut syscall.Handle
+	stdErr syscall.Handle
+}
+
+type processModifyRequest struct {
+	Operation   string
+	ConsoleSize *consoleSize `json:",omitempty"`
+	CloseHandle *closeHandle `json:",omitempty"`
+}
+
+type consoleSize struct {
+	Height uint16
+	Width  uint16
+}
+
+type closeHandle struct {
+	Handle string
+}
+
+type ProcessStatus struct {
+	ProcessID      uint32
+	Exited         bool
+	ExitCode       uint32
+	LastWaitResult int32
+}
+
+const (
+	stdIn  string = "StdIn"
+	stdOut string = "StdOut"
+	stdErr string = "StdErr"
+)
+
+const (
+	modifyConsoleSize string = "ConsoleSize"
+	modifyCloseHandle string = "CloseHandle"
+)
+
+// Pid returns the process ID of the process within the container.
+func (process *Process) Pid() int {
+	return process.processID
+}
+
+// SystemID returns the ID of the process's compute system.
+func (process *Process) SystemID() string {
+	return process.system.ID()
+}
+
+// Kill signals the process to terminate but does not wait for it to finish terminating.
+func (process *Process) Kill() error {
+	process.handleLock.RLock()
+	defer process.handleLock.RUnlock()
+	operation := "Kill"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if process.handle == 0 {
+		return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+	}
+
+	var resultp *uint16
+	err := hcsTerminateProcess(process.handle, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return makeProcessError(process, operation, err, events)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// Wait waits for the process to exit.
+func (process *Process) Wait() error {
+	operation := "Wait"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
+	if err != nil {
+		return makeProcessError(process, operation, err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// WaitTimeout waits for the process to exit or the duration to elapse. It returns
+// false if timeout occurs.
+func (process *Process) WaitTimeout(timeout time.Duration) error {
+	operation := "WaitTimeout"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, &timeout)
+	if err != nil {
+		return makeProcessError(process, operation, err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// ResizeConsole resizes the console of the process.
+func (process *Process) ResizeConsole(width, height uint16) error {
+	process.handleLock.RLock()
+	defer process.handleLock.RUnlock()
+	operation := "ResizeConsole"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if process.handle == 0 {
+		return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+	}
+
+	modifyRequest := processModifyRequest{
+		Operation: modifyConsoleSize,
+		ConsoleSize: &consoleSize{
+			Height: height,
+			Width:  width,
+		},
+	}
+
+	modifyRequestb, err := json.Marshal(modifyRequest)
+	if err != nil {
+		return err
+	}
+
+	modifyRequestStr := string(modifyRequestb)
+
+	var resultp *uint16
+	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return makeProcessError(process, operation, err, events)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+func (process *Process) Properties() (*ProcessStatus, error) {
+	process.handleLock.RLock()
+	defer process.handleLock.RUnlock()
+	operation := "Properties"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if process.handle == 0 {
+		return nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
+	}
+
+	var (
+		resultp     *uint16
+		propertiesp *uint16
+	)
+	err := hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return nil, makeProcessError(process, operation, err, events)
+	}
+
+	if propertiesp == nil {
+		return nil, ErrUnexpectedValue
+	}
+	propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
+
+	properties := &ProcessStatus{}
+	if err := json.Unmarshal(propertiesRaw, properties); err != nil {
+		return nil, makeProcessError(process, operation, err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d, properties=%s", process.processID, propertiesRaw)
+	return properties, nil
+}
+
+// ExitCode returns the exit code of the process. The process must have
+// already terminated.
+func (process *Process) ExitCode() (int, error) {
+	operation := "ExitCode"
+	properties, err := process.Properties()
+	if err != nil {
+		return 0, makeProcessError(process, operation, err, nil)
+	}
+
+	if properties.Exited == false {
+		return 0, makeProcessError(process, operation, ErrInvalidProcessState, nil)
+	}
+
+	if properties.LastWaitResult != 0 {
+		return 0, makeProcessError(process, operation, syscall.Errno(properties.LastWaitResult), nil)
+	}
+
+	return int(properties.ExitCode), nil
+}
+
+// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
+// these pipes does not close the underlying pipes; it should be possible to
+// call this multiple times to get multiple interfaces.
+func (process *Process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
+	process.handleLock.RLock()
+	defer process.handleLock.RUnlock()
+	operation := "Stdio"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if process.handle == 0 {
+		return nil, nil, nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
+	}
+
+	var stdIn, stdOut, stdErr syscall.Handle
+
+	if process.cachedPipes == nil {
+		var (
+			processInfo hcsProcessInformation
+			resultp     *uint16
+		)
+		err := hcsGetProcessInfo(process.handle, &processInfo, &resultp)
+		events := processHcsResult(resultp)
+		if err != nil {
+			return nil, nil, nil, makeProcessError(process, operation, err, events)
+		}
+
+		stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError
+	} else {
+		// Use cached pipes
+		stdIn, stdOut, stdErr = process.cachedPipes.stdIn, process.cachedPipes.stdOut, process.cachedPipes.stdErr
+
+		// Invalidate the cache
+		process.cachedPipes = nil
+	}
+
+	pipes, err := makeOpenFiles([]syscall.Handle{stdIn, stdOut, stdErr})
+	if err != nil {
+		return nil, nil, nil, makeProcessError(process, operation, err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return pipes[0], pipes[1], pipes[2], nil
+}
+
+// CloseStdin closes the write side of the stdin pipe so that the process is
+// notified on the read side that there is no more data in stdin.
+func (process *Process) CloseStdin() error {
+	process.handleLock.RLock()
+	defer process.handleLock.RUnlock()
+	operation := "CloseStdin"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	if process.handle == 0 {
+		return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+	}
+
+	modifyRequest := processModifyRequest{
+		Operation: modifyCloseHandle,
+		CloseHandle: &closeHandle{
+			Handle: stdIn,
+		},
+	}
+
+	modifyRequestb, err := json.Marshal(modifyRequest)
+	if err != nil {
+		return err
+	}
+
+	modifyRequestStr := string(modifyRequestb)
+
+	var resultp *uint16
+	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return makeProcessError(process, operation, err, events)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+// Close cleans up any state associated with the process but does not kill
+// or wait on it.
+func (process *Process) Close() error {
+	process.handleLock.Lock()
+	defer process.handleLock.Unlock()
+	operation := "Close"
+	title := "hcsshim::Process::" + operation
+	logrus.Debugf(title+" processid=%d", process.processID)
+
+	// Don't double free this
+	if process.handle == 0 {
+		return nil
+	}
+
+	if err := process.unregisterCallback(); err != nil {
+		return makeProcessError(process, operation, err, nil)
+	}
+
+	if err := hcsCloseProcess(process.handle); err != nil {
+		return makeProcessError(process, operation, err, nil)
+	}
+
+	process.handle = 0
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return nil
+}
+
+func (process *Process) registerCallback() error {
+	context := &notifcationWatcherContext{
+		channels: newChannels(),
+	}
+
+	callbackMapLock.Lock()
+	callbackNumber := nextCallback
+	nextCallback++
+	callbackMap[callbackNumber] = context
+	callbackMapLock.Unlock()
+
+	var callbackHandle hcsCallback
+	err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
+	if err != nil {
+		return err
+	}
+	context.handle = callbackHandle
+	process.callbackNumber = callbackNumber
+
+	return nil
+}
+
+func (process *Process) unregisterCallback() error {
+	callbackNumber := process.callbackNumber
+
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
+
+	if context == nil {
+		return nil
+	}
+
+	handle := context.handle
+
+	if handle == 0 {
+		return nil
+	}
+
+	// hcsUnregisterProcessCallback has its own syncronization
+	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
+	err := hcsUnregisterProcessCallback(handle)
+	if err != nil {
+		return err
+	}
+
+	closeChannels(context.channels)
+
+	callbackMapLock.Lock()
+	callbackMap[callbackNumber] = nil
+	callbackMapLock.Unlock()
+
+	handle = 0
+
+	return nil
+}

+ 547 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go

@@ -0,0 +1,547 @@
+package hcs
+
+import (
+	"encoding/json"
+	"os"
+	"strconv"
+	"sync"
+	"syscall"
+	"time"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"github.com/Microsoft/hcsshim/internal/schema1"
+	"github.com/Microsoft/hcsshim/internal/timeout"
+	"github.com/sirupsen/logrus"
+)
+
+// currentContainerStarts is used to limit the number of concurrent container
+// starts.
+var currentContainerStarts containerStarts
+
+type containerStarts struct {
+	maxParallel int
+	inProgress  int
+	sync.Mutex
+}
+
+func init() {
+	mpsS := os.Getenv("HCSSHIM_MAX_PARALLEL_START")
+	if len(mpsS) > 0 {
+		mpsI, err := strconv.Atoi(mpsS)
+		if err != nil || mpsI < 0 {
+			return
+		}
+		currentContainerStarts.maxParallel = mpsI
+	}
+}
+
+type System struct {
+	handleLock     sync.RWMutex
+	handle         hcsSystem
+	id             string
+	callbackNumber uintptr
+}
+
+// CreateComputeSystem creates a new compute system with the given configuration but does not start it.
+func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (*System, error) {
+	operation := "CreateComputeSystem"
+	title := "hcsshim::" + operation
+
+	computeSystem := &System{
+		id: id,
+	}
+
+	hcsDocumentB, err := json.Marshal(hcsDocumentInterface)
+	if err != nil {
+		return nil, err
+	}
+
+	hcsDocument := string(hcsDocumentB)
+	logrus.Debugf(title+" ID=%s config=%s", id, hcsDocument)
+
+	var (
+		resultp  *uint16
+		identity syscall.Handle
+	)
+	createError := hcsCreateComputeSystem(id, hcsDocument, identity, &computeSystem.handle, &resultp)
+
+	if createError == nil || IsPending(createError) {
+		if err := computeSystem.registerCallback(); err != nil {
+			// Terminate the compute system if it still exists. We're okay to
+			// ignore a failure here.
+			computeSystem.Terminate()
+			return nil, makeSystemError(computeSystem, operation, "", err, nil)
+		}
+	}
+
+	events, err := processAsyncHcsResult(createError, resultp, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.Duration)
+	if err != nil {
+		if err == ErrTimeout {
+			// Terminate the compute system if it still exists. We're okay to
+			// ignore a failure here.
+			computeSystem.Terminate()
+		}
+		return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s handle=%d", id, computeSystem.handle)
+	return computeSystem, nil
+}
+
+// OpenComputeSystem opens an existing compute system by ID.
+func OpenComputeSystem(id string) (*System, error) {
+	operation := "OpenComputeSystem"
+	title := "hcsshim::" + operation
+	logrus.Debugf(title+" ID=%s", id)
+
+	computeSystem := &System{
+		id: id,
+	}
+
+	var (
+		handle  hcsSystem
+		resultp *uint16
+	)
+	err := hcsOpenComputeSystem(id, &handle, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return nil, makeSystemError(computeSystem, operation, "", err, events)
+	}
+
+	computeSystem.handle = handle
+
+	if err := computeSystem.registerCallback(); err != nil {
+		return nil, makeSystemError(computeSystem, operation, "", err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
+	return computeSystem, nil
+}
+
+// GetComputeSystems gets a list of the compute systems on the system that match the query
+func GetComputeSystems(q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) {
+	operation := "GetComputeSystems"
+	title := "hcsshim::" + operation
+
+	queryb, err := json.Marshal(q)
+	if err != nil {
+		return nil, err
+	}
+
+	query := string(queryb)
+	logrus.Debugf(title+" query=%s", query)
+
+	var (
+		resultp         *uint16
+		computeSystemsp *uint16
+	)
+	err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return nil, &HcsError{Op: operation, Err: err, Events: events}
+	}
+
+	if computeSystemsp == nil {
+		return nil, ErrUnexpectedValue
+	}
+	computeSystemsRaw := interop.ConvertAndFreeCoTaskMemBytes(computeSystemsp)
+	computeSystems := []schema1.ContainerProperties{}
+	if err := json.Unmarshal(computeSystemsRaw, &computeSystems); err != nil {
+		return nil, err
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return computeSystems, nil
+}
+
+// Start synchronously starts the computeSystem.
+func (computeSystem *System) Start() error {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::Start ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	if computeSystem.handle == 0 {
+		return makeSystemError(computeSystem, "Start", "", ErrAlreadyClosed, nil)
+	}
+
+	// This is a very simple backoff-retry loop to limit the number
+	// of parallel container starts if environment variable
+	// HCSSHIM_MAX_PARALLEL_START is set to a positive integer.
+	// It should generally only be used as a workaround to various
+	// platform issues that exist between RS1 and RS4 as of Aug 2018
+	if currentContainerStarts.maxParallel > 0 {
+		for {
+			currentContainerStarts.Lock()
+			if currentContainerStarts.inProgress < currentContainerStarts.maxParallel {
+				currentContainerStarts.inProgress++
+				currentContainerStarts.Unlock()
+				break
+			}
+			if currentContainerStarts.inProgress == currentContainerStarts.maxParallel {
+				currentContainerStarts.Unlock()
+				time.Sleep(100 * time.Millisecond)
+			}
+		}
+		// Make sure we decrement the count when we are done.
+		defer func() {
+			currentContainerStarts.Lock()
+			currentContainerStarts.inProgress--
+			currentContainerStarts.Unlock()
+		}()
+	}
+
+	var resultp *uint16
+	err := hcsStartComputeSystem(computeSystem.handle, "", &resultp)
+	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.Duration)
+	if err != nil {
+		return makeSystemError(computeSystem, "Start", "", err, events)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+// ID returns the compute system's identifier.
+func (computeSystem *System) ID() string {
+	return computeSystem.id
+}
+
+// Shutdown requests a compute system shutdown, if IsPending() on the error returned is true,
+// it may not actually be shut down until Wait() succeeds.
+func (computeSystem *System) Shutdown() error {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::Shutdown"
+	logrus.Debugf(title)
+	if computeSystem.handle == 0 {
+		return makeSystemError(computeSystem, "Shutdown", "", ErrAlreadyClosed, nil)
+	}
+
+	var resultp *uint16
+	err := hcsShutdownComputeSystem(computeSystem.handle, "", &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return makeSystemError(computeSystem, "Shutdown", "", err, events)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+// Terminate requests a compute system terminate, if IsPending() on the error returned is true,
+// it may not actually be shut down until Wait() succeeds.
+func (computeSystem *System) Terminate() error {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::Terminate ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	if computeSystem.handle == 0 {
+		return makeSystemError(computeSystem, "Terminate", "", ErrAlreadyClosed, nil)
+	}
+
+	var resultp *uint16
+	err := hcsTerminateComputeSystem(computeSystem.handle, "", &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return makeSystemError(computeSystem, "Terminate", "", err, events)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+// Wait synchronously waits for the compute system to shutdown or terminate.
+func (computeSystem *System) Wait() error {
+	title := "hcsshim::ComputeSystem::Wait ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	err := waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
+	if err != nil {
+		return makeSystemError(computeSystem, "Wait", "", err, nil)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+// WaitTimeout synchronously waits for the compute system to terminate or the duration to elapse.
+// If the timeout expires, IsTimeout(err) == true
+func (computeSystem *System) WaitTimeout(timeout time.Duration) error {
+	title := "hcsshim::ComputeSystem::WaitTimeout ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	err := waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, &timeout)
+	if err != nil {
+		return makeSystemError(computeSystem, "WaitTimeout", "", err, nil)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+func (computeSystem *System) Properties(types ...schema1.PropertyType) (*schema1.ContainerProperties, error) {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+
+	queryj, err := json.Marshal(schema1.PropertyQuery{types})
+	if err != nil {
+		return nil, makeSystemError(computeSystem, "Properties", "", err, nil)
+	}
+
+	var resultp, propertiesp *uint16
+	err = hcsGetComputeSystemProperties(computeSystem.handle, string(queryj), &propertiesp, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return nil, makeSystemError(computeSystem, "Properties", "", err, events)
+	}
+
+	if propertiesp == nil {
+		return nil, ErrUnexpectedValue
+	}
+	propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
+	properties := &schema1.ContainerProperties{}
+	if err := json.Unmarshal(propertiesRaw, properties); err != nil {
+		return nil, makeSystemError(computeSystem, "Properties", "", err, nil)
+	}
+	return properties, nil
+}
+
+// Pause pauses the execution of the computeSystem. This feature is not enabled in TP5.
+func (computeSystem *System) Pause() error {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::Pause ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	if computeSystem.handle == 0 {
+		return makeSystemError(computeSystem, "Pause", "", ErrAlreadyClosed, nil)
+	}
+
+	var resultp *uint16
+	err := hcsPauseComputeSystem(computeSystem.handle, "", &resultp)
+	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.Duration)
+	if err != nil {
+		return makeSystemError(computeSystem, "Pause", "", err, events)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+// Resume resumes the execution of the computeSystem. This feature is not enabled in TP5.
+func (computeSystem *System) Resume() error {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::Resume ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	if computeSystem.handle == 0 {
+		return makeSystemError(computeSystem, "Resume", "", ErrAlreadyClosed, nil)
+	}
+
+	var resultp *uint16
+	err := hcsResumeComputeSystem(computeSystem.handle, "", &resultp)
+	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.Duration)
+	if err != nil {
+		return makeSystemError(computeSystem, "Resume", "", err, events)
+	}
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+// CreateProcess launches a new process within the computeSystem.
+func (computeSystem *System) CreateProcess(c interface{}) (*Process, error) {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::CreateProcess ID=" + computeSystem.ID()
+	var (
+		processInfo   hcsProcessInformation
+		processHandle hcsProcess
+		resultp       *uint16
+	)
+
+	if computeSystem.handle == 0 {
+		return nil, makeSystemError(computeSystem, "CreateProcess", "", ErrAlreadyClosed, nil)
+	}
+
+	configurationb, err := json.Marshal(c)
+	if err != nil {
+		return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
+	}
+
+	configuration := string(configurationb)
+	logrus.Debugf(title+" config=%s", configuration)
+
+	err = hcsCreateProcess(computeSystem.handle, configuration, &processInfo, &processHandle, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return nil, makeSystemError(computeSystem, "CreateProcess", configuration, err, events)
+	}
+
+	process := &Process{
+		handle:    processHandle,
+		processID: int(processInfo.ProcessId),
+		system:    computeSystem,
+		cachedPipes: &cachedPipes{
+			stdIn:  processInfo.StdInput,
+			stdOut: processInfo.StdOutput,
+			stdErr: processInfo.StdError,
+		},
+	}
+
+	if err := process.registerCallback(); err != nil {
+		return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%d", process.processID)
+	return process, nil
+}
+
+// OpenProcess gets an interface to an existing process within the computeSystem.
+func (computeSystem *System) OpenProcess(pid int) (*Process, error) {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::ComputeSystem::OpenProcess ID=" + computeSystem.ID()
+	logrus.Debugf(title+" processid=%d", pid)
+	var (
+		processHandle hcsProcess
+		resultp       *uint16
+	)
+
+	if computeSystem.handle == 0 {
+		return nil, makeSystemError(computeSystem, "OpenProcess", "", ErrAlreadyClosed, nil)
+	}
+
+	err := hcsOpenProcess(computeSystem.handle, uint32(pid), &processHandle, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return nil, makeSystemError(computeSystem, "OpenProcess", "", err, events)
+	}
+
+	process := &Process{
+		handle:    processHandle,
+		processID: pid,
+		system:    computeSystem,
+	}
+
+	if err := process.registerCallback(); err != nil {
+		return nil, makeSystemError(computeSystem, "OpenProcess", "", err, nil)
+	}
+
+	logrus.Debugf(title+" succeeded processid=%s", process.processID)
+	return process, nil
+}
+
+// Close cleans up any state associated with the compute system but does not terminate or wait for it.
+func (computeSystem *System) Close() error {
+	computeSystem.handleLock.Lock()
+	defer computeSystem.handleLock.Unlock()
+	title := "hcsshim::ComputeSystem::Close ID=" + computeSystem.ID()
+	logrus.Debugf(title)
+
+	// Don't double free this
+	if computeSystem.handle == 0 {
+		return nil
+	}
+
+	if err := computeSystem.unregisterCallback(); err != nil {
+		return makeSystemError(computeSystem, "Close", "", err, nil)
+	}
+
+	if err := hcsCloseComputeSystem(computeSystem.handle); err != nil {
+		return makeSystemError(computeSystem, "Close", "", err, nil)
+	}
+
+	computeSystem.handle = 0
+
+	logrus.Debugf(title + " succeeded")
+	return nil
+}
+
+func (computeSystem *System) registerCallback() error {
+	context := &notifcationWatcherContext{
+		channels: newChannels(),
+	}
+
+	callbackMapLock.Lock()
+	callbackNumber := nextCallback
+	nextCallback++
+	callbackMap[callbackNumber] = context
+	callbackMapLock.Unlock()
+
+	var callbackHandle hcsCallback
+	err := hcsRegisterComputeSystemCallback(computeSystem.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
+	if err != nil {
+		return err
+	}
+	context.handle = callbackHandle
+	computeSystem.callbackNumber = callbackNumber
+
+	return nil
+}
+
+func (computeSystem *System) unregisterCallback() error {
+	callbackNumber := computeSystem.callbackNumber
+
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
+
+	if context == nil {
+		return nil
+	}
+
+	handle := context.handle
+
+	if handle == 0 {
+		return nil
+	}
+
+	// hcsUnregisterComputeSystemCallback has its own syncronization
+	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
+	err := hcsUnregisterComputeSystemCallback(handle)
+	if err != nil {
+		return err
+	}
+
+	closeChannels(context.channels)
+
+	callbackMapLock.Lock()
+	callbackMap[callbackNumber] = nil
+	callbackMapLock.Unlock()
+
+	handle = 0
+
+	return nil
+}
+
+// Modifies the System by sending a request to HCS
+func (computeSystem *System) Modify(config interface{}) error {
+	computeSystem.handleLock.RLock()
+	defer computeSystem.handleLock.RUnlock()
+	title := "hcsshim::Modify ID=" + computeSystem.id
+
+	if computeSystem.handle == 0 {
+		return makeSystemError(computeSystem, "Modify", "", ErrAlreadyClosed, nil)
+	}
+
+	requestJSON, err := json.Marshal(config)
+	if err != nil {
+		return err
+	}
+
+	requestString := string(requestJSON)
+	logrus.Debugf(title + " " + requestString)
+
+	var resultp *uint16
+	err = hcsModifyComputeSystem(computeSystem.handle, requestString, &resultp)
+	events := processHcsResult(resultp)
+	if err != nil {
+		return makeSystemError(computeSystem, "Modify", requestString, err, events)
+	}
+	logrus.Debugf(title + " succeeded ")
+	return nil
+}

+ 1 - 1
vendor/github.com/Microsoft/hcsshim/utils.go → vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go

@@ -1,4 +1,4 @@
-package hcsshim
+package hcs
 
 import (
 	"io"

+ 5 - 5
vendor/github.com/Microsoft/hcsshim/waithelper.go → vendor/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go

@@ -1,4 +1,4 @@
-package hcsshim
+package hcs
 
 import (
 	"time"
@@ -6,13 +6,13 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
-	err = processHcsResult(err, resultp)
+func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
+	events := processHcsResult(resultp)
 	if IsPending(err) {
-		return waitForNotification(callbackNumber, expectedNotification, timeout)
+		return nil, waitForNotification(callbackNumber, expectedNotification, timeout)
 	}
 
-	return err
+	return events, err
 }
 
 func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {

+ 441 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/zsyscall_windows.go

@@ -0,0 +1,441 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package hcs
+
+import (
+	"syscall"
+	"unsafe"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+
+	procHcsEnumerateComputeSystems         = modvmcompute.NewProc("HcsEnumerateComputeSystems")
+	procHcsCreateComputeSystem             = modvmcompute.NewProc("HcsCreateComputeSystem")
+	procHcsOpenComputeSystem               = modvmcompute.NewProc("HcsOpenComputeSystem")
+	procHcsCloseComputeSystem              = modvmcompute.NewProc("HcsCloseComputeSystem")
+	procHcsStartComputeSystem              = modvmcompute.NewProc("HcsStartComputeSystem")
+	procHcsShutdownComputeSystem           = modvmcompute.NewProc("HcsShutdownComputeSystem")
+	procHcsTerminateComputeSystem          = modvmcompute.NewProc("HcsTerminateComputeSystem")
+	procHcsPauseComputeSystem              = modvmcompute.NewProc("HcsPauseComputeSystem")
+	procHcsResumeComputeSystem             = modvmcompute.NewProc("HcsResumeComputeSystem")
+	procHcsGetComputeSystemProperties      = modvmcompute.NewProc("HcsGetComputeSystemProperties")
+	procHcsModifyComputeSystem             = modvmcompute.NewProc("HcsModifyComputeSystem")
+	procHcsRegisterComputeSystemCallback   = modvmcompute.NewProc("HcsRegisterComputeSystemCallback")
+	procHcsUnregisterComputeSystemCallback = modvmcompute.NewProc("HcsUnregisterComputeSystemCallback")
+	procHcsCreateProcess                   = modvmcompute.NewProc("HcsCreateProcess")
+	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")
+)
+
+func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(query)
+	if hr != nil {
+		return
+	}
+	return _hcsEnumerateComputeSystems(_p0, computeSystems, result)
+}
+
+func _hcsEnumerateComputeSystems(query *uint16, computeSystems **uint16, result **uint16) (hr error) {
+	if hr = procHcsEnumerateComputeSystems.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsEnumerateComputeSystems.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(computeSystems)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(configuration)
+	if hr != nil {
+		return
+	}
+	return _hcsCreateComputeSystem(_p0, _p1, identity, computeSystem, result)
+}
+
+func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
+	if hr = procHcsCreateComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsCreateComputeSystem.Addr(), 5, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), uintptr(identity), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _hcsOpenComputeSystem(_p0, computeSystem, result)
+}
+
+func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
+	if hr = procHcsOpenComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsOpenComputeSystem.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
+	if hr = procHcsCloseComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsCloseComputeSystem.Addr(), 1, uintptr(computeSystem), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsStartComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsStartComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsStartComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsShutdownComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsShutdownComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsTerminateComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsTerminateComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsPauseComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsPauseComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsPauseComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(options)
+	if hr != nil {
+		return
+	}
+	return _hcsResumeComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+	if hr = procHcsResumeComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsResumeComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
+	if hr != nil {
+		return
+	}
+	return _hcsGetComputeSystemProperties(computeSystem, _p0, properties, result)
+}
+
+func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
+	if hr = procHcsGetComputeSystemProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsGetComputeSystemProperties.Addr(), 4, uintptr(computeSystem), uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(configuration)
+	if hr != nil {
+		return
+	}
+	return _hcsModifyComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, result **uint16) (hr error) {
+	if hr = procHcsModifyComputeSystem.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsModifyComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(configuration)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
+	if hr = procHcsRegisterComputeSystemCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsRegisterComputeSystemCallback.Addr(), 4, uintptr(computeSystem), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
+	if hr = procHcsUnregisterComputeSystemCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsUnregisterComputeSystemCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(processParameters)
+	if hr != nil {
+		return
+	}
+	return _hcsCreateProcess(computeSystem, _p0, processInformation, process, result)
+}
+
+func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
+	if hr = procHcsCreateProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsCreateProcess.Addr(), 5, uintptr(computeSystem), uintptr(unsafe.Pointer(processParameters)), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) {
+	if hr = procHcsOpenProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsOpenProcess.Addr(), 4, uintptr(computeSystem), uintptr(pid), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsCloseProcess(process hcsProcess) (hr error) {
+	if hr = procHcsCloseProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsCloseProcess.Addr(), 1, uintptr(process), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
+	if hr = procHcsTerminateProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 2, uintptr(process), uintptr(unsafe.Pointer(result)), 0)
+	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
+	}
+	r0, _, _ := syscall.Syscall(procHcsGetProcessInfo.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) {
+	if hr = procHcsGetProcessProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsGetProcessProperties.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processProperties)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(settings)
+	if hr != nil {
+		return
+	}
+	return _hcsModifyProcess(process, _p0, result)
+}
+
+func _hcsModifyProcess(process hcsProcess, settings *uint16, result **uint16) (hr error) {
+	if hr = procHcsModifyProcess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsModifyProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
+	if hr != nil {
+		return
+	}
+	return _hcsGetServiceProperties(_p0, properties, result)
+}
+
+func _hcsGetServiceProperties(propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
+	if hr = procHcsGetServiceProperties.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsGetServiceProperties.Addr(), 3, uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
+	if hr = procHcsRegisterProcessCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHcsRegisterProcessCallback.Addr(), 4, uintptr(process), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) {
+	if hr = procHcsUnregisterProcessCallback.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procHcsUnregisterProcessCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}

+ 51 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcserror/hcserror.go

@@ -0,0 +1,51 @@
+package hcserror
+
+import (
+	"fmt"
+	"syscall"
+)
+
+const ERROR_GEN_FAILURE = syscall.Errno(31)
+
+type HcsError struct {
+	title string
+	rest  string
+	Err   error
+}
+
+func (e *HcsError) Error() string {
+	s := e.title
+	if len(s) > 0 && s[len(s)-1] != ' ' {
+		s += " "
+	}
+	s += fmt.Sprintf("failed in Win32: %s (0x%x)", e.Err, Win32FromError(e.Err))
+	if e.rest != "" {
+		if e.rest[0] != ' ' {
+			s += " "
+		}
+		s += e.rest
+	}
+	return s
+}
+
+func New(err error, title, rest string) error {
+	// Pass through DLL errors directly since they do not originate from HCS.
+	if _, ok := err.(*syscall.DLLError); ok {
+		return err
+	}
+	return &HcsError{title, rest, err}
+}
+
+func Errorf(err error, title, format string, a ...interface{}) error {
+	return New(err, title, fmt.Sprintf(format, a...))
+}
+
+func Win32FromError(err error) uint32 {
+	if herr, ok := err.(*HcsError); ok {
+		return Win32FromError(herr.Err)
+	}
+	if code, ok := err.(syscall.Errno); ok {
+		return uint32(code)
+	}
+	return uint32(ERROR_GEN_FAILURE)
+}

+ 23 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hns.go

@@ -0,0 +1,23 @@
+package hns
+
+import "fmt"
+
+//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go hns.go
+
+//sys _hnsCall(method string, path string, object string, response **uint16) (hr error) = vmcompute.HNSCall?
+
+type EndpointNotFoundError struct {
+	EndpointName string
+}
+
+func (e EndpointNotFoundError) Error() string {
+	return fmt.Sprintf("Endpoint %s not found", e.EndpointName)
+}
+
+type NetworkNotFoundError struct {
+	NetworkName string
+}
+
+func (e NetworkNotFoundError) Error() string {
+	return fmt.Sprintf("Network %s not found", e.NetworkName)
+}

+ 260 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsendpoint.go

@@ -0,0 +1,260 @@
+package hns
+
+import (
+	"encoding/json"
+	"net"
+
+	"github.com/sirupsen/logrus"
+)
+
+// HNSEndpoint represents a network endpoint in HNS
+type HNSEndpoint struct {
+	Id                 string            `json:"ID,omitempty"`
+	Name               string            `json:",omitempty"`
+	VirtualNetwork     string            `json:",omitempty"`
+	VirtualNetworkName string            `json:",omitempty"`
+	Policies           []json.RawMessage `json:",omitempty"`
+	MacAddress         string            `json:",omitempty"`
+	IPAddress          net.IP            `json:",omitempty"`
+	DNSSuffix          string            `json:",omitempty"`
+	DNSServerList      string            `json:",omitempty"`
+	GatewayAddress     string            `json:",omitempty"`
+	EnableInternalDNS  bool              `json:",omitempty"`
+	DisableICC         bool              `json:",omitempty"`
+	PrefixLength       uint8             `json:",omitempty"`
+	IsRemoteEndpoint   bool              `json:",omitempty"`
+	Namespace          *Namespace        `json:",omitempty"`
+}
+
+//SystemType represents the type of the system on which actions are done
+type SystemType string
+
+// SystemType const
+const (
+	ContainerType      SystemType = "Container"
+	VirtualMachineType SystemType = "VirtualMachine"
+	HostType           SystemType = "Host"
+)
+
+// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
+// Supported resource types are Network and Request Types are Add/Remove
+type EndpointAttachDetachRequest struct {
+	ContainerID    string     `json:"ContainerId,omitempty"`
+	SystemType     SystemType `json:"SystemType"`
+	CompartmentID  uint16     `json:"CompartmentId,omitempty"`
+	VirtualNICName string     `json:"VirtualNicName,omitempty"`
+}
+
+// EndpointResquestResponse is object to get the endpoint request response
+type EndpointResquestResponse struct {
+	Success bool
+	Error   string
+}
+
+// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
+func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
+	endpoint := &HNSEndpoint{}
+	err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
+	if err != nil {
+		return nil, err
+	}
+
+	return endpoint, nil
+}
+
+// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
+func HNSListEndpointRequest() ([]HNSEndpoint, error) {
+	var endpoint []HNSEndpoint
+	err := hnsCall("GET", "/endpoints/", "", &endpoint)
+	if err != nil {
+		return nil, err
+	}
+
+	return endpoint, nil
+}
+
+// GetHNSEndpointByID get the Endpoint by ID
+func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
+	return HNSEndpointRequest("GET", endpointID, "")
+}
+
+// GetHNSEndpointByName gets the endpoint filtered by Name
+func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
+	hnsResponse, err := HNSListEndpointRequest()
+	if err != nil {
+		return nil, err
+	}
+	for _, hnsEndpoint := range hnsResponse {
+		if hnsEndpoint.Name == endpointName {
+			return &hnsEndpoint, nil
+		}
+	}
+	return nil, EndpointNotFoundError{EndpointName: endpointName}
+}
+
+// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
+func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
+	operation := "Create"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	jsonString, err := json.Marshal(endpoint)
+	if err != nil {
+		return nil, err
+	}
+	return HNSEndpointRequest("POST", "", string(jsonString))
+}
+
+// Delete Endpoint by sending EndpointRequest to HNS
+func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
+	operation := "Delete"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	return HNSEndpointRequest("DELETE", endpoint.Id, "")
+}
+
+// Update Endpoint
+func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
+	operation := "Update"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	jsonString, err := json.Marshal(endpoint)
+	if err != nil {
+		return nil, err
+	}
+	err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
+
+	return endpoint, err
+}
+
+// ApplyACLPolicy applies a set of ACL Policies on the Endpoint
+func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
+	operation := "ApplyACLPolicy"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	for _, policy := range policies {
+		if policy == nil {
+			continue
+		}
+		jsonString, err := json.Marshal(policy)
+		if err != nil {
+			return err
+		}
+		endpoint.Policies = append(endpoint.Policies, jsonString)
+	}
+
+	_, err := endpoint.Update()
+	return err
+}
+
+// ContainerAttach attaches an endpoint to container
+func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
+	operation := "ContainerAttach"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	requestMessage := &EndpointAttachDetachRequest{
+		ContainerID:   containerID,
+		CompartmentID: compartmentID,
+		SystemType:    ContainerType,
+	}
+	response := &EndpointResquestResponse{}
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// ContainerDetach detaches an endpoint from container
+func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
+	operation := "ContainerDetach"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	requestMessage := &EndpointAttachDetachRequest{
+		ContainerID: containerID,
+		SystemType:  ContainerType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// HostAttach attaches a nic on the host
+func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
+	operation := "HostAttach"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	requestMessage := &EndpointAttachDetachRequest{
+		CompartmentID: compartmentID,
+		SystemType:    HostType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+
+}
+
+// HostDetach detaches a nic on the host
+func (endpoint *HNSEndpoint) HostDetach() error {
+	operation := "HostDetach"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	requestMessage := &EndpointAttachDetachRequest{
+		SystemType: HostType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// VirtualMachineNICAttach attaches a endpoint to a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
+	operation := "VirtualMachineNicAttach"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+	requestMessage := &EndpointAttachDetachRequest{
+		VirtualNICName: virtualMachineNICName,
+		SystemType:     VirtualMachineType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// VirtualMachineNICDetach detaches a endpoint  from a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
+	operation := "VirtualMachineNicDetach"
+	title := "hcsshim::HNSEndpoint::" + operation
+	logrus.Debugf(title+" id=%s", endpoint.Id)
+
+	requestMessage := &EndpointAttachDetachRequest{
+		SystemType: VirtualMachineType,
+	}
+	response := &EndpointResquestResponse{}
+
+	jsonString, err := json.Marshal(requestMessage)
+	if err != nil {
+		return err
+	}
+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}

+ 5 - 3
vendor/github.com/Microsoft/hcsshim/hnsfuncs.go → vendor/github.com/Microsoft/hcsshim/internal/hns/hnsfuncs.go

@@ -1,9 +1,11 @@
-package hcsshim
+package hns
 
 import (
 	"encoding/json"
 	"fmt"
 
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/interop"
 	"github.com/sirupsen/logrus"
 )
 
@@ -13,9 +15,9 @@ func hnsCall(method, path, request string, returnResponse interface{}) error {
 
 	err := _hnsCall(method, path, request, &responseBuffer)
 	if err != nil {
-		return makeError(err, "hnsCall ", "")
+		return hcserror.New(err, "hnsCall ", "")
 	}
-	response := convertAndFreeCoTaskMemString(responseBuffer)
+	response := interop.ConvertAndFreeCoTaskMemString(responseBuffer)
 
 	hnsresponse := &hnsResponse{}
 	if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {

+ 28 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsglobals.go

@@ -0,0 +1,28 @@
+package hns
+
+type HNSGlobals struct {
+	Version HNSVersion `json:"Version"`
+}
+
+type HNSVersion struct {
+	Major int `json:"Major"`
+	Minor int `json:"Minor"`
+}
+
+var (
+	HNSVersion1803 = HNSVersion{Major: 7, Minor: 2}
+)
+
+func GetHNSGlobals() (*HNSGlobals, error) {
+	var version HNSVersion
+	err := hnsCall("GET", "/globals/version", "", &version)
+	if err != nil {
+		return nil, err
+	}
+
+	globals := &HNSGlobals{
+		Version: version,
+	}
+
+	return globals, nil
+}

+ 141 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsnetwork.go

@@ -0,0 +1,141 @@
+package hns
+
+import (
+	"encoding/json"
+	"net"
+
+	"github.com/sirupsen/logrus"
+)
+
+// Subnet is assoicated with a network and represents a list
+// of subnets available to the network
+type Subnet struct {
+	AddressPrefix  string            `json:",omitempty"`
+	GatewayAddress string            `json:",omitempty"`
+	Policies       []json.RawMessage `json:",omitempty"`
+}
+
+// MacPool is assoicated with a network and represents a list
+// of macaddresses available to the network
+type MacPool struct {
+	StartMacAddress string `json:",omitempty"`
+	EndMacAddress   string `json:",omitempty"`
+}
+
+// HNSNetwork represents a network in HNS
+type HNSNetwork struct {
+	Id                   string            `json:"ID,omitempty"`
+	Name                 string            `json:",omitempty"`
+	Type                 string            `json:",omitempty"`
+	NetworkAdapterName   string            `json:",omitempty"`
+	SourceMac            string            `json:",omitempty"`
+	Policies             []json.RawMessage `json:",omitempty"`
+	MacPools             []MacPool         `json:",omitempty"`
+	Subnets              []Subnet          `json:",omitempty"`
+	DNSSuffix            string            `json:",omitempty"`
+	DNSServerList        string            `json:",omitempty"`
+	DNSServerCompartment uint32            `json:",omitempty"`
+	ManagementIP         string            `json:",omitempty"`
+	AutomaticDNS         bool              `json:",omitempty"`
+}
+
+type hnsNetworkResponse struct {
+	Success bool
+	Error   string
+	Output  HNSNetwork
+}
+
+type hnsResponse struct {
+	Success bool
+	Error   string
+	Output  json.RawMessage
+}
+
+// HNSNetworkRequest makes a call into HNS to update/query a single network
+func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
+	var network HNSNetwork
+	err := hnsCall(method, "/networks/"+path, request, &network)
+	if err != nil {
+		return nil, err
+	}
+
+	return &network, nil
+}
+
+// HNSListNetworkRequest makes a HNS call to query the list of available networks
+func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
+	var network []HNSNetwork
+	err := hnsCall(method, "/networks/"+path, request, &network)
+	if err != nil {
+		return nil, err
+	}
+
+	return network, nil
+}
+
+// GetHNSNetworkByID
+func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
+	return HNSNetworkRequest("GET", networkID, "")
+}
+
+// GetHNSNetworkName filtered by Name
+func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
+	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
+	if err != nil {
+		return nil, err
+	}
+	for _, hnsnetwork := range hsnnetworks {
+		if hnsnetwork.Name == networkName {
+			return &hnsnetwork, nil
+		}
+	}
+	return nil, NetworkNotFoundError{NetworkName: networkName}
+}
+
+// Create Network by sending NetworkRequest to HNS.
+func (network *HNSNetwork) Create() (*HNSNetwork, error) {
+	operation := "Create"
+	title := "hcsshim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s", network.Id)
+
+	jsonString, err := json.Marshal(network)
+	if err != nil {
+		return nil, err
+	}
+	return HNSNetworkRequest("POST", "", string(jsonString))
+}
+
+// Delete Network by sending NetworkRequest to HNS
+func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
+	operation := "Delete"
+	title := "hcsshim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s", network.Id)
+
+	return HNSNetworkRequest("DELETE", network.Id, "")
+}
+
+// Creates an endpoint on the Network.
+func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
+	return &HNSEndpoint{
+		VirtualNetwork: network.Id,
+		IPAddress:      ipAddress,
+		MacAddress:     string(macAddress),
+	}
+}
+
+func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+	operation := "CreateEndpoint"
+	title := "hcsshim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
+
+	endpoint.VirtualNetwork = network.Id
+	return endpoint.Create()
+}
+
+func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+	operation := "CreateRemoteEndpoint"
+	title := "hcsshim::HNSNetwork::" + operation
+	logrus.Debugf(title+" id=%s", network.Id)
+	endpoint.IsRemoteEndpoint = true
+	return network.CreateEndpoint(endpoint)
+}

+ 98 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go

@@ -0,0 +1,98 @@
+package hns
+
+// Type of Request Support in ModifySystem
+type PolicyType string
+
+// RequestType const
+const (
+	Nat                  PolicyType = "NAT"
+	ACL                  PolicyType = "ACL"
+	PA                   PolicyType = "PA"
+	VLAN                 PolicyType = "VLAN"
+	VSID                 PolicyType = "VSID"
+	VNet                 PolicyType = "VNET"
+	L2Driver             PolicyType = "L2Driver"
+	Isolation            PolicyType = "Isolation"
+	QOS                  PolicyType = "QOS"
+	OutboundNat          PolicyType = "OutBoundNAT"
+	ExternalLoadBalancer PolicyType = "ELB"
+	Route                PolicyType = "ROUTE"
+)
+
+type NatPolicy struct {
+	Type         PolicyType `json:"Type"`
+	Protocol     string
+	InternalPort uint16
+	ExternalPort uint16
+}
+
+type QosPolicy struct {
+	Type                            PolicyType `json:"Type"`
+	MaximumOutgoingBandwidthInBytes uint64
+}
+
+type IsolationPolicy struct {
+	Type               PolicyType `json:"Type"`
+	VLAN               uint
+	VSID               uint
+	InDefaultIsolation bool
+}
+
+type VlanPolicy struct {
+	Type PolicyType `json:"Type"`
+	VLAN uint
+}
+
+type VsidPolicy struct {
+	Type PolicyType `json:"Type"`
+	VSID uint
+}
+
+type PaPolicy struct {
+	Type PolicyType `json:"Type"`
+	PA   string     `json:"PA"`
+}
+
+type OutboundNatPolicy struct {
+	Policy
+	VIP        string   `json:"VIP,omitempty"`
+	Exceptions []string `json:"ExceptionList,omitempty"`
+}
+
+type ActionType string
+type DirectionType string
+type RuleType string
+
+const (
+	Allow ActionType = "Allow"
+	Block ActionType = "Block"
+
+	In  DirectionType = "In"
+	Out DirectionType = "Out"
+
+	Host   RuleType = "Host"
+	Switch RuleType = "Switch"
+)
+
+type ACLPolicy struct {
+	Type            PolicyType `json:"Type"`
+	Id              string     `json:"Id,omitempty"`
+	Protocol        uint16
+	Protocols       string `json:"Protocols,omitempty"`
+	InternalPort    uint16
+	Action          ActionType
+	Direction       DirectionType
+	LocalAddresses  string
+	RemoteAddresses string
+	LocalPorts      string `json:"LocalPorts,omitempty"`
+	LocalPort       uint16
+	RemotePorts     string `json:"RemotePorts,omitempty"`
+	RemotePort      uint16
+	RuleType        RuleType `json:"RuleType,omitempty"`
+	Priority        uint16
+	ServiceName     string
+}
+
+type Policy struct {
+	Type PolicyType `json:"Type"`
+}

+ 200 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicylist.go

@@ -0,0 +1,200 @@
+package hns
+
+import (
+	"encoding/json"
+
+	"github.com/sirupsen/logrus"
+)
+
+// RoutePolicy is a structure defining schema for Route based Policy
+type RoutePolicy struct {
+	Policy
+	DestinationPrefix string `json:"DestinationPrefix,omitempty"`
+	NextHop           string `json:"NextHop,omitempty"`
+	EncapEnabled      bool   `json:"NeedEncap,omitempty"`
+}
+
+// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy
+type ELBPolicy struct {
+	LBPolicy
+	SourceVIP string   `json:"SourceVIP,omitempty"`
+	VIPs      []string `json:"VIPs,omitempty"`
+	ILB       bool     `json:"ILB,omitempty"`
+}
+
+// LBPolicy is a structure defining schema for LoadBalancing based Policy
+type LBPolicy struct {
+	Policy
+	Protocol     uint16 `json:"Protocol,omitempty"`
+	InternalPort uint16
+	ExternalPort uint16
+}
+
+// PolicyList is a structure defining schema for Policy list request
+type PolicyList struct {
+	ID                 string            `json:"ID,omitempty"`
+	EndpointReferences []string          `json:"References,omitempty"`
+	Policies           []json.RawMessage `json:"Policies,omitempty"`
+}
+
+// HNSPolicyListRequest makes a call into HNS to update/query a single network
+func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
+	var policy PolicyList
+	err := hnsCall(method, "/policylists/"+path, request, &policy)
+	if err != nil {
+		return nil, err
+	}
+
+	return &policy, nil
+}
+
+// HNSListPolicyListRequest gets all the policy list
+func HNSListPolicyListRequest() ([]PolicyList, error) {
+	var plist []PolicyList
+	err := hnsCall("GET", "/policylists/", "", &plist)
+	if err != nil {
+		return nil, err
+	}
+
+	return plist, nil
+}
+
+// PolicyListRequest makes a HNS call to modify/query a network policy list
+func PolicyListRequest(method, path, request string) (*PolicyList, error) {
+	policylist := &PolicyList{}
+	err := hnsCall(method, "/policylists/"+path, request, &policylist)
+	if err != nil {
+		return nil, err
+	}
+
+	return policylist, nil
+}
+
+// GetPolicyListByID get the policy list by ID
+func GetPolicyListByID(policyListID string) (*PolicyList, error) {
+	return PolicyListRequest("GET", policyListID, "")
+}
+
+// Create PolicyList by sending PolicyListRequest to HNS.
+func (policylist *PolicyList) Create() (*PolicyList, error) {
+	operation := "Create"
+	title := "hcsshim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s", policylist.ID)
+	jsonString, err := json.Marshal(policylist)
+	if err != nil {
+		return nil, err
+	}
+	return PolicyListRequest("POST", "", string(jsonString))
+}
+
+// Delete deletes PolicyList
+func (policylist *PolicyList) Delete() (*PolicyList, error) {
+	operation := "Delete"
+	title := "hcsshim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s", policylist.ID)
+
+	return PolicyListRequest("DELETE", policylist.ID, "")
+}
+
+// AddEndpoint add an endpoint to a Policy List
+func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+	operation := "AddEndpoint"
+	title := "hcsshim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+	_, err := policylist.Delete()
+	if err != nil {
+		return nil, err
+	}
+
+	// Add Endpoint to the Existing List
+	policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+
+	return policylist.Create()
+}
+
+// RemoveEndpoint removes an endpoint from the Policy List
+func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+	operation := "RemoveEndpoint"
+	title := "hcsshim::PolicyList::" + operation
+	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+	_, err := policylist.Delete()
+	if err != nil {
+		return nil, err
+	}
+
+	elementToRemove := "/endpoints/" + endpoint.Id
+
+	var references []string
+
+	for _, endpointReference := range policylist.EndpointReferences {
+		if endpointReference == elementToRemove {
+			continue
+		}
+		references = append(references, endpointReference)
+	}
+	policylist.EndpointReferences = references
+	return policylist.Create()
+}
+
+// AddLoadBalancer policy list for the specified endpoints
+func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
+	operation := "AddLoadBalancer"
+	title := "hcsshim::PolicyList::" + operation
+	logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
+
+	policylist := &PolicyList{}
+
+	elbPolicy := &ELBPolicy{
+		SourceVIP: sourceVIP,
+		ILB:       isILB,
+	}
+
+	if len(vip) > 0 {
+		elbPolicy.VIPs = []string{vip}
+	}
+	elbPolicy.Type = ExternalLoadBalancer
+	elbPolicy.Protocol = protocol
+	elbPolicy.InternalPort = internalPort
+	elbPolicy.ExternalPort = externalPort
+
+	for _, endpoint := range endpoints {
+		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+	}
+
+	jsonString, err := json.Marshal(elbPolicy)
+	if err != nil {
+		return nil, err
+	}
+	policylist.Policies = append(policylist.Policies, jsonString)
+	return policylist.Create()
+}
+
+// AddRoute adds route policy list for the specified endpoints
+func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
+	operation := "AddRoute"
+	title := "hcsshim::PolicyList::" + operation
+	logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
+
+	policylist := &PolicyList{}
+
+	rPolicy := &RoutePolicy{
+		DestinationPrefix: destinationPrefix,
+		NextHop:           nextHop,
+		EncapEnabled:      encapEnabled,
+	}
+	rPolicy.Type = Route
+
+	for _, endpoint := range endpoints {
+		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+	}
+
+	jsonString, err := json.Marshal(rPolicy)
+	if err != nil {
+		return nil, err
+	}
+
+	policylist.Policies = append(policylist.Policies, jsonString)
+	return policylist.Create()
+}

+ 49 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/hnssupport.go

@@ -0,0 +1,49 @@
+package hns
+
+import (
+	"github.com/sirupsen/logrus"
+)
+
+type HNSSupportedFeatures struct {
+	Acl HNSAclFeatures `json:"ACL"`
+}
+
+type HNSAclFeatures struct {
+	AclAddressLists       bool `json:"AclAddressLists"`
+	AclNoHostRulePriority bool `json:"AclHostRulePriority"`
+	AclPortRanges         bool `json:"AclPortRanges"`
+	AclRuleId             bool `json:"AclRuleId"`
+}
+
+func GetHNSSupportedFeatures() HNSSupportedFeatures {
+	var hnsFeatures HNSSupportedFeatures
+
+	globals, err := GetHNSGlobals()
+	if err != nil {
+		// Expected on pre-1803 builds, all features will be false/unsupported
+		logrus.Debugf("Unable to obtain HNS globals: %s", err)
+		return hnsFeatures
+	}
+
+	hnsFeatures.Acl = HNSAclFeatures{
+		AclAddressLists:       isHNSFeatureSupported(globals.Version, HNSVersion1803),
+		AclNoHostRulePriority: isHNSFeatureSupported(globals.Version, HNSVersion1803),
+		AclPortRanges:         isHNSFeatureSupported(globals.Version, HNSVersion1803),
+		AclRuleId:             isHNSFeatureSupported(globals.Version, HNSVersion1803),
+	}
+
+	return hnsFeatures
+}
+
+func isHNSFeatureSupported(currentVersion HNSVersion, minVersionSupported HNSVersion) bool {
+	if currentVersion.Major < minVersionSupported.Major {
+		return false
+	}
+	if currentVersion.Major > minVersionSupported.Major {
+		return true
+	}
+	if currentVersion.Minor < minVersionSupported.Minor {
+		return false
+	}
+	return true
+}

+ 110 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/namespace.go

@@ -0,0 +1,110 @@
+package hns
+
+import (
+	"encoding/json"
+	"fmt"
+	"os"
+	"path"
+	"strings"
+)
+
+type namespaceRequest struct {
+	IsDefault bool `json:",omitempty"`
+}
+
+type namespaceEndpointRequest struct {
+	ID string `json:"Id"`
+}
+
+type NamespaceResource struct {
+	Type string
+	Data json.RawMessage
+}
+
+type namespaceResourceRequest struct {
+	Type string
+	Data interface{}
+}
+
+type Namespace struct {
+	ID           string
+	IsDefault    bool                `json:",omitempty"`
+	ResourceList []NamespaceResource `json:",omitempty"`
+}
+
+func issueNamespaceRequest(id *string, method, subpath string, request interface{}) (*Namespace, error) {
+	var err error
+	hnspath := "/namespaces/"
+	if id != nil {
+		hnspath = path.Join(hnspath, *id)
+	}
+	if subpath != "" {
+		hnspath = path.Join(hnspath, subpath)
+	}
+	var reqJSON []byte
+	if request != nil {
+		if reqJSON, err = json.Marshal(request); err != nil {
+			return nil, err
+		}
+	}
+	var ns Namespace
+	err = hnsCall(method, hnspath, string(reqJSON), &ns)
+	if err != nil {
+		if strings.Contains(err.Error(), "Element not found.") {
+			return nil, os.ErrNotExist
+		}
+		return nil, fmt.Errorf("%s %s: %s", method, hnspath, err)
+	}
+	return &ns, err
+}
+
+func CreateNamespace() (string, error) {
+	req := namespaceRequest{}
+	ns, err := issueNamespaceRequest(nil, "POST", "", &req)
+	if err != nil {
+		return "", err
+	}
+	return ns.ID, nil
+}
+
+func RemoveNamespace(id string) error {
+	_, err := issueNamespaceRequest(&id, "DELETE", "", nil)
+	return err
+}
+
+func GetNamespaceEndpoints(id string) ([]string, error) {
+	ns, err := issueNamespaceRequest(&id, "GET", "", nil)
+	if err != nil {
+		return nil, err
+	}
+	var endpoints []string
+	for _, rsrc := range ns.ResourceList {
+		if rsrc.Type == "Endpoint" {
+			var endpoint namespaceEndpointRequest
+			err = json.Unmarshal(rsrc.Data, &endpoint)
+			if err != nil {
+				return nil, fmt.Errorf("unmarshal endpoint: %s", err)
+			}
+			endpoints = append(endpoints, endpoint.ID)
+		}
+	}
+	return endpoints, nil
+}
+
+func AddNamespaceEndpoint(id string, endpointID string) error {
+	resource := namespaceResourceRequest{
+		Type: "Endpoint",
+		Data: namespaceEndpointRequest{endpointID},
+	}
+	_, err := issueNamespaceRequest(&id, "POST", "addresource", &resource)
+	return err
+}
+
+func RemoveNamespaceEndpoint(id string, endpointID string) error {
+	resource := namespaceResourceRequest{
+		Type: "Endpoint",
+		Data: namespaceEndpointRequest{endpointID},
+	}
+	_, err := issueNamespaceRequest(&id, "POST", "removeresource", &resource)
+	return err
+}

+ 74 - 0
vendor/github.com/Microsoft/hcsshim/internal/hns/zsyscall_windows.go

@@ -0,0 +1,74 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package hns
+
+import (
+	"syscall"
+	"unsafe"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+
+	procHNSCall = modvmcompute.NewProc("HNSCall")
+)
+
+func _hnsCall(method string, path string, object string, response **uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(method)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(path)
+	if hr != nil {
+		return
+	}
+	var _p2 *uint16
+	_p2, hr = syscall.UTF16PtrFromString(object)
+	if hr != nil {
+		return
+	}
+	return __hnsCall(_p0, _p1, _p2, response)
+}
+
+func __hnsCall(method *uint16, path *uint16, object *uint16, response **uint16) (hr error) {
+	if hr = procHNSCall.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procHNSCall.Addr(), 4, uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}

+ 27 - 0
vendor/github.com/Microsoft/hcsshim/internal/interop/interop.go

@@ -0,0 +1,27 @@
+package interop
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go interop.go
+
+//sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
+
+func ConvertAndFreeCoTaskMemString(buffer *uint16) string {
+	str := syscall.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(buffer))[:])
+	coTaskMemFree(unsafe.Pointer(buffer))
+	return str
+}
+
+func ConvertAndFreeCoTaskMemBytes(buffer *uint16) []byte {
+	return []byte(ConvertAndFreeCoTaskMemString(buffer))
+}
+
+func Win32FromHresult(hr uintptr) syscall.Errno {
+	if hr&0x1fff0000 == 0x00070000 {
+		return syscall.Errno(hr & 0xffff)
+	}
+	return syscall.Errno(hr)
+}

+ 48 - 0
vendor/github.com/Microsoft/hcsshim/internal/interop/zsyscall_windows.go

@@ -0,0 +1,48 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package interop
+
+import (
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modole32 = windows.NewLazySystemDLL("ole32.dll")
+
+	procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
+)
+
+func coTaskMemFree(buffer unsafe.Pointer) {
+	syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(buffer), 0, 0)
+	return
+}

+ 24 - 0
vendor/github.com/Microsoft/hcsshim/internal/longpath/longpath.go

@@ -0,0 +1,24 @@
+package longpath
+
+import (
+	"path/filepath"
+	"strings"
+)
+
+// LongAbs makes a path absolute and returns it in NT long path form.
+func LongAbs(path string) (string, error) {
+	if strings.HasPrefix(path, `\\?\`) || strings.HasPrefix(path, `\\.\`) {
+		return path, nil
+	}
+	if !filepath.IsAbs(path) {
+		absPath, err := filepath.Abs(path)
+		if err != nil {
+			return "", err
+		}
+		path = absPath
+	}
+	if strings.HasPrefix(path, `\\`) {
+		return `\\?\UNC\` + path[2:], nil
+	}
+	return `\\?\` + path, nil
+}

+ 52 - 0
vendor/github.com/Microsoft/hcsshim/internal/mergemaps/merge.go

@@ -0,0 +1,52 @@
+package mergemaps
+
+import "encoding/json"
+
+// Merge recursively merges map `fromMap` into map `ToMap`. Any pre-existing values
+// in ToMap are overwritten. Values in fromMap are added to ToMap.
+// From http://stackoverflow.com/questions/40491438/merging-two-json-strings-in-golang
+func Merge(fromMap, ToMap interface{}) interface{} {
+	switch fromMap := fromMap.(type) {
+	case map[string]interface{}:
+		ToMap, ok := ToMap.(map[string]interface{})
+		if !ok {
+			return fromMap
+		}
+		for keyToMap, valueToMap := range ToMap {
+			if valueFromMap, ok := fromMap[keyToMap]; ok {
+				fromMap[keyToMap] = Merge(valueFromMap, valueToMap)
+			} else {
+				fromMap[keyToMap] = valueToMap
+			}
+		}
+	case nil:
+		// merge(nil, map[string]interface{...}) -> map[string]interface{...}
+		ToMap, ok := ToMap.(map[string]interface{})
+		if ok {
+			return ToMap
+		}
+	}
+	return fromMap
+}
+
+// MergeJSON merges the contents of a JSON string into an object representation,
+// returning a new object suitable for translating to JSON.
+func MergeJSON(object interface{}, additionalJSON []byte) (interface{}, error) {
+	if len(additionalJSON) == 0 {
+		return object, nil
+	}
+	objectJSON, err := json.Marshal(object)
+	if err != nil {
+		return nil, err
+	}
+	var objectMap, newMap map[string]interface{}
+	err = json.Unmarshal(objectJSON, &objectMap)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(additionalJSON, &newMap)
+	if err != nil {
+		return nil, err
+	}
+	return Merge(newMap, objectMap), nil
+}

+ 53 - 49
vendor/github.com/Microsoft/hcsshim/safeopen.go → vendor/github.com/Microsoft/hcsshim/internal/safefile/safeopen.go

@@ -1,4 +1,4 @@
-package hcsshim
+package safefile
 
 import (
 	"errors"
@@ -10,9 +10,13 @@ import (
 	"unicode/utf16"
 	"unsafe"
 
+	"github.com/Microsoft/hcsshim/internal/longpath"
+
 	winio "github.com/Microsoft/go-winio"
 )
 
+//go:generate go run $GOROOT\src\syscall\mksyscall_windows.go -output zsyscall_windows.go safeopen.go
+
 //sys ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) = ntdll.NtCreateFile
 //sys ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) = ntdll.NtSetInformationFile
 //sys rtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
@@ -53,28 +57,28 @@ const (
 	_FileLinkInformation          = 11
 	_FileDispositionInformationEx = 64
 
-	_FILE_READ_ATTRIBUTES  = 0x0080
-	_FILE_WRITE_ATTRIBUTES = 0x0100
-	_DELETE                = 0x10000
+	FILE_READ_ATTRIBUTES  = 0x0080
+	FILE_WRITE_ATTRIBUTES = 0x0100
+	DELETE                = 0x10000
 
-	_FILE_OPEN   = 1
-	_FILE_CREATE = 2
+	FILE_OPEN   = 1
+	FILE_CREATE = 2
 
-	_FILE_DIRECTORY_FILE          = 0x00000001
-	_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
-	_FILE_DELETE_ON_CLOSE         = 0x00001000
-	_FILE_OPEN_FOR_BACKUP_INTENT  = 0x00004000
-	_FILE_OPEN_REPARSE_POINT      = 0x00200000
+	FILE_DIRECTORY_FILE          = 0x00000001
+	FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
+	FILE_DELETE_ON_CLOSE         = 0x00001000
+	FILE_OPEN_FOR_BACKUP_INTENT  = 0x00004000
+	FILE_OPEN_REPARSE_POINT      = 0x00200000
 
-	_FILE_DISPOSITION_DELETE = 0x00000001
+	FILE_DISPOSITION_DELETE = 0x00000001
 
 	_OBJ_DONT_REPARSE = 0x1000
 
 	_STATUS_REPARSE_POINT_ENCOUNTERED = 0xC000050B
 )
 
-func openRoot(path string) (*os.File, error) {
-	longpath, err := makeLongAbsPath(path)
+func OpenRoot(path string) (*os.File, error) {
+	longpath, err := longpath.LongAbs(path)
 	if err != nil {
 		return nil, err
 	}
@@ -141,7 +145,7 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
 		0,
 		shareFlags,
 		createDisposition,
-		_FILE_OPEN_FOR_BACKUP_INTENT|_FILE_SYNCHRONOUS_IO_NONALERT|flags,
+		FILE_OPEN_FOR_BACKUP_INTENT|FILE_SYNCHRONOUS_IO_NONALERT|flags,
 		nil,
 		0,
 	)
@@ -149,7 +153,7 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
 		return nil, rtlNtStatusToDosError(status)
 	}
 
-	fullPath, err := makeLongAbsPath(filepath.Join(root.Name(), path))
+	fullPath, err := longpath.LongAbs(filepath.Join(root.Name(), path))
 	if err != nil {
 		syscall.Close(syscall.Handle(h))
 		return nil, err
@@ -158,9 +162,9 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
 	return os.NewFile(h, fullPath), nil
 }
 
-// openRelative opens a relative path from the given root, failing if
+// OpenRelative opens a relative path from the given root, failing if
 // any of the intermediate path components are reparse points.
-func openRelative(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
+func OpenRelative(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
 	f, err := openRelativeInternal(path, root, accessMask, shareFlags, createDisposition, flags)
 	if err != nil {
 		err = &os.PathError{Op: "open", Path: filepath.Join(root.Name(), path), Err: err}
@@ -168,17 +172,17 @@ func openRelative(path string, root *os.File, accessMask uint32, shareFlags uint
 	return f, err
 }
 
-// linkRelative creates a hard link from oldname to newname (relative to oldroot
+// LinkRelative creates a hard link from oldname to newname (relative to oldroot
 // and newroot), failing if any of the intermediate path components are reparse
 // points.
-func linkRelative(oldname string, oldroot *os.File, newname string, newroot *os.File) error {
+func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os.File) error {
 	// Open the old file.
 	oldf, err := openRelativeInternal(
 		oldname,
 		oldroot,
 		syscall.FILE_WRITE_ATTRIBUTES,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_OPEN,
+		FILE_OPEN,
 		0,
 	)
 	if err != nil {
@@ -195,8 +199,8 @@ func linkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
 			newroot,
 			syscall.GENERIC_READ,
 			syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-			_FILE_OPEN,
-			_FILE_DIRECTORY_FILE)
+			FILE_OPEN,
+			FILE_DIRECTORY_FILE)
 		if err != nil {
 			return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: err}
 		}
@@ -248,7 +252,7 @@ func linkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
 
 // deleteOnClose marks a file to be deleted when the handle is closed.
 func deleteOnClose(f *os.File) error {
-	disposition := fileDispositionInformationEx{Flags: _FILE_DISPOSITION_DELETE}
+	disposition := fileDispositionInformationEx{Flags: FILE_DISPOSITION_DELETE}
 	var iosb ioStatusBlock
 	status := ntSetInformationFile(
 		f.Fd(),
@@ -281,16 +285,16 @@ func clearReadOnly(f *os.File) error {
 	return winio.SetFileBasicInfo(f, &sbi)
 }
 
-// removeRelative removes a file or directory relative to a root, failing if any
+// RemoveRelative removes a file or directory relative to a root, failing if any
 // intermediate path components are reparse points.
-func removeRelative(path string, root *os.File) error {
+func RemoveRelative(path string, root *os.File) error {
 	f, err := openRelativeInternal(
 		path,
 		root,
-		_FILE_READ_ATTRIBUTES|_FILE_WRITE_ATTRIBUTES|_DELETE,
+		FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|DELETE,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_OPEN,
-		_FILE_OPEN_REPARSE_POINT)
+		FILE_OPEN,
+		FILE_OPEN_REPARSE_POINT)
 	if err == nil {
 		defer f.Close()
 		err = deleteOnClose(f)
@@ -306,10 +310,10 @@ func removeRelative(path string, root *os.File) error {
 	return nil
 }
 
-// removeAllRelative removes a directory tree relative to a root, failing if any
+// RemoveAllRelative removes a directory tree relative to a root, failing if any
 // intermediate path components are reparse points.
-func removeAllRelative(path string, root *os.File) error {
-	fi, err := lstatRelative(path, root)
+func RemoveAllRelative(path string, root *os.File) error {
+	fi, err := LstatRelative(path, root)
 	if err != nil {
 		if os.IsNotExist(err) {
 			return nil
@@ -319,7 +323,7 @@ func removeAllRelative(path string, root *os.File) error {
 	fileAttributes := fi.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 	if fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 || fileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
 		// If this is a reparse point, it can't have children. Simple remove will do.
-		err := removeRelative(path, root)
+		err := RemoveRelative(path, root)
 		if err == nil || os.IsNotExist(err) {
 			return nil
 		}
@@ -327,7 +331,7 @@ func removeAllRelative(path string, root *os.File) error {
 	}
 
 	// It is necessary to use os.Open as Readdirnames does not work with
-	// openRelative. This is safe because the above lstatrelative fails
+	// OpenRelative. This is safe because the above lstatrelative fails
 	// if the target is outside the root, and we know this is not a
 	// symlink from the above FILE_ATTRIBUTE_REPARSE_POINT check.
 	fd, err := os.Open(filepath.Join(root.Name(), path))
@@ -344,7 +348,7 @@ func removeAllRelative(path string, root *os.File) error {
 	for {
 		names, err1 := fd.Readdirnames(100)
 		for _, name := range names {
-			err1 := removeAllRelative(path+string(os.PathSeparator)+name, root)
+			err1 := RemoveAllRelative(path+string(os.PathSeparator)+name, root)
 			if err == nil {
 				err = err1
 			}
@@ -363,7 +367,7 @@ func removeAllRelative(path string, root *os.File) error {
 	fd.Close()
 
 	// Remove directory.
-	err1 := removeRelative(path, root)
+	err1 := RemoveRelative(path, root)
 	if err1 == nil || os.IsNotExist(err1) {
 		return nil
 	}
@@ -373,16 +377,16 @@ func removeAllRelative(path string, root *os.File) error {
 	return err
 }
 
-// mkdirRelative creates a directory relative to a root, failing if any
+// MkdirRelative creates a directory relative to a root, failing if any
 // intermediate path components are reparse points.
-func mkdirRelative(path string, root *os.File) error {
+func MkdirRelative(path string, root *os.File) error {
 	f, err := openRelativeInternal(
 		path,
 		root,
 		0,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_CREATE,
-		_FILE_DIRECTORY_FILE)
+		FILE_CREATE,
+		FILE_DIRECTORY_FILE)
 	if err == nil {
 		f.Close()
 	} else {
@@ -391,16 +395,16 @@ func mkdirRelative(path string, root *os.File) error {
 	return err
 }
 
-// lstatRelative performs a stat operation on a file relative to a root, failing
+// LstatRelative performs a stat operation on a file relative to a root, failing
 // if any intermediate path components are reparse points.
-func lstatRelative(path string, root *os.File) (os.FileInfo, error) {
+func LstatRelative(path string, root *os.File) (os.FileInfo, error) {
 	f, err := openRelativeInternal(
 		path,
 		root,
-		_FILE_READ_ATTRIBUTES,
+		FILE_READ_ATTRIBUTES,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_OPEN,
-		_FILE_OPEN_REPARSE_POINT)
+		FILE_OPEN,
+		FILE_OPEN_REPARSE_POINT)
 	if err != nil {
 		return nil, &os.PathError{Op: "stat", Path: filepath.Join(root.Name(), path), Err: err}
 	}
@@ -408,16 +412,16 @@ func lstatRelative(path string, root *os.File) (os.FileInfo, error) {
 	return f.Stat()
 }
 
-// ensureNotReparsePointRelative validates that a given file (relative to a
+// EnsureNotReparsePointRelative validates that a given file (relative to a
 // root) and all intermediate path components are not a reparse points.
-func ensureNotReparsePointRelative(path string, root *os.File) error {
+func EnsureNotReparsePointRelative(path string, root *os.File) error {
 	// Perform an open with OBJ_DONT_REPARSE but without specifying FILE_OPEN_REPARSE_POINT.
-	f, err := openRelative(
+	f, err := OpenRelative(
 		path,
 		root,
 		0,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_OPEN,
+		FILE_OPEN,
 		0)
 	if err != nil {
 		return err

+ 79 - 0
vendor/github.com/Microsoft/hcsshim/internal/safefile/zsyscall_windows.go

@@ -0,0 +1,79 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package safefile
+
+import (
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modntdll    = windows.NewLazySystemDLL("ntdll.dll")
+	modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
+
+	procNtCreateFile               = modntdll.NewProc("NtCreateFile")
+	procNtSetInformationFile       = modntdll.NewProc("NtSetInformationFile")
+	procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
+	procLocalAlloc                 = modkernel32.NewProc("LocalAlloc")
+	procLocalFree                  = modkernel32.NewProc("LocalFree")
+)
+
+func ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) {
+	r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(fileAttributes), uintptr(shareAccess), uintptr(createDisposition), uintptr(createOptions), uintptr(unsafe.Pointer(eaBuffer)), uintptr(eaLength), 0)
+	status = uint32(r0)
+	return
+}
+
+func ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) {
+	r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(information), uintptr(length), uintptr(class), 0)
+	status = uint32(r0)
+	return
+}
+
+func rtlNtStatusToDosError(status uint32) (winerr error) {
+	r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
+	if r0 != 0 {
+		winerr = syscall.Errno(r0)
+	}
+	return
+}
+
+func localAlloc(flags uint32, size int) (ptr uintptr) {
+	r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(size), 0)
+	ptr = uintptr(r0)
+	return
+}
+
+func localFree(ptr uintptr) {
+	syscall.Syscall(procLocalFree.Addr(), 1, uintptr(ptr), 0, 0)
+	return
+}

+ 228 - 0
vendor/github.com/Microsoft/hcsshim/internal/schema1/schema1.go

@@ -0,0 +1,228 @@
+package schema1
+
+import (
+	"encoding/json"
+	"time"
+)
+
+// ProcessConfig is used as both the input of Container.CreateProcess
+// and to convert the parameters to JSON for passing onto the HCS
+type ProcessConfig struct {
+	ApplicationName   string            `json:",omitempty"`
+	CommandLine       string            `json:",omitempty"`
+	CommandArgs       []string          `json:",omitempty"` // Used by Linux Containers on Windows
+	User              string            `json:",omitempty"`
+	WorkingDirectory  string            `json:",omitempty"`
+	Environment       map[string]string `json:",omitempty"`
+	EmulateConsole    bool              `json:",omitempty"`
+	CreateStdInPipe   bool              `json:",omitempty"`
+	CreateStdOutPipe  bool              `json:",omitempty"`
+	CreateStdErrPipe  bool              `json:",omitempty"`
+	ConsoleSize       [2]uint           `json:",omitempty"`
+	CreateInUtilityVm bool              `json:",omitempty"` // Used by Linux Containers on Windows
+	OCISpecification  *json.RawMessage  `json:",omitempty"` // Used by Linux Containers on Windows
+}
+
+type Layer struct {
+	ID   string
+	Path string
+}
+
+type MappedDir struct {
+	HostPath          string
+	ContainerPath     string
+	ReadOnly          bool
+	BandwidthMaximum  uint64
+	IOPSMaximum       uint64
+	CreateInUtilityVM bool
+	// LinuxMetadata - Support added in 1803/RS4+.
+	LinuxMetadata bool `json:",omitempty"`
+}
+
+type MappedPipe struct {
+	HostPath          string
+	ContainerPipeName string
+}
+
+type HvRuntime struct {
+	ImagePath           string `json:",omitempty"`
+	SkipTemplate        bool   `json:",omitempty"`
+	LinuxInitrdFile     string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM
+	LinuxKernelFile     string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM
+	LinuxBootParameters string `json:",omitempty"` // Additional boot parameters for starting a Linux Utility VM in initrd mode
+	BootSource          string `json:",omitempty"` // "Vhd" for Linux Utility VM booting from VHD
+	WritableBootSource  bool   `json:",omitempty"` // Linux Utility VM booting from VHD
+}
+
+type MappedVirtualDisk struct {
+	HostPath          string `json:",omitempty"` // Path to VHD on the host
+	ContainerPath     string // Platform-specific mount point path in the container
+	CreateInUtilityVM bool   `json:",omitempty"`
+	ReadOnly          bool   `json:",omitempty"`
+	Cache             string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
+	AttachOnly        bool   `json:",omitempty:`
+}
+
+// AssignedDevice represents a device that has been directly assigned to a container
+//
+// NOTE: Support added in RS5
+type AssignedDevice struct {
+	//  InterfaceClassGUID of the device to assign to container.
+	InterfaceClassGUID string `json:"InterfaceClassGuid,omitempty"`
+}
+
+// ContainerConfig is used as both the input of CreateContainer
+// and to convert the parameters to JSON for passing onto the HCS
+type ContainerConfig struct {
+	SystemType                  string              // HCS requires this to be hard-coded to "Container"
+	Name                        string              // Name of the container. We use the docker ID.
+	Owner                       string              `json:",omitempty"` // The management platform that created this container
+	VolumePath                  string              `json:",omitempty"` // Windows volume path for scratch space. Used by Windows Server Containers only. Format \\?\\Volume{GUID}
+	IgnoreFlushesDuringBoot     bool                `json:",omitempty"` // Optimization hint for container startup in Windows
+	LayerFolderPath             string              `json:",omitempty"` // Where the layer folders are located. Used by Windows Server Containers only. Format  %root%\windowsfilter\containerID
+	Layers                      []Layer             // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
+	Credentials                 string              `json:",omitempty"` // Credentials information
+	ProcessorCount              uint32              `json:",omitempty"` // Number of processors to assign to the container.
+	ProcessorWeight             uint64              `json:",omitempty"` // CPU shares (relative weight to other containers with cpu shares). Range is from 1 to 10000. A value of 0 results in default shares.
+	ProcessorMaximum            int64               `json:",omitempty"` // Specifies the portion of processor cycles that this container can use as a percentage times 100. Range is from 1 to 10000. A value of 0 results in no limit.
+	StorageIOPSMaximum          uint64              `json:",omitempty"` // Maximum Storage IOPS
+	StorageBandwidthMaximum     uint64              `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
+	StorageSandboxSize          uint64              `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
+	MemoryMaximumInMB           int64               `json:",omitempty"` // Maximum memory available to the container in Megabytes
+	HostName                    string              `json:",omitempty"` // Hostname
+	MappedDirectories           []MappedDir         `json:",omitempty"` // List of mapped directories (volumes/mounts)
+	MappedPipes                 []MappedPipe        `json:",omitempty"` // List of mapped Windows named pipes
+	HvPartition                 bool                // True if it a Hyper-V Container
+	NetworkSharedContainerName  string              `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
+	EndpointList                []string            `json:",omitempty"` // List of networking endpoints to be attached to container
+	HvRuntime                   *HvRuntime          `json:",omitempty"` // Hyper-V container settings. Used by Hyper-V containers only. Format ImagePath=%root%\BaseLayerID\UtilityVM
+	Servicing                   bool                `json:",omitempty"` // True if this container is for servicing
+	AllowUnqualifiedDNSQuery    bool                `json:",omitempty"` // True to allow unqualified DNS name resolution
+	DNSSearchList               string              `json:",omitempty"` // Comma seperated list of DNS suffixes to use for name resolution
+	ContainerType               string              `json:",omitempty"` // "Linux" for Linux containers on Windows. Omitted otherwise.
+	TerminateOnLastHandleClosed bool                `json:",omitempty"` // Should HCS terminate the container once all handles have been closed
+	MappedVirtualDisks          []MappedVirtualDisk `json:",omitempty"` // Array of virtual disks to mount at start
+	AssignedDevices             []AssignedDevice    `json:",omitempty"` // Array of devices to assign. NOTE: Support added in RS5
+}
+
+type ComputeSystemQuery struct {
+	IDs    []string `json:"Ids,omitempty"`
+	Types  []string `json:",omitempty"`
+	Names  []string `json:",omitempty"`
+	Owners []string `json:",omitempty"`
+}
+
+type PropertyType string
+
+const (
+	PropertyTypeStatistics        PropertyType = "Statistics"
+	PropertyTypeProcessList                    = "ProcessList"
+	PropertyTypeMappedVirtualDisk              = "MappedVirtualDisk"
+)
+
+type PropertyQuery struct {
+	PropertyTypes []PropertyType `json:",omitempty"`
+}
+
+// ContainerProperties holds the properties for a container and the processes running in that container
+type ContainerProperties struct {
+	ID                           string `json:"Id"`
+	State                        string
+	Name                         string
+	SystemType                   string
+	Owner                        string
+	SiloGUID                     string                              `json:"SiloGuid,omitempty"`
+	RuntimeID                    string                              `json:"RuntimeId,omitempty"`
+	IsRuntimeTemplate            bool                                `json:",omitempty"`
+	RuntimeImagePath             string                              `json:",omitempty"`
+	Stopped                      bool                                `json:",omitempty"`
+	ExitType                     string                              `json:",omitempty"`
+	AreUpdatesPending            bool                                `json:",omitempty"`
+	ObRoot                       string                              `json:",omitempty"`
+	Statistics                   Statistics                          `json:",omitempty"`
+	ProcessList                  []ProcessListItem                   `json:",omitempty"`
+	MappedVirtualDiskControllers map[int]MappedVirtualDiskController `json:",omitempty"`
+}
+
+// MemoryStats holds the memory statistics for a container
+type MemoryStats struct {
+	UsageCommitBytes            uint64 `json:"MemoryUsageCommitBytes,omitempty"`
+	UsageCommitPeakBytes        uint64 `json:"MemoryUsageCommitPeakBytes,omitempty"`
+	UsagePrivateWorkingSetBytes uint64 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
+}
+
+// ProcessorStats holds the processor statistics for a container
+type ProcessorStats struct {
+	TotalRuntime100ns  uint64 `json:",omitempty"`
+	RuntimeUser100ns   uint64 `json:",omitempty"`
+	RuntimeKernel100ns uint64 `json:",omitempty"`
+}
+
+// StorageStats holds the storage statistics for a container
+type StorageStats struct {
+	ReadCountNormalized  uint64 `json:",omitempty"`
+	ReadSizeBytes        uint64 `json:",omitempty"`
+	WriteCountNormalized uint64 `json:",omitempty"`
+	WriteSizeBytes       uint64 `json:",omitempty"`
+}
+
+// NetworkStats holds the network statistics for a container
+type NetworkStats struct {
+	BytesReceived          uint64 `json:",omitempty"`
+	BytesSent              uint64 `json:",omitempty"`
+	PacketsReceived        uint64 `json:",omitempty"`
+	PacketsSent            uint64 `json:",omitempty"`
+	DroppedPacketsIncoming uint64 `json:",omitempty"`
+	DroppedPacketsOutgoing uint64 `json:",omitempty"`
+	EndpointId             string `json:",omitempty"`
+	InstanceId             string `json:",omitempty"`
+}
+
+// Statistics is the structure returned by a statistics call on a container
+type Statistics struct {
+	Timestamp          time.Time      `json:",omitempty"`
+	ContainerStartTime time.Time      `json:",omitempty"`
+	Uptime100ns        uint64         `json:",omitempty"`
+	Memory             MemoryStats    `json:",omitempty"`
+	Processor          ProcessorStats `json:",omitempty"`
+	Storage            StorageStats   `json:",omitempty"`
+	Network            []NetworkStats `json:",omitempty"`
+}
+
+// ProcessList is the structure of an item returned by a ProcessList call on a container
+type ProcessListItem struct {
+	CreateTimestamp              time.Time `json:",omitempty"`
+	ImageName                    string    `json:",omitempty"`
+	KernelTime100ns              uint64    `json:",omitempty"`
+	MemoryCommitBytes            uint64    `json:",omitempty"`
+	MemoryWorkingSetPrivateBytes uint64    `json:",omitempty"`
+	MemoryWorkingSetSharedBytes  uint64    `json:",omitempty"`
+	ProcessId                    uint32    `json:",omitempty"`
+	UserTime100ns                uint64    `json:",omitempty"`
+}
+
+// MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
+type MappedVirtualDiskController struct {
+	MappedVirtualDisks map[int]MappedVirtualDisk `json:",omitempty"`
+}
+
+// Type of Request Support in ModifySystem
+type RequestType string
+
+// Type of Resource Support in ModifySystem
+type ResourceType string
+
+// RequestType const
+const (
+	Add     RequestType  = "Add"
+	Remove  RequestType  = "Remove"
+	Network ResourceType = "Network"
+)
+
+// ResourceModificationRequestResponse is the structure used to send request to the container to modify the system
+// Supported resource types are Network and Request Types are Add/Remove
+type ResourceModificationRequestResponse struct {
+	Resource ResourceType `json:"ResourceType"`
+	Data     interface{}  `json:"Settings"`
+	Request  RequestType  `json:"RequestType,omitempty"`
+}

+ 26 - 0
vendor/github.com/Microsoft/hcsshim/internal/timeout/timeout.go

@@ -0,0 +1,26 @@
+package timeout
+
+import (
+	"os"
+	"strconv"
+	"time"
+)
+
+// Duration is the default time to wait for various operations.
+// - Waiting for async notifications from HCS
+// - Waiting for processes to launch through
+// - Waiting to copy data to/from a launched processes stdio pipes.
+//
+// This can be overridden through environment variable `HCS_TIMEOUT_SECONDS`
+
+var Duration = 4 * time.Minute
+
+func init() {
+	envTimeout := os.Getenv("HCSSHIM_TIMEOUT_SECONDS")
+	if len(envTimeout) > 0 {
+		e, err := strconv.Atoi(envTimeout)
+		if err == nil && e > 0 {
+			Duration = time.Second * time.Duration(e)
+		}
+	}
+}

+ 25 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/activatelayer.go

@@ -0,0 +1,25 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// ActivateLayer will find the layer with the given id and mount it's filesystem.
+// For a read/write layer, the mounted filesystem will appear as a volume on the
+// host, while a read-only layer is generally expected to be a no-op.
+// An activated layer must later be deactivated via DeactivateLayer.
+func ActivateLayer(path string) error {
+	title := "hcsshim::ActivateLayer "
+	logrus.Debugf(title+"path %s", path)
+
+	err := activateLayer(&stdDriverInfo, path)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", path)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+" - succeeded path=%s", path)
+	return nil
+}

+ 10 - 8
vendor/github.com/Microsoft/hcsshim/baselayer.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/baselayer.go

@@ -1,4 +1,4 @@
-package hcsshim
+package wclayer
 
 import (
 	"errors"
@@ -7,6 +7,8 @@ import (
 	"syscall"
 
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/safefile"
 )
 
 type baseLayerWriter struct {
@@ -29,7 +31,7 @@ type dirInfo struct {
 func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
 	for i := range dis {
 		di := &dis[len(dis)-i-1] // reverse order: process child directories first
-		f, err := openRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, _FILE_OPEN, _FILE_DIRECTORY_FILE)
+		f, err := safefile.OpenRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, safefile.FILE_OPEN, safefile.FILE_DIRECTORY_FILE)
 		if err != nil {
 			return err
 		}
@@ -84,21 +86,21 @@ func (w *baseLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) (err e
 
 	extraFlags := uint32(0)
 	if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
-		extraFlags |= _FILE_DIRECTORY_FILE
+		extraFlags |= safefile.FILE_DIRECTORY_FILE
 		if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
 			w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
 		}
 	}
 
 	mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
-	f, err = openRelative(name, w.root, mode, syscall.FILE_SHARE_READ, _FILE_CREATE, extraFlags)
+	f, err = safefile.OpenRelative(name, w.root, mode, syscall.FILE_SHARE_READ, safefile.FILE_CREATE, extraFlags)
 	if err != nil {
-		return makeError(err, "Failed to openRelative", name)
+		return hcserror.New(err, "Failed to safefile.OpenRelative", name)
 	}
 
 	err = winio.SetFileBasicInfo(f, fileInfo)
 	if err != nil {
-		return makeError(err, "Failed to SetFileBasicInfo", name)
+		return hcserror.New(err, "Failed to SetFileBasicInfo", name)
 	}
 
 	w.f = f
@@ -119,7 +121,7 @@ func (w *baseLayerWriter) AddLink(name string, target string) (err error) {
 		return err
 	}
 
-	return linkRelative(target, w.root, name, w.root)
+	return safefile.LinkRelative(target, w.root, name, w.root)
 }
 
 func (w *baseLayerWriter) Remove(name string) error {
@@ -157,7 +159,7 @@ func (w *baseLayerWriter) Close() error {
 		}
 
 		if w.hasUtilityVM {
-			err := ensureNotReparsePointRelative("UtilityVM", w.root)
+			err := safefile.EnsureNotReparsePointRelative("UtilityVM", w.root)
 			if err != nil {
 				return err
 			}

+ 23 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/createlayer.go

@@ -0,0 +1,23 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// CreateLayer creates a new, empty, read-only layer on the filesystem based on
+// the parent layer provided.
+func CreateLayer(path, parent string) error {
+	title := "hcsshim::CreateLayer "
+	logrus.Debugf(title+"Flavour %d ID %s parent %s", path, parent)
+
+	err := createLayer(&stdDriverInfo, path, parent)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s parent=%s flavour=%d", path, parent)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+" - succeeded path=%s parent=%s flavour=%d", path, parent)
+	return nil
+}

+ 31 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/createscratchlayer.go

@@ -0,0 +1,31 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// CreateScratchLayer creates and populates new read-write layer for use by a container.
+// This requires both the id of the direct parent layer, as well as the full list
+// of paths to all parent layers up to the base (and including the direct parent
+// whose id was provided).
+func CreateScratchLayer(path string, parentLayerPaths []string) error {
+	title := "hcsshim::CreateScratchLayer "
+	logrus.Debugf(title+"path %s", path)
+
+	// Generate layer descriptors
+	layers, err := layerPathsToDescriptors(parentLayerPaths)
+	if err != nil {
+		return err
+	}
+
+	err = createSandboxLayer(&stdDriverInfo, path, 0, layers)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", path)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+"- succeeded path=%s", path)
+	return nil
+}

+ 22 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/deactivatelayer.go

@@ -0,0 +1,22 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
+func DeactivateLayer(path string) error {
+	title := "hcsshim::DeactivateLayer "
+	logrus.Debugf(title+"path %s", path)
+
+	err := deactivateLayer(&stdDriverInfo, path)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", path)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+"succeeded path=%s", path)
+	return nil
+}

+ 23 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go

@@ -0,0 +1,23 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// DestroyLayer will remove the on-disk files representing the layer with the given
+// path, including that layer's containing folder, if any.
+func DestroyLayer(path string) error {
+	title := "hcsshim::DestroyLayer "
+	logrus.Debugf(title+"path %s", path)
+
+	err := destroyLayer(&stdDriverInfo, path)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", path)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+"succeeded path=%s", path)
+	return nil
+}

+ 22 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go

@@ -0,0 +1,22 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// ExpandScratchSize expands the size of a layer to at least size bytes.
+func ExpandScratchSize(path string, size uint64) error {
+	title := "hcsshim::ExpandScratchSize "
+	logrus.Debugf(title+"path=%s size=%d", path, size)
+
+	err := expandSandboxSize(&stdDriverInfo, path, size)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s size=%d", path, size)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+"- succeeded path=%s size=%d", path, size)
+	return nil
+}

+ 19 - 28
vendor/github.com/Microsoft/hcsshim/exportlayer.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/exportlayer.go

@@ -1,4 +1,4 @@
-package hcsshim
+package wclayer
 
 import (
 	"io"
@@ -7,6 +7,8 @@ import (
 	"syscall"
 
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/interop"
 	"github.com/sirupsen/logrus"
 )
 
@@ -15,9 +17,9 @@ import (
 // format includes any metadata required for later importing the layer (using
 // ImportLayer), and requires the full list of parent layer paths in order to
 // perform the export.
-func ExportLayer(info DriverInfo, layerId string, exportFolderPath string, parentLayerPaths []string) error {
+func ExportLayer(path string, exportFolderPath string, parentLayerPaths []string) error {
 	title := "hcsshim::ExportLayer "
-	logrus.Debugf(title+"flavour %d layerId %s folder %s", info.Flavour, layerId, exportFolderPath)
+	logrus.Debugf(title+"path %s folder %s", path, exportFolderPath)
 
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -25,21 +27,14 @@ func ExportLayer(info DriverInfo, layerId string, exportFolderPath string, paren
 		return err
 	}
 
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
+	err = exportLayer(&stdDriverInfo, path, exportFolderPath, layers)
 	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s folder=%s", path, exportFolderPath)
 		logrus.Error(err)
 		return err
 	}
 
-	err = exportLayer(&infop, layerId, exportFolderPath, layers)
-	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s flavour=%d folder=%s", layerId, info.Flavour, exportFolderPath)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"succeeded flavour=%d layerId=%s folder=%s", info.Flavour, layerId, exportFolderPath)
+	logrus.Debugf(title+"succeeded path=%s folder=%s", path, exportFolderPath)
 	return nil
 }
 
@@ -69,11 +64,11 @@ func (r *FilterLayerReader) Next() (string, int64, *winio.FileBasicInfo, error)
 		if err == syscall.ERROR_NO_MORE_FILES {
 			err = io.EOF
 		} else {
-			err = makeError(err, "ExportLayerNext", "")
+			err = hcserror.New(err, "ExportLayerNext", "")
 		}
 		return "", 0, nil, err
 	}
-	fileName := convertAndFreeCoTaskMemString(fileNamep)
+	fileName := interop.ConvertAndFreeCoTaskMemString(fileNamep)
 	if deleted != 0 {
 		fileInfo = nil
 	}
@@ -88,7 +83,7 @@ func (r *FilterLayerReader) Read(b []byte) (int, error) {
 	var bytesRead uint32
 	err := exportLayerRead(r.context, b, &bytesRead)
 	if err != nil {
-		return 0, makeError(err, "ExportLayerRead", "")
+		return 0, hcserror.New(err, "ExportLayerRead", "")
 	}
 	if bytesRead == 0 {
 		return 0, io.EOF
@@ -103,7 +98,7 @@ func (r *FilterLayerReader) Close() (err error) {
 	if r.context != 0 {
 		err = exportLayerEnd(r.context)
 		if err != nil {
-			err = makeError(err, "ExportLayerEnd", "")
+			err = hcserror.New(err, "ExportLayerEnd", "")
 		}
 		r.context = 0
 	}
@@ -113,34 +108,30 @@ func (r *FilterLayerReader) Close() (err error) {
 // NewLayerReader returns a new layer reader for reading the contents of an on-disk layer.
 // The caller must have taken the SeBackupPrivilege privilege
 // to call this and any methods on the resulting LayerReader.
-func NewLayerReader(info DriverInfo, layerID string, parentLayerPaths []string) (LayerReader, error) {
+func NewLayerReader(path string, parentLayerPaths []string) (LayerReader, error) {
 	if procExportLayerBegin.Find() != nil {
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// legacy export code path.
-		path, err := ioutil.TempDir("", "hcs")
+		exportPath, err := ioutil.TempDir("", "hcs")
 		if err != nil {
 			return nil, err
 		}
-		err = ExportLayer(info, layerID, path, parentLayerPaths)
+		err = ExportLayer(path, exportPath, parentLayerPaths)
 		if err != nil {
-			os.RemoveAll(path)
+			os.RemoveAll(exportPath)
 			return nil, err
 		}
-		return &legacyLayerReaderWrapper{newLegacyLayerReader(path)}, nil
+		return &legacyLayerReaderWrapper{newLegacyLayerReader(exportPath)}, nil
 	}
 
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	if err != nil {
 		return nil, err
 	}
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		return nil, err
-	}
 	r := &FilterLayerReader{}
-	err = exportLayerBegin(&infop, layerID, layers, &r.context)
+	err = exportLayerBegin(&stdDriverInfo, path, layers, &r.context)
 	if err != nil {
-		return nil, makeError(err, "ExportLayerBegin", "")
+		return nil, hcserror.New(err, "ExportLayerBegin", "")
 	}
 	return r, err
 }

+ 12 - 18
vendor/github.com/Microsoft/hcsshim/getlayermountpath.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/getlayermountpath.go

@@ -1,34 +1,28 @@
-package hcsshim
+package wclayer
 
 import (
 	"syscall"
 
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 	"github.com/sirupsen/logrus"
 )
 
-// GetLayerMountPath will look for a mounted layer with the given id and return
+// GetLayerMountPath will look for a mounted layer with the given path and return
 // the path at which that layer can be accessed.  This path may be a volume path
 // if the layer is a mounted read-write layer, otherwise it is expected to be the
 // folder path at which the layer is stored.
-func GetLayerMountPath(info DriverInfo, id string) (string, error) {
+func GetLayerMountPath(path string) (string, error) {
 	title := "hcsshim::GetLayerMountPath "
-	logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return "", err
-	}
+	logrus.Debugf(title+"path %s", path)
 
 	var mountPathLength uintptr
 	mountPathLength = 0
 
 	// Call the procedure itself.
 	logrus.Debugf("Calling proc (1)")
-	err = getLayerMountPath(&infop, id, &mountPathLength, nil)
+	err := getLayerMountPath(&stdDriverInfo, path, &mountPathLength, nil)
 	if err != nil {
-		err = makeErrorf(err, title, "(first call) id=%s flavour=%d", id, info.Flavour)
+		err = hcserror.Errorf(err, title, "(first call) path=%s", path)
 		logrus.Error(err)
 		return "", err
 	}
@@ -42,14 +36,14 @@ func GetLayerMountPath(info DriverInfo, id string) (string, error) {
 
 	// Call the procedure again
 	logrus.Debugf("Calling proc (2)")
-	err = getLayerMountPath(&infop, id, &mountPathLength, &mountPathp[0])
+	err = getLayerMountPath(&stdDriverInfo, path, &mountPathLength, &mountPathp[0])
 	if err != nil {
-		err = makeErrorf(err, title, "(second call) id=%s flavour=%d", id, info.Flavour)
+		err = hcserror.Errorf(err, title, "(second call) path=%s", path)
 		logrus.Error(err)
 		return "", err
 	}
 
-	path := syscall.UTF16ToString(mountPathp[0:])
-	logrus.Debugf(title+"succeeded flavour=%d id=%s path=%s", info.Flavour, id, path)
-	return path, nil
+	mountPath := syscall.UTF16ToString(mountPathp[0:])
+	logrus.Debugf(title+"succeeded path=%s mountPath=%s", path, mountPath)
+	return mountPath, nil
 }

+ 8 - 4
vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/getsharedbaseimages.go

@@ -1,6 +1,10 @@
-package hcsshim
+package wclayer
 
-import "github.com/sirupsen/logrus"
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"github.com/sirupsen/logrus"
+)
 
 // GetSharedBaseImages will enumerate the images stored in the common central
 // image store and return descriptive info about those images for the purpose
@@ -12,11 +16,11 @@ func GetSharedBaseImages() (imageData string, err error) {
 	var buffer *uint16
 	err = getBaseImages(&buffer)
 	if err != nil {
-		err = makeError(err, title, "")
+		err = hcserror.New(err, title, "")
 		logrus.Error(err)
 		return
 	}
-	imageData = convertAndFreeCoTaskMemString(buffer)
+	imageData = interop.ConvertAndFreeCoTaskMemString(buffer)
 	logrus.Debugf(title+" - succeeded output=%s", imageData)
 	return
 }

+ 24 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/grantvmaccess.go

@@ -0,0 +1,24 @@
+package wclayer
+
+import (
+	"fmt"
+
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// GrantVmAccess adds access to a file for a given VM
+func GrantVmAccess(vmid string, filepath string) error {
+	title := fmt.Sprintf("hcsshim::GrantVmAccess id:%s path:%s ", vmid, filepath)
+	logrus.Debugf(title)
+
+	err := grantVmAccess(vmid, filepath)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", filepath)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title + " - succeeded")
+	return nil
+}

+ 24 - 40
vendor/github.com/Microsoft/hcsshim/importlayer.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/importlayer.go

@@ -1,4 +1,4 @@
-package hcsshim
+package wclayer
 
 import (
 	"errors"
@@ -7,6 +7,8 @@ import (
 	"path/filepath"
 
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/safefile"
 	"github.com/sirupsen/logrus"
 )
 
@@ -14,9 +16,9 @@ import (
 // that into a layer with the id layerId.  Note that in order to correctly populate
 // the layer and interperet the transport format, all parent layers must already
 // be present on the system at the paths provided in parentLayerPaths.
-func ImportLayer(info DriverInfo, layerID string, importFolderPath string, parentLayerPaths []string) error {
+func ImportLayer(path string, importFolderPath string, parentLayerPaths []string) error {
 	title := "hcsshim::ImportLayer "
-	logrus.Debugf(title+"flavour %d layerId %s folder %s", info.Flavour, layerID, importFolderPath)
+	logrus.Debugf(title+"path %s folder %s", path, importFolderPath)
 
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -24,21 +26,14 @@ func ImportLayer(info DriverInfo, layerID string, importFolderPath string, paren
 		return err
 	}
 
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
+	err = importLayer(&stdDriverInfo, path, importFolderPath, layers)
 	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s folder=%s", path, importFolderPath)
 		logrus.Error(err)
 		return err
 	}
 
-	err = importLayer(&infop, layerID, importFolderPath, layers)
-	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s flavour=%d folder=%s", layerID, info.Flavour, importFolderPath)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"succeeded flavour=%d layerId=%s folder=%s", info.Flavour, layerID, importFolderPath)
+	logrus.Debugf(title+"succeeded path=%s folder=%s", path, importFolderPath)
 	return nil
 }
 
@@ -73,7 +68,7 @@ func (w *FilterLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 	}
 	err := importLayerNext(w.context, name, fileInfo)
 	if err != nil {
-		return makeError(err, "ImportLayerNext", "")
+		return hcserror.New(err, "ImportLayerNext", "")
 	}
 	return nil
 }
@@ -92,7 +87,7 @@ func (w *FilterLayerWriter) Remove(name string) error {
 	}
 	err := importLayerNext(w.context, name, nil)
 	if err != nil {
-		return makeError(err, "ImportLayerNext", "")
+		return hcserror.New(err, "ImportLayerNext", "")
 	}
 	return nil
 }
@@ -101,7 +96,7 @@ func (w *FilterLayerWriter) Remove(name string) error {
 func (w *FilterLayerWriter) Write(b []byte) (int, error) {
 	err := importLayerWrite(w.context, b)
 	if err != nil {
-		err = makeError(err, "ImportLayerWrite", "")
+		err = hcserror.New(err, "ImportLayerWrite", "")
 		return 0, err
 	}
 	return len(b), err
@@ -113,7 +108,7 @@ func (w *FilterLayerWriter) Close() (err error) {
 	if w.context != 0 {
 		err = importLayerEnd(w.context)
 		if err != nil {
-			err = makeError(err, "ImportLayerEnd", "")
+			err = hcserror.New(err, "ImportLayerEnd", "")
 		}
 		w.context = 0
 	}
@@ -122,8 +117,6 @@ func (w *FilterLayerWriter) Close() (err error) {
 
 type legacyLayerWriterWrapper struct {
 	*legacyLayerWriter
-	info             DriverInfo
-	layerID          string
 	path             string
 	parentLayerPaths []string
 }
@@ -136,28 +129,26 @@ func (r *legacyLayerWriterWrapper) Close() error {
 		return err
 	}
 
-	info := r.info
-	info.HomeDir = ""
-	if err = ImportLayer(info, r.destRoot.Name(), r.path, r.parentLayerPaths); err != nil {
+	if err = ImportLayer(r.destRoot.Name(), r.path, r.parentLayerPaths); err != nil {
 		return err
 	}
 	for _, name := range r.Tombstones {
-		if err = removeRelative(name, r.destRoot); err != nil && !os.IsNotExist(err) {
+		if err = safefile.RemoveRelative(name, r.destRoot); err != nil && !os.IsNotExist(err) {
 			return err
 		}
 	}
 	// Add any hard links that were collected.
 	for _, lnk := range r.PendingLinks {
-		if err = removeRelative(lnk.Path, r.destRoot); err != nil && !os.IsNotExist(err) {
+		if err = safefile.RemoveRelative(lnk.Path, r.destRoot); err != nil && !os.IsNotExist(err) {
 			return err
 		}
-		if err = linkRelative(lnk.Target, lnk.TargetRoot, lnk.Path, r.destRoot); err != nil {
+		if err = safefile.LinkRelative(lnk.Target, lnk.TargetRoot, lnk.Path, r.destRoot); err != nil {
 			return err
 		}
 	}
 	// Prepare the utility VM for use if one is present in the layer.
 	if r.HasUtilityVM {
-		err := ensureNotReparsePointRelative("UtilityVM", r.destRoot)
+		err := safefile.EnsureNotReparsePointRelative("UtilityVM", r.destRoot)
 		if err != nil {
 			return err
 		}
@@ -172,10 +163,10 @@ func (r *legacyLayerWriterWrapper) Close() error {
 // NewLayerWriter returns a new layer writer for creating a layer on disk.
 // The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges
 // to call this and any methods on the resulting LayerWriter.
-func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string) (LayerWriter, error) {
+func NewLayerWriter(path string, parentLayerPaths []string) (LayerWriter, error) {
 	if len(parentLayerPaths) == 0 {
 		// This is a base layer. It gets imported differently.
-		f, err := openRoot(filepath.Join(info.HomeDir, layerID))
+		f, err := safefile.OpenRoot(path)
 		if err != nil {
 			return nil, err
 		}
@@ -187,19 +178,17 @@ func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string)
 	if procImportLayerBegin.Find() != nil {
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// legacy export code path.
-		path, err := ioutil.TempDir("", "hcs")
+		importPath, err := ioutil.TempDir("", "hcs")
 		if err != nil {
 			return nil, err
 		}
-		w, err := newLegacyLayerWriter(path, parentLayerPaths, filepath.Join(info.HomeDir, layerID))
+		w, err := newLegacyLayerWriter(importPath, parentLayerPaths, path)
 		if err != nil {
 			return nil, err
 		}
 		return &legacyLayerWriterWrapper{
 			legacyLayerWriter: w,
-			info:              info,
-			layerID:           layerID,
-			path:              path,
+			path:              importPath,
 			parentLayerPaths:  parentLayerPaths,
 		}, nil
 	}
@@ -208,15 +197,10 @@ func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string)
 		return nil, err
 	}
 
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		return nil, err
-	}
-
 	w := &FilterLayerWriter{}
-	err = importLayerBegin(&infop, layerID, layers, &w.context)
+	err = importLayerBegin(&stdDriverInfo, path, layers, &w.context)
 	if err != nil {
-		return nil, makeError(err, "ImportLayerStart", "")
+		return nil, hcserror.New(err, "ImportLayerStart", "")
 	}
 	return w, nil
 }

+ 25 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerexists.go

@@ -0,0 +1,25 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// LayerExists will return true if a layer with the given id exists and is known
+// to the system.
+func LayerExists(path string) (bool, error) {
+	title := "hcsshim::LayerExists "
+	logrus.Debugf(title+"path %s", path)
+
+	// Call the procedure itself.
+	var exists uint32
+	err := layerExists(&stdDriverInfo, path, &exists)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", path)
+		logrus.Error(err)
+		return false, err
+	}
+
+	logrus.Debugf(title+"succeeded path=%s exists=%d", path, exists)
+	return exists != 0, nil
+}

+ 13 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go

@@ -0,0 +1,13 @@
+package wclayer
+
+import (
+	"path/filepath"
+
+	"github.com/Microsoft/hcsshim/internal/guid"
+)
+
+// LayerID returns the layer ID of a layer on disk.
+func LayerID(path string) (guid.GUID, error) {
+	_, file := filepath.Split(path)
+	return NameToGuid(file)
+}

+ 8 - 23
vendor/github.com/Microsoft/hcsshim/layerutils.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go

@@ -1,12 +1,12 @@
-package hcsshim
+package wclayer
 
 // This file contains utility functions to support storage (graph) related
 // functionality.
 
 import (
-	"path/filepath"
 	"syscall"
 
+	"github.com/Microsoft/hcsshim/internal/guid"
 	"github.com/sirupsen/logrus"
 )
 
@@ -22,28 +22,16 @@ struct DriverInfo {
     LPCWSTR HomeDir;
 };
 */
-type DriverInfo struct {
-	Flavour int
-	HomeDir string
-}
 
 type driverInfo struct {
 	Flavour  int
 	HomeDirp *uint16
 }
 
-func convertDriverInfo(info DriverInfo) (driverInfo, error) {
-	homedirp, err := syscall.UTF16PtrFromString(info.HomeDir)
-	if err != nil {
-		logrus.Debugf("Failed conversion of home to pointer for driver info: %s", err.Error())
-		return driverInfo{}, err
-	}
-
-	return driverInfo{
-		Flavour:  info.Flavour,
-		HomeDirp: homedirp,
-	}, nil
-}
+var (
+	utf16EmptyString uint16
+	stdDriverInfo    = driverInfo{1, &utf16EmptyString}
+)
 
 /* To pass into syscall, we need a struct matching the following:
 typedef struct _WC_LAYER_DESCRIPTOR {
@@ -75,7 +63,7 @@ typedef struct _WC_LAYER_DESCRIPTOR {
 } WC_LAYER_DESCRIPTOR, *PWC_LAYER_DESCRIPTOR;
 */
 type WC_LAYER_DESCRIPTOR struct {
-	LayerId GUID
+	LayerId guid.GUID
 	Flags   uint32
 	Pathp   *uint16
 }
@@ -85,10 +73,7 @@ func layerPathsToDescriptors(parentLayerPaths []string) ([]WC_LAYER_DESCRIPTOR,
 	var layers []WC_LAYER_DESCRIPTOR
 
 	for i := 0; i < len(parentLayerPaths); i++ {
-		// Create a layer descriptor, using the folder name
-		// as the source for a GUID LayerId
-		_, folderName := filepath.Split(parentLayerPaths[i])
-		g, err := NameToGuid(folderName)
+		g, err := LayerID(parentLayerPaths[i])
 		if err != nil {
 			logrus.Debugf("Failed to convert name to guid %s", err)
 			return nil, err

+ 51 - 63
vendor/github.com/Microsoft/hcsshim/legacy.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go

@@ -1,4 +1,4 @@
-package hcsshim
+package wclayer
 
 import (
 	"bufio"
@@ -6,12 +6,15 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
 	"syscall"
 
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/longpath"
+	"github.com/Microsoft/hcsshim/internal/safefile"
 )
 
 var errorIterationCanceled = errors.New("")
@@ -34,23 +37,6 @@ func openFileOrDir(path string, mode uint32, createDisposition uint32) (file *os
 	return winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createDisposition)
 }
 
-func makeLongAbsPath(path string) (string, error) {
-	if strings.HasPrefix(path, `\\?\`) || strings.HasPrefix(path, `\\.\`) {
-		return path, nil
-	}
-	if !filepath.IsAbs(path) {
-		absPath, err := filepath.Abs(path)
-		if err != nil {
-			return "", err
-		}
-		path = absPath
-	}
-	if strings.HasPrefix(path, `\\`) {
-		return `\\?\UNC\` + path[2:], nil
-	}
-	return `\\?\` + path, nil
-}
-
 func hasPathPrefix(p, prefix string) bool {
 	return strings.HasPrefix(p, prefix) && len(p) > len(prefix) && p[len(prefix)] == '\\'
 }
@@ -106,7 +92,7 @@ func readTombstones(path string) (map[string]([]string), error) {
 }
 
 func (r *legacyLayerReader) walkUntilCancelled() error {
-	root, err := makeLongAbsPath(r.root)
+	root, err := longpath.LongAbs(r.root)
 	if err != nil {
 		return err
 	}
@@ -283,7 +269,7 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
 		if err != nil {
 			return
 		}
-		fileInfo.FileAttributes = uintptr(attr)
+		fileInfo.FileAttributes = attr
 		beginning := int64(4)
 
 		// Find the accurate file size.
@@ -349,6 +335,7 @@ type legacyLayerWriter struct {
 	destRoot        *os.File
 	parentRoots     []*os.File
 	currentFile     *os.File
+	bufWriter       *bufio.Writer
 	currentFileName string
 	currentFileRoot *os.File
 	backupWriter    *winio.BackupFileWriter
@@ -373,21 +360,22 @@ func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) (w
 			w = nil
 		}
 	}()
-	w.root, err = openRoot(root)
+	w.root, err = safefile.OpenRoot(root)
 	if err != nil {
 		return
 	}
-	w.destRoot, err = openRoot(destRoot)
+	w.destRoot, err = safefile.OpenRoot(destRoot)
 	if err != nil {
 		return
 	}
 	for _, r := range parentRoots {
-		f, err := openRoot(r)
+		f, err := safefile.OpenRoot(r)
 		if err != nil {
 			return w, err
 		}
 		w.parentRoots = append(w.parentRoots, f)
 	}
+	w.bufWriter = bufio.NewWriterSize(ioutil.Discard, 65536)
 	return
 }
 
@@ -408,7 +396,7 @@ func (w *legacyLayerWriter) CloseRoots() {
 
 func (w *legacyLayerWriter) initUtilityVM() error {
 	if !w.HasUtilityVM {
-		err := mkdirRelative(utilityVMPath, w.destRoot)
+		err := safefile.MkdirRelative(utilityVMPath, w.destRoot)
 		if err != nil {
 			return err
 		}
@@ -426,6 +414,11 @@ func (w *legacyLayerWriter) initUtilityVM() error {
 }
 
 func (w *legacyLayerWriter) reset() error {
+	err := w.bufWriter.Flush()
+	if err != nil {
+		return err
+	}
+	w.bufWriter.Reset(ioutil.Discard)
 	if w.currentIsDir {
 		r := w.currentFile
 		br := winio.NewBackupStreamReader(r)
@@ -449,7 +442,7 @@ func (w *legacyLayerWriter) reset() error {
 				// describes a directory reparse point. Delete the placeholder
 				// directory to prevent future files being added into the
 				// destination of the reparse point during the ImportLayer call
-				if err := removeRelative(w.currentFileName, w.currentFileRoot); err != nil {
+				if err := safefile.RemoveRelative(w.currentFileName, w.currentFileRoot); err != nil {
 					return err
 				}
 				w.pendingDirs = append(w.pendingDirs, pendingDir{Path: w.currentFileName, Root: w.currentFileRoot})
@@ -474,13 +467,13 @@ func (w *legacyLayerWriter) reset() error {
 
 // copyFileWithMetadata copies a file using the backup/restore APIs in order to preserve metadata
 func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
-	src, err := openRelative(
+	src, err := safefile.OpenRelative(
 		subPath,
 		srcRoot,
 		syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY,
 		syscall.FILE_SHARE_READ,
-		_FILE_OPEN,
-		_FILE_OPEN_REPARSE_POINT)
+		safefile.FILE_OPEN,
+		safefile.FILE_OPEN_REPARSE_POINT)
 	if err != nil {
 		return nil, err
 	}
@@ -495,14 +488,14 @@ func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool
 
 	extraFlags := uint32(0)
 	if isDir {
-		extraFlags |= _FILE_DIRECTORY_FILE
+		extraFlags |= safefile.FILE_DIRECTORY_FILE
 	}
-	dest, err := openRelative(
+	dest, err := safefile.OpenRelative(
 		subPath,
 		destRoot,
 		syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
 		syscall.FILE_SHARE_READ,
-		_FILE_CREATE,
+		safefile.FILE_CREATE,
 		extraFlags)
 	if err != nil {
 		return nil, err
@@ -534,7 +527,7 @@ func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool
 // the file names in the provided map and just copies those files.
 func cloneTree(srcRoot *os.File, destRoot *os.File, subPath string, mutatedFiles map[string]bool) error {
 	var di []dirInfo
-	err := ensureNotReparsePointRelative(subPath, srcRoot)
+	err := safefile.EnsureNotReparsePointRelative(subPath, srcRoot)
 	if err != nil {
 		return err
 	}
@@ -566,18 +559,12 @@ func cloneTree(srcRoot *os.File, destRoot *os.File, subPath string, mutatedFiles
 				di = append(di, dirInfo{path: relPath, fileInfo: *fi})
 			}
 		} else {
-			err = linkRelative(relPath, srcRoot, relPath, destRoot)
+			err = safefile.LinkRelative(relPath, srcRoot, relPath, destRoot)
 			if err != nil {
 				return err
 			}
 		}
 
-		// Don't recurse on reparse points in go1.8 and older. Filepath.Walk
-		// handles this in go1.9 and newer.
-		if isDir && isReparsePoint && shouldSkipDirectoryReparse {
-			return filepath.SkipDir
-		}
-
 		return nil
 	})
 	if err != nil {
@@ -604,9 +591,9 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
 			return errors.New("invalid UtilityVM layer")
 		}
-		createDisposition := uint32(_FILE_OPEN)
+		createDisposition := uint32(safefile.FILE_OPEN)
 		if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
-			st, err := lstatRelative(name, w.destRoot)
+			st, err := safefile.LstatRelative(name, w.destRoot)
 			if err != nil && !os.IsNotExist(err) {
 				return err
 			}
@@ -614,14 +601,14 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 				// Delete the existing file/directory if it is not the same type as this directory.
 				existingAttr := st.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 				if (uint32(fileInfo.FileAttributes)^existingAttr)&(syscall.FILE_ATTRIBUTE_DIRECTORY|syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
-					if err = removeAllRelative(name, w.destRoot); err != nil {
+					if err = safefile.RemoveAllRelative(name, w.destRoot); err != nil {
 						return err
 					}
 					st = nil
 				}
 			}
 			if st == nil {
-				if err = mkdirRelative(name, w.destRoot); err != nil {
+				if err = safefile.MkdirRelative(name, w.destRoot); err != nil {
 					return err
 				}
 			}
@@ -630,20 +617,20 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 			}
 		} else {
 			// Overwrite any existing hard link.
-			err := removeRelative(name, w.destRoot)
+			err := safefile.RemoveRelative(name, w.destRoot)
 			if err != nil && !os.IsNotExist(err) {
 				return err
 			}
-			createDisposition = _FILE_CREATE
+			createDisposition = safefile.FILE_CREATE
 		}
 
-		f, err := openRelative(
+		f, err := safefile.OpenRelative(
 			name,
 			w.destRoot,
 			syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
 			syscall.FILE_SHARE_READ,
 			createDisposition,
-			_FILE_OPEN_REPARSE_POINT,
+			safefile.FILE_OPEN_REPARSE_POINT,
 		)
 		if err != nil {
 			return err
@@ -651,7 +638,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		defer func() {
 			if f != nil {
 				f.Close()
-				removeRelative(name, w.destRoot)
+				safefile.RemoveRelative(name, w.destRoot)
 			}
 		}()
 
@@ -661,6 +648,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		}
 
 		w.backupWriter = winio.NewBackupFileWriter(f, true)
+		w.bufWriter.Reset(w.backupWriter)
 		w.currentFile = f
 		w.currentFileName = name
 		w.currentFileRoot = w.destRoot
@@ -671,7 +659,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 
 	fname := name
 	if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
-		err := mkdirRelative(name, w.root)
+		err := safefile.MkdirRelative(name, w.root)
 		if err != nil {
 			return err
 		}
@@ -679,14 +667,14 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		w.currentIsDir = true
 	}
 
-	f, err := openRelative(fname, w.root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, _FILE_CREATE, 0)
+	f, err := safefile.OpenRelative(fname, w.root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, safefile.FILE_CREATE, 0)
 	if err != nil {
 		return err
 	}
 	defer func() {
 		if f != nil {
 			f.Close()
-			removeRelative(fname, w.root)
+			safefile.RemoveRelative(fname, w.root)
 		}
 	}()
 
@@ -699,10 +687,13 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 
 	if hasPathPrefix(name, hivesPath) {
 		w.backupWriter = winio.NewBackupFileWriter(f, false)
+		w.bufWriter.Reset(w.backupWriter)
 	} else {
+		w.bufWriter.Reset(f)
 		// The file attributes are written before the stream.
-		err = binary.Write(f, binary.LittleEndian, uint32(fileInfo.FileAttributes))
+		err = binary.Write(w.bufWriter, binary.LittleEndian, uint32(fileInfo.FileAttributes))
 		if err != nil {
+			w.bufWriter.Reset(ioutil.Discard)
 			return err
 		}
 	}
@@ -744,7 +735,7 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
 		selectedRoot = w.destRoot
 	} else {
 		for _, r := range roots {
-			if _, err := lstatRelative(target, r); err != nil {
+			if _, err := safefile.LstatRelative(target, r); err != nil {
 				if !os.IsNotExist(err) {
 					return err
 				}
@@ -780,10 +771,10 @@ func (w *legacyLayerWriter) Remove(name string) error {
 		// Make sure the path exists; os.RemoveAll will not fail if the file is
 		// already gone, and this needs to be a fatal error for diagnostics
 		// purposes.
-		if _, err := lstatRelative(name, w.destRoot); err != nil {
+		if _, err := safefile.LstatRelative(name, w.destRoot); err != nil {
 			return err
 		}
-		err = removeAllRelative(name, w.destRoot)
+		err = safefile.RemoveAllRelative(name, w.destRoot)
 		if err != nil {
 			return err
 		}
@@ -795,24 +786,21 @@ func (w *legacyLayerWriter) Remove(name string) error {
 }
 
 func (w *legacyLayerWriter) Write(b []byte) (int, error) {
-	if w.backupWriter == nil {
-		if w.currentFile == nil {
-			return 0, errors.New("closed")
-		}
-		return w.currentFile.Write(b)
+	if w.backupWriter == nil && w.currentFile == nil {
+		return 0, errors.New("closed")
 	}
-	return w.backupWriter.Write(b)
+	return w.bufWriter.Write(b)
 }
 
 func (w *legacyLayerWriter) Close() error {
 	if err := w.reset(); err != nil {
 		return err
 	}
-	if err := removeRelative("tombstones.txt", w.root); err != nil && !os.IsNotExist(err) {
+	if err := safefile.RemoveRelative("tombstones.txt", w.root); err != nil && !os.IsNotExist(err) {
 		return err
 	}
 	for _, pd := range w.pendingDirs {
-		err := mkdirRelative(pd.Path, pd.Root)
+		err := safefile.MkdirRelative(pd.Path, pd.Root)
 		if err != nil {
 			return err
 		}

+ 24 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go

@@ -0,0 +1,24 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/guid"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// NameToGuid converts the given string into a GUID using the algorithm in the
+// Host Compute Service, ensuring GUIDs generated with the same string are common
+// across all clients.
+func NameToGuid(name string) (id guid.GUID, err error) {
+	title := "hcsshim::NameToGuid "
+
+	err = nameToGuid(name, &id)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "name=%s", name)
+		logrus.Error(err)
+		return
+	}
+
+	logrus.Debugf(title+"name:%s guid:%s", name, id.String())
+	return
+}

+ 8 - 14
vendor/github.com/Microsoft/hcsshim/preparelayer.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/preparelayer.go

@@ -1,21 +1,22 @@
-package hcsshim
+package wclayer
 
 import (
 	"sync"
 
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 	"github.com/sirupsen/logrus"
 )
 
 var prepareLayerLock sync.Mutex
 
-// PrepareLayer finds a mounted read-write layer matching layerId and enables the
+// PrepareLayer finds a mounted read-write layer matching path and enables the
 // the filesystem filter for use on that layer.  This requires the paths to all
 // parent layers, and is necessary in order to view or interact with the layer
 // as an actual filesystem (reading and writing files, creating directories, etc).
 // Disabling the filter must be done via UnprepareLayer.
-func PrepareLayer(info DriverInfo, layerId string, parentLayerPaths []string) error {
+func PrepareLayer(path string, parentLayerPaths []string) error {
 	title := "hcsshim::PrepareLayer "
-	logrus.Debugf(title+"flavour %d layerId %s", info.Flavour, layerId)
+	logrus.Debugf(title+"path %s", path)
 
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -23,24 +24,17 @@ func PrepareLayer(info DriverInfo, layerId string, parentLayerPaths []string) er
 		return err
 	}
 
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
 	// This lock is a temporary workaround for a Windows bug. Only allowing one
 	// call to prepareLayer at a time vastly reduces the chance of a timeout.
 	prepareLayerLock.Lock()
 	defer prepareLayerLock.Unlock()
-	err = prepareLayer(&infop, layerId, layers)
+	err = prepareLayer(&stdDriverInfo, path, layers)
 	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s flavour=%d", layerId, info.Flavour)
+		err = hcserror.Errorf(err, title, "path=%s", path)
 		logrus.Error(err)
 		return err
 	}
 
-	logrus.Debugf(title+"succeeded flavour=%d layerId=%s", info.Flavour, layerId)
+	logrus.Debugf(title+"succeeded path=%s", path)
 	return nil
 }

+ 1 - 1
vendor/github.com/Microsoft/hcsshim/processimage.go → vendor/github.com/Microsoft/hcsshim/internal/wclayer/processimage.go

@@ -1,4 +1,4 @@
-package hcsshim
+package wclayer
 
 import "os"
 

+ 23 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/unpreparelayer.go

@@ -0,0 +1,23 @@
+package wclayer
+
+import (
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/sirupsen/logrus"
+)
+
+// UnprepareLayer disables the filesystem filter for the read-write layer with
+// the given id.
+func UnprepareLayer(path string) error {
+	title := "hcsshim::UnprepareLayer "
+	logrus.Debugf(title+"path %s", path)
+
+	err := unprepareLayer(&stdDriverInfo, path)
+	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s", path)
+		logrus.Error(err)
+		return err
+	}
+
+	logrus.Debugf(title+"succeeded path=%s", path)
+	return nil
+}

+ 37 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go

@@ -0,0 +1,37 @@
+package wclayer
+
+import "github.com/Microsoft/hcsshim/internal/guid"
+
+//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go -winio wclayer.go
+
+//sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer?
+//sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer?
+//sys createLayer(info *driverInfo, id string, parent string) (hr error) = vmcompute.CreateLayer?
+//sys createSandboxLayer(info *driverInfo, id string, parent uintptr, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CreateSandboxLayer?
+//sys expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) = vmcompute.ExpandSandboxSize?
+//sys deactivateLayer(info *driverInfo, id string) (hr error) = vmcompute.DeactivateLayer?
+//sys destroyLayer(info *driverInfo, id string) (hr error) = vmcompute.DestroyLayer?
+//sys exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ExportLayer?
+//sys getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) = vmcompute.GetLayerMountPath?
+//sys getBaseImages(buffer **uint16) (hr error) = vmcompute.GetBaseImages?
+//sys importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ImportLayer?
+//sys layerExists(info *driverInfo, id string, exists *uint32) (hr error) = vmcompute.LayerExists?
+//sys nameToGuid(name string, guid *_guid) (hr error) = vmcompute.NameToGuid?
+//sys prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.PrepareLayer?
+//sys unprepareLayer(info *driverInfo, id string) (hr error) = vmcompute.UnprepareLayer?
+//sys processBaseImage(path string) (hr error) = vmcompute.ProcessBaseImage?
+//sys processUtilityImage(path string) (hr error) = vmcompute.ProcessUtilityImage?
+
+//sys importLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ImportLayerBegin?
+//sys importLayerNext(context uintptr, fileName string, fileInfo *winio.FileBasicInfo) (hr error) = vmcompute.ImportLayerNext?
+//sys importLayerWrite(context uintptr, buffer []byte) (hr error) = vmcompute.ImportLayerWrite?
+//sys importLayerEnd(context uintptr) (hr error) = vmcompute.ImportLayerEnd?
+
+//sys exportLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ExportLayerBegin?
+//sys exportLayerNext(context uintptr, fileName **uint16, fileInfo *winio.FileBasicInfo, fileSize *int64, deleted *uint32) (hr error) = vmcompute.ExportLayerNext?
+//sys exportLayerRead(context uintptr, buffer []byte, bytesRead *uint32) (hr error) = vmcompute.ExportLayerRead?
+//sys exportLayerEnd(context uintptr) (hr error) = vmcompute.ExportLayerEnd?
+
+//sys grantVmAccess(vmid string, filepath string) (hr error) = vmcompute.GrantVmAccess?
+
+type _guid = guid.GUID

+ 597 - 0
vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go

@@ -0,0 +1,597 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package wclayer
+
+import (
+	"syscall"
+	"unsafe"
+
+	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/interop"
+	"golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+
+	procActivateLayer       = modvmcompute.NewProc("ActivateLayer")
+	procCopyLayer           = modvmcompute.NewProc("CopyLayer")
+	procCreateLayer         = modvmcompute.NewProc("CreateLayer")
+	procCreateSandboxLayer  = modvmcompute.NewProc("CreateSandboxLayer")
+	procExpandSandboxSize   = modvmcompute.NewProc("ExpandSandboxSize")
+	procDeactivateLayer     = modvmcompute.NewProc("DeactivateLayer")
+	procDestroyLayer        = modvmcompute.NewProc("DestroyLayer")
+	procExportLayer         = modvmcompute.NewProc("ExportLayer")
+	procGetLayerMountPath   = modvmcompute.NewProc("GetLayerMountPath")
+	procGetBaseImages       = modvmcompute.NewProc("GetBaseImages")
+	procImportLayer         = modvmcompute.NewProc("ImportLayer")
+	procLayerExists         = modvmcompute.NewProc("LayerExists")
+	procNameToGuid          = modvmcompute.NewProc("NameToGuid")
+	procPrepareLayer        = modvmcompute.NewProc("PrepareLayer")
+	procUnprepareLayer      = modvmcompute.NewProc("UnprepareLayer")
+	procProcessBaseImage    = modvmcompute.NewProc("ProcessBaseImage")
+	procProcessUtilityImage = modvmcompute.NewProc("ProcessUtilityImage")
+	procImportLayerBegin    = modvmcompute.NewProc("ImportLayerBegin")
+	procImportLayerNext     = modvmcompute.NewProc("ImportLayerNext")
+	procImportLayerWrite    = modvmcompute.NewProc("ImportLayerWrite")
+	procImportLayerEnd      = modvmcompute.NewProc("ImportLayerEnd")
+	procExportLayerBegin    = modvmcompute.NewProc("ExportLayerBegin")
+	procExportLayerNext     = modvmcompute.NewProc("ExportLayerNext")
+	procExportLayerRead     = modvmcompute.NewProc("ExportLayerRead")
+	procExportLayerEnd      = modvmcompute.NewProc("ExportLayerEnd")
+	procGrantVmAccess       = modvmcompute.NewProc("GrantVmAccess")
+)
+
+func activateLayer(info *driverInfo, id string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _activateLayer(info, _p0)
+}
+
+func _activateLayer(info *driverInfo, id *uint16) (hr error) {
+	if hr = procActivateLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procActivateLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(srcId)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(dstId)
+	if hr != nil {
+		return
+	}
+	return _copyLayer(info, _p0, _p1, descriptors)
+}
+
+func _copyLayer(info *driverInfo, srcId *uint16, dstId *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p2 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p2 = &descriptors[0]
+	}
+	if hr = procCopyLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procCopyLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(srcId)), uintptr(unsafe.Pointer(dstId)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func createLayer(info *driverInfo, id string, parent string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(parent)
+	if hr != nil {
+		return
+	}
+	return _createLayer(info, _p0, _p1)
+}
+
+func _createLayer(info *driverInfo, id *uint16, parent *uint16) (hr error) {
+	if hr = procCreateLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procCreateLayer.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(parent)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func createSandboxLayer(info *driverInfo, id string, parent uintptr, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _createSandboxLayer(info, _p0, parent, descriptors)
+}
+
+func _createSandboxLayer(info *driverInfo, id *uint16, parent uintptr, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p1 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p1 = &descriptors[0]
+	}
+	if hr = procCreateSandboxLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procCreateSandboxLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(parent), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _expandSandboxSize(info, _p0, size)
+}
+
+func _expandSandboxSize(info *driverInfo, id *uint16, size uint64) (hr error) {
+	if hr = procExpandSandboxSize.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procExpandSandboxSize.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(size))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func deactivateLayer(info *driverInfo, id string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _deactivateLayer(info, _p0)
+}
+
+func _deactivateLayer(info *driverInfo, id *uint16) (hr error) {
+	if hr = procDeactivateLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procDeactivateLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func destroyLayer(info *driverInfo, id string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _destroyLayer(info, _p0)
+}
+
+func _destroyLayer(info *driverInfo, id *uint16) (hr error) {
+	if hr = procDestroyLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procDestroyLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(path)
+	if hr != nil {
+		return
+	}
+	return _exportLayer(info, _p0, _p1, descriptors)
+}
+
+func _exportLayer(info *driverInfo, id *uint16, path *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p2 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p2 = &descriptors[0]
+	}
+	if hr = procExportLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procExportLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _getLayerMountPath(info, _p0, length, buffer)
+}
+
+func _getLayerMountPath(info *driverInfo, id *uint16, length *uintptr, buffer *uint16) (hr error) {
+	if hr = procGetLayerMountPath.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procGetLayerMountPath.Addr(), 4, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(length)), uintptr(unsafe.Pointer(buffer)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func getBaseImages(buffer **uint16) (hr error) {
+	if hr = procGetBaseImages.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procGetBaseImages.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(path)
+	if hr != nil {
+		return
+	}
+	return _importLayer(info, _p0, _p1, descriptors)
+}
+
+func _importLayer(info *driverInfo, id *uint16, path *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p2 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p2 = &descriptors[0]
+	}
+	if hr = procImportLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procImportLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func layerExists(info *driverInfo, id string, exists *uint32) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _layerExists(info, _p0, exists)
+}
+
+func _layerExists(info *driverInfo, id *uint16, exists *uint32) (hr error) {
+	if hr = procLayerExists.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procLayerExists.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(exists)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func nameToGuid(name string, guid *_guid) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(name)
+	if hr != nil {
+		return
+	}
+	return _nameToGuid(_p0, guid)
+}
+
+func _nameToGuid(name *uint16, guid *_guid) (hr error) {
+	if hr = procNameToGuid.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procNameToGuid.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(guid)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _prepareLayer(info, _p0, descriptors)
+}
+
+func _prepareLayer(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
+	var _p1 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p1 = &descriptors[0]
+	}
+	if hr = procPrepareLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procPrepareLayer.Addr(), 4, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func unprepareLayer(info *driverInfo, id string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _unprepareLayer(info, _p0)
+}
+
+func _unprepareLayer(info *driverInfo, id *uint16) (hr error) {
+	if hr = procUnprepareLayer.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procUnprepareLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func processBaseImage(path string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(path)
+	if hr != nil {
+		return
+	}
+	return _processBaseImage(_p0)
+}
+
+func _processBaseImage(path *uint16) (hr error) {
+	if hr = procProcessBaseImage.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procProcessBaseImage.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func processUtilityImage(path string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(path)
+	if hr != nil {
+		return
+	}
+	return _processUtilityImage(_p0)
+}
+
+func _processUtilityImage(path *uint16) (hr error) {
+	if hr = procProcessUtilityImage.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procProcessUtilityImage.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func importLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _importLayerBegin(info, _p0, descriptors, context)
+}
+
+func _importLayerBegin(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
+	var _p1 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p1 = &descriptors[0]
+	}
+	if hr = procImportLayerBegin.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procImportLayerBegin.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), uintptr(unsafe.Pointer(context)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func importLayerNext(context uintptr, fileName string, fileInfo *winio.FileBasicInfo) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(fileName)
+	if hr != nil {
+		return
+	}
+	return _importLayerNext(context, _p0, fileInfo)
+}
+
+func _importLayerNext(context uintptr, fileName *uint16, fileInfo *winio.FileBasicInfo) (hr error) {
+	if hr = procImportLayerNext.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procImportLayerNext.Addr(), 3, uintptr(context), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(fileInfo)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func importLayerWrite(context uintptr, buffer []byte) (hr error) {
+	var _p0 *byte
+	if len(buffer) > 0 {
+		_p0 = &buffer[0]
+	}
+	if hr = procImportLayerWrite.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procImportLayerWrite.Addr(), 3, uintptr(context), uintptr(unsafe.Pointer(_p0)), uintptr(len(buffer)))
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func importLayerEnd(context uintptr) (hr error) {
+	if hr = procImportLayerEnd.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procImportLayerEnd.Addr(), 1, uintptr(context), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func exportLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(id)
+	if hr != nil {
+		return
+	}
+	return _exportLayerBegin(info, _p0, descriptors, context)
+}
+
+func _exportLayerBegin(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
+	var _p1 *WC_LAYER_DESCRIPTOR
+	if len(descriptors) > 0 {
+		_p1 = &descriptors[0]
+	}
+	if hr = procExportLayerBegin.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procExportLayerBegin.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), uintptr(unsafe.Pointer(context)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func exportLayerNext(context uintptr, fileName **uint16, fileInfo *winio.FileBasicInfo, fileSize *int64, deleted *uint32) (hr error) {
+	if hr = procExportLayerNext.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procExportLayerNext.Addr(), 5, uintptr(context), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(fileInfo)), uintptr(unsafe.Pointer(fileSize)), uintptr(unsafe.Pointer(deleted)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func exportLayerRead(context uintptr, buffer []byte, bytesRead *uint32) (hr error) {
+	var _p0 *byte
+	if len(buffer) > 0 {
+		_p0 = &buffer[0]
+	}
+	if hr = procExportLayerRead.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall6(procExportLayerRead.Addr(), 4, uintptr(context), uintptr(unsafe.Pointer(_p0)), uintptr(len(buffer)), uintptr(unsafe.Pointer(bytesRead)), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func exportLayerEnd(context uintptr) (hr error) {
+	if hr = procExportLayerEnd.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procExportLayerEnd.Addr(), 1, uintptr(context), 0, 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}
+
+func grantVmAccess(vmid string, filepath string) (hr error) {
+	var _p0 *uint16
+	_p0, hr = syscall.UTF16PtrFromString(vmid)
+	if hr != nil {
+		return
+	}
+	var _p1 *uint16
+	_p1, hr = syscall.UTF16PtrFromString(filepath)
+	if hr != nil {
+		return
+	}
+	return _grantVmAccess(_p0, _p1)
+}
+
+func _grantVmAccess(vmid *uint16, filepath *uint16) (hr error) {
+	if hr = procGrantVmAccess.Find(); hr != nil {
+		return
+	}
+	r0, _, _ := syscall.Syscall(procGrantVmAccess.Addr(), 2, uintptr(unsafe.Pointer(vmid)), uintptr(unsafe.Pointer(filepath)), 0)
+	if int32(r0) < 0 {
+		hr = interop.Win32FromHresult(r0)
+	}
+	return
+}

+ 108 - 0
vendor/github.com/Microsoft/hcsshim/layer.go

@@ -0,0 +1,108 @@
+package hcsshim
+
+import (
+	"crypto/sha1"
+	"path/filepath"
+
+	"github.com/Microsoft/hcsshim/internal/guid"
+
+	"github.com/Microsoft/hcsshim/internal/wclayer"
+)
+
+func layerPath(info *DriverInfo, id string) string {
+	return filepath.Join(info.HomeDir, id)
+}
+
+func ActivateLayer(info DriverInfo, id string) error {
+	return wclayer.ActivateLayer(layerPath(&info, id))
+}
+func CreateLayer(info DriverInfo, id, parent string) error {
+	return wclayer.CreateLayer(layerPath(&info, id), parent)
+}
+// New clients should use CreateScratchLayer instead. Kept in to preserve API compatibility.
+func CreateSandboxLayer(info DriverInfo, layerId, parentId string, parentLayerPaths []string) error {
+	return wclayer.CreateScratchLayer(layerPath(&info, layerId), parentLayerPaths)
+}
+func CreateScratchLayer(info DriverInfo, layerId, parentId string, parentLayerPaths []string) error {
+	return wclayer.CreateScratchLayer(layerPath(&info, layerId), parentLayerPaths)
+}
+func DeactivateLayer(info DriverInfo, id string) error {
+	return wclayer.DeactivateLayer(layerPath(&info, id))
+}
+func DestroyLayer(info DriverInfo, id string) error {
+	return wclayer.DestroyLayer(layerPath(&info, id))
+}
+// New clients should use ExpandScratchSize instead. Kept in to preserve API compatibility.
+func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
+	return wclayer.ExpandScratchSize(layerPath(&info, layerId), size)
+}
+func ExpandScratchSize(info DriverInfo, layerId string, size uint64) error {
+	return wclayer.ExpandScratchSize(layerPath(&info, layerId), size)
+}
+func ExportLayer(info DriverInfo, layerId string, exportFolderPath string, parentLayerPaths []string) error {
+	return wclayer.ExportLayer(layerPath(&info, layerId), exportFolderPath, parentLayerPaths)
+}
+func GetLayerMountPath(info DriverInfo, id string) (string, error) {
+	return wclayer.GetLayerMountPath(layerPath(&info, id))
+}
+func GetSharedBaseImages() (imageData string, err error) {
+	return wclayer.GetSharedBaseImages()
+}
+func ImportLayer(info DriverInfo, layerID string, importFolderPath string, parentLayerPaths []string) error {
+	return wclayer.ImportLayer(layerPath(&info, layerID), importFolderPath, parentLayerPaths)
+}
+func LayerExists(info DriverInfo, id string) (bool, error) {
+	return wclayer.LayerExists(layerPath(&info, id))
+}
+func PrepareLayer(info DriverInfo, layerId string, parentLayerPaths []string) error {
+	return wclayer.PrepareLayer(layerPath(&info, layerId), parentLayerPaths)
+}
+func ProcessBaseLayer(path string) error {
+	return wclayer.ProcessBaseLayer(path)
+}
+func ProcessUtilityVMImage(path string) error {
+	return wclayer.ProcessUtilityVMImage(path)
+}
+func UnprepareLayer(info DriverInfo, layerId string) error {
+	return wclayer.UnprepareLayer(layerPath(&info, layerId))
+}
+
+type DriverInfo struct {
+	Flavour int
+	HomeDir string
+}
+
+type FilterLayerReader = wclayer.FilterLayerReader
+type FilterLayerWriter = wclayer.FilterLayerWriter
+
+type GUID [16]byte
+
+func NameToGuid(name string) (id GUID, err error) {
+	g, err := wclayer.NameToGuid(name)
+	return GUID(g), err
+}
+
+func NewGUID(source string) *GUID {
+	h := sha1.Sum([]byte(source))
+	var g GUID
+	copy(g[0:], h[0:16])
+	return &g
+}
+
+func (g *GUID) ToString() string {
+	return (guid.GUID)(*g).String()
+}
+
+type LayerReader = wclayer.LayerReader
+
+func NewLayerReader(info DriverInfo, layerID string, parentLayerPaths []string) (LayerReader, error) {
+	return wclayer.NewLayerReader(layerPath(&info, layerID), parentLayerPaths)
+}
+
+type LayerWriter = wclayer.LayerWriter
+
+func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string) (LayerWriter, error) {
+	return wclayer.NewLayerWriter(layerPath(&info, layerID), parentLayerPaths)
+}
+
+type WC_LAYER_DESCRIPTOR = wclayer.WC_LAYER_DESCRIPTOR

+ 0 - 30
vendor/github.com/Microsoft/hcsshim/layerexists.go

@@ -1,30 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// LayerExists will return true if a layer with the given id exists and is known
-// to the system.
-func LayerExists(info DriverInfo, id string) (bool, error) {
-	title := "hcsshim::LayerExists "
-	logrus.Debugf(title+"Flavour %d ID %s", info.Flavour, id)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return false, err
-	}
-
-	// Call the procedure itself.
-	var exists uint32
-
-	err = layerExists(&infop, id, &exists)
-	if err != nil {
-		err = makeErrorf(err, title, "id=%s flavour=%d", id, info.Flavour)
-		logrus.Error(err)
-		return false, err
-	}
-
-	logrus.Debugf(title+"succeeded flavour=%d id=%s exists=%d", info.Flavour, id, exists)
-	return exists != 0, nil
-}

+ 0 - 7
vendor/github.com/Microsoft/hcsshim/legacy18.go

@@ -1,7 +0,0 @@
-// +build !go1.9
-
-package hcsshim
-
-// Due to a bug in go1.8 and before, directory reparse points need to be skipped
-// during filepath.Walk. This is fixed in go1.9
-var shouldSkipDirectoryReparse = true

+ 0 - 7
vendor/github.com/Microsoft/hcsshim/legacy19.go

@@ -1,7 +0,0 @@
-// +build go1.9
-
-package hcsshim
-
-// Due to a bug in go1.8 and before, directory reparse points need to be skipped
-// during filepath.Walk. This is fixed in go1.9
-var shouldSkipDirectoryReparse = false

+ 0 - 20
vendor/github.com/Microsoft/hcsshim/nametoguid.go

@@ -1,20 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// NameToGuid converts the given string into a GUID using the algorithm in the
-// Host Compute Service, ensuring GUIDs generated with the same string are common
-// across all clients.
-func NameToGuid(name string) (id GUID, err error) {
-	title := "hcsshim::NameToGuid "
-	logrus.Debugf(title+"Name %s", name)
-
-	err = nameToGuid(name, &id)
-	if err != nil {
-		err = makeErrorf(err, title, "name=%s", name)
-		logrus.Error(err)
-		return
-	}
-
-	return
-}

+ 15 - 327
vendor/github.com/Microsoft/hcsshim/process.go

@@ -1,384 +1,72 @@
 package hcsshim
 
 import (
-	"encoding/json"
 	"io"
-	"sync"
-	"syscall"
 	"time"
 
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hcs"
 )
 
 // ContainerError is an error encountered in HCS
 type process struct {
-	handleLock     sync.RWMutex
-	handle         hcsProcess
-	processID      int
-	container      *container
-	cachedPipes    *cachedPipes
-	callbackNumber uintptr
+	p *hcs.Process
 }
 
-type cachedPipes struct {
-	stdIn  syscall.Handle
-	stdOut syscall.Handle
-	stdErr syscall.Handle
-}
-
-type processModifyRequest struct {
-	Operation   string
-	ConsoleSize *consoleSize `json:",omitempty"`
-	CloseHandle *closeHandle `json:",omitempty"`
-}
-
-type consoleSize struct {
-	Height uint16
-	Width  uint16
-}
-
-type closeHandle struct {
-	Handle string
-}
-
-type processStatus struct {
-	ProcessID      uint32
-	Exited         bool
-	ExitCode       uint32
-	LastWaitResult int32
-}
-
-const (
-	stdIn  string = "StdIn"
-	stdOut string = "StdOut"
-	stdErr string = "StdErr"
-)
-
-const (
-	modifyConsoleSize string = "ConsoleSize"
-	modifyCloseHandle string = "CloseHandle"
-)
-
 // Pid returns the process ID of the process within the container.
 func (process *process) Pid() int {
-	return process.processID
+	return process.p.Pid()
 }
 
 // Kill signals the process to terminate but does not wait for it to finish terminating.
 func (process *process) Kill() error {
-	process.handleLock.RLock()
-	defer process.handleLock.RUnlock()
-	operation := "Kill"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	if process.handle == 0 {
-		return makeProcessError(process, operation, "", ErrAlreadyClosed)
-	}
-
-	var resultp *uint16
-	err := hcsTerminateProcess(process.handle, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return nil
+	return convertProcessError(process.p.Kill(), process)
 }
 
 // Wait waits for the process to exit.
 func (process *process) Wait() error {
-	operation := "Wait"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
-	if err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return nil
+	return convertProcessError(process.p.Wait(), process)
 }
 
 // WaitTimeout waits for the process to exit or the duration to elapse. It returns
 // false if timeout occurs.
 func (process *process) WaitTimeout(timeout time.Duration) error {
-	operation := "WaitTimeout"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, &timeout)
-	if err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return nil
+	return convertProcessError(process.p.WaitTimeout(timeout), process)
 }
 
 // ExitCode returns the exit code of the process. The process must have
 // already terminated.
 func (process *process) ExitCode() (int, error) {
-	process.handleLock.RLock()
-	defer process.handleLock.RUnlock()
-	operation := "ExitCode"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	if process.handle == 0 {
-		return 0, makeProcessError(process, operation, "", ErrAlreadyClosed)
-	}
-
-	properties, err := process.properties()
+	code, err := process.p.ExitCode()
 	if err != nil {
-		return 0, makeProcessError(process, operation, "", err)
-	}
-
-	if properties.Exited == false {
-		return 0, makeProcessError(process, operation, "", ErrInvalidProcessState)
-	}
-
-	if properties.LastWaitResult != 0 {
-		return 0, makeProcessError(process, operation, "", syscall.Errno(properties.LastWaitResult))
+		err = convertProcessError(err, process)
 	}
-
-	logrus.Debugf(title+" succeeded processid=%d exitCode=%d", process.processID, properties.ExitCode)
-	return int(properties.ExitCode), nil
+	return code, err
 }
 
 // ResizeConsole resizes the console of the process.
 func (process *process) ResizeConsole(width, height uint16) error {
-	process.handleLock.RLock()
-	defer process.handleLock.RUnlock()
-	operation := "ResizeConsole"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	if process.handle == 0 {
-		return makeProcessError(process, operation, "", ErrAlreadyClosed)
-	}
-
-	modifyRequest := processModifyRequest{
-		Operation: modifyConsoleSize,
-		ConsoleSize: &consoleSize{
-			Height: height,
-			Width:  width,
-		},
-	}
-
-	modifyRequestb, err := json.Marshal(modifyRequest)
-	if err != nil {
-		return err
-	}
-
-	modifyRequestStr := string(modifyRequestb)
-
-	var resultp *uint16
-	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return nil
-}
-
-func (process *process) properties() (*processStatus, error) {
-	operation := "properties"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	var (
-		resultp     *uint16
-		propertiesp *uint16
-	)
-	err := hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return nil, err
-	}
-
-	if propertiesp == nil {
-		return nil, ErrUnexpectedValue
-	}
-	propertiesRaw := convertAndFreeCoTaskMemBytes(propertiesp)
-
-	properties := &processStatus{}
-	if err := json.Unmarshal(propertiesRaw, properties); err != nil {
-		return nil, err
-	}
-
-	logrus.Debugf(title+" succeeded processid=%d, properties=%s", process.processID, propertiesRaw)
-	return properties, nil
+	return convertProcessError(process.p.ResizeConsole(width, height), process)
 }
 
 // Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
 // these pipes does not close the underlying pipes; it should be possible to
 // call this multiple times to get multiple interfaces.
 func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
-	process.handleLock.RLock()
-	defer process.handleLock.RUnlock()
-	operation := "Stdio"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	if process.handle == 0 {
-		return nil, nil, nil, makeProcessError(process, operation, "", ErrAlreadyClosed)
-	}
-
-	var stdIn, stdOut, stdErr syscall.Handle
-
-	if process.cachedPipes == nil {
-		var (
-			processInfo hcsProcessInformation
-			resultp     *uint16
-		)
-		err := hcsGetProcessInfo(process.handle, &processInfo, &resultp)
-		err = processHcsResult(err, resultp)
-		if err != nil {
-			return nil, nil, nil, makeProcessError(process, operation, "", err)
-		}
-
-		stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError
-	} else {
-		// Use cached pipes
-		stdIn, stdOut, stdErr = process.cachedPipes.stdIn, process.cachedPipes.stdOut, process.cachedPipes.stdErr
-
-		// Invalidate the cache
-		process.cachedPipes = nil
-	}
-
-	pipes, err := makeOpenFiles([]syscall.Handle{stdIn, stdOut, stdErr})
+	stdin, stdout, stderr, err := process.p.Stdio()
 	if err != nil {
-		return nil, nil, nil, makeProcessError(process, operation, "", err)
+		err = convertProcessError(err, process)
 	}
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return pipes[0], pipes[1], pipes[2], nil
+	return stdin, stdout, stderr, err
 }
 
 // CloseStdin closes the write side of the stdin pipe so that the process is
 // notified on the read side that there is no more data in stdin.
 func (process *process) CloseStdin() error {
-	process.handleLock.RLock()
-	defer process.handleLock.RUnlock()
-	operation := "CloseStdin"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	if process.handle == 0 {
-		return makeProcessError(process, operation, "", ErrAlreadyClosed)
-	}
-
-	modifyRequest := processModifyRequest{
-		Operation: modifyCloseHandle,
-		CloseHandle: &closeHandle{
-			Handle: stdIn,
-		},
-	}
-
-	modifyRequestb, err := json.Marshal(modifyRequest)
-	if err != nil {
-		return err
-	}
-
-	modifyRequestStr := string(modifyRequestb)
-
-	var resultp *uint16
-	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
-	err = processHcsResult(err, resultp)
-	if err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return nil
+	return convertProcessError(process.p.CloseStdin(), process)
 }
 
 // Close cleans up any state associated with the process but does not kill
 // or wait on it.
 func (process *process) Close() error {
-	process.handleLock.Lock()
-	defer process.handleLock.Unlock()
-	operation := "Close"
-	title := "HCSShim::Process::" + operation
-	logrus.Debugf(title+" processid=%d", process.processID)
-
-	// Don't double free this
-	if process.handle == 0 {
-		return nil
-	}
-
-	if err := process.unregisterCallback(); err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	if err := hcsCloseProcess(process.handle); err != nil {
-		return makeProcessError(process, operation, "", err)
-	}
-
-	process.handle = 0
-
-	logrus.Debugf(title+" succeeded processid=%d", process.processID)
-	return nil
-}
-
-func (process *process) registerCallback() error {
-	context := &notifcationWatcherContext{
-		channels: newChannels(),
-	}
-
-	callbackMapLock.Lock()
-	callbackNumber := nextCallback
-	nextCallback++
-	callbackMap[callbackNumber] = context
-	callbackMapLock.Unlock()
-
-	var callbackHandle hcsCallback
-	err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
-	if err != nil {
-		return err
-	}
-	context.handle = callbackHandle
-	process.callbackNumber = callbackNumber
-
-	return nil
-}
-
-func (process *process) unregisterCallback() error {
-	callbackNumber := process.callbackNumber
-
-	callbackMapLock.RLock()
-	context := callbackMap[callbackNumber]
-	callbackMapLock.RUnlock()
-
-	if context == nil {
-		return nil
-	}
-
-	handle := context.handle
-
-	if handle == 0 {
-		return nil
-	}
-
-	// hcsUnregisterProcessCallback has its own syncronization
-	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
-	err := hcsUnregisterProcessCallback(handle)
-	if err != nil {
-		return err
-	}
-
-	closeChannels(context.channels)
-
-	callbackMapLock.Lock()
-	callbackMap[callbackNumber] = nil
-	callbackMapLock.Unlock()
-
-	handle = 0
-
-	return nil
+	return convertProcessError(process.p.Close(), process)
 }

+ 0 - 27
vendor/github.com/Microsoft/hcsshim/unpreparelayer.go

@@ -1,27 +0,0 @@
-package hcsshim
-
-import "github.com/sirupsen/logrus"
-
-// UnprepareLayer disables the filesystem filter for the read-write layer with
-// the given id.
-func UnprepareLayer(info DriverInfo, layerId string) error {
-	title := "hcsshim::UnprepareLayer "
-	logrus.Debugf(title+"flavour %d layerId %s", info.Flavour, layerId)
-
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		logrus.Error(err)
-		return err
-	}
-
-	err = unprepareLayer(&infop, layerId)
-	if err != nil {
-		err = makeErrorf(err, title, "layerId=%s flavour=%d", layerId, info.Flavour)
-		logrus.Error(err)
-		return err
-	}
-
-	logrus.Debugf(title+"succeeded flavour %d layerId=%s", info.Flavour, layerId)
-	return nil
-}

+ 1 - 2
vendor/github.com/Microsoft/hcsshim/version.go

@@ -2,6 +2,5 @@ package hcsshim
 
 // IsTP4 returns whether the currently running Windows build is at least TP4.
 func IsTP4() bool {
-	// HNSCall was not present in TP4
-	return procHNSCall.Find() != nil
+	return false
 }

+ 0 - 1080
vendor/github.com/Microsoft/hcsshim/zhcsshim.go

@@ -1,1080 +0,0 @@
-// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
-
-package hcsshim
-
-import (
-	"syscall"
-	"unsafe"
-
-	"github.com/Microsoft/go-winio"
-	"golang.org/x/sys/windows"
-)
-
-var _ unsafe.Pointer
-
-// Do the interface allocations only once for common
-// Errno values.
-const (
-	errnoERROR_IO_PENDING = 997
-)
-
-var (
-	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
-)
-
-// errnoErr returns common boxed Errno values, to prevent
-// allocations at runtime.
-func errnoErr(e syscall.Errno) error {
-	switch e {
-	case 0:
-		return nil
-	case errnoERROR_IO_PENDING:
-		return errERROR_IO_PENDING
-	}
-	// TODO: add more here, after collecting data on the common
-	// error values see on Windows. (perhaps when running
-	// all.bat?)
-	return e
-}
-
-var (
-	modole32     = windows.NewLazySystemDLL("ole32.dll")
-	modiphlpapi  = windows.NewLazySystemDLL("iphlpapi.dll")
-	modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
-	modntdll     = windows.NewLazySystemDLL("ntdll.dll")
-	modkernel32  = windows.NewLazySystemDLL("kernel32.dll")
-
-	procCoTaskMemFree                      = modole32.NewProc("CoTaskMemFree")
-	procSetCurrentThreadCompartmentId      = modiphlpapi.NewProc("SetCurrentThreadCompartmentId")
-	procActivateLayer                      = modvmcompute.NewProc("ActivateLayer")
-	procCopyLayer                          = modvmcompute.NewProc("CopyLayer")
-	procCreateLayer                        = modvmcompute.NewProc("CreateLayer")
-	procCreateSandboxLayer                 = modvmcompute.NewProc("CreateSandboxLayer")
-	procExpandSandboxSize                  = modvmcompute.NewProc("ExpandSandboxSize")
-	procDeactivateLayer                    = modvmcompute.NewProc("DeactivateLayer")
-	procDestroyLayer                       = modvmcompute.NewProc("DestroyLayer")
-	procExportLayer                        = modvmcompute.NewProc("ExportLayer")
-	procGetLayerMountPath                  = modvmcompute.NewProc("GetLayerMountPath")
-	procGetBaseImages                      = modvmcompute.NewProc("GetBaseImages")
-	procImportLayer                        = modvmcompute.NewProc("ImportLayer")
-	procLayerExists                        = modvmcompute.NewProc("LayerExists")
-	procNameToGuid                         = modvmcompute.NewProc("NameToGuid")
-	procPrepareLayer                       = modvmcompute.NewProc("PrepareLayer")
-	procUnprepareLayer                     = modvmcompute.NewProc("UnprepareLayer")
-	procProcessBaseImage                   = modvmcompute.NewProc("ProcessBaseImage")
-	procProcessUtilityImage                = modvmcompute.NewProc("ProcessUtilityImage")
-	procImportLayerBegin                   = modvmcompute.NewProc("ImportLayerBegin")
-	procImportLayerNext                    = modvmcompute.NewProc("ImportLayerNext")
-	procImportLayerWrite                   = modvmcompute.NewProc("ImportLayerWrite")
-	procImportLayerEnd                     = modvmcompute.NewProc("ImportLayerEnd")
-	procExportLayerBegin                   = modvmcompute.NewProc("ExportLayerBegin")
-	procExportLayerNext                    = modvmcompute.NewProc("ExportLayerNext")
-	procExportLayerRead                    = modvmcompute.NewProc("ExportLayerRead")
-	procExportLayerEnd                     = modvmcompute.NewProc("ExportLayerEnd")
-	procHcsEnumerateComputeSystems         = modvmcompute.NewProc("HcsEnumerateComputeSystems")
-	procHcsCreateComputeSystem             = modvmcompute.NewProc("HcsCreateComputeSystem")
-	procHcsOpenComputeSystem               = modvmcompute.NewProc("HcsOpenComputeSystem")
-	procHcsCloseComputeSystem              = modvmcompute.NewProc("HcsCloseComputeSystem")
-	procHcsStartComputeSystem              = modvmcompute.NewProc("HcsStartComputeSystem")
-	procHcsShutdownComputeSystem           = modvmcompute.NewProc("HcsShutdownComputeSystem")
-	procHcsTerminateComputeSystem          = modvmcompute.NewProc("HcsTerminateComputeSystem")
-	procHcsPauseComputeSystem              = modvmcompute.NewProc("HcsPauseComputeSystem")
-	procHcsResumeComputeSystem             = modvmcompute.NewProc("HcsResumeComputeSystem")
-	procHcsGetComputeSystemProperties      = modvmcompute.NewProc("HcsGetComputeSystemProperties")
-	procHcsModifyComputeSystem             = modvmcompute.NewProc("HcsModifyComputeSystem")
-	procHcsRegisterComputeSystemCallback   = modvmcompute.NewProc("HcsRegisterComputeSystemCallback")
-	procHcsUnregisterComputeSystemCallback = modvmcompute.NewProc("HcsUnregisterComputeSystemCallback")
-	procHcsCreateProcess                   = modvmcompute.NewProc("HcsCreateProcess")
-	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")
-	procHcsModifyServiceSettings           = modvmcompute.NewProc("HcsModifyServiceSettings")
-	procHNSCall                            = modvmcompute.NewProc("HNSCall")
-	procNtCreateFile                       = modntdll.NewProc("NtCreateFile")
-	procNtSetInformationFile               = modntdll.NewProc("NtSetInformationFile")
-	procRtlNtStatusToDosErrorNoTeb         = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
-	procLocalAlloc                         = modkernel32.NewProc("LocalAlloc")
-	procLocalFree                          = modkernel32.NewProc("LocalFree")
-)
-
-func coTaskMemFree(buffer unsafe.Pointer) {
-	syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(buffer), 0, 0)
-	return
-}
-
-func SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) {
-	r0, _, _ := syscall.Syscall(procSetCurrentThreadCompartmentId.Addr(), 1, uintptr(compartmentId), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func activateLayer(info *driverInfo, id string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _activateLayer(info, _p0)
-}
-
-func _activateLayer(info *driverInfo, id *uint16) (hr error) {
-	if hr = procActivateLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procActivateLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(srcId)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(dstId)
-	if hr != nil {
-		return
-	}
-	return _copyLayer(info, _p0, _p1, descriptors)
-}
-
-func _copyLayer(info *driverInfo, srcId *uint16, dstId *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p2 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p2 = &descriptors[0]
-	}
-	if hr = procCopyLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procCopyLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(srcId)), uintptr(unsafe.Pointer(dstId)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func createLayer(info *driverInfo, id string, parent string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(parent)
-	if hr != nil {
-		return
-	}
-	return _createLayer(info, _p0, _p1)
-}
-
-func _createLayer(info *driverInfo, id *uint16, parent *uint16) (hr error) {
-	if hr = procCreateLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procCreateLayer.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(parent)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(parent)
-	if hr != nil {
-		return
-	}
-	return _createSandboxLayer(info, _p0, _p1, descriptors)
-}
-
-func _createSandboxLayer(info *driverInfo, id *uint16, parent *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p2 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p2 = &descriptors[0]
-	}
-	if hr = procCreateSandboxLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procCreateSandboxLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(parent)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _expandSandboxSize(info, _p0, size)
-}
-
-func _expandSandboxSize(info *driverInfo, id *uint16, size uint64) (hr error) {
-	if hr = procExpandSandboxSize.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procExpandSandboxSize.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(size))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func deactivateLayer(info *driverInfo, id string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _deactivateLayer(info, _p0)
-}
-
-func _deactivateLayer(info *driverInfo, id *uint16) (hr error) {
-	if hr = procDeactivateLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procDeactivateLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func destroyLayer(info *driverInfo, id string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _destroyLayer(info, _p0)
-}
-
-func _destroyLayer(info *driverInfo, id *uint16) (hr error) {
-	if hr = procDestroyLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procDestroyLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(path)
-	if hr != nil {
-		return
-	}
-	return _exportLayer(info, _p0, _p1, descriptors)
-}
-
-func _exportLayer(info *driverInfo, id *uint16, path *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p2 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p2 = &descriptors[0]
-	}
-	if hr = procExportLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procExportLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _getLayerMountPath(info, _p0, length, buffer)
-}
-
-func _getLayerMountPath(info *driverInfo, id *uint16, length *uintptr, buffer *uint16) (hr error) {
-	if hr = procGetLayerMountPath.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procGetLayerMountPath.Addr(), 4, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(length)), uintptr(unsafe.Pointer(buffer)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func getBaseImages(buffer **uint16) (hr error) {
-	if hr = procGetBaseImages.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procGetBaseImages.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(path)
-	if hr != nil {
-		return
-	}
-	return _importLayer(info, _p0, _p1, descriptors)
-}
-
-func _importLayer(info *driverInfo, id *uint16, path *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p2 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p2 = &descriptors[0]
-	}
-	if hr = procImportLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procImportLayer.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(_p2)), uintptr(len(descriptors)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func layerExists(info *driverInfo, id string, exists *uint32) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _layerExists(info, _p0, exists)
-}
-
-func _layerExists(info *driverInfo, id *uint16, exists *uint32) (hr error) {
-	if hr = procLayerExists.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procLayerExists.Addr(), 3, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(exists)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func nameToGuid(name string, guid *GUID) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(name)
-	if hr != nil {
-		return
-	}
-	return _nameToGuid(_p0, guid)
-}
-
-func _nameToGuid(name *uint16, guid *GUID) (hr error) {
-	if hr = procNameToGuid.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procNameToGuid.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(guid)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _prepareLayer(info, _p0, descriptors)
-}
-
-func _prepareLayer(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR) (hr error) {
-	var _p1 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p1 = &descriptors[0]
-	}
-	if hr = procPrepareLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procPrepareLayer.Addr(), 4, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func unprepareLayer(info *driverInfo, id string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _unprepareLayer(info, _p0)
-}
-
-func _unprepareLayer(info *driverInfo, id *uint16) (hr error) {
-	if hr = procUnprepareLayer.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procUnprepareLayer.Addr(), 2, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func processBaseImage(path string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(path)
-	if hr != nil {
-		return
-	}
-	return _processBaseImage(_p0)
-}
-
-func _processBaseImage(path *uint16) (hr error) {
-	if hr = procProcessBaseImage.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procProcessBaseImage.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func processUtilityImage(path string) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(path)
-	if hr != nil {
-		return
-	}
-	return _processUtilityImage(_p0)
-}
-
-func _processUtilityImage(path *uint16) (hr error) {
-	if hr = procProcessUtilityImage.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procProcessUtilityImage.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func importLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _importLayerBegin(info, _p0, descriptors, context)
-}
-
-func _importLayerBegin(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
-	var _p1 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p1 = &descriptors[0]
-	}
-	if hr = procImportLayerBegin.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procImportLayerBegin.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), uintptr(unsafe.Pointer(context)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func importLayerNext(context uintptr, fileName string, fileInfo *winio.FileBasicInfo) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(fileName)
-	if hr != nil {
-		return
-	}
-	return _importLayerNext(context, _p0, fileInfo)
-}
-
-func _importLayerNext(context uintptr, fileName *uint16, fileInfo *winio.FileBasicInfo) (hr error) {
-	if hr = procImportLayerNext.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procImportLayerNext.Addr(), 3, uintptr(context), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(fileInfo)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func importLayerWrite(context uintptr, buffer []byte) (hr error) {
-	var _p0 *byte
-	if len(buffer) > 0 {
-		_p0 = &buffer[0]
-	}
-	if hr = procImportLayerWrite.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procImportLayerWrite.Addr(), 3, uintptr(context), uintptr(unsafe.Pointer(_p0)), uintptr(len(buffer)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func importLayerEnd(context uintptr) (hr error) {
-	if hr = procImportLayerEnd.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procImportLayerEnd.Addr(), 1, uintptr(context), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func exportLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _exportLayerBegin(info, _p0, descriptors, context)
-}
-
-func _exportLayerBegin(info *driverInfo, id *uint16, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) {
-	var _p1 *WC_LAYER_DESCRIPTOR
-	if len(descriptors) > 0 {
-		_p1 = &descriptors[0]
-	}
-	if hr = procExportLayerBegin.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procExportLayerBegin.Addr(), 5, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(_p1)), uintptr(len(descriptors)), uintptr(unsafe.Pointer(context)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func exportLayerNext(context uintptr, fileName **uint16, fileInfo *winio.FileBasicInfo, fileSize *int64, deleted *uint32) (hr error) {
-	if hr = procExportLayerNext.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procExportLayerNext.Addr(), 5, uintptr(context), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(fileInfo)), uintptr(unsafe.Pointer(fileSize)), uintptr(unsafe.Pointer(deleted)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func exportLayerRead(context uintptr, buffer []byte, bytesRead *uint32) (hr error) {
-	var _p0 *byte
-	if len(buffer) > 0 {
-		_p0 = &buffer[0]
-	}
-	if hr = procExportLayerRead.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procExportLayerRead.Addr(), 4, uintptr(context), uintptr(unsafe.Pointer(_p0)), uintptr(len(buffer)), uintptr(unsafe.Pointer(bytesRead)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func exportLayerEnd(context uintptr) (hr error) {
-	if hr = procExportLayerEnd.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procExportLayerEnd.Addr(), 1, uintptr(context), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(query)
-	if hr != nil {
-		return
-	}
-	return _hcsEnumerateComputeSystems(_p0, computeSystems, result)
-}
-
-func _hcsEnumerateComputeSystems(query *uint16, computeSystems **uint16, result **uint16) (hr error) {
-	if hr = procHcsEnumerateComputeSystems.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsEnumerateComputeSystems.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(computeSystems)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(configuration)
-	if hr != nil {
-		return
-	}
-	return _hcsCreateComputeSystem(_p0, _p1, identity, computeSystem, result)
-}
-
-func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
-	if hr = procHcsCreateComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHcsCreateComputeSystem.Addr(), 5, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), uintptr(identity), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(id)
-	if hr != nil {
-		return
-	}
-	return _hcsOpenComputeSystem(_p0, computeSystem, result)
-}
-
-func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
-	if hr = procHcsOpenComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsOpenComputeSystem.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
-	if hr = procHcsCloseComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsCloseComputeSystem.Addr(), 1, uintptr(computeSystem), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(options)
-	if hr != nil {
-		return
-	}
-	return _hcsStartComputeSystem(computeSystem, _p0, result)
-}
-
-func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
-	if hr = procHcsStartComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsStartComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(options)
-	if hr != nil {
-		return
-	}
-	return _hcsShutdownComputeSystem(computeSystem, _p0, result)
-}
-
-func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
-	if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsShutdownComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(options)
-	if hr != nil {
-		return
-	}
-	return _hcsTerminateComputeSystem(computeSystem, _p0, result)
-}
-
-func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
-	if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsTerminateComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(options)
-	if hr != nil {
-		return
-	}
-	return _hcsPauseComputeSystem(computeSystem, _p0, result)
-}
-
-func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
-	if hr = procHcsPauseComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsPauseComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(options)
-	if hr != nil {
-		return
-	}
-	return _hcsResumeComputeSystem(computeSystem, _p0, result)
-}
-
-func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
-	if hr = procHcsResumeComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsResumeComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
-	if hr != nil {
-		return
-	}
-	return _hcsGetComputeSystemProperties(computeSystem, _p0, properties, result)
-}
-
-func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
-	if hr = procHcsGetComputeSystemProperties.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHcsGetComputeSystemProperties.Addr(), 4, uintptr(computeSystem), uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(configuration)
-	if hr != nil {
-		return
-	}
-	return _hcsModifyComputeSystem(computeSystem, _p0, result)
-}
-
-func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, result **uint16) (hr error) {
-	if hr = procHcsModifyComputeSystem.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsModifyComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(configuration)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
-	if hr = procHcsRegisterComputeSystemCallback.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHcsRegisterComputeSystemCallback.Addr(), 4, uintptr(computeSystem), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
-	if hr = procHcsUnregisterComputeSystemCallback.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsUnregisterComputeSystemCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(processParameters)
-	if hr != nil {
-		return
-	}
-	return _hcsCreateProcess(computeSystem, _p0, processInformation, process, result)
-}
-
-func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
-	if hr = procHcsCreateProcess.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHcsCreateProcess.Addr(), 5, uintptr(computeSystem), uintptr(unsafe.Pointer(processParameters)), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) {
-	if hr = procHcsOpenProcess.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHcsOpenProcess.Addr(), 4, uintptr(computeSystem), uintptr(pid), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsCloseProcess(process hcsProcess) (hr error) {
-	if hr = procHcsCloseProcess.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsCloseProcess.Addr(), 1, uintptr(process), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
-	if hr = procHcsTerminateProcess.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 2, uintptr(process), uintptr(unsafe.Pointer(result)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) {
-	if hr = procHcsGetProcessInfo.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsGetProcessInfo.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) {
-	if hr = procHcsGetProcessProperties.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsGetProcessProperties.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processProperties)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(settings)
-	if hr != nil {
-		return
-	}
-	return _hcsModifyProcess(process, _p0, result)
-}
-
-func _hcsModifyProcess(process hcsProcess, settings *uint16, result **uint16) (hr error) {
-	if hr = procHcsModifyProcess.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsModifyProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
-	if hr != nil {
-		return
-	}
-	return _hcsGetServiceProperties(_p0, properties, result)
-}
-
-func _hcsGetServiceProperties(propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
-	if hr = procHcsGetServiceProperties.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsGetServiceProperties.Addr(), 3, uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
-	if hr = procHcsRegisterProcessCallback.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHcsRegisterProcessCallback.Addr(), 4, uintptr(process), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) {
-	if hr = procHcsUnregisterProcessCallback.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsUnregisterProcessCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func hcsModifyServiceSettings(settings string, result **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(settings)
-	if hr != nil {
-		return
-	}
-	return _hcsModifyServiceSettings(_p0, result)
-}
-
-func _hcsModifyServiceSettings(settings *uint16, result **uint16) (hr error) {
-	if hr = procHcsModifyServiceSettings.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall(procHcsModifyServiceSettings.Addr(), 2, uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)), 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func _hnsCall(method string, path string, object string, response **uint16) (hr error) {
-	var _p0 *uint16
-	_p0, hr = syscall.UTF16PtrFromString(method)
-	if hr != nil {
-		return
-	}
-	var _p1 *uint16
-	_p1, hr = syscall.UTF16PtrFromString(path)
-	if hr != nil {
-		return
-	}
-	var _p2 *uint16
-	_p2, hr = syscall.UTF16PtrFromString(object)
-	if hr != nil {
-		return
-	}
-	return __hnsCall(_p0, _p1, _p2, response)
-}
-
-func __hnsCall(method *uint16, path *uint16, object *uint16, response **uint16) (hr error) {
-	if hr = procHNSCall.Find(); hr != nil {
-		return
-	}
-	r0, _, _ := syscall.Syscall6(procHNSCall.Addr(), 4, uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)), 0, 0)
-	if int32(r0) < 0 {
-		hr = syscall.Errno(win32FromHresult(r0))
-	}
-	return
-}
-
-func ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) {
-	r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(fileAttributes), uintptr(shareAccess), uintptr(createDisposition), uintptr(createOptions), uintptr(unsafe.Pointer(eaBuffer)), uintptr(eaLength), 0)
-	status = uint32(r0)
-	return
-}
-
-func ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) {
-	r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(information), uintptr(length), uintptr(class), 0)
-	status = uint32(r0)
-	return
-}
-
-func rtlNtStatusToDosError(status uint32) (winerr error) {
-	r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
-	if r0 != 0 {
-		winerr = syscall.Errno(r0)
-	}
-	return
-}
-
-func localAlloc(flags uint32, size int) (ptr uintptr) {
-	r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(size), 0)
-	ptr = uintptr(r0)
-	return
-}
-
-func localFree(ptr uintptr) {
-	syscall.Syscall(procLocalFree.Addr(), 1, uintptr(ptr), 0, 0)
-	return
-}

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