From 53dd65df9d69b3e7ab30f9a990ba0fd815599dba Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Wed, 4 May 2022 15:51:58 +0200 Subject: Support different artifact registry per cloud --- .../api/integration/ServiceRegistry.java | 4 ++- .../controller/maintenance/ArtifactExpirer.java | 34 ++++++++++++++++------ .../integration/ServiceRegistryMock.java | 6 ++-- .../maintenance/ArtifactExpirerTest.java | 3 +- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java index c258f088eeb..52f687e5708 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration; +import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.HostName; import com.yahoo.vespa.hosted.controller.api.identifiers.ControllerVersion; import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveService; @@ -36,6 +37,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.vcmr.ChangeRequestClien import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry; import java.time.Clock; +import java.util.Optional; /** * This provides access to all service dependencies of the controller. Implementations of this are responsible for @@ -99,7 +101,7 @@ public interface ServiceRegistry { BillingDatabaseClient billingDatabase(); - ArtifactRegistry containerRegistry(); + Optional artifactRegistry(CloudName cloudName); TenantSecretService tenantSecretService(); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirer.java index a7cff2fdda0..47eeb291dd7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirer.java @@ -2,9 +2,11 @@ package com.yahoo.vespa.hosted.controller.maintenance; import com.yahoo.component.Version; +import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.SystemName; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.api.integration.artifact.Artifact; +import com.yahoo.vespa.hosted.controller.api.integration.artifact.ArtifactRegistry; import com.yahoo.vespa.hosted.controller.versions.VersionStatus; import com.yahoo.vespa.hosted.controller.versions.VespaVersion; @@ -35,16 +37,30 @@ public class ArtifactExpirer extends ControllerMaintainer { @Override protected double maintain() { - Instant now = controller().clock().instant(); - VersionStatus versionStatus = controller().readVersionStatus(); - List artifactsToExpire = controller().serviceRegistry().containerRegistry().list().stream() - .filter(artifact -> isExpired(artifact, now, versionStatus)) - .collect(Collectors.toList()); - if (!artifactsToExpire.isEmpty()) { - log.log(Level.INFO, "Expiring " + artifactsToExpire.size() + " artifacts: " + artifactsToExpire); - controller().serviceRegistry().containerRegistry().deleteAll(artifactsToExpire); + return controller().clouds().stream() + .flatMapToDouble(cloud -> + controller().serviceRegistry().artifactRegistry(cloud).stream() + .mapToDouble(artifactRegistry -> maintain(cloud, artifactRegistry))) + .average() + .orElse(1); + } + + private double maintain(CloudName cloudName, ArtifactRegistry artifactRegistry) { + try { + Instant now = controller().clock().instant(); + VersionStatus versionStatus = controller().readVersionStatus(); + List artifactsToExpire = artifactRegistry.list().stream() + .filter(artifact -> isExpired(artifact, now, versionStatus)) + .collect(Collectors.toList()); + if (!artifactsToExpire.isEmpty()) { + log.log(Level.INFO, "Expiring " + artifactsToExpire.size() + " artifacts: " + artifactsToExpire); + artifactRegistry.deleteAll(artifactsToExpire); + } + return 1; + } catch (RuntimeException e) { + log.log(Level.WARNING, "Failed to expire artifacts in " + cloudName + ". Will retry in " + interval(), e); + return 0; } - return 1.0; } /** Returns whether given artifact is expired */ diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java index 0b37c4ebb8d..d923a4d1207 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java @@ -5,6 +5,7 @@ import com.google.inject.Inject; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.component.AbstractComponent; import com.yahoo.component.Version; +import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.SystemName; import com.yahoo.test.ManualClock; @@ -50,6 +51,7 @@ import com.yahoo.vespa.hosted.controller.api.integration.user.RoleMaintainerMock import com.yahoo.vespa.hosted.controller.api.integration.vcmr.MockChangeRequestClient; import java.time.Instant; +import java.util.Optional; /** * A mock implementation of a {@link ServiceRegistry} for testing purposes. @@ -236,8 +238,8 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg } @Override - public ArtifactRegistryMock containerRegistry() { - return containerRegistry; + public Optional artifactRegistry(CloudName cloudName) { + return Optional.of(containerRegistry); } @Override diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirerTest.java index ddc1c0b599f..237732aa60a 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ArtifactExpirerTest.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.controller.maintenance; import com.yahoo.component.Version; +import com.yahoo.config.provision.CloudName; import com.yahoo.vespa.hosted.controller.api.integration.artifact.Artifact; import com.yahoo.vespa.hosted.controller.api.integration.container.ContainerImage.Architecture; import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester; @@ -24,7 +25,7 @@ public class ArtifactExpirerTest { public void maintain() { DeploymentTester tester = new DeploymentTester(); ArtifactExpirer expirer = new ArtifactExpirer(tester.controller(), Duration.ofDays(1)); - ArtifactRegistryMock registry = tester.controllerTester().serviceRegistry().containerRegistry(); + ArtifactRegistryMock registry = tester.controllerTester().serviceRegistry().artifactRegistry(CloudName.defaultName()).orElseThrow(); Instant instant = tester.clock().instant(); Artifact image0 = new Artifact("image0", "registry.example.com", "vespa/vespa", instant, Version.fromString("7.1"), Optional.empty()); -- cgit v1.2.3