summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2023-09-08 12:37:16 +0200
committerjonmv <venstad@gmail.com>2023-09-08 12:37:16 +0200
commit5935d65540ab4f19e1ea9783ea2df3f7f1c1c807 (patch)
tree31634f52b72badee6eb0f322d968dcce99f414e7 /controller-server
parent4e14c5c0cec9150f35a93222368af174f911798d (diff)
Store optional dependent job and change for each run (will be used for tests)
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Run.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java47
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java14
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json10
7 files changed, 80 insertions, 15 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
index 81eaa17f95d..42044cf335a 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
@@ -405,7 +405,7 @@ public class DeploymentTrigger {
private void abortIfOutdated(JobStatus job, List<DeploymentStatus.Job> jobs) {
job.lastTriggered()
- .filter(last -> ! last.hasEnded() && last.reason().isEmpty())
+ .filter(last -> ! last.hasEnded() && last.reason().reason().isEmpty())
.ifPresent(last -> {
if (jobs.stream().noneMatch(versions -> versions.versions().targetsMatch(last.versions())
&& versions.versions().sourcesMatchIfPresent(last.versions()))) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
index 5ccb59e3ebc..589188bfc4f 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
@@ -36,6 +36,7 @@ import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId;
import com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.pkg.ApplicationPackageDiff;
import com.yahoo.vespa.hosted.controller.application.pkg.TestPackage;
+import com.yahoo.vespa.hosted.controller.deployment.Run.Reason;
import com.yahoo.vespa.hosted.controller.notification.Notification;
import com.yahoo.vespa.hosted.controller.notification.Notification.Type;
import com.yahoo.vespa.hosted.controller.notification.NotificationSource;
@@ -717,7 +718,8 @@ public class JobController {
throw new IllegalArgumentException("Cannot start " + type + " for " + id + "; it is already running!");
RunId newId = new RunId(id, type, last.map(run -> run.id().number()).orElse(0L) + 1);
- curator.writeLastRun(Run.initial(newId, versions, isRedeployment, controller.clock().instant(), profile, reason));
+ curator.writeLastRun(Run.initial(newId, versions, isRedeployment, controller.clock().instant(), profile,
+ new Reason(reason, Optional.empty(), Optional.empty())));
metric.jobStarted(newId.job());
});
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Run.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Run.java
index 0c5fb3fb3cb..12e04df4790 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Run.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/Run.java
@@ -2,7 +2,9 @@
package com.yahoo.vespa.hosted.controller.deployment;
import com.yahoo.config.provision.CloudAccount;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.application.Change;
import java.security.cert.X509Certificate;
import java.time.Instant;
@@ -44,13 +46,13 @@ public class Run {
private final Optional<X509Certificate> testerCertificate;
private final boolean dryRun;
private final Optional<CloudAccount> cloudAccount;
- private final Optional<String> reason;
+ private final Reason reason;
// For deserialisation only -- do not use!
public Run(RunId id, Map<Step, StepInfo> steps, Versions versions, boolean isRedeployment, Instant start, Optional<Instant> end,
Optional<Instant> sleepUntil, RunStatus status, long lastTestRecord, Instant lastVespaLogTimestamp,
Optional<Instant> noNodesDownSince, Optional<ConvergenceSummary> convergenceSummary,
- Optional<X509Certificate> testerCertificate, boolean dryRun, Optional<CloudAccount> cloudAccount, Optional<String> reason) {
+ Optional<X509Certificate> testerCertificate, boolean dryRun, Optional<CloudAccount> cloudAccount, Reason reason) {
this.id = id;
this.steps = Collections.unmodifiableMap(new EnumMap<>(steps));
this.versions = versions;
@@ -69,12 +71,12 @@ public class Run {
this.reason = reason;
}
- public static Run initial(RunId id, Versions versions, boolean isRedeployment, Instant now, JobProfile profile, Optional<String> triggeredBy) {
+ public static Run initial(RunId id, Versions versions, boolean isRedeployment, Instant now, JobProfile profile, Reason reason) {
EnumMap<Step, StepInfo> steps = new EnumMap<>(Step.class);
profile.steps().forEach(step -> steps.put(step, StepInfo.initial(step)));
return new Run(id, steps, requireNonNull(versions), isRedeployment, requireNonNull(now), Optional.empty(),
Optional.empty(), running, -1, Instant.EPOCH, Optional.empty(), Optional.empty(),
- Optional.empty(), profile == JobProfile.developmentDryRun, Optional.empty(), triggeredBy);
+ Optional.empty(), profile == JobProfile.developmentDryRun, Optional.empty(), reason);
}
/** Returns a new Run with the status of the given completed step set accordingly. */
@@ -278,7 +280,7 @@ public class Run {
public Optional<CloudAccount> cloudAccount() { return cloudAccount; }
/** The specific reason for triggering this run, if any. This should be empty for jobs triggered bvy deployment orchestration. */
- public Optional<String> reason() {
+ public Reason reason() {
return reason;
}
@@ -342,4 +344,6 @@ public class Run {
throw new IllegalStateException("This run ended at " + end.get() + " -- it can't be further modified!");
}
+ public record Reason(Optional<String> reason, Optional<JobId> dependent, Optional<Change> change) { }
+
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
index 73d0bf6cad6..b1ca6c63816 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java
@@ -11,11 +11,14 @@ import com.yahoo.slime.Inspector;
import com.yahoo.slime.ObjectTraverser;
import com.yahoo.slime.Slime;
import com.yahoo.slime.SlimeUtils;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.application.Change;
import com.yahoo.vespa.hosted.controller.deployment.ConvergenceSummary;
import com.yahoo.vespa.hosted.controller.deployment.Run;
+import com.yahoo.vespa.hosted.controller.deployment.Run.Reason;
import com.yahoo.vespa.hosted.controller.deployment.RunStatus;
import com.yahoo.vespa.hosted.controller.deployment.Step;
import com.yahoo.vespa.hosted.controller.deployment.Step.Status;
@@ -101,6 +104,8 @@ class RunSerializer {
private static final String isDryRunField = "isDryRun";
private static final String cloudAccountField = "account";
private static final String reasonField = "reason";
+ private static final String dependentField = "dependent";
+ private static final String changeField = "change";
Run runFromSlime(Slime slime) {
return runFromSlime(slime.get());
@@ -147,7 +152,7 @@ class RunSerializer {
SlimeUtils.optionalString(runObject.field(testerCertificateField)).map(X509CertificateUtils::fromPem),
runObject.field(isDryRunField).valid() && runObject.field(isDryRunField).asBool(),
SlimeUtils.optionalString(runObject.field(cloudAccountField)).map(CloudAccount::from),
- SlimeUtils.optionalString(runObject.field(reasonField)));
+ reasonFrom(runObject));
}
private Versions versionsFromSlime(Inspector versionsObject, RunId id) {
@@ -241,7 +246,7 @@ class RunSerializer {
});
runObject.setBool(isDryRunField, run.isDryRun());
run.cloudAccount().ifPresent(account -> runObject.setString(cloudAccountField, account.value()));
- run.reason().ifPresent(reason -> runObject.setString(reasonField, reason));
+ toSlime(run.reason(), runObject);
}
private void toSlime(Version platformVersion, RevisionId revsion, Cursor versionsObject) {
@@ -372,4 +377,42 @@ class RunSerializer {
};
}
+ Reason reasonFrom(Inspector object) {
+ return new Reason(SlimeUtils.optionalString(object.field(reasonField)),
+ Optional.ofNullable(jobIdFrom(object.field(dependentField))),
+ Optional.ofNullable(toChange(object.field(changeField))));
+ }
+
+ void toSlime(Reason reason, Cursor object) {
+ reason.reason().ifPresent(value -> object.setString(reasonField, value));
+ reason.dependent().ifPresent(dependent -> toSlime(dependent, object.setObject(dependentField)));
+ reason.change().ifPresent(change -> toSlime(change, object.setObject(changeField)));
+ }
+
+ JobId jobIdFrom(Inspector object) {
+ if ( ! object.valid()) return null;
+ return new JobId(ApplicationId.fromSerializedForm(object.field(applicationField).asString()),
+ JobType.ofSerialized(object.field(jobTypeField).asString()));
+ }
+
+ void toSlime(JobId jobId, Cursor object) {
+ object.setString(applicationField, jobId.application().serializedForm());
+ object.setString(jobTypeField, jobId.type().serialized());
+ }
+
+ Change toChange(Inspector object) {
+ if ( ! object.valid()) return null;
+ Change change = Change.empty();
+ if (object.field(platformVersionField).valid())
+ change = change.with(Version.fromString(object.field(platformVersionField).asString()));
+ if (object.field(buildField).valid())
+ change = change.with(RevisionId.forProduction(object.field(buildField).asLong()));
+ return change;
+ }
+
+ void toSlime(Change change, Cursor object) {
+ change.platform().ifPresent(version -> object.setString(platformVersionField, version.toString()));
+ change.revision().ifPresent(revision -> object.setLong(buildField, revision.number()));
+ }
+
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
index 982e81d92b1..140cc142ceb 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
@@ -125,7 +125,7 @@ class JobControllerApiHandlerHelper {
Run run = jobController.run(runId);
detailsObject.setBool("active", ! run.hasEnded());
detailsObject.setString("status", nameOf(run.status()));
- run.reason().ifPresent(reason -> detailsObject.setString("reason", reason));
+ run.reason().reason().ifPresent(reason -> detailsObject.setString("reason", reason));
try {
jobController.updateTestLog(runId);
jobController.updateVespaLog(runId);
@@ -498,7 +498,7 @@ class JobControllerApiHandlerHelper {
runObject.setLong("start", run.start().toEpochMilli());
run.end().ifPresent(end -> runObject.setLong("end", end.toEpochMilli()));
runObject.setString("status", nameOf(run.status()));
- run.reason().ifPresent(reason -> runObject.setString("reason", reason));
+ run.reason().reason().ifPresent(reason -> runObject.setString("reason", reason));
toSlime(runObject.setObject("versions"), run.versions(), application);
Cursor runStepsArray = runObject.setArray("steps");
run.steps().forEach((step, info) -> {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java
index cae5037ab6f..fc1a694e0f7 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java
@@ -7,12 +7,15 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.security.X509CertificateUtils;
import com.yahoo.slime.SlimeUtils;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
+import com.yahoo.vespa.hosted.controller.application.Change;
import com.yahoo.vespa.hosted.controller.deployment.ConvergenceSummary;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentContext;
import com.yahoo.vespa.hosted.controller.deployment.JobProfile;
import com.yahoo.vespa.hosted.controller.deployment.Run;
+import com.yahoo.vespa.hosted.controller.deployment.Run.Reason;
import com.yahoo.vespa.hosted.controller.deployment.RunStatus;
import com.yahoo.vespa.hosted.controller.deployment.Step;
import com.yahoo.vespa.hosted.controller.deployment.StepInfo;
@@ -82,11 +85,15 @@ public class RunSerializerTest {
assertFalse(run.hasEnded());
assertEquals(running, run.status());
assertEquals(3, run.lastTestLogEntry());
- assertEquals(new Version(1, 2, 3), run.versions().targetPlatform());
+ Version version1 = new Version(1, 2, 3);
+ assertEquals(version1, run.versions().targetPlatform());
RevisionId revision1 = RevisionId.forDevelopment(123, id.job());
RevisionId revision2 = RevisionId.forProduction(122);
assertEquals(revision1, run.versions().targetRevision());
- assertEquals("because", run.reason().get());
+ assertEquals(new Reason(Optional.of("because"),
+ Optional.of(new JobId(id.application(), id.type())),
+ Optional.of(Change.of(version1).with(revision2))),
+ run.reason());
assertEquals(new Version(1, 2, 2), run.versions().sourcePlatform().get());
assertEquals(revision2, run.versions().sourceRevision().get());
assertEquals(Optional.of(new ConvergenceSummary(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233)),
@@ -145,7 +152,8 @@ public class RunSerializerTest {
assertEquals(new String(SlimeUtils.toJsonBytes(serializer.toSlime(run).get(), false), UTF_8),
new String(SlimeUtils.toJsonBytes(serializer.toSlime(phoenix).get(), false), UTF_8));
- Run initial = Run.initial(id, run.versions(), run.isRedeployment(), run.start(), JobProfile.production, Optional.empty());
+ Run initial = Run.initial(id, run.versions(), run.isRedeployment(), run.start(), JobProfile.production,
+ new Reason(Optional.empty(), Optional.empty(), Optional.empty()));
assertEquals(initial, serializer.runFromSlime(serializer.toSlime(initial)));
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json
index 1216bcefab6..618a7e66c5e 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/run-status.json
@@ -54,6 +54,14 @@
"deployedDirectly": false
}
},
- "reason": "because"
+ "reason": "because",
+ "dependent": {
+ "id": "tenant:application:default",
+ "type": "prod.us-east-3"
+ },
+ "change": {
+ "platform": "1.2.3",
+ "build": 122
+ }
}
] \ No newline at end of file