Search in sources :

Example 11 with ExtensionUninstaller

use of io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller in project stackgres by ongres.

the class ExtensionReconciliationTest method testReconciliationWithExtensionAlreadyPresent_installIsSkippedButStatusUpdated.

@Test
void testReconciliationWithExtensionAlreadyPresent_installIsSkippedButStatusUpdated() throws Exception {
    StackGresClusterInstalledExtension installedExtension = getInstalledExtension();
    ExtensionReconciliatorContext context = getContext(cluster -> {
        cluster.getSpec().getPostgres().setExtensions(null);
        cluster.getSpec().setToInstallPostgresExtensions(new ArrayList<>());
        cluster.getSpec().getToInstallPostgresExtensions().add(installedExtension);
    });
    when(extensionManager.getExtensionInstaller(any(), any(StackGresClusterInstalledExtension.class))).thenReturn(extensionInstaller);
    when(extensionInstaller.isExtensionInstalled()).thenReturn(true);
    when(extensionInstaller.isLinksCreated()).thenReturn(true);
    Assertions.assertTrue(reconciliator.reconcile(null, context).result().get());
    Assertions.assertTrue(Optional.of(context.getCluster()).map(StackGresCluster::getStatus).map(StackGresClusterStatus::getPodStatuses).stream().flatMap(List::stream).anyMatch(podStatus -> podStatus.getName().equals("test-0")));
    Assertions.assertFalse(context.getCluster().getStatus().getPodStatuses().stream().filter(podStatus -> podStatus.getName().equals("test-0")).findAny().map(StackGresClusterPodStatus::getPendingRestart).orElse(false));
    Assertions.assertIterableEquals(ImmutableList.of(installedExtension), context.getCluster().getStatus().getPodStatuses().stream().filter(podStatus -> podStatus.getName().equals("test-0")).findAny().map(StackGresClusterPodStatus::getInstalledPostgresExtensions).stream().flatMap(List::stream).collect(ImmutableList.toImmutableList()));
    verify(extensionInstaller, times(1)).isExtensionInstalled();
    verify(extensionInstaller, times(1)).isLinksCreated();
    verify(extensionUninstaller, times(0)).isExtensionInstalled();
    verify(extensionInstaller, times(0)).downloadAndExtract();
    verify(extensionInstaller, times(0)).verify();
    verify(extensionInstaller, times(0)).installExtension();
    verify(extensionInstaller, times(0)).createExtensionLinks();
    verify(extensionInstaller, times(0)).doesInstallOverwriteAnySharedLibrary();
    verify(extensionInstaller, times(0)).setExtensionAsPending();
    verify(extensionUninstaller, times(0)).uninstallExtension();
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BeforeEach(org.junit.jupiter.api.BeforeEach) Mock(org.mockito.Mock) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) StackGresClusterList(io.stackgres.common.crd.sgcluster.StackGresClusterList) ArrayList(java.util.ArrayList) ExtensionUninstaller(io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller) ImmutableList(com.google.common.collect.ImmutableList) StackGresClusterInstalledExtension(io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) ExtensionInstaller(io.stackgres.common.extension.ExtensionManager.ExtensionInstaller) MockitoExtension(org.mockito.junit.jupiter.MockitoExtension) Mockito.times(org.mockito.Mockito.times) Mockito.doNothing(org.mockito.Mockito.doNothing) Mockito.when(org.mockito.Mockito.when) JsonUtil(io.stackgres.testutil.JsonUtil) Mockito.verify(org.mockito.Mockito.verify) Consumer(java.util.function.Consumer) Test(org.junit.jupiter.api.Test) StackGresComponent(io.stackgres.common.StackGresComponent) StackGresClusterSpec(io.stackgres.common.crd.sgcluster.StackGresClusterSpec) List(java.util.List) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Assertions(org.junit.jupiter.api.Assertions) Optional(java.util.Optional) StackGresClusterInstalledExtension(io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) StackGresClusterList(io.stackgres.common.crd.sgcluster.StackGresClusterList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) Test(org.junit.jupiter.api.Test)

Example 12 with ExtensionUninstaller

use of io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller in project stackgres by ongres.

the class ExtensionReconciliator method reconcile.

@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "False positives")
public ReconciliationResult<Boolean> reconcile(KubernetesClient client, T context) throws Exception {
    final ImmutableList.Builder<Exception> exceptions = ImmutableList.builder();
    final StackGresCluster cluster = context.getCluster();
    final ImmutableList<StackGresClusterInstalledExtension> extensions = context.getExtensions();
    if (cluster.getStatus() == null) {
        cluster.setStatus(new StackGresClusterStatus());
    }
    if (cluster.getStatus().getPodStatuses() == null) {
        cluster.getStatus().setPodStatuses(new ArrayList<>());
    }
    if (cluster.getStatus().getPodStatuses().stream().noneMatch(podStatus -> podStatus.getName().equals(podName))) {
        StackGresClusterPodStatus podStatus = new StackGresClusterPodStatus();
        podStatus.setName(podName);
        podStatus.setInstalledPostgresExtensions(new ArrayList<>());
        cluster.getStatus().getPodStatuses().add(podStatus);
    }
    final StackGresClusterPodStatus podStatus = cluster.getStatus().getPodStatuses().stream().filter(status -> status.getName().equals(podName)).findAny().get();
    if (podStatus.getInstalledPostgresExtensions() == null) {
        podStatus.setInstalledPostgresExtensions(new ArrayList<>());
    }
    final List<StackGresClusterInstalledExtension> installedExtensions = podStatus.getInstalledPostgresExtensions();
    LOGGER.info("Reconcile postgres extensions...");
    boolean clusterUpdated = false;
    final List<StackGresClusterInstalledExtension> extensionToUninstall = installedExtensions.stream().filter(installedExtension -> extensions.stream().noneMatch(installedExtension::same)).collect(Collectors.toList());
    for (StackGresClusterInstalledExtension installedExtension : extensionToUninstall) {
        ExtensionUninstaller extensionUninstaller = extensionManager.getExtensionUninstaller(context, installedExtension);
        try {
            if (!skipSharedLibrariesOverwrites) {
                if (extensionUninstaller.isExtensionInstalled()) {
                    LOGGER.info("Removing extension {}", ExtensionUtil.getDescription(installedExtension));
                    extensionEventEmitter.emitExtensionRemoved(installedExtension);
                    extensionUninstaller.uninstallExtension();
                }
                installedExtensions.remove(installedExtension);
                clusterUpdated = true;
            } else {
                LOGGER.info("Skip uninstallation of extension {}", ExtensionUtil.getDescription(installedExtension));
                if (!Optional.ofNullable(podStatus.getPendingRestart()).orElse(false)) {
                    podStatus.setPendingRestart(true);
                    clusterUpdated = true;
                }
            }
        } catch (Exception ex) {
            exceptions.add(ex);
            onUninstallException(client, cluster, ExtensionUtil.getDescription(installedExtension), podName, ex);
        }
    }
    for (StackGresClusterInstalledExtension extension : extensions) {
        try {
            final ExtensionInstaller extensionInstaller = Optional.ofNullable(extensionManager.getExtensionInstaller(context, extension)).orElseThrow(() -> new IllegalStateException("Can not find extension " + ExtensionUtil.getDescription(extension)));
            if (!extensionInstaller.isExtensionInstalled() && (!skipSharedLibrariesOverwrites || !extensionInstaller.isExtensionPendingOverwrite())) {
                LOGGER.info("Download extension {}", ExtensionUtil.getDescription(extension));
                extensionEventEmitter.emitExtensionDownloading(extension);
                extensionInstaller.downloadAndExtract();
                LOGGER.info("Verify extension {}", ExtensionUtil.getDescription(extension));
                extensionInstaller.verify();
                if (skipSharedLibrariesOverwrites && extensionInstaller.doesInstallOverwriteAnySharedLibrary()) {
                    LOGGER.info("Skip installation of extension {}", ExtensionUtil.getDescription(extension));
                    if (!extensionInstaller.isExtensionPendingOverwrite()) {
                        extensionInstaller.setExtensionAsPending();
                    }
                    if (!Optional.ofNullable(podStatus.getPendingRestart()).orElse(false)) {
                        extensionEventEmitter.emitExtensionDeployedRestart(extension);
                        podStatus.setPendingRestart(true);
                        clusterUpdated = true;
                    }
                } else {
                    LOGGER.info("Install extension {}", ExtensionUtil.getDescription(extension));
                    extensionInstaller.installExtension();
                    extensionEventEmitter.emitExtensionDeployed(extension);
                }
            } else {
                if (!extensionInstaller.isLinksCreated()) {
                    LOGGER.info("Create links for extension {}", ExtensionUtil.getDescription(extension));
                    extensionInstaller.createExtensionLinks();
                }
            }
            if (installedExtensions.stream().noneMatch(anInstalledExtension -> anInstalledExtension.equals(extension))) {
                installedExtensions.stream().filter(anInstalledExtension -> anInstalledExtension.same(extension)).peek(previousInstalledExtension -> LOGGER.info("Extension upgraded from {} to {}", ExtensionUtil.getDescription(previousInstalledExtension), ExtensionUtil.getDescription(extension))).peek(previousInstalledExtension -> extensionEventEmitter.emitExtensionChanged(previousInstalledExtension, extension)).findAny().ifPresent(installedExtensions::remove);
                installedExtensions.add(extension);
                clusterUpdated = true;
            }
        } catch (Exception ex) {
            exceptions.add(ex);
            onInstallException(client, cluster, ExtensionUtil.getDescription(extension), podName, ex);
        }
    }
    if (!skipSharedLibrariesOverwrites && Optional.ofNullable(podStatus.getPendingRestart()).orElse(false)) {
        podStatus.setPendingRestart(false);
        clusterUpdated = true;
    }
    LOGGER.info("Reconciliation of postgres extensions completed");
    return new ReconciliationResult<>(clusterUpdated, exceptions.build());
}
Also used : StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) ExtensionInstaller(io.stackgres.common.extension.ExtensionManager.ExtensionInstaller) Logger(org.slf4j.Logger) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) ReconciliationResult(io.stackgres.operatorframework.reconciliation.ReconciliationResult) LoggerFactory(org.slf4j.LoggerFactory) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) List(java.util.List) ExtensionUninstaller(io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller) ImmutableList(com.google.common.collect.ImmutableList) StackGresClusterInstalledExtension(io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Optional(java.util.Optional) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) ImmutableList(com.google.common.collect.ImmutableList) StackGresClusterInstalledExtension(io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension) ReconciliationResult(io.stackgres.operatorframework.reconciliation.ReconciliationResult) StackGresClusterPodStatus(io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus) ExtensionInstaller(io.stackgres.common.extension.ExtensionManager.ExtensionInstaller) StackGresCluster(io.stackgres.common.crd.sgcluster.StackGresCluster) StackGresClusterStatus(io.stackgres.common.crd.sgcluster.StackGresClusterStatus) ExtensionUninstaller(io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)12 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)12 StackGresCluster (io.stackgres.common.crd.sgcluster.StackGresCluster)12 StackGresClusterInstalledExtension (io.stackgres.common.crd.sgcluster.StackGresClusterInstalledExtension)12 StackGresClusterPodStatus (io.stackgres.common.crd.sgcluster.StackGresClusterPodStatus)12 StackGresClusterStatus (io.stackgres.common.crd.sgcluster.StackGresClusterStatus)12 ExtensionInstaller (io.stackgres.common.extension.ExtensionManager.ExtensionInstaller)12 ExtensionUninstaller (io.stackgres.common.extension.ExtensionManager.ExtensionUninstaller)12 ArrayList (java.util.ArrayList)12 List (java.util.List)12 Optional (java.util.Optional)12 StackGresComponent (io.stackgres.common.StackGresComponent)11 StackGresClusterList (io.stackgres.common.crd.sgcluster.StackGresClusterList)11 StackGresClusterSpec (io.stackgres.common.crd.sgcluster.StackGresClusterSpec)11 JsonUtil (io.stackgres.testutil.JsonUtil)11 Consumer (java.util.function.Consumer)11 Assertions (org.junit.jupiter.api.Assertions)11 BeforeEach (org.junit.jupiter.api.BeforeEach)11 Test (org.junit.jupiter.api.Test)11 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)11