本文整理匯總了Golang中github.com/Microsoft/hcsshim.CreateProcessParams.Environment方法的典型用法代碼示例。如果您正苦於以下問題:Golang CreateProcessParams.Environment方法的具體用法?Golang CreateProcessParams.Environment怎麽用?Golang CreateProcessParams.Environment使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類github.com/Microsoft/hcsshim.CreateProcessParams
的用法示例。
在下文中一共展示了CreateProcessParams.Environment方法的11個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: Run
//.........這裏部分代碼省略.........
// IMPORTANT: Don't fail if fails to change state. It could already
// have been stopped through kill().
// Otherwise, the docker daemon will hang in job wait()
logrus.Warnf("Ignoring error from TerminateComputeSystem %s", err)
}
} else {
logrus.Debugf("Shutting down container %s", c.ID)
if err := hcsshim.ShutdownComputeSystem(c.ID); err != nil {
// IMPORTANT: Don't fail if fails to change state. It could already
// have been stopped through kill().
// Otherwise, the docker daemon will hang in job wait()
logrus.Warnf("Ignoring error from ShutdownComputeSystem %s", err)
}
}
}()
// We use a different pipe name between real and dummy mode in the HCS
var serverPipeFormat, clientPipeFormat string
if dummyMode {
clientPipeFormat = `\\.\pipe\docker-run-%[1]s-%[2]s`
serverPipeFormat = clientPipeFormat
} else {
clientPipeFormat = `\\.\pipe\docker-run-%[2]s`
serverPipeFormat = `\\.\Containers\%[1]s\Device\NamedPipe\docker-run-%[2]s`
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: c.ProcessConfig.Tty,
WorkingDirectory: c.WorkingDir,
ConsoleSize: c.ProcessConfig.ConsoleSize,
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(c.ProcessConfig.Env)
// Connect stdin
if pipes.Stdin != nil {
stdInPipe := fmt.Sprintf(serverPipeFormat, c.ID, "stdin")
createProcessParms.StdInPipe = fmt.Sprintf(clientPipeFormat, c.ID, "stdin")
// Listen on the named pipe
inListen, err = npipe.Listen(stdInPipe)
if err != nil {
logrus.Errorf("stdin failed to listen on %s err=%s", stdInPipe, err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
defer inListen.Close()
// Launch a goroutine to do the accept. We do this so that we can
// cause an otherwise blocking goroutine to gracefully close when
// the caller (us) closes the listener
go stdinAccept(inListen, stdInPipe, pipes.Stdin)
}
// Connect stdout
stdOutPipe := fmt.Sprintf(serverPipeFormat, c.ID, "stdout")
createProcessParms.StdOutPipe = fmt.Sprintf(clientPipeFormat, c.ID, "stdout")
outListen, err = npipe.Listen(stdOutPipe)
if err != nil {
logrus.Errorf("stdout failed to listen on %s err=%s", stdOutPipe, err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
defer outListen.Close()
go stdouterrAccept(outListen, stdOutPipe, pipes.Stdout)
示例2: AddProcess
// AddProcess is the handler for adding a process to an already running
// container. It's called through docker exec.
func (clnt *client) AddProcess(containerID, processFriendlyName string, procToAdd Process) error {
clnt.lock(containerID)
defer clnt.unlock(containerID)
container, err := clnt.getContainer(containerID)
if err != nil {
return err
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: procToAdd.Terminal,
ConsoleSize: procToAdd.InitialConsoleSize,
}
// Take working directory from the process to add if it is defined,
// otherwise take from the first process.
if procToAdd.Cwd != "" {
createProcessParms.WorkingDirectory = procToAdd.Cwd
} else {
createProcessParms.WorkingDirectory = container.ociSpec.Process.Cwd
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(procToAdd.Env)
createProcessParms.CommandLine = strings.Join(procToAdd.Args, " ")
logrus.Debugf("commandLine: %s", createProcessParms.CommandLine)
// Start the command running in the container. Note we always tell HCS to
// create stdout as it's required regardless of '-i' or '-t' options, so that
// docker can always grab the output through logs. We also tell HCS to always
// create stdin, even if it's not used - it will be closed shortly. Stderr
// is only created if it we're not -t.
var stdout, stderr io.ReadCloser
var pid uint32
iopipe := &IOPipe{Terminal: procToAdd.Terminal}
pid, iopipe.Stdin, stdout, stderr, err = hcsshim.CreateProcessInComputeSystem(
containerID,
true,
true,
!procToAdd.Terminal,
createProcessParms)
if err != nil {
logrus.Errorf("AddProcess %s CreateProcessInComputeSystem() failed %s", containerID, err)
return err
}
// Convert io.ReadClosers to io.Readers
if stdout != nil {
iopipe.Stdout = openReaderFromPipe(stdout)
}
if stderr != nil {
iopipe.Stderr = openReaderFromPipe(stderr)
}
// Add the process to the containers list of processes
container.processes[processFriendlyName] =
&process{
processCommon: processCommon{
containerID: containerID,
friendlyName: processFriendlyName,
client: clnt,
systemPid: pid,
},
commandLine: createProcessParms.CommandLine,
}
// Make sure the lock is not held while calling back into the daemon
clnt.unlock(containerID)
// Tell the engine to attach streams back to the client
if err := clnt.backend.AttachStreams(processFriendlyName, *iopipe); err != nil {
return err
}
// Lock again so that the defer unlock doesn't fail. (I really don't like this code)
clnt.lock(containerID)
// Spin up a go routine waiting for exit to handle cleanup
go container.waitExit(pid, processFriendlyName, false)
return nil
}
示例3: Run
//.........這裏部分代碼省略.........
}
// Start the container
logrus.Debugln("Starting container ", c.ID)
err = hcsshim.StartComputeSystem(c.ID)
if err != nil {
logrus.Errorf("Failed to start compute system: %s", err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
defer func() {
// Stop the container
if forceKill {
logrus.Debugf("Forcibly terminating container %s", c.ID)
if errno, err := hcsshim.TerminateComputeSystem(c.ID, hcsshim.TimeoutInfinite, "exec-run-defer"); err != nil {
logrus.Warnf("Ignoring error from TerminateComputeSystem 0x%X %s", errno, err)
}
} else {
logrus.Debugf("Shutting down container %s", c.ID)
if errno, err := hcsshim.ShutdownComputeSystem(c.ID, hcsshim.TimeoutInfinite, "exec-run-defer"); err != nil {
if errno != hcsshim.Win32SystemShutdownIsInProgress &&
errno != hcsshim.Win32SpecifiedPathInvalid &&
errno != hcsshim.Win32SystemCannotFindThePathSpecified {
logrus.Warnf("Ignoring error from ShutdownComputeSystem 0x%X %s", errno, err)
}
}
}
}()
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: c.ProcessConfig.Tty,
WorkingDirectory: c.WorkingDir,
ConsoleSize: c.ProcessConfig.ConsoleSize,
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(c.ProcessConfig.Env)
createProcessParms.CommandLine, err = createCommandLine(&c.ProcessConfig, c.ArgsEscaped)
if err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
// Start the command running in the container.
pid, stdin, stdout, stderr, _, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !c.ProcessConfig.Tty, createProcessParms)
if err != nil {
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
// Now that the process has been launched, begin copying data to and from
// the named pipes for the std handles.
setupPipes(stdin, stdout, stderr, pipes)
//Save the PID as we'll need this in Kill()
logrus.Debugf("PID %d", pid)
c.ContainerPid = int(pid)
if c.ProcessConfig.Tty {
term = NewTtyConsole(c.ID, pid)
} else {
term = NewStdConsole()
}
c.ProcessConfig.Terminal = term
// Maintain our list of active containers. We'll need this later for exec
// and other commands.
d.Lock()
d.activeContainers[c.ID] = &activeContainer{
command: c,
}
d.Unlock()
if hooks.Start != nil {
// A closed channel for OOM is returned here as it will be
// non-blocking and return the correct result when read.
chOOM := make(chan struct{})
close(chOOM)
hooks.Start(&c.ProcessConfig, int(pid), chOOM)
}
var (
exitCode int32
errno uint32
)
exitCode, errno, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid, hcsshim.TimeoutInfinite)
if err != nil {
if errno != hcsshim.Win32PipeHasBeenEnded {
logrus.Warnf("WaitForProcessInComputeSystem failed (container may have been killed): %s", err)
}
// Do NOT return err here as the container would have
// started, otherwise docker will deadlock. It's perfectly legitimate
// for WaitForProcessInComputeSystem to fail in situations such
// as the container being killed on another thread.
return execdriver.ExitStatus{ExitCode: hcsshim.WaitErrExecFailed}, nil
}
logrus.Debugf("Exiting Run() exitCode %d id=%s", exitCode, c.ID)
return execdriver.ExitStatus{ExitCode: int(exitCode)}, nil
}
示例4: Exec
// Exec implements the exec driver Driver interface.
func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
var (
term execdriver.Terminal
err error
exitCode int32
errno uint32
)
active := d.activeContainers[c.ID]
if active == nil {
return -1, fmt.Errorf("Exec - No active container exists with ID %s", c.ID)
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: processConfig.Tty, // Note NOT c.ProcessConfig.Tty
WorkingDirectory: c.WorkingDir,
}
// Configure the environment for the process // Note NOT c.ProcessConfig.Env
createProcessParms.Environment = setupEnvironmentVariables(processConfig.Env)
// Create the commandline for the process // Note NOT c.ProcessConfig
createProcessParms.CommandLine, err = createCommandLine(processConfig, false)
if err != nil {
return -1, err
}
// Start the command running in the container.
pid, stdin, stdout, stderr, rc, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms)
if err != nil {
// TODO Windows: TP4 Workaround. In Hyper-V containers, there is a limitation
// of one exec per container. This should be fixed post TP4. CreateProcessInComputeSystem
// will return a specific error which we handle here to give a good error message
// back to the user instead of an inactionable "An invalid argument was supplied"
if rc == hcsshim.Win32InvalidArgument {
return -1, fmt.Errorf("The limit of docker execs per Hyper-V container has been exceeded")
}
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
return -1, err
}
// Now that the process has been launched, begin copying data to and from
// the named pipes for the std handles.
setupPipes(stdin, stdout, stderr, pipes)
// Note NOT c.ProcessConfig.Tty
if processConfig.Tty {
term = NewTtyConsole(c.ID, pid)
} else {
term = NewStdConsole()
}
processConfig.Terminal = term
// Invoke the start callback
if hooks.Start != nil {
// A closed channel for OOM is returned here as it will be
// non-blocking and return the correct result when read.
chOOM := make(chan struct{})
close(chOOM)
hooks.Start(&c.ProcessConfig, int(pid), chOOM)
}
if exitCode, errno, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid, hcsshim.TimeoutInfinite); err != nil {
if errno == hcsshim.Win32PipeHasBeenEnded {
logrus.Debugf("Exiting Run() after WaitForProcessInComputeSystem failed with recognised error 0x%X", errno)
return hcsshim.WaitErrExecFailed, nil
}
logrus.Warnf("WaitForProcessInComputeSystem failed (container may have been killed): 0x%X %s", errno, err)
return -1, err
}
logrus.Debugln("Exiting Run()", c.ID)
return int(exitCode), nil
}
示例5: Exec
func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
var (
inListen, outListen, errListen *npipe.PipeListener
term execdriver.Terminal
err error
randomID string = stringid.GenerateNonCryptoID()
serverPipeFormat, clientPipeFormat string
pid uint32
exitCode int32
)
active := d.activeContainers[c.ID]
if active == nil {
return -1, fmt.Errorf("Exec - No active container exists with ID %s", c.ID)
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: processConfig.Tty, // Note NOT c.ProcessConfig.Tty
WorkingDirectory: c.WorkingDir,
}
// Configure the environment for the process // Note NOT c.ProcessConfig.Tty
createProcessParms.Environment = setupEnvironmentVariables(processConfig.Env)
// We use another unique ID here for each exec instance otherwise it
// may conflict with the pipe name being used by RUN.
// We use a different pipe name between real and dummy mode in the HCS
if dummyMode {
clientPipeFormat = `\\.\pipe\docker-exec-%[1]s-%[2]s-%[3]s`
serverPipeFormat = clientPipeFormat
} else {
clientPipeFormat = `\\.\pipe\docker-exec-%[2]s-%[3]s`
serverPipeFormat = `\\.\Containers\%[1]s\Device\NamedPipe\docker-exec-%[2]s-%[3]s`
}
// Connect stdin
if pipes.Stdin != nil {
stdInPipe := fmt.Sprintf(serverPipeFormat, c.ID, randomID, "stdin")
createProcessParms.StdInPipe = fmt.Sprintf(clientPipeFormat, c.ID, randomID, "stdin")
// Listen on the named pipe
inListen, err = npipe.Listen(stdInPipe)
if err != nil {
logrus.Errorf("stdin failed to listen on %s %s ", stdInPipe, err)
return -1, err
}
defer inListen.Close()
// Launch a goroutine to do the accept. We do this so that we can
// cause an otherwise blocking goroutine to gracefully close when
// the caller (us) closes the listener
go stdinAccept(inListen, stdInPipe, pipes.Stdin)
}
// Connect stdout
stdOutPipe := fmt.Sprintf(serverPipeFormat, c.ID, randomID, "stdout")
createProcessParms.StdOutPipe = fmt.Sprintf(clientPipeFormat, c.ID, randomID, "stdout")
outListen, err = npipe.Listen(stdOutPipe)
if err != nil {
logrus.Errorf("stdout failed to listen on %s %s", stdOutPipe, err)
return -1, err
}
defer outListen.Close()
go stdouterrAccept(outListen, stdOutPipe, pipes.Stdout)
// No stderr on TTY. Note NOT c.ProcessConfig.Tty
if !processConfig.Tty {
// Connect stderr
stdErrPipe := fmt.Sprintf(serverPipeFormat, c.ID, randomID, "stderr")
createProcessParms.StdErrPipe = fmt.Sprintf(clientPipeFormat, c.ID, randomID, "stderr")
errListen, err = npipe.Listen(stdErrPipe)
if err != nil {
logrus.Errorf("Stderr failed to listen on %s %s", stdErrPipe, err)
return -1, err
}
defer errListen.Close()
go stdouterrAccept(errListen, stdErrPipe, pipes.Stderr)
}
// While this should get caught earlier, just in case, validate that we
// have something to run.
if processConfig.Entrypoint == "" {
err = errors.New("No entrypoint specified")
logrus.Error(err)
return -1, err
}
// Build the command line of the process
createProcessParms.CommandLine = processConfig.Entrypoint
for _, arg := range processConfig.Arguments {
logrus.Debugln("appending ", arg)
createProcessParms.CommandLine += " " + arg
}
logrus.Debugln("commandLine: ", createProcessParms.CommandLine)
// Start the command running in the container.
//.........這裏部分代碼省略.........
示例6: Exec
// Exec implements the exec driver Driver interface.
func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
var (
term execdriver.Terminal
err error
exitCode int32
)
active := d.activeContainers[c.ID]
if active == nil {
return -1, fmt.Errorf("Exec - No active container exists with ID %s", c.ID)
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: processConfig.Tty, // Note NOT c.ProcessConfig.Tty
WorkingDirectory: c.WorkingDir,
}
// Configure the environment for the process // Note NOT c.ProcessConfig.Tty
createProcessParms.Environment = setupEnvironmentVariables(processConfig.Env)
// While this should get caught earlier, just in case, validate that we
// have something to run.
if processConfig.Entrypoint == "" {
err = errors.New("No entrypoint specified")
logrus.Error(err)
return -1, err
}
// Build the command line of the process
createProcessParms.CommandLine = processConfig.Entrypoint
for _, arg := range processConfig.Arguments {
logrus.Debugln("appending ", arg)
createProcessParms.CommandLine += " " + arg
}
logrus.Debugln("commandLine: ", createProcessParms.CommandLine)
// Start the command running in the container.
pid, stdin, stdout, stderr, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms)
if err != nil {
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
return -1, err
}
// Now that the process has been launched, begin copying data to and from
// the named pipes for the std handles.
setupPipes(stdin, stdout, stderr, pipes)
// Note NOT c.ProcessConfig.Tty
if processConfig.Tty {
term = NewTtyConsole(c.ID, pid)
} else {
term = NewStdConsole()
}
processConfig.Terminal = term
// Invoke the start callback
if startCallback != nil {
startCallback(&c.ProcessConfig, int(pid))
}
if exitCode, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid); err != nil {
logrus.Errorf("Failed to WaitForProcessInComputeSystem %s", err)
return -1, err
}
// TODO Windows - Do something with this exit code
logrus.Debugln("Exiting Run() with ExitCode 0", c.ID)
return int(exitCode), nil
}
示例7: start
func (ctr *container) start() error {
var err error
// Start the container
logrus.Debugln("Starting container ", ctr.containerID)
if err = hcsshim.StartComputeSystem(ctr.containerID); err != nil {
logrus.Errorf("Failed to start compute system: %s", err)
return err
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: ctr.ociSpec.Process.Terminal,
WorkingDirectory: ctr.ociSpec.Process.Cwd,
ConsoleSize: ctr.ociSpec.Process.InitialConsoleSize,
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(ctr.ociSpec.Process.Env)
createProcessParms.CommandLine = strings.Join(ctr.ociSpec.Process.Args, " ")
iopipe := &IOPipe{Terminal: ctr.ociSpec.Process.Terminal}
// Start the command running in the container. Note we always tell HCS to
// create stdout as it's required regardless of '-i' or '-t' options, so that
// docker can always grab the output through logs. We also tell HCS to always
// create stdin, even if it's not used - it will be closed shortly. Stderr
// is only created if it we're not -t.
var pid uint32
var stdout, stderr io.ReadCloser
pid, iopipe.Stdin, stdout, stderr, err = hcsshim.CreateProcessInComputeSystem(
ctr.containerID,
true,
true,
!ctr.ociSpec.Process.Terminal,
createProcessParms)
if err != nil {
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
// Explicitly terminate the compute system here.
if err2 := hcsshim.TerminateComputeSystem(ctr.containerID, hcsshim.TimeoutInfinite, "CreateProcessInComputeSystem failed"); err2 != nil {
// Ignore this error, there's not a lot we can do except log it
logrus.Warnf("Failed to TerminateComputeSystem after a failed CreateProcessInComputeSystem. Ignoring this.", err2)
} else {
logrus.Debugln("Cleaned up after failed CreateProcessInComputeSystem by calling TerminateComputeSystem")
}
return err
}
// Convert io.ReadClosers to io.Readers
if stdout != nil {
iopipe.Stdout = openReaderFromPipe(stdout)
}
if stderr != nil {
iopipe.Stderr = openReaderFromPipe(stderr)
}
// Save the PID
logrus.Debugf("Process started - PID %d", pid)
ctr.systemPid = uint32(pid)
// Spin up a go routine waiting for exit to handle cleanup
go ctr.waitExit(pid, InitFriendlyName, true)
ctr.client.appendContainer(ctr)
if err := ctr.client.backend.AttachStreams(ctr.containerID, *iopipe); err != nil {
// OK to return the error here, as waitExit will handle tear-down in HCS
return err
}
// Tell the docker engine that the container has started.
si := StateInfo{
State: StateStart,
Pid: ctr.systemPid, // Not sure this is needed? Double-check monitor.go in daemon BUGBUG @jhowardmsft
}
return ctr.client.backend.StateChanged(ctr.containerID, si)
}
示例8: Exec
// Exec implements the exec driver Driver interface.
func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
var (
term execdriver.Terminal
err error
exitCode int32
errno uint32
)
active := d.activeContainers[c.ID]
if active == nil {
return -1, fmt.Errorf("Exec - No active container exists with ID %s", c.ID)
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: processConfig.Tty, // Note NOT c.ProcessConfig.Tty
WorkingDirectory: c.WorkingDir,
}
// Configure the environment for the process // Note NOT c.ProcessConfig.Tty
createProcessParms.Environment = setupEnvironmentVariables(processConfig.Env)
// While this should get caught earlier, just in case, validate that we
// have something to run.
if processConfig.Entrypoint == "" {
err = errors.New("No entrypoint specified")
logrus.Error(err)
return -1, err
}
// Build the command line of the process
createProcessParms.CommandLine = processConfig.Entrypoint
for _, arg := range processConfig.Arguments {
logrus.Debugln("appending ", arg)
createProcessParms.CommandLine += " " + arg
}
logrus.Debugln("commandLine: ", createProcessParms.CommandLine)
// Start the command running in the container.
pid, stdin, stdout, stderr, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms)
if err != nil {
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
return -1, err
}
// Now that the process has been launched, begin copying data to and from
// the named pipes for the std handles.
setupPipes(stdin, stdout, stderr, pipes)
// Note NOT c.ProcessConfig.Tty
if processConfig.Tty {
term = NewTtyConsole(c.ID, pid)
} else {
term = NewStdConsole()
}
processConfig.Terminal = term
// Invoke the start callback
if hooks.Start != nil {
// A closed channel for OOM is returned here as it will be
// non-blocking and return the correct result when read.
chOOM := make(chan struct{})
close(chOOM)
hooks.Start(&c.ProcessConfig, int(pid), chOOM)
}
if exitCode, errno, err = hcsshim.WaitForProcessInComputeSystem(c.ID, pid, hcsshim.TimeoutInfinite); err != nil {
if errno == hcsshim.Win32PipeHasBeenEnded {
logrus.Debugf("Exiting Run() after WaitForProcessInComputeSystem failed with recognised error 0x%X", errno)
return hcsshim.WaitErrExecFailed, nil
}
logrus.Warnf("WaitForProcessInComputeSystem failed (container may have been killed): 0x%X %s", errno, err)
return -1, err
}
logrus.Debugln("Exiting Run()", c.ID)
return int(exitCode), nil
}
示例9: start
func (ctr *container) start() error {
var err error
// Start the container. If this is a servicing container, this call will block
// until the container is done with the servicing execution.
logrus.Debugln("Starting container ", ctr.containerID)
if err = hcsshim.StartComputeSystem(ctr.containerID); err != nil {
logrus.Errorf("Failed to start compute system: %s", err)
return err
}
for _, option := range ctr.options {
if s, ok := option.(*ServicingOption); ok && s.IsServicing {
// Since the servicing operation is complete when StartCommputeSystem returns without error,
// we can shutdown (which triggers merge) and exit early.
const shutdownTimeout = 5 * 60 * 1000 // 4 minutes
const terminateTimeout = 1 * 60 * 1000 // 1 minute
if err := hcsshim.ShutdownComputeSystem(ctr.containerID, shutdownTimeout, ""); err != nil {
logrus.Errorf("Failed during cleanup of servicing container: %s", err)
// Terminate the container, ignoring errors.
if err2 := hcsshim.TerminateComputeSystem(ctr.containerID, terminateTimeout, ""); err2 != nil {
logrus.Errorf("Failed to terminate container %s after shutdown failure: %q", ctr.containerID, err2)
}
return err
}
return nil
}
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: ctr.ociSpec.Process.Terminal,
WorkingDirectory: ctr.ociSpec.Process.Cwd,
ConsoleSize: ctr.ociSpec.Process.InitialConsoleSize,
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(ctr.ociSpec.Process.Env)
createProcessParms.CommandLine = strings.Join(ctr.ociSpec.Process.Args, " ")
iopipe := &IOPipe{Terminal: ctr.ociSpec.Process.Terminal}
// Start the command running in the container. Note we always tell HCS to
// create stdout as it's required regardless of '-i' or '-t' options, so that
// docker can always grab the output through logs. We also tell HCS to always
// create stdin, even if it's not used - it will be closed shortly. Stderr
// is only created if it we're not -t.
var pid uint32
var stdout, stderr io.ReadCloser
pid, iopipe.Stdin, stdout, stderr, err = hcsshim.CreateProcessInComputeSystem(
ctr.containerID,
true,
true,
!ctr.ociSpec.Process.Terminal,
createProcessParms)
if err != nil {
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
// Explicitly terminate the compute system here.
if err2 := hcsshim.TerminateComputeSystem(ctr.containerID, hcsshim.TimeoutInfinite, "CreateProcessInComputeSystem failed"); err2 != nil {
// Ignore this error, there's not a lot we can do except log it
logrus.Warnf("Failed to TerminateComputeSystem after a failed CreateProcessInComputeSystem. Ignoring this.", err2)
} else {
logrus.Debugln("Cleaned up after failed CreateProcessInComputeSystem by calling TerminateComputeSystem")
}
return err
}
ctr.startedAt = time.Now()
// TEMP: Work around Windows BS/DEL behavior.
iopipe.Stdin = fixStdinBackspaceBehavior(iopipe.Stdin, ctr.ociSpec.Process.Terminal)
// Convert io.ReadClosers to io.Readers
if stdout != nil {
iopipe.Stdout = openReaderFromPipe(stdout)
}
if stderr != nil {
iopipe.Stderr = openReaderFromPipe(stderr)
}
// Save the PID
logrus.Debugf("Process started - PID %d", pid)
ctr.systemPid = uint32(pid)
// Spin up a go routine waiting for exit to handle cleanup
go ctr.waitExit(pid, InitFriendlyName, true)
ctr.client.appendContainer(ctr)
if err := ctr.client.backend.AttachStreams(ctr.containerID, *iopipe); err != nil {
// OK to return the error here, as waitExit will handle tear-down in HCS
return err
}
// Tell the docker engine that the container has started.
si := StateInfo{
CommonStateInfo: CommonStateInfo{
State: StateStart,
Pid: ctr.systemPid, // Not sure this is needed? Double-check monitor.go in daemon BUGBUG @jhowardmsft
}}
return ctr.client.backend.StateChanged(ctr.containerID, si)
//.........這裏部分代碼省略.........
示例10: Run
//.........這裏部分代碼省略.........
// Start the container
logrus.Debugln("Starting container ", c.ID)
err = hcsshim.StartComputeSystem(c.ID)
if err != nil {
logrus.Errorf("Failed to start compute system: %s", err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
defer func() {
// Stop the container
if forceKill {
logrus.Debugf("Forcibly terminating container %s", c.ID)
if errno, err := hcsshim.TerminateComputeSystem(c.ID, hcsshim.TimeoutInfinite, "exec-run-defer"); err != nil {
logrus.Warnf("Ignoring error from TerminateComputeSystem 0x%X %s", errno, err)
}
} else {
logrus.Debugf("Shutting down container %s", c.ID)
if errno, err := hcsshim.ShutdownComputeSystem(c.ID, hcsshim.TimeoutInfinite, "exec-run-defer"); err != nil {
if errno != hcsshim.Win32SystemShutdownIsInProgress &&
errno != hcsshim.Win32SpecifiedPathInvalid &&
errno != hcsshim.Win32SystemCannotFindThePathSpecified {
logrus.Warnf("Ignoring error from ShutdownComputeSystem 0x%X %s", errno, err)
}
}
}
}()
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: c.ProcessConfig.Tty,
WorkingDirectory: c.WorkingDir,
ConsoleSize: c.ProcessConfig.ConsoleSize,
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(c.ProcessConfig.Env)
// This should get caught earlier, but just in case - validate that we
// have something to run
if c.ProcessConfig.Entrypoint == "" {
err = errors.New("No entrypoint specified")
logrus.Error(err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
// Build the command line of the process
createProcessParms.CommandLine = c.ProcessConfig.Entrypoint
for _, arg := range c.ProcessConfig.Arguments {
logrus.Debugln("appending ", arg)
createProcessParms.CommandLine += " " + syscall.EscapeArg(arg)
}
logrus.Debugf("CommandLine: %s", createProcessParms.CommandLine)
// Start the command running in the container.
pid, stdin, stdout, stderr, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !c.ProcessConfig.Tty, createProcessParms)
if err != nil {
logrus.Errorf("CreateProcessInComputeSystem() failed %s", err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
// Now that the process has been launched, begin copying data to and from
// the named pipes for the std handles.
setupPipes(stdin, stdout, stderr, pipes)
//Save the PID as we'll need this in Kill()
logrus.Debugf("PID %d", pid)
c.ContainerPid = int(pid)
示例11: Run
//.........這裏部分代碼省略.........
// IMPORTANT: Don't fail if fails to change state. It could already
// have been stopped through kill().
// Otherwise, the docker daemon will hang in job wait()
logrus.Warnf("Ignoring error from TerminateComputeSystem %s", err)
}
} else {
logrus.Debugf("Shutting down container %s", c.ID)
if err := hcsshim.ShutdownComputeSystem(c.ID); err != nil {
// IMPORTANT: Don't fail if fails to change state. It could already
// have been stopped through kill().
// Otherwise, the docker daemon will hang in job wait()
logrus.Warnf("Ignoring error from ShutdownComputeSystem %s", err)
}
}
}()
// We use a different pipe name between real and dummy mode in the HCS
var serverPipeFormat, clientPipeFormat string
if dummyMode {
clientPipeFormat = `\\.\pipe\docker-run-%[1]s-%[2]s`
serverPipeFormat = clientPipeFormat
} else {
clientPipeFormat = `\\.\pipe\docker-run-%[2]s`
serverPipeFormat = `\\.\Containers\%[1]s\Device\NamedPipe\docker-run-%[2]s`
}
createProcessParms := hcsshim.CreateProcessParams{
EmulateConsole: c.ProcessConfig.Tty,
WorkingDirectory: c.WorkingDir,
ConsoleSize: c.ProcessConfig.ConsoleSize,
}
// Configure the environment for the process
createProcessParms.Environment = setupEnvironmentVariables(c.ProcessConfig.Env)
// Connect stdin
if pipes.Stdin != nil {
stdInPipe := fmt.Sprintf(serverPipeFormat, c.ID, "stdin")
createProcessParms.StdInPipe = fmt.Sprintf(clientPipeFormat, c.ID, "stdin")
// Listen on the named pipe
inListen, err = npipe.Listen(stdInPipe)
if err != nil {
logrus.Errorf("stdin failed to listen on %s err=%s", stdInPipe, err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
defer inListen.Close()
// Launch a goroutine to do the accept. We do this so that we can
// cause an otherwise blocking goroutine to gracefully close when
// the caller (us) closes the listener
go stdinAccept(inListen, stdInPipe, pipes.Stdin)
}
// Connect stdout
stdOutPipe := fmt.Sprintf(serverPipeFormat, c.ID, "stdout")
createProcessParms.StdOutPipe = fmt.Sprintf(clientPipeFormat, c.ID, "stdout")
outListen, err = npipe.Listen(stdOutPipe)
if err != nil {
logrus.Errorf("stdout failed to listen on %s err=%s", stdOutPipe, err)
return execdriver.ExitStatus{ExitCode: -1}, err
}
defer outListen.Close()
go stdouterrAccept(outListen, stdOutPipe, pipes.Stdout)