blob: bd0f65ab3988aede78a3d9e5719d5036706c74a0 [file] [log] [blame]
#=============================================================================#
# Copyright (c) 2009, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================#
##
# Shell (PowerShell) script to start R server (for StatET)
##
# Usually you have to change only the CONFIG sections. You should set at least:
# R_HOME
# JAVA_HOME
# Depending on the system configuration, it can be required to set:
# S_HOSTADDRESS
#
# The authentication is set to 'none' by default.
##
# Usage of this script:
# startup.sh <address> [options]
# startup.sh <name> [options]
# It starts the R server asynchronously in background by default.
# <address> the complete RMI-address
# <name> the session name only (the hostname
# should be set in this file)
# Options:
# -wd=<working directory> initial R working directory
# -debug enables debug output and
# runs R in foreground
#
# Note: This script does not start an RMI registry! You have to launch it
# as system daemon or manually (see Java documentation), e.g. by:
# %JAVA_HOME%/bin/rmiregistry.exe -J-Djava.rmi.server.codebase=file:///<path to file org.eclipse.statet.rj.server.jar>
# or in a detached process (not official):
# %JAVA_HOME%/bin/javaw.exe -Djava.rmi.server.codebase=file:///<path to file org.eclipse.statet.rj.server.jar> sun.rmi.registry.RegistryImpl
##
# Author: Stephan Wahlbrink <sw@wahlbrink.eu>
###############################################################################
###############################################################################
# SCRIPT - INIT / READING PARAMETERS ##########################################
###############################################################################
param([String] $ADDRESS)
if ([String]::IsNullOrEmpty("$ADDRESS"))
{
echo "Missing address or name for R server"
exit -1
}
$S_NAME=$ADDRESS -replace '.*\/([^/]+)$', '$1'
$S_HOSTADDRESS=""
$S_REGISTRY_PORT=""
if ( $ADDRESS -ne $S_NAME ) {
$S_HOSTADDRESS=$ADDRESS -replace '[^/]*\/\/([^:/]*).*', '$1'
$S_REGISTRY_PORT=$ADDRESS -replace '[^/]*\/\/[^:/]*:?([0-9]*)\/.*', '$1'
}
$WD=$HOME
$SCRIPT=$MyInvocation.MyCommand.Path
foreach ($1 in $Args) {
switch -wildcard ("$1") {
"-wd=*" {
$WD=$1.Substring(4)
}
# "-host=*" {
# $S_HOSTADDRESS=$1.Substring(6)
# }
"-debug*" {
$DEBUG=1
echo "Debug mode enabled"
}
"-dev*" {
$DEV=1
echo "Development mode enabled"
}
default {
echo "Unknown parameter: $1"
}
}
}
###############################################################################
###############################################################################
# CONFIG - SYSTEM SETTINGS ####################################################
###############################################################################
# Configure the startup in the following sections
###############################################################################
# Required system specific settings
#
# Set the path to home of R and Java.
# If parts of the R installation (e.g. the documentation) are located in not
# sub-directories of R home, it is often required to set additional variables
# specifying the several installation locations (see example).
#
# Example:
# R_HOME="/usr/lib/R"
# R_ARCH="/x64"
# R_DOC_DIR="/usr/share/doc/R"
# R_SHARE_DIR="/usr/share/R"
# R_INCLUDE_DIR="/usr/include/R"
# R_LIBS_SITE="/usr/local/lib/R/site-library"
# JAVA_HOME="C:\Program Files\Java\jdk-1.8.0"
$R_HOME=""
$R_ARCH="/x64"
$JAVA_HOME=""
###############################################################################
# Set the home and work directory of this R server.
# The home must contain the jar files of this server, if this file is in this
# directory, you don't have to change the value.
# The working directory is for files like log files
##
# Example:
# RJS_HOME=`dirname "$SCRIPT"`
# RJS_WORK="$HOME/R/rjserver/work"
$RJS_HOME=Split-Path -Path $SCRIPT -Parent
$RJS_WORK="$HOME/R/rjserver/work"
###############################################################################
# Set explicitly the hostname and port you want to use to access the RMI
# registry/R server.
# It is recommended to use the IP address instead of a name.
# By default, the hostname is extracted form the specified RMI address
# (script parameter). Nevertheless there are some reasons to set it explicitly
# here, e.g.:
# - For SSH tunnel connections '127.0.0.1' (localhost) is sufficient;
# recommend, if no other network connections are used; and required if the
# public IP address is blocked by the firewall.
# - To make sure that the correct IP address is set even the hostname is
# used in the RMI address.
##
# Usage:
# S_HOSTADDRESS=<ip or hostname>
# S_REGISTRY_PORT=<port of rmi-registry>
# Example:
# S_HOSTADDRESS=192.168.1.80
#$S_HOSTADDRESS=""
###############################################################################
# Add additional java options here
##
# Example:
# JAVA_OPTS="-server -Djava.net.preferIPv4Stack=true"
# JAVA_OPTS="-server -Dorg.eclipse.statet.rj.rmi.disableSocketFactory=true"
$JAVA_OPTS=@("-server")
$JAVA_OPTS_LIB=@()
###############################################################################
# CONFIG - AUTHENTICATION METHODS #############################################
###############################################################################
# You must specify the method (exactly one) to use for authentication when
# clients wants to connect to the R.
# There are several methods available. The methods provided by default
# are described in the following subsections. To change the method uncomment
# the lines of method you want to use and comment the previous AUTH definition.
##
# General usage:
# RJ parm: -auth=<method-id>[:<config>]
# -auth=<classname>[:<config>]
#
# <config> option depends on the selected method
###############################################################################
# Authentication method: disabled / 'none'
#
# Disables authentication. Anybody can connect to R. Use it only if you are in
# a secure environment! All users can connect to R get full user rights!
##
# General usage:
# RJ param: -auth=none
#
# Script Usage:
# AUTH=none
$AUTH="none"
###############################################################################
# Authentication method: password file / 'name-pass'
#
# Authentication using loginname-password combination.
##
# General usage:
# RJ Param: -auth=name-pass:file=<passwordfile>
#
# Script usage:
# AUTH="name-pass:file"
# AUTH_PW_FILE="$HOME/R/rjserver/logins"
#
# <passwordfile> is the path to a property file with
# pairs of loginname and password, for example:
# myname=mypassword
# Make sure that only authorized users can read this file!
#$AUTH="name-pass:file"
#$AUTH_PW_FILE="$HOME/R/rjserver/logins"
###############################################################################
# Authentication method: local user account / 'local-shaj'
#
# Authentication using your local loginname-password combination (PAM).
# The 'Shaj' library is required for this method. It is provided in sources and
# binary form for several platforms. If no binary match your environment, you
# have to build it for your system. You find the files inside the folder
# shaj
# of this remotetools package.
##
# General Usage:
# RJ Param: -auth=local-shaj
# Java Prop: java.library.path=<folder of library>
#
# Script Usage:
# AUTH="local-shaj"
# AUTH_SHAJ_LD_DIR="<folder of library>"
# Example:
# AUTH=local-shaj
# AUTH_SHAJ_LD_DIR="$RJS_HOME/shaj/linux-x64"
#$AUTH="local-shaj"
#$AUTH_SHAJ_LD_DIR="$RJS_HOME/shaj/<platform>"
###############################################################################
# Authentication method: ssh / 'fx' (exchange over file)
#
# Authentication for automatic startup (via ssh by StatET).
##
# General Usage:
# RJ Param: -auth=fx:file=<keyfile>
#
# Script Usage:
# AUTH="fx:file"
# AUTH_FX_FILE="<keyfile>"
# AUTH_FX_USER=$USER
# AUTH_FX_MASK="600"
#
# <keyfile> a (empty). The fs permission to edit the files represents the
# right to login into R, so:
# The file must be writable for authorized user only!
# If the script setup is used, the files is created automatically and
# the permission is set according to AUTH_FX_USER and AUTH_FX_MASK
#$AUTH="fx:file"
$AUTH_FX_FILE="$RJS_WORK/session-$S_NAME.lock"
$AUTH_FX_USER=[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$AUTH_FX_MASK=new-object System.Security.AccessControl.FileSystemAccessRule $AUTH_FX_USER, 'FullControl', 'Allow'
###############################################################################
# SCRIPT - STARTUP SERVER #####################################################
###############################################################################
# Usually you don't have to edit the lines below
$PATH_SEP=";"
if ( !( Test-Path "$RJS_WORK" ) ) {
# New-Item -ItemType directory -Force -Path "$RJS_WORK"
mkdir -p "$RJS_WORK"
}
## Final RMI address
if ( $S_HOSTADDRESS ) {
$S_ADDRESS="//$S_HOSTADDRESS"
if ( $S_REGISTRY_PORT ) {
$S_ADDRESS="$S_ADDRESS:$S_REGISTRY_PORT"
}
$S_ADDRESS="$S_ADDRESS/$S_NAME"
} else {
$S_ADDRESS="///$S_NAME"
}
## Finish auth configuration
if ( $FORCE_AUTH ) {
$AUTH="$FORCE_AUTH"
}
if ( $AUTH -eq "name-pass:file" ) {
$AUTH="name-pass:file=$AUTH_PW_FILE"
}
if ( $AUTH -eq "local-shaj" ) {
$AUTH="local-shaj"
$JAVA_OPTS_LIB="$JAVA_OPTS_LIB$PATH_SEP$AUTH_SHAJ_LD_DIR"
$JAVA_CP="$JAVA_CP$PATH_SEP$RJS_HOME/shaj/auth.jar"
}
if ( "$AUTH" -eq "fx:file" ) {
$AUTH="fx:file=$AUTH_FX_FILE"
$AUTH_FX_FOLDER=Split-Path -Path $AUTH_FX_FILE -Parent
mkdir -p "$AUTH_FX_FOLDER"
echo "00000000" > "$AUTH_FX_FILE"
$ACL=Get-Acl "$AUTH_FX_FILE"
$ACL.SetAccessRule($AUTH_FX_MASK)
#$SystemAccessRule = new-object System.Security.AccessControl.FileSystemAccessRule 'SYSTEM', 'FullControl', 'Allow'
#$ACL.SetAccessRule($SystemAccessRule)
$ACL.SetAccessRuleProtection($True, $False)
Set-Acl "$AUTH_FX_FILE" $ACL
}
$OPTS=@("-auth=$AUTH")
if ( $DEBUG ) {
$OPTS+="-verbose"
}
## RJ package implementation to load
$RLIB_PATHS=@("$R_LIBS", "$R_LIBS_USER", "$R_LIBS_SITE", "$R_HOME/library")
:ITER_PATHS foreach ( $LIB_PATH in $RLIB_PATHS ) {
$ITEMS= $LIB_PATH.split(";")
foreach ( $ITEM in $ITEMS ) {
if (( $ITEM ) -and ( Test-Path "$ITEM/rj/DESCRIPTION" )) {
echo "R package 'rj' found at '$ITEM/rj'."
$RJS_BOOT_CP="$ITEM/rj/server/rj-boot.jar"
break ITER_PATHS;
}
}
}
if ( ! $RJS_BOOT_CP ) {
echo "R package 'rj' not found."
exit -2
}
$RJS_BOOT_CLASS="RJSrv"
## Java config
$JAVA_EXE="$JAVA_HOME/bin/java.exe"
if ( $DEV )
{
$JAVA_CP="$RJS_BOOT_CP$PATH_SEP$RJS_HOME/../org.eclipse.statet.rj.server/bin$PATH_SEP$RJS_HOME/../org.eclipse.statet.rj.data/bin$PATH_SEP$RJS_HOME/../org.eclipse.statet.jcommons.util/bin$PATH_SEP$RJS_HOME/bin$PATH_SEP$RJS_HOME/binShaj"
$RMI_BASE="file://$RJS_HOME/../org.eclipse.statet.rj.server/bin"
$RJAVA_CP=""
} else {
$JAVA_CP="$RJS_BOOT_CP$PATH_SEP$RJS_HOME/org.eclipse.statet.rj.server.jar$PATH_SEP$RJS_HOME/org.eclipse.statet.rj.data.jar$PATH_SEP$RJS_HOME/org.eclipse.statet.jcommons.util.jar$PATH_SEP$JAVA_CP"
$RMI_BASE="file://$RJS_HOME/org.eclipse.statet.rj.server.jar"
$RJAVA_CP=""
}
$JAVA_OPTS+="-Djava.security.policy=$RJS_HOME/security.policy"
$JAVA_OPTS+="-Djava.rmi.server.codebase=$RMI_BASE"
if ( $S_HOSTADDRESS ) {
$JAVA_OPTS+="-Djava.rmi.server.hostname=$S_HOSTADDRESS"
}
if ( $JAVA_OPTS_LIB ) {
$JAVA_OPTS+="-Djava.library.path=$JAVA_OPTS_LIB"
}
if ( $RJAVA_CP ) {
$JAVA_OPTS+="-Drjava.class.path=$RJAVA_CP"
}
## Other environment
$PATH="$R_HOME/bin$R_ARCH$PATH_SEP$Env:PATH"
$LD_LIBRARY_PATH="$R_HOME/lib"
$env:PATH = $PATH
$env:JAVA_HOME = $JAVA_HOME
$env:R_HOME = $R_HOME
$env:R_ARCH = $R_ARCH
$env:R_LIBS = $R_LIBS
$env:R_LIBS_USER = $R_LIBS_USER
$env:R_LIBS_SITE = $R_LIBS_SITE
$env:R_DOC_DIR = $R_DOC_DIR
$env:R_SHARE_DIR = $R_SHARE_DIR
$env:R_INCLUDE_DIR = $R_INCLUDE_DIR
$env:LC_ALL = $LC_ALL
cd $WD
$START_ARGS=@('-cp',$JAVA_CP)+$JAVA_OPTS+@($RJS_BOOT_CLASS,'start',$S_ADDRESS)+$OPTS
#echo "$JAVA_EXE $START_ARGS"
if ( $DEBUG ) {
# Set-ExecutionPolicy RemoteSigned -Scope Process -Force
echo "S_HOSTADDRESS= $S_HOSTADDRESS"
echo "S_REGISTRY_PORT= $S_REGISTRY_PORT"
echo "PATH= $PATH"
echo "LD_LIBRARY_PATH= $LD_LIBRARY_PATH"
echo "R_HOME= $R_HOME"
echo "R_ARCH= $R_ARCH"
echo "JAVA_HOME= $JAVA_HOME"
echo "JAVA_EXE= $JAVA_EXE"
echo "CLASSPATH= $JAVA_CP"
echo "JAVA_OPTIONS= $JAVA_OPTS"
echo "AUTH= $AUTH"
# Start server directly
& $JAVA_EXE $START_ARGS
$START_EXIT=$LastExitCode
exit $START_EXIT
} else {
# First check if running or dead server is already bound
$CLEAN_ARGS=@('-cp',$JAVA_CP)+$JAVA_OPTS+@($RJS_BOOT_CLASS,'clean',$S_ADDRESS)
& $JAVA_EXE $CLEAN_ARGS
$CLEAN_EXIT=$LastExitcode
if ( $CLEAN_EXIT -ne 0 ) {
echo "Check and cleanup of old server failed (CODE=$CLEAN_EXIT), cancelling startup."
exit $CLEAN_EXIT
}
# Start server detached
$JAVA_EXE="$JAVA_HOME/bin/javaw.exe"
$START_PROCESS=Start-Process $JAVA_EXE -NoNewWindow -PassThru `
-RedirectStandardOutput "$RJS_WORK/session-$S_NAME.out" `
-RedirectStandardError "$RJS_WORK/session-$S_NAME.err" `
$START_ARGS
#$START_EXIT=
$START_PID=$START_PROCESS.Id
if ( ! $START_PROCESS.HasExited ) {
echo "Started server in background (PID=$START_PID)."
exit 0
} else {
echo "Startup failed"
exit -1
}
}