diff options
3 files changed, 53 insertions, 2 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeScheduler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeScheduler.java index beba542760c..6f4a8429c74 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeScheduler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeScheduler.java @@ -160,9 +160,10 @@ public class OsUpgradeScheduler extends ControllerMaintainer { @Override public Optional<Change> change(Version currentVersion, Instant instant) { CalendarVersion version = findVersion(instant, currentVersion); + Instant predicatedInstant = instant; while (!version.version().isAfter(currentVersion)) { - instant = instant.plus(Duration.ofDays(1)); - version = findVersion(instant, currentVersion); + predicatedInstant = predicatedInstant.plus(Duration.ofDays(1)); + version = findVersion(predicatedInstant, currentVersion); } Duration cooldown = remainingCooldownAt(instant, version); Instant schedulingInstant = schedulingInstant(instant.plus(cooldown), system); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeSchedulerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeSchedulerTest.java index 31a1fe96fb7..016db28c2aa 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeSchedulerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeSchedulerTest.java @@ -95,6 +95,39 @@ public class OsUpgradeSchedulerTest { } @Test + void schedule_calendar_versioned_release_in_cd() { + ControllerTester tester = new ControllerTester(SystemName.cd); + OsUpgradeScheduler scheduler = new OsUpgradeScheduler(tester.controller(), Duration.ofDays(1)); + Instant t0 = Instant.parse("2022-01-16T02:05:00.00Z"); // Inside trigger period + tester.clock().setInstant(t0); + CloudName cloud = CloudName.from("cloud"); + ZoneApi zone = zone("prod.us-west-1", cloud); + tester.zoneRegistry().setZones(zone).reprovisionToUpgradeOsIn(zone); + + // Set initial target + Version version0 = Version.fromString("7.0.0.20220101"); + tester.controller().upgradeOsIn(cloud, version0, Duration.ofDays(1), false); + + // Next version is triggered + Version version1 = Version.fromString("7.0.0.20220301"); + tester.clock().advance(Duration.ofDays(44)); + assertEquals("2022-03-01T02:05:00", formatInstant(tester.clock().instant())); + scheduler.maintain(); + assertEquals(version0, tester.controller().osVersionTarget(cloud).get().osVersion().version()); + // Cool-down passes + tester.clock().advance(Duration.ofDays(1)); + assertEquals(version1, scheduler.changeIn(cloud).get().version()); + scheduler.maintain(); + assertEquals(version1, tester.controller().osVersionTarget(cloud).get().osVersion().version()); + + // Estimate next change + Optional<OsUpgradeScheduler.Change> nextChange = scheduler.changeIn(cloud); + assertTrue(nextChange.isPresent()); + assertEquals("7.0.0.20220426", nextChange.get().version().toFullString()); + assertEquals("2022-04-27T02:00:00", formatInstant(nextChange.get().scheduleAt())); + } + + @Test void schedule_stable_release() { ControllerTester tester = new ControllerTester(); OsUpgradeScheduler scheduler = new OsUpgradeScheduler(tester.controller(), Duration.ofDays(1)); diff --git a/storage/src/vespa/storage/storageserver/rpc/cluster_controller_api_rpc_service.cpp b/storage/src/vespa/storage/storageserver/rpc/cluster_controller_api_rpc_service.cpp index be0239c1370..bb69c0a8641 100644 --- a/storage/src/vespa/storage/storageserver/rpc/cluster_controller_api_rpc_service.cpp +++ b/storage/src/vespa/storage/storageserver/rpc/cluster_controller_api_rpc_service.cpp @@ -7,6 +7,7 @@ #include <vespa/storage/storageserver/rpcrequestwrapper.h> #include <vespa/vdslib/state/clusterstate.h> #include <vespa/fnet/frt/supervisor.h> +#include <vespa/fnet/frt/require_capabilities.h> #include <vespa/fnet/frt/rpcrequest.h> #include <vespa/storageapi/message/state.h> #include <vespa/vespalib/util/host_name.h> @@ -32,10 +33,21 @@ void ClusterControllerApiRpcService::close() { _closed.store(true); } +namespace { + +std::unique_ptr<FRT_RequireCapabilities> make_cc_api_capability_filter() { + return std::make_unique<FRT_RequireCapabilities>(vespalib::net::tls::CapabilitySet::of({ + vespalib::net::tls::Capability::content_cluster_controller_internal_state_api() + })); +} + +} + void ClusterControllerApiRpcService::register_server_methods(SharedRpcResources& rpc_resources) { FRT_ReflectionBuilder rb(&rpc_resources.supervisor()); rb.DefineMethod("getnodestate3", "sii", "ss", FRT_METHOD(ClusterControllerApiRpcService::RPC_getNodeState2), this); + rb.RequestAccessFilter(make_cc_api_capability_filter()); rb.MethodDesc("Get state of this node"); rb.ParamDesc("nodestate", "Expected state of given node. If correct, the " "request will be queued on target until it changes. To not give " @@ -45,6 +57,7 @@ void ClusterControllerApiRpcService::register_server_methods(SharedRpcResources& rb.ReturnDesc("hostinfo", "Information about host this node is running on"); //------------------------------------------------------------------------- rb.DefineMethod("getnodestate2", "si", "s", FRT_METHOD(ClusterControllerApiRpcService::RPC_getNodeState2), this); + rb.RequestAccessFilter(make_cc_api_capability_filter()); rb.MethodDesc("Get state of this node"); rb.ParamDesc("nodestate", "Expected state of given node. If correct, the " "request will be queued on target until it changes. To not give " @@ -53,21 +66,25 @@ void ClusterControllerApiRpcService::register_server_methods(SharedRpcResources& rb.ReturnDesc("nodestate", "State string for this node"); //------------------------------------------------------------------------- rb.DefineMethod("setsystemstate2", "s", "", FRT_METHOD(ClusterControllerApiRpcService::RPC_setSystemState2), this); + rb.RequestAccessFilter(make_cc_api_capability_filter()); rb.MethodDesc("Set systemstate on this node"); rb.ParamDesc("systemstate", "New systemstate to set"); //------------------------------------------------------------------------- rb.DefineMethod("setdistributionstates", "bix", "", FRT_METHOD(ClusterControllerApiRpcService::RPC_setDistributionStates), this); + rb.RequestAccessFilter(make_cc_api_capability_filter()); rb.MethodDesc("Set distribution states for cluster and bucket spaces"); rb.ParamDesc("compressionType", "Compression type for payload"); rb.ParamDesc("uncompressedSize", "Uncompressed size for payload"); rb.ParamDesc("payload", "Binary Slime format payload"); //------------------------------------------------------------------------- rb.DefineMethod("activate_cluster_state_version", "i", "i", FRT_METHOD(ClusterControllerApiRpcService::RPC_activateClusterStateVersion), this); + rb.RequestAccessFilter(make_cc_api_capability_filter()); rb.MethodDesc("Explicitly activates an already prepared cluster state version"); rb.ParamDesc("activate_version", "Expected cluster state version to activate"); rb.ReturnDesc("actual_version", "Cluster state version that was prepared on the node prior to receiving RPC"); //------------------------------------------------------------------------- rb.DefineMethod("getcurrenttime", "", "lis", FRT_METHOD(ClusterControllerApiRpcService::RPC_getCurrentTime), this); + rb.RequestAccessFilter(make_cc_api_capability_filter()); rb.MethodDesc("Get current time on this node"); rb.ReturnDesc("seconds", "Current time in seconds since epoch"); rb.ReturnDesc("nanoseconds", "additional nanoseconds since epoch"); |