Forráskód Böngészése

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

[18.09] Buildkit cherry-picks
Andrew Hsu 6 éve
szülő
commit
00a9cf39ed
100 módosított fájl, 5106 hozzáadás és 3608 törlés
  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
 // 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)
 	eg, ctx := errgroup.WithContext(ctx)
 
 
 	var fsCacheSize uint64
 	var fsCacheSize uint64
@@ -102,9 +102,10 @@ func (b *Backend) PruneCache(ctx context.Context) (*types.BuildCachePruneReport,
 	})
 	})
 
 
 	var buildCacheSize int64
 	var buildCacheSize int64
+	var cacheIDs []string
 	eg.Go(func() error {
 	eg.Go(func() error {
 		var err error
 		var err error
-		buildCacheSize, err = b.buildkit.Prune(ctx)
+		buildCacheSize, cacheIDs, err = b.buildkit.Prune(ctx, opts)
 		if err != nil {
 		if err != nil {
 			return errors.Wrap(err, "failed to prune build cache")
 			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 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
 // 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)
 	Build(context.Context, backend.BuildConfig) (string, error)
 
 
 	// Prune build cache
 	// Prune build cache
-	PruneCache(context.Context) (*types.BuildCachePruneReport, error)
+	PruneCache(context.Context, types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error)
 
 
 	Cancel(context.Context, string) 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
 // buildRouter is a router to talk with the build controller
 type buildRouter struct {
 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
 // 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()
 	r.initRoutes()
 	return r
 	return r
 }
 }
@@ -32,3 +36,18 @@ func (r *buildRouter) initRoutes() {
 		router.NewPostRoute("/build/cancel", r.postCancel),
 		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"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/container"
 	"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/api/types/versions"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/pkg/ioutils"
 	"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 {
 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 {
 	if err != nil {
 		return err
 		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"))
 		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.
 	// 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"))
 		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 (
 import (
 	"github.com/docker/docker/api/server/router"
 	"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"
 	"github.com/docker/docker/builder/fscache"
 )
 )
 
 
 // systemRouter provides information about the Docker system overall.
 // systemRouter provides information about the Docker system overall.
 // It gathers information about host, daemon and container events.
 // It gathers information about host, daemon and container events.
 type systemRouter struct {
 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
 // 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{
 	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{
 	r.routes = []router.Route{

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

@@ -8,6 +8,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/api/server/httputils"
 	"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"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/filters"
 	"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 {
 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))
 		w.Header().Set("Builder-Version", string(bv))
 	}
 	}
 	_, err := w.Write([]byte{'O', 'K'})
 	_, err := w.Write([]byte{'O', 'K'})

+ 57 - 0
api/swagger.yaml

@@ -1513,6 +1513,31 @@ definitions:
       aux:
       aux:
         $ref: "#/definitions/ImageID"
         $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:
   ImageID:
     type: "object"
     type: "object"
     description: "Image ID or Digest"
     description: "Image ID or Digest"
@@ -6358,6 +6383,29 @@ paths:
       produces:
       produces:
         - "application/json"
         - "application/json"
       operationId: "BuildPrune"
       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:
       responses:
         200:
         200:
           description: "No error"
           description: "No error"
@@ -6365,6 +6413,11 @@ paths:
             type: "object"
             type: "object"
             title: "BuildPruneResponse"
             title: "BuildPruneResponse"
             properties:
             properties:
+              CachesDeleted:
+                type: "array"
+                items:
+                  description: "ID of build cache object"
+                  type: "string"
               SpaceReclaimed:
               SpaceReclaimed:
                 description: "Disk space reclaimed in bytes"
                 description: "Disk space reclaimed in bytes"
                 type: "integer"
                 type: "integer"
@@ -7199,6 +7252,10 @@ paths:
                 type: "array"
                 type: "array"
                 items:
                 items:
                   $ref: "#/definitions/Volume"
                   $ref: "#/definitions/Volume"
+              BuildCache:
+                type: "array"
+                items:
+                  $ref: "#/definitions/BuildCache"
             example:
             example:
               LayersSize: 1092588
               LayersSize: 1092588
               Images:
               Images:

+ 15 - 7
api/types/types.go

@@ -543,6 +543,7 @@ type ImagesPruneReport struct {
 // BuildCachePruneReport contains the response for Engine API:
 // BuildCachePruneReport contains the response for Engine API:
 // POST "/build/prune"
 // POST "/build/prune"
 type BuildCachePruneReport struct {
 type BuildCachePruneReport struct {
+	CachesDeleted  []string
 	SpaceReclaimed uint64
 	SpaceReclaimed uint64
 }
 }
 
 
@@ -592,14 +593,21 @@ type BuildResult struct {
 
 
 // BuildCache contains information about a build cache record
 // BuildCache contains information about a build cache record
 type BuildCache struct {
 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
 	CreatedAt   time.Time
 	LastUsedAt  *time.Time
 	LastUsedAt  *time.Time
 	UsageCount  int
 	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
 		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
 	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
 	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) {
 func (s *snapshotter) getLayer(key string, withCommitted bool) (layer.Layer, error) {
 	s.mu.Lock()
 	s.mu.Lock()
 	l, ok := s.refs[key]
 	l, ok := s.refs[key]

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

@@ -29,6 +29,21 @@ import (
 	grpcmetadata "google.golang.org/grpc/metadata"
 	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() {
 func init() {
 	llbsolver.AllowNetworkHostUnstable = true
 	llbsolver.AllowNetworkHostUnstable = true
 }
 }
@@ -87,48 +102,94 @@ func (b *Builder) DiskUsage(ctx context.Context) ([]*types.BuildCache, error) {
 	var items []*types.BuildCache
 	var items []*types.BuildCache
 	for _, r := range duResp.Record {
 	for _, r := range duResp.Record {
 		items = append(items, &types.BuildCache{
 		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,
 			CreatedAt:   r.CreatedAt,
 			LastUsedAt:  r.LastUsedAt,
 			LastUsedAt:  r.LastUsedAt,
 			UsageCount:  int(r.UsageCount),
 			UsageCount:  int(r.UsageCount),
-			Parent:      r.Parent,
-			Description: r.Description,
 		})
 		})
 	}
 	}
 	return items, nil
 	return items, nil
 }
 }
 
 
 // Prune clears all reclaimable build cache
 // 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)
 	ch := make(chan *controlapi.UsageRecord)
 
 
 	eg, ctx := errgroup.WithContext(ctx)
 	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 {
 	eg.Go(func() error {
 		defer close(ch)
 		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},
 			streamProxy: streamProxy{ctx: ctx},
 			ch:          ch,
 			ch:          ch,
 		})
 		})
 	})
 	})
 
 
 	var size int64
 	var size int64
+	var cacheIDs []string
 	eg.Go(func() error {
 	eg.Go(func() error {
 		for r := range ch {
 		for r := range ch {
 			size += r.Size_
 			size += r.Size_
+			cacheIDs = append(cacheIDs, r.ID)
 		}
 		}
 		return nil
 		return nil
 	})
 	})
 
 
 	if err := eg.Wait(); err != 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
 // 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/containerimage"
 	"github.com/docker/docker/builder/builder-next/adapters/snapshot"
 	"github.com/docker/docker/builder/builder-next/adapters/snapshot"
 	containerimageexp "github.com/docker/docker/builder/builder-next/exporter"
 	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"
 	mobyworker "github.com/docker/docker/builder/builder-next/worker"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/moby/buildkit/cache"
 	"github.com/moby/buildkit/cache"
@@ -69,9 +70,20 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
 		MetadataStore: md,
 		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{
 	cm, err := cache.NewManager(cache.ManagerOpt{
-		Snapshotter:   snapshotter,
-		MetadataStore: md,
+		Snapshotter:     snapshotter,
+		MetadataStore:   md,
+		PruneRefChecker: refChecker,
 	})
 	})
 	if err != nil {
 	if err != nil {
 		return nil, err
 		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"
 	"context"
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
+	"net/url"
 
 
 	"github.com/docker/docker/api/types"
 	"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
 // 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 {
 	if err := cli.NewVersionError("1.31", "build prune"); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
 	report := types.BuildCachePruneReport{}
 	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 {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}

+ 1 - 1
client/interface.go

@@ -86,7 +86,7 @@ type DistributionAPIClient interface {
 // ImageAPIClient defines API client methods for the images
 // ImageAPIClient defines API client methods for the images
 type ImageAPIClient interface {
 type ImageAPIClient interface {
 	ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
 	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
 	BuildCancel(ctx context.Context, id string) error
 	ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
 	ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
 	ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, 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"
 	swarmrouter "github.com/docker/docker/api/server/router/swarm"
 	systemrouter "github.com/docker/docker/api/server/router/system"
 	systemrouter "github.com/docker/docker/api/server/router/system"
 	"github.com/docker/docker/api/server/router/volume"
 	"github.com/docker/docker/api/server/router/volume"
-	"github.com/docker/docker/api/types"
 	buildkit "github.com/docker/docker/builder/builder-next"
 	buildkit "github.com/docker/docker/builder/builder-next"
 	"github.com/docker/docker/builder/dockerfile"
 	"github.com/docker/docker/builder/dockerfile"
 	"github.com/docker/docker/builder/fscache"
 	"github.com/docker/docker/builder/fscache"
@@ -253,8 +252,8 @@ type routerOptions struct {
 	sessionManager *session.Manager
 	sessionManager *session.Manager
 	buildBackend   *buildbackend.Backend
 	buildBackend   *buildbackend.Backend
 	buildCache     *fscache.FSCache // legacy
 	buildCache     *fscache.FSCache // legacy
+	features       *map[string]bool
 	buildkit       *buildkit.Builder
 	buildkit       *buildkit.Builder
-	builderVersion types.BuilderVersion
 	daemon         *daemon.Daemon
 	daemon         *daemon.Daemon
 	api            *apiserver.Server
 	api            *apiserver.Server
 	cluster        *cluster.Cluster
 	cluster        *cluster.Cluster
@@ -300,20 +299,12 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
 	if err != nil {
 	if err != nil {
 		return opts, errors.Wrap(err, "failed to create buildmanager")
 		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{
 	return routerOptions{
 		sessionManager: sm,
 		sessionManager: sm,
 		buildBackend:   bb,
 		buildBackend:   bb,
 		buildCache:     buildCache,
 		buildCache:     buildCache,
 		buildkit:       bk,
 		buildkit:       bk,
-		builderVersion: bv,
+		features:       daemon.Features(),
 		daemon:         daemon,
 		daemon:         daemon,
 	}, nil
 	}, nil
 }
 }
@@ -487,9 +478,9 @@ func initRouter(opts routerOptions) {
 		checkpointrouter.NewRouter(opts.daemon, decoder),
 		checkpointrouter.NewRouter(opts.daemon, decoder),
 		container.NewRouter(opts.daemon, decoder),
 		container.NewRouter(opts.daemon, decoder),
 		image.NewRouter(opts.daemon.ImageService()),
 		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()),
 		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),
 		sessionrouter.NewRouter(opts.sessionManager),
 		swarmrouter.NewRouter(opts.cluster),
 		swarmrouter.NewRouter(opts.cluster),
 		pluginrouter.NewRouter(opts.daemon.PluginManager()),
 		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
 	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 {
 func (daemon *Daemon) restore() error {
 	containers := make(map[string]*container.Container)
 	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.reloadDebug(conf, attributes)
 	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
 	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
 	daemon.reloadShutdownTimeout(conf, attributes)
 	daemon.reloadShutdownTimeout(conf, attributes)
+	daemon.reloadFeatures(conf, attributes)
 
 
 	if err := daemon.reloadClusterDiscovery(conf, attributes); err != nil {
 	if err := daemon.reloadClusterDiscovery(conf, attributes); err != nil {
 		return err
 		return err
@@ -322,3 +323,13 @@ func (daemon *Daemon) reloadNetworkDiagnosticPort(conf *config.Config, attribute
 
 
 	return nil
 	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"
 	"strings"
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/api/types"
 	dclient "github.com/docker/docker/client"
 	dclient "github.com/docker/docker/client"
 	"github.com/docker/docker/internal/test/fakecontext"
 	"github.com/docker/docker/internal/test/fakecontext"
 	"github.com/docker/docker/internal/test/request"
 	"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.Contains(string(outBytes), "Successfully built"))
 	assert.Check(t, is.Equal(strings.Count(string(outBytes), "Using cache"), 4))
 	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)
 	assert.Check(t, err)
 
 
 	du, err = client.DiskUsage(context.TODO())
 	du, err = client.DiskUsage(context.TODO())

+ 6 - 6
vendor.conf

@@ -1,7 +1,7 @@
 # the following lines are in sorted order, FYI
 # the following lines are in sorted order, FYI
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
 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/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
 github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a
 github.com/golang/gddo 9b12a26f3fbd7397dee4e20939ddca719d840d2a
@@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.6
 golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
 golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
 
 
 # buildkit
 # buildkit
-github.com/moby/buildkit e1cd06ad6b74e4b747306c4408c451b3b6d87a89
+github.com/moby/buildkit 6812dac65e0440bb75affce1fb2175e640edc15d
 github.com/tonistiigi/fsutil b19464cd1b6a00773b4f2eb7acf9c30426f9df42
 github.com/tonistiigi/fsutil b19464cd1b6a00773b4f2eb7acf9c30426f9df42
 github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
 github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
@@ -75,7 +75,7 @@ github.com/pborman/uuid v1.0
 google.golang.org/grpc v1.12.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
 # 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/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce # v1.0.1-43-gd810dbc
 github.com/opencontainers/image-spec v1.0.1
 github.com/opencontainers/image-spec v1.0.1
 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
@@ -114,11 +114,11 @@ github.com/googleapis/gax-go v2.0.0
 google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
 google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
 
 
 # containerd
 # 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/fifo 3d5202aec260678c48179c56f40e6f38a095738c
 github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
 github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
-github.com/containerd/console 4d8a41f4ce5b9bae77c41786ea2458330f43f081
+github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
 github.com/containerd/go-runc edcf3de1f4971445c42d61f20d506b30612aa031
 github.com/containerd/go-runc edcf3de1f4971445c42d61f20d506b30612aa031
 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
 github.com/containerd/ttrpc 94dde388801693c54f88a6596f713b51a8b30b2d
 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 {
 		if err != nil {
 			return "", 0, nil, err
 			return "", 0, nil, err
 		}
 		}
-		fileInfo.FileAttributes = uintptr(attr)
+		fileInfo.FileAttributes = uint32(attr)
 	} else {
 	} else {
 		if hdr.Typeflag == tar.TypeDir {
 		if hdr.Typeflag == tar.TypeDir {
 			fileInfo.FileAttributes |= syscall.FILE_ATTRIBUTE_DIRECTORY
 			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.
 // FileBasicInfo contains file access time and file attributes information.
 type FileBasicInfo struct {
 type FileBasicInfo struct {
 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime
-	FileAttributes                                          uintptr // includes padding
+	FileAttributes                                          uint32
+	pad                                                     uint32 // padding
 }
 }
 
 
 // GetFileBasicInfo retrieves times and attributes for a file.
 // GetFileBasicInfo retrieves times and attributes for a file.

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

@@ -1,12 +1,13 @@
 # hcsshim
 # 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
 ## Contributing
----------------
+
 This project welcomes contributions and suggestions.  Most contributions require you to agree to a
 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
 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.
 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
 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.
 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
 ## 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
 [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).
 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.
 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
 package hcsshim
 
 
 import (
 import (
-	"encoding/json"
 	"fmt"
 	"fmt"
 	"os"
 	"os"
-	"sync"
-	"syscall"
 	"time"
 	"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
 // 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
 // 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
 // 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
 // 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
 // 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
 // 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
 // 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
 // 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 of Request Support in ModifySystem
-type RequestType string
+type RequestType = schema1.RequestType
 
 
 // Type of Resource Support in ModifySystem
 // Type of Resource Support in ModifySystem
-type ResourceType string
+type ResourceType = schema1.ResourceType
 
 
 // RequestType const
 // RequestType const
 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
 // 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
 // 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
 // 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() {
 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.
 // CreateContainer creates a new container with the given configuration but does not start it.
 func CreateContainer(id string, c *ContainerConfig) (Container, error) {
 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 {
 	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 != 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.
 // OpenContainer opens an existing container by ID.
 func OpenContainer(id string) (Container, error) {
 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 {
 	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
 // GetContainers gets a list of the containers on the system that match the query
 func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) {
 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.
 // Start synchronously starts the container.
 func (container *container) Start() error {
 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 {
 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 {
 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 {
 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
 // HasPendingUpdates returns true if the container has updates pending to install
 func (container *container) HasPendingUpdates() (bool, error) {
 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) {
 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 {
 	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
 	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) {
 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 {
 	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
 	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) {
 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 {
 	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
 	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.
 // CreateProcess launches a new process within the container.
 func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
 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 {
 	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.
 // OpenProcess gets an interface to an existing process within the container.
 func (container *container) OpenProcess(pid int) (Process, error) {
 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 {
 	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.
 // Close cleans up any state associated with the container but does not terminate or wait for it.
 func (container *container) Close() error {
 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 {
 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
 package hcsshim
 
 
 import (
 import (
-	"errors"
 	"fmt"
 	"fmt"
 	"syscall"
 	"syscall"
+
+	"github.com/Microsoft/hcsshim/internal/hns"
+
+	"github.com/Microsoft/hcsshim/internal/hcs"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 )
 )
 
 
 var (
 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 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
 	// 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
 	// ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
 	// decimal -2147024883 / hex 0x8007000d
 	// 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 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 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 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 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 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
 	// ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
 	// a different expected notification
 	// a different expected notification
-	ErrUnexpectedContainerExit = errors.New("unexpected container exit")
+	ErrUnexpectedContainerExit = hcs.ErrUnexpectedContainerExit
 
 
 	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
 	// ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
 	// is lost while waiting for a notification
 	// 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 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 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 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 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 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
 	// 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.
 	// 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 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 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
 	// 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
 // ProcessError is an error encountered in HCS during an operation on a Process object
 type ProcessError struct {
 type ProcessError struct {
@@ -94,6 +85,7 @@ type ProcessError struct {
 	Operation string
 	Operation string
 	ExtraInfo string
 	ExtraInfo string
 	Err       error
 	Err       error
+	Events    []hcs.ErrorEvent
 }
 }
 
 
 // ContainerError is an error encountered in HCS during an operation on a Container object
 // ContainerError is an error encountered in HCS during an operation on a Container object
@@ -102,6 +94,7 @@ type ContainerError struct {
 	Operation string
 	Operation string
 	ExtraInfo string
 	ExtraInfo string
 	Err       error
 	Err       error
+	Events    []hcs.ErrorEvent
 }
 }
 
 
 func (e *ContainerError) Error() string {
 func (e *ContainerError) Error() string {
@@ -113,7 +106,7 @@ func (e *ContainerError) Error() string {
 		return "unexpected nil container for error: " + e.Err.Error()
 		return "unexpected nil container for error: " + e.Err.Error()
 	}
 	}
 
 
-	s := "container " + e.Container.id
+	s := "container " + e.Container.system.ID()
 
 
 	if e.Operation != "" {
 	if e.Operation != "" {
 		s += " encountered an error during " + e.Operation
 		s += " encountered an error during " + e.Operation
@@ -123,11 +116,15 @@ func (e *ContainerError) Error() string {
 	case nil:
 	case nil:
 		break
 		break
 	case syscall.Errno:
 	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:
 	default:
 		s += fmt.Sprintf(": %s", e.Err.Error())
 		s += fmt.Sprintf(": %s", e.Err.Error())
 	}
 	}
 
 
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+
 	if e.ExtraInfo != "" {
 	if e.ExtraInfo != "" {
 		s += " extra info: " + 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()
 		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 != "" {
 	if e.Operation != "" {
 		s += " encountered an error during " + e.Operation
 		s += " encountered an error during " + e.Operation
 	}
 	}
@@ -167,11 +159,15 @@ func (e *ProcessError) Error() string {
 	case nil:
 	case nil:
 		break
 		break
 	case syscall.Errno:
 	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:
 	default:
 		s += fmt.Sprintf(": %s", e.Err.Error())
 		s += fmt.Sprintf(": %s", e.Err.Error())
 	}
 	}
 
 
+	for _, ev := range e.Events {
+		s += "\n" + ev.String()
+	}
+
 	return s
 	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
 // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 func IsNotExist(err error) bool {
 func IsNotExist(err error) bool {
-	err = getInnerError(err)
 	if _, ok := err.(EndpointNotFoundError); ok {
 	if _, ok := err.(EndpointNotFoundError); ok {
 		return true
 		return true
 	}
 	}
 	if _, ok := err.(NetworkNotFoundError); ok {
 	if _, ok := err.(NetworkNotFoundError); ok {
 		return true
 		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
 // IsAlreadyClosed checks if an error is caused by the Container or Process having been
 // already closed by a call to the Close() method.
 // already closed by a call to the Close() method.
 func IsAlreadyClosed(err error) bool {
 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
 // IsPending returns a boolean indicating whether the error is that
 // the requested operation is being completed in the background.
 // the requested operation is being completed in the background.
 func IsPending(err error) bool {
 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
 // IsTimeout returns a boolean indicating whether the error is caused by
 // a timeout waiting for the operation to complete.
 // a timeout waiting for the operation to complete.
 func IsTimeout(err error) bool {
 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
 // 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
 // already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
 func IsAlreadyStopped(err error) bool {
 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
 // 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
 // ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
 // is thrown from the Platform
 // is thrown from the Platform
 func IsNotSupported(err error) bool {
 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 {
 func getInnerError(err error) error {
@@ -259,3 +241,17 @@ func getInnerError(err error) error {
 	}
 	}
 	return err
 	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
 package hcsshim
 
 
 import (
 import (
-	"fmt"
 	"syscall"
 	"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 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 (
 const (
 	// Specific user-visible exit codes
 	// Specific user-visible exit codes
 	WaitErrExecFailed = 32767
 	WaitErrExecFailed = 32767
 
 
-	ERROR_GEN_FAILURE          = syscall.Errno(31)
+	ERROR_GEN_FAILURE          = hcserror.ERROR_GEN_FAILURE
 	ERROR_SHUTDOWN_IN_PROGRESS = syscall.Errno(1115)
 	ERROR_SHUTDOWN_IN_PROGRESS = syscall.Errno(1115)
 	WSAEINVAL                  = syscall.Errno(10022)
 	WSAEINVAL                  = syscall.Errno(10022)
 
 
@@ -85,82 +25,4 @@ const (
 	TimeoutInfinite = 0xFFFFFFFF
 	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
 package hcsshim
 
 
 import (
 import (
-	"encoding/json"
-	"net"
-
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hns"
 )
 )
 
 
 // HNSEndpoint represents a network endpoint in 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
 //SystemType represents the type of the system on which actions are done
 type SystemType string
 type SystemType string
@@ -37,39 +19,19 @@ const (
 
 
 // EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
 // 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
 // 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
 // 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
 // HNSEndpointRequest makes a HNS call to modify/query a network endpoint
 func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
 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
 // HNSListEndpointRequest makes a HNS call to query the list of available endpoints
 func HNSListEndpointRequest() ([]HNSEndpoint, error) {
 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
 // 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
 // GetHNSEndpointByID get the Endpoint by ID
 func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
 func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
-	return HNSEndpointRequest("GET", endpointID, "")
+	return hns.GetHNSEndpointByID(endpointID)
 }
 }
 
 
 // GetHNSEndpointByName gets the endpoint filtered by Name
 // GetHNSEndpointByName gets the endpoint filtered by Name
 func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
 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
 package hcsshim
 
 
 import (
 import (
-	"encoding/json"
-	"net"
-
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hns"
 )
 )
 
 
 // Subnet is assoicated with a network and represents a list
 // Subnet is assoicated with a network and represents a list
 // of subnets available to the network
 // 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
 // MacPool is assoicated with a network and represents a list
 // of macaddresses available to the network
 // 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
 // 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
 // HNSNetworkRequest makes a call into HNS to update/query a single network
 func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
 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
 // HNSListNetworkRequest makes a HNS call to query the list of available networks
 func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
 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
 // GetHNSNetworkByID
 func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
 func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
-	return HNSNetworkRequest("GET", networkID, "")
+	return hns.GetHNSNetworkByID(networkID)
 }
 }
 
 
 // GetHNSNetworkName filtered by Name
 // GetHNSNetworkName filtered by Name
 func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
 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
 package hcsshim
 
 
+import (
+	"github.com/Microsoft/hcsshim/internal/hns"
+)
+
 // Type of Request Support in ModifySystem
 // Type of Request Support in ModifySystem
-type PolicyType string
+type PolicyType = hns.PolicyType
 
 
 // RequestType const
 // RequestType const
 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 (
 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
 package hcsshim
 
 
 import (
 import (
-	"encoding/json"
-
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hns"
 )
 )
 
 
 // RoutePolicy is a structure defining schema for Route based Policy
 // 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
 // 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
 // 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
 // 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
 // HNSPolicyListRequest makes a call into HNS to update/query a single network
 func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
 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
 // HNSListPolicyListRequest gets all the policy list
 func HNSListPolicyListRequest() ([]PolicyList, error) {
 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
 // PolicyListRequest makes a HNS call to modify/query a network policy list
 func PolicyListRequest(method, path, request string) (*PolicyList, error) {
 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
 // GetPolicyListByID get the policy list by ID
 func GetPolicyListByID(policyListID string) (*PolicyList, error) {
 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
 // AddLoadBalancer policy list for the specified endpoints
 func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
 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
 // AddRoute adds route policy list for the specified endpoints
 func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
 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
 package hcsshim
 
 
 import (
 import (
-	"encoding/json"
 	"io"
 	"io"
 	"time"
 	"time"
+
+	"github.com/Microsoft/hcsshim/internal/schema1"
 )
 )
 
 
 // ProcessConfig is used as both the input of Container.CreateProcess
 // ProcessConfig is used as both the input of Container.CreateProcess
 // and to convert the parameters to JSON for passing onto the HCS
 // 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
 // ContainerConfig is used as both the input of CreateContainer
 // and to convert the parameters to JSON for passing onto the HCS
 // 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.
 // Container represents a created (but not necessarily running) container.
 type Container interface {
 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 (
 import (
 	"sync"
 	"sync"
 	"syscall"
 	"syscall"
+
+	"github.com/Microsoft/hcsshim/internal/interop"
 )
 )
 
 
 var (
 var (
@@ -62,7 +64,7 @@ func closeChannels(channels notificationChannels) {
 func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
 func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
 	var result error
 	var result error
 	if int32(notificationStatus) < 0 {
 	if int32(notificationStatus) < 0 {
-		result = syscall.Errno(win32FromHresult(notificationStatus))
+		result = interop.Win32FromHresult(notificationStatus)
 	}
 	}
 
 
 	callbackMapLock.RLock()
 	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"
 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 (
 import (
 	"io"
 	"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 (
 import (
 	"time"
 	"time"
@@ -6,13 +6,13 @@ import (
 	"github.com/sirupsen/logrus"
 	"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) {
 	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 {
 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 (
 import (
 	"encoding/json"
 	"encoding/json"
 	"fmt"
 	"fmt"
 
 
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/interop"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
 
 
@@ -13,9 +15,9 @@ func hnsCall(method, path, request string, returnResponse interface{}) error {
 
 
 	err := _hnsCall(method, path, request, &responseBuffer)
 	err := _hnsCall(method, path, request, &responseBuffer)
 	if err != nil {
 	if err != nil {
-		return makeError(err, "hnsCall ", "")
+		return hcserror.New(err, "hnsCall ", "")
 	}
 	}
-	response := convertAndFreeCoTaskMemString(responseBuffer)
+	response := interop.ConvertAndFreeCoTaskMemString(responseBuffer)
 
 
 	hnsresponse := &hnsResponse{}
 	hnsresponse := &hnsResponse{}
 	if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
 	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 (
 import (
 	"errors"
 	"errors"
@@ -10,9 +10,13 @@ import (
 	"unicode/utf16"
 	"unicode/utf16"
 	"unsafe"
 	"unsafe"
 
 
+	"github.com/Microsoft/hcsshim/internal/longpath"
+
 	winio "github.com/Microsoft/go-winio"
 	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 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 ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) = ntdll.NtSetInformationFile
 //sys rtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
 //sys rtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
@@ -53,28 +57,28 @@ const (
 	_FileLinkInformation          = 11
 	_FileLinkInformation          = 11
 	_FileDispositionInformationEx = 64
 	_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
 	_OBJ_DONT_REPARSE = 0x1000
 
 
 	_STATUS_REPARSE_POINT_ENCOUNTERED = 0xC000050B
 	_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 {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -141,7 +145,7 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
 		0,
 		0,
 		shareFlags,
 		shareFlags,
 		createDisposition,
 		createDisposition,
-		_FILE_OPEN_FOR_BACKUP_INTENT|_FILE_SYNCHRONOUS_IO_NONALERT|flags,
+		FILE_OPEN_FOR_BACKUP_INTENT|FILE_SYNCHRONOUS_IO_NONALERT|flags,
 		nil,
 		nil,
 		0,
 		0,
 	)
 	)
@@ -149,7 +153,7 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
 		return nil, rtlNtStatusToDosError(status)
 		return nil, rtlNtStatusToDosError(status)
 	}
 	}
 
 
-	fullPath, err := makeLongAbsPath(filepath.Join(root.Name(), path))
+	fullPath, err := longpath.LongAbs(filepath.Join(root.Name(), path))
 	if err != nil {
 	if err != nil {
 		syscall.Close(syscall.Handle(h))
 		syscall.Close(syscall.Handle(h))
 		return nil, err
 		return nil, err
@@ -158,9 +162,9 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
 	return os.NewFile(h, fullPath), nil
 	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.
 // 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)
 	f, err := openRelativeInternal(path, root, accessMask, shareFlags, createDisposition, flags)
 	if err != nil {
 	if err != nil {
 		err = &os.PathError{Op: "open", Path: filepath.Join(root.Name(), path), Err: err}
 		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
 	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
 // and newroot), failing if any of the intermediate path components are reparse
 // points.
 // 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.
 	// Open the old file.
 	oldf, err := openRelativeInternal(
 	oldf, err := openRelativeInternal(
 		oldname,
 		oldname,
 		oldroot,
 		oldroot,
 		syscall.FILE_WRITE_ATTRIBUTES,
 		syscall.FILE_WRITE_ATTRIBUTES,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_OPEN,
+		FILE_OPEN,
 		0,
 		0,
 	)
 	)
 	if err != nil {
 	if err != nil {
@@ -195,8 +199,8 @@ func linkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
 			newroot,
 			newroot,
 			syscall.GENERIC_READ,
 			syscall.GENERIC_READ,
 			syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
 			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 {
 		if err != nil {
 			return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: err}
 			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.
 // deleteOnClose marks a file to be deleted when the handle is closed.
 func deleteOnClose(f *os.File) error {
 func deleteOnClose(f *os.File) error {
-	disposition := fileDispositionInformationEx{Flags: _FILE_DISPOSITION_DELETE}
+	disposition := fileDispositionInformationEx{Flags: FILE_DISPOSITION_DELETE}
 	var iosb ioStatusBlock
 	var iosb ioStatusBlock
 	status := ntSetInformationFile(
 	status := ntSetInformationFile(
 		f.Fd(),
 		f.Fd(),
@@ -281,16 +285,16 @@ func clearReadOnly(f *os.File) error {
 	return winio.SetFileBasicInfo(f, &sbi)
 	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.
 // 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(
 	f, err := openRelativeInternal(
 		path,
 		path,
 		root,
 		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,
 		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 {
 	if err == nil {
 		defer f.Close()
 		defer f.Close()
 		err = deleteOnClose(f)
 		err = deleteOnClose(f)
@@ -306,10 +310,10 @@ func removeRelative(path string, root *os.File) error {
 	return nil
 	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.
 // 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 err != nil {
 		if os.IsNotExist(err) {
 		if os.IsNotExist(err) {
 			return nil
 			return nil
@@ -319,7 +323,7 @@ func removeAllRelative(path string, root *os.File) error {
 	fileAttributes := fi.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 	fileAttributes := fi.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 	if fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 || fileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
 	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.
 		// 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) {
 		if err == nil || os.IsNotExist(err) {
 			return nil
 			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
 	// 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
 	// if the target is outside the root, and we know this is not a
 	// symlink from the above FILE_ATTRIBUTE_REPARSE_POINT check.
 	// symlink from the above FILE_ATTRIBUTE_REPARSE_POINT check.
 	fd, err := os.Open(filepath.Join(root.Name(), path))
 	fd, err := os.Open(filepath.Join(root.Name(), path))
@@ -344,7 +348,7 @@ func removeAllRelative(path string, root *os.File) error {
 	for {
 	for {
 		names, err1 := fd.Readdirnames(100)
 		names, err1 := fd.Readdirnames(100)
 		for _, name := range names {
 		for _, name := range names {
-			err1 := removeAllRelative(path+string(os.PathSeparator)+name, root)
+			err1 := RemoveAllRelative(path+string(os.PathSeparator)+name, root)
 			if err == nil {
 			if err == nil {
 				err = err1
 				err = err1
 			}
 			}
@@ -363,7 +367,7 @@ func removeAllRelative(path string, root *os.File) error {
 	fd.Close()
 	fd.Close()
 
 
 	// Remove directory.
 	// Remove directory.
-	err1 := removeRelative(path, root)
+	err1 := RemoveRelative(path, root)
 	if err1 == nil || os.IsNotExist(err1) {
 	if err1 == nil || os.IsNotExist(err1) {
 		return nil
 		return nil
 	}
 	}
@@ -373,16 +377,16 @@ func removeAllRelative(path string, root *os.File) error {
 	return err
 	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.
 // 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(
 	f, err := openRelativeInternal(
 		path,
 		path,
 		root,
 		root,
 		0,
 		0,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
 		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 {
 	if err == nil {
 		f.Close()
 		f.Close()
 	} else {
 	} else {
@@ -391,16 +395,16 @@ func mkdirRelative(path string, root *os.File) error {
 	return err
 	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.
 // 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(
 	f, err := openRelativeInternal(
 		path,
 		path,
 		root,
 		root,
-		_FILE_READ_ATTRIBUTES,
+		FILE_READ_ATTRIBUTES,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_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 {
 	if err != nil {
 		return nil, &os.PathError{Op: "stat", Path: filepath.Join(root.Name(), path), Err: err}
 		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()
 	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.
 // 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.
 	// Perform an open with OBJ_DONT_REPARSE but without specifying FILE_OPEN_REPARSE_POINT.
-	f, err := openRelative(
+	f, err := OpenRelative(
 		path,
 		path,
 		root,
 		root,
 		0,
 		0,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
 		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		_FILE_OPEN,
+		FILE_OPEN,
 		0)
 		0)
 	if err != nil {
 	if err != nil {
 		return err
 		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 (
 import (
 	"errors"
 	"errors"
@@ -7,6 +7,8 @@ import (
 	"syscall"
 	"syscall"
 
 
 	"github.com/Microsoft/go-winio"
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/safefile"
 )
 )
 
 
 type baseLayerWriter struct {
 type baseLayerWriter struct {
@@ -29,7 +31,7 @@ type dirInfo struct {
 func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
 func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
 	for i := range dis {
 	for i := range dis {
 		di := &dis[len(dis)-i-1] // reverse order: process child directories first
 		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 {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -84,21 +86,21 @@ func (w *baseLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) (err e
 
 
 	extraFlags := uint32(0)
 	extraFlags := uint32(0)
 	if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 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 {
 		if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
 			w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
 			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)
 	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 {
 	if err != nil {
-		return makeError(err, "Failed to openRelative", name)
+		return hcserror.New(err, "Failed to safefile.OpenRelative", name)
 	}
 	}
 
 
 	err = winio.SetFileBasicInfo(f, fileInfo)
 	err = winio.SetFileBasicInfo(f, fileInfo)
 	if err != nil {
 	if err != nil {
-		return makeError(err, "Failed to SetFileBasicInfo", name)
+		return hcserror.New(err, "Failed to SetFileBasicInfo", name)
 	}
 	}
 
 
 	w.f = f
 	w.f = f
@@ -119,7 +121,7 @@ func (w *baseLayerWriter) AddLink(name string, target string) (err error) {
 		return err
 		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 {
 func (w *baseLayerWriter) Remove(name string) error {
@@ -157,7 +159,7 @@ func (w *baseLayerWriter) Close() error {
 		}
 		}
 
 
 		if w.hasUtilityVM {
 		if w.hasUtilityVM {
-			err := ensureNotReparsePointRelative("UtilityVM", w.root)
+			err := safefile.EnsureNotReparsePointRelative("UtilityVM", w.root)
 			if err != nil {
 			if err != nil {
 				return err
 				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 (
 import (
 	"io"
 	"io"
@@ -7,6 +7,8 @@ import (
 	"syscall"
 	"syscall"
 
 
 	"github.com/Microsoft/go-winio"
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/interop"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
 
 
@@ -15,9 +17,9 @@ import (
 // format includes any metadata required for later importing the layer (using
 // format includes any metadata required for later importing the layer (using
 // ImportLayer), and requires the full list of parent layer paths in order to
 // ImportLayer), and requires the full list of parent layer paths in order to
 // perform the export.
 // 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 "
 	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
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -25,21 +27,14 @@ func ExportLayer(info DriverInfo, layerId string, exportFolderPath string, paren
 		return err
 		return err
 	}
 	}
 
 
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
+	err = exportLayer(&stdDriverInfo, path, exportFolderPath, layers)
 	if err != nil {
 	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s folder=%s", path, exportFolderPath)
 		logrus.Error(err)
 		logrus.Error(err)
 		return 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
 	return nil
 }
 }
 
 
@@ -69,11 +64,11 @@ func (r *FilterLayerReader) Next() (string, int64, *winio.FileBasicInfo, error)
 		if err == syscall.ERROR_NO_MORE_FILES {
 		if err == syscall.ERROR_NO_MORE_FILES {
 			err = io.EOF
 			err = io.EOF
 		} else {
 		} else {
-			err = makeError(err, "ExportLayerNext", "")
+			err = hcserror.New(err, "ExportLayerNext", "")
 		}
 		}
 		return "", 0, nil, err
 		return "", 0, nil, err
 	}
 	}
-	fileName := convertAndFreeCoTaskMemString(fileNamep)
+	fileName := interop.ConvertAndFreeCoTaskMemString(fileNamep)
 	if deleted != 0 {
 	if deleted != 0 {
 		fileInfo = nil
 		fileInfo = nil
 	}
 	}
@@ -88,7 +83,7 @@ func (r *FilterLayerReader) Read(b []byte) (int, error) {
 	var bytesRead uint32
 	var bytesRead uint32
 	err := exportLayerRead(r.context, b, &bytesRead)
 	err := exportLayerRead(r.context, b, &bytesRead)
 	if err != nil {
 	if err != nil {
-		return 0, makeError(err, "ExportLayerRead", "")
+		return 0, hcserror.New(err, "ExportLayerRead", "")
 	}
 	}
 	if bytesRead == 0 {
 	if bytesRead == 0 {
 		return 0, io.EOF
 		return 0, io.EOF
@@ -103,7 +98,7 @@ func (r *FilterLayerReader) Close() (err error) {
 	if r.context != 0 {
 	if r.context != 0 {
 		err = exportLayerEnd(r.context)
 		err = exportLayerEnd(r.context)
 		if err != nil {
 		if err != nil {
-			err = makeError(err, "ExportLayerEnd", "")
+			err = hcserror.New(err, "ExportLayerEnd", "")
 		}
 		}
 		r.context = 0
 		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.
 // NewLayerReader returns a new layer reader for reading the contents of an on-disk layer.
 // The caller must have taken the SeBackupPrivilege privilege
 // The caller must have taken the SeBackupPrivilege privilege
 // to call this and any methods on the resulting LayerReader.
 // 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 {
 	if procExportLayerBegin.Find() != nil {
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// legacy export code path.
 		// legacy export code path.
-		path, err := ioutil.TempDir("", "hcs")
+		exportPath, err := ioutil.TempDir("", "hcs")
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		err = ExportLayer(info, layerID, path, parentLayerPaths)
+		err = ExportLayer(path, exportPath, parentLayerPaths)
 		if err != nil {
 		if err != nil {
-			os.RemoveAll(path)
+			os.RemoveAll(exportPath)
 			return nil, err
 			return nil, err
 		}
 		}
-		return &legacyLayerReaderWrapper{newLegacyLayerReader(path)}, nil
+		return &legacyLayerReaderWrapper{newLegacyLayerReader(exportPath)}, nil
 	}
 	}
 
 
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		return nil, err
-	}
 	r := &FilterLayerReader{}
 	r := &FilterLayerReader{}
-	err = exportLayerBegin(&infop, layerID, layers, &r.context)
+	err = exportLayerBegin(&stdDriverInfo, path, layers, &r.context)
 	if err != nil {
 	if err != nil {
-		return nil, makeError(err, "ExportLayerBegin", "")
+		return nil, hcserror.New(err, "ExportLayerBegin", "")
 	}
 	}
 	return r, err
 	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 (
 import (
 	"syscall"
 	"syscall"
 
 
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 	"github.com/sirupsen/logrus"
 	"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
 // 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
 // if the layer is a mounted read-write layer, otherwise it is expected to be the
 // folder path at which the layer is stored.
 // 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 "
 	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
 	var mountPathLength uintptr
 	mountPathLength = 0
 	mountPathLength = 0
 
 
 	// Call the procedure itself.
 	// Call the procedure itself.
 	logrus.Debugf("Calling proc (1)")
 	logrus.Debugf("Calling proc (1)")
-	err = getLayerMountPath(&infop, id, &mountPathLength, nil)
+	err := getLayerMountPath(&stdDriverInfo, path, &mountPathLength, nil)
 	if err != 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)
 		logrus.Error(err)
 		return "", err
 		return "", err
 	}
 	}
@@ -42,14 +36,14 @@ func GetLayerMountPath(info DriverInfo, id string) (string, error) {
 
 
 	// Call the procedure again
 	// Call the procedure again
 	logrus.Debugf("Calling proc (2)")
 	logrus.Debugf("Calling proc (2)")
-	err = getLayerMountPath(&infop, id, &mountPathLength, &mountPathp[0])
+	err = getLayerMountPath(&stdDriverInfo, path, &mountPathLength, &mountPathp[0])
 	if err != nil {
 	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)
 		logrus.Error(err)
 		return "", 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
 // GetSharedBaseImages will enumerate the images stored in the common central
 // image store and return descriptive info about those images for the purpose
 // 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
 	var buffer *uint16
 	err = getBaseImages(&buffer)
 	err = getBaseImages(&buffer)
 	if err != nil {
 	if err != nil {
-		err = makeError(err, title, "")
+		err = hcserror.New(err, title, "")
 		logrus.Error(err)
 		logrus.Error(err)
 		return
 		return
 	}
 	}
-	imageData = convertAndFreeCoTaskMemString(buffer)
+	imageData = interop.ConvertAndFreeCoTaskMemString(buffer)
 	logrus.Debugf(title+" - succeeded output=%s", imageData)
 	logrus.Debugf(title+" - succeeded output=%s", imageData)
 	return
 	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 (
 import (
 	"errors"
 	"errors"
@@ -7,6 +7,8 @@ import (
 	"path/filepath"
 	"path/filepath"
 
 
 	"github.com/Microsoft/go-winio"
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/hcserror"
+	"github.com/Microsoft/hcsshim/internal/safefile"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
 
 
@@ -14,9 +16,9 @@ import (
 // that into a layer with the id layerId.  Note that in order to correctly populate
 // 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
 // the layer and interperet the transport format, all parent layers must already
 // be present on the system at the paths provided in parentLayerPaths.
 // 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 "
 	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
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -24,21 +26,14 @@ func ImportLayer(info DriverInfo, layerID string, importFolderPath string, paren
 		return err
 		return err
 	}
 	}
 
 
-	// Convert info to API calling convention
-	infop, err := convertDriverInfo(info)
+	err = importLayer(&stdDriverInfo, path, importFolderPath, layers)
 	if err != nil {
 	if err != nil {
+		err = hcserror.Errorf(err, title, "path=%s folder=%s", path, importFolderPath)
 		logrus.Error(err)
 		logrus.Error(err)
 		return 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
 	return nil
 }
 }
 
 
@@ -73,7 +68,7 @@ func (w *FilterLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 	}
 	}
 	err := importLayerNext(w.context, name, fileInfo)
 	err := importLayerNext(w.context, name, fileInfo)
 	if err != nil {
 	if err != nil {
-		return makeError(err, "ImportLayerNext", "")
+		return hcserror.New(err, "ImportLayerNext", "")
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -92,7 +87,7 @@ func (w *FilterLayerWriter) Remove(name string) error {
 	}
 	}
 	err := importLayerNext(w.context, name, nil)
 	err := importLayerNext(w.context, name, nil)
 	if err != nil {
 	if err != nil {
-		return makeError(err, "ImportLayerNext", "")
+		return hcserror.New(err, "ImportLayerNext", "")
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -101,7 +96,7 @@ func (w *FilterLayerWriter) Remove(name string) error {
 func (w *FilterLayerWriter) Write(b []byte) (int, error) {
 func (w *FilterLayerWriter) Write(b []byte) (int, error) {
 	err := importLayerWrite(w.context, b)
 	err := importLayerWrite(w.context, b)
 	if err != nil {
 	if err != nil {
-		err = makeError(err, "ImportLayerWrite", "")
+		err = hcserror.New(err, "ImportLayerWrite", "")
 		return 0, err
 		return 0, err
 	}
 	}
 	return len(b), err
 	return len(b), err
@@ -113,7 +108,7 @@ func (w *FilterLayerWriter) Close() (err error) {
 	if w.context != 0 {
 	if w.context != 0 {
 		err = importLayerEnd(w.context)
 		err = importLayerEnd(w.context)
 		if err != nil {
 		if err != nil {
-			err = makeError(err, "ImportLayerEnd", "")
+			err = hcserror.New(err, "ImportLayerEnd", "")
 		}
 		}
 		w.context = 0
 		w.context = 0
 	}
 	}
@@ -122,8 +117,6 @@ func (w *FilterLayerWriter) Close() (err error) {
 
 
 type legacyLayerWriterWrapper struct {
 type legacyLayerWriterWrapper struct {
 	*legacyLayerWriter
 	*legacyLayerWriter
-	info             DriverInfo
-	layerID          string
 	path             string
 	path             string
 	parentLayerPaths []string
 	parentLayerPaths []string
 }
 }
@@ -136,28 +129,26 @@ func (r *legacyLayerWriterWrapper) Close() error {
 		return err
 		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
 		return err
 	}
 	}
 	for _, name := range r.Tombstones {
 	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
 			return err
 		}
 		}
 	}
 	}
 	// Add any hard links that were collected.
 	// Add any hard links that were collected.
 	for _, lnk := range r.PendingLinks {
 	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
 			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
 			return err
 		}
 		}
 	}
 	}
 	// Prepare the utility VM for use if one is present in the layer.
 	// Prepare the utility VM for use if one is present in the layer.
 	if r.HasUtilityVM {
 	if r.HasUtilityVM {
-		err := ensureNotReparsePointRelative("UtilityVM", r.destRoot)
+		err := safefile.EnsureNotReparsePointRelative("UtilityVM", r.destRoot)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -172,10 +163,10 @@ func (r *legacyLayerWriterWrapper) Close() error {
 // NewLayerWriter returns a new layer writer for creating a layer on disk.
 // NewLayerWriter returns a new layer writer for creating a layer on disk.
 // The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges
 // The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges
 // to call this and any methods on the resulting LayerWriter.
 // 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 {
 	if len(parentLayerPaths) == 0 {
 		// This is a base layer. It gets imported differently.
 		// 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 {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -187,19 +178,17 @@ func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string)
 	if procImportLayerBegin.Find() != nil {
 	if procImportLayerBegin.Find() != nil {
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// The new layer reader is not available on this Windows build. Fall back to the
 		// legacy export code path.
 		// legacy export code path.
-		path, err := ioutil.TempDir("", "hcs")
+		importPath, err := ioutil.TempDir("", "hcs")
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
-		w, err := newLegacyLayerWriter(path, parentLayerPaths, filepath.Join(info.HomeDir, layerID))
+		w, err := newLegacyLayerWriter(importPath, parentLayerPaths, path)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 		return &legacyLayerWriterWrapper{
 		return &legacyLayerWriterWrapper{
 			legacyLayerWriter: w,
 			legacyLayerWriter: w,
-			info:              info,
-			layerID:           layerID,
-			path:              path,
+			path:              importPath,
 			parentLayerPaths:  parentLayerPaths,
 			parentLayerPaths:  parentLayerPaths,
 		}, nil
 		}, nil
 	}
 	}
@@ -208,15 +197,10 @@ func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string)
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	infop, err := convertDriverInfo(info)
-	if err != nil {
-		return nil, err
-	}
-
 	w := &FilterLayerWriter{}
 	w := &FilterLayerWriter{}
-	err = importLayerBegin(&infop, layerID, layers, &w.context)
+	err = importLayerBegin(&stdDriverInfo, path, layers, &w.context)
 	if err != nil {
 	if err != nil {
-		return nil, makeError(err, "ImportLayerStart", "")
+		return nil, hcserror.New(err, "ImportLayerStart", "")
 	}
 	}
 	return w, nil
 	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
 // This file contains utility functions to support storage (graph) related
 // functionality.
 // functionality.
 
 
 import (
 import (
-	"path/filepath"
 	"syscall"
 	"syscall"
 
 
+	"github.com/Microsoft/hcsshim/internal/guid"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
 
 
@@ -22,28 +22,16 @@ struct DriverInfo {
     LPCWSTR HomeDir;
     LPCWSTR HomeDir;
 };
 };
 */
 */
-type DriverInfo struct {
-	Flavour int
-	HomeDir string
-}
 
 
 type driverInfo struct {
 type driverInfo struct {
 	Flavour  int
 	Flavour  int
 	HomeDirp *uint16
 	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:
 /* To pass into syscall, we need a struct matching the following:
 typedef struct _WC_LAYER_DESCRIPTOR {
 typedef struct _WC_LAYER_DESCRIPTOR {
@@ -75,7 +63,7 @@ typedef struct _WC_LAYER_DESCRIPTOR {
 } WC_LAYER_DESCRIPTOR, *PWC_LAYER_DESCRIPTOR;
 } WC_LAYER_DESCRIPTOR, *PWC_LAYER_DESCRIPTOR;
 */
 */
 type WC_LAYER_DESCRIPTOR struct {
 type WC_LAYER_DESCRIPTOR struct {
-	LayerId GUID
+	LayerId guid.GUID
 	Flags   uint32
 	Flags   uint32
 	Pathp   *uint16
 	Pathp   *uint16
 }
 }
@@ -85,10 +73,7 @@ func layerPathsToDescriptors(parentLayerPaths []string) ([]WC_LAYER_DESCRIPTOR,
 	var layers []WC_LAYER_DESCRIPTOR
 	var layers []WC_LAYER_DESCRIPTOR
 
 
 	for i := 0; i < len(parentLayerPaths); i++ {
 	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 {
 		if err != nil {
 			logrus.Debugf("Failed to convert name to guid %s", err)
 			logrus.Debugf("Failed to convert name to guid %s", err)
 			return nil, 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 (
 import (
 	"bufio"
 	"bufio"
@@ -6,12 +6,15 @@ import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
+	"io/ioutil"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
 	"strings"
 	"strings"
 	"syscall"
 	"syscall"
 
 
 	"github.com/Microsoft/go-winio"
 	"github.com/Microsoft/go-winio"
+	"github.com/Microsoft/hcsshim/internal/longpath"
+	"github.com/Microsoft/hcsshim/internal/safefile"
 )
 )
 
 
 var errorIterationCanceled = errors.New("")
 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)
 	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 {
 func hasPathPrefix(p, prefix string) bool {
 	return strings.HasPrefix(p, prefix) && len(p) > len(prefix) && p[len(prefix)] == '\\'
 	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 {
 func (r *legacyLayerReader) walkUntilCancelled() error {
-	root, err := makeLongAbsPath(r.root)
+	root, err := longpath.LongAbs(r.root)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -283,7 +269,7 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil
 		if err != nil {
 		if err != nil {
 			return
 			return
 		}
 		}
-		fileInfo.FileAttributes = uintptr(attr)
+		fileInfo.FileAttributes = attr
 		beginning := int64(4)
 		beginning := int64(4)
 
 
 		// Find the accurate file size.
 		// Find the accurate file size.
@@ -349,6 +335,7 @@ type legacyLayerWriter struct {
 	destRoot        *os.File
 	destRoot        *os.File
 	parentRoots     []*os.File
 	parentRoots     []*os.File
 	currentFile     *os.File
 	currentFile     *os.File
+	bufWriter       *bufio.Writer
 	currentFileName string
 	currentFileName string
 	currentFileRoot *os.File
 	currentFileRoot *os.File
 	backupWriter    *winio.BackupFileWriter
 	backupWriter    *winio.BackupFileWriter
@@ -373,21 +360,22 @@ func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) (w
 			w = nil
 			w = nil
 		}
 		}
 	}()
 	}()
-	w.root, err = openRoot(root)
+	w.root, err = safefile.OpenRoot(root)
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
-	w.destRoot, err = openRoot(destRoot)
+	w.destRoot, err = safefile.OpenRoot(destRoot)
 	if err != nil {
 	if err != nil {
 		return
 		return
 	}
 	}
 	for _, r := range parentRoots {
 	for _, r := range parentRoots {
-		f, err := openRoot(r)
+		f, err := safefile.OpenRoot(r)
 		if err != nil {
 		if err != nil {
 			return w, err
 			return w, err
 		}
 		}
 		w.parentRoots = append(w.parentRoots, f)
 		w.parentRoots = append(w.parentRoots, f)
 	}
 	}
+	w.bufWriter = bufio.NewWriterSize(ioutil.Discard, 65536)
 	return
 	return
 }
 }
 
 
@@ -408,7 +396,7 @@ func (w *legacyLayerWriter) CloseRoots() {
 
 
 func (w *legacyLayerWriter) initUtilityVM() error {
 func (w *legacyLayerWriter) initUtilityVM() error {
 	if !w.HasUtilityVM {
 	if !w.HasUtilityVM {
-		err := mkdirRelative(utilityVMPath, w.destRoot)
+		err := safefile.MkdirRelative(utilityVMPath, w.destRoot)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -426,6 +414,11 @@ func (w *legacyLayerWriter) initUtilityVM() error {
 }
 }
 
 
 func (w *legacyLayerWriter) reset() error {
 func (w *legacyLayerWriter) reset() error {
+	err := w.bufWriter.Flush()
+	if err != nil {
+		return err
+	}
+	w.bufWriter.Reset(ioutil.Discard)
 	if w.currentIsDir {
 	if w.currentIsDir {
 		r := w.currentFile
 		r := w.currentFile
 		br := winio.NewBackupStreamReader(r)
 		br := winio.NewBackupStreamReader(r)
@@ -449,7 +442,7 @@ func (w *legacyLayerWriter) reset() error {
 				// describes a directory reparse point. Delete the placeholder
 				// describes a directory reparse point. Delete the placeholder
 				// directory to prevent future files being added into the
 				// directory to prevent future files being added into the
 				// destination of the reparse point during the ImportLayer call
 				// 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
 					return err
 				}
 				}
 				w.pendingDirs = append(w.pendingDirs, pendingDir{Path: w.currentFileName, Root: w.currentFileRoot})
 				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
 // 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) {
 func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
-	src, err := openRelative(
+	src, err := safefile.OpenRelative(
 		subPath,
 		subPath,
 		srcRoot,
 		srcRoot,
 		syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY,
 		syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY,
 		syscall.FILE_SHARE_READ,
 		syscall.FILE_SHARE_READ,
-		_FILE_OPEN,
-		_FILE_OPEN_REPARSE_POINT)
+		safefile.FILE_OPEN,
+		safefile.FILE_OPEN_REPARSE_POINT)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -495,14 +488,14 @@ func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool
 
 
 	extraFlags := uint32(0)
 	extraFlags := uint32(0)
 	if isDir {
 	if isDir {
-		extraFlags |= _FILE_DIRECTORY_FILE
+		extraFlags |= safefile.FILE_DIRECTORY_FILE
 	}
 	}
-	dest, err := openRelative(
+	dest, err := safefile.OpenRelative(
 		subPath,
 		subPath,
 		destRoot,
 		destRoot,
 		syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
 		syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
 		syscall.FILE_SHARE_READ,
 		syscall.FILE_SHARE_READ,
-		_FILE_CREATE,
+		safefile.FILE_CREATE,
 		extraFlags)
 		extraFlags)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		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.
 // 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 {
 func cloneTree(srcRoot *os.File, destRoot *os.File, subPath string, mutatedFiles map[string]bool) error {
 	var di []dirInfo
 	var di []dirInfo
-	err := ensureNotReparsePointRelative(subPath, srcRoot)
+	err := safefile.EnsureNotReparsePointRelative(subPath, srcRoot)
 	if err != nil {
 	if err != nil {
 		return err
 		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})
 				di = append(di, dirInfo{path: relPath, fileInfo: *fi})
 			}
 			}
 		} else {
 		} else {
-			err = linkRelative(relPath, srcRoot, relPath, destRoot)
+			err = safefile.LinkRelative(relPath, srcRoot, relPath, destRoot)
 			if err != nil {
 			if err != nil {
 				return err
 				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
 		return nil
 	})
 	})
 	if err != nil {
 	if err != nil {
@@ -604,9 +591,9 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
 		if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
 			return errors.New("invalid UtilityVM layer")
 			return errors.New("invalid UtilityVM layer")
 		}
 		}
-		createDisposition := uint32(_FILE_OPEN)
+		createDisposition := uint32(safefile.FILE_OPEN)
 		if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
 		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) {
 			if err != nil && !os.IsNotExist(err) {
 				return 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.
 				// Delete the existing file/directory if it is not the same type as this directory.
 				existingAttr := st.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 				existingAttr := st.Sys().(*syscall.Win32FileAttributeData).FileAttributes
 				if (uint32(fileInfo.FileAttributes)^existingAttr)&(syscall.FILE_ATTRIBUTE_DIRECTORY|syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
 				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
 						return err
 					}
 					}
 					st = nil
 					st = nil
 				}
 				}
 			}
 			}
 			if st == nil {
 			if st == nil {
-				if err = mkdirRelative(name, w.destRoot); err != nil {
+				if err = safefile.MkdirRelative(name, w.destRoot); err != nil {
 					return err
 					return err
 				}
 				}
 			}
 			}
@@ -630,20 +617,20 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 			}
 			}
 		} else {
 		} else {
 			// Overwrite any existing hard link.
 			// Overwrite any existing hard link.
-			err := removeRelative(name, w.destRoot)
+			err := safefile.RemoveRelative(name, w.destRoot)
 			if err != nil && !os.IsNotExist(err) {
 			if err != nil && !os.IsNotExist(err) {
 				return err
 				return err
 			}
 			}
-			createDisposition = _FILE_CREATE
+			createDisposition = safefile.FILE_CREATE
 		}
 		}
 
 
-		f, err := openRelative(
+		f, err := safefile.OpenRelative(
 			name,
 			name,
 			w.destRoot,
 			w.destRoot,
 			syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
 			syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
 			syscall.FILE_SHARE_READ,
 			syscall.FILE_SHARE_READ,
 			createDisposition,
 			createDisposition,
-			_FILE_OPEN_REPARSE_POINT,
+			safefile.FILE_OPEN_REPARSE_POINT,
 		)
 		)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
@@ -651,7 +638,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		defer func() {
 		defer func() {
 			if f != nil {
 			if f != nil {
 				f.Close()
 				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.backupWriter = winio.NewBackupFileWriter(f, true)
+		w.bufWriter.Reset(w.backupWriter)
 		w.currentFile = f
 		w.currentFile = f
 		w.currentFileName = name
 		w.currentFileName = name
 		w.currentFileRoot = w.destRoot
 		w.currentFileRoot = w.destRoot
@@ -671,7 +659,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 
 
 	fname := name
 	fname := name
 	if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
 	if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
-		err := mkdirRelative(name, w.root)
+		err := safefile.MkdirRelative(name, w.root)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -679,14 +667,14 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
 		w.currentIsDir = true
 		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 {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	defer func() {
 	defer func() {
 		if f != nil {
 		if f != nil {
 			f.Close()
 			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) {
 	if hasPathPrefix(name, hivesPath) {
 		w.backupWriter = winio.NewBackupFileWriter(f, false)
 		w.backupWriter = winio.NewBackupFileWriter(f, false)
+		w.bufWriter.Reset(w.backupWriter)
 	} else {
 	} else {
+		w.bufWriter.Reset(f)
 		// The file attributes are written before the stream.
 		// 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 {
 		if err != nil {
+			w.bufWriter.Reset(ioutil.Discard)
 			return err
 			return err
 		}
 		}
 	}
 	}
@@ -744,7 +735,7 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
 		selectedRoot = w.destRoot
 		selectedRoot = w.destRoot
 	} else {
 	} else {
 		for _, r := range roots {
 		for _, r := range roots {
-			if _, err := lstatRelative(target, r); err != nil {
+			if _, err := safefile.LstatRelative(target, r); err != nil {
 				if !os.IsNotExist(err) {
 				if !os.IsNotExist(err) {
 					return 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
 		// 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
 		// already gone, and this needs to be a fatal error for diagnostics
 		// purposes.
 		// purposes.
-		if _, err := lstatRelative(name, w.destRoot); err != nil {
+		if _, err := safefile.LstatRelative(name, w.destRoot); err != nil {
 			return err
 			return err
 		}
 		}
-		err = removeAllRelative(name, w.destRoot)
+		err = safefile.RemoveAllRelative(name, w.destRoot)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -795,24 +786,21 @@ func (w *legacyLayerWriter) Remove(name string) error {
 }
 }
 
 
 func (w *legacyLayerWriter) Write(b []byte) (int, 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 {
 func (w *legacyLayerWriter) Close() error {
 	if err := w.reset(); err != nil {
 	if err := w.reset(); err != nil {
 		return err
 		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
 		return err
 	}
 	}
 	for _, pd := range w.pendingDirs {
 	for _, pd := range w.pendingDirs {
-		err := mkdirRelative(pd.Path, pd.Root)
+		err := safefile.MkdirRelative(pd.Path, pd.Root)
 		if err != nil {
 		if err != nil {
 			return err
 			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 (
 import (
 	"sync"
 	"sync"
 
 
+	"github.com/Microsoft/hcsshim/internal/hcserror"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
 
 
 var prepareLayerLock sync.Mutex
 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
 // 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
 // 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).
 // as an actual filesystem (reading and writing files, creating directories, etc).
 // Disabling the filter must be done via UnprepareLayer.
 // 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 "
 	title := "hcsshim::PrepareLayer "
-	logrus.Debugf(title+"flavour %d layerId %s", info.Flavour, layerId)
+	logrus.Debugf(title+"path %s", path)
 
 
 	// Generate layer descriptors
 	// Generate layer descriptors
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
 	layers, err := layerPathsToDescriptors(parentLayerPaths)
@@ -23,24 +24,17 @@ func PrepareLayer(info DriverInfo, layerId string, parentLayerPaths []string) er
 		return err
 		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
 	// 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.
 	// call to prepareLayer at a time vastly reduces the chance of a timeout.
 	prepareLayerLock.Lock()
 	prepareLayerLock.Lock()
 	defer prepareLayerLock.Unlock()
 	defer prepareLayerLock.Unlock()
-	err = prepareLayer(&infop, layerId, layers)
+	err = prepareLayer(&stdDriverInfo, path, layers)
 	if err != nil {
 	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)
 		logrus.Error(err)
 		return err
 		return err
 	}
 	}
 
 
-	logrus.Debugf(title+"succeeded flavour=%d layerId=%s", info.Flavour, layerId)
+	logrus.Debugf(title+"succeeded path=%s", path)
 	return nil
 	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"
 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
 package hcsshim
 
 
 import (
 import (
-	"encoding/json"
 	"io"
 	"io"
-	"sync"
-	"syscall"
 	"time"
 	"time"
 
 
-	"github.com/sirupsen/logrus"
+	"github.com/Microsoft/hcsshim/internal/hcs"
 )
 )
 
 
 // ContainerError is an error encountered in HCS
 // ContainerError is an error encountered in HCS
 type process struct {
 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.
 // Pid returns the process ID of the process within the container.
 func (process *process) Pid() int {
 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.
 // Kill signals the process to terminate but does not wait for it to finish terminating.
 func (process *process) Kill() error {
 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.
 // Wait waits for the process to exit.
 func (process *process) Wait() error {
 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
 // WaitTimeout waits for the process to exit or the duration to elapse. It returns
 // false if timeout occurs.
 // false if timeout occurs.
 func (process *process) WaitTimeout(timeout time.Duration) error {
 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
 // ExitCode returns the exit code of the process. The process must have
 // already terminated.
 // already terminated.
 func (process *process) ExitCode() (int, error) {
 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 {
 	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.
 // ResizeConsole resizes the console of the process.
 func (process *process) ResizeConsole(width, height uint16) error {
 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
 // Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
 // these pipes does not close the underlying pipes; it should be possible to
 // these pipes does not close the underlying pipes; it should be possible to
 // call this multiple times to get multiple interfaces.
 // call this multiple times to get multiple interfaces.
 func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
 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 {
 	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
 // 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.
 // notified on the read side that there is no more data in stdin.
 func (process *process) CloseStdin() error {
 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
 // Close cleans up any state associated with the process but does not kill
 // or wait on it.
 // or wait on it.
 func (process *process) Close() error {
 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.
 // IsTP4 returns whether the currently running Windows build is at least TP4.
 func IsTP4() bool {
 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
-}

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott