Search in sources :

Example 1 with ClusterRestartState

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();
    });
}
Also used : StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) StackGresClusterDbOpsStatus(io.stackgres.common.crd.sgcluster.StackGresClusterDbOpsStatus) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) StackGresDbOpsMinorVersionUpgrade(io.stackgres.common.crd.sgdbops.StackGresDbOpsMinorVersionUpgrade) PatroniApiHandler(io.stackgres.jobs.dbops.clusterrestart.PatroniApiHandler) StackGresClusterDbOpsMinorVersionUpgradeStatus(io.stackgres.common.crd.sgcluster.StackGresClusterDbOpsMinorVersionUpgradeStatus) DbOpsRestartStatus(io.stackgres.common.crd.sgdbops.DbOpsRestartStatus) ClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState) StackGresDbOps(io.stackgres.common.crd.sgdbops.StackGresDbOps) Uni(io.smallrye.mutiny.Uni) AbstractRestartStateHandler(io.stackgres.jobs.dbops.AbstractRestartStateHandler) Inject(javax.inject.Inject) StackGresDbOpsMinorVersionUpgradeStatus(io.stackgres.common.crd.sgdbops.StackGresDbOpsMinorVersionUpgradeStatus) ClusterDbOpsRestartStatus(io.stackgres.common.crd.sgcluster.ClusterDbOpsRestartStatus) Optional(java.util.Optional) StackGresDbOpsStatus(io.stackgres.common.crd.sgdbops.StackGresDbOpsStatus) PatroniInformation(io.stackgres.jobs.dbops.clusterrestart.PatroniInformation) ApplicationScoped(javax.enterprise.context.ApplicationScoped) StateHandler(io.stackgres.jobs.dbops.StateHandler) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) StackGresDbOpsSpec(io.stackgres.common.crd.sgdbops.StackGresDbOpsSpec) StackGresClusterDbOpsMinorVersionUpgradeStatus(io.stackgres.common.crd.sgcluster.StackGresClusterDbOpsMinorVersionUpgradeStatus)

Example 2 with ClusterRestartState

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);
}
Also used : StackGresContext(io.stackgres.common.StackGresContext) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) WithKubernetesTestServer(io.quarkus.test.kubernetes.client.WithKubernetesTestServer) MockKubeDb(io.stackgres.jobs.dbops.lock.MockKubeDb) StringUtils(io.stackgres.testutil.StringUtils) Tuple2(org.jooq.lambda.tuple.Tuple2) Duration(java.time.Duration) ImmutableRestartEvent(io.stackgres.jobs.dbops.clusterrestart.ImmutableRestartEvent) RestartReasons(io.stackgres.common.ClusterPendingRestartUtil.RestartReasons) ImmutableMap(com.google.common.collect.ImmutableMap) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) PodTestUtil(io.stackgres.jobs.dbops.clusterrestart.PodTestUtil) Test(org.junit.jupiter.api.Test) List(java.util.List) Tuple(org.jooq.lambda.tuple.Tuple) Mockito.inOrder(org.mockito.Mockito.inOrder) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) Optional(java.util.Optional) ClusterRestartImpl(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartImpl) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) DbOpsRestartStatus(io.stackgres.common.crd.sgdbops.DbOpsRestartStatus) InvalidCluster(io.stackgres.jobs.dbops.clusterrestart.InvalidCluster) Seq(org.jooq.lambda.Seq) Mockito.lenient(org.mockito.Mockito.lenient) Function(java.util.function.Function) Multi(io.smallrye.mutiny.Multi) StackGresDbOps(io.stackgres.common.crd.sgdbops.StackGresDbOps) RestartEventType(io.stackgres.jobs.dbops.clusterrestart.RestartEventType) Inject(javax.inject.Inject) ImmutableClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ImmutableClusterRestartState) ClusterDbOpsRestartStatus(io.stackgres.common.crd.sgcluster.ClusterDbOpsRestartStatus) StackGresDbOpsStatus(io.stackgres.common.crd.sgdbops.StackGresDbOpsStatus) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) InjectMock(io.quarkus.test.junit.mockito.InjectMock) DbOpsEventEmitter(io.stackgres.common.event.DbOpsEventEmitter) InOrder(org.mockito.InOrder) Lists(org.apache.commons.compress.utils.Lists) Pod(io.fabric8.kubernetes.api.model.Pod) Mockito.when(org.mockito.Mockito.when) ClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState) JsonUtil(io.stackgres.testutil.JsonUtil) Comparator(java.util.Comparator) PodTestUtil.assertPodEquals(io.stackgres.jobs.dbops.clusterrestart.PodTestUtil.assertPodEquals) Pod(io.fabric8.kubernetes.api.model.Pod) Test(org.junit.jupiter.api.Test)

Example 3 with 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();
}
Also used : StackGresContext(io.stackgres.common.StackGresContext) StackGresDbOpsRestart(io.stackgres.common.crd.sgdbops.StackGresDbOpsRestart) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) LoggerFactory(org.slf4j.LoggerFactory) DbOpsRestartStatus(io.stackgres.common.crd.sgdbops.DbOpsRestartStatus) InvalidCluster(io.stackgres.jobs.dbops.clusterrestart.InvalidCluster) Function(java.util.function.Function) StackGresDbOps(io.stackgres.common.crd.sgdbops.StackGresDbOps) RestartEvent(io.stackgres.jobs.dbops.clusterrestart.RestartEvent) ArrayList(java.util.ArrayList) Uni(io.smallrye.mutiny.Uni) Inject(javax.inject.Inject) ImmutableClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ImmutableClusterRestartState) ImmutableList(com.google.common.collect.ImmutableList) Duration(java.time.Duration) Map(java.util.Map) ClusterDbOpsRestartStatus(io.stackgres.common.crd.sgcluster.ClusterDbOpsRestartStatus) CustomResourceFinder(io.stackgres.common.resource.CustomResourceFinder) StackGresDbOpsSpec(io.stackgres.common.crd.sgdbops.StackGresDbOpsSpec) StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) REDUCED_IMPACT_METHOD(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartImpl.REDUCED_IMPACT_METHOD) RestartReasons(io.stackgres.common.ClusterPendingRestartUtil.RestartReasons) Logger(org.slf4j.Logger) EventEmitter(io.stackgres.common.event.EventEmitter) ClusterRestart(io.stackgres.jobs.dbops.clusterrestart.ClusterRestart) ClusterRestartStateHandlerImpl(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartStateHandlerImpl) LabelFactoryForCluster(io.stackgres.common.LabelFactoryForCluster) Pod(io.fabric8.kubernetes.api.model.Pod) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) ClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState) List(java.util.List) CustomResourceScheduler(io.stackgres.common.resource.CustomResourceScheduler) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) ResourceScanner(io.stackgres.common.resource.ResourceScanner) Optional(java.util.Optional) ResourceFinder(io.stackgres.common.resource.ResourceFinder) NotNull(org.jetbrains.annotations.NotNull) ClusterPendingRestartUtil(io.stackgres.common.ClusterPendingRestartUtil) Pod(io.fabric8.kubernetes.api.model.Pod) StackGresDbOpsSpec(io.stackgres.common.crd.sgdbops.StackGresDbOpsSpec) DbOpsRestartStatus(io.stackgres.common.crd.sgdbops.DbOpsRestartStatus) ClusterDbOpsRestartStatus(io.stackgres.common.crd.sgcluster.ClusterDbOpsRestartStatus)

Example 4 with ClusterRestartState

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");
    }
}
Also used : LockRequest(io.stackgres.jobs.dbops.lock.LockRequest) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) LoggerFactory(org.slf4j.LoggerFactory) StackGresDbOpsCondition(io.stackgres.common.crd.sgdbops.StackGresDbOpsCondition) JobsProperty(io.stackgres.jobs.app.JobsProperty) LockAcquirer(io.stackgres.jobs.dbops.lock.LockAcquirer) StackGresDbOps(io.stackgres.common.crd.sgdbops.StackGresDbOps) Uni(io.smallrye.mutiny.Uni) Inject(javax.inject.Inject) Duration(java.time.Duration) StackGresDbOpsStatus(io.stackgres.common.crd.sgdbops.StackGresDbOpsStatus) CustomResourceFinder(io.stackgres.common.resource.CustomResourceFinder) Any(javax.enterprise.inject.Any) Instance(javax.enterprise.inject.Instance) Infrastructure(io.smallrye.mutiny.infrastructure.Infrastructure) Logger(org.slf4j.Logger) ImmutableLockRequest(io.stackgres.jobs.dbops.lock.ImmutableLockRequest) TimeoutException(io.smallrye.mutiny.TimeoutException) Instant(java.time.Instant) ClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState) DBOPS_LOCK_TIMEOUT(io.stackgres.jobs.app.JobsProperty.DBOPS_LOCK_TIMEOUT) DbOpsStatusCondition(io.stackgres.common.crd.sgdbops.DbOpsStatusCondition) List(java.util.List) DBOPS_LOCK_POLL_INTERVAL(io.stackgres.jobs.app.JobsProperty.DBOPS_LOCK_POLL_INTERVAL) CustomResourceScheduler(io.stackgres.common.resource.CustomResourceScheduler) DateTimeFormatter(java.time.format.DateTimeFormatter) Optional(java.util.Optional) ApplicationScoped(javax.enterprise.context.ApplicationScoped) StackGresDbOps(io.stackgres.common.crd.sgdbops.StackGresDbOps) TimeoutException(io.smallrye.mutiny.TimeoutException) StackGresDbOpsStatus(io.stackgres.common.crd.sgdbops.StackGresDbOpsStatus) ClusterRestartState(io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState) LockRequest(io.stackgres.jobs.dbops.lock.LockRequest) ImmutableLockRequest(io.stackgres.jobs.dbops.lock.ImmutableLockRequest) TimeoutException(io.smallrye.mutiny.TimeoutException)

Aggregations

StackGresCluster (io.stackgres.common.crd.sgcluster.StackGresCluster)4 StackGresDbOps (io.stackgres.common.crd.sgdbops.StackGresDbOps)4 ClusterRestartState (io.stackgres.jobs.dbops.clusterrestart.ClusterRestartState)4 Optional (java.util.Optional)4 Inject (javax.inject.Inject)4 Uni (io.smallrye.mutiny.Uni)3 ClusterDbOpsRestartStatus (io.stackgres.common.crd.sgcluster.ClusterDbOpsRestartStatus)3 DbOpsRestartStatus (io.stackgres.common.crd.sgdbops.DbOpsRestartStatus)3 StackGresDbOpsStatus (io.stackgres.common.crd.sgdbops.StackGresDbOpsStatus)3 Duration (java.time.Duration)3 Instant (java.time.Instant)3 List (java.util.List)3 HasMetadata (io.fabric8.kubernetes.api.model.HasMetadata)2 ObjectMeta (io.fabric8.kubernetes.api.model.ObjectMeta)2 Pod (io.fabric8.kubernetes.api.model.Pod)2 RestartReasons (io.stackgres.common.ClusterPendingRestartUtil.RestartReasons)2 StackGresContext (io.stackgres.common.StackGresContext)2 StackGresClusterStatus (io.stackgres.common.crd.sgcluster.StackGresClusterStatus)2 StackGresDbOpsSpec (io.stackgres.common.crd.sgdbops.StackGresDbOpsSpec)2 CustomResourceFinder (io.stackgres.common.resource.CustomResourceFinder)2