Browse Source

HPCC-23560 Add build-time flag for containerized mode

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 5 years ago
parent
commit
9ed3df170d

+ 7 - 5
CMakeLists.txt

@@ -167,8 +167,6 @@ elseif ( NOT MAKE_DOCS_ONLY )
     HPCC_ADD_SUBDIRECTORY (tools)
     HPCC_ADD_SUBDIRECTORY (common)
     HPCC_ADD_SUBDIRECTORY (dali)
-    HPCC_ADD_SUBDIRECTORY (deploy)
-    HPCC_ADD_SUBDIRECTORY (deployment)
     HPCC_ADD_SUBDIRECTORY (ecl)
     HPCC_ADD_SUBDIRECTORY (ecllibrary)
     HPCC_ADD_SUBDIRECTORY (esp)
@@ -178,9 +176,13 @@ elseif ( NOT MAKE_DOCS_ONLY )
     HPCC_ADD_SUBDIRECTORY (rtl)
     HPCC_ADD_SUBDIRECTORY (services "PLATFORM")
     HPCC_ADD_SUBDIRECTORY (thorlcr "PLATFORM")
-    HPCC_ADD_SUBDIRECTORY (testing)
-    HPCC_ADD_SUBDIRECTORY (configuration)
-
+    if (NOT CONTAINERIZED)
+      HPCC_ADD_SUBDIRECTORY (testing)
+      HPCC_ADD_SUBDIRECTORY (deploy)
+      HPCC_ADD_SUBDIRECTORY (deployment)
+      HPCC_ADD_SUBDIRECTORY (configuration)
+    endif()
+    
     if ( WIN32 )
         HPCC_ADD_SUBDIRECTORY (clienttools/IDEPlugins "CLIENTTOOLS_ONLY")
         HPCC_ADD_SUBDIRECTORY (clienttools/win "CLIENTTOOLS_ONLY")

+ 5 - 0
cmake_modules/commonSetup.cmake

@@ -44,6 +44,7 @@ IF ("${COMMONSETUP_DONE}" STREQUAL "")
       cmake_policy ( SET CMP0054 NEW )
     endif()
   endif()
+  option(CONTAINERIZED "Build for container images." OFF)
   option(CLIENTTOOLS "Enable the building/inclusion of a Client Tools component." ON)
   option(PLATFORM "Enable the building/inclusion of a Platform component." ON)
   option(DEVEL "Enable the building/inclusion of a Development component." OFF)
@@ -782,6 +783,10 @@ IF ("${COMMONSETUP_DONE}" STREQUAL "")
          add_definitions (-D_USE_AERON)
       ENDIF(USE_AERON)
 
+      IF (CONTAINERIZED)
+         add_definitions (-D_CONTAINERIZED)
+      ENDIF(CONTAINERIZED)
+
       IF (USE_ICU)
         find_package(ICU)
         IF (ICU_FOUND)

+ 3 - 7
common/workunit/workunit.cpp

@@ -7380,8 +7380,6 @@ public:
                         primaryThorProcesses.append(thorName);
                 }
                 unsigned nodes = thor.getCount("ThorSlaveProcess");
-                if (!nodes)
-                    throw MakeStringException(WUERR_MismatchClusterSize,"CEnvironmentClusterInfo: Thor cluster can not have 0 slave processes");
                 unsigned slavesPerNode = thor.getPropInt("@slavesPerNode", 1);
                 unsigned channelsPerSlave = thor.getPropInt("@channelsPerSlave", 1);
                 unsigned ts = nodes * slavesPerNode * channelsPerSlave;
@@ -7389,9 +7387,6 @@ public:
                 if (clusterWidth && (ts!=clusterWidth)) 
                     throw MakeStringException(WUERR_MismatchClusterSize,"CEnvironmentClusterInfo: mismatched thor sizes in cluster");
                 clusterWidth = ts;
-                bool islcr = !thor.getPropBool("@Legacy");
-                if (!islcr)
-                    throw MakeStringException(WUERR_MismatchThorType,"CEnvironmentClusterInfo: Legacy Thor no longer supported");
             }
             platform = ThorLCRCluster;
         }
@@ -7763,7 +7758,7 @@ IConstWUClusterInfo* getTargetClusterInfo(IPropertyTree *environment, IPropertyT
 {
     const char *clustname = cluster->queryProp("@name");
 
-    // MORE - at the moment configenf specifies eclagent and thor queues by (in effect) placing an 'example' thor or eclagent in the topology 
+    // MORE - at the moment configenv specifies eclagent and thor queues by (in effect) placing an 'example' thor or eclagent in the topology
     // that uses the queue that will be used.
     // We should and I hope will change that, at which point the code below gets simpler
 
@@ -7788,7 +7783,8 @@ IConstWUClusterInfo* getTargetClusterInfo(IPropertyTree *environment, IPropertyT
         if (thorName) 
         {
             xpath.clear().appendf("Software/ThorCluster[@name=\"%s\"]", thorName);
-            thors.append(*environment->getPropTree(xpath.str()));
+            if (environment->hasProp(xpath.str()))
+                thors.append(*environment->getPropTree(xpath.str()));
         }
     }
     const char *roxieName = cluster->queryProp("RoxieCluster/@process");

+ 10 - 0
dali/server/daserver.cpp

@@ -144,6 +144,8 @@ void usage(void)
  */
 static bool populateWhiteListFromEnvironment(IWhiteListWriter &writer)
 {
+    if (isCloud())
+        return false;
     Owned<IRemoteConnection> conn = querySDS().connect("/Environment", 0, 0, INFINITE);
     assertex(conn);
 
@@ -365,6 +367,14 @@ int main(int argc, char* argv[])
             port = atoi(argv[++i]);
         else if (streq(argv[i],"--rank") || streq(argv[i],"-r"))
             myrank = atoi(argv[++i]);
+#ifdef _DEBUG
+        else if (streq(argv[i],"--hold"))
+        {
+            bool held = true;
+            while (held)
+                Sleep(5);
+        }
+#endif
         else {
             usage();
             return EXIT_FAILURE;

+ 1 - 0
dockerfiles/buildall.sh

@@ -16,6 +16,7 @@ if [[ -n ${INPUT_BUILDTYPE} ]] ; then
   BUILD_TYPE=$INPUT_BUILDTYPE
   BUILD_LABEL=${BUILD_TAG}-$INPUT_BUILDTYPE
 else
+  BUILD_LABEL=${BUILD_TAG}
   BUILD_TYPE=RelWithDebInfo
 fi
 

+ 2 - 2
dockerfiles/dali/Dockerfile

@@ -3,11 +3,11 @@ FROM hpccsystems/platform-core:${BUILD_LABEL}
 
 USER hpcc
 
-WORKDIR /etc/HPCCSystems/
-RUN sed -i "s+</DaliServerProcess>+<WhiteList enabled='false'/></DaliServerProcess>+" environment.xml
 RUN mkdir -p /var/lib/HPCCSystems/dali
 WORKDIR /var/lib/HPCCSystems/dali
 COPY --chown=hpcc:hpcc daliconf.xml /var/lib/HPCCSystems/dali
+COPY --chown=hpcc:hpcc environment.xml /etc/HPCCSystems/environment.xml
+COPY --chown=hpcc:hpcc environment.conf /etc/HPCCSystems/environment.conf
 #RUN daserver --init
 ENTRYPOINT ["daserver"]
 

+ 81 - 0
dockerfiles/dali/environment.conf

@@ -0,0 +1,81 @@
+## Default environment configuration file for OpenHPCC
+
+[DEFAULT]
+configs=/etc/HPCCSystems
+path=/opt/HPCCSystems
+classpath=/opt/HPCCSystems/classes
+runtime=/var/lib/HPCCSystems
+lock=/var/lock/HPCCSystems
+
+# Supported logging fields: AUD,CLS,DET,MID,TIM,DAT,PID,TID,NOD,JOB,USE,SES,COD,MLT,MCT,NNT,COM,QUO,PFX,ALL,STD
+logfields=TIM+DAT+MLT+MID+PID+TID+COD+QUO+PFX+AUD
+pid=/var/run/HPCCSystems
+log=/var/log/HPCCSystems
+user=hpcc
+group=hpcc
+
+#umask=022
+#nice=0
+
+home=/Users
+environment=environment.xml
+sourcedir=/etc/HPCCSystems/source
+blockname=HPCCSystems
+interface=*
+# enable epoll method for notification events (true/false)
+use_epoll=true
+#epoll_hdlperthrd=10
+# allow kernel pagecache flushing where enabled (true/false)
+allow_pgcache_flush=true
+# report UDP network stats
+udp_stats=true
+mpStart=7101
+mpEnd=7500
+mpSoMaxConn=128
+mpTraceLevel=0
+# enable SSL for dafilesrv remote file access (SSLNone/false | SSLOnly/true | SSLFirst | UnsecureFirst)
+# Enabling requires setting the HPCCPassPhrase, HPCCCertFile, and HPCCPrivateKeyFile values
+#dfsUseSSL=SSLNone
+
+#Specify location of HPCC PKI public/private key files
+# note: if HPCCPassPhrase specified it must be encrypted
+#HPCCPassPhrase=
+#HPCCCertificateFile=/Users/rchapman/certificate/certificate.pem
+#HPCCPublicKeyFile=/Users/rchapman/certificate/public.key.pem
+#HPCCPrivateKeyFile=/Users/rchapman/certificate/key.pem
+
+jvmoptions=-XX:-UsePerfData
+#Options to enable remote debugging of Java service or application
+#jvmoptions=-XX:-UsePerfData -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=2000
+#JNI_PATH=/absolute/path/to/alternative/libjvm.so
+
+# Python plugins can call python cleanup code on exit, but this seems to cause lockups in some Tensorflow examples
+# In most cases, skipping the cleanup is harmless and avoids these lockups
+skipPythonCleanup=true
+
+# Although HPCC platform includes plugins for both Python2 and Python3, only one may be safely enabled at a time
+# as the Python libraries export the same symbols for both versions. Enabling both may lead to unpredicatable results
+# including segfaults or undefined symbol errors.
+#
+# If you would prefer to use python 2 and disable python3, change the line below to read
+#  additionalPlugins=python2
+#
+# Multiple paths can be specified (separate with :, or ; on Windows).
+# Relative paths are assumed to be relative to /Users/rchapman/hpcc/opt/HPCCSystems/versioned
+additionalPlugins=python3
+
+# To en-/disable Drop Zone restriction.
+# Default is enabled (true).
+useDropZoneRestriction=true
+# If set, will force matching local file paths to become remote reads, e.g:
+#forceRemotePattern=/var/lib/HPCCSystems/hpcc-data/eclagent/*
+
+# Dafilesrv: default client side connection settings (NB: 0 = disable/use system defaults)
+#dafsConnectTimeoutSeconds=100
+#dafsConnectRetries=2
+#dafsMaxReceiveTimeSeconds=0
+
+# Dafilesrv: set to change number of seconds before retrying an unresponsive dafilesrv connection (default 10 seconds)
+# NB: for now this only applies to the last cached server 
+#dafsConnectFailRetrySeconds=10
+

+ 55 - 0
dockerfiles/dali/environment.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Environment>
+ <Software>
+  <DaliServerProcess build="_"
+                     buildSet="dali"
+                     name="mydali"
+                     recoverFromIncErrors="true">
+  <WhiteList enabled='false'/>                     
+  </DaliServerProcess>
+
+  <EclAgentProcess name="myeclagent"/>
+  <ThorCluster name="mythor"/>
+  <RoxieCluster name="myroxie"/>
+
+  
+  <Directories name="HPCCSystems">
+   <Category dir="/var/log/[NAME]/[INST]" name="log"/>
+   <Category dir="/var/lib/[NAME]/[INST]" name="run"/>
+   <Category dir="/etc/[NAME]/[INST]" name="conf"/>
+   <Category dir="/var/lib/[NAME]/[INST]/temp" name="temp"/>
+   <Category dir="/var/lib/[NAME]/hpcc-data/[COMPONENT]" name="data"/>
+   <Category dir="/var/lib/[NAME]/hpcc-data2/[COMPONENT]" name="data2"/>
+   <Category dir="/var/lib/[NAME]/hpcc-data3/[COMPONENT]" name="data3"/>
+   <Category dir="/var/lib/[NAME]/hpcc-mirror/[COMPONENT]" name="mirror"/>
+   <Category dir="/var/lib/[NAME]/queries/[INST]" name="query"/>
+   <Category dir="/var/lock/[NAME]/[INST]" name="lock"/>
+   <Category dir="/var/lib/[NAME]/hpcc-data4/[COMPONENT]" name="data4"/>
+   <Category dir="/var/lib/[NAME]/keys" name="keys"/>
+  </Directories>
+  <Topology build="_" buildSet="topology" name="topology">
+   <Cluster name="hthor" prefix="hthor" alias="">
+    <EclSchedulerProcess process="myeclscheduler"/>
+    <EclAgentProcess process="myeclagent"/>
+    <EclCCServerProcess process="myeclccserver"/>
+   </Cluster>
+   <Cluster name="thor" prefix="thor" alias="">
+    <EclAgentProcess process="myeclagent"/>
+    <EclCCServerProcess process="myeclccserver"/>
+    <ThorCluster process="mythor"/>
+    <EclSchedulerProcess process="myeclscheduler"/>
+   </Cluster>
+   <Cluster name="roxie" prefix="roxie" alias="">
+    <RoxieCluster process="myroxie"/>
+    <EclCCServerProcess process="myeclccserver"/>
+    <EclSchedulerProcess process="myeclscheduler"/>
+   </Cluster>
+   <Cluster name="thor_roxie" prefix="thor" alias="">
+    <EclCCServerProcess process="myeclccserver"/>
+    <ThorCluster process="mythor"/>
+    <RoxieCluster process="myroxie"/>
+    <EclSchedulerProcess process="myeclscheduler"/>
+   </Cluster>
+  </Topology>
+ </Software>
+</Environment>

+ 0 - 1
dockerfiles/eclccserver/Dockerfile

@@ -6,4 +6,3 @@ RUN mkdir -p /var/lib/HPCCSystems/eclccserver
 WORKDIR /var/lib/HPCCSystems/eclccserver
 RUN eclccserver --init > eclccserver.json
 ENTRYPOINT [ "eclccserver", "--config=eclccserver.json" ]
-

File diff suppressed because it is too large
+ 0 - 2
dockerfiles/esp/esp.xml


+ 3 - 3
dockerfiles/incr.sh

@@ -8,8 +8,8 @@
 
 HEAD=$(git rev-parse --short HEAD)
 PREV=$1
-[[ -z ${PREV} ]] && PREV=$(git log --format=format:%h $(git describe --abbrev=0 --tags)..HEAD | grep `docker images hpccsystems/platform-core --format {{.Tag}} | head -n 1`)
-[[ -z ${PREV} ]] && PREV=$(git describe --abbrev=0 --tags)
+[[ -z ${PREV} ]] && PREV=$(git log --format=format:%h-Debug $(git describe --abbrev=0 --tags)..HEAD | grep `docker images hpccsystems/platform-build --format {{.Tag}} | head -n 1`)
+[[ -z ${PREV} ]] && PREV=$(git describe --abbrev=0 --tags)-Debug
 
 BUILD_TYPE=Debug
 BUILD_LABEL=${HEAD}-Debug
@@ -29,7 +29,7 @@ else
     if [[ -n "$FORCE" ]] ; then
       docker image build -t hpccsystems/platform-build:${BUILD_LABEL} --build-arg PREV_LABEL=${HEAD}-Debug --build-arg BASE_VER=7.8 --build-arg BUILD_TYPE=Debug platform-build/
     else
-      docker image build -t hpccsystems/platform-build:${BUILD_LABEL} --build-arg PREV_LABEL=${PREV}-Debug --build-arg COMMIT=${HEAD} --build-arg USER=${GITHUB_USER} platform-build-incremental/
+      docker image build -t hpccsystems/platform-build:${BUILD_LABEL} --build-arg PREV_LABEL=${PREV} --build-arg COMMIT=${HEAD} --build-arg USER=${GITHUB_USER} platform-build-incremental/
     fi
     docker image build -t hpccsystems/platform-core:${BUILD_LABEL} --build-arg BUILD_LABEL=${BUILD_LABEL} platform-core-debug/  
     

+ 2 - 1
dockerfiles/platform-build-incremental/Dockerfile

@@ -9,4 +9,5 @@ ARG COMMIT
 
 RUN git fetch ${USER} && git checkout ${COMMIT} 
 WORKDIR /hpcc-dev/build
-RUN rm *.deb && make -j$(($(nproc)*3/2)) package
+RUN cmake /hpcc-dev/HPCC-Platform -Wno-dev -DCONTAINERIZED=1 -DCMAKE_BUILD_TYPE=Debug
+RUN make -j$(($(nproc)*3/2)) install

+ 2 - 2
dockerfiles/platform-build/Dockerfile

@@ -18,11 +18,11 @@ RUN mkdir build
 WORKDIR /hpcc-dev/build
 
 ARG BUILD_TYPE=RelWithDebInfo
-RUN JAVA_HOME=`/usr/libexec/java_home` cmake /hpcc-dev/HPCC-Platform -Wno-dev -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
+RUN cmake /hpcc-dev/HPCC-Platform -Wno-dev -DCONTAINERIZED=1 -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
 
 RUN make -j$(nproc) jlib
 RUN make -j$(nproc) esp
 RUN make -j$(nproc) roxie
 RUN make  ws_workunits  ecl
 RUN make -j$(nproc)
-RUN make -j$(nproc) package
+RUN make -j$(nproc) install

+ 8 - 2
dockerfiles/platform-core-debug/Dockerfile

@@ -7,10 +7,16 @@ RUN apt-get install -y \
     dnsutils \
     nano 
 
-RUN dpkg -i /hpcc-dev/build/*.deb ; \
-    apt-get install -f -y
+RUN useradd -s /bin/bash -r -U -c "hpcc runtime User" hpcc
+RUN passwd -l hpcc 
+
+RUN mkdir /var/lib/HPCCSystems && chown hpcc:hpcc /var/lib/HPCCSystems
+RUN mkdir /var/log/HPCCSystems && chown hpcc:hpcc /var/log/HPCCSystems
+RUN mkdir /var/lock/HPCCSystems && chown hpcc:hpcc /var/lock/HPCCSystems
+RUN mkdir /var/run/HPCCSystems && chown hpcc:hpcc /var/run/HPCCSystems
 
 USER hpcc
+
 ENV PATH="/opt/HPCCSystems/bin:${PATH}"
 ENV HPCC_containerized=1
 ENV HPCC_DLLSERVER_PATH=/var/lib/HPCCSystems/queries

+ 15 - 6
dockerfiles/platform-core/Dockerfile

@@ -29,17 +29,26 @@ RUN apt-get install -y \
 
 RUN apt-get install -y \
   libxslt1.1
-  
-COPY --from=build /hpcc-dev/build/*.deb /
-RUN dpkg -i *.deb ; \
-    apt-get install -f && \
-    apt-get clean && \
-    rm *.deb
 
 RUN apt-get install -y \
     dnsutils \
     nano 
 
+COPY --from=build /opt/HPCCSystems /
+
+#RUN dpkg -i *.deb ; \
+#    apt-get install -f && \
+#    apt-get clean && \
+#    rm *.deb
+
+RUN useradd -s /bin/bash -r -U -c "hpcc runtime User" hpcc
+RUN passwd -l hpcc 
+
+RUN mkdir /var/lib/HPCCSystems && chown hpcc:hpcc /var/lib/HPCCSystems
+RUN mkdir /var/log/HPCCSystems && chown hpcc:hpcc /var/log/HPCCSystems
+RUN mkdir /var/lock/HPCCSystems && chown hpcc:hpcc /var/lock/HPCCSystems
+RUN mkdir /var/run/HPCCSystems && chown hpcc:hpcc /var/run/HPCCSystems
+
 USER hpcc
 ENV PATH="/opt/HPCCSystems/bin:${PATH}"
 ENV HPCC_containerized=1

+ 4 - 1
esp/files/scripts/CMakeLists.txt

@@ -13,7 +13,10 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 ################################################################################
-add_subdirectory (configmgr)
+
+if (NOT CONTAINERIZED)
+  add_subdirectory (configmgr)
+endif()
 
 set ( SCRIPTS_FILES
     ${CMAKE_CURRENT_SOURCE_DIR}/bpsreport.js

+ 5 - 3
esp/services/CMakeLists.txt

@@ -18,8 +18,6 @@ IF (USE_OPENLDAP)
     HPCC_ADD_SUBDIRECTORY (ws_access "PLATFORM")
 ENDIF(USE_OPENLDAP)
 HPCC_ADD_SUBDIRECTORY (ws_account "PLATFORM")
-HPCC_ADD_SUBDIRECTORY (ws_config "PLATFORM")
-HPCC_ADD_SUBDIRECTORY (ws_configmgr "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_dfu "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_ecl "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_fileio "PLATFORM")
@@ -28,7 +26,6 @@ HPCC_ADD_SUBDIRECTORY (ws_machine "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_smc "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_topology "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_workunits "PLATFORM")
-HPCC_ADD_SUBDIRECTORY (WsDeploy "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_packageprocess "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_esdlconfig "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (esdl_svc_engine "PLATFORM")
@@ -40,3 +37,8 @@ HPCC_ADD_SUBDIRECTORY (espcontrol "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_elk "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_store "PLATFORM")
 HPCC_ADD_SUBDIRECTORY (ws_codesign "PLATFORM")
+if (NOT CONTAINERIZED)
+  HPCC_ADD_SUBDIRECTORY (ws_config "PLATFORM")
+  HPCC_ADD_SUBDIRECTORY (ws_configmgr "PLATFORM")
+  HPCC_ADD_SUBDIRECTORY (WsDeploy "PLATFORM")
+endif()

+ 3 - 1
esp/services/ws_smc/ws_smcService.cpp

@@ -2611,6 +2611,7 @@ bool CWsSMCEx::onLockQuery(IEspContext &context, IEspLockQueryRequest &req, IEsp
 
 void CActivityInfoReader::threadmain()
 {
+#ifndef _CONTAINERIZED
     PROGLOG("WsSMC CActivityInfoReader Thread started.");
     unsigned int autoRebuildMillSeconds = 1000*autoRebuildSeconds;
     while (!stopping)
@@ -2658,4 +2659,5 @@ void CActivityInfoReader::threadmain()
             waiting.compare_exchange_strong(expected, false);
         }
     }
-}
+#endif
+}

+ 6 - 4
initfiles/CMakeLists.txt

@@ -38,10 +38,12 @@ if ( PLATFORM AND UNIX )
     configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bash-vars.in" "${CMAKE_BINARY_DIR}/bash-vars")
     set(bash-vars "${CMAKE_BINARY_DIR}/bash-vars")
 
-    ADD_SUBDIRECTORY(etc)
-    ADD_SUBDIRECTORY(bash)
-    ADD_SUBDIRECTORY(bin)
-    ADD_SUBDIRECTORY(sbin)
+    if ( NOT CONTAINERIZED )
+      ADD_SUBDIRECTORY(etc)
+      ADD_SUBDIRECTORY(bash)
+      ADD_SUBDIRECTORY(bin)
+      ADD_SUBDIRECTORY(sbin)
+    endif()
 endif ()
 
 if ( PLATFORM OR CLIENTTOOLS_ONLY )

+ 1 - 1
initfiles/componentfiles/launcher/CMakeLists.txt

@@ -18,7 +18,7 @@
 install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/hpcc-systems.desktop DESTINATION share COMPONENT Runtime )
 install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/LN.png DESTINATION share COMPONENT Runtime )
 
-if(PLATFORM)
+if(PLATFORM AND NOT CONTAINERIZED)
     SET_DEPENDENCIES(CPACK_DEBIAN_PACKAGE_DEPENDS xterm)
     configure_file(hpcc-systems-desktop.install.in hpcc-systems-desktop.install @ONLY)
     configure_file(hpcc-systems-desktop.uninstall.in hpcc-systems-desktop.uninstall @ONLY)

+ 8 - 0
system/jlib/jptree.cpp

@@ -7905,6 +7905,14 @@ jlib_decl IPropertyTree * loadConfiguration(const char * defaultYaml, const char
             displayConfig(config, componentTag);
             exit(0);
         }
+#ifdef _DEBUG
+        else if (strsame(cur, "--hold"))
+        {
+            bool held = true;
+            while (held)
+                Sleep(5);
+        }
+#endif
         else if (strsame(cur, "--outputconfig"))
         {
             outputConfig = true;