use of com.yahoo.vespa.hosted.dockerapi.ContainerName in project vespa by vespa-engine.
the class NodeAgentImpl method restartServices.
private void restartServices(ContainerNodeSpec nodeSpec, Container existingContainer) {
if (existingContainer.state.isRunning() && nodeSpec.nodeState == Node.State.active) {
ContainerName containerName = existingContainer.name;
logger.info("Restarting services for " + containerName);
// Since we are restarting the services we need to suspend the node.
orchestratorSuspendNode();
dockerOperations.restartVespaOnNode(containerName);
}
}
use of com.yahoo.vespa.hosted.dockerapi.ContainerName in project vespa by vespa-engine.
the class StorageMaintainerTest method testMaintenanceThrottlingAfterFailedMaintenance.
@Test
public void testMaintenanceThrottlingAfterFailedMaintenance() {
String hostname = "node-123.us-north-3.test.yahoo.com";
ContainerName containerName = ContainerName.fromHostname(hostname);
try {
when(processExecuter.exec(any(String[].class))).thenThrow(new RuntimeException("Something went wrong")).thenReturn(new Pair<>(0, ""));
} catch (IOException ignored) {
}
try {
storageMaintainer.removeOldFilesFromNode(containerName);
fail("Maintenance job should've failed!");
} catch (RuntimeException ignored) {
}
verifyProcessExecuterCalled(1);
// Maintenance job failed, we should be able to immediately re-run it
storageMaintainer.removeOldFilesFromNode(containerName);
verifyProcessExecuterCalled(2);
}
use of com.yahoo.vespa.hosted.dockerapi.ContainerName in project vespa by vespa-engine.
the class StorageMaintainerTest method testMaintenanceThrottlingAfterSuccessfulMaintenance.
@Test
public void testMaintenanceThrottlingAfterSuccessfulMaintenance() {
String hostname = "node-123.us-north-3.test.yahoo.com";
ContainerName containerName = ContainerName.fromHostname(hostname);
ContainerNodeSpec nodeSpec = new ContainerNodeSpec.Builder().hostname(hostname).nodeState(Node.State.ready).nodeType("tenants").nodeFlavor("docker").minCpuCores(1).minMainMemoryAvailableGb(1).minDiskAvailableGb(1).build();
try {
when(processExecuter.exec(any(String[].class))).thenReturn(new Pair<>(0, ""));
} catch (IOException ignored) {
}
storageMaintainer.removeOldFilesFromNode(containerName);
verifyProcessExecuterCalled(1);
// Will not actually run maintenance job until an hour passes
storageMaintainer.removeOldFilesFromNode(containerName);
verifyProcessExecuterCalled(1);
// Coredump handler has its own throttler
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, false);
verifyProcessExecuterCalled(2);
clock.advance(Duration.ofMinutes(61));
storageMaintainer.removeOldFilesFromNode(containerName);
verifyProcessExecuterCalled(3);
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, false);
verifyProcessExecuterCalled(4);
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, false);
verifyProcessExecuterCalled(4);
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, true);
verifyProcessExecuterCalled(5);
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, true);
verifyProcessExecuterCalled(6);
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, false);
verifyProcessExecuterCalled(6);
// cleanupNodeStorage is unthrottled and it should reset previous times
storageMaintainer.cleanupNodeStorage(containerName, nodeSpec);
verifyProcessExecuterCalled(7);
storageMaintainer.cleanupNodeStorage(containerName, nodeSpec);
verifyProcessExecuterCalled(8);
storageMaintainer.handleCoreDumpsForContainer(containerName, nodeSpec, false);
verifyProcessExecuterCalled(9);
}
use of com.yahoo.vespa.hosted.dockerapi.ContainerName in project vespa by vespa-engine.
the class NodeAgentImplTest method testGetRelevantMetrics.
@Test
@SuppressWarnings("unchecked")
public void testGetRelevantMetrics() throws Exception {
final ObjectMapper objectMapper = new ObjectMapper();
ClassLoader classLoader = getClass().getClassLoader();
File statsFile = new File(classLoader.getResource("docker.stats.json").getFile());
Map<String, Map<String, Object>> dockerStats = objectMapper.readValue(statsFile, Map.class);
Map<String, Object> networks = dockerStats.get("networks");
Map<String, Object> precpu_stats = dockerStats.get("precpu_stats");
Map<String, Object> cpu_stats = dockerStats.get("cpu_stats");
Map<String, Object> memory_stats = dockerStats.get("memory_stats");
Map<String, Object> blkio_stats = dockerStats.get("blkio_stats");
Docker.ContainerStats stats1 = new ContainerStatsImpl(networks, precpu_stats, memory_stats, blkio_stats);
Docker.ContainerStats stats2 = new ContainerStatsImpl(networks, cpu_stats, memory_stats, blkio_stats);
ContainerNodeSpec.Owner owner = new ContainerNodeSpec.Owner("tester", "testapp", "testinstance");
ContainerNodeSpec.Membership membership = new ContainerNodeSpec.Membership("clustType", "clustId", "grp", 3, false);
final ContainerNodeSpec nodeSpec = nodeSpecBuilder.wantedDockerImage(dockerImage).currentDockerImage(dockerImage).nodeState(Node.State.active).vespaVersion(vespaVersion).owner(owner).membership(membership).minMainMemoryAvailableGb(2).allowedToBeDown(true).build();
NodeAgentImpl nodeAgent = makeNodeAgent(dockerImage, true);
when(nodeRepository.getContainerNodeSpec(eq(hostName))).thenReturn(Optional.of(nodeSpec));
when(storageMaintainer.getDiskUsageFor(eq(containerName))).thenReturn(Optional.of(39625000000L));
when(dockerOperations.getContainerStats(eq(containerName))).thenReturn(Optional.of(stats1)).thenReturn(Optional.of(stats2));
when(pathResolver.getApplicationStoragePathForHost()).thenReturn(Files.createTempDirectory("bar"));
// Run the converge loop once to initialize lastNodeSpec
nodeAgent.converge();
// Update metrics once to init and lastCpuMetric
nodeAgent.updateContainerNodeMetrics();
clock.advance(Duration.ofSeconds(1234));
Path pathToExpectedMetrics = Paths.get(classLoader.getResource("expected.container.system.metrics.txt").getPath());
String expectedMetrics = new String(Files.readAllBytes(pathToExpectedMetrics)).replaceAll("\\s", "").replaceAll("\\n", "");
String[] expectedCommand = { "vespa-rpc-invoke", "-t", "2", "tcp/localhost:19091", "setExtraMetrics", expectedMetrics };
doAnswer(invocation -> {
ContainerName calledContainerName = (ContainerName) invocation.getArguments()[0];
long calledTimeout = (long) invocation.getArguments()[1];
String[] calledCommand = new String[invocation.getArguments().length - 2];
System.arraycopy(invocation.getArguments(), 2, calledCommand, 0, calledCommand.length);
calledCommand[calledCommand.length - 1] = calledCommand[calledCommand.length - 1].replaceAll("\"timestamp\":\\d+", "\"timestamp\":0");
assertEquals(containerName, calledContainerName);
assertEquals(5L, calledTimeout);
assertArrayEquals(expectedCommand, calledCommand);
return null;
}).when(dockerOperations).executeCommandInContainerAsRoot(any(), any(), anyVararg());
nodeAgent.updateContainerNodeMetrics();
}
use of com.yahoo.vespa.hosted.dockerapi.ContainerName in project vespa by vespa-engine.
the class MultiDockerTest method test.
@Test
public void test() throws InterruptedException {
try (DockerTester dockerTester = new DockerTester()) {
addAndWaitForNode(dockerTester, "host1.test.yahoo.com", new DockerImage("image1"));
ContainerNodeSpec containerNodeSpec2 = addAndWaitForNode(dockerTester, "host2.test.yahoo.com", new DockerImage("image2"));
dockerTester.addContainerNodeSpec(new ContainerNodeSpec.Builder(containerNodeSpec2).nodeState(Node.State.dirty).minCpuCores(1).minMainMemoryAvailableGb(1).minDiskAvailableGb(1).build());
// Wait until it is marked ready
while (dockerTester.nodeRepositoryMock.getContainerNodeSpec(containerNodeSpec2.hostname).filter(nodeSpec -> nodeSpec.nodeState != Node.State.ready).isPresent()) {
Thread.sleep(10);
}
addAndWaitForNode(dockerTester, "host3.test.yahoo.com", new DockerImage("image1"));
dockerTester.callOrderVerifier.assertInOrder("createContainerCommand with DockerImage { imageId=image1 }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerTester.NODE_PROGRAM + ", resume]", "createContainerCommand with DockerImage { imageId=image2 }, HostName: host2.test.yahoo.com, ContainerName { name=host2 }", "executeInContainerAsRoot with ContainerName { name=host2 }, args: [" + DockerTester.NODE_PROGRAM + ", resume]", "stopContainer with ContainerName { name=host2 }", "deleteContainer with ContainerName { name=host2 }", "createContainerCommand with DockerImage { imageId=image1 }, HostName: host3.test.yahoo.com, ContainerName { name=host3 }", "executeInContainerAsRoot with ContainerName { name=host3 }, args: [" + DockerTester.NODE_PROGRAM + ", resume]");
dockerTester.callOrderVerifier.assertInOrderWithAssertMessage("Maintainer did not receive call to delete application storage", "deleteContainer with ContainerName { name=host2 }", "DeleteContainerStorage with ContainerName { name=host2 }");
dockerTester.callOrderVerifier.assertInOrder("updateNodeAttributes with HostName: host1.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image1, vespaVersion='1.2.3', hardwareDivergence='null'}", "updateNodeAttributes with HostName: host2.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image2, vespaVersion='1.2.3', hardwareDivergence='null'}", "markNodeAvailableForNewAllocation with HostName: host2.test.yahoo.com", "updateNodeAttributes with HostName: host3.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image1, vespaVersion='1.2.3', hardwareDivergence='null'}");
}
}
Aggregations