diff options
author | Håkon Hallingstad <hakon@yahooinc.com> | 2022-08-18 16:57:55 +0200 |
---|---|---|
committer | Håkon Hallingstad <hakon@yahooinc.com> | 2022-08-18 16:57:55 +0200 |
commit | b679206de2431f11e52e6734abfcaefa40554037 (patch) | |
tree | bde9c884a71f552165d5554596c48bcd3f63fdf1 /flags/src | |
parent | 7a65553cd4efc3574cb1bd859b17008ecdf878d6 (diff) |
Allow overriding wanted docker tag and vespa version
Diffstat (limited to 'flags/src')
4 files changed, 72 insertions, 7 deletions
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java b/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java index 9f40013f627..c1877373ce2 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java @@ -20,7 +20,7 @@ public class FetchVector { * Note: If this enum is changed, you must also change {@link DimensionHelper}. */ public enum Dimension { - /** A legal value for TenantName, e.g. vespa-team */ + /** Value from TenantName::value, e.g. vespa-team */ TENANT_ID, /** Value from ApplicationId::serializedForm of the form tenant:applicationName:instance. */ @@ -29,7 +29,7 @@ public class FetchVector { /** Node type from com.yahoo.config.provision.NodeType::name, e.g. tenant, host, confighost, controller, etc. */ NODE_TYPE, - /** Cluster type from com.yahoo.config.provision.ClusterSpec.Type::value, e.g. content, container, admin */ + /** Cluster type from com.yahoo.config.provision.ClusterSpec.Type::name, e.g. content, container, admin */ CLUSTER_TYPE, /** Cluster ID from com.yahoo.config.provision.ClusterSpec.Id::value, e.g. cluster-controllers, logserver. */ diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index e349165b855..9552e1a961d 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -11,6 +11,7 @@ import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Optional; import java.util.TreeMap; +import java.util.function.Predicate; import static com.yahoo.vespa.flags.FetchVector.Dimension.APPLICATION_ID; import static com.yahoo.vespa.flags.FetchVector.Dimension.CONSOLE_USER_EMAIL; @@ -490,7 +491,19 @@ public class Flags { public static UnboundStringFlag defineStringFlag(String flagId, String defaultValue, List<String> owners, String createdAt, String expiresAt, String description, String modificationEffect, FetchVector.Dimension... dimensions) { - return define(UnboundStringFlag::new, flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions); + return defineStringFlag(flagId, defaultValue, owners, + createdAt, expiresAt, description, + modificationEffect, value -> true, + dimensions); + } + + /** WARNING: public for testing: All flags should be defined in {@link Flags}. */ + public static UnboundStringFlag defineStringFlag(String flagId, String defaultValue, List<String> owners, + String createdAt, String expiresAt, String description, + String modificationEffect, Predicate<String> validator, + FetchVector.Dimension... dimensions) { + return define((i, d, v) -> new UnboundStringFlag(i, d, v, validator), + flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions); } /** WARNING: public for testing: All flags should be defined in {@link Flags}. */ @@ -532,7 +545,7 @@ public class Flags { @FunctionalInterface private interface TypedUnboundFlagFactory<T, U extends UnboundFlag<?, ?, ?>> { - U create(FlagId id, T defaultVale, FetchVector defaultFetchVector); + U create(FlagId id, T defaultValue, FetchVector defaultFetchVector); } /** diff --git a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java index b5a292a554d..0003d5e42c7 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java @@ -9,6 +9,8 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.List; +import java.util.function.Predicate; +import java.util.regex.Pattern; import static com.yahoo.vespa.flags.FetchVector.Dimension.APPLICATION_ID; import static com.yahoo.vespa.flags.FetchVector.Dimension.CLUSTER_ID; @@ -17,6 +19,7 @@ import static com.yahoo.vespa.flags.FetchVector.Dimension.CONSOLE_USER_EMAIL; import static com.yahoo.vespa.flags.FetchVector.Dimension.HOSTNAME; import static com.yahoo.vespa.flags.FetchVector.Dimension.NODE_TYPE; import static com.yahoo.vespa.flags.FetchVector.Dimension.TENANT_ID; +import static com.yahoo.vespa.flags.FetchVector.Dimension.VESPA_VERSION; import static com.yahoo.vespa.flags.FetchVector.Dimension.ZONE_ID; /** @@ -113,6 +116,28 @@ public class PermanentFlags { "Takes effect on next deployment from controller", ZONE_ID, APPLICATION_ID); + private static final String VERSION_QUALIFIER_REGEX = "[a-zA-Z0-9_-]+"; + private static final Pattern QUALIFIER_PATTERN = Pattern.compile("^" + VERSION_QUALIFIER_REGEX + "$"); + private static final Pattern VERSION_PATTERN = Pattern.compile("^\\d\\.\\d\\.\\d(\\." + VERSION_QUALIFIER_REGEX + ")?$"); + + public static final UnboundStringFlag WANTED_DOCKER_TAG = defineStringFlag( + "wanted-docker-tag", "", + "If non-empty the flag value overrides the docker image tag of the wantedDockerImage of the node object. " + + "If the flag value contains '.', it must specify a valid Vespa version like '8.83.42'. " + + "Otherwise a '.' + the flag value will be appended.", + "Takes effect on the next host admin tick. The upgrade to the new wanted docker image is orchestrated.", + value -> value.isEmpty() || QUALIFIER_PATTERN.matcher(value).find() || VERSION_PATTERN.matcher(value).find(), + HOSTNAME, NODE_TYPE, TENANT_ID, APPLICATION_ID, CLUSTER_TYPE, CLUSTER_ID, VESPA_VERSION); + + public static final UnboundStringFlag WANTED_VESPA_VERSION = defineStringFlag( + "wanted-vespa-version", "", + "If non-empty the flag value overrides the wantedVespaVersion of the node object." + + "If the flag value contains '.', it must specify a valid Vespa version like '8.83.42'. " + + "Otherwise a '.' + the flag value will be appended.", + "Takes effect on the next host admin tick. The upgrade to the new wanted docker image is orchestrated.", + value -> value.isEmpty() || QUALIFIER_PATTERN.matcher(value).find() || VERSION_PATTERN.matcher(value).find(), + HOSTNAME, NODE_TYPE, TENANT_ID, APPLICATION_ID, CLUSTER_TYPE, CLUSTER_ID, VESPA_VERSION); + public static final UnboundStringFlag ZOOKEEPER_SERVER_VERSION = defineStringFlag( "zookeeper-server-version", "3.7.1", // Note: Nodes running Vespa 7 have 3.7.1 as the only available version "ZooKeeper server version, a jar file zookeeper-server-<ZOOKEEPER_SERVER_VERSION>-jar-with-dependencies.jar must exist", @@ -280,6 +305,11 @@ public class PermanentFlags { return Flags.defineStringFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions); } + private static UnboundStringFlag defineStringFlag( + String flagId, String defaultValue, String description, String modificationEffect, Predicate<String> validator, FetchVector.Dimension... dimensions) { + return Flags.defineStringFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, validator, dimensions); + } + private static UnboundIntFlag defineIntFlag( String flagId, int defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) { return Flags.defineIntFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions); diff --git a/flags/src/main/java/com/yahoo/vespa/flags/UnboundStringFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/UnboundStringFlag.java index f96be55e2eb..9c69e917fa6 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/UnboundStringFlag.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/UnboundStringFlag.java @@ -4,6 +4,10 @@ package com.yahoo.vespa.flags; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.TextNode; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + /** * @author hakonhall */ @@ -13,8 +17,26 @@ public class UnboundStringFlag extends UnboundFlagImpl<String, StringFlag, Unbou } public UnboundStringFlag(FlagId id, String defaultValue, FetchVector defaultFetchVector) { - super(id, defaultValue, defaultFetchVector, - new SimpleFlagSerializer<>(TextNode::new, JsonNode::isTextual, JsonNode::asText), - UnboundStringFlag::new, StringFlag::new); + this(id, defaultValue, defaultFetchVector, + new SimpleFlagSerializer<>(TextNode::new, JsonNode::isTextual, JsonNode::asText)); + } + + public UnboundStringFlag(FlagId id, String defaultValue, Predicate<String> validator) { + this(id, defaultValue, new FetchVector(), validator); + } + + public UnboundStringFlag(FlagId id, String defaultValue, FetchVector fetchVector, Predicate<String> validator) { + this(id, defaultValue, fetchVector, + new SimpleFlagSerializer<>(stringValue -> { + if (!validator.test(stringValue)) + throw new IllegalArgumentException("Invalid value: '" + stringValue + "'"); + return new TextNode(stringValue); + }, + JsonNode::isTextual, JsonNode::asText)); + } + + public UnboundStringFlag(FlagId id, String defaultValue, FetchVector defaultFetchVector, + FlagSerializer<String> serializer) { + super(id, defaultValue, defaultFetchVector, serializer, UnboundStringFlag::new, StringFlag::new); } } |