LCOW: OCI Spec and Environment for container start
Signed-off-by: John Howard <jhoward@microsoft.com>
This commit is contained in:
parent
07034a4420
commit
f154588226
15 changed files with 275 additions and 107 deletions
|
@ -203,7 +203,7 @@ func TestFromScratch(t *testing.T) {
|
|||
assert.True(t, req.state.hasFromImage())
|
||||
assert.Equal(t, "", req.state.imageID)
|
||||
// Windows does not set the default path. TODO @jhowardmsft LCOW support. This will need revisiting as we get further into the implementation
|
||||
expected := "PATH=" + system.DefaultPathEnv
|
||||
expected := "PATH=" + system.DefaultPathEnv(runtime.GOOS)
|
||||
if runtime.GOOS == "windows" {
|
||||
expected = ""
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package dockerfile
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
|
@ -228,14 +229,19 @@ func (s *dispatchState) beginStage(stageName string, image builder.Image) {
|
|||
}
|
||||
|
||||
// Add the default PATH to runConfig.ENV if one exists for the platform and there
|
||||
// is no PATH set. Note that windows won't have one as it's set by HCS
|
||||
// is no PATH set. Note that Windows containers on Windows won't have one as it's set by HCS
|
||||
func (s *dispatchState) setDefaultPath() {
|
||||
if system.DefaultPathEnv == "" {
|
||||
// TODO @jhowardmsft LCOW Support - This will need revisiting later
|
||||
platform := runtime.GOOS
|
||||
if platform == "windows" && system.LCOWSupported() {
|
||||
platform = "linux"
|
||||
}
|
||||
if system.DefaultPathEnv(platform) == "" {
|
||||
return
|
||||
}
|
||||
envMap := opts.ConvertKVStringsToMap(s.runConfig.Env)
|
||||
if _, ok := envMap["PATH"]; !ok {
|
||||
s.runConfig.Env = append(s.runConfig.Env, "PATH="+system.DefaultPathEnv)
|
||||
s.runConfig.Env = append(s.runConfig.Env, "PATH="+system.DefaultPathEnv(platform))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/docker/docker/restartmanager"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/volume"
|
||||
|
@ -1004,3 +1005,31 @@ func (container *Container) ConfigsDirPath() string {
|
|||
func (container *Container) ConfigFilePath(configRef swarmtypes.ConfigReference) string {
|
||||
return filepath.Join(container.ConfigsDirPath(), configRef.ConfigID)
|
||||
}
|
||||
|
||||
// CreateDaemonEnvironment creates a new environment variable slice for this container.
|
||||
func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string) []string {
|
||||
// Setup environment
|
||||
// TODO @jhowardmsft LCOW Support. This will need revisiting later.
|
||||
platform := container.Platform
|
||||
if platform == "" {
|
||||
platform = runtime.GOOS
|
||||
}
|
||||
env := []string{}
|
||||
if runtime.GOOS != "windows" || (runtime.GOOS == "windows" && system.LCOWSupported() && platform == "linux") {
|
||||
env = []string{
|
||||
"PATH=" + system.DefaultPathEnv(platform),
|
||||
"HOSTNAME=" + container.Config.Hostname,
|
||||
}
|
||||
if tty {
|
||||
env = append(env, "TERM=xterm")
|
||||
}
|
||||
env = append(env, linkedEnv...)
|
||||
}
|
||||
|
||||
// because the env on the container can override certain default values
|
||||
// we need to replace the 'env' keys where they match and append anything
|
||||
// else.
|
||||
//return ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env)
|
||||
foo := ReplaceOrAppendEnvValues(env, container.Config.Env)
|
||||
return foo
|
||||
}
|
||||
|
|
|
@ -35,27 +35,6 @@ type ExitStatus struct {
|
|||
OOMKilled bool
|
||||
}
|
||||
|
||||
// CreateDaemonEnvironment returns the list of all environment variables given the list of
|
||||
// environment variables related to links.
|
||||
// Sets PATH, HOSTNAME and if container.Config.Tty is set: TERM.
|
||||
// The defaults set here do not override the values in container.Config.Env
|
||||
func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string) []string {
|
||||
// Setup environment
|
||||
env := []string{
|
||||
"PATH=" + system.DefaultPathEnv,
|
||||
"HOSTNAME=" + container.Config.Hostname,
|
||||
}
|
||||
if tty {
|
||||
env = append(env, "TERM=xterm")
|
||||
}
|
||||
env = append(env, linkedEnv...)
|
||||
// because the env on the container can override certain default values
|
||||
// we need to replace the 'env' keys where they match and append anything
|
||||
// else.
|
||||
env = ReplaceOrAppendEnvValues(env, container.Config.Env)
|
||||
return env
|
||||
}
|
||||
|
||||
// TrySetNetworkMount attempts to set the network mounts given a provided destination and
|
||||
// the path to use for it; return true if the given destination was a network mount file
|
||||
func (container *Container) TrySetNetworkMount(destination string, path string) bool {
|
||||
|
|
|
@ -23,14 +23,6 @@ type ExitStatus struct {
|
|||
ExitCode int
|
||||
}
|
||||
|
||||
// CreateDaemonEnvironment creates a new environment variable slice for this container.
|
||||
func (container *Container) CreateDaemonEnvironment(_ bool, linkedEnv []string) []string {
|
||||
// because the env on the container can override certain default values
|
||||
// we need to replace the 'env' keys where they match and append anything
|
||||
// else.
|
||||
return ReplaceOrAppendEnvValues(linkedEnv, container.Config.Env)
|
||||
}
|
||||
|
||||
// UnmountIpcMounts unmounts Ipc related mounts.
|
||||
// This is a NOOP on windows.
|
||||
func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
|
||||
|
|
|
@ -7,11 +7,17 @@ import (
|
|||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/oci"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
||||
s := oci.DefaultSpec()
|
||||
img, err := daemon.GetImage(string(c.ImageID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := oci.DefaultOSSpec(img.OS)
|
||||
|
||||
linkedEnv, err := daemon.setupLinkedContainers(c)
|
||||
if err != nil {
|
||||
|
@ -95,7 +101,30 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
|||
if !c.Config.ArgsEscaped {
|
||||
s.Process.Args = escapeArgs(s.Process.Args)
|
||||
}
|
||||
|
||||
s.Process.Cwd = c.Config.WorkingDir
|
||||
s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
|
||||
if c.Config.Tty {
|
||||
s.Process.Terminal = c.Config.Tty
|
||||
s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0]
|
||||
s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1]
|
||||
}
|
||||
s.Process.User.Username = c.Config.User
|
||||
|
||||
if img.OS == "windows" {
|
||||
daemon.createSpecWindowsFields(c, &s, isHyperV)
|
||||
} else {
|
||||
// TODO @jhowardmsft LCOW Support. Modify this check when running in dual-mode
|
||||
if system.LCOWSupported() && img.OS == "linux" {
|
||||
daemon.createSpecLinuxFields(c, &s)
|
||||
}
|
||||
}
|
||||
|
||||
return (*specs.Spec)(&s), nil
|
||||
}
|
||||
|
||||
// Sets the Windows-specific fields of the OCI spec
|
||||
func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.Spec, isHyperV bool) {
|
||||
if len(s.Process.Cwd) == 0 {
|
||||
// We default to C:\ to workaround the oddity of the case that the
|
||||
// default directory for cmd running as LocalSystem (or
|
||||
|
@ -106,17 +135,11 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
|||
// as c:\. Hence, setting it to default of c:\ makes for consistency.
|
||||
s.Process.Cwd = `C:\`
|
||||
}
|
||||
s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
|
||||
s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0]
|
||||
s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1]
|
||||
s.Process.Terminal = c.Config.Tty
|
||||
s.Process.User.Username = c.Config.User
|
||||
|
||||
// In spec.Root. This is not set for Hyper-V containers
|
||||
if !isHyperV {
|
||||
s.Root.Path = c.BaseFS
|
||||
}
|
||||
s.Root.Readonly = false // Windows does not support a read-only root filesystem
|
||||
if !isHyperV {
|
||||
s.Root.Path = c.BaseFS // This is not set for Hyper-V containers
|
||||
}
|
||||
|
||||
// In s.Windows.Resources
|
||||
cpuShares := uint16(c.HostConfig.CPUShares)
|
||||
|
@ -157,7 +180,17 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
|||
Iops: &c.HostConfig.IOMaximumIOps,
|
||||
},
|
||||
}
|
||||
return (*specs.Spec)(&s), nil
|
||||
}
|
||||
|
||||
// Sets the Linux-specific fields of the OCI spec
|
||||
// TODO: @jhowardmsft LCOW Support. We need to do a lot more pulling in what can
|
||||
// be pulled in from oci_linux.go.
|
||||
func (daemon *Daemon) createSpecLinuxFields(c *container.Container, s *specs.Spec) {
|
||||
if len(s.Process.Cwd) == 0 {
|
||||
s.Process.Cwd = `/`
|
||||
}
|
||||
s.Root.Path = "rootfs"
|
||||
s.Root.Readonly = c.HostConfig.ReadonlyRootfs
|
||||
}
|
||||
|
||||
func escapeArgs(args []string) []string {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package libcontainerd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -96,8 +97,17 @@ const defaultOwner = "docker"
|
|||
func (clnt *client) Create(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
|
||||
clnt.lock(containerID)
|
||||
defer clnt.unlock(containerID)
|
||||
logrus.Debugln("libcontainerd: client.Create() with spec", spec)
|
||||
if b, err := json.Marshal(spec); err == nil {
|
||||
logrus.Debugln("libcontainerd: client.Create() with spec", string(b))
|
||||
}
|
||||
osName := spec.Platform.OS
|
||||
if osName == "windows" {
|
||||
return clnt.createWindows(containerID, checkpoint, checkpointDir, spec, attachStdio, options...)
|
||||
}
|
||||
return clnt.createLinux(containerID, checkpoint, checkpointDir, spec, attachStdio, options...)
|
||||
}
|
||||
|
||||
func (clnt *client) createWindows(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
|
||||
configuration := &hcsshim.ContainerConfig{
|
||||
SystemType: "Container",
|
||||
Name: containerID,
|
||||
|
@ -265,17 +275,100 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir
|
|||
// Call start, and if it fails, delete the container from our
|
||||
// internal structure, start will keep HCS in sync by deleting the
|
||||
// container there.
|
||||
logrus.Debugf("libcontainerd: Create() id=%s, Calling start()", containerID)
|
||||
logrus.Debugf("libcontainerd: createWindows() id=%s, Calling start()", containerID)
|
||||
if err := container.start(attachStdio); err != nil {
|
||||
clnt.deleteContainer(containerID)
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("libcontainerd: Create() id=%s completed successfully", containerID)
|
||||
logrus.Debugf("libcontainerd: createWindows() id=%s completed successfully", containerID)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (clnt *client) createLinux(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
|
||||
logrus.Debugf("libcontainerd: createLinux(): containerId %s ", containerID)
|
||||
|
||||
// TODO @jhowardmsft LCOW Support: This needs to be configurable, not hard-coded.
|
||||
// However, good-enough for the LCOW bring-up.
|
||||
configuration := &hcsshim.ContainerConfig{
|
||||
HvPartition: true,
|
||||
Name: containerID,
|
||||
SystemType: "container",
|
||||
ContainerType: "linux",
|
||||
TerminateOnLastHandleClosed: true,
|
||||
HvRuntime: &hcsshim.HvRuntime{
|
||||
ImagePath: `c:\program files\lcow`,
|
||||
},
|
||||
}
|
||||
|
||||
var layerOpt *LayerOption
|
||||
for _, option := range options {
|
||||
if l, ok := option.(*LayerOption); ok {
|
||||
layerOpt = l
|
||||
}
|
||||
}
|
||||
|
||||
// We must have a layer option with at least one path
|
||||
if layerOpt == nil || layerOpt.LayerPaths == nil {
|
||||
return fmt.Errorf("no layer option or paths were supplied to the runtime")
|
||||
}
|
||||
|
||||
// LayerFolderPath (writeable layer) + Layers (Guid + path)
|
||||
configuration.LayerFolderPath = layerOpt.LayerFolderPath
|
||||
for _, layerPath := range layerOpt.LayerPaths {
|
||||
_, filename := filepath.Split(layerPath)
|
||||
g, err := hcsshim.NameToGuid(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configuration.Layers = append(configuration.Layers, hcsshim.Layer{
|
||||
ID: g.ToString(),
|
||||
Path: filepath.Join(layerPath, "layer.vhd"),
|
||||
})
|
||||
}
|
||||
|
||||
hcsContainer, err := hcsshim.CreateContainer(containerID, configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Construct a container object for calling start on it.
|
||||
container := &container{
|
||||
containerCommon: containerCommon{
|
||||
process: process{
|
||||
processCommon: processCommon{
|
||||
containerID: containerID,
|
||||
client: clnt,
|
||||
friendlyName: InitFriendlyName,
|
||||
},
|
||||
},
|
||||
processes: make(map[string]*process),
|
||||
},
|
||||
ociSpec: spec,
|
||||
hcsContainer: hcsContainer,
|
||||
}
|
||||
|
||||
container.options = options
|
||||
for _, option := range options {
|
||||
if err := option.Apply(container); err != nil {
|
||||
logrus.Errorf("libcontainerd: createLinux() %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Call start, and if it fails, delete the container from our
|
||||
// internal structure, start will keep HCS in sync by deleting the
|
||||
// container there.
|
||||
logrus.Debugf("libcontainerd: createLinux() id=%s, Calling start()", containerID)
|
||||
if err := container.start(attachStdio); err != nil {
|
||||
clnt.deleteContainer(containerID)
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("libcontainerd: createLinux() id=%s completed successfully", containerID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddProcess is the handler for adding a process to an already running
|
||||
// container. It's called through docker exec. It returns the system pid of the
|
||||
// exec'd process.
|
||||
|
@ -292,13 +385,15 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
|
|||
// create stdin, even if it's not used - it will be closed shortly. Stderr
|
||||
// is only created if it we're not -t.
|
||||
createProcessParms := hcsshim.ProcessConfig{
|
||||
EmulateConsole: procToAdd.Terminal,
|
||||
CreateStdInPipe: true,
|
||||
CreateStdOutPipe: true,
|
||||
CreateStdErrPipe: !procToAdd.Terminal,
|
||||
}
|
||||
createProcessParms.ConsoleSize[0] = uint(procToAdd.ConsoleSize.Height)
|
||||
createProcessParms.ConsoleSize[1] = uint(procToAdd.ConsoleSize.Width)
|
||||
if procToAdd.Terminal {
|
||||
createProcessParms.EmulateConsole = true
|
||||
createProcessParms.ConsoleSize[0] = uint(procToAdd.ConsoleSize.Height)
|
||||
createProcessParms.ConsoleSize[1] = uint(procToAdd.ConsoleSize.Width)
|
||||
}
|
||||
|
||||
// Take working directory from the process to add if it is defined,
|
||||
// otherwise take from the first process.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package libcontainerd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -10,6 +11,7 @@ import (
|
|||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
|
@ -83,6 +85,16 @@ func (ctr *container) start(attachStdio StdioCallback) error {
|
|||
createProcessParms.CommandLine = strings.Join(ctr.ociSpec.Process.Args, " ")
|
||||
createProcessParms.User = ctr.ociSpec.Process.User.Username
|
||||
|
||||
// LCOW requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM.
|
||||
if system.LCOWSupported() && ctr.ociSpec.Platform.OS == "linux" {
|
||||
ociBuf, err := json.Marshal(ctr.ociSpec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ociRaw := json.RawMessage(ociBuf)
|
||||
createProcessParms.OCISpecification = &ociRaw
|
||||
}
|
||||
|
||||
// Start the command running in the container.
|
||||
newProcess, err := ctr.hcsContainer.CreateProcess(createProcessParms)
|
||||
if err != nil {
|
||||
|
@ -228,11 +240,14 @@ func (ctr *container) waitExit(process *process, isFirstProcessToStart bool) err
|
|||
if !isFirstProcessToStart {
|
||||
si.State = StateExitProcess
|
||||
} else {
|
||||
updatePending, err := ctr.hcsContainer.HasPendingUpdates()
|
||||
if err != nil {
|
||||
logrus.Warnf("libcontainerd: HasPendingUpdates() failed (container may have been killed): %s", err)
|
||||
} else {
|
||||
si.UpdatePending = updatePending
|
||||
// Pending updates is only applicable for WCOW
|
||||
if ctr.ociSpec.Platform.OS == "windows" {
|
||||
updatePending, err := ctr.hcsContainer.HasPendingUpdates()
|
||||
if err != nil {
|
||||
logrus.Warnf("libcontainerd: HasPendingUpdates() failed (container may have been killed): %s", err)
|
||||
} else {
|
||||
si.UpdatePending = updatePending
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Debugf("libcontainerd: shutting down container %s", ctr.containerID)
|
||||
|
|
|
@ -30,14 +30,55 @@ func defaultCapabilities() []string {
|
|||
}
|
||||
}
|
||||
|
||||
// DefaultSpec returns default oci spec used by docker.
|
||||
// DefaultSpec returns the default spec used by docker for the current Platform
|
||||
func DefaultSpec() specs.Spec {
|
||||
s := specs.Spec{
|
||||
return DefaultOSSpec(runtime.GOOS)
|
||||
}
|
||||
|
||||
// DefaultOSSpec returns the spec for a given OS
|
||||
func DefaultOSSpec(osName string) specs.Spec {
|
||||
if osName == "windows" {
|
||||
return DefaultWindowsSpec()
|
||||
} else if osName == "solaris" {
|
||||
return DefaultSolarisSpec()
|
||||
} else {
|
||||
return DefaultLinuxSpec()
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultWindowsSpec create a default spec for running Windows containers
|
||||
func DefaultWindowsSpec() specs.Spec {
|
||||
return specs.Spec{
|
||||
Version: specs.Version,
|
||||
Platform: specs.Platform{
|
||||
OS: runtime.GOOS,
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
Windows: &specs.Windows{},
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultSolarisSpec create a default spec for running Solaris containers
|
||||
func DefaultSolarisSpec() specs.Spec {
|
||||
s := specs.Spec{
|
||||
Version: "0.6.0",
|
||||
Platform: specs.Platform{
|
||||
OS: "SunOS",
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
}
|
||||
s.Solaris = &specs.Solaris{}
|
||||
return s
|
||||
}
|
||||
|
||||
// DefaultLinuxSpec create a default spec for running Linux containers
|
||||
func DefaultLinuxSpec() specs.Spec {
|
||||
s := specs.Spec{
|
||||
Version: specs.Version,
|
||||
Platform: specs.Platform{
|
||||
OS: "linux",
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
}
|
||||
s.Mounts = []specs.Mount{
|
||||
{
|
||||
|
@ -91,7 +132,6 @@ func DefaultSpec() specs.Spec {
|
|||
"/proc/timer_list",
|
||||
"/proc/timer_stats",
|
||||
"/proc/sched_debug",
|
||||
"/sys/firmware",
|
||||
},
|
||||
ReadonlyPaths: []string{
|
||||
"/proc/asound",
|
||||
|
@ -172,5 +212,10 @@ func DefaultSpec() specs.Spec {
|
|||
},
|
||||
}
|
||||
|
||||
// For LCOW support, don't mask /sys/firmware
|
||||
if runtime.GOOS != "windows" {
|
||||
s.Linux.MaskedPaths = append(s.Linux.MaskedPaths, "/sys/firmware")
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package oci
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// DefaultSpec returns default oci spec used by docker.
|
||||
func DefaultSpec() specs.Spec {
|
||||
s := specs.Spec{
|
||||
Version: "0.6.0",
|
||||
Platform: specs.Platform{
|
||||
OS: "SunOS",
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
}
|
||||
s.Solaris = &specs.Solaris{}
|
||||
return s
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package oci
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// DefaultSpec returns default spec used by docker.
|
||||
func DefaultSpec() specs.Spec {
|
||||
return specs.Spec{
|
||||
Version: specs.Version,
|
||||
Platform: specs.Platform{
|
||||
OS: runtime.GOOS,
|
||||
Arch: runtime.GOARCH,
|
||||
},
|
||||
Windows: &specs.Windows{},
|
||||
}
|
||||
}
|
21
pkg/system/path.go
Normal file
21
pkg/system/path.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package system
|
||||
|
||||
import "runtime"
|
||||
|
||||
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
// DefaultPathEnv is unix style list of directories to search for
|
||||
// executables. Each directory is separated from the next by a colon
|
||||
// ':' character .
|
||||
func DefaultPathEnv(platform string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
if platform != runtime.GOOS && LCOWSupported() {
|
||||
return defaultUnixPathEnv
|
||||
}
|
||||
// Deliberately empty on Windows containers on Windows as the default path will be set by
|
||||
// the container. Docker has no context of what the default path should be.
|
||||
return ""
|
||||
}
|
||||
return defaultUnixPathEnv
|
||||
|
||||
}
|
|
@ -2,11 +2,6 @@
|
|||
|
||||
package system
|
||||
|
||||
// DefaultPathEnv is unix style list of directories to search for
|
||||
// executables. Each directory is separated from the next by a colon
|
||||
// ':' character .
|
||||
const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
||||
// is the system drive. This is a no-op on Linux.
|
||||
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||
|
|
|
@ -8,10 +8,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// DefaultPathEnv is deliberately empty on Windows as the default path will be set by
|
||||
// the container. Docker has no context of what the default path should be.
|
||||
const DefaultPathEnv = ""
|
||||
|
||||
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
|
||||
// This is used, for example, when validating a user provided path in docker cp.
|
||||
// If a drive letter is supplied, it must be the system drive. The drive letter
|
||||
|
|
|
@ -5,6 +5,7 @@ package v2
|
|||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
|
@ -108,7 +109,7 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
|
|||
}
|
||||
|
||||
envs := make([]string, 1, len(p.PluginObj.Settings.Env)+1)
|
||||
envs[0] = "PATH=" + system.DefaultPathEnv
|
||||
envs[0] = "PATH=" + system.DefaultPathEnv(runtime.GOOS)
|
||||
envs = append(envs, p.PluginObj.Settings.Env...)
|
||||
|
||||
args := append(p.PluginObj.Config.Entrypoint, p.PluginObj.Settings.Args...)
|
||||
|
|
Loading…
Reference in a new issue