diff --git a/java/coherence-operator/src/main/java/com/oracle/coherence/k8s/CoherenceOperatorLifecycleListener.java b/java/coherence-operator/src/main/java/com/oracle/coherence/k8s/CoherenceOperatorLifecycleListener.java index 867501ac..cfa27832 100644 --- a/java/coherence-operator/src/main/java/com/oracle/coherence/k8s/CoherenceOperatorLifecycleListener.java +++ b/java/coherence-operator/src/main/java/com/oracle/coherence/k8s/CoherenceOperatorLifecycleListener.java @@ -282,8 +282,21 @@ void initCohCtl() { String defaultProtocol = provider == null || provider.isEmpty() ? "http" : "https"; String protocol = Config.getProperty("coherence.operator.cli.protocol", defaultProtocol); String home = System.getProperty("user.home"); + File fileHome = new File(home); String connectionType = "http"; + if (!fileHome.exists() || !fileHome.isDirectory()) { + LOGGER.info("CoherenceOperator: user home \"" + home + + "\" does not exist, creating default cohctl config at /coherence-operator/utils"); + home = "/coherence-operator/utils"; + fileHome = new File(home); + } + + if (!fileHome.exists() || !fileHome.isDirectory()) { + LOGGER.error("CoherenceOperator: Cannot create cohctl config, directory " + home + " does not exist"); + return; + } + File cohctlHome = new File(home + File.separator + ".cohctl"); File configFile = new File(cohctlHome, "cohctl.yaml"); @@ -320,7 +333,7 @@ void initCohCtl() { } } catch (Exception e) { - LOGGER.error(e, "Coherence Operator: Failed to create default cohctl config"); + LOGGER.error("Coherence Operator: Failed to create default cohctl config. " + e.getMessage()); } } } diff --git a/pkg/runner/cmd_initialise.go b/pkg/runner/cmd_initialise.go index df7d76e1..23f02277 100644 --- a/pkg/runner/cmd_initialise.go +++ b/pkg/runner/cmd_initialise.go @@ -88,9 +88,11 @@ func initialiseWithEnv(cmd *cobra.Command, getEnv EnvFunction) (bool, error) { persistenceTrashDir := persistenceDir + pathSep + "trash" persistenceSnapshotsDir := persistenceDir + pathSep + "snapshots" - snapshotDir, err := flagSet.GetString(ArgSnapshotsDir) - if err != nil { - return false, err + clusterName := getEnv(v1.EnvVarCohClusterName) + if clusterName != "" { + persistenceActiveDir = persistenceActiveDir + pathSep + clusterName + persistenceTrashDir = persistenceTrashDir + pathSep + clusterName + persistenceSnapshotsDir = persistenceSnapshotsDir + pathSep + clusterName } fmt.Println("Starting container initialisation") @@ -168,32 +170,12 @@ func initialiseWithEnv(cmd *cobra.Command, getEnv EnvFunction) (bool, error) { dirNames = append(dirNames, persistenceActiveDir, persistenceTrashDir, persistenceSnapshotsDir) } - _, err = os.Stat(snapshotDir) - if err == nil { - // if "/snapshot" exists then we'll create the cluster snapshot directory - clusterName := getEnv(v1.EnvVarCohClusterName) - if clusterName != "" { - snapshotClusterDir := pathSep + "snapshot" + pathSep + clusterName - dirNames = append(dirNames, snapshotClusterDir) - } - } - for _, dirName := range dirNames { fmt.Printf("Creating directory %s\n", dirName) err = os.MkdirAll(dirName, os.ModePerm) if err != nil { return false, err } - info, err := os.Stat(dirName) - if err != nil { - return false, err - } - if info.Mode().Perm() != os.ModePerm { - err = os.Chmod(dirName, os.ModePerm) - if err != nil { - return false, err - } - } } fmt.Println("Finished container initialisation") diff --git a/test/e2e/remote/persistence-active-snapshot-security.yaml b/test/e2e/remote/persistence-active-snapshot-security.yaml new file mode 100644 index 00000000..e811cf47 --- /dev/null +++ b/test/e2e/remote/persistence-active-snapshot-security.yaml @@ -0,0 +1,46 @@ +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: snapshot-cluster +spec: + role: one + replicas: 1 + image: ${TEST_APPLICATION_IMAGE} + imagePullPolicy: ${TEST_IMAGE_PULL_POLICY} + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: "OnRootMismatch" + readinessProbe: + initialDelaySeconds: 10 + periodSeconds: 10 + coherence: + cacheConfig: test-cache-config.xml + management: + enabled: true + persistence: + mode: active + persistentVolumeClaim: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + snapshots: + persistentVolumeClaim: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + jvm: + args: + - "-Dcoherence.k8s.operator.health.logs=true" + application: + main: com.oracle.coherence.k8s.testing.RestServer + ports: + - name: management + port: 30000 + - name: rest + port: 8080 diff --git a/test/e2e/remote/persistence_test.go b/test/e2e/remote/persistence_test.go index 1ebd3e03..71f6b68c 100644 --- a/test/e2e/remote/persistence_test.go +++ b/test/e2e/remote/persistence_test.go @@ -70,6 +70,16 @@ func TestSnapshotWithActivePersistence(t *testing.T) { assertPersistence("persistence-active-snapshot.yaml", "snapshot-volume", true, true, true, t) } +// Deploy a Coherence resource with both persistence and snapshot configured and a securityContext so +// that the container is not running as the root user. +// Persistence will be active, a PVC will be created for the StatefulSet. Put data in a cache, take a snapshot, +// delete the deployment, re-deploy the deployment, recover the snapshot, assert that the data is recovered. +func TestSnapshotWithActivePersistenceWithSecurityContext(t *testing.T) { + // Make sure we defer clean-up when we're done!! + testContext.CleanupAfterTest(t) + assertPersistence("persistence-active-snapshot-security.yaml", "snapshot-volume", true, true, true, t) +} + func assertPersistence(yamlFile, pVolName string, isSnapshot, isClearCanary, isRestart bool, t *testing.T) { g := NewGomegaWithT(t) ns := helper.GetTestNamespace()