summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorValerij Fredriksen <valerij92@gmail.com>2020-09-25 10:42:13 +0200
committerValerij Fredriksen <valerij92@gmail.com>2020-09-25 10:42:13 +0200
commit9fe53dc16eaf71124bebf16aa283a4ee37625e86 (patch)
treeca66715ff87a6db3f4ddd6536d51e7fdeeea582d /configserver
parent9c90d3aaed422af9ecf41e2da34866ee7c26ee5c (diff)
Allow creating Deployment with PrepareParams
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java4
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java119
2 files changed, 63 insertions, 60 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index bd704611bcb..2ea97e92632 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -396,7 +396,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
LocalSession newSession = sessionRepository.createSessionFromExisting(activeSession, logger, true, timeoutBudget);
sessionRepository.addLocalSession(newSession);
- return Optional.of(Deployment.unprepared(newSession, this, hostProvisioner, tenant, timeout, clock,
+ return Optional.of(Deployment.unprepared(newSession, this, hostProvisioner, tenant, logger, timeout, clock,
false /* don't validate as this is already deployed */, bootstrap));
}
@@ -420,7 +420,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
}
private Deployment deployment(LocalSession session, Tenant tenant, Duration timeout, boolean force) {
- return Deployment.prepared(session, this, hostProvisioner, tenant, timeout, clock, false, force);
+ return Deployment.prepared(session, this, hostProvisioner, tenant, logger, timeout, clock, false, force);
}
public Transaction deactivateCurrentActivateNew(Session active, LocalSession prepared, boolean force) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java
index 6c111ff0131..d9efe2c4b97 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/Deployment.java
@@ -1,14 +1,12 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.deploy;
-import com.yahoo.component.Version;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.AthenzDomain;
-import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.Provisioner;
-import java.util.logging.Level;
import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.ApplicationRepository.ActionTimer;
import com.yahoo.vespa.config.server.TimeoutBudget;
@@ -18,13 +16,13 @@ import com.yahoo.vespa.config.server.session.LocalSession;
import com.yahoo.vespa.config.server.session.PrepareParams;
import com.yahoo.vespa.config.server.session.RemoteSession;
import com.yahoo.vespa.config.server.session.Session;
-import com.yahoo.vespa.config.server.session.SilentDeployLogger;
import com.yahoo.vespa.config.server.tenant.Tenant;
import com.yahoo.vespa.curator.Lock;
import java.time.Clock;
import java.time.Duration;
import java.util.Optional;
+import java.util.logging.Level;
import java.util.logging.Logger;
import static com.yahoo.vespa.curator.Curator.CompletionWaiter;
@@ -44,81 +42,54 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
/** The session containing the application instance to activate */
private final LocalSession session;
private final ApplicationRepository applicationRepository;
- private final Optional<Provisioner> hostProvisioner;
+ private final Supplier<PrepareParams> params;
+ private final Optional<Provisioner> provisioner;
private final Tenant tenant;
- private final Duration timeout;
+ private final DeployLogger logger;
private final Clock clock;
- private final DeployLogger logger = new SilentDeployLogger();
-
- /** The repository part of docker image this application should run on. Version is separate from image repo */
- final Optional<DockerImage> dockerImageRepository;
-
- /** The Vespa version this application should run on */
- private final Version version;
-
- /** True if this deployment is done to bootstrap the config server */
- private final boolean isBootstrap;
-
- /** The (optional) Athenz domain this application should use */
- private final Optional<AthenzDomain> athenzDomain;
- private boolean prepared = false;
-
- /** Whether this model should be validated (only takes effect if prepared=false) */
- private final boolean validate;
+ private boolean prepared;
- /** Whether activation of this model should be forced */
- private final boolean force;
-
- private Deployment(LocalSession session, ApplicationRepository applicationRepository,
- Optional<Provisioner> hostProvisioner, Tenant tenant, Duration timeout,
- Clock clock, boolean prepared, boolean validate, boolean isBootstrap, boolean force) {
+ private Deployment(LocalSession session, ApplicationRepository applicationRepository, Supplier<PrepareParams> params,
+ Optional<Provisioner> provisioner, Tenant tenant, DeployLogger logger, Clock clock, boolean prepared) {
this.session = session;
this.applicationRepository = applicationRepository;
- this.hostProvisioner = hostProvisioner;
+ this.params = params;
+ this.provisioner = provisioner;
this.tenant = tenant;
- this.timeout = timeout;
+ this.logger = logger;
this.clock = clock;
this.prepared = prepared;
- this.validate = validate;
- this.dockerImageRepository = session.getDockerImageRepository();
- this.version = session.getVespaVersion();
- this.isBootstrap = isBootstrap;
- this.athenzDomain = session.getAthenzDomain();
- this.force = force;
}
public static Deployment unprepared(LocalSession session, ApplicationRepository applicationRepository,
- Optional<Provisioner> hostProvisioner, Tenant tenant,
+ Optional<Provisioner> provisioner, Tenant tenant, PrepareParams params, DeployLogger logger, Clock clock) {
+ return new Deployment(session, applicationRepository, () -> params, provisioner, tenant, logger, clock, false);
+ }
+
+ public static Deployment unprepared(LocalSession session, ApplicationRepository applicationRepository,
+ Optional<Provisioner> provisioner, Tenant tenant, DeployLogger logger,
Duration timeout, Clock clock, boolean validate, boolean isBootstrap) {
- return new Deployment(session, applicationRepository, hostProvisioner, tenant, timeout, clock, false,
- validate, isBootstrap, false);
+ Supplier<PrepareParams> params = createPrepareParams(clock, timeout, session, isBootstrap, !validate, false);
+ return new Deployment(session, applicationRepository, params, provisioner, tenant, logger, clock, false);
}
public static Deployment prepared(LocalSession session, ApplicationRepository applicationRepository,
- Optional<Provisioner> hostProvisioner, Tenant tenant,
+ Optional<Provisioner> provisioner, Tenant tenant, DeployLogger logger,
Duration timeout, Clock clock, boolean isBootstrap, boolean force) {
- return new Deployment(session, applicationRepository, hostProvisioner, tenant,
- timeout, clock, true, true, isBootstrap, force);
+ Supplier<PrepareParams> params = createPrepareParams(clock, timeout, session, isBootstrap, false, force);
+ return new Deployment(session, applicationRepository, params, provisioner, tenant, logger, clock, true);
}
/** Prepares this. This does nothing if this is already prepared */
@Override
public void prepare() {
if (prepared) return;
+ PrepareParams params = this.params.get();
ApplicationId applicationId = session.getApplicationId();
try (ActionTimer timer = applicationRepository.timerFor(applicationId, "deployment.prepareMillis")) {
- TimeoutBudget timeoutBudget = new TimeoutBudget(clock, timeout);
-
- PrepareParams.Builder params = new PrepareParams.Builder().applicationId(applicationId)
- .timeoutBudget(timeoutBudget)
- .ignoreValidationErrors(!validate)
- .vespaVersion(version.toString())
- .isBootstrap(isBootstrap);
- dockerImageRepository.ifPresent(params::dockerImageRepository);
- athenzDomain.ifPresent(params::athenzDomain);
Optional<ApplicationSet> activeApplicationSet = applicationRepository.getCurrentActiveApplicationSet(tenant, applicationId);
- tenant.getSessionRepository().prepareLocalSession(session, logger, params.build(), activeApplicationSet,
+ tenant.getSessionRepository().prepareLocalSession(session, logger, params, activeApplicationSet,
tenant.getPath(), clock.instant());
this.prepared = true;
}
@@ -130,16 +101,17 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
prepare();
validateSessionStatus(session);
+ PrepareParams params = this.params.get();
ApplicationId applicationId = session.getApplicationId();
try (ActionTimer timer = applicationRepository.timerFor(applicationId, "deployment.activateMillis")) {
- TimeoutBudget timeoutBudget = new TimeoutBudget(clock, timeout);
+ TimeoutBudget timeoutBudget = params.getTimeoutBudget();
if ( ! timeoutBudget.hasTimeLeft()) throw new RuntimeException("Timeout exceeded when trying to activate '" + applicationId + "'");
RemoteSession previousActiveSession;
CompletionWaiter waiter;
try (Lock lock = tenant.getApplicationRepo().lock(applicationId)) {
previousActiveSession = applicationRepository.getActiveSession(applicationId);
- waiter = applicationRepository.activate(session, previousActiveSession, applicationId, force);
+ waiter = applicationRepository.activate(session, previousActiveSession, applicationId, params.force());
}
catch (RuntimeException e) {
throw e;
@@ -150,7 +122,7 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
waiter.awaitCompletion(timeoutBudget.timeLeft());
log.log(Level.INFO, session.logPre() + "Session " + session.getSessionId() + " activated successfully using " +
- hostProvisioner.map(provisioner -> provisioner.getClass().getSimpleName()).orElse("no host provisioner") +
+ provisioner.map(provisioner -> provisioner.getClass().getSimpleName()).orElse("no host provisioner") +
". Config generation " + session.getMetaData().getGeneration() +
(previousActiveSession != null ? ". Based on session " + previousActiveSession.getSessionId() : "") +
". File references: " + applicationRepository.getFileReferences(applicationId));
@@ -165,7 +137,7 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
*/
@Override
public void restart(HostFilter filter) {
- hostProvisioner.get().restart(session.getApplicationId(), filter);
+ provisioner.get().restart(session.getApplicationId(), filter);
}
/** Exposes the session of this for testing only */
@@ -180,4 +152,35 @@ public class Deployment implements com.yahoo.config.provision.Deployment {
}
}
+ /**
+ * @param clock system clock
+ * @param timeout total timeout duration of prepare + activate
+ * @param session the local session for this deployment
+ * @param isBootstrap true if this deployment is done to bootstrap the config server
+ * @param ignoreValidationErrors whether this model should be validated
+ * @param force whether activation of this model should be forced
+ */
+ private static Supplier<PrepareParams> createPrepareParams(
+ Clock clock, Duration timeout, LocalSession session,
+ boolean isBootstrap, boolean ignoreValidationErrors, boolean force) {
+
+ // Supplier because shouldn't/cant create this before validateSessionStatus() for prepared deployments
+ // memoized because we want to create this once for unprepared deployments
+ return Suppliers.memoize(() -> {
+ TimeoutBudget timeoutBudget = new TimeoutBudget(clock, timeout);
+
+ PrepareParams.Builder params = new PrepareParams.Builder()
+ .applicationId(session.getApplicationId())
+ .vespaVersion(session.getVespaVersion().toString())
+ .timeoutBudget(timeoutBudget)
+ .ignoreValidationErrors(ignoreValidationErrors)
+ .isBootstrap(isBootstrap)
+ .force(force);
+ session.getDockerImageRepository().ifPresent(params::dockerImageRepository);
+ session.getAthenzDomain().ifPresent(params::athenzDomain);
+
+ return params.build();
+ });
+ }
+
}