summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeScheduler.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/OsUpgradeSchedulerTest.java33
-rw-r--r--storage/src/vespa/storage/storageserver/rpc/cluster_controller_api_rpc_service.cpp17
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");