Make cbuildbot --buildbot enforce cleanup despite SIGKILL.

BUG=chromium-os:5409
TEST=cbuildbot x86-generic-full --buildbot --buildbroot wherever
     # Wait a bit, then hit it with a sigkill.  Verify it shuts down
     # quickly/cleanly.
Change-Id: I1b958a09a1a7b9a770e0ee7a04426634eab999d5
Reviewed-on: https://gerrit.chromium.org/gerrit/17301
Commit-Ready: Brian Harring <ferringb@chromium.org>
Reviewed-by: Brian Harring <ferringb@chromium.org>
Tested-by: Brian Harring <ferringb@chromium.org>
diff --git a/scripts/cbuildbot.py b/scripts/cbuildbot.py
index 074d832..2778423 100644
--- a/scripts/cbuildbot.py
+++ b/scripts/cbuildbot.py
@@ -31,6 +31,7 @@
 from chromite.buildbot import tee
 
 from chromite.lib import cgroups
+from chromite.lib import cleanup
 from chromite.lib import cros_build_lib as cros_lib
 from chromite.lib import sudo
 
@@ -944,11 +945,20 @@
                  'rather than the root of it.  This is not supported.'
                  % options.buildroot)
 
-  with sudo.SudoKeepAlive():
-    with cros_lib.AllowDisabling(options.cgroups,
-                                 cgroups.ContainChildren, 'cbuildbot'):
-      with cros_lib.AllowDisabling(options.timeout > 0,
-                                   cros_lib.Timeout, options.timeout):
-        if not options.buildbot:
-          build_config = cbuildbot_config.OverrideConfigForTrybot(build_config)
-        _RunBuildStagesWrapper(options, build_config)
+  with cleanup.EnforcedCleanupSection() as critical_section:
+    with sudo.SudoKeepAlive():
+      with cros_lib.AllowDisabling(options.cgroups,
+                                   cgroups.ContainChildren, 'cbuildbot'):
+        # Mark everything between EnforcedCleanupSection and here as having to
+        # be rolled back via the contextmanager cleanup handlers.  This ensures
+        # that sudo bits cannot outlive cbuildbot, that anything cgroups
+        # would kill gets killed, etc.
+        critical_section.ForkWatchdog()
+
+        with cros_lib.AllowDisabling(options.timeout > 0,
+                                     cros_lib.Timeout, options.timeout):
+          if not options.buildbot:
+            build_config = cbuildbot_config.OverrideConfigForTrybot(
+                build_config)
+
+          _RunBuildStagesWrapper(options, build_config)