|
@@ -82,7 +82,7 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
|
|
// | | Isolation=Process | Isolation=Hyper-V |
|
|
// | | Isolation=Process | Isolation=Hyper-V |
|
|
// +-----------------+--------------------------------------------+---------------------------------------------------+
|
|
// +-----------------+--------------------------------------------+---------------------------------------------------+
|
|
// | VolumePath | \\?\\Volume{GUIDa} | |
|
|
// | VolumePath | \\?\\Volume{GUIDa} | |
|
|
-// | LayerFolderPath | %root%\windowsfilter\containerID | %root%\windowsfilter\containerID (servicing only) |
|
|
|
|
|
|
+// | LayerFolderPath | %root%\windowsfilter\containerID | |
|
|
// | Layers[] | ID=GUIDb;Path=%root%\windowsfilter\layerID | ID=GUIDb;Path=%root%\windowsfilter\layerID |
|
|
// | Layers[] | ID=GUIDb;Path=%root%\windowsfilter\layerID | ID=GUIDb;Path=%root%\windowsfilter\layerID |
|
|
// | HvRuntime | | ImagePath=%root%\BaseLayerID\UtilityVM |
|
|
// | HvRuntime | | ImagePath=%root%\BaseLayerID\UtilityVM |
|
|
// +-----------------+--------------------------------------------+---------------------------------------------------+
|
|
// +-----------------+--------------------------------------------+---------------------------------------------------+
|
|
@@ -104,7 +104,6 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
|
|
// "MappedDirectories": [],
|
|
// "MappedDirectories": [],
|
|
// "HvPartition": false,
|
|
// "HvPartition": false,
|
|
// "EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"],
|
|
// "EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"],
|
|
-// "Servicing": false
|
|
|
|
//}
|
|
//}
|
|
//
|
|
//
|
|
// Isolation=Hyper-V example:
|
|
// Isolation=Hyper-V example:
|
|
@@ -126,7 +125,6 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
|
|
// "HvRuntime": {
|
|
// "HvRuntime": {
|
|
// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM"
|
|
// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM"
|
|
// },
|
|
// },
|
|
-// "Servicing": false
|
|
|
|
//}
|
|
//}
|
|
func (c *client) Create(_ context.Context, id string, spec *specs.Spec, runtimeOptions interface{}) error {
|
|
func (c *client) Create(_ context.Context, id string, spec *specs.Spec, runtimeOptions interface{}) error {
|
|
if ctr := c.getContainer(id); ctr != nil {
|
|
if ctr := c.getContainer(id); ctr != nil {
|
|
@@ -155,7 +153,6 @@ func (c *client) createWindows(id string, spec *specs.Spec, runtimeOptions inter
|
|
IgnoreFlushesDuringBoot: spec.Windows.IgnoreFlushesDuringBoot,
|
|
IgnoreFlushesDuringBoot: spec.Windows.IgnoreFlushesDuringBoot,
|
|
HostName: spec.Hostname,
|
|
HostName: spec.Hostname,
|
|
HvPartition: false,
|
|
HvPartition: false,
|
|
- Servicing: spec.Windows.Servicing,
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if spec.Windows.Resources != nil {
|
|
if spec.Windows.Resources != nil {
|
|
@@ -324,9 +321,6 @@ func (c *client) createWindows(id string, spec *specs.Spec, runtimeOptions inter
|
|
waitCh: make(chan struct{}),
|
|
waitCh: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
|
|
- // Start the container. If this is a servicing container, this call
|
|
|
|
- // will block until the container is done with the servicing
|
|
|
|
- // execution.
|
|
|
|
logger.Debug("starting container")
|
|
logger.Debug("starting container")
|
|
if err = hcsContainer.Start(); err != nil {
|
|
if err = hcsContainer.Start(); err != nil {
|
|
c.logger.WithError(err).Error("failed to start container")
|
|
c.logger.WithError(err).Error("failed to start container")
|
|
@@ -525,9 +519,7 @@ func (c *client) createLinux(id string, spec *specs.Spec, runtimeOptions interfa
|
|
waitCh: make(chan struct{}),
|
|
waitCh: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
|
|
- // Start the container. If this is a servicing container, this call
|
|
|
|
- // will block until the container is done with the servicing
|
|
|
|
- // execution.
|
|
|
|
|
|
+ // Start the container.
|
|
logger.Debug("starting container")
|
|
logger.Debug("starting container")
|
|
if err = hcsContainer.Start(); err != nil {
|
|
if err = hcsContainer.Start(); err != nil {
|
|
c.logger.WithError(err).Error("failed to start container")
|
|
c.logger.WithError(err).Error("failed to start container")
|
|
@@ -588,14 +580,14 @@ func (c *client) Start(_ context.Context, id, _ string, withStdin bool, attachSt
|
|
)
|
|
)
|
|
if ctr.ociSpec.Process != nil {
|
|
if ctr.ociSpec.Process != nil {
|
|
emulateConsole = ctr.ociSpec.Process.Terminal
|
|
emulateConsole = ctr.ociSpec.Process.Terminal
|
|
- createStdErrPipe = !ctr.ociSpec.Process.Terminal && !ctr.ociSpec.Windows.Servicing
|
|
|
|
|
|
+ createStdErrPipe = !ctr.ociSpec.Process.Terminal
|
|
}
|
|
}
|
|
|
|
|
|
createProcessParms := &hcsshim.ProcessConfig{
|
|
createProcessParms := &hcsshim.ProcessConfig{
|
|
EmulateConsole: emulateConsole,
|
|
EmulateConsole: emulateConsole,
|
|
WorkingDirectory: ctr.ociSpec.Process.Cwd,
|
|
WorkingDirectory: ctr.ociSpec.Process.Cwd,
|
|
- CreateStdInPipe: !ctr.ociSpec.Windows.Servicing,
|
|
|
|
- CreateStdOutPipe: !ctr.ociSpec.Windows.Servicing,
|
|
|
|
|
|
+ CreateStdInPipe: true,
|
|
|
|
+ CreateStdOutPipe: true,
|
|
CreateStdErrPipe: createStdErrPipe,
|
|
CreateStdErrPipe: createStdErrPipe,
|
|
}
|
|
}
|
|
|
|
|
|
@@ -655,21 +647,6 @@ func (c *client) Start(_ context.Context, id, _ string, withStdin bool, attachSt
|
|
}
|
|
}
|
|
logger.WithField("pid", p.pid).Debug("init process started")
|
|
logger.WithField("pid", p.pid).Debug("init process started")
|
|
|
|
|
|
- // If this is a servicing container, wait on the process synchronously here and
|
|
|
|
- // if it succeeds, wait for it cleanly shutdown and merge into the parent container.
|
|
|
|
- if ctr.ociSpec.Windows.Servicing {
|
|
|
|
- // reapProcess takes the lock
|
|
|
|
- ctr.Unlock()
|
|
|
|
- defer ctr.Lock()
|
|
|
|
- exitCode := c.reapProcess(ctr, p)
|
|
|
|
-
|
|
|
|
- if exitCode != 0 {
|
|
|
|
- return -1, errors.Errorf("libcontainerd: servicing container %s returned non-zero exit code %d", ctr.id, exitCode)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return p.pid, nil
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
dio, err := newIOFromProcess(newProcess, ctr.ociSpec.Process.Terminal)
|
|
dio, err := newIOFromProcess(newProcess, ctr.ociSpec.Process.Terminal)
|
|
if err != nil {
|
|
if err != nil {
|
|
logger.WithError(err).Error("failed to get stdio pipes")
|
|
logger.WithError(err).Error("failed to get stdio pipes")
|
|
@@ -1275,7 +1252,6 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
|
eventErr = fmt.Errorf("hcsProcess.Close() failed %s", err)
|
|
eventErr = fmt.Errorf("hcsProcess.Close() failed %s", err)
|
|
}
|
|
}
|
|
|
|
|
|
- var pendingUpdates bool
|
|
|
|
if p.id == InitProcessName {
|
|
if p.id == InitProcessName {
|
|
// Update container status
|
|
// Update container status
|
|
ctr.Lock()
|
|
ctr.Lock()
|
|
@@ -1285,16 +1261,6 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
|
close(ctr.waitCh)
|
|
close(ctr.waitCh)
|
|
ctr.Unlock()
|
|
ctr.Unlock()
|
|
|
|
|
|
- // Handle any servicing
|
|
|
|
- if exitCode == 0 && ctr.isWindows && !ctr.ociSpec.Windows.Servicing {
|
|
|
|
- pendingUpdates, err = ctr.hcsContainer.HasPendingUpdates()
|
|
|
|
- logger.Infof("Pending updates: %v", pendingUpdates)
|
|
|
|
- if err != nil {
|
|
|
|
- logger.WithError(err).
|
|
|
|
- Warnf("failed to check for pending updates (container may have been killed)")
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if err := c.shutdownContainer(ctr); err != nil {
|
|
if err := c.shutdownContainer(ctr); err != nil {
|
|
exitCode = -1
|
|
exitCode = -1
|
|
logger.WithError(err).Warn("failed to shutdown container")
|
|
logger.WithError(err).Warn("failed to shutdown container")
|
|
@@ -1320,37 +1286,34 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if !(ctr.isWindows && ctr.ociSpec.Windows.Servicing) {
|
|
|
|
- c.eventQ.append(ctr.id, func() {
|
|
|
|
- ei := EventInfo{
|
|
|
|
- ContainerID: ctr.id,
|
|
|
|
- ProcessID: p.id,
|
|
|
|
- Pid: uint32(p.pid),
|
|
|
|
- ExitCode: uint32(exitCode),
|
|
|
|
- ExitedAt: exitedAt,
|
|
|
|
- UpdatePending: pendingUpdates,
|
|
|
|
- Error: eventErr,
|
|
|
|
- }
|
|
|
|
- c.logger.WithFields(logrus.Fields{
|
|
|
|
|
|
+ c.eventQ.append(ctr.id, func() {
|
|
|
|
+ ei := EventInfo{
|
|
|
|
+ ContainerID: ctr.id,
|
|
|
|
+ ProcessID: p.id,
|
|
|
|
+ Pid: uint32(p.pid),
|
|
|
|
+ ExitCode: uint32(exitCode),
|
|
|
|
+ ExitedAt: exitedAt,
|
|
|
|
+ Error: eventErr,
|
|
|
|
+ }
|
|
|
|
+ c.logger.WithFields(logrus.Fields{
|
|
|
|
+ "container": ctr.id,
|
|
|
|
+ "event": EventExit,
|
|
|
|
+ "event-info": ei,
|
|
|
|
+ }).Info("sending event")
|
|
|
|
+ err := c.backend.ProcessEvent(ctr.id, EventExit, ei)
|
|
|
|
+ if err != nil {
|
|
|
|
+ c.logger.WithError(err).WithFields(logrus.Fields{
|
|
"container": ctr.id,
|
|
"container": ctr.id,
|
|
"event": EventExit,
|
|
"event": EventExit,
|
|
"event-info": ei,
|
|
"event-info": ei,
|
|
- }).Info("sending event")
|
|
|
|
- err := c.backend.ProcessEvent(ctr.id, EventExit, ei)
|
|
|
|
- if err != nil {
|
|
|
|
- c.logger.WithError(err).WithFields(logrus.Fields{
|
|
|
|
- "container": ctr.id,
|
|
|
|
- "event": EventExit,
|
|
|
|
- "event-info": ei,
|
|
|
|
- }).Error("failed to process event")
|
|
|
|
- }
|
|
|
|
- if p.id != InitProcessName {
|
|
|
|
- ctr.Lock()
|
|
|
|
- delete(ctr.execs, p.id)
|
|
|
|
- ctr.Unlock()
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ }).Error("failed to process event")
|
|
|
|
+ }
|
|
|
|
+ if p.id != InitProcessName {
|
|
|
|
+ ctr.Lock()
|
|
|
|
+ delete(ctr.execs, p.id)
|
|
|
|
+ ctr.Unlock()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
|
|
return exitCode
|
|
return exitCode
|
|
}
|
|
}
|