Signed-off-by: John Howard <jhoward@microsoft.com>
| ... | ... |
@@ -203,7 +203,7 @@ func TestFromScratch(t *testing.T) {
|
| 203 | 203 |
assert.True(t, req.state.hasFromImage()) |
| 204 | 204 |
assert.Equal(t, "", req.state.imageID) |
| 205 | 205 |
// Windows does not set the default path. TODO @jhowardmsft LCOW support. This will need revisiting as we get further into the implementation |
| 206 |
- expected := "PATH=" + system.DefaultPathEnv |
|
| 206 |
+ expected := "PATH=" + system.DefaultPathEnv(runtime.GOOS) |
|
| 207 | 207 |
if runtime.GOOS == "windows" {
|
| 208 | 208 |
expected = "" |
| 209 | 209 |
} |
| ... | ... |
@@ -22,6 +22,7 @@ package dockerfile |
| 22 | 22 |
import ( |
| 23 | 23 |
"bytes" |
| 24 | 24 |
"fmt" |
| 25 |
+ "runtime" |
|
| 25 | 26 |
"strings" |
| 26 | 27 |
|
| 27 | 28 |
"github.com/docker/docker/api/types/container" |
| ... | ... |
@@ -228,14 +229,19 @@ func (s *dispatchState) beginStage(stageName string, image builder.Image) {
|
| 228 | 228 |
} |
| 229 | 229 |
|
| 230 | 230 |
// Add the default PATH to runConfig.ENV if one exists for the platform and there |
| 231 |
-// is no PATH set. Note that windows won't have one as it's set by HCS |
|
| 231 |
+// is no PATH set. Note that Windows containers on Windows won't have one as it's set by HCS |
|
| 232 | 232 |
func (s *dispatchState) setDefaultPath() {
|
| 233 |
- if system.DefaultPathEnv == "" {
|
|
| 233 |
+ // TODO @jhowardmsft LCOW Support - This will need revisiting later |
|
| 234 |
+ platform := runtime.GOOS |
|
| 235 |
+ if platform == "windows" && system.LCOWSupported() {
|
|
| 236 |
+ platform = "linux" |
|
| 237 |
+ } |
|
| 238 |
+ if system.DefaultPathEnv(platform) == "" {
|
|
| 234 | 239 |
return |
| 235 | 240 |
} |
| 236 | 241 |
envMap := opts.ConvertKVStringsToMap(s.runConfig.Env) |
| 237 | 242 |
if _, ok := envMap["PATH"]; !ok {
|
| 238 |
- s.runConfig.Env = append(s.runConfig.Env, "PATH="+system.DefaultPathEnv) |
|
| 243 |
+ s.runConfig.Env = append(s.runConfig.Env, "PATH="+system.DefaultPathEnv(platform)) |
|
| 239 | 244 |
} |
| 240 | 245 |
} |
| 241 | 246 |
|
| ... | ... |
@@ -34,6 +34,7 @@ import ( |
| 34 | 34 |
"github.com/docker/docker/pkg/ioutils" |
| 35 | 35 |
"github.com/docker/docker/pkg/signal" |
| 36 | 36 |
"github.com/docker/docker/pkg/symlink" |
| 37 |
+ "github.com/docker/docker/pkg/system" |
|
| 37 | 38 |
"github.com/docker/docker/restartmanager" |
| 38 | 39 |
"github.com/docker/docker/runconfig" |
| 39 | 40 |
"github.com/docker/docker/volume" |
| ... | ... |
@@ -1004,3 +1005,31 @@ func (container *Container) ConfigsDirPath() string {
|
| 1004 | 1004 |
func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) string {
|
| 1005 | 1005 |
return filepath.Join(container.ConfigsDirPath(), configRef.ConfigID) |
| 1006 | 1006 |
} |
| 1007 |
+ |
|
| 1008 |
+// CreateDaemonEnvironment creates a new environment variable slice for this container. |
|
| 1009 |
+func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string) []string {
|
|
| 1010 |
+ // Setup environment |
|
| 1011 |
+ // TODO @jhowardmsft LCOW Support. This will need revisiting later. |
|
| 1012 |
+ platform := container.Platform |
|
| 1013 |
+ if platform == "" {
|
|
| 1014 |
+ platform = runtime.GOOS |
|
| 1015 |
+ } |
|
| 1016 |
+ env := []string{}
|
|
| 1017 |
+ if runtime.GOOS != "windows" || (runtime.GOOS == "windows" && system.LCOWSupported() && platform == "linux") {
|
|
| 1018 |
+ env = []string{
|
|
| 1019 |
+ "PATH=" + system.DefaultPathEnv(platform), |
|
| 1020 |
+ "HOSTNAME=" + container.Config.Hostname, |
|
| 1021 |
+ } |
|
| 1022 |
+ if tty {
|
|
| 1023 |
+ env = append(env, "TERM=xterm") |
|
| 1024 |
+ } |
|
| 1025 |
+ env = append(env, linkedEnv...) |
|
| 1026 |
+ } |
|
| 1027 |
+ |
|
| 1028 |
+ // because the env on the container can override certain default values |
|
| 1029 |
+ // we need to replace the 'env' keys where they match and append anything |
|
| 1030 |
+ // else. |
|
| 1031 |
+ //return ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env) |
|
| 1032 |
+ foo := ReplaceOrAppendEnvValues(env, container.Config.Env) |
|
| 1033 |
+ return foo |
|
| 1034 |
+} |
| ... | ... |
@@ -35,27 +35,6 @@ type ExitStatus struct {
|
| 35 | 35 |
OOMKilled bool |
| 36 | 36 |
} |
| 37 | 37 |
|
| 38 |
-// CreateDaemonEnvironment returns the list of all environment variables given the list of |
|
| 39 |
-// environment variables related to links. |
|
| 40 |
-// Sets PATH, HOSTNAME and if container.Config.Tty is set: TERM. |
|
| 41 |
-// The defaults set here do not override the values in container.Config.Env |
|
| 42 |
-func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string) []string {
|
|
| 43 |
- // Setup environment |
|
| 44 |
- env := []string{
|
|
| 45 |
- "PATH=" + system.DefaultPathEnv, |
|
| 46 |
- "HOSTNAME=" + container.Config.Hostname, |
|
| 47 |
- } |
|
| 48 |
- if tty {
|
|
| 49 |
- env = append(env, "TERM=xterm") |
|
| 50 |
- } |
|
| 51 |
- env = append(env, linkedEnv...) |
|
| 52 |
- // because the env on the container can override certain default values |
|
| 53 |
- // we need to replace the 'env' keys where they match and append anything |
|
| 54 |
- // else. |
|
| 55 |
- env = ReplaceOrAppendEnvValues(env, container.Config.Env) |
|
| 56 |
- return env |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 | 38 |
// TrySetNetworkMount attempts to set the network mounts given a provided destination and |
| 60 | 39 |
// the path to use for it; return true if the given destination was a network mount file |
| 61 | 40 |
func (container *Container) TrySetNetworkMount(destination string, path string) bool {
|
| ... | ... |
@@ -23,14 +23,6 @@ type ExitStatus struct {
|
| 23 | 23 |
ExitCode int |
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
-// CreateDaemonEnvironment creates a new environment variable slice for this container. |
|
| 27 |
-func (container *Container) CreateDaemonEnvironment(_ bool, linkedEnv []string) []string {
|
|
| 28 |
- // because the env on the container can override certain default values |
|
| 29 |
- // we need to replace the 'env' keys where they match and append anything |
|
| 30 |
- // else. |
|
| 31 |
- return ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env) |
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 | 26 |
// UnmountIpcMounts unmounts Ipc related mounts. |
| 35 | 27 |
// This is a NOOP on windows. |
| 36 | 28 |
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
|
| ... | ... |
@@ -7,11 +7,17 @@ import ( |
| 7 | 7 |
"github.com/docker/docker/container" |
| 8 | 8 |
"github.com/docker/docker/oci" |
| 9 | 9 |
"github.com/docker/docker/pkg/sysinfo" |
| 10 |
+ "github.com/docker/docker/pkg/system" |
|
| 10 | 11 |
"github.com/opencontainers/runtime-spec/specs-go" |
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
| 14 |
- s := oci.DefaultSpec() |
|
| 15 |
+ img, err := daemon.GetImage(string(c.ImageID)) |
|
| 16 |
+ if err != nil {
|
|
| 17 |
+ return nil, err |
|
| 18 |
+ } |
|
| 19 |
+ |
|
| 20 |
+ s := oci.DefaultOSSpec(img.OS) |
|
| 15 | 21 |
|
| 16 | 22 |
linkedEnv, err := daemon.setupLinkedContainers(c) |
| 17 | 23 |
if err != nil {
|
| ... | ... |
@@ -95,7 +101,30 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
| 95 | 95 |
if !c.Config.ArgsEscaped {
|
| 96 | 96 |
s.Process.Args = escapeArgs(s.Process.Args) |
| 97 | 97 |
} |
| 98 |
+ |
|
| 98 | 99 |
s.Process.Cwd = c.Config.WorkingDir |
| 100 |
+ s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv) |
|
| 101 |
+ if c.Config.Tty {
|
|
| 102 |
+ s.Process.Terminal = c.Config.Tty |
|
| 103 |
+ s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0] |
|
| 104 |
+ s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1] |
|
| 105 |
+ } |
|
| 106 |
+ s.Process.User.Username = c.Config.User |
|
| 107 |
+ |
|
| 108 |
+ if img.OS == "windows" {
|
|
| 109 |
+ daemon.createSpecWindowsFields(c, &s, isHyperV) |
|
| 110 |
+ } else {
|
|
| 111 |
+ // TODO @jhowardmsft LCOW Support. Modify this check when running in dual-mode |
|
| 112 |
+ if system.LCOWSupported() && img.OS == "linux" {
|
|
| 113 |
+ daemon.createSpecLinuxFields(c, &s) |
|
| 114 |
+ } |
|
| 115 |
+ } |
|
| 116 |
+ |
|
| 117 |
+ return (*specs.Spec)(&s), nil |
|
| 118 |
+} |
|
| 119 |
+ |
|
| 120 |
+// Sets the Windows-specific fields of the OCI spec |
|
| 121 |
+func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.Spec, isHyperV bool) {
|
|
| 99 | 122 |
if len(s.Process.Cwd) == 0 {
|
| 100 | 123 |
// We default to C:\ to workaround the oddity of the case that the |
| 101 | 124 |
// default directory for cmd running as LocalSystem (or |
| ... | ... |
@@ -106,17 +135,11 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
| 106 | 106 |
// as c:\. Hence, setting it to default of c:\ makes for consistency. |
| 107 | 107 |
s.Process.Cwd = `C:\` |
| 108 | 108 |
} |
| 109 |
- s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv) |
|
| 110 |
- s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0] |
|
| 111 |
- s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1] |
|
| 112 |
- s.Process.Terminal = c.Config.Tty |
|
| 113 |
- s.Process.User.Username = c.Config.User |
|
| 114 | 109 |
|
| 115 |
- // In spec.Root. This is not set for Hyper-V containers |
|
| 110 |
+ s.Root.Readonly = false // Windows does not support a read-only root filesystem |
|
| 116 | 111 |
if !isHyperV {
|
| 117 |
- s.Root.Path = c.BaseFS |
|
| 112 |
+ s.Root.Path = c.BaseFS // This is not set for Hyper-V containers |
|
| 118 | 113 |
} |
| 119 |
- s.Root.Readonly = false // Windows does not support a read-only root filesystem |
|
| 120 | 114 |
|
| 121 | 115 |
// In s.Windows.Resources |
| 122 | 116 |
cpuShares := uint16(c.HostConfig.CPUShares) |
| ... | ... |
@@ -157,7 +180,17 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
| 157 | 157 |
Iops: &c.HostConfig.IOMaximumIOps, |
| 158 | 158 |
}, |
| 159 | 159 |
} |
| 160 |
- return (*specs.Spec)(&s), nil |
|
| 160 |
+} |
|
| 161 |
+ |
|
| 162 |
+// Sets the Linux-specific fields of the OCI spec |
|
| 163 |
+// TODO: @jhowardmsft LCOW Support. We need to do a lot more pulling in what can |
|
| 164 |
+// be pulled in from oci_linux.go. |
|
| 165 |
+func (daemon *Daemon) createSpecLinuxFields(c *container.Container, s *specs.Spec) {
|
|
| 166 |
+ if len(s.Process.Cwd) == 0 {
|
|
| 167 |
+ s.Process.Cwd = `/` |
|
| 168 |
+ } |
|
| 169 |
+ s.Root.Path = "rootfs" |
|
| 170 |
+ s.Root.Readonly = c.HostConfig.ReadonlyRootfs |
|
| 161 | 171 |
} |
| 162 | 172 |
|
| 163 | 173 |
func escapeArgs(args []string) []string {
|
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package libcontainerd |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "encoding/json" |
|
| 4 | 5 |
"errors" |
| 5 | 6 |
"fmt" |
| 6 | 7 |
"io" |
| ... | ... |
@@ -96,8 +97,17 @@ const defaultOwner = "docker" |
| 96 | 96 |
func (clnt *client) Create(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
|
| 97 | 97 |
clnt.lock(containerID) |
| 98 | 98 |
defer clnt.unlock(containerID) |
| 99 |
- logrus.Debugln("libcontainerd: client.Create() with spec", spec)
|
|
| 99 |
+ if b, err := json.Marshal(spec); err == nil {
|
|
| 100 |
+ logrus.Debugln("libcontainerd: client.Create() with spec", string(b))
|
|
| 101 |
+ } |
|
| 102 |
+ osName := spec.Platform.OS |
|
| 103 |
+ if osName == "windows" {
|
|
| 104 |
+ return clnt.createWindows(containerID, checkpoint, checkpointDir, spec, attachStdio, options...) |
|
| 105 |
+ } |
|
| 106 |
+ return clnt.createLinux(containerID, checkpoint, checkpointDir, spec, attachStdio, options...) |
|
| 107 |
+} |
|
| 100 | 108 |
|
| 109 |
+func (clnt *client) createWindows(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
|
|
| 101 | 110 |
configuration := &hcsshim.ContainerConfig{
|
| 102 | 111 |
SystemType: "Container", |
| 103 | 112 |
Name: containerID, |
| ... | ... |
@@ -265,17 +275,100 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir |
| 265 | 265 |
// Call start, and if it fails, delete the container from our |
| 266 | 266 |
// internal structure, start will keep HCS in sync by deleting the |
| 267 | 267 |
// container there. |
| 268 |
- logrus.Debugf("libcontainerd: Create() id=%s, Calling start()", containerID)
|
|
| 268 |
+ logrus.Debugf("libcontainerd: createWindows() id=%s, Calling start()", containerID)
|
|
| 269 | 269 |
if err := container.start(attachStdio); err != nil {
|
| 270 | 270 |
clnt.deleteContainer(containerID) |
| 271 | 271 |
return err |
| 272 | 272 |
} |
| 273 | 273 |
|
| 274 |
- logrus.Debugf("libcontainerd: Create() id=%s completed successfully", containerID)
|
|
| 274 |
+ logrus.Debugf("libcontainerd: createWindows() id=%s completed successfully", containerID)
|
|
| 275 | 275 |
return nil |
| 276 | 276 |
|
| 277 | 277 |
} |
| 278 | 278 |
|
| 279 |
+func (clnt *client) createLinux(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
|
|
| 280 |
+ logrus.Debugf("libcontainerd: createLinux(): containerId %s ", containerID)
|
|
| 281 |
+ |
|
| 282 |
+ // TODO @jhowardmsft LCOW Support: This needs to be configurable, not hard-coded. |
|
| 283 |
+ // However, good-enough for the LCOW bring-up. |
|
| 284 |
+ configuration := &hcsshim.ContainerConfig{
|
|
| 285 |
+ HvPartition: true, |
|
| 286 |
+ Name: containerID, |
|
| 287 |
+ SystemType: "container", |
|
| 288 |
+ ContainerType: "linux", |
|
| 289 |
+ TerminateOnLastHandleClosed: true, |
|
| 290 |
+ HvRuntime: &hcsshim.HvRuntime{
|
|
| 291 |
+ ImagePath: `c:\program files\lcow`, |
|
| 292 |
+ }, |
|
| 293 |
+ } |
|
| 294 |
+ |
|
| 295 |
+ var layerOpt *LayerOption |
|
| 296 |
+ for _, option := range options {
|
|
| 297 |
+ if l, ok := option.(*LayerOption); ok {
|
|
| 298 |
+ layerOpt = l |
|
| 299 |
+ } |
|
| 300 |
+ } |
|
| 301 |
+ |
|
| 302 |
+ // We must have a layer option with at least one path |
|
| 303 |
+ if layerOpt == nil || layerOpt.LayerPaths == nil {
|
|
| 304 |
+ return fmt.Errorf("no layer option or paths were supplied to the runtime")
|
|
| 305 |
+ } |
|
| 306 |
+ |
|
| 307 |
+ // LayerFolderPath (writeable layer) + Layers (Guid + path) |
|
| 308 |
+ configuration.LayerFolderPath = layerOpt.LayerFolderPath |
|
| 309 |
+ for _, layerPath := range layerOpt.LayerPaths {
|
|
| 310 |
+ _, filename := filepath.Split(layerPath) |
|
| 311 |
+ g, err := hcsshim.NameToGuid(filename) |
|
| 312 |
+ if err != nil {
|
|
| 313 |
+ return err |
|
| 314 |
+ } |
|
| 315 |
+ configuration.Layers = append(configuration.Layers, hcsshim.Layer{
|
|
| 316 |
+ ID: g.ToString(), |
|
| 317 |
+ Path: filepath.Join(layerPath, "layer.vhd"), |
|
| 318 |
+ }) |
|
| 319 |
+ } |
|
| 320 |
+ |
|
| 321 |
+ hcsContainer, err := hcsshim.CreateContainer(containerID, configuration) |
|
| 322 |
+ if err != nil {
|
|
| 323 |
+ return err |
|
| 324 |
+ } |
|
| 325 |
+ |
|
| 326 |
+ // Construct a container object for calling start on it. |
|
| 327 |
+ container := &container{
|
|
| 328 |
+ containerCommon: containerCommon{
|
|
| 329 |
+ process: process{
|
|
| 330 |
+ processCommon: processCommon{
|
|
| 331 |
+ containerID: containerID, |
|
| 332 |
+ client: clnt, |
|
| 333 |
+ friendlyName: InitFriendlyName, |
|
| 334 |
+ }, |
|
| 335 |
+ }, |
|
| 336 |
+ processes: make(map[string]*process), |
|
| 337 |
+ }, |
|
| 338 |
+ ociSpec: spec, |
|
| 339 |
+ hcsContainer: hcsContainer, |
|
| 340 |
+ } |
|
| 341 |
+ |
|
| 342 |
+ container.options = options |
|
| 343 |
+ for _, option := range options {
|
|
| 344 |
+ if err := option.Apply(container); err != nil {
|
|
| 345 |
+ logrus.Errorf("libcontainerd: createLinux() %v", err)
|
|
| 346 |
+ } |
|
| 347 |
+ } |
|
| 348 |
+ |
|
| 349 |
+ // Call start, and if it fails, delete the container from our |
|
| 350 |
+ // internal structure, start will keep HCS in sync by deleting the |
|
| 351 |
+ // container there. |
|
| 352 |
+ logrus.Debugf("libcontainerd: createLinux() id=%s, Calling start()", containerID)
|
|
| 353 |
+ if err := container.start(attachStdio); err != nil {
|
|
| 354 |
+ clnt.deleteContainer(containerID) |
|
| 355 |
+ return err |
|
| 356 |
+ } |
|
| 357 |
+ |
|
| 358 |
+ logrus.Debugf("libcontainerd: createLinux() id=%s completed successfully", containerID)
|
|
| 359 |
+ return nil |
|
| 360 |
+} |
|
| 361 |
+ |
|
| 279 | 362 |
// AddProcess is the handler for adding a process to an already running |
| 280 | 363 |
// container. It's called through docker exec. It returns the system pid of the |
| 281 | 364 |
// exec'd process. |
| ... | ... |
@@ -292,13 +385,15 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly |
| 292 | 292 |
// create stdin, even if it's not used - it will be closed shortly. Stderr |
| 293 | 293 |
// is only created if it we're not -t. |
| 294 | 294 |
createProcessParms := hcsshim.ProcessConfig{
|
| 295 |
- EmulateConsole: procToAdd.Terminal, |
|
| 296 | 295 |
CreateStdInPipe: true, |
| 297 | 296 |
CreateStdOutPipe: true, |
| 298 | 297 |
CreateStdErrPipe: !procToAdd.Terminal, |
| 299 | 298 |
} |
| 300 |
- createProcessParms.ConsoleSize[0] = uint(procToAdd.ConsoleSize.Height) |
|
| 301 |
- createProcessParms.ConsoleSize[1] = uint(procToAdd.ConsoleSize.Width) |
|
| 299 |
+ if procToAdd.Terminal {
|
|
| 300 |
+ createProcessParms.EmulateConsole = true |
|
| 301 |
+ createProcessParms.ConsoleSize[0] = uint(procToAdd.ConsoleSize.Height) |
|
| 302 |
+ createProcessParms.ConsoleSize[1] = uint(procToAdd.ConsoleSize.Width) |
|
| 303 |
+ } |
|
| 302 | 304 |
|
| 303 | 305 |
// Take working directory from the process to add if it is defined, |
| 304 | 306 |
// otherwise take from the first process. |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package libcontainerd |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "encoding/json" |
|
| 4 | 5 |
"fmt" |
| 5 | 6 |
"io" |
| 6 | 7 |
"io/ioutil" |
| ... | ... |
@@ -10,6 +11,7 @@ import ( |
| 10 | 10 |
|
| 11 | 11 |
"github.com/Microsoft/hcsshim" |
| 12 | 12 |
"github.com/Sirupsen/logrus" |
| 13 |
+ "github.com/docker/docker/pkg/system" |
|
| 13 | 14 |
"github.com/opencontainers/runtime-spec/specs-go" |
| 14 | 15 |
) |
| 15 | 16 |
|
| ... | ... |
@@ -83,6 +85,16 @@ func (ctr *container) start(attachStdio StdioCallback) error {
|
| 83 | 83 |
createProcessParms.CommandLine = strings.Join(ctr.ociSpec.Process.Args, " ") |
| 84 | 84 |
createProcessParms.User = ctr.ociSpec.Process.User.Username |
| 85 | 85 |
|
| 86 |
+ // LCOW requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM. |
|
| 87 |
+ if system.LCOWSupported() && ctr.ociSpec.Platform.OS == "linux" {
|
|
| 88 |
+ ociBuf, err := json.Marshal(ctr.ociSpec) |
|
| 89 |
+ if err != nil {
|
|
| 90 |
+ return err |
|
| 91 |
+ } |
|
| 92 |
+ ociRaw := json.RawMessage(ociBuf) |
|
| 93 |
+ createProcessParms.OCISpecification = &ociRaw |
|
| 94 |
+ } |
|
| 95 |
+ |
|
| 86 | 96 |
// Start the command running in the container. |
| 87 | 97 |
newProcess, err := ctr.hcsContainer.CreateProcess(createProcessParms) |
| 88 | 98 |
if err != nil {
|
| ... | ... |
@@ -228,11 +240,14 @@ func (ctr *container) waitExit(process *process, isFirstProcessToStart bool) err |
| 228 | 228 |
if !isFirstProcessToStart {
|
| 229 | 229 |
si.State = StateExitProcess |
| 230 | 230 |
} else {
|
| 231 |
- updatePending, err := ctr.hcsContainer.HasPendingUpdates() |
|
| 232 |
- if err != nil {
|
|
| 233 |
- logrus.Warnf("libcontainerd: HasPendingUpdates() failed (container may have been killed): %s", err)
|
|
| 234 |
- } else {
|
|
| 235 |
- si.UpdatePending = updatePending |
|
| 231 |
+ // Pending updates is only applicable for WCOW |
|
| 232 |
+ if ctr.ociSpec.Platform.OS == "windows" {
|
|
| 233 |
+ updatePending, err := ctr.hcsContainer.HasPendingUpdates() |
|
| 234 |
+ if err != nil {
|
|
| 235 |
+ logrus.Warnf("libcontainerd: HasPendingUpdates() failed (container may have been killed): %s", err)
|
|
| 236 |
+ } else {
|
|
| 237 |
+ si.UpdatePending = updatePending |
|
| 238 |
+ } |
|
| 236 | 239 |
} |
| 237 | 240 |
|
| 238 | 241 |
logrus.Debugf("libcontainerd: shutting down container %s", ctr.containerID)
|
| 239 | 242 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,221 @@ |
| 0 |
+package oci |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "os" |
|
| 4 |
+ "runtime" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/opencontainers/runtime-spec/specs-go" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func iPtr(i int64) *int64 { return &i }
|
|
| 10 |
+func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
|
|
| 11 |
+func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
|
|
| 12 |
+ |
|
| 13 |
+func defaultCapabilities() []string {
|
|
| 14 |
+ return []string{
|
|
| 15 |
+ "CAP_CHOWN", |
|
| 16 |
+ "CAP_DAC_OVERRIDE", |
|
| 17 |
+ "CAP_FSETID", |
|
| 18 |
+ "CAP_FOWNER", |
|
| 19 |
+ "CAP_MKNOD", |
|
| 20 |
+ "CAP_NET_RAW", |
|
| 21 |
+ "CAP_SETGID", |
|
| 22 |
+ "CAP_SETUID", |
|
| 23 |
+ "CAP_SETFCAP", |
|
| 24 |
+ "CAP_SETPCAP", |
|
| 25 |
+ "CAP_NET_BIND_SERVICE", |
|
| 26 |
+ "CAP_SYS_CHROOT", |
|
| 27 |
+ "CAP_KILL", |
|
| 28 |
+ "CAP_AUDIT_WRITE", |
|
| 29 |
+ } |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+// DefaultSpec returns the default spec used by docker for the current Platform |
|
| 33 |
+func DefaultSpec() specs.Spec {
|
|
| 34 |
+ return DefaultOSSpec(runtime.GOOS) |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+// DefaultOSSpec returns the spec for a given OS |
|
| 38 |
+func DefaultOSSpec(osName string) specs.Spec {
|
|
| 39 |
+ if osName == "windows" {
|
|
| 40 |
+ return DefaultWindowsSpec() |
|
| 41 |
+ } else if osName == "solaris" {
|
|
| 42 |
+ return DefaultSolarisSpec() |
|
| 43 |
+ } else {
|
|
| 44 |
+ return DefaultLinuxSpec() |
|
| 45 |
+ } |
|
| 46 |
+} |
|
| 47 |
+ |
|
| 48 |
+// DefaultWindowsSpec create a default spec for running Windows containers |
|
| 49 |
+func DefaultWindowsSpec() specs.Spec {
|
|
| 50 |
+ return specs.Spec{
|
|
| 51 |
+ Version: specs.Version, |
|
| 52 |
+ Platform: specs.Platform{
|
|
| 53 |
+ OS: runtime.GOOS, |
|
| 54 |
+ Arch: runtime.GOARCH, |
|
| 55 |
+ }, |
|
| 56 |
+ Windows: &specs.Windows{},
|
|
| 57 |
+ } |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 60 |
+// DefaultSolarisSpec create a default spec for running Solaris containers |
|
| 61 |
+func DefaultSolarisSpec() specs.Spec {
|
|
| 62 |
+ s := specs.Spec{
|
|
| 63 |
+ Version: "0.6.0", |
|
| 64 |
+ Platform: specs.Platform{
|
|
| 65 |
+ OS: "SunOS", |
|
| 66 |
+ Arch: runtime.GOARCH, |
|
| 67 |
+ }, |
|
| 68 |
+ } |
|
| 69 |
+ s.Solaris = &specs.Solaris{}
|
|
| 70 |
+ return s |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+// DefaultLinuxSpec create a default spec for running Linux containers |
|
| 74 |
+func DefaultLinuxSpec() specs.Spec {
|
|
| 75 |
+ s := specs.Spec{
|
|
| 76 |
+ Version: specs.Version, |
|
| 77 |
+ Platform: specs.Platform{
|
|
| 78 |
+ OS: "linux", |
|
| 79 |
+ Arch: runtime.GOARCH, |
|
| 80 |
+ }, |
|
| 81 |
+ } |
|
| 82 |
+ s.Mounts = []specs.Mount{
|
|
| 83 |
+ {
|
|
| 84 |
+ Destination: "/proc", |
|
| 85 |
+ Type: "proc", |
|
| 86 |
+ Source: "proc", |
|
| 87 |
+ Options: []string{"nosuid", "noexec", "nodev"},
|
|
| 88 |
+ }, |
|
| 89 |
+ {
|
|
| 90 |
+ Destination: "/dev", |
|
| 91 |
+ Type: "tmpfs", |
|
| 92 |
+ Source: "tmpfs", |
|
| 93 |
+ Options: []string{"nosuid", "strictatime", "mode=755"},
|
|
| 94 |
+ }, |
|
| 95 |
+ {
|
|
| 96 |
+ Destination: "/dev/pts", |
|
| 97 |
+ Type: "devpts", |
|
| 98 |
+ Source: "devpts", |
|
| 99 |
+ Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
|
|
| 100 |
+ }, |
|
| 101 |
+ {
|
|
| 102 |
+ Destination: "/sys", |
|
| 103 |
+ Type: "sysfs", |
|
| 104 |
+ Source: "sysfs", |
|
| 105 |
+ Options: []string{"nosuid", "noexec", "nodev", "ro"},
|
|
| 106 |
+ }, |
|
| 107 |
+ {
|
|
| 108 |
+ Destination: "/sys/fs/cgroup", |
|
| 109 |
+ Type: "cgroup", |
|
| 110 |
+ Source: "cgroup", |
|
| 111 |
+ Options: []string{"ro", "nosuid", "noexec", "nodev"},
|
|
| 112 |
+ }, |
|
| 113 |
+ {
|
|
| 114 |
+ Destination: "/dev/mqueue", |
|
| 115 |
+ Type: "mqueue", |
|
| 116 |
+ Source: "mqueue", |
|
| 117 |
+ Options: []string{"nosuid", "noexec", "nodev"},
|
|
| 118 |
+ }, |
|
| 119 |
+ } |
|
| 120 |
+ s.Process.Capabilities = &specs.LinuxCapabilities{
|
|
| 121 |
+ Bounding: defaultCapabilities(), |
|
| 122 |
+ Permitted: defaultCapabilities(), |
|
| 123 |
+ Inheritable: defaultCapabilities(), |
|
| 124 |
+ Effective: defaultCapabilities(), |
|
| 125 |
+ } |
|
| 126 |
+ |
|
| 127 |
+ s.Linux = &specs.Linux{
|
|
| 128 |
+ MaskedPaths: []string{
|
|
| 129 |
+ "/proc/kcore", |
|
| 130 |
+ "/proc/latency_stats", |
|
| 131 |
+ "/proc/timer_list", |
|
| 132 |
+ "/proc/timer_stats", |
|
| 133 |
+ "/proc/sched_debug", |
|
| 134 |
+ }, |
|
| 135 |
+ ReadonlyPaths: []string{
|
|
| 136 |
+ "/proc/asound", |
|
| 137 |
+ "/proc/bus", |
|
| 138 |
+ "/proc/fs", |
|
| 139 |
+ "/proc/irq", |
|
| 140 |
+ "/proc/sys", |
|
| 141 |
+ "/proc/sysrq-trigger", |
|
| 142 |
+ }, |
|
| 143 |
+ Namespaces: []specs.LinuxNamespace{
|
|
| 144 |
+ {Type: "mount"},
|
|
| 145 |
+ {Type: "network"},
|
|
| 146 |
+ {Type: "uts"},
|
|
| 147 |
+ {Type: "pid"},
|
|
| 148 |
+ {Type: "ipc"},
|
|
| 149 |
+ }, |
|
| 150 |
+ // Devices implicitly contains the following devices: |
|
| 151 |
+ // null, zero, full, random, urandom, tty, console, and ptmx. |
|
| 152 |
+ // ptmx is a bind-mount or symlink of the container's ptmx. |
|
| 153 |
+ // See also: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices |
|
| 154 |
+ Devices: []specs.LinuxDevice{},
|
|
| 155 |
+ Resources: &specs.LinuxResources{
|
|
| 156 |
+ Devices: []specs.LinuxDeviceCgroup{
|
|
| 157 |
+ {
|
|
| 158 |
+ Allow: false, |
|
| 159 |
+ Access: "rwm", |
|
| 160 |
+ }, |
|
| 161 |
+ {
|
|
| 162 |
+ Allow: true, |
|
| 163 |
+ Type: "c", |
|
| 164 |
+ Major: iPtr(1), |
|
| 165 |
+ Minor: iPtr(5), |
|
| 166 |
+ Access: "rwm", |
|
| 167 |
+ }, |
|
| 168 |
+ {
|
|
| 169 |
+ Allow: true, |
|
| 170 |
+ Type: "c", |
|
| 171 |
+ Major: iPtr(1), |
|
| 172 |
+ Minor: iPtr(3), |
|
| 173 |
+ Access: "rwm", |
|
| 174 |
+ }, |
|
| 175 |
+ {
|
|
| 176 |
+ Allow: true, |
|
| 177 |
+ Type: "c", |
|
| 178 |
+ Major: iPtr(1), |
|
| 179 |
+ Minor: iPtr(9), |
|
| 180 |
+ Access: "rwm", |
|
| 181 |
+ }, |
|
| 182 |
+ {
|
|
| 183 |
+ Allow: true, |
|
| 184 |
+ Type: "c", |
|
| 185 |
+ Major: iPtr(1), |
|
| 186 |
+ Minor: iPtr(8), |
|
| 187 |
+ Access: "rwm", |
|
| 188 |
+ }, |
|
| 189 |
+ {
|
|
| 190 |
+ Allow: true, |
|
| 191 |
+ Type: "c", |
|
| 192 |
+ Major: iPtr(5), |
|
| 193 |
+ Minor: iPtr(0), |
|
| 194 |
+ Access: "rwm", |
|
| 195 |
+ }, |
|
| 196 |
+ {
|
|
| 197 |
+ Allow: true, |
|
| 198 |
+ Type: "c", |
|
| 199 |
+ Major: iPtr(5), |
|
| 200 |
+ Minor: iPtr(1), |
|
| 201 |
+ Access: "rwm", |
|
| 202 |
+ }, |
|
| 203 |
+ {
|
|
| 204 |
+ Allow: false, |
|
| 205 |
+ Type: "c", |
|
| 206 |
+ Major: iPtr(10), |
|
| 207 |
+ Minor: iPtr(229), |
|
| 208 |
+ Access: "rwm", |
|
| 209 |
+ }, |
|
| 210 |
+ }, |
|
| 211 |
+ }, |
|
| 212 |
+ } |
|
| 213 |
+ |
|
| 214 |
+ // For LCOW support, don't mask /sys/firmware |
|
| 215 |
+ if runtime.GOOS != "windows" {
|
|
| 216 |
+ s.Linux.MaskedPaths = append(s.Linux.MaskedPaths, "/sys/firmware") |
|
| 217 |
+ } |
|
| 218 |
+ |
|
| 219 |
+ return s |
|
| 220 |
+} |
| 0 | 221 |
deleted file mode 100644 |
| ... | ... |
@@ -1,176 +0,0 @@ |
| 1 |
-package oci |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "os" |
|
| 5 |
- "runtime" |
|
| 6 |
- |
|
| 7 |
- "github.com/opencontainers/runtime-spec/specs-go" |
|
| 8 |
-) |
|
| 9 |
- |
|
| 10 |
-func iPtr(i int64) *int64 { return &i }
|
|
| 11 |
-func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
|
|
| 12 |
-func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
|
|
| 13 |
- |
|
| 14 |
-func defaultCapabilities() []string {
|
|
| 15 |
- return []string{
|
|
| 16 |
- "CAP_CHOWN", |
|
| 17 |
- "CAP_DAC_OVERRIDE", |
|
| 18 |
- "CAP_FSETID", |
|
| 19 |
- "CAP_FOWNER", |
|
| 20 |
- "CAP_MKNOD", |
|
| 21 |
- "CAP_NET_RAW", |
|
| 22 |
- "CAP_SETGID", |
|
| 23 |
- "CAP_SETUID", |
|
| 24 |
- "CAP_SETFCAP", |
|
| 25 |
- "CAP_SETPCAP", |
|
| 26 |
- "CAP_NET_BIND_SERVICE", |
|
| 27 |
- "CAP_SYS_CHROOT", |
|
| 28 |
- "CAP_KILL", |
|
| 29 |
- "CAP_AUDIT_WRITE", |
|
| 30 |
- } |
|
| 31 |
-} |
|
| 32 |
- |
|
| 33 |
-// DefaultSpec returns default oci spec used by docker. |
|
| 34 |
-func DefaultSpec() specs.Spec {
|
|
| 35 |
- s := specs.Spec{
|
|
| 36 |
- Version: specs.Version, |
|
| 37 |
- Platform: specs.Platform{
|
|
| 38 |
- OS: runtime.GOOS, |
|
| 39 |
- Arch: runtime.GOARCH, |
|
| 40 |
- }, |
|
| 41 |
- } |
|
| 42 |
- s.Mounts = []specs.Mount{
|
|
| 43 |
- {
|
|
| 44 |
- Destination: "/proc", |
|
| 45 |
- Type: "proc", |
|
| 46 |
- Source: "proc", |
|
| 47 |
- Options: []string{"nosuid", "noexec", "nodev"},
|
|
| 48 |
- }, |
|
| 49 |
- {
|
|
| 50 |
- Destination: "/dev", |
|
| 51 |
- Type: "tmpfs", |
|
| 52 |
- Source: "tmpfs", |
|
| 53 |
- Options: []string{"nosuid", "strictatime", "mode=755"},
|
|
| 54 |
- }, |
|
| 55 |
- {
|
|
| 56 |
- Destination: "/dev/pts", |
|
| 57 |
- Type: "devpts", |
|
| 58 |
- Source: "devpts", |
|
| 59 |
- Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
|
|
| 60 |
- }, |
|
| 61 |
- {
|
|
| 62 |
- Destination: "/sys", |
|
| 63 |
- Type: "sysfs", |
|
| 64 |
- Source: "sysfs", |
|
| 65 |
- Options: []string{"nosuid", "noexec", "nodev", "ro"},
|
|
| 66 |
- }, |
|
| 67 |
- {
|
|
| 68 |
- Destination: "/sys/fs/cgroup", |
|
| 69 |
- Type: "cgroup", |
|
| 70 |
- Source: "cgroup", |
|
| 71 |
- Options: []string{"ro", "nosuid", "noexec", "nodev"},
|
|
| 72 |
- }, |
|
| 73 |
- {
|
|
| 74 |
- Destination: "/dev/mqueue", |
|
| 75 |
- Type: "mqueue", |
|
| 76 |
- Source: "mqueue", |
|
| 77 |
- Options: []string{"nosuid", "noexec", "nodev"},
|
|
| 78 |
- }, |
|
| 79 |
- } |
|
| 80 |
- s.Process.Capabilities = &specs.LinuxCapabilities{
|
|
| 81 |
- Bounding: defaultCapabilities(), |
|
| 82 |
- Permitted: defaultCapabilities(), |
|
| 83 |
- Inheritable: defaultCapabilities(), |
|
| 84 |
- Effective: defaultCapabilities(), |
|
| 85 |
- } |
|
| 86 |
- |
|
| 87 |
- s.Linux = &specs.Linux{
|
|
| 88 |
- MaskedPaths: []string{
|
|
| 89 |
- "/proc/kcore", |
|
| 90 |
- "/proc/latency_stats", |
|
| 91 |
- "/proc/timer_list", |
|
| 92 |
- "/proc/timer_stats", |
|
| 93 |
- "/proc/sched_debug", |
|
| 94 |
- "/sys/firmware", |
|
| 95 |
- }, |
|
| 96 |
- ReadonlyPaths: []string{
|
|
| 97 |
- "/proc/asound", |
|
| 98 |
- "/proc/bus", |
|
| 99 |
- "/proc/fs", |
|
| 100 |
- "/proc/irq", |
|
| 101 |
- "/proc/sys", |
|
| 102 |
- "/proc/sysrq-trigger", |
|
| 103 |
- }, |
|
| 104 |
- Namespaces: []specs.LinuxNamespace{
|
|
| 105 |
- {Type: "mount"},
|
|
| 106 |
- {Type: "network"},
|
|
| 107 |
- {Type: "uts"},
|
|
| 108 |
- {Type: "pid"},
|
|
| 109 |
- {Type: "ipc"},
|
|
| 110 |
- }, |
|
| 111 |
- // Devices implicitly contains the following devices: |
|
| 112 |
- // null, zero, full, random, urandom, tty, console, and ptmx. |
|
| 113 |
- // ptmx is a bind-mount or symlink of the container's ptmx. |
|
| 114 |
- // See also: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices |
|
| 115 |
- Devices: []specs.LinuxDevice{},
|
|
| 116 |
- Resources: &specs.LinuxResources{
|
|
| 117 |
- Devices: []specs.LinuxDeviceCgroup{
|
|
| 118 |
- {
|
|
| 119 |
- Allow: false, |
|
| 120 |
- Access: "rwm", |
|
| 121 |
- }, |
|
| 122 |
- {
|
|
| 123 |
- Allow: true, |
|
| 124 |
- Type: "c", |
|
| 125 |
- Major: iPtr(1), |
|
| 126 |
- Minor: iPtr(5), |
|
| 127 |
- Access: "rwm", |
|
| 128 |
- }, |
|
| 129 |
- {
|
|
| 130 |
- Allow: true, |
|
| 131 |
- Type: "c", |
|
| 132 |
- Major: iPtr(1), |
|
| 133 |
- Minor: iPtr(3), |
|
| 134 |
- Access: "rwm", |
|
| 135 |
- }, |
|
| 136 |
- {
|
|
| 137 |
- Allow: true, |
|
| 138 |
- Type: "c", |
|
| 139 |
- Major: iPtr(1), |
|
| 140 |
- Minor: iPtr(9), |
|
| 141 |
- Access: "rwm", |
|
| 142 |
- }, |
|
| 143 |
- {
|
|
| 144 |
- Allow: true, |
|
| 145 |
- Type: "c", |
|
| 146 |
- Major: iPtr(1), |
|
| 147 |
- Minor: iPtr(8), |
|
| 148 |
- Access: "rwm", |
|
| 149 |
- }, |
|
| 150 |
- {
|
|
| 151 |
- Allow: true, |
|
| 152 |
- Type: "c", |
|
| 153 |
- Major: iPtr(5), |
|
| 154 |
- Minor: iPtr(0), |
|
| 155 |
- Access: "rwm", |
|
| 156 |
- }, |
|
| 157 |
- {
|
|
| 158 |
- Allow: true, |
|
| 159 |
- Type: "c", |
|
| 160 |
- Major: iPtr(5), |
|
| 161 |
- Minor: iPtr(1), |
|
| 162 |
- Access: "rwm", |
|
| 163 |
- }, |
|
| 164 |
- {
|
|
| 165 |
- Allow: false, |
|
| 166 |
- Type: "c", |
|
| 167 |
- Major: iPtr(10), |
|
| 168 |
- Minor: iPtr(229), |
|
| 169 |
- Access: "rwm", |
|
| 170 |
- }, |
|
| 171 |
- }, |
|
| 172 |
- }, |
|
| 173 |
- } |
|
| 174 |
- |
|
| 175 |
- return s |
|
| 176 |
-} |
| 177 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,20 +0,0 @@ |
| 1 |
-package oci |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "runtime" |
|
| 5 |
- |
|
| 6 |
- "github.com/opencontainers/runtime-spec/specs-go" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// DefaultSpec returns default oci spec used by docker. |
|
| 10 |
-func DefaultSpec() specs.Spec {
|
|
| 11 |
- s := specs.Spec{
|
|
| 12 |
- Version: "0.6.0", |
|
| 13 |
- Platform: specs.Platform{
|
|
| 14 |
- OS: "SunOS", |
|
| 15 |
- Arch: runtime.GOARCH, |
|
| 16 |
- }, |
|
| 17 |
- } |
|
| 18 |
- s.Solaris = &specs.Solaris{}
|
|
| 19 |
- return s |
|
| 20 |
-} |
| 21 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,19 +0,0 @@ |
| 1 |
-package oci |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "runtime" |
|
| 5 |
- |
|
| 6 |
- "github.com/opencontainers/runtime-spec/specs-go" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// DefaultSpec returns default spec used by docker. |
|
| 10 |
-func DefaultSpec() specs.Spec {
|
|
| 11 |
- return specs.Spec{
|
|
| 12 |
- Version: specs.Version, |
|
| 13 |
- Platform: specs.Platform{
|
|
| 14 |
- OS: runtime.GOOS, |
|
| 15 |
- Arch: runtime.GOARCH, |
|
| 16 |
- }, |
|
| 17 |
- Windows: &specs.Windows{},
|
|
| 18 |
- } |
|
| 19 |
-} |
| 20 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 0 |
+package system |
|
| 1 |
+ |
|
| 2 |
+import "runtime" |
|
| 3 |
+ |
|
| 4 |
+const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
|
| 5 |
+ |
|
| 6 |
+// DefaultPathEnv is unix style list of directories to search for |
|
| 7 |
+// executables. Each directory is separated from the next by a colon |
|
| 8 |
+// ':' character . |
|
| 9 |
+func DefaultPathEnv(platform string) string {
|
|
| 10 |
+ if runtime.GOOS == "windows" {
|
|
| 11 |
+ if platform != runtime.GOOS && LCOWSupported() {
|
|
| 12 |
+ return defaultUnixPathEnv |
|
| 13 |
+ } |
|
| 14 |
+ // Deliberately empty on Windows containers on Windows as the default path will be set by |
|
| 15 |
+ // the container. Docker has no context of what the default path should be. |
|
| 16 |
+ return "" |
|
| 17 |
+ } |
|
| 18 |
+ return defaultUnixPathEnv |
|
| 19 |
+ |
|
| 20 |
+} |
| ... | ... |
@@ -2,11 +2,6 @@ |
| 2 | 2 |
|
| 3 | 3 |
package system |
| 4 | 4 |
|
| 5 |
-// DefaultPathEnv is unix style list of directories to search for |
|
| 6 |
-// executables. Each directory is separated from the next by a colon |
|
| 7 |
-// ':' character . |
|
| 8 |
-const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
|
| 9 |
- |
|
| 10 | 5 |
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter, |
| 11 | 6 |
// is the system drive. This is a no-op on Linux. |
| 12 | 7 |
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
| ... | ... |
@@ -8,10 +8,6 @@ import ( |
| 8 | 8 |
"strings" |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 |
-// DefaultPathEnv is deliberately empty on Windows as the default path will be set by |
|
| 12 |
-// the container. Docker has no context of what the default path should be. |
|
| 13 |
-const DefaultPathEnv = "" |
|
| 14 |
- |
|
| 15 | 11 |
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path. |
| 16 | 12 |
// This is used, for example, when validating a user provided path in docker cp. |
| 17 | 13 |
// If a drive letter is supplied, it must be the system drive. The drive letter |
| ... | ... |
@@ -5,6 +5,7 @@ package v2 |
| 5 | 5 |
import ( |
| 6 | 6 |
"os" |
| 7 | 7 |
"path/filepath" |
| 8 |
+ "runtime" |
|
| 8 | 9 |
"strings" |
| 9 | 10 |
|
| 10 | 11 |
"github.com/docker/docker/api/types" |
| ... | ... |
@@ -108,7 +109,7 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
|
| 108 | 108 |
} |
| 109 | 109 |
|
| 110 | 110 |
envs := make([]string, 1, len(p.PluginObj.Settings.Env)+1) |
| 111 |
- envs[0] = "PATH=" + system.DefaultPathEnv |
|
| 111 |
+ envs[0] = "PATH=" + system.DefaultPathEnv(runtime.GOOS) |
|
| 112 | 112 |
envs = append(envs, p.PluginObj.Settings.Env...) |
| 113 | 113 |
|
| 114 | 114 |
args := append(p.PluginObj.Config.Entrypoint, p.PluginObj.Settings.Args...) |