diff options
author | Valerij Fredriksen <valerijf@oath.com> | 2018-09-11 17:29:11 +0200 |
---|---|---|
committer | Valerij Fredriksen <valerijf@oath.com> | 2018-09-11 17:29:11 +0200 |
commit | 84faad39527a879badc71c74377257869676b0c4 (patch) | |
tree | ec960a9406e05c11b580d9d55fcb4d2f094928e0 /node-admin | |
parent | 24906dc9b8ecf0c1e4bd2da3cee1d63b1f5a6210 (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.java | 34 | ||||
-rw-r--r-- | node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTest.java | 48 |
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")); |