diff options
author | Harald Musum <musum@verizonmedia.com> | 2020-09-24 12:46:23 +0200 |
---|---|---|
committer | Harald Musum <musum@verizonmedia.com> | 2020-09-24 12:46:23 +0200 |
commit | a4c4d9075fa1a6bd9d23cac3c72ac57071493fcf (patch) | |
tree | 87d90bf1ed95d96992388d27f1b3872261982532 /configserver | |
parent | 6704090650b19fff7f69fa8a997fddad9ca91c3a (diff) |
Store vespa version in ZooKeeper as well
Use version in ZooKeeper if configserver-distribute-application-package is true,
fallback to version in file. Will always write to ZooKeeper so this can be
the only source in the future.
This means that if configserver-distribute-application-package is true
and version data is found in ZooKeeper, redeployment of appplication packages
will only be done on one config server
Diffstat (limited to 'configserver')
3 files changed, 89 insertions, 18 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/version/VersionState.java b/configserver/src/main/java/com/yahoo/vespa/config/server/version/VersionState.java index 641aa31a6b7..a591ca07e5e 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/version/VersionState.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/version/VersionState.java @@ -5,45 +5,78 @@ import com.google.inject.Inject; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.component.Version; import com.yahoo.io.IOUtils; +import com.yahoo.path.Path; +import com.yahoo.text.Utf8; +import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.defaults.Defaults; +import com.yahoo.vespa.flags.BooleanFlag; +import com.yahoo.vespa.flags.FlagSource; +import com.yahoo.vespa.flags.Flags; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Optional; /** - * Contains version information for this configserver. + * + * Contains version information for this configserver. Stored both in file system and in ZooKeeper (uses + * data in ZooKeeper if distributeApplicationPackage and data found in ZooKeeper) * * @author Ulf Lilleengen */ public class VersionState { + static final Path versionPath = Path.fromString("/config/v2/vespa_version"); + private final File versionFile; + private final Curator curator; + private final BooleanFlag distributeApplicationPackage; @Inject - public VersionState(ConfigserverConfig config) { - this(new File(Defaults.getDefaults().underVespaHome(config.configServerDBDir()), "vespa_version")); + public VersionState(ConfigserverConfig config, Curator curator, FlagSource flagsource) { + this(new File(Defaults.getDefaults().underVespaHome(config.configServerDBDir()), "vespa_version"), curator, flagsource); } - public VersionState(File versionFile) { + public VersionState(File versionFile, Curator curator, FlagSource flagSource) { this.versionFile = versionFile; + this.curator = curator; + this.distributeApplicationPackage = Flags.CONFIGSERVER_DISTRIBUTE_APPLICATION_PACKAGE.bindTo(flagSource); } public boolean isUpgraded() { + System.out.println("current version: " + currentVersion() + ", stored version: " + storedVersion()); return currentVersion().compareTo(storedVersion()) > 0; } public void saveNewVersion() { + saveNewVersion(currentVersion().toFullString()); + } + + public void saveNewVersion(String vespaVersion) { + curator.set(versionPath, Utf8.toBytes(vespaVersion)); try (FileWriter writer = new FileWriter(versionFile)) { - writer.write(currentVersion().toFullString()); + writer.write(vespaVersion); } catch (IOException e) { throw new RuntimeException(e); } } public Version storedVersion() { + if (distributeApplicationPackage.value()) { + Optional<byte[]> version = curator.getData(versionPath); + if(version.isPresent()) { + System.out.println("Found version in zk "); + try { + return Version.fromString(Utf8.toString(version.get())); + } catch (Exception e) { + return new Version(0, 0, 0); // Use an old value to signal we don't know + } + } + } try (FileReader reader = new FileReader(versionFile)) { + System.out.println("Found version in file "); return Version.fromString(IOUtils.readAll(reader)); } catch (Exception e) { return new Version(0, 0, 0); // Use an old value to signal we don't know @@ -54,6 +87,10 @@ public class VersionState { return new Version(VespaVersion.major, VespaVersion.minor, VespaVersion.micro); } + File versionFile() { + return versionFile; + } + @Override public String toString() { return String.format("Current version:%s, stored version:%s", currentVersion(), storedVersion()); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java index bda17faec12..d7009c95ee2 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java @@ -25,6 +25,7 @@ import com.yahoo.vespa.config.server.rpc.RpcServer; import com.yahoo.vespa.config.server.version.VersionState; import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.curator.mock.MockCurator; +import com.yahoo.vespa.flags.InMemoryFlagSource; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -56,6 +57,8 @@ import static org.junit.Assert.assertTrue; */ public class ConfigServerBootstrapTest { + private final MockCurator curator = new MockCurator(); + @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -66,8 +69,7 @@ public class ConfigServerBootstrapTest { DeployTester tester = new DeployTester(List.of(createHostedModelFactory()), configserverConfig, provisioner); tester.deployApp("src/test/apps/hosted/"); - File versionFile = temporaryFolder.newFile(); - VersionState versionState = new VersionState(versionFile); + VersionState versionState = createVersionState(); assertTrue(versionState.isUpgraded()); RpcServer rpcServer = createRpcServer(configserverConfig); @@ -99,8 +101,7 @@ public class ConfigServerBootstrapTest { DeployTester tester = new DeployTester(List.of(createHostedModelFactory()), configserverConfig, provisioner); tester.deployApp("src/test/apps/hosted/"); - File versionFile = temporaryFolder.newFile(); - VersionState versionState = new VersionState(versionFile); + VersionState versionState = createVersionState(); assertTrue(versionState.isUpgraded()); RpcServer rpcServer = createRpcServer(configserverConfig); @@ -124,8 +125,7 @@ public class ConfigServerBootstrapTest { DeployTester tester = new DeployTester(List.of(createHostedModelFactory()), configserverConfig); tester.deployApp("src/test/apps/hosted/"); - File versionFile = temporaryFolder.newFile(); - VersionState versionState = new VersionState(versionFile); + VersionState versionState = createVersionState(); assertTrue(versionState.isUpgraded()); // Manipulate application package so that it will fail deployment when config server starts @@ -168,8 +168,7 @@ public class ConfigServerBootstrapTest { tester.deployApp("src/test/apps/app/", vespaVersion, Instant.now()); ApplicationId applicationId = tester.applicationId(); - File versionFile = temporaryFolder.newFile(); - VersionState versionState = new VersionState(versionFile); + VersionState versionState = createVersionState(); assertTrue(versionState.isUpgraded()); // Ugly hack, but I see no other way of doing it: @@ -242,6 +241,10 @@ public class ConfigServerBootstrapTest { stateMonitor); } + private VersionState createVersionState() throws IOException { + return new VersionState(temporaryFolder.newFile(), curator, new InMemoryFlagSource()); + } + public static class MockRpcServer extends com.yahoo.vespa.config.server.rpc.MockRpcServer { volatile boolean isRunning = false; diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/version/VersionStateTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/version/VersionStateTest.java index 8a1a7fbea20..1340935108b 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/version/VersionStateTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/version/VersionStateTest.java @@ -4,12 +4,16 @@ package com.yahoo.vespa.config.server.version; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.component.Version; import com.yahoo.io.IOUtils; +import com.yahoo.vespa.curator.mock.MockCurator; +import com.yahoo.vespa.flags.Flags; +import com.yahoo.vespa.flags.InMemoryFlagSource; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; @@ -20,28 +24,49 @@ import static org.junit.Assert.assertTrue; * @author Ulf Lilleengen */ public class VersionStateTest { + InMemoryFlagSource flagSource = new InMemoryFlagSource(); @Rule public TemporaryFolder tempDir = new TemporaryFolder(); + private final MockCurator curator = new MockCurator(); @Test public void upgrade() throws IOException { + upgrade(true); + upgrade(false); + } + + public void upgrade(boolean distributeApplicationPackage) throws IOException { + flagSource.withBooleanFlag(Flags.CONFIGSERVER_DISTRIBUTE_APPLICATION_PACKAGE.id(), distributeApplicationPackage); Version unknownVersion = new Version(0, 0, 0); - File versionFile = tempDir.newFile(); - VersionState state = new VersionState(versionFile); + + VersionState state = createVersionState(); assertThat(state.storedVersion(), is(unknownVersion)); assertTrue(state.isUpgraded()); state.saveNewVersion(); assertFalse(state.isUpgraded()); - IOUtils.writeFile(versionFile, "badversion", false); + state.saveNewVersion("badversion"); assertThat(state.storedVersion(), is(unknownVersion)); assertTrue(state.isUpgraded()); - IOUtils.writeFile(versionFile, "5.0.0", false); + state.saveNewVersion("5.0.0"); assertThat(state.storedVersion(), is(new Version(5, 0, 0))); assertTrue(state.isUpgraded()); + // Remove zk node, should find version in ZooKeeper + curator.delete(VersionState.versionPath); + assertThat(state.storedVersion(), is(new Version(5, 0, 0))); + assertTrue(state.isUpgraded()); + + // Save new version, remove version in file, should find version in ZooKeeper + state.saveNewVersion("6.0.0"); + if (distributeApplicationPackage) { + Files.delete(state.versionFile().toPath()); + assertThat(state.storedVersion(), is(new Version(6, 0, 0))); + assertTrue(state.isUpgraded()); + } + state.saveNewVersion(); assertThat(state.currentVersion(), is(state.storedVersion())); assertFalse(state.isUpgraded()); @@ -50,7 +75,9 @@ public class VersionStateTest { @Test public void serverdbfile() throws IOException { File dbDir = tempDir.newFolder(); - VersionState state = new VersionState(new ConfigserverConfig(new ConfigserverConfig.Builder().configServerDBDir(dbDir.getAbsolutePath()))); + VersionState state = new VersionState(new ConfigserverConfig.Builder().configServerDBDir(dbDir.getAbsolutePath()).build(), + curator, + new InMemoryFlagSource()); state.saveNewVersion(); File versionFile = new File(dbDir, "vespa_version"); assertTrue(versionFile.exists()); @@ -58,4 +85,8 @@ public class VersionStateTest { assertThat(stored, is(state.currentVersion())); } + private VersionState createVersionState() throws IOException { + return new VersionState(tempDir.newFile(), curator, flagSource); + } + } |