use of io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState in project stackgres by ongres.
the class MinorVersionUpgradeRestartStateHandlerImpl method initRestartStatusValues.
@Override
protected Uni<Void> initRestartStatusValues(ClusterRestartState clusterRestartState, StackGresCluster cluster) {
return super.initRestartStatusValues(clusterRestartState, cluster).chain(ignore -> Uni.combine().all().unis(getSourcePostgresVersion(cluster), getTargetPostgresVersion(cluster)).asTuple()).chain(versionTuple -> {
StackGresClusterDbOpsMinorVersionUpgradeStatus restartStatus = cluster.getStatus().getDbOps().getMinorVersionUpgrade();
restartStatus.setSourcePostgresVersion(versionTuple.getItem1());
restartStatus.setTargetPostgresVersion(versionTuple.getItem2());
return Uni.createFrom().voidItem();
});
}
use of io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState in project stackgres by ongres.
the class ClusterStateHandlerTest method buildRestartState_shouldNotFail.
@Test
void buildRestartState_shouldNotFail() {
podTestUtil.preparePods(cluster, 0, 1, 2);
var pods = podTestUtil.getClusterPods(cluster);
final Pod primaryPod = pods.stream().filter(pod -> pod.getMetadata().getName().endsWith("-0")).findAny().get();
final Pod replica1Pod = pods.stream().filter(pod -> pod.getMetadata().getName().endsWith("-1")).findAny().get();
initializeDbOpsStatus(dbOps, pods);
dbOps = kubeDb.addOrReplaceDbOps(dbOps);
var expectedClusterState = ImmutableClusterRestartState.builder().namespace(dbOps.getMetadata().getNamespace()).dbOpsName(dbOps.getMetadata().getName()).dbOpsOperation(dbOps.getSpec().getOp()).clusterName(dbOps.getSpec().getSgCluster()).isOnlyPendingRestart(false).restartMethod(dbOps.getSpec().getSecurityUpgrade().getMethod()).isSwitchoverInitiated(Boolean.FALSE).isSwitchoverFinalized(Boolean.FALSE).primaryInstance(primaryPod).addInitialInstances(primaryPod, replica1Pod).addRestartedInstances(replica1Pod).addAllTotalInstances(pods).putAllPodRestartReasonsMap(pods.stream().collect(ImmutableMap.toImmutableMap(Function.identity(), pod -> RestartReasons.of()))).build();
var clusterRestartState = getRestartStateHandler().restartCluster(dbOps).await().atMost(Duration.ofMillis(50));
assertEqualsRestartState(expectedClusterState, clusterRestartState);
}
use of io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState in project stackgres by ongres.
the class AbstractRestartStateHandler method buildClusterRestartState.
protected ClusterRestartState buildClusterRestartState(StackGresDbOps dbOps, StackGresCluster cluster, Optional<StatefulSet> statefulSet, List<Pod> clusterPods) {
DbOpsRestartStatus restartStatus = getDbOpRestartStatus(dbOps);
Map<String, Pod> podsDict = clusterPods.stream().collect(Collectors.toMap(pod -> pod.getMetadata().getName(), Function.identity()));
var initialInstances = Optional.ofNullable(restartStatus.getInitialInstances()).map(instances -> instances.stream().map(podsDict::get).collect(Collectors.toUnmodifiableList())).orElse(clusterPods);
var restartedInstances = Optional.ofNullable(restartStatus.getRestartedInstances()).map(instances -> instances.stream().map(podsDict::get).collect(Collectors.toUnmodifiableList())).orElse(List.of());
var podRestartReasonsMap = clusterPods.stream().collect(Collectors.toUnmodifiableMap(Function.identity(), pod -> getPodRestartReasons(cluster, statefulSet, pod)));
final String method = getRestartMethod(dbOps).orElse(REDUCED_IMPACT_METHOD);
final boolean onlyPendingRestart = Optional.of(dbOps.getSpec()).map(StackGresDbOpsSpec::getRestart).map(StackGresDbOpsRestart::getOnlyPendingRestart).orElse(false);
return ImmutableClusterRestartState.builder().namespace(dbOps.getMetadata().getNamespace()).dbOpsName(dbOps.getMetadata().getName()).dbOpsOperation(dbOps.getSpec().getOp()).clusterName(cluster.getMetadata().getName()).restartMethod(method).isOnlyPendingRestart(onlyPendingRestart).primaryInstance(getPrimaryInstance(clusterPods)).isSwitchoverInitiated(restartStatus.getSwitchoverInitiated() != null).isSwitchoverFinalized(restartStatus.getSwitchoverFinalized() != null).initialInstances(initialInstances).restartedInstances(restartedInstances).totalInstances(clusterPods).podRestartReasonsMap(podRestartReasonsMap).build();
}
use of io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState in project stackgres by ongres.
the class DbOpLauncherImpl method launchDbOp.
@Override
public void launchDbOp(String dbOpName, String namespace) {
StackGresDbOps dbOps = dbOpsFinder.findByNameAndNamespace(dbOpName, namespace).orElseThrow(() -> new IllegalArgumentException(StackGresDbOps.KIND + " " + dbOpName + " does not exists in namespace " + namespace));
Instance<DatabaseOperationJob> jobImpl = instance.select(new DatabaseOperationLiteral(dbOps.getSpec().getOp()));
if (jobImpl.isResolvable()) {
LOGGER.info("Initializing conditions for SgDbOps {}", dbOps.getMetadata().getName());
var status = Optional.ofNullable(dbOps.getStatus()).or(() -> Optional.of(new StackGresDbOpsStatus())).map(dbOpsStatus -> {
dbOpsStatus.setOpStarted(Instant.now().toString());
dbOpsStatus.setOpRetries(Optional.ofNullable(dbOpsStatus.getOpRetries()).map(opRetries -> opRetries + 1).orElse(0));
dbOpsStatus.setConditions(getStartingConditions());
return dbOpsStatus;
}).orElseThrow();
dbOps.setStatus(status);
final StackGresDbOps initializedDbOps = dbOpsScheduler.update(dbOps);
try {
final int lockPollInterval = Integer.parseInt(DBOPS_LOCK_POLL_INTERVAL.getString());
final int timeout = Integer.parseInt(DBOPS_LOCK_TIMEOUT.getString());
LockRequest lockRequest = ImmutableLockRequest.builder().namespace(initializedDbOps.getMetadata().getNamespace()).serviceAccount(JobsProperty.SERVICE_ACCOUNT.getString()).podName(JobsProperty.POD_NAME.getString()).pollInterval(lockPollInterval).timeout(timeout).lockResourceName(initializedDbOps.getSpec().getSgCluster()).build();
Infrastructure.setDroppedExceptionHandler(err -> LOGGER.error("Dropped exception ", err));
lockAcquirer.lockRun(lockRequest, (targetCluster) -> {
databaseOperationEventEmitter.operationStarted(dbOpName, namespace);
final DatabaseOperationJob databaseOperationJob = jobImpl.get();
Uni<ClusterRestartState> jobUni = databaseOperationJob.runJob(initializedDbOps, targetCluster);
if (initializedDbOps.getSpec().getTimeout() != null) {
jobUni.await().atMost(Duration.parse(initializedDbOps.getSpec().getTimeout()));
} else {
jobUni.await().indefinitely();
}
databaseOperationEventEmitter.operationCompleted(dbOpName, namespace);
});
LOGGER.info("Operation completed for SgDbOp {}", dbOpName);
updateToCompletedConditions(dbOpName, namespace);
} catch (TimeoutException timeoutEx) {
updateToTimeoutConditions(dbOpName, namespace);
databaseOperationEventEmitter.operationTimedOut(dbOpName, namespace);
throw timeoutEx;
} catch (Exception e) {
updateToFailedConditions(dbOpName, namespace);
databaseOperationEventEmitter.operationFailed(dbOpName, namespace);
throw e;
}
} else if (jobImpl.isAmbiguous()) {
throw new IllegalStateException("Multiple implementations of the operation " + dbOps.getSpec().getOp() + " found");
} else {
throw new IllegalStateException("Implementation of operation " + dbOps.getSpec().getOp() + " not found");
}
}
Aggregations