diff options
author | Harald Musum <musum@yahooinc.com> | 2023-07-12 17:22:47 +0200 |
---|---|---|
committer | Harald Musum <musum@yahooinc.com> | 2023-07-12 17:22:47 +0200 |
commit | 026ed49604b37573e3dc32eefee7a95b50ac9907 (patch) | |
tree | cfb628936001f25ef7b37392ad2bf9bea4ea6ab7 | |
parent | f14f7e7e5b322214cb5d58abbfd0453af5113df0 (diff) |
Add ConfigDumper
4 files changed, 77 insertions, 5 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducers.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducers.java index bf39d9d3e88..d51b7063ece 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducers.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducers.java @@ -50,7 +50,8 @@ class ArtifactProducers { new JvmDumper.Jstack(), new PmapReporter(), new VespaLogDumper(sleeper), - new ZooKeeperSnapshotDumper()); + new ZooKeeperSnapshotDumper(), + new ConfigDumper()); var aliases = Map.of( "jvm-dump", diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ConfigDumper.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ConfigDumper.java new file mode 100644 index 00000000000..6dfdcc82170 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ConfigDumper.java @@ -0,0 +1,35 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.node.admin.maintenance.servicedump; + +import com.yahoo.vespa.hosted.node.admin.task.util.fs.ContainerPath; + +import java.util.List; + +import static com.yahoo.vespa.hosted.node.admin.maintenance.servicedump.Artifact.Classification.CONFIDENTIAL; +import static com.yahoo.vespa.hosted.node.admin.maintenance.servicedump.Artifact.Classification.INTERNAL; + +/** + * Performs dump of config on a node. + * + * @author hmusum + */ +class ConfigDumper implements ArtifactProducer { + @Override public String artifactName() { return "config-dump"; } + @Override public String description() { return "Dumps config"; } + + @Override + public List<Artifact> produceArtifacts(Context ctx) { + ContainerPath dir = ctx.outputContainerPath().resolve("config"); + ContainerPath configDump = ctx.outputContainerPath().resolve("config-dump.tar.zst"); + List<String> cmd = List.of("bash", "-c", + String.format("mkdir -p %s; /opt/vespa/bin/vespa-configproxy-cmd -m dumpcache %s; tar cvf %s.tar %s; zstd %s.tar -o %s", + dir.pathInContainer(), + dir.pathInContainer(), + dir.pathInContainer(), + dir.pathInContainer(), + dir.pathInContainer(), + configDump.pathInContainer())); + ctx.executeCommandInNode(cmd, true); + return List.of(Artifact.newBuilder().classification(INTERNAL).file(configDump).build()); + } +} diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducersTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducersTest.java index fc1bc41a06b..b6d572c8903 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducersTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/ArtifactProducersTest.java @@ -21,7 +21,7 @@ class ArtifactProducersTest { IllegalArgumentException.class, () -> instance.resolve(List.of("unknown-artifact"))); String expectedMsg = "Invalid artifact type 'unknown-artifact'. Valid types are " + - "['jvm-heap-dump', 'jvm-jfr', 'jvm-jmap', 'jvm-jstack', 'jvm-jstat', 'perf-report', 'pmap', " + + "['config-dump', 'jvm-heap-dump', 'jvm-jfr', 'jvm-jmap', 'jvm-jstack', 'jvm-jstat', 'perf-report', 'pmap', " + "'vespa-log', 'zookeeper-snapshot'] " + "and valid aliases are " + "['jvm-dump': ['jvm-heap-dump', 'jvm-jmap', 'jvm-jstack', 'jvm-jstat', 'vespa-log']]"; diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java index 30f5d09303d..b0988bbf53e 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/servicedump/VespaServiceDumperImplTest.java @@ -145,9 +145,7 @@ class VespaServiceDumperImplTest { // Setup mocks ContainerOperations operations = mock(ContainerOperations.class); when(operations.executeCommandInContainer(any(), any(), any())) - .thenReturn(new CommandResult(null, 0, "12345")) - .thenReturn(new CommandResult(null, 0, "")) - .thenReturn(new CommandResult(null, 0, "")); + .thenReturn(new CommandResult(null, 0, "12345")); SyncClient syncClient = createSyncClientMock(); NodeRepoMock nodeRepository = new NodeRepoMock(); TestTimer timer = new TestTimer(Instant.ofEpochMilli(1600001000000L)); @@ -178,6 +176,44 @@ class VespaServiceDumperImplTest { } @Test + void invokes_config_proxy_command_whn_invoking_config_dump() { + // Setup mocks + ContainerOperations operations = mock(ContainerOperations.class); + when(operations.executeCommandInContainer(any(), any(), any())) + .thenReturn(new CommandResult(null, 0, "12345")); + SyncClient syncClient = createSyncClientMock(); + NodeRepoMock nodeRepository = new NodeRepoMock(); + TestTimer timer = new TestTimer(Instant.ofEpochMilli(1600001000000L)); + NodeSpec nodeSpec = createNodeSpecWithDumpRequest(nodeRepository, List.of("config-dump")); + + VespaServiceDumper reporter = new VespaServiceDumperImpl( + ArtifactProducers.createDefault(Sleeper.NOOP), operations, syncClient, nodeRepository, timer); + NodeAgentContextImpl context = NodeAgentContextImpl.builder(nodeSpec) + .fileSystem(fileSystem) + .build(); + reporter.processServiceDumpRequest(context); + + verify(operations).executeCommandInContainer( + context, + context.users().vespa(), + "bash", + "-c", + "mkdir -p /opt/vespa/var/tmp/vespa-service-dump-1600000000000/config;" + + " /opt/vespa/bin/vespa-configproxy-cmd -m dumpcache /opt/vespa/var/tmp/vespa-service-dump-1600000000000/config;" + + " tar cvf /opt/vespa/var/tmp/vespa-service-dump-1600000000000/config.tar /opt/vespa/var/tmp/vespa-service-dump-1600000000000/config;" + + " zstd /opt/vespa/var/tmp/vespa-service-dump-1600000000000/config.tar -o /opt/vespa/var/tmp/vespa-service-dump-1600000000000/config-dump.tar.zst"); + + String expectedJson = "{\"createdMillis\":1600000000000,\"startedAt\":1600001000000,\"completedAt\":1600001000000," + + "\"location\":\"s3://uri-1/tenant1/service-dump/default-container-1-1600000000000/\"," + + "\"configId\":\"default/container.1\",\"artifacts\":[\"config-dump\"],\"dumpOptions\":{}}"; + assertReportEquals(nodeRepository, expectedJson); + + List<URI> expectedUris = List.of( + URI.create("s3://uri-1/tenant1/service-dump/default-container-1-1600000000000/config-dump.tar.zst")); + assertSyncedFiles(context, syncClient, expectedUris); + } + + @Test void handles_multiple_artifact_types() { // Setup mocks ContainerOperations operations = mock(ContainerOperations.class); |