summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-09-24 12:46:23 +0200
committerHarald Musum <musum@verizonmedia.com>2020-09-24 12:46:23 +0200
commita4c4d9075fa1a6bd9d23cac3c72ac57071493fcf (patch)
tree87d90bf1ed95d96992388d27f1b3872261982532 /configserver
parent6704090650b19fff7f69fa8a997fddad9ca91c3a (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')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/version/VersionState.java47
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java19
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/version/VersionStateTest.java41
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);
+ }
+
}