Skip to content

Owls 91448 - Prevent insecure file system warnings by ensuring files are at a minimum of umask 027 and handle Openshift platform. #2533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions documentation/staging/content/faq/security-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ Warnings may be at the level of the JDK, or that SSL is not enabled. Some warnin
- For Domain in Image, create a new image with the recommended changes or use [configuration overrides]({{< relref "/userguide/managing-domains/configoverrides/_index.md" >}}).

- For Model in Image, supply model files with the recommended changes in its image's `modelHome` directory or use [runtime updates]({{< relref "/userguide/managing-domains/model-in-image/runtime-updates.md" >}}).

{{% notice note %}}
For information about handling file permission warnings on the OpenShift Kubernetes Platform, see the [OpenShift chapter]({{<relref "/security/openshift.md">}}) in the Security section.
{{% /notice %}}

3 changes: 3 additions & 0 deletions documentation/staging/content/security/openshift.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,6 @@ see [OpenShift]({{<relref "/userguide/platforms/environments#openshift">}}).
#### Using a dedicated namespace

When the user that installs an individual instance of the operator does not have the required privileges to create resources at the Kubernetes cluster level, a dedicated namespace can be used for the operator instance and all the WebLogic domains that it manages. For more details about the `dedicated` setting, please refer to [Operator Helm configuration values]({{< relref "/userguide/managing-operators/using-helm#operator-helm-configuration-values" >}}).

#### Set the Helm chart property `kubernetesPlatorm` to `OpenShift`
Beginning with operator version 3.3.2, set the operator `kubernetesPlatform` Helm chart property to `OpenShift`. This property accommodates OpenShift security requirements. For more information, see [Operator Helm configuration values]({{<relref "/userguide/managing-operators/using-helm#operator-helm-configuration-values">}}).
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ Example:
javaLoggingLevel: "FINE"
```

##### `kubernetesPlatform`
Specify the Kubernetes platform on which the operator is running. This setting has no default, the only valid value is OpenShift, and the setting should be left unset for other platforms. When set to `OpenShift`, the operator:
- Sets the domain home file permissions in each WebLogic Server pod to work correctly in OpenShift for [Model in Image]({{< relref "/samples/domains/model-in-image/_index.md" >}}), and [Domain home in Image]({{< relref "/samples/domains/domain-home-in-image/_index.md" >}}) domains. Specifically, it sets file group permissions so that they match file user permissions.
- Sets the `weblogic.SecureMode.WarnOnInsecureFileSystem` Java system property to `false` on the command line of each WebLogic Server. This flag suppresses insecure file system warnings reported in the WebLogic Server console when the WebLogic Server is in production mode. These warnings result from setting the file permissions necessary to work with restricted security context constraints on OpenShift.

For more information about the security requirements for running WebLogic in OpenShift, see the [OpenShift chapter]({{<relref "/security/openshift.md">}}) in the Security section.

Example:
```yaml
kubernetesPlatform: OpenShift
```
#### Creating the operator pod

##### `image`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ Operator 2.0.1+ is certified for use on OpenShift Container Platform 3.11.43+, w

Operator 2.5.0+ is certified for use on OpenShift Container Platform 4.3.0+ with Kubernetes 1.16.2+.

When using the operator in OpenShift, a security context constraint is required to ensure that WebLogic containers run with a UNIX UID that has the correct permissions on the domain file system.
This could be either the `anyuid` SCC or a custom one that you define for user/group `1000`. For more information, see [OpenShift]({{<relref "/security/openshift.md">}}) in the Security section.
To accommodate OpenShift security requirements:
- For security requirements to run WebLogic in OpenShift, see the [OpenShift chapter]({{<relref "/security/openshift.md">}}) in the Security section.
- Beginning with operator version 3.3.2, specify the `kubernetesPlatorm` Helm chart property with value `OpenShift`. For more information, see [Operator Helm configuration values]({{<relref "/userguide/managing-operators/using-helm#operator-helm-configuration-values">}}).

### Important note about development-focused Kubernetes distributions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ data:
{{- if .tokenReviewAuthentication }}
tokenReviewAuthentication: {{ .tokenReviewAuthentication | quote }}
{{- end }}
{{- if .kubernetesPlatform }}
kubernetesPlatform: {{ .kubernetesPlatform | quote }}
{{- end }}
kind: "ConfigMap"
metadata:
labels:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ spec:
value: "false"
- name: "JAVA_LOGGING_LEVEL"
value: {{ .javaLoggingLevel | quote }}
- name: "KUBERNETES_PLATFORM"
value: {{ .kubernetesPlatform | quote }}
- name: "JAVA_LOGGING_MAXSIZE"
value: {{ .javaLoggingFileSizeLimit | default 20000000 | quote }}
- name: "JAVA_LOGGING_COUNT"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ static TuningParameters getInstance() {

FeatureGates getFeatureGates();

String getKubernetesPlatform();

class MainTuning {
public final int initializationRetryDelaySeconds;
public final int domainPresenceFailureRetrySeconds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import oracle.kubernetes.operator.logging.LoggingFactory;
import oracle.kubernetes.operator.logging.MessageKeys;

import static oracle.kubernetes.operator.helpers.BasePodStepContext.KUBERNETES_PLATFORM_HELM_VARIABLE;

public class TuningParametersImpl extends ConfigMapConsumer implements TuningParameters {
public static final int DEFAULT_CALL_LIMIT = 50;

Expand All @@ -28,6 +30,7 @@ public class TuningParametersImpl extends ConfigMapConsumer implements TuningPar
private WatchTuning watch = null;
private PodTuning pod = null;
private FeatureGates featureGates = null;
private String kubernetesPlatform = null;

private TuningParametersImpl(ScheduledExecutorService executorService) {
super(executorService);
Expand Down Expand Up @@ -95,6 +98,8 @@ private void update() {
FeatureGates featureGates =
new FeatureGates(generateFeatureGates(get("featureGates")));

String kubernetesPlatform = get(KUBERNETES_PLATFORM_HELM_VARIABLE);

lock.writeLock().lock();
try {
if (!main.equals(this.main)
Expand All @@ -109,6 +114,7 @@ private void update() {
this.watch = watch;
this.pod = pod;
this.featureGates = featureGates;
this.kubernetesPlatform = kubernetesPlatform;
} finally {
lock.writeLock().unlock();
}
Expand Down Expand Up @@ -175,4 +181,14 @@ public FeatureGates getFeatureGates() {
lock.readLock().unlock();
}
}

@Override
public String getKubernetesPlatform() {
lock.readLock().lock();
try {
return kubernetesPlatform;
} finally {
lock.readLock().unlock();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

public abstract class BasePodStepContext extends StepContextBase {

public static final String KUBERNETES_PLATFORM_HELM_VARIABLE = "kubernetesPlatform";

BasePodStepContext(DomainPresenceInfo info) {
super(info);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ List<V1EnvVar> getConfiguredEnvVars(TuningParameters tuningParameters) {
addEnvVar(vars, IntrospectorJobEnvVars.ISTIO_ENABLED, Boolean.toString(isIstioEnabled()));
addEnvVar(vars, IntrospectorJobEnvVars.ADMIN_CHANNEL_PORT_FORWARDING_ENABLED,
Boolean.toString(isAdminChannelPortForwardingEnabled(getDomain().getSpec())));
Optional.ofNullable(getKubernetesPlatform(tuningParameters))
.ifPresent(v -> addEnvVar(vars, ServerEnvVars.KUBERNETES_PLATFORM, v));

addEnvVar(vars, IntrospectorJobEnvVars.ISTIO_READINESS_PORT, Integer.toString(getIstioReadinessPort()));
addEnvVar(vars, IntrospectorJobEnvVars.ISTIO_POD_NAMESPACE, getNamespace());
if (isUseOnlineUpdate()) {
Expand Down Expand Up @@ -391,6 +394,10 @@ List<V1EnvVar> getConfiguredEnvVars(TuningParameters tuningParameters) {
return vars;
}

private String getKubernetesPlatform(TuningParameters tuningParameters) {
return tuningParameters.getKubernetesPlatform();
}

}

static class DomainIntrospectorJobStep extends Step {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ protected V1PodSpec createSpec(TuningParameters tuningParameters) {
@Override
List<V1EnvVar> getConfiguredEnvVars(TuningParameters tuningParameters) {
List<V1EnvVar> vars = createCopy(getServerSpec().getEnvironmentVariables());
addStartupEnvVars(vars);
addStartupEnvVars(vars, tuningParameters);
return vars;
}

Expand Down Expand Up @@ -526,7 +526,7 @@ List<V1EnvVar> getConfiguredEnvVars(TuningParameters tuningParameters) {
List<V1EnvVar> envVars = createCopy((List<V1EnvVar>) packet.get(ProcessingConstants.ENVVARS));

List<V1EnvVar> vars = new ArrayList<>(envVars);
addStartupEnvVars(vars);
addStartupEnvVars(vars, tuningParameters);
return vars;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ private V1SecretVolumeSource getRuntimeEncryptionSecretVolumeSource(String name)
* Sets the environment variables used by operator/src/main/resources/scripts/startServer.sh
* @param vars a list to which new variables are to be added
*/
void addStartupEnvVars(List<V1EnvVar> vars) {
void addStartupEnvVars(List<V1EnvVar> vars, TuningParameters tuningParameters) {
addEnvVar(vars, ServerEnvVars.DOMAIN_NAME, getDomainName());
addEnvVar(vars, ServerEnvVars.DOMAIN_HOME, getDomainHome());
addEnvVar(vars, ServerEnvVars.ADMIN_NAME, getAsName());
Expand All @@ -929,6 +929,8 @@ void addStartupEnvVars(List<V1EnvVar> vars) {
Optional.ofNullable(getDataHome()).ifPresent(v -> addEnvVar(vars, ServerEnvVars.DATA_HOME, v));
Optional.ofNullable(getServerSpec().getAuxiliaryImages()).ifPresent(cm -> addAuxiliaryImageEnv(cm, vars));
addEnvVarIfTrue(mockWls(), vars, "MOCK_WLS");
Optional.ofNullable(getKubernetesPlatform(tuningParameters)).ifPresent(v ->
addEnvVar(vars, ServerEnvVars.KUBERNETES_PLATFORM, v));
}

protected void addAuxiliaryImageEnv(List<AuxiliaryImage> auxiliaryImageList, List<V1EnvVar> vars) {
Expand Down Expand Up @@ -1079,6 +1081,10 @@ private boolean mockWls() {
return Boolean.getBoolean("mockWLS");
}

private String getKubernetesPlatform(TuningParameters tuningParameters) {
return tuningParameters.getKubernetesPlatform();
}

private abstract class BaseStep extends Step {
BaseStep() {
this(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ public class ServerEnvVars {
/** If present, pod scripts will watch for changes to override configurations and move them into place. */
public static final String DYNAMIC_CONFIG_OVERRIDE = "DYNAMIC_CONFIG_OVERRIDE";

public static final String KUBERNETES_PLATFORM = "KUBERNETES_PLATFORM";

private static final List<String> RESERVED_NAMES = Arrays.asList(
DOMAIN_UID, DOMAIN_NAME, DOMAIN_HOME, NODEMGR_HOME, SERVER_NAME, SERVICE_NAME,
ADMIN_NAME, AS_SERVICE_NAME, ADMIN_PORT, ADMIN_PORT_SECURE, ADMIN_SERVER_PORT_SECURE,
LOG_HOME, SERVER_OUT_IN_POD_LOG, DATA_HOME, ACCESS_LOG_IN_LOG_HOME, DYNAMIC_CONFIG_OVERRIDE);
LOG_HOME, SERVER_OUT_IN_POD_LOG, DATA_HOME, ACCESS_LOG_IN_LOG_HOME, DYNAMIC_CONFIG_OVERRIDE,
KUBERNETES_PLATFORM);

static boolean isReserved(String name) {
return RESERVED_NAMES.contains(name);
Expand Down
4 changes: 4 additions & 0 deletions operator/src/main/resources/scripts/introspectDomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,10 @@ def generate(self):
self.close()

def addDomainConfig(self):
kubernetes_platform = self.env.getEnvOrDef("KUBERNETES_PLATFORM", "")
if (str(kubernetes_platform).upper() == 'OPENSHIFT'):
os.system("chmod -R g=u %s" % self.domain_home)

# Note: only config type is needed fmwconfig, security is excluded because it's in the primordial and contain
# all the many policies files
packcmd = "tar -pczf /tmp/domain.tar.gz %s/config/config.xml %s/config/jdbc/ %s/config/jms %s/config/coherence " \
Expand Down
12 changes: 9 additions & 3 deletions operator/src/main/resources/scripts/modelInImage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ function createModelDomain() {
trace "Using newly created domain"
elif [ -f ${PRIMORDIAL_DOMAIN_ZIPPED} ] ; then
trace "Using existing primordial domain"
cd / && base64 -d ${PRIMORDIAL_DOMAIN_ZIPPED} > ${LOCAL_PRIM_DOMAIN_ZIP} && tar -xzf ${LOCAL_PRIM_DOMAIN_ZIP}
cd / && base64 -d ${PRIMORDIAL_DOMAIN_ZIPPED} > ${LOCAL_PRIM_DOMAIN_ZIP} && tar -pxzf ${LOCAL_PRIM_DOMAIN_ZIP}
# create empty lib since we don't archive it in primordial zip and WDT will fail without it
mkdir ${DOMAIN_HOME}/lib
# Since the SerializedSystem ini is encrypted, restore it first
Expand All @@ -564,7 +564,7 @@ function createModelDomain() {
function restoreDomainConfig() {
restoreEncodedTar "domainzip.secure" || return 1

chmod +x ${DOMAIN_HOME}/bin/*.sh ${DOMAIN_HOME}/*.sh || return 1
chmod u+x ${DOMAIN_HOME}/bin/*.sh ${DOMAIN_HOME}/*.sh || return 1
}

# Expands into the root directory the MII primordial domain, stored in one or more config maps
Expand All @@ -580,7 +580,7 @@ function restoreEncodedTar() {
cat $(ls ${OPERATOR_ROOT}/introspector*/${1} | sort -t- -k3) > /tmp/domain.secure || return 1
base64 -d "/tmp/domain.secure" > /tmp/domain.tar.gz || return 1

tar -xzf /tmp/domain.tar.gz || return 1
tar -pxzf /tmp/domain.tar.gz || return 1
}

# This is before WDT compareModel implementation
Expand Down Expand Up @@ -785,6 +785,12 @@ function createPrimordialDomain() {
local MII_PASSPHRASE=$(cat ${RUNTIME_ENCRYPTION_SECRET_PASSWORD})
encrypt_decrypt_domain_secret "encrypt" ${DOMAIN_HOME} ${MII_PASSPHRASE}

if [[ "${KUBERNETES_PLATFORM^^}" == "OPENSHIFT" ]]; then
# Operator running on Openshift platform - change file permissions in the DOMAIN_HOME dir to give
# group same permissions as user .
chmod -R g=u ${DOMAIN_HOME} || return 1
fi

tar -pczf ${LOCAL_PRIM_DOMAIN_ZIP} --exclude ${DOMAIN_HOME}/wlsdeploy --exclude ${DOMAIN_HOME}/sysman/log \
--exclude ${DOMAIN_HOME}/lib --exclude ${DOMAIN_HOME}/backup_config ${empath} ${DOMAIN_HOME}/*

Expand Down
14 changes: 14 additions & 0 deletions operator/src/main/resources/scripts/startServer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ createFolder ${DOMAIN_HOME}/servers/${SERVER_NAME}/security
copyIfChanged /weblogic-operator/introspector/boot.properties \
${DOMAIN_HOME}/servers/${SERVER_NAME}/security/boot.properties

# remove write and execute permissions for group to prevent insecure file system warnings.
chmod g-wx ${DOMAIN_HOME}/servers/${SERVER_NAME}/security/boot.properties


if [ ${DOMAIN_SOURCE_TYPE} != "FromModel" ]; then
trace "Copying situational configuration files from operator cm to ${DOMAIN_HOME}/optconfig directory"
copySitCfgWhileBooting /weblogic-operator/introspector ${DOMAIN_HOME}/optconfig 'Sit-Cfg-CFG--'
Expand All @@ -298,6 +302,16 @@ if [ ${DOMAIN_SOURCE_TYPE} != "FromModel" ]; then
copySitCfgWhileBooting /weblogic-operator/introspector ${DOMAIN_HOME}/optconfig/diagnostics 'Sit-Cfg-WLDF--'
fi

if [[ "${KUBERNETES_PLATFORM^^}" == "OPENSHIFT" ]]; then
# When the Operator is running on Openshift platform, disable insecure file system warnings.
export JAVA_OPTIONS="-Dweblogic.SecureMode.WarnOnInsecureFileSystem=false $JAVA_OPTIONS"
if [[ "${DOMAIN_SOURCE_TYPE}" == "Image" ]]; then
# Change the file permissions in the DOMAIN_HOME dir to give group same permissions as user .
chmod -R g=u ${DOMAIN_HOME} || return 1
fi

fi

#
# Start WLS
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import static oracle.kubernetes.operator.DomainProcessorTestSetup.createTestDomain;
import static oracle.kubernetes.operator.ProcessingConstants.DOMAIN_TOPOLOGY;
import static oracle.kubernetes.operator.ProcessingConstants.JOBWATCHER_COMPONENT_NAME;
import static oracle.kubernetes.operator.helpers.BasePodStepContext.KUBERNETES_PLATFORM_HELM_VARIABLE;
import static oracle.kubernetes.operator.helpers.Matchers.hasConfigMapVolume;
import static oracle.kubernetes.operator.helpers.Matchers.hasContainer;
import static oracle.kubernetes.operator.helpers.Matchers.hasEnvVar;
Expand Down Expand Up @@ -985,6 +986,25 @@ void whenNotConfigured_introspectorPodSpec_hasTrueAccessLogInLogHomeEnvVar() {
);
}

@Test
void whenOperatorHasKubernetesPlatformConfigured_introspectorPodSpecHasKubernetesPlatformEnvVariable() {
TuningParametersStub.setParameter(KUBERNETES_PLATFORM_HELM_VARIABLE, "Openshift");
V1JobSpec jobSpec = createJobSpec();

assertThat(getMatchingContainerEnv(domainPresenceInfo, jobSpec),
hasEnvVar(ServerEnvVars.KUBERNETES_PLATFORM, "Openshift")
);
}

@Test
void whenNotConfigured_KubernetesPlatform_introspectorPodSpecHasNoKubernetesPlatformEnvVariable() {
V1JobSpec jobSpec = createJobSpec();

assertThat(getMatchingContainerEnv(domainPresenceInfo, jobSpec),
not(hasEnvVar(ServerEnvVars.KUBERNETES_PLATFORM, "Openshift"))
);
}

@Test
void whenNoExistingTopologyRunIntrospector() {
runCreateJob();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
import static oracle.kubernetes.operator.ProcessingConstants.MII_DYNAMIC_UPDATE_SUCCESS;
import static oracle.kubernetes.operator.ProcessingConstants.SERVER_SCAN;
import static oracle.kubernetes.operator.helpers.AnnotationHelper.SHA256_ANNOTATION;
import static oracle.kubernetes.operator.helpers.BasePodStepContext.KUBERNETES_PLATFORM_HELM_VARIABLE;
import static oracle.kubernetes.operator.helpers.DomainIntrospectorJobTest.TEST_VOLUME_NAME;
import static oracle.kubernetes.operator.helpers.DomainStatusMatcher.hasStatus;
import static oracle.kubernetes.operator.helpers.EventHelper.EventItem.DOMAIN_ROLL_STARTING;
Expand Down Expand Up @@ -1077,6 +1078,21 @@ void whenPodCreated_withLivenessCustomScriptSpecified_hasEnvVariable() {
assertThat(getCreatedPodSpecContainer().getEnv(), hasEnvVar("LIVENESS_PROBE_CUSTOM_SCRIPT", customScript));
}

@Test
void whenOperatorHasKubernetesPlatformConfigured_createdPodSpecContainerHasKubernetesPlatformEnvVariable() {
TuningParametersStub.setParameter(KUBERNETES_PLATFORM_HELM_VARIABLE, "Openshift");
assertThat(getCreatedPodSpecContainer().getEnv(),
hasEnvVar(ServerEnvVars.KUBERNETES_PLATFORM, "Openshift")
);
}

@Test
void whenNotConfigured_KubernetesPlatform_createdPodSpecContainerHasNoKubernetesPlatformEnvVariable() {
assertThat(getCreatedPodSpecContainer().getEnv(),
not(hasEnvVar(ServerEnvVars.KUBERNETES_PLATFORM, "Openshift"))
);
}

private static final String OVERRIDE_DATA_DIR = "/u01/data";
private static final String OVERRIDE_DATA_HOME = OVERRIDE_DATA_DIR + File.separator + UID;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,9 @@ public Set<Entry<String, String>> entrySet() {
public FeatureGates getFeatureGates() {
return new FeatureGates(Collections.singletonList(ENABLED_FEATURE));
}

@Override
public String getKubernetesPlatform() {
return namedParameters.get("kubernetesPlatform");
}
}
8 changes: 4 additions & 4 deletions operator/src/test/sh/modelInImageTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ testOnRestoreDomainConfig_base64DecodeZip() {
testOnRestoreDomainConfig_unTarDomain() {
restoreDomainConfig

assertEquals "TAR command arguments" "-xzf /tmp/domain.tar.gz" "$TAR_ARGS"
assertEquals "TAR command arguments" "-pxzf /tmp/domain.tar.gz" "$TAR_ARGS"
}

testOnRestoreDomainConfig_makeScriptsExecutable() {
restoreDomainConfig

assertEquals "CD command arguments" "+x ${DOMAIN_HOME}/bin/*.sh ${DOMAIN_HOME}/*.sh" "$CHMOD_ARGS"
assertEquals "CD command arguments" "u+x ${DOMAIN_HOME}/bin/*.sh ${DOMAIN_HOME}/*.sh" "$CHMOD_ARGS"
}

testOnRestorePrimordialDomain_useRootDirectory() {
Expand Down Expand Up @@ -119,7 +119,7 @@ testOnRestoreDomainConfig_whenNoIndexesDefinedCatSingleFile() {
testOnRestorePrimordialDomain_unTarDomain() {
restorePrimordialDomain

assertEquals "TAR command arguments" "-xzf /tmp/domain.tar.gz" "$TAR_ARGS"
assertEquals "TAR command arguments" "-pxzf /tmp/domain.tar.gz" "$TAR_ARGS"
}

######################### Mocks for the tests ###############
Expand Down Expand Up @@ -168,4 +168,4 @@ chmod() {
. ${SCRIPTPATH}/modelInImage.sh

# shellcheck source=target/classes/shunit/shunit2
. ${SHUNIT2_PATH}
. ${SHUNIT2_PATH}