ContainerCleanup implements Runnable { @Override public void run() { ContainerId containerId = container.getContainerId(); String containerIdStr = containerId.toString(); LOG.info("Cleaning up container " + containerIdStr); try { context.getNMStateStore().storeContainerKilled(containerId); } catch (IOException e) { LOG.error("Unable to mark container " + containerId + " killed in store", e); } boolean alreadyLaunched = !launch.markLaunched(); if (!alreadyLaunched) { LOG.info("Container " + containerIdStr + " not launched." + " No cleanup needed to be done"); return; } if (LOG.isDebugEnabled()) { LOG.debug("Marking container " + containerIdStr + " as inactive"); } exec.deactivateContainer(containerId); Path pidFilePath = launch.getPidFilePath(); if (LOG.isDebugEnabled()) { LOG.debug("Getting pid for container {} to kill" + " from pid file {}", containerIdStr, pidFilePath != null ? pidFilePath : "null"); } try { String processId = launch.getContainerPid(); String user = container.getUser(); if (processId != null) { signalProcess(processId, user, containerIdStr); } else { if (!launch.isLaunchCompleted()) { LOG.warn("Container clean up before pid file created " + containerIdStr); dispatcher.getEventHandler().handle( new ContainerExitEvent(container.getContainerId(), ContainerEventType.CONTAINER_KILLED_ON_REQUEST, Shell.WINDOWS ? ContainerExecutor.ExitCode.FORCE_KILLED.getExitCode() : ContainerExecutor.ExitCode.TERMINATED.getExitCode(), "Container terminated before pid file created.")); } if (DockerLinuxContainerRuntime.isDockerContainerRequested(conf, container.getLaunchContext().getEnvironment())) { reapDockerContainerNoPid(user); } } } catch (Exception e) { String message = "Exception when trying to cleanup container " + containerIdStr + ": " + StringUtils.stringifyException(e); LOG.warn(message); dispatcher.getEventHandler().handle( new ContainerDiagnosticsUpdateEvent(containerId, message)); } finally { if (pidFilePath != null) { try { FileContext lfs = FileContext.getLocalFSFileContext(); lfs.delete(pidFilePath, false); lfs.delete(pidFilePath.suffix(EXIT_CODE_FILE_SUFFIX), false); } catch (IOException ioe) { LOG.warn("{} exception trying to delete pid file {}. Ignoring.", containerId, pidFilePath, ioe); } } } try { launch.reapContainer(); } catch (IOException ioe) { LOG.warn("{} exception trying to reap container. Ignoring.", containerId, ioe); } } ContainerCleanup(Context context, Configuration configuration,
      Dispatcher dispatcher, ContainerExecutor exec,
      Container container,
      ContainerLaunch containerLaunch); @Override void run();  }
@Test public void testNoCleanupWhenContainerNotLaunched() throws IOException { cleanup.run(); verify(launch, Mockito.times(0)).signalContainer( Mockito.any(SignalContainerCommand.class)); }
@Test public void testCleanup() throws Exception { launch.containerAlreadyLaunched.set(true); cleanup.run(); ArgumentCaptor<ContainerSignalContext> captor = ArgumentCaptor.forClass(ContainerSignalContext.class); verify(executor, Mockito.times(1)).signalContainer(captor.capture()); Assert.assertEquals("signal", ContainerExecutor.Signal.TERM, captor.getValue().getSignal()); }