diff --git a/buildScript/dependencies.gradle b/buildScript/dependencies.gradle index 63b88a606..700b94a1b 100644 --- a/buildScript/dependencies.gradle +++ b/buildScript/dependencies.gradle @@ -108,6 +108,11 @@ dependencies { implementation 'org.asdf-format:asdf-core:0.1-alpha-10' implementation 'edu.stsci:roman-datamodels:0.1-alpha-3' + // tomcat for standalone + implementation 'org.apache.tomcat.embed:tomcat-embed-core:11.0.21' + implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:11.0.21' + implementation 'org.apache.tomcat.embed:tomcat-embed-jasper:11.0.21' + } diff --git a/config/web.xml b/config/web.xml index 0bce30626..fec09b187 100644 --- a/config/web.xml +++ b/config/web.xml @@ -89,29 +89,6 @@ /CmdSrv/async/* - - H2Console - org.h2.server.web.WebServlet - - -webAllowOthers - true - - 2 - - - H2Console - /admin/db/* - - - - alertviewer - /alertviewer.html - - - alertviewer - /alertviewer/* - - diff --git a/settings.gradle b/settings.gradle index ccc464db0..d0393cb12 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,8 @@ rootProject.name = 'firefly_root' -include 'firefly', 'firefly_data' +include 'firefly', 'firefly_data', "firefly_standalone" project(":firefly").projectDir = file('src/firefly') project(":firefly_data").projectDir = file('src/firefly_data') +project(":firefly_standalone").projectDir = file('src/firefly_standalone') diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/util/VersionUtil.java b/src/firefly/java/edu/caltech/ipac/firefly/server/util/VersionUtil.java index a340ecb39..718deb2eb 100644 --- a/src/firefly/java/edu/caltech/ipac/firefly/server/util/VersionUtil.java +++ b/src/firefly/java/edu/caltech/ipac/firefly/server/util/VersionUtil.java @@ -64,32 +64,35 @@ public static void initVersion(ServletContext context) { } public static void ingestVersion(ServletContext context) { - - _version.setAppName(context.getServletContextName()); - _version.setConfigLastModTime(ServerContext.getConfigLastModTime()); - - File confDir = ServerContext.getWebappConfigDir(); - Properties props = new Properties(); try { + _version.setAppName(context.getServletContextName()); + _version.setConfigLastModTime(ServerContext.getConfigLastModTime()); + + File confDir = ServerContext.getWebappConfigDir(); + Properties props = new Properties(); props.load(new FileInputStream(new File(confDir, VERSION_FILE))); - _version.setMajor(getNum(props.getProperty(MAJOR))); - _version.setMinor(getNum(props.getProperty(MINOR))); - _version.setRev(props.getProperty(REV)); - _version.setVersionType(Version.convertVersionType(props.getProperty(TYPE))); - _version.setBuild(getNum(props.getProperty(BUILD_NUMBER))); - _version.setBuildDate(props.getProperty(BUILD_DATE)); - _version.setBuildTime(props.getProperty(BUILD_TIME)); - _version.setBuildTag(props.getProperty(BUILD_TAG)); - _version.setBuildCommit(props.getProperty(BUILD_COMMIT)); - _version.setBuildCommitFirefly(props.getProperty(BUILD_COMMIT_FIREFLY)); - _version.setBuildFireflyTag(props.getProperty(BUILD_FIREFLY_TAG)); - _version.setBuildFireflyBranch(props.getProperty(BUILD_FIREFLY_BRANCH)); - _version.setDevCycleTag(props.getProperty(DEV_CYCLE_TAG)); + ingestVersion(props); } catch (IOException e) { // just ignore } } + public static void ingestVersion(Properties props) { + _version.setMajor(getNum(props.getProperty(MAJOR))); + _version.setMinor(getNum(props.getProperty(MINOR))); + _version.setRev(props.getProperty(REV)); + _version.setVersionType(Version.convertVersionType(props.getProperty(TYPE))); + _version.setBuild(getNum(props.getProperty(BUILD_NUMBER))); + _version.setBuildDate(props.getProperty(BUILD_DATE)); + _version.setBuildTime(props.getProperty(BUILD_TIME)); + _version.setBuildTag(props.getProperty(BUILD_TAG)); + _version.setBuildCommit(props.getProperty(BUILD_COMMIT)); + _version.setBuildCommitFirefly(props.getProperty(BUILD_COMMIT_FIREFLY)); + _version.setBuildFireflyTag(props.getProperty(BUILD_FIREFLY_TAG)); + _version.setBuildFireflyBranch(props.getProperty(BUILD_FIREFLY_BRANCH)); + _version.setDevCycleTag(props.getProperty(DEV_CYCLE_TAG)); + } + public static Version getAppVersion() { return _version; } private static int getNum(String s) { diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisContext.java b/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisContext.java index 7f2bdc7ee..a63cbd0ed 100644 --- a/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisContext.java +++ b/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisContext.java @@ -27,7 +27,9 @@ public class VisContext { static public void init() { if (_initialized) return; - System.setProperty("java.awt.headless", "true"); +// System.setProperty("java.awt.headless", "true"); + boolean desktop= AppProperties.getBooleanProperty("runAsDesktopApplication", false); + System.setProperty("java.awt.headless", desktop ? "false" : "true"); //todo make this smart depending on context, no PR until it is done!!!! initFootprints(); initCounters(); _initialized = true; diff --git a/src/firefly/java/edu/caltech/ipac/util/StringUtils.java b/src/firefly/java/edu/caltech/ipac/util/StringUtils.java index 4584c8364..bdfd01e4a 100644 --- a/src/firefly/java/edu/caltech/ipac/util/StringUtils.java +++ b/src/firefly/java/edu/caltech/ipac/util/StringUtils.java @@ -4,7 +4,6 @@ package edu.caltech.ipac.util; import edu.caltech.ipac.firefly.core.Util; -import edu.caltech.ipac.firefly.server.util.Logger; import javax.validation.constraints.NotNull; import java.net.MalformedURLException; @@ -45,8 +44,6 @@ public static enum Align {LEFT, RIGHT, MIDDLE} public static final long GIG_HUNDREDTH= GIG / 100; public static final long K = 1024; - private static final Logger.LoggerImpl logger = Logger.getLogger(); - public static String[] groupMatch(String regex, String val) { return groupMatch(regex, val, 0); } diff --git a/src/firefly/java/edu/caltech/ipac/util/download/URLDownload.java b/src/firefly/java/edu/caltech/ipac/util/download/URLDownload.java index 123e6462a..e21bfc040 100644 --- a/src/firefly/java/edu/caltech/ipac/util/download/URLDownload.java +++ b/src/firefly/java/edu/caltech/ipac/util/download/URLDownload.java @@ -58,7 +58,6 @@ public class URLDownload { private static final int BUFFER_SIZE = FileUtil.BUFFER_SIZE; - private static final Logger.LoggerImpl _log = Logger.getLogger(); private static final int MAX_REDIRECT= 2; static { @@ -83,7 +82,7 @@ public void checkServerTrusted(X509Certificate[] arg0, String arg1) { } sc.init(null, trustAllCerts, null); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (KeyManagementException | NoSuchAlgorithmException e) { - _log.error(e); + loggerError(e); } } @@ -200,11 +199,13 @@ public static Map buildReqHeaders(URL url, Map r if (requestHeaders== null) requestHeaders= Collections.emptyMap(); Map h = new HashMap<>(requestHeaders); if (ops==null || ops.useCredentials) { - var inputs= new HttpServiceInput(url.toString()); - var credentials= inputs.getHeaders(); - if (credentials!=null && !credentials.isEmpty()) { - if (!credentials.keySet().stream().allMatch(h::containsKey)) h.putAll(credentials); - } + try { + var inputs= new HttpServiceInput(url.toString()); + var credentials= inputs.getHeaders(); + if (credentials!=null && !credentials.isEmpty()) { + if (!credentials.keySet().stream().allMatch(h::containsKey)) h.putAll(credentials); + } + } catch (NoClassDefFoundError ignore) { } } return h; } @@ -247,7 +248,11 @@ private static String sendHeadersToCompactStr(Map> sendHeade } } else { - workBuff.append(sanitizeHeader(se.getKey(), String.valueOf(se.getValue()))); + try { + workBuff.append(sanitizeHeader(se.getKey(), String.valueOf(se.getValue()))); + } catch (NoClassDefFoundError e) { + workBuff.append(se.getKey()+"="+se.getValue()); + } } outStr.append(workBuff.toString()); } @@ -306,7 +311,7 @@ public static URLConnection makeConnection(URL url, } return conn; } catch (IOException e) { - logError(url,null,e); + loggerError(url,null,e); throw e; } } @@ -390,10 +395,10 @@ public static HttpResultInfo getDataFromURL(URL url, if (!ops.logErrorsOnly) logSuccess(result,url,dlSeconds,reqProp, postData); return result; } catch (SSLException | SocketTimeoutException | UnknownHostException e) { - logError(url, postData, e); + loggerError(url, postData, e); return exceptionToResponse(e,requestHeaders); } catch (IOException e) { - logError(url, postData, e); + loggerError(url, postData, e); throw new FailedRequestException(ResponseMessage.getNetworkCallFailureMessage(e), e, getResponseCode(conn)); } } @@ -418,7 +423,7 @@ public static HttpResultInfo getHeader(URL url, } catch (SSLException | SocketTimeoutException | UnknownHostException e) { return exceptionToResponse(e,h); } catch (IOException e) { - logError(url, null, e); + loggerError(url, null, e); throw new FailedRequestException(ResponseMessage.getNetworkCallFailureMessage(e), e, -1); } } @@ -476,10 +481,10 @@ private static HttpResultInfo getHeaderFromConnection(HttpURLConnection conn, } return result; } catch (SSLException | SocketTimeoutException | UnknownHostException e) { - logError(conn.getURL(), null , e); + loggerError(conn.getURL(), null , e); return exceptionToResponse(e,requestHeaders); } catch (IOException e) { - logError(conn.getURL(), null, e); + loggerError(conn.getURL(), null, e); throw new FailedRequestException(ResponseMessage.getNetworkCallFailureMessage(e), e, getResponseCode(conn)); } } @@ -505,7 +510,7 @@ public static FileInfo getDataToFileUsingPost(URL url, Map postData, Options ops= new Options(true, true, 0L, false, false, timeoutInSec, dl, false, false); return getDataToFile(makeURLConnection(url, cookies, requestHeader), outfile, ops, postData,0); } catch (IOException e) { - logError(url, postData, e); + loggerError(url, postData, e); throw new FailedRequestException(ResponseMessage.getNetworkCallFailureMessage(e), e); } } @@ -636,7 +641,7 @@ public static FileInfo getDataToFile(HttpURLConnection conn, } catch (SSLException | SocketTimeoutException | UnknownHostException e) { return exceptionToFileInfo(e); } catch (IOException e) { - logError(conn.getURL(), null, e); + loggerError(conn.getURL(), null, e); throw new FailedRequestException(ResponseMessage.getNetworkCallFailureMessage(e),e, getResponseCode(conn)); } } @@ -760,7 +765,7 @@ private static FileInfo checkAlreadyDownloaded(HttpURLConnection urlConn, File o urlConn.setIfModifiedSince(outfile.lastModified()); if (getResponseCode(urlConn) == HttpURLConnection.HTTP_NOT_MODIFIED) { String urlStr= urlConn.getURL().toString(); - _log.info(outfile.getName() + ": Not downloading, already have current version, from "+urlStr); + loggerInfo(outfile.getName() + ": Not downloading, already have current version, from "+urlStr); retval = new FileInfo(outfile, getSuggestedFileName(urlConn), HttpURLConnection.HTTP_NOT_MODIFIED, ResponseMessage.getHttpResponseMessage(HttpURLConnection.HTTP_NOT_MODIFIED)); retval.putAttribute(FileInfo.FILE_DOWNLOADED,false+""); @@ -774,7 +779,7 @@ private static FileInfo checkAlreadyDownloaded(HttpURLConnection urlConn, File o } - private static void logError(URL url, Map postData, Exception e) { + private static void loggerError(URL url, Map postData, Exception e) { List strList = new ArrayList<>(6); strList.add("----------Network Error-----------"); if (url != null) { @@ -788,7 +793,7 @@ private static void logError(URL url, Map postData, Exception e) { strList.add(StringUtils.pad(20,"----------Exception ")); strList.add(e.toString()); } - _log.warn(strList.toArray(new String[0])); + loggerInfo(strList.toArray(new String[0])); } private static void logHeaderForError(String originalUrl, Map postData, HttpURLConnection conn, Map> sendHeaders) { @@ -861,9 +866,9 @@ private static void logHeaderForError(String originalUrl, Map postData else { outStr.add("No headers or status received, invalid http response, using work around"); } - _log.info(outStr.toArray(new String[0])); + loggerInfo(outStr.toArray(new String[0])); } catch (Exception e) { - _log.info(e.getMessage() + ":" + " url=" + (conn.getURL()!=null ? conn.getURL().toString() : "none")); + loggerInfo(e.getMessage() + ":" + " url=" + (conn.getURL()!=null ? conn.getURL().toString() : "none")); } } @@ -880,7 +885,7 @@ private static void logSuccess(FileInfo fileInfo, File outfile, URL url, double "more response headers: "+otherHeadersToStr(fileInfo) )); if (postData!=null) strList.add("post data: " +postDataLogString(postData)); - _log.info(strList.toArray(new String[0])); + loggerInfo(strList.toArray(new String[0])); } private static void logSuccess(HttpResultInfo r, URL url, double dSeconds, Map> sendHeaders, Map postData) { @@ -889,7 +894,7 @@ private static void logSuccess(HttpResultInfo r, URL url, double dSeconds, Map values) { return workBuff.toString(); } + private static void loggerInfo(String ...msgs) { + try { + Logger.getLogger().info(msgs); + } catch (NoClassDefFoundError t) { + Arrays.stream(msgs).forEach(System.out::println); + } + } + + private static void loggerError(Throwable t, String ...msgs) { + try { + Logger.getLogger().error(t, msgs); + } catch (NoClassDefFoundError e) { + System.out.println(t.getMessage()); + Arrays.stream(msgs).forEach(System.out::println); + } + } + public static class Options { private boolean onlyIfModified; private boolean uncompress; diff --git a/src/firefly/java/edu/caltech/ipac/visualize/plot/plotdata/FitsRead.java b/src/firefly/java/edu/caltech/ipac/visualize/plot/plotdata/FitsRead.java index 490466605..b39cfb8ba 100644 --- a/src/firefly/java/edu/caltech/ipac/visualize/plot/plotdata/FitsRead.java +++ b/src/firefly/java/edu/caltech/ipac/visualize/plot/plotdata/FitsRead.java @@ -249,6 +249,7 @@ public static void setDefaultFutureStretch(RangeValues defaultRangeValues) { * @param lsstMasks mask array * @deprecated */ + @Deprecated public synchronized void doStretchMask( byte[] pixelData, int startPixel, diff --git a/src/firefly_standalone/assets/fireflyDockIcon.png b/src/firefly_standalone/assets/fireflyDockIcon.png new file mode 100644 index 000000000..9df5ee29d Binary files /dev/null and b/src/firefly_standalone/assets/fireflyDockIcon.png differ diff --git a/src/firefly_standalone/assets/fireflySplash.png b/src/firefly_standalone/assets/fireflySplash.png new file mode 100644 index 000000000..3281c98ca Binary files /dev/null and b/src/firefly_standalone/assets/fireflySplash.png differ diff --git a/src/firefly_standalone/assets/javaInstaller.sh b/src/firefly_standalone/assets/javaInstaller.sh new file mode 100755 index 000000000..bc5f5e0f2 --- /dev/null +++ b/src/firefly_standalone/assets/javaInstaller.sh @@ -0,0 +1,50 @@ +#!/bin/bash + + +getJreKey() { + arch=$(uname -a) + name=$(uname) + jarKey="unknown" + + if [[ "$name" == "Darwin" ]]; then + if [[ "$arch" == "arm64" ]]; then + jreKey="macOSArm64" + else + jreKey="macOSIntel" + fi + else + if [[ "$arch" == "aarch64" ]]; then + jreKey="linuxArm64" + elif [[ "$arch" == "x86_64" ]]; then + jreKey="linux64" + else + jreKey= + fi + fi + + echo "$jreKey" +} + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +INSTALL_DIR=$(cd "${SCRIPT_DIR}/../.." && pwd) +javaInstallation="${INSTALL_DIR}/javaInstallation" +jreJsonFile="${INSTALL_DIR}/application/current/jreVersion.json" + + +#jreKey=$($INSTALL_DIR/application/current/jreKey.sh) +jreKey=$(getJreKey) + +jreUrl=$(cat "$jreJsonFile" | jq -r ".$jreKey.url") +javaPath=$(cat "$jreJsonFile" | jq -r ".$jreKey.java") +JAVA="$javaInstallation/$javaPath" + +if [ -f "$JAVA" ]; then + echo $JAVA + exit 0 +fi + +mkdir "$javaInstallation" +curl -L "$jreUrl" > "$javaInstallation/jre.tar.gz" +(cd "$javaInstallation" && tar -xzvf jre.tar.gz &> $javaInstallation/jre_tar_expand.log) +echo $JAVA + diff --git a/src/firefly_standalone/assets/jreVersion.json b/src/firefly_standalone/assets/jreVersion.json new file mode 100644 index 000000000..e8c6676a2 --- /dev/null +++ b/src/firefly_standalone/assets/jreVersion.json @@ -0,0 +1,23 @@ +{ + "javaVersion" : "21.0.11", + "linux64" : { + "url": "https://api.adoptium.net/v3/binary/latest/21/ga/linux/x64/jre/hotspot/normal/eclipse", + "java" : "jdk-21.0.11+10-jre/Contents/Home/bin/java" + }, + "linuxArm64" : { + "url": "https://api.adoptium.net/v3/binary/latest/21/ga/linux/aarch64/jre/hotspot/normal/eclipse", + "java" : "jdk-21.0.11+10-jre/Contents/Home/bin/java" + }, + "macOSIntel" : { + "url": "https://api.adoptium.net/v3/binary/latest/21/ga/mac/x64/jre/hotspot/normal/eclipse", + "java" : "jdk-21.0.11+10-jre/Contents/Home/bin/java" + }, + "macOSArm64" : { + "url": "https://api.adoptium.net/v3/binary/latest/21/ga/mac/aarch64/jre/hotspot/normal/eclipse", + "java" : "jdk-21.0.11+10-jre/Contents/Home/bin/java" + }, + "window" : { + "url": "https://api.adoptium.net/v3/binary/latest/21/ga/windows/x64/jre/hotspot/normal/eclipse", + "java" : "don't know" + } +} \ No newline at end of file diff --git a/src/firefly_standalone/assets/package-files.txt b/src/firefly_standalone/assets/package-files.txt new file mode 100644 index 000000000..5bc73bcdf --- /dev/null +++ b/src/firefly_standalone/assets/package-files.txt @@ -0,0 +1,6 @@ + +firefly.war +tomcat-annotations-api-11.0.21.jar +tomcat-embed-core-11.0.21.jar +tomcat-embed-websocket-11.0.21.jar +standalone.jar diff --git a/src/firefly_standalone/assets/standalone_cleanup.sh b/src/firefly_standalone/assets/standalone_cleanup.sh new file mode 100644 index 000000000..92f53b5ba --- /dev/null +++ b/src/firefly_standalone/assets/standalone_cleanup.sh @@ -0,0 +1,46 @@ + +cleanupMinutes=1440 +logfileMaxAge=7200 +rm_cmd=/bin/rm +rm_cmd="echo will remove:" +workarea_dir="${HOME}/.firefly/workarea/firefly" +shared_workarea="${HOME}/firefly/shared-workarea" +find_cmd="/usr/bin/find" + +function doCleanup() { + workarea="${1}" + log_dir="${workarea}/cleanup_logs" + mkdir -p "${log_dir}" + + # cleanup old log files + ${find_cmd} "${log_dir}" -type f -mmin +${logfileMaxAge} -exec $rm_cmd '{}' \+ + + # cleanup old work files + timestamp=$(date +20%y%m%dT%H%M%S) + log_file="${log_dir}/cleanup.${timestamp}.log" + clean_dirs=("${workarea}/temp_files" "${workarea}/visualize/fits-cache" "${workarea}/visualize/users") + dirs_to_clear=("${workarea}/visualize/users" "${workarea}/temp_files") + echo "Cleanup: " $workarea + echo 'Cleanup: log file: ' "${log_file}" + { + echo "Cleaning up work files older that ${cleanupMinutes} minutes, dir: ${workarea}" + [[ -d "${workarea}/HiPS" ]] && ${find_cmd} "${workarea}/HiPS" -type f -mtime +90 -exec $rm_cmd '{}' \+ -print + [[ -d "${workarea}/stage" ]] && ${find_cmd} "${workarea}/stage" -type f -mtime +7 -exec $rm_cmd '{}' \+ -print + [[ -d "${workarea}/upload" ]] && ${find_cmd} "${workarea}/upload" -type f -mtime +7 -exec $rm_cmd '{}' \+ -print + [[ -d "${workarea}/perm_files" ]] && ${find_cmd} "${workarea}/perm_files" -type f -atime +1 -exec $rm_cmd '{}' \+ -print + for dir in "${clean_dirs[@]}"; do + if [ -d "${dir}" ]; then + ${find_cmd} "${dir}" -type f -amin +${cleanupMinutes} -exec $rm_cmd '{}' \+ -print + fi + done + for dir in "${dirs_to_clear[@]}"; do # remove empty directories excluding those at the starting level + [[ -d "${dir}" ]] && ${find_cmd} "${dir}" -mindepth 1 -depth -type d -empty -print -exec $rm_cmd '{}' \; + done + } > "${log_file}" 2>&1 +} + + +# Remove temporary products for each Firefly workarea +# Find app directories (should be only one, but loop for safety) +doCleanup "${workarea_dir}" + diff --git a/src/firefly_standalone/assets/startFirefly b/src/firefly_standalone/assets/startFirefly new file mode 100644 index 000000000..d2dddb892 --- /dev/null +++ b/src/firefly_standalone/assets/startFirefly @@ -0,0 +1,7 @@ +#!/bin/bash + + +fireflyDir="${HOME}/.firefly" +INSTALL_DIR=$(cat "$fireflyDir/applicationPath.txt") +applicationDir="${INSTALL_DIR}/application/current" +"$applicationDir/startFireflyServer.sh" "$@" diff --git a/src/firefly_standalone/assets/startFireflyServer.sh b/src/firefly_standalone/assets/startFireflyServer.sh new file mode 100755 index 000000000..a6e884af2 --- /dev/null +++ b/src/firefly_standalone/assets/startFireflyServer.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +INSTALL_DIR=$(cd "${SCRIPT_DIR}/../.." && pwd) +fireflyDir="${HOME}/.firefly" +applicationDir="${INSTALL_DIR}/application/current" +appNew="${INSTALL_DIR}/application/new" +applicationJars="${applicationDir}/jars" +appLog="${fireflyDir}/logs/application.log" +userOpsFile="${fireflyDir}/user_ops.sh" +ADMIN_USER="admin" +ADMIN_PASSWORD="admin" +MIN_JVM_SIZE=1G +MAX_JVM_SIZE=10G + +# todo - i think we can remove serverConfigDir +serverConfigDir="${HOME}/config" + +debugParams= +loggingLevel="INFO" +doClean="FALSE" +verbose="FALSE" +doExit="FALSE" + +for arg in "$@"; do + if [[ "$arg" == "-debug" || "$arg" == "-d" ]]; then + debugParams="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005" + fi + if [[ "$arg" == "-logDebug" || "$arg" == "-ld" ]]; then + loggingLevel="DEBUG" + fi + if [ "$arg" == "-verbose" ]; then + verbose="TRUE" + fi + if [ "$arg" == "-clean" ]; then + doClean="TRUE" + fi + if [ "$arg" == "-cleanAndExit" ]; then + doClean="TRUE" + doExit="TRUE" + fi +done + + + +if [ "$doClean" == "TRUE" ]; then + /bin/rm -rf "${fireflyDir}/workarea" + echo "removing: ${fireflyDir}/workarea" + /bin/rm -rf "${fireflyDir}/temp" + echo "removing: ${fireflyDir}/temp" + /bin/rm -rf "${fireflyDir}/logs" + echo "removing: ${fireflyDir}/logs" + /bin/rm -rf "${fireflyDir}/webapps" + echo "removing: ${fireflyDir}/webapps" + /bin/rm -rf "${fireflyDir}/work" + echo "removing: ${fireflyDir}/work" + if [ "$doExit" == "TRUE" ]; then + exit 0; + fi + fi + +if [[ -d "$appNew" && -f "$appNew/complete" ]]; then + if [[ -f "$INSTALL_DIR/disableUpdate" ]]; then + echo ">>>>>>>>> Update available but disabled" + else + echo ">>>>>>>>> updating..." + exec "$appNew/../updater.sh" + fi +fi + +if [ ! -f "$applicationDir/jars/firefly.jar" ]; then + FILES_FROM_WAR="WEB-INF/lib/firefly.jar WEB-INF/lib/json-simple-1.1.1.jar WEB-INF/config/version.tag" + (cd $applicationDir && unzip -oj firefly.war ${FILES_FROM_WAR} ) +fi + + + +[ ! -d "${applicationJars}" ] && mkdir "$applicationJars" +[ ! -d "${fireflyDir}/temp" ] && mkdir "${fireflyDir}/temp" +[ ! -d "${fireflyDir}/logs" ] && mkdir "${fireflyDir}/logs" +if [ "$verbose" == "TRUE" ]; then + echo "$applicationDir/*.jar" to "$applicationJars" +fi +if ls $applicationDir/*.jar >/dev/null 2>&1; then + /bin/mv $applicationDir/*.jar "$applicationJars" +fi + + + +JAVA_OPS= +if [ -f "$userOpsFile" ]; then + source $userOpsFile + if [ "$verbose" == "TRUE" ]; then + echo JAVA_OPS = $JAVA_OPS + fi +fi + +PROPS=" \ + -Xms${MIN_JVM_SIZE} -Xmx${MAX_JVM_SIZE} \ + --add-opens java.base/java.util=ALL-UNNAMED \ + -XX:+UnlockExperimentalVMOptions \ + -XX:TrimNativeHeapInterval=30000 \ + -XX:+UseZGC \ + -Dnet.sf.ehcache.enableShutdownHook=true \ + -Dlogging.level=${loggingLevel} \ + -Djava.net.preferIPv4Stack=true \ + -Dwork.directory=${fireflyDir}/workarea \ + -DrunAsDesktopApplication=true \ + -Dvisualize.fits.search.path=${HOME} \ + -Dredis.db.dir=${fireflyDir}/temp/redis \ + -Djava.io.tmpdir=${fireflyDir}/temp \ + -Dalerts.dir=${fireflyDir}/alerts \ + -Dserver_config_dir=${serverConfigDir} \ + -DADMIN_USER=${ADMIN_USER} \ + -DADMIN_PASSWORD=${ADMIN_PASSWORD} \ + -DADMIN_PROTECTED= \ + ${JAVA_OPS} + " + +splash="-splash:${applicationDir}/fireflySplash.png" +dockIcon="-Xdock:icon=${applicationDir}/fireflyDockIcon.png" +nameParam='-Xdock:name=Firefly Server' + +JAVA=$("$applicationDir"/javaInstaller.sh) + +export CLASSPATH=${applicationJars}'/*' +if [ "$verbose" == "TRUE" ]; then + echo + echo Using classpath + echo $CLASSPATH + echo +fi + +{ +echo "------------------------------------------------" +echo "---------- Starting Firefly server" +echo "---------- $(date)" +echo "------------------------------------------------" +echo ${JAVA} ${debugParams} ${splash} ${dockIcon} "${nameParam}" ${PROPS} edu.caltech.ipac.app.FireflyApplication >> "$appLog" +} >> "$appLog" +(cd "$applicationDir" && ${JAVA} ${debugParams} ${splash} ${dockIcon} "${nameParam}" ${PROPS} edu.caltech.ipac.app.FireflyApplication) diff --git a/src/firefly_standalone/assets/updater.sh b/src/firefly_standalone/assets/updater.sh new file mode 100644 index 000000000..4bf9539dc --- /dev/null +++ b/src/firefly_standalone/assets/updater.sh @@ -0,0 +1,19 @@ +#!/bin/bash + + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +INSTALL_DIR=$(cd "${SCRIPT_DIR}/.." && pwd) +applicationRoot="${INSTALL_DIR}/application" +appNew="${applicationRoot}/new" +appCurrent="${applicationRoot}/current" +appOld="${applicationRoot}/old" + + +if [[ -d "$appNew" && -d "$appCurrent" && -f "$appNew/complete" ]]; then + /bin/rm -rf "$appOld" + /bin/mv "$appCurrent" "$appOld" + /bin/mv "$appNew" "$appCurrent" +fi + +exec "$appCurrent/startFireflyServer.sh" + diff --git a/src/firefly_standalone/build.gradle b/src/firefly_standalone/build.gradle new file mode 100644 index 000000000..fe32d250d --- /dev/null +++ b/src/firefly_standalone/build.gradle @@ -0,0 +1,59 @@ +group 'edu.caltech.ipac' + +ext["app-name"] = 'firefly_standalone' + +configurations { + bundled +} + +sourceSets { + main.java.srcDir '.' + main.resources { + srcDirs "." + exclude "**/*.gradle" + } +} + +dependencies { + implementation ':firefly' + bundled 'org.apache.tomcat.embed:tomcat-embed-core:11.0.21' + bundled 'org.apache.tomcat.embed:tomcat-embed-websocket:11.0.21' + bundled 'org.apache.tomcat.embed:tomcat-embed-jasper:11.0.21' +} + +// sourceSets { +// main.java { +// srcDir '**/firefly_standalone/**' +// } +// } + +jar { + archiveFileName = 'firefly_standalone.jar' + include "**/*" + from sourceSets.main.allJava +} + + + +def stageTarget= file("${buildDir}/zipFiles") +def fireflyWar = project(':firefly').tasks.named('war') + + +task stageFiles(type: Copy) { +// dependsOn jar, fireflyWar + dependsOn jar + + into stageTarget + + from { fireflyWar.get().archivePath } + from { jar.archivePath } + from configurations.bundled + + from("${rootDir}/src/firefly_standalone/assets") + } + +task zip(type: Jar, dependsOn: stageFiles) { + archiveFileName = "standalone.zip" + from "${buildDir}/zipFiles" + destinationDirectory = file ("$rootDir/build/dist") +} diff --git a/src/firefly_standalone/java/edu/caltech/ipac/app/FireflyApplication.java b/src/firefly_standalone/java/edu/caltech/ipac/app/FireflyApplication.java new file mode 100644 index 000000000..659f2e1ae --- /dev/null +++ b/src/firefly_standalone/java/edu/caltech/ipac/app/FireflyApplication.java @@ -0,0 +1,438 @@ +package edu.caltech.ipac.app; + +import edu.caltech.ipac.firefly.server.util.VersionUtil; +import edu.caltech.ipac.util.FileUtil; +import edu.caltech.ipac.util.StringUtils; +import edu.caltech.ipac.util.download.FailedRequestException; +import edu.caltech.ipac.util.download.URLDownload; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.startup.Tomcat; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import javax.swing.*; +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Desktop; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.SplashScreen; +import java.awt.SystemTray; +import java.awt.Toolkit; +import java.awt.TrayIcon; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Properties; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + + +public class FireflyApplication { + + private static final File pwd = new File(System.getProperty("user.dir")); + private static final File ffDir = new File(System.getProperty("user.home"), ".firefly"); + private static final File installDir = new File(pwd, "../..").getAbsoluteFile(); + private static final File tomcatDir = ffDir; + private static final File tomcatTmp = new File(tomcatDir, "temp"); + private static final File tomcatLogs = new File(tomcatDir, "logs"); + private static final File applicationRoot = new File(installDir, "application"); + private static final File applicationDir = new File(applicationRoot, "current"); + private static final File cleanupScript= new File(applicationDir,"standalone_cleanup.sh"); + private static final File installScript= new File(applicationDir,"install.sh"); + private static final File portFile = new File(ffDir, "port.txt"); + private static final File dockIconFile= new File(applicationDir,"fireflyDockIcon.png"); + private static final File applicationLogFile= new File(tomcatLogs, "application.log"); + private static final File fireflyWarDir= new File(applicationDir, "firefly-war"); + private static final File versionTagPropFile= new File(applicationDir, "version.tag"); + private static final File versionTextOutFile= new File(ffDir, "version.txt"); + private static final String compressibleMimeType= String.join(",", Arrays.asList( + "text/html", "text/plain", "text/css", "text/javascript", + "application/javascript", "application/json", "application/xml", + "text/xml", "application/x-votable+xml", "application/x-yaml", "application/ld+json", + "image/svg+xml", "text/csv", "application/xhtml+xml", + "application/rss+xml", "application/atom+xml", "application/x-font-ttf", + "font/otf", "font/woff", "font/woff2", + "application/octet-stream" + )); + private static final boolean useLogFile= true; + private static final int DEFAULT_PORT= 8888; + private static String fireflyVersion; + private static String javaVersion; + private static boolean updateAvailable= false; + private static PrintStream terminalOut= null; + private static boolean initComplete= false; + + + + public static void start() throws LifecycleException, URISyntaxException, IOException, InterruptedException { + String terminalDevice = System.getProperty("os.name").toLowerCase().contains("win") + ? "CON" : "/dev/tty"; + fireflyVersion= saveVersion(); + javaVersion = System.getProperty("java.version"); + terminalOut = new PrintStream(new FileOutputStream(terminalDevice)); + ensureFireflyDir(); + var port= getPort(); + + + if (useLogFile) setupLogger(); + + Tomcat tomcat = new Tomcat(); + tomcat.setBaseDir(tomcatDir.getAbsolutePath()); + tomcat.setPort(port); + + + boolean tomcatStarted = false; + if (!isRunning(port)) { + setupUI(tomcat,port); + tomcat.addUser("admin", "admin"); + tomcat.addWebapp("/firefly", fireflyWarDir.getAbsolutePath()); + terminalOut.println("Firefly server starting (is takes a few seconds)..."); + Connector connector= tomcat.getConnector(); + connector.setPort(port); + connector.setProperty("compression", "on"); + connector.setProperty("useSendfile", "false"); + connector.setProperty("compressibleMimeType", compressibleMimeType); + tomcat.start(); + tomcatStarted = true; + } + + if (!tomcatStarted) { + terminalOut.println("Firefly is already running"); + openBrowser(port); + fireflyReadyMessage(port); + System.exit(0); + } + + + hideSplash(); + initComplete= true; + openBrowser(port); + fireflyReadyMessage(port); + Thread.sleep(5 * 1000); // 5 seconds + updateAvailable= doAutoUpdateCheck(); + doWorkAreaCleanup(); + while (tomcat.getServer().getState().isAvailable()) { + Thread.sleep(3600 * 1000); // 1 hour + if (!updateAvailable) updateAvailable= doAutoUpdateCheck(); + doWorkAreaCleanup(); + } + + } + + public static boolean doAutoUpdateCheck() { + boolean updateAvailable= false; + try { + var result= URLDownload.getDataFromURL(new URI("https://api.github.com/repos/Caltech-IPAC/firefly/releases/latest").toURL(),null,null); + var obj= (JSONObject) new JSONParser().parse(result.getResultAsString()); + var availableVersion= (String) obj.get("name"); + var newVerAvailable= isNewVersionAvailable(fireflyVersion,availableVersion); + + String urlStr= null; + var assetsAry= (JSONArray)obj.get("assets"); + if (newVerAvailable && assetsAry!=null && !assetsAry.isEmpty()) { + for(Object entry: assetsAry){ + JSONObject asset= (JSONObject)entry; + if (StringUtils.areEqual((String)asset.get("name"),"standalone.zip")) { + urlStr= (String)asset.get("url"); + } + } + } + String overrideUrlStr= null; +// overrideUrlStr= "/Users/roby/dev/firefly/build/dist/standalone.zip"; // todo remove after testing + if (overrideUrlStr!=null) urlStr= overrideUrlStr; + updateAvailable= urlStr!=null; + if (updateAvailable) doUpdateInstall(urlStr); + + String updateMsg= updateAvailable ? ", Update available (relaunch Firefly to finish update)" : ""; + + terminalOut.println("**** Update Check: Current Version: "+fireflyVersion+ + ", Available version: "+ availableVersion + + ", Java Version: "+ javaVersion + + updateMsg); + + } catch (FailedRequestException | MalformedURLException | URISyntaxException | ParseException e) { + System.out.println(e.toString()); + } + return updateAvailable; + } + + public static boolean isNewVersionAvailable(String currVer, String availableVer) { + if (currVer==null) currVer= "0,0.0"; + if (availableVer==null) availableVer= "0,0.0"; + var cVer= currVer.split("\\."); + var nVer= availableVer.split("\\."); + if (cVer.length!=3 || nVer.length!=3) return false; + var curr= Arrays.stream(cVer).map((s) -> StringUtils.getInt(s,0)).toList(); + var next= Arrays.stream(nVer).map((s) -> StringUtils.getInt(s,0)).toList(); + return (next.get(0)>curr.get(0) || next.get(1)>curr.get(1) || next.get(2)>curr.get(2)); + } + + public static String saveVersion() { + try { + Properties props = new Properties(); + props.load(new FileInputStream(versionTagPropFile)); + VersionUtil.ingestVersion(props); + var vInfo= VersionUtil.getVersionInfo(); + var fVerList= vInfo.stream().filter(kv -> kv.getKey().equals("Firefly Version")).toList(); + if (fVerList.size()==1) { + var vStr= fVerList.getFirst().getValue(); + + String major="0"; + String minor="0"; + String rev="0"; + var phase1= vStr.split("-"); + var realVStr= phase1[0]; + var parts= realVStr.split("\\."); + if (parts.length>1) { + major= parts[0]; + minor= parts[1]; + if (parts.length>2) rev= parts[2]; + } + var version= major+"."+minor+"."+rev; + FileUtil.writeStringToFile(versionTextOutFile, version); + return version; + } + } catch (IOException e) { + System.out.println("failed to get version: " + e.toString()); + } + return null; + } + + public static void doUpdateInstall(String packageUrl) { + ProcessBuilder pb = new ProcessBuilder(installScript.getAbsolutePath(), + "-url", packageUrl, "-asUpdate", + "-installDir", installDir.getAbsolutePath() ); + try { + Process process = pb.start(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + } + int exitCode = process.waitFor(); + if (exitCode != 0) System.out.println("auto update job failed with code: " + exitCode); + + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + + public static void setupLogger() throws IOException { + Logger logger= Logger.getLogger(""); + for (Handler h : logger.getHandlers()) { + logger.removeHandler(h); + } + + + //todo - determine if there is a downside to both writing to application.log + + // setup logger + Handler fileHandler = new FileHandler(applicationLogFile.getAbsolutePath(), true); + fileHandler.setFormatter(new SimpleFormatter()); + fileHandler.setLevel(Level.ALL); + logger.addHandler(fileHandler); + + // set system out for stuff that logger misses + System.setOut(new PrintStream(new FileOutputStream(applicationLogFile,true))); + } + + public static void doWorkAreaCleanup() { + ProcessBuilder pb = new ProcessBuilder(cleanupScript.getAbsolutePath()," --once"); + try { + Process process = pb.start(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + } + int exitCode = process.waitFor(); + if (exitCode != 0) System.out.println("clean up job failed with code: " + exitCode); + + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + + + public static void openBrowser(int port) throws InterruptedException { + if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + try { + Thread.sleep(500); + Desktop.getDesktop().browse(new URI(makeUrlString(port))); + } catch (URISyntaxException | InterruptedException | IOException ignore) { + System.out.println("Could not open browser"); + } + } + } + + public static String makeUrlString(int port) { return "http://localhost:"+port+"/firefly/";} + + public static void ensureFireflyDir() { + confirmDirOrExit(ffDir); + confirmDirOrExit(tomcatDir); + confirmDirOrExit(tomcatTmp); + confirmDirOrExit(tomcatLogs); + } + + public static int getPort() { + try { + if (!portFile.canRead()) return DEFAULT_PORT; + String pStr= FileUtil.readFile(portFile); + if (pStr==null) return DEFAULT_PORT; + return Integer.parseInt(pStr.split("\\s+")[0]); + } catch (IOException | NumberFormatException e) { + return DEFAULT_PORT; + } + } + + private static void confirmDirOrExit(File dir) { + boolean exists = true; + if (!dir.exists()) { + exists = dir.mkdir(); + } + if (!exists || !dir.canWrite()) { + System.out.println("Can't write to " + dir.getAbsolutePath() + " directory"); + System.exit(0); + } + } + + private static void setupUI(Tomcat tomcat, int port) { + System.setProperty("apple.awt.UIElement", "false"); + System.setProperty("apple.laf.useScreenMenuBar", "true"); + System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Firefly"); + setupTray(tomcat, port); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + if (tomcat.getServer().getState().isAvailable()) { + System.out.println("Shutting down Firefly..."); + tomcat.stop(); + tomcat.destroy(); + } + } catch (Exception e) { + e.printStackTrace(); + } + finally { + Runtime.getRuntime().halt(0); + } + })); + if (Desktop.isDesktopSupported()) { + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.APP_ABOUT)) { + desktop.setAboutHandler(e -> showAboutDialog(port) ); + } + } + } + + public static void stopFireflyServer(Tomcat tomcat) { + try { + if (tomcat.getServer().getState().isAvailable()) { + System.out.println("Shutting down Firefly Server..."); + tomcat.stop(); + tomcat.destroy(); + } + } catch (Exception e) { + e.printStackTrace(); + } + finally { + Runtime.getRuntime().halt(0); + } + } + + public static void showAboutDialog(int port) { + String outstr= String.format("Firefly Version: %s
Java Version: %s
", + fireflyVersion, javaVersion); + outstr+= String.format("To load Firefly: %s",makeUrlString(port), makeUrlString(port)); + if (updateAvailable) outstr+= "

"+"Update available (relaunch Firefly to finish update)"; + if (!initComplete)outstr+= "

"+"Server Initializing..."; + JLabel label= new JLabel(outstr); + label.setForeground(Color.black); + label.setText(outstr); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + try { + Desktop.getDesktop().browse(new URI(makeUrlString(port))); + } catch (Exception ignore) { } + } + }); + JOptionPane.showMessageDialog(null, label, "Firefly", JOptionPane.INFORMATION_MESSAGE); + + } + + public static boolean isRunning(int port) { + try (ServerSocket serverSocket = new ServerSocket(port)) { + return false; // Port is available + } catch (IOException e) { + return true; // Port is in use + } + } + + public static void hideSplash() { + SplashScreen splash = SplashScreen.getSplashScreen(); + if (splash != null) splash.close(); + } + + public static void setupTray(Tomcat tomcat, int port) { + System.setProperty("apple.awt.enableTemplateImages", "false"); + if (!SystemTray.isSupported()) { + System.out.println("SystemTray is not supported on this platform."); + return; + } + SystemTray tray = SystemTray.getSystemTray(); + Image image = Toolkit.getDefaultToolkit().getImage(dockIconFile.getAbsolutePath()); + + // Create a popup menu for the icon + PopupMenu popup = new PopupMenu(); + MenuItem exitItem = new MenuItem("Shutdown Firefly Server"); + MenuItem aboutItem = new MenuItem("About Firefly"); + popup.add(aboutItem); + popup.add(exitItem); + exitItem.addActionListener(e -> stopFireflyServer(tomcat)); + aboutItem.addActionListener(e -> showAboutDialog(port) ); + TrayIcon trayIcon = new TrayIcon(image, "Firefly Server", popup); + trayIcon.setImageAutoSize(true); // Automatically scale the image + + try { + tray.add(trayIcon); + } catch (AWTException e) { + System.err.println("TrayIcon could not be added."); + } + } + + + public static void fireflyReadyMessage(int port) throws IOException { + terminalOut.println("\n---------------------------------"); + terminalOut.println("Firefly ready: use URL: " + makeUrlString(port)); + terminalOut.println("---------------------------------\n"); + } + + public static void main(String[] args) { + try { + FireflyApplication.start(); + } catch (Exception e) { + System.out.println("Error starting Firefly Application: " + e.getMessage()); + } + } +} + diff --git a/standalone/install.sh b/standalone/install.sh new file mode 100755 index 000000000..b4173a797 --- /dev/null +++ b/standalone/install.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +INSTALL_DIR="$PWD/firefly" +fireflyDir="${HOME}/.firefly" +applicationPath="current" +url= +#TMP_PACKAGE_URL=file:///Users/roby/dev/firefly/build/dist/standalone.zip + +#todo change asset name to: standalone.jar + +startScript="startFirefly" +altUrl= +installJre="TRUE" +initialInstall="TRUE" +installType="installing" +#if [ -n "$1" ]; then +# altUrl=$1 +#fi + +echo "params: " $* + +while [ $# -gt 0 ]; do + if [[ "$1" == "-url" ]]; then + shift + altUrl=$1 + fi + if [[ "$1" == "-installDir" ]]; then + shift + INSTALL_DIR=$1 + fi + if [[ "$1" == "-asUpdate" ]]; then + installJre="FALSE" + initialInstall="FALSE" + applicationPath="new" + installType="updating" + fi + shift +done + +echo "$installType in $INSTALL_DIR" + +PACKAGE_ASSET_NAME="standalone.zip" +#todo remove next line before PR merge +PACKAGE_ASSET_NAME="test_standalone.zip" +applicationRoot="${INSTALL_DIR}/application" +applicationDir="${applicationRoot}/${applicationPath}" + + +targetPackageFile="${applicationDir}/standalone.zip" + +packageUrl=$(curl -s "https://api.github.com/repos/Caltech-IPAC/firefly/releases/latest" | \ +jq -r '.assets[] | [.name, .browser_download_url] | @tsv' | \ +while IFS=$'\t' read -r asset_name download_url; do + if [ "$asset_name" == $PACKAGE_ASSET_NAME ]; then + echo "$download_url" + fi +done) +if [ -z "$altUrl" ]; then + url=$packageUrl +else + url=$altUrl +fi + +if [ -z "$url" ]; then + echo "No package defined to download, could not find it as a github asset https://github.com/Caltech-IPAC/firefly/releases" + exit 0 +fi + +mkdir "$fireflyDir" +mkdir -p "$applicationDir" +echo "$INSTALL_DIR" > "$fireflyDir/applicationPath.txt" +rm -f "$applicationDir"/complete +echo "install from: $url" +if [[ "$url" == http* ]]; then + curl -sL "$url" > "${targetPackageFile}" +else + cp "$url" "${targetPackageFile}" +fi +(cd "$applicationDir" && unzip -o "${targetPackageFile}") +mkdir "$applicationDir/firefly-war" +(cd "$applicationDir/firefly-war" && unzip -o "${applicationDir}/firefly.war") + +scriptPath=$(realpath "$0") +cp "$scriptPath" "$applicationDir/install.sh" +chmod 775 "$applicationDir/standalone_cleanup.sh" \ + "$applicationDir/$startScript" \ + "$applicationDir/startFireflyServer.sh" \ + "$applicationDir/javaInstaller.sh" \ + "$applicationDir/jreKey.sh" \ + "$applicationDir/updater.sh" \ + "$applicationDir/install.sh" +/bin/mv "$applicationDir/updater.sh" "$applicationRoot" + +if [ "$initialInstall" == "TRUE" ]; then + cp "$applicationDir/$startScript" . + chmod +x "./$startScript" + echo "8888" > "$fireflyDir/port.txt" +fi + +if [ ! -f "$fireflyDir/user_ops.sh" ]; then + echo "JAVA_OPS=" > "$fireflyDir/user_ops.sh" +fi + +if [ "$installJre" == "TRUE" ]; then + "$applicationDir"/javaInstaller.sh +fi +touch "$applicationDir"/complete \ No newline at end of file diff --git a/standalone/remoteInstall.sh b/standalone/remoteInstall.sh new file mode 100644 index 000000000..210ea7896 --- /dev/null +++ b/standalone/remoteInstall.sh @@ -0,0 +1,9 @@ +#!/bin/bash +INSTALL_SCRIPT="https://raw.githubusercontent.com/Caltech-IPAC/firefly/refs/heads/dev/standalone/install.sh" +#todo remove next line before PR merge +INSTALL_SCRIPT="https://raw.githubusercontent.com/Caltech-IPAC/firefly/refs/heads/FIREFLY-1980-standalone/standalone/install.sh" + +curl -s ${INSTALL_SCRIPT} > ./install.sh +chmod +x ./install.sh +./install.sh "$@" +/bin/rm -f ./install.sh \ No newline at end of file