瀏覽代碼

Merge pull request #36267 from Microsoft/jjh/removeservicing

Windows: Remove servicing mode
Sebastiaan van Stijn 7 年之前
父節點
當前提交
1346a2c89a

+ 1 - 4
daemon/monitor.go

@@ -111,10 +111,7 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc
 			}
 
 			daemon.setStateCounter(c)
-			if err := c.CheckpointTo(daemon.containersReplica); err != nil {
-				return err
-			}
-			return daemon.postRunProcessing(c, ei)
+			return c.CheckpointTo(daemon.containersReplica)
 		}
 
 		if execConfig := c.ExecCommands.Get(ei.ProcessID); execConfig != nil {

+ 0 - 11
daemon/monitor_linux.go

@@ -1,11 +0,0 @@
-package daemon // import "github.com/docker/docker/daemon"
-
-import (
-	"github.com/docker/docker/container"
-	"github.com/docker/docker/libcontainerd"
-)
-
-// postRunProcessing perfoms any processing needed on the container after it has stopped.
-func (daemon *Daemon) postRunProcessing(_ *container.Container, _ libcontainerd.EventInfo) error {
-	return nil
-}

+ 0 - 53
daemon/monitor_windows.go

@@ -1,53 +0,0 @@
-package daemon // import "github.com/docker/docker/daemon"
-
-import (
-	"context"
-
-	"github.com/docker/docker/container"
-	"github.com/docker/docker/libcontainerd"
-	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
-)
-
-// postRunProcessing starts a servicing container if required
-func (daemon *Daemon) postRunProcessing(c *container.Container, ei libcontainerd.EventInfo) error {
-	if ei.ExitCode == 0 && ei.UpdatePending {
-		spec, err := daemon.createSpec(c)
-		if err != nil {
-			return err
-		}
-		// Turn on servicing
-		spec.Windows.Servicing = true
-
-		copts, err := daemon.getLibcontainerdCreateOptions(c)
-		if err != nil {
-			return err
-		}
-
-		// Create a new servicing container, which will start, complete the
-		// update, and merge back the results if it succeeded, all as part of
-		// the below function call.
-		ctx := context.Background()
-		svcID := c.ID + "_servicing"
-		logger := logrus.WithField("container", svcID)
-		if err := daemon.containerd.Create(ctx, svcID, spec, copts); err != nil {
-			c.SetExitCode(-1)
-			return errors.Wrap(err, "post-run update servicing failed")
-		}
-		_, err = daemon.containerd.Start(ctx, svcID, "", false, nil)
-		if err != nil {
-			logger.WithError(err).Warn("failed to run servicing container")
-			if err := daemon.containerd.Delete(ctx, svcID); err != nil {
-				logger.WithError(err).Warn("failed to delete servicing container")
-			}
-		} else {
-			if _, _, err := daemon.containerd.DeleteTask(ctx, svcID); err != nil {
-				logger.WithError(err).Warn("failed to delete servicing container task")
-			}
-			if err := daemon.containerd.Delete(ctx, svcID); err != nil {
-				logger.WithError(err).Warn("failed to delete servicing container")
-			}
-		}
-	}
-	return nil
-}

+ 0 - 3
daemon/oci_windows.go

@@ -326,9 +326,6 @@ func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.S
 		s.Windows.CredentialSpec = cs
 	}
 
-	// Assume we are not starting a container for a servicing operation
-	s.Windows.Servicing = false
-
 	return nil
 }
 

+ 0 - 29
integration-cli/docker_cli_run_test.go

@@ -4237,35 +4237,6 @@ func (s *DockerSuite) TestRunCredentialSpecWellFormed(c *check.C) {
 	dockerCmd(c, "run", `--security-opt=credentialspec=file://valid.json`, "busybox", "true")
 }
 
-// Windows specific test to ensure that a servicing app container is started
-// if necessary once a container exits. It does this by forcing a no-op
-// servicing event and verifying the event from Hyper-V-Compute
-func (s *DockerSuite) TestRunServicingContainer(c *check.C) {
-	testRequires(c, DaemonIsWindows, SameHostDaemon)
-
-	// This functionality does not exist in post-RS3 builds.
-	// Note we get the version number from the full build string, as Windows
-	// reports Windows 8 version 6.2 build 9200 from non-manifested binaries.
-	// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
-	v, err := kernel.GetKernelVersion()
-	c.Assert(err, checker.IsNil)
-	build, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0])
-	if build > 16299 {
-		c.Skip("Disabled on post-RS3 builds")
-	}
-
-	out := cli.DockerCmd(c, "run", "-d", testEnv.PlatformDefaults.BaseImage, "cmd", "/c", "mkdir c:\\programdata\\Microsoft\\Windows\\ContainerUpdates\\000_000_d99f45d0-ffc8-4af7-bd9c-ea6a62e035c9_200 && sc control cexecsvc 255").Combined()
-	containerID := strings.TrimSpace(out)
-	cli.WaitExited(c, containerID, 60*time.Second)
-
-	result := icmd.RunCommand("powershell", "echo", `(Get-WinEvent -ProviderName "Microsoft-Windows-Hyper-V-Compute" -FilterXPath 'Event[System[EventID=2010]]' -MaxEvents 1).Message`)
-	result.Assert(c, icmd.Success)
-	out2 := result.Combined()
-	c.Assert(out2, checker.Contains, `"Servicing":true`, check.Commentf("Servicing container does not appear to have been started: %s", out2))
-	c.Assert(out2, checker.Contains, `Windows Container (Servicing)`, check.Commentf("Didn't find 'Windows Container (Servicing): %s", out2))
-	c.Assert(out2, checker.Contains, containerID+"_servicing", check.Commentf("Didn't find '%s_servicing': %s", containerID+"_servicing", out2))
-}
-
 func (s *DockerSuite) TestRunDuplicateMount(c *check.C) {
 	testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace)
 

+ 30 - 67
libcontainerd/client_local_windows.go

@@ -82,7 +82,7 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
 // |                 | Isolation=Process                          | Isolation=Hyper-V                                 |
 // +-----------------+--------------------------------------------+---------------------------------------------------+
 // | 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        |
 // | HvRuntime       |                                            | ImagePath=%root%\BaseLayerID\UtilityVM            |
 // +-----------------+--------------------------------------------+---------------------------------------------------+
@@ -104,7 +104,6 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
 //	"MappedDirectories": [],
 //	"HvPartition": false,
 //	"EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"],
-//	"Servicing": false
 //}
 //
 // Isolation=Hyper-V example:
@@ -126,7 +125,6 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
 //	"HvRuntime": {
 //		"ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM"
 //	},
-//	"Servicing": false
 //}
 func (c *client) Create(_ context.Context, id string, spec *specs.Spec, runtimeOptions interface{}) error {
 	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,
 		HostName:                spec.Hostname,
 		HvPartition:             false,
-		Servicing:               spec.Windows.Servicing,
 	}
 
 	if spec.Windows.Resources != nil {
@@ -324,9 +321,6 @@ func (c *client) createWindows(id string, spec *specs.Spec, runtimeOptions inter
 		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")
 	if err = hcsContainer.Start(); err != nil {
 		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{}),
 	}
 
-	// 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")
 	if err = hcsContainer.Start(); err != nil {
 		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 {
 		emulateConsole = ctr.ociSpec.Process.Terminal
-		createStdErrPipe = !ctr.ociSpec.Process.Terminal && !ctr.ociSpec.Windows.Servicing
+		createStdErrPipe = !ctr.ociSpec.Process.Terminal
 	}
 
 	createProcessParms := &hcsshim.ProcessConfig{
 		EmulateConsole:   emulateConsole,
 		WorkingDirectory: ctr.ociSpec.Process.Cwd,
-		CreateStdInPipe:  !ctr.ociSpec.Windows.Servicing,
-		CreateStdOutPipe: !ctr.ociSpec.Windows.Servicing,
+		CreateStdInPipe:  true,
+		CreateStdOutPipe: true,
 		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")
 
-	// 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)
 	if err != nil {
 		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)
 	}
 
-	var pendingUpdates bool
 	if p.id == InitProcessName {
 		// Update container status
 		ctr.Lock()
@@ -1285,16 +1261,6 @@ func (c *client) reapProcess(ctr *container, p *process) int {
 		close(ctr.waitCh)
 		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 {
 			exitCode = -1
 			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,
 				"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,
-					"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
 }

+ 1 - 3
libcontainerd/types.go

@@ -71,9 +71,7 @@ type EventInfo struct {
 	ExitCode    uint32
 	ExitedAt    time.Time
 	OOMKilled   bool
-	// Windows Only field
-	UpdatePending bool
-	Error         error
+	Error       error
 }
 
 // Backend defines callbacks that the client of the library needs to implement.