summaryrefslogtreecommitdiffstats
path: root/node-admin
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@oath.com>2018-09-11 17:29:11 +0200
committerValerij Fredriksen <valerijf@oath.com>2018-09-11 17:29:11 +0200
commit84faad39527a879badc71c74377257869676b0c4 (patch)
treeec960a9406e05c11b580d9d55fcb4d2f094928e0 /node-admin
parent24906dc9b8ecf0c1e4bd2da3cee1d63b1f5a6210 (diff)
Add queryInstalled to Yum
Diffstat (limited to 'node-admin')
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java34
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTest.java48
2 files changed, 80 insertions, 2 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java
index 3a9c49a0f2d..d7a503f5dcd 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java
@@ -3,15 +3,19 @@ package com.yahoo.vespa.hosted.node.admin.task.util.yum;
import com.yahoo.vespa.hosted.node.admin.component.TaskContext;
import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandLine;
+import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandResult;
import com.yahoo.vespa.hosted.node.admin.task.util.process.Terminal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
+import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
/**
* @author hakonhall
@@ -24,17 +28,43 @@ public class Yum {
private static final Pattern INSTALL_NOOP_PATTERN = NOTHING_TO_DO_PATTERN;
private static final Pattern UPGRADE_NOOP_PATTERN = Pattern.compile("(?dm)^No packages marked for update$");
private static final Pattern REMOVE_NOOP_PATTERN = Pattern.compile("(?dm)^No Packages marked for removal$");
-
-
private static final Pattern UNKNOWN_PACKAGE_PATTERN = Pattern.compile(
"(?dm)^No package ([^ ]+) available\\.$");
+
+ // WARNING: These must be in the same order as the supplier below
+ private static final String RPM_QUERYFORMAT = Stream.of("NAME", "EPOCH", "VERSION", "RELEASE", "ARCH")
+ .map(formatter -> "%{" + formatter + "}")
+ .collect(Collectors.joining("\\n"));
+ private static final Function<YumPackageName.Builder, List<Function<String, YumPackageName.Builder>>>
+ PACKAGE_NAME_BUILDERS_GENERATOR = builder -> Arrays.asList(
+ builder::setName, builder::setEpoch, builder::setVersion, builder::setRelease, builder::setArchitecture);
+
+
private final Terminal terminal;
public Yum(Terminal terminal) {
this.terminal = terminal;
}
+ public Optional<YumPackageName> queryInstalled(TaskContext context, String packageName) {
+ CommandResult commandResult = terminal.newCommandLine(context)
+ .add("rpm", "-q", packageName, "--queryformat", RPM_QUERYFORMAT)
+ .ignoreExitCode()
+ .executeSilently();
+
+ if (commandResult.getExitCode() != 0) return Optional.empty();
+
+ YumPackageName.Builder builder = new YumPackageName.Builder();
+ List<Function<String, YumPackageName.Builder>> builders = PACKAGE_NAME_BUILDERS_GENERATOR.apply(builder);
+ List<Optional<String>> lines = commandResult.mapEachLine(line -> Optional.of(line).filter(s -> !"(none)".equals(s)));
+ if (lines.size() != builders.size()) throw new IllegalStateException(String.format(
+ "Unexpected response from rpm, expected %d lines, got %d" + builders.size(), commandResult.getOutput()));
+
+ IntStream.range(0, builders.size()).forEach(i -> lines.get(i).ifPresent(builders.get(i)::apply));
+ return Optional.of(builder.build());
+ }
+
/**
* Lock and install, or if necessary downgrade, a package to a given version.
*
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTest.java
index 2e65c1aae09..c7e2885a907 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTest.java
@@ -7,6 +7,8 @@ import com.yahoo.vespa.hosted.node.admin.task.util.process.TestTerminal;
import org.junit.After;
import org.junit.Test;
+import java.util.Optional;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -26,6 +28,52 @@ public class YumTest {
}
@Test
+ public void testQueryInstalledNevra() {
+ terminal.expectCommand(
+ "rpm -q docker --queryformat \"%{NAME}\\\\n%{EPOCH}\\\\n%{VERSION}\\\\n%{RELEASE}\\\\n%{ARCH}\" 2>&1",
+ 0,
+ "docker\n2\n1.13.1\n74.git6e3bb8e.el7.centos\nx86_64");
+
+ Optional<YumPackageName> installed = yum.queryInstalled(taskContext, "docker");
+
+ assertTrue(installed.isPresent());
+ assertEquals("docker", installed.get().getName());
+ assertEquals("2", installed.get().getEpoch().get());
+ assertEquals("1.13.1", installed.get().getVersion().get());
+ assertEquals("74.git6e3bb8e.el7.centos", installed.get().getRelease().get());
+ assertEquals("x86_64", installed.get().getArchitecture().get());
+ }
+
+ @Test
+ public void testQueryInstalledPartial() {
+ terminal.expectCommand(
+ "rpm -q vespa-node-admin --queryformat \"%{NAME}\\\\n%{EPOCH}\\\\n%{VERSION}\\\\n%{RELEASE}\\\\n%{ARCH}\" 2>&1",
+ 0,
+ "vespa-node-admin\n(none)\n6.283.62\n1.el7\nnoarch");
+
+ Optional<YumPackageName> installed = yum.queryInstalled(taskContext, "vespa-node-admin");
+
+ assertTrue(installed.isPresent());
+ assertEquals("vespa-node-admin", installed.get().getName());
+ assertFalse(installed.get().getEpoch().isPresent());
+ assertEquals("6.283.62", installed.get().getVersion().get());
+ assertEquals("1.el7", installed.get().getRelease().get());
+ assertEquals("noarch", installed.get().getArchitecture().get());
+ }
+
+ @Test
+ public void testQueryNotInstalled() {
+ terminal.expectCommand(
+ "rpm -q fake-package --queryformat \"%{NAME}\\\\n%{EPOCH}\\\\n%{VERSION}\\\\n%{RELEASE}\\\\n%{ARCH}\" 2>&1",
+ 1,
+ "package fake-package is not installed");
+
+ Optional<YumPackageName> installed = yum.queryInstalled(taskContext, "fake-package");
+
+ assertFalse(installed.isPresent());
+ }
+
+ @Test
public void testArrayConversion() {
YumPackageName[] expected = new YumPackageName[] { new YumPackageName.Builder("1").build() };
assertArrayEquals(expected, Yum.toYumPackageNameArray("1"));