aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2022-04-11 08:24:39 +0200
committerjonmv <venstad@gmail.com>2022-04-11 13:42:27 +0200
commit1e9d33b4070cf785644a4eb34f6efb1a36e79b79 (patch)
treeae66ccf1f4978bdaf68bf5f0c21a3f544a944639
parentc3cc2c85fe25785688d56bd8a71650ac4668f7c9 (diff)
Allow cancelling rollout of builds, through /application/v4/
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java7
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java1
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json2
6 files changed, 23 insertions, 5 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java
index 75bb7c406e7..29d7005ddc7 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java
@@ -85,12 +85,13 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> {
return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), false, Optional.empty(), true, false, Optional.empty(), 0);
}
- /** Creates a version from a completed build, an author email, and build meta data. */
+ /** Creates a version from a completed build, an author email, and build metadata. */
public static ApplicationVersion from(SourceRevision source, long buildNumber, String authorEmail,
Version compileVersion, Instant buildTime) {
return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.of(authorEmail), Optional.of(compileVersion), Optional.of(buildTime), Optional.empty(), Optional.empty(), false, Optional.empty(), true, false, Optional.empty(), 0);
}
+ /** Creates a minimal version for a development build. */
public static ApplicationVersion forDevelopment(long buildNumber, Optional<Version> compileVersion) {
return new ApplicationVersion(Optional.empty(), OptionalLong.of(buildNumber), Optional.empty(), compileVersion, Optional.empty(), Optional.empty(), Optional.empty(), true, Optional.empty(), true, false, Optional.empty(), 0);
}
@@ -165,7 +166,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> {
/** Returns a copy of this without a package stored. */
public ApplicationVersion withoutPackage() {
- return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, false, shouldSkip, Optional.empty(), 0);
+ return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, false, shouldSkip, description, risk);
}
/** Whether we still have the package for this revision. */
@@ -175,7 +176,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> {
/** Returns a copy of this which will not be rolled out to production. */
public ApplicationVersion skipped() {
- return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, hasPackage, true, Optional.empty(), 0);
+ return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, hasPackage, true, description, risk);
}
/** Whether we still have the package for this revision. */
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
index 98c64a2a11e..b7874734e11 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/PathGroup.java
@@ -103,6 +103,7 @@ enum PathGroup {
/** Paths used by application administrators. */
applicationInfo(Matcher.tenant,
Matcher.application,
+ "/application/v4/tenant/{tenant}/application/{application}/submit/{build}",
"/application/v4/tenant/{tenant}/application/{application}/package",
"/application/v4/tenant/{tenant}/application/{application}/diff/{number}",
"/application/v4/tenant/{tenant}/application/{application}/compile-version",
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
index 4d342e3b1ee..e7b6f7fe8e5 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Policy.java
@@ -87,7 +87,7 @@ enum Policy {
.on(PathGroup.application, PathGroup.applicationInfo, PathGroup.reindexing, PathGroup.serviceDump)
.in(SystemName.all())),
- /** Read access to application information and settings. */
+ /** Update access to application information and settings. */
applicationUpdate(Privilege.grant(Action.update)
.on(PathGroup.application, PathGroup.applicationInfo)
.in(SystemName.all())),
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 4bda89acd95..620e4101c36 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -66,6 +66,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeReposi
import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
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.api.integration.deployment.SourceRevision;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.RestartFilter;
@@ -354,6 +355,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying")) return cancelDeploy(path.get("tenant"), path.get("application"), "default", "all");
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying/{choice}")) return cancelDeploy(path.get("tenant"), path.get("application"), "default", path.get("choice"));
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/key")) return removeDeployKey(path.get("tenant"), path.get("application"), request);
+ if (path.matches("/application/v4/tenant/{tenant}/application/{application}/submit/{build}")) return cancelBuild(path.get("tenant"), path.get("application"), path.get("build"));
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}")) return deleteInstance(path.get("tenant"), path.get("application"), path.get("instance"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/deploying")) return cancelDeploy(path.get("tenant"), path.get("application"), path.get("instance"), "all");
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/deploying/{choice}")) return cancelDeploy(path.get("tenant"), path.get("application"), path.get("instance"), path.get("choice"));
@@ -1932,6 +1934,15 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
.orElseThrow(() -> new IllegalArgumentException("Build number '" + build + "' was not found"));
}
+ private HttpResponse cancelBuild(String tenantName, String applicationName, String build){
+ TenantAndApplicationId id = TenantAndApplicationId.from(tenantName, applicationName);
+ RevisionId revision = RevisionId.forProduction(Long.parseLong(build));
+ controller.applications().lockApplicationOrThrow(id, application -> {
+ controller.applications().store(application.withRevisions(revisions -> revisions.with(revisions.get(revision).skipped())));
+ });
+ return new MessageResponse("Marked build '" + build + "' as non-deployable");
+ }
+
/** Cancel ongoing change for given application, e.g., everything with {"cancel":"all"} */
private HttpResponse cancelDeploy(String tenantName, String applicationName, String instanceName, String choice) {
ApplicationId id = ApplicationId.from(tenantName, applicationName, instanceName);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index ebbaaa20a8d..b59b57a4e5f 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -834,6 +834,11 @@ public class ApplicationApiTest extends ControllerContainerTest {
"{\"message\":\"Application package version: 1.0.4-commit1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
+ // DELETE submitted build, to mark it as non-deployable
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit/3", DELETE)
+ .userIdentity(USER_ID),
+ "{\"message\":\"Marked build '3' as non-deployable\"}");
+
// GET deployment job overview, after triggering system and staging test jobs.
assertEquals(2, tester.controller().applications().deploymentTrigger().triggerReadyJobs());
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1/job", GET)
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json
index 837b08b461b..dde366f4864 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json
@@ -695,7 +695,7 @@
"commit": "commit1",
"description": "my best commit yet",
"risk": 9001,
- "deployable": true
+ "deployable": false
},
{
"build": 2,