YARN-9486. Docker container exited with failure does not get clean up correctly. Contributed by Eric Yang

This commit is contained in:
Eric Badger 2019-04-26 01:21:28 +00:00
parent b5dcf64f97
commit 79d3d35398
3 changed files with 25 additions and 3 deletions

View File

@ -95,8 +95,10 @@ public void run() {
+ " killed in store", e); + " killed in store", e);
} }
// launch flag will be set to true if process already launched // launch flag will be set to true if process already launched,
boolean alreadyLaunched = !launch.markLaunched(); // in process of launching, or failed to launch.
boolean alreadyLaunched = !launch.markLaunched() ||
launch.isLaunchCompleted();
if (!alreadyLaunched) { if (!alreadyLaunched) {
LOG.info("Container " + containerIdStr + " not launched." LOG.info("Container " + containerIdStr + " not launched."
+ " No cleanup needed to be done"); + " No cleanup needed to be done");

View File

@ -87,7 +87,14 @@ public Integer call() {
Path nmPrivateTruststorePath = (container.getCredentials().getSecretKey( Path nmPrivateTruststorePath = (container.getCredentials().getSecretKey(
AMSecretKeys.YARN_APPLICATION_AM_TRUSTSTORE) == null) ? null : AMSecretKeys.YARN_APPLICATION_AM_TRUSTSTORE) == null) ? null :
getNmPrivateTruststorePath(appIdStr, containerIdStr); getNmPrivateTruststorePath(appIdStr, containerIdStr);
try {
// try to locate existing pid file.
pidFilePath = getPidFilePath(appIdStr, containerIdStr); pidFilePath = getPidFilePath(appIdStr, containerIdStr);
} catch (IOException e) {
// reset pid file path if it did not exist.
String pidFileSubpath = getPidFileSubpath(appIdStr, containerIdStr);
pidFilePath = dirsHandler.getLocalPathForWrite(pidFileSubpath);
}
LOG.info("Relaunch container with " LOG.info("Relaunch container with "
+ "workDir = " + containerWorkDir.toString() + "workDir = " + containerWorkDir.toString()

View File

@ -79,6 +79,7 @@ public void setup() throws Exception {
launch = mock(ContainerLaunch.class); launch = mock(ContainerLaunch.class);
launch.containerAlreadyLaunched = new AtomicBoolean(false); launch.containerAlreadyLaunched = new AtomicBoolean(false);
launch.completed = new AtomicBoolean(false);
launch.pidFilePath = new Path("target/" + containerId.toString() + ".pid"); launch.pidFilePath = new Path("target/" + containerId.toString() + ".pid");
when(launch.getContainerPid()).thenReturn(containerId.toString()); when(launch.getContainerPid()).thenReturn(containerId.toString());
@ -105,4 +106,16 @@ public void testCleanup() throws Exception {
Assert.assertEquals("signal", ContainerExecutor.Signal.TERM, Assert.assertEquals("signal", ContainerExecutor.Signal.TERM,
captor.getValue().getSignal()); captor.getValue().getSignal());
} }
@Test
public void testFailedExitCleanup() throws Exception {
launch.completed.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());
}
} }