Jelajahi Sumber

Revendor HCSShim @ v0.5.13

Signed-off-by: John Howard <jhoward@microsoft.com>
John Howard (VM) 8 tahun lalu
induk
melakukan
4f7db6739d
2 mengubah file dengan 75 tambahan dan 1 penghapusan
  1. 1 1
      vendor.conf
  2. 74 0
      vendor/github.com/Microsoft/hcsshim/container.go

+ 1 - 1
vendor.conf

@@ -1,6 +1,6 @@
 # the following lines are in sorted order, FYI
 github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
-github.com/Microsoft/hcsshim v0.5.12
+github.com/Microsoft/hcsshim v0.5.13
 # TODO: get rid of this fork once PR https://github.com/Microsoft/go-winio/pull/43 is merged
 github.com/Microsoft/go-winio 7c7d6b461cb10872c1138a0d7f3acf9a41b5c353 https://github.com/dgageot/go-winio.git
 github.com/Sirupsen/logrus v0.11.0

+ 74 - 0
vendor/github.com/Microsoft/hcsshim/container.go

@@ -2,6 +2,8 @@ package hcsshim
 
 import (
 	"encoding/json"
+	"fmt"
+	"os"
 	"runtime"
 	"sync"
 	"syscall"
@@ -103,8 +105,27 @@ type ProcessListItem struct {
 	UserTime100ns                uint64    `json:",omitempty"`
 }
 
+// createContainerAdditionalJSON is read from the environment at initialisation
+// time. It allows an environment variable to define additional JSON which
+// is merged in the CreateContainer call to HCS.
+var createContainerAdditionalJSON string
+
+func init() {
+	createContainerAdditionalJSON = os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON")
+}
+
 // CreateContainer creates a new container with the given configuration but does not start it.
 func CreateContainer(id string, c *ContainerConfig) (Container, error) {
+	return createContainerWithJSON(id, c, "")
+}
+
+// CreateContainerWithJSON creates a new container with the given configuration but does not start it.
+// It is identical to CreateContainer except that optional additional JSON can be merged before passing to HCS.
+func CreateContainerWithJSON(id string, c *ContainerConfig, additionalJSON string) (Container, error) {
+	return createContainerWithJSON(id, c, additionalJSON)
+}
+
+func createContainerWithJSON(id string, c *ContainerConfig, additionalJSON string) (Container, error) {
 	operation := "CreateContainer"
 	title := "HCSShim::" + operation
 
@@ -120,6 +141,32 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
 	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
@@ -142,6 +189,33 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
 	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 fromMap
+}
+
 // OpenContainer opens an existing container by ID.
 func OpenContainer(id string) (Container, error) {
 	operation := "OpenContainer"