���� JFIF �� � ( %"1"%)+...383,7(-.-
![]() Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.20 System : Linux st2.domain.com 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 User : apache ( 48) PHP Version : 7.4.20 Disable Function : NONE Directory : /usr/local/FlashphonerWebCallServer/bin/ |
#!/bin/bash # # Startup script for Flashphoner WebCallServer # # chkconfig: - 80 20 # description: Flashphoner WebCallServer provides WEB to SIP gateway services # #### BEGIN INIT INFO # Provides: WebCallServer # Required-Start: $time $local_fs $remote_fs $network # Required-Stop: $time $local_fs $remote_fs # Default-Start: 3 4 5 # Default-Stop: S 0 1 2 6 # Short-Description: WebCallServer Init Script # Description: WebCallServer Init Script ### END INIT INFO # Import functions from init.d FUNCTIONS_EXIST=false if [ -f /etc/rc.d/init.d/functions ] ; then . /etc/rc.d/init.d/functions FUNCTIONS_EXIST=true fi if [ -f /etc/init.d/functions ] ; then . /etc/init.d/functions FUNCTIONS_EXIST=true fi if ! $FUNCTIONS_EXIST ; then failure() { return 0 } success() { return 0 } fi # Global variables configuration # Declare global variables function declareGlobals() { PRODUCT=FlashphonerWebCallServer WCS_HOME="/usr/local/$PRODUCT" FLASHPHONER_USER="flashphoner" } # Get product name function getProduct() { echo "$PRODUCT" } # Get WCS home directory function getHome() { echo "$WCS_HOME" } # Get WCS user name function getUser() { echo "$FLASHPHONER_USER" } # Get flashphoner.properties config function getWCSConfig() { echo "$(getHome)/conf/flashphoner.properties" } # Get database.yml config function getDatabaseYml() { echo "$(getHome)/conf/database.yml" } # Environment variables configuration # Configure environment variables function setUpEvironment() { local envConfig="$(getHome)/bin/setenv.sh" # Clean Java options to prevent dubbinng while re-initializing #WCS-3034 WCS_JAVA_OPTS="" WCS_SERVER_OPTS="" [ -r "$envConfig" ] && . "$envConfig" } # Get Java options function getJavaOpts() { echo "$WCS_JAVA_OPTS" } # Get server options function getServerOpts() { echo "$WCS_SERVER_OPTS" } # Get library path function getLdLibraryPath() { echo "$LD_LIBRARY_PATH" } # Get Java executable function getJavaExec() { local javaExec=$_EXECJAVA if [[ "$javaExec" == "" ]]; then javaExec=`which java` fi echo "$javaExec" } # Get non root mode setting function getNonRoot() { echo "$WCS_NON_ROOT" } # Check root mode to use in conditions function isRootMode() { if [ "$(getNonRoot)" == "false" ]; then true; return else false; return fi } # Check non root mode to use in conditions function isNonRootMode() { if [ "$(getNonRoot)" == "true" ]; then true; return else false; return fi } # Get PID file name depending on root mode function getPidFile() { local pidFile="FlashphonerMainWebCallServer.pid" local pidPath="" if isRootMode; then pidPath="/var/run" else pidPath="$(getHome)/bin" fi echo "$pidPath/$pidFile" } # Get lock file name depending on root mode function getLockFile() { local lockFile="$(getProduct)" local lockPath="" if isRootMode; then lockPath="/var/run" [ -w "/var/lock/subsys" ] && lockPath=/var/lock/subsys else lockPath="$(getHome)/bin" fi echo "$lockPath/$lockFile" } # Get file descriptors limit function getFDLimit() { local fdLimit=$WCS_FD_LIMIT if [[ "$fdLimit" == "" ]]; then fdLimit=20000 fi echo "$fdLimit" } # Get startup log file name function getStartupLogFile() { local startupLogFile=$WCS_STARTUP_LOG if [[ "$startupLogFile" == "" ]]; then startupLogFile=$(getHome)/logs/startup.log fi echo "$startupLogFile" } # Get enterprise builds URL function getEnterpriseUrl() { echo "$ENTERPRISE_URL" } # Get login to download enterprise builds function getEnterpriseLogin() { echo "$ENTERPRISE_LOGIN" } # Get password to download enterprise builds function getEnterprisePasswd() { echo "$ENTERPRISE_PASSWD" } # Logging functions # Declare logging variables function declareLog() { local logFile=$1 DEBUG=${DEBUG:-false} DEFAULT_LOG=${DEFAULT_LOG:-} setDefaultLogFile $logFile } # Check if debug log enabled function isDebugEnabled() { if [[ ! -z $DEBUG ]]; then $DEBUG; return else false; return fi } # Enable debug logging function enableDebug() { DEBUG=true } # Disable debug logging function disableDebug() { DEBUG=false } # Get default log file function getDefaultLogFile() { echo "$DEFAULT_LOG" } # Set default log file function setDefaultLogFile() { local logFile=$1 [[ -z $logFile ]] && return 1 if checkLogPath $logFile; then DEFAULT_LOG=$logFile fi } # # Check if log file path exists and make the dir if needed function checkLogPath() { local logFile=$1 local result=0 [[ -z $logFile ]] && return 1 logPath=$(dirname "$logFile") if [[ ! -d $logPath ]]; then mkdir -p $logPath result=$? fi return $result } # Form log timestamp function logDate() { local dateToLog=`echo "[$(date '+%Y-%m-%d %H:%M:%S')]"` echo "$dateToLog" } # Write to a log file function writeLog() { local level=$1 local message=$2 local logFile=$3 local owner=$(getCurrentUser) local logPath="" local callerFuncName="" [[ -z $logFile ]] && logFile=$(getDefaultLogFile) if [[ "$level" == "" || "$message" == "" || "$logFile" == "" ]]; then return 1 fi if [[ -f $logFile ]]; then owner=$(ls -l $logFile | awk '{print $3}'); else checkLogPath $logFile [[ $? -ne 0 ]] && return 1 fi # Determine caller function name for callerFuncName in ${FUNCNAME[@]}; do if [[ "$callerFuncName" == "${FUNCNAME[0]}" || "$callerFuncName" =~ ^log ]]; then continue else break fi done if [[ $owner != $(getCurrentUser) ]]; then # The log file is owned by someone else, try to sudo to it sudo -u $owner echo -e "$(logDate) $level: $message" >> $logFile else echo -e "$(logDate) $level $callerFuncName - $message" >> $logFile fi } # Write INFO level message function logInfo() { local message=$1 local logFile=$2 writeLog "INFO" "$message" "$logFile" } # Write WARN level message function logWarn() { local message=$1 local logFile=$2 writeLog "WARN" "$message" "$logFile" } # Write ERROR level message function logError() { local message=$1 local logFile=$2 writeLog "ERROR" "$message" "$logFile" } # Write DEBUG level message function logDebug() { local message=$1 local logFile=$2 if isDebugEnabled; then writeLog "DEBUG" "$message" "$logFile" fi } # Various helper functions # Check if user exists in system function isUser() { local user=$1 if [[ -z $user ]]; then user=$(getUser) fi if [[ "$(getent passwd $1)" =~ "^$1" ]]; then true; return else false; return fi } # Get current user running script function getCurrentUser() { echo "$(whoami)" } # Get daemon type function getDaemonType() { local daemonType=`ps --no-headers -o comm 1` echo "$daemonType" } # Check if service is running function isService() { # Check service only if systemd used #WCS-3034 if [[ $(getDaemonType) != 'systemd' ]]; then false; return fi if systemctl is-active --quiet webcallserver.service; then true; return else false; return fi } # Check if the script is running from root function isScriptRunningFromRoot() { if [[ "$(getCurrentUser)" == "root" ]]; then true; return else false; return fi } # Set file system item owner to user function setOwner() { local user=$1 local object=$2 if [[ "$user" == "" || "$object" == "" ]]; then return 1 fi if isScriptRunningFromRoot; then chown -R $user $object fi } # Get Java version function getJavaVersion() { local jdkVersion=`java -version 2>&1` local javaFullVersion=`echo $jdkVersion | head -1 | cut -d" " -f 3 | tr -d \"` local javaMajor=`echo $javaFullVersion | cut -d \. -f 1` local javaMinor=0 local javaVersion=0 if [[ $javaMajor -eq 1 ]]; then javaMinor=`echo $java_ver | cut -d \. -f 2` if [[ $javaMinor -ge 8 ]]; then javaVersion=$javaMinor fi elif [[ $javaMajor -ge 8 ]]; then javaVersion=$javaMajor fi logDebug "Java version $javaVersion" echo "$javaVersion" } # Get user running the process by pid function getUserByPid() { local pid=$1 local user=`ps -o uname= -p "$pid"` logDebug "Process $pid running as user $user" echo "$user" } # Amazon cloud operations # Declare Amazon cloud constants function declareCloudConstants_Amazon() { METADATA_URL_AMAZON=${METADATA_URL_AMAZON:-"http://169.254.169.254/latest/meta-data"} } # Detect a cloud function isCloud_Amazon() { declareCloudConstants_Amazon local kernel=$(uname -r | grep amzn) local os=$(cat /etc/issue | grep -e "Amazon\|AMI") local metadata=$(curl --max-time 1 --insecure -s -i -o /dev/null -w '%{http_code}' $METADATA_URL_AMAZON/ | grep 200) if [[ $kernel || $os || $metadata == "200" ]]; then true; return else false; return fi } # Get cloud public IP function getPublicIp_Amazon() { local publicIp=$(curl -s -f $METADATA_URL_AMAZON/public-ipv4) if [[ $? -ne 0 ]]; then publicIp="" fi logDebug "Public ip detecting using command 'curl -s -f $METADATA_URL_AMAZON/public-ipv4'" echo "$publicIp" } # Get cloud public IP function getPrivateIp_Amazon() { local privateIp=$(curl -s -f $METADATA_URL_AMAZON/local-ipv4) if [[ $? -ne 0 ]]; then privateIp="" fi logDebug "Private ip detecting using command 'curl -s -f $METADATA_URL_AMAZON/local-ipv4'" echo "$privateIp" } # Set admin password to instanse id function setAdminPasswd_Amazon() { local instanceId="" if [ ! -d "$(getHome)/logs/server_logs" ]; then if grep "admin:" "$(getDatabaseYml)" > /dev/null 2>&1; then # Set InstanceId as admin password instanceId=$(echo -n $(wget -q -O - $METADATA_URL_AMAZON/instance-id) | md5sum | cut -f1 -d"-" | tr -d " ") sed -i -e "/admin:/s/password:\ [0-9A-Za-z]*,/password:\ $instanceId,/" "$(getDatabaseYml)" fi fi } # Google cloud operations # Declare Amazon cloud constants function declareCloudConstants_Google() { METADATA_URL_GOOGLE=${METADATA_URL_GOOGLE:-"http://metadata.google.internal/computeMetadata/v1/instance"} HEADER_GOOGLE=${HEADER_GOOGLE:-'-H Metadata-Flavor:Google'} } # Detect a cloud function isCloud_Google() { declareCloudConstants_Google local metadata=$(curl --insecure -s -i -o /dev/null -w '%{http_code}' $HEADER_GOOGLE $METADATA_URL_GOOGLE/ | grep 200) if [[ $metadata == "200" ]]; then true; return else false; return fi } # Get cloud public IP function getPublicIp_Google() { local publicIp=$(curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/access-configs/0/external-ip) if [[ $? -ne 0 ]]; then publicIp="" fi logDebug "Public ip detecting using command 'curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/access-configs/0/external-ip'" echo "$publicIp" } # Get cloud public IP function getPrivateIp_Google() { local privateIp=$(curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/ip) if [[ $? -ne 0 ]]; then privateIp="" fi logDebug "Public ip detecting using command 'curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/ip'" echo "$privateIp" } # Set admin password to instanse id function setAdminPasswd_Google() { return 0 } # Abstarct cloud checking functions # Declare clouds list function declareClouds() { CLOUDS=( "Amazon" "Google" ) CLOUD="" } # Get clouds list function getClouds() { echo "${CLOUDS[@]}" } # Add cloud to list function addCloud() { CLOUDS+=($1) } # Get current cloud name function getCurrentCloud() { echo "$CLOUD" } # Set current cloud name function setCurrentCloud() { local currentCloud=$1 if [[ ! -z $currentCloud ]]; then CLOUD=$currentCloud fi } # Check if certain cloud detector function exists function isCloudFunc() { local func=$1 if [[ "$(declare -fF $func)" ]]; then true; return else false; return fi } # Update settings to work behind NAT function updateSettings() { local cloud=$1 local wcsConfig=$(getWCSConfig) if ! grep "client_mode" $wcsConfig > /dev/null ; then echo -e "\nclient_mode=false" >> $wcsConfig fi if ! grep "rtc_ice_add_local_component" $wcsConfig > /dev/null ; then echo -e "\nrtc_ice_add_local_component=true" >> $wcsConfig fi isCloudFunc updateSettings_$cloud && updateSettings_$cloud } # Helper function to update IP settings function updateIpSettings() { local privateIp=$1 local publicIp=$2 # Use function from IP module to write IPs to the config writeIps $privateIp $publicIp } # Update IP addresses if allowed function updateIps() { local privateIp=$1 local publicIp=$2 local wcsConfig=$(getWCSConfig) local holdIpSettings="hold_ip_settings" local holdIpValue="" holdIpValue=$(cat $wcsConfig | grep "$holdIpSettings" | cut -d"=" -f2) if [[ $holdIpValue == "true" ]]; then return 0 fi logDebug "Cloud IPs detected: ip=$publicIp ip_local=$privateIp" if [[ "$publicIp" != "" && "$privateIp" != "" ]]; then updateIpSettings $privateIp $publicIp elif [[ "$privateIp" != "" ]]; then updateIpSettings $privateIp $privateIp else sed -i -e "s/^\(ip[ \t]*=\|ip_local[ \t]*=\|cdn_ip[ \t]*=\).*\$/\1/" $wcsConfig fi } # Check a cloud function checkCloud() { local cloud=$1 local publicIp="" local privateIp="" if isCloud_$cloud; then isCloudFunc getPublicIp_$cloud && publicIp=$(getPublicIp_$cloud) isCloudFunc getPrivateIp_$cloud && privateIp=$(getPrivateIp_$cloud) updateIps $privateIp $publicIp updateSettings $cloud isCloudFunc setAdminPasswd_$cloud && setAdminPasswd_$cloud true; return else false; return fi } # Main cloud detection function: check clouds until the first match function checkClouds() { local cloud="" declareClouds for cloud in $(getClouds); do if checkCloud $cloud; then setCurrentCloud $cloud logInfo "Cloud environment detected like $cloud" $(getStartupLogFile) break fi done } # Cloud env detection checker to allow non-cloud specific operations function isNotInCloud() { local currentCloud="$(getCurrentCloud)" if [[ -z $currentCloud ]]; then true; return else false; return fi } # Directories management functions # Make a dir if not exists and set owner if needed function makeDir() { local dirName=$1 [ -z $dirName ] && return 1 [ ! -d "$dirName" ] && mkdir -p $dirName [ isDirActionRequired ] && setOwner $(getUser) $dirName } # Set access rights to default dirs (and make then if not exist) function setAccessRightsToDirs() { local defaultDirs=( logs hls records media snapshots report metrics ) local dirName="" for dir in ${defaultDirs[@]}; do makeDir $(getHome)/$dir done } # Helper function to check if access rights action required function isDirActionRequired() { if [[ isUser && isScriptRunningFromRoot ]]; then true; return else false; return fi } # Licence checking function function checkLicense() { local licenseFile="$(getHome)/conf/flashphoner.license" if [ ! -f "$licenseFile" ]; then echo "" echo "ERROR: Missing license file: (${licenseFile})" echo "You must activate license." echo "Execute the following commands to do it:" echo "" echo "cd $WCS_APP_HOME/bin" echo "./activation.sh" echo "" return 1 fi $(getJavaExec) -Dcom.flashphoner.fms.AppHome="$(getHome)" -cp "$(getHome)/lib/*" com.flashphoner.server.license.ExpiredUpdates if [ "$?" -eq "1" ]; then exit 1; fi } # Server state checking functions # Check if server is running function isServerRunning() { pidFile=$(getPidFile) lockFile=$(getLockFile) if [[ -f $pidFile && -f $lockFile && -d /proc/$(cat $pidFile) ]]; then logDebug "Server is running, pid $(cat $pidFile)" true; return else logDebug "Server is not running" false; return fi } # Check local status function localStatus() { if isServerRunning; then echo "$(getProduct) started" elif [[ -f $(getLockFile) ]]; then echo "$(getProduct) not running but subsys locked" else echo "$(getProduct) not running" fi return 0 } # WCS starting functions # Declare startup global variables function declareStart() { SERVER_PID={$SERVER_PID:-} } # Get server pid function getServerPid() { echo "$SERVER_PID" } # Set server pid function setServerPid() { local pid=$1 if [[ ! -z $pid ]]; then SERVER_PID=$pid fi } # Check Java optiions before start function checkJavaOptions() { local startupLog=$(getStartupLogFile) logInfo "Checking JVM options" $startupLog $(getJavaExec) -version $(getJavaOpts) >> $startupLog 2>> $startupLog return $? } # Form WCS running options function getRunOptions() { local wcsRunOptions="$(getJavaOpts) -Dcom.flashphoner.fms.AppHome=$(getHome) -Djava.library.path=$(getHome)/lib/so:$(getHome)/lib -DWCS_NON_ROOT=$(getNonRoot) $(getServerOpts)" echo "$wcsRunOptions" } # Start WCS sudoing to default user function startWithSudo() { local standalone=$1 local user=$(getUser) local pid="" local parent="" if [[ "$standalone" == "standalone" ]]; then sudo -u $user env LD_LIBRARY_PATH=$(getLdLibraryPath) $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server else logInfo "Starting $(getProduct) as user $user" sudo -u $user env LD_LIBRARY_PATH=$(getLdLibraryPath) $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server > /dev/null 2>&1 & fi # Get sudo command pid parent=$! sleep 1 # Get main process pid pid=$(ps -o pid= --ppid $parent) setServerPid "$pid" } # Start WCS as current user function startAsCurrentUser() { local standalone=$1 local pid="" if [[ "$standalone" == "standalone" ]]; then $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server else logInfo "Starting $(getProduct)" $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server > /dev/null 2>&1 & fi pid=$! setServerPid "$pid" } # Start WCS depending on user and mode function startServer() { local standalone=$1 local nonRootUser=$(getUser) local currentUser=$(getCurrentUser) local startAsCurrent=true local pid="" if isScriptRunningFromRoot; then # When runing from root, always start as root startAsCurrent=true elif isRootMode; then # When running as non root fail if server is in root mode logError "$(getProduct) cannot be started from user $nonRootUser, please switch WCS_NON_ROOT in setenv.sh to true!" $(getStartupLogFile) echo "" return 1 elif [[ $nonRootUser == $currentUser ]]; then # When running as predefined user in non root mode, start as predefined user startAsCurrent=true else # When running as other non root user in non root mode, start sudoing to predefined user startAsCurrent=false fi logDebug "startAsCurrent=$startAsCurrent, standalone=$standalone, startup options=$(getRunOptions)" if $startAsCurrent; then startAsCurrentUser $standalone else startWithSudo $standalone fi } # Tweak hosts file for hostname if needed function tweakHostsFile() { if [[ ! `getent hosts \`hostname\`` ]]; then echo "127.0.0.1 $(hostname)" >> /etc/hosts fi } # Make symlink to records folder function makeRecordsSymlink() { local recordsSymlink="$(getHome)/client/records" if [[ ! -L $recordsSymlink && -d $(getHome)/records ]]; then ln -sf $(getHome)/records $recordsSymlink fi } # Main startup function function start() { local standalone=$1 local msgAlreadyRunning="$(getProduct) is already running" local msgIpAddressesFail="$(getProduct) can't start due to incorrect Java options" local msgJavaOptionsFail="$(getProduct) can't start due to incorrect Java options" local msgCantStart="$(getProduct) can't start" local msgStart="$(getProduct) startup" local pid="" declareStart #Check if server is already running if isServerRunning; then logInfo $msgAlreadyRunning $(getStartupLogFile) echo $"$msgAlreadyRunning" return 0 fi # Check license (and dont't go futher if updates expired checkLicense # If we have enough permissions if isScriptRunningFromRoot; then # Tweak hosts file tweakHostsFile # set open file descriptors limit ulimit -n $(getFDLimit) fi # Check cloud environment checkClouds # If we are not in cloud, check and detect IP addresses if they are not set if isNotInCloud; then setIp # Do not start if setIp failed [[ $? -ne 0 ]] && failure "$msgIpAddressesFail" && return 1 fi echo -n $"$(getProduct): starting" # Set default foders access permissions if we starting from root if isDirActionRequired; then setAccessRightsToDirs fi # Check Java options before start if ! checkJavaOptions; then logError "$msgJavaOptionsFail" $(getStartupLogFile) echo -e "$msgJavaOptionsFail" failure "$msgJavaOptionsFail" return 1 fi # Set signal trapper when starting in standalone mode if [[ "$standalone" == "standalone" ]]; then trap 'echo -e "\n######### Stop standalone mode #########\n"; exit 0' 2 echo -e "\n######### Start standalone mode #########\n" fi # Start with user choosing logic startServer $standalone pid=$(getServerPid) # Fail if no pid returned if [[ "$pid" == "" ]]; then failure "$msgCantStart" return 1 fi # Check if process is started sleep 1 if [[ `ps -p $pid | grep -c $pid` == '0' ]]; then failure "$msgCantStart" return 1 fi # Save pid to file if not exists yet if [[ ! -f $(getPidFile) ]]; then echo $pid > $(getPidFile) fi success "$msgStart" echo touch $(getLockFile) # Clean up obsolete GC logs rm -rf $(getHome)/logs/*.0 # Make symlink to records folder makeRecordsSymlink # Set permissions to all logs created if starting first time as root sleep 1 if isDirActionRequired; then setOwner $(getUser) "$(getHome)/logs" [ isNonRootMode ] && setOwner $(getUser) "$(getLockFile)" [ isNonRootMode ] && setOwner $(getUser) "$(getPidFile)" fi return 0 } # WCS stopping functions # Stop WCS process function stop() { local msgStopping="$(getProduct): stopping" local msgStopped="$(getProduct) stopped" local msgNotRunning="$(getProduct): not running" local msgShutdown="$(getProduct): shutdown" local pid="" local userRunFrom="" local stopped=false if isServerRunning; then echo -e $"$msgStopping" read pid < $(getPidFile) userRunFrom=$(getUserByPid $pid) kill -15 $pid rm -f $(getPidFile) rm -f $(getLockFile) stopped=true logInfo "$msgStopped" $(getStartupLogFile) # Set access right to dirs if the stopped instance was run from non prefdefined user if [[ $userRunFrom != $(getUser) && isDirActionRequired ]]; then setAccessRightsToDirs fi else echo -n $"msgNotRunning" fi if $stopped; then success "msgShutdown" fi echo return 0 } # IP configuration functions # Declare IP variables function declareIp() { CONST_IP_UNDEFINED="undefined" IP_EXTERNAL=${IP_EXTERNAL:-$CONST_IP_UNDEFINED} IP_LOCAL=${IP_LOCAL:-$CONST_IP_UNDEFINED} LOCAL_IP_COUNT=${LOCAL_IP_COUNT:-0} } # Get external IP value function getExternalIp() { echo "$IP_EXTERNAL" } # Set external IP value function setExternalIp() { local externalIp=$1 if [[ ! -z $externalIp ]]; then IP_EXTERNAL=$externalIp fi } # Get internal IP value function getInternalIp() { echo "$IP_INTERNAL" } # Set external IP value function setInternalIp() { local internalIp=$1 if [[ ! -z $internalIp ]]; then IP_INTERNAL=$internalIp fi } # Get local IP count function getLocalIpCount() { echo "$LOCAL_IP_COUNT" } # Set local IP count function setLocalIpCount() { local localIpCount=$1 if [[ ! -z $localIpCount ]]; then LOCAL_IP_COUNT=$localIpCount fi } # Check if address is empty or undefined function isEmptyOrUndef() { local ip=$1 if [[ -z $ip || "$ip" == "$CONST_IP_UNDEFINED" ]]; then true; return else false; return fi } # Count local interfaces function countLocalIfaces() { local localIpCount=0 local i for i in $(hostname -I); do ((localIpCount++)) done setLocalIpCount $localIpCount } # Find local IP in hostname generated list function findLocalIp() { local ip=$1 local localIp=$CONST_IP_UNDEFINED local i for i in $(hostname -I) ; do if [[ "$ip" == "$i" ]]; then localIp=$ip fi done echo "$localIp" } # Get external IP from public detector site with error code checking function getIpByUrl() { local url=$1 local httpResponse="" local httpBody="" local httpStatus=400 if [[ -z $url ]]; then echo "" return 1 fi httpResponse=`/usr/bin/curl -s -w "HTTPSTATUS:%{http_code}" $url` httpBody=$(echo "$httpResponse" | sed -E 's/HTTPSTATUS\:[0-9]{3}$//') httpStatus=$(echo "$httpResponse" | tr -d '\n' | sed -E 's/.*HTTPSTATUS:([0-9]{3})$/\1/') if [[ $httpStatus -eq 200 ]]; then echo "$httpBody" return 0 fi echo "" return 1 } # Detect external IP function detectExternalIp() { local extIp1="$(getIpByUrl https://api.ipify.org)" local extIp2="$(getIpByUrl ipinfo.io/ip)" local extIp=$CONST_IP_UNDEFINED if [[ $extIp1 != '' ]]; then extIp=$extIp1 elif [[ $extIp2 != '' ]]; then extIp=$extIp2 fi echo "$extIp" } # Get IPs from hostname list function getIpsFromHostname() { local localIp=$(getInternalIp) local externalIp=$(getExternalIp) logDebug "localIp=$localIp, externalIp=$externalIp" if isEmptyOrUndef $localIp; then localIp=$(hostname -I | tr -d '[:space:]') fi if isEmptyOrUndef $externalIp; then setExternalIp $localIp fi setInternalIp $localIp } # Ask user for IPs function askUserForIps() { local localIp=$(getInternalIp) local externalIp=$(getExternalIp) local addr="" if [[ "$localIp" == "$CONST_IP_UNDEFINED" ]];then read -p "What is your server LAN IP? " addr else read -p "We have found $(getLocalIpCount) IPs, what should be used for WCS: $(hostname -I)? " addr fi logDebug "User choose address $addr" if isEmptyOrUndef $externalIp; then setExternalIp $addr fi setInternalIp $addr } # Try to configure IPs manually or semi-manually function configureIps() { local localIpCount=$(getLocalIpCount) logDebug "Configuring IP: localIpCount=$localIpCount" if [[ $localIpCount -eq 1 ]]; then getIpsFromHostname else askUserForIps fi } # Ask user to confirm the server is in private network function askUserForLan() { local extIp=$1 echo -e "We have found these IP on your server\n" echo -e "External IP\t\tLocal IPs" echo -e "$extIp\t\t$(hostname -I)\n" read -p "Is your server located in your LAN [yes/no] ? " confirm if [[ $confirm = n* ]]; then logDebug "extIp=$extIp" [[ $extIp != "$CONST_IP_UNDEFINED" ]] && setExternalIp $extIp fi configureIps echo -e "Thanks. We have configured:\n" echo -e "ip = $(getExternalIp)" echo -e "ip_local = $(getInternalIp)" echo -e "\n" read -p "Press any key to continue..." } # Main IP detection function function detectIps { local interactive=$1 local extIp="$(detectExternalIp)" local localIp="$(findLocalIp $extIp)" logDebug "Detecting IP: extIp=$extIp, localIp=$localIp" if [[ "$extIp" == "$localIp" && "$extIp" != "$CONST_IP_UNDEFINED" ]]; then setExternalIp $extIp setInternalIp $localIp elif [[ ! -z $interactive ]]; then # Ask user in intercative mode only, if set-ip command is used askUserForLan $extIp fi } # Check if IPs are not configured in settings function isIpsEmpty() { local privateIp="" local publicIp="" local wcsConfig=$(getWCSConfig) publicIp=`sed -n -e "s/^ip[ \t]*=[ \t]*\(.*\)/\1/p" $wcsConfig` privateIp=`sed -n -e "s/^ip_local[ \t]*=[ \t]*\(.*\)/\1/p" $wcsConfig` if [[ -z $publicIp || -z $privateIp ]]; then true; return else false; return fi } # Helper function to write IP settings function writeIp() { local setting=$1 local value=$2 local wcsConfig="$(getWCSConfig)" [[ -z $setting || -z $value ]] && return 1 if [[ "$(grep -e "^$setting[ \t]*=" $wcsConfig)" != "" ]]; then logDebug "There is $setting setting, replacing $setting=$value" sed -i -e "s/^\($setting[ \t]*=\).*\$/\1$value/" $wcsConfig else logDebug "No $setting setting, adding $setting=$value" echo -e "\n$setting=$value" >> $wcsConfig fi return 0 } # Write IPs to config file function writeIps() { local privateIp=$1 local publicIp=$2 local wcsConfig="$(getWCSConfig)" local result=1 if isEmptyOrUndef "$publicIp" || isEmptyOrUndef "$privateIp"; then # Do not write undefined addresses return 1 fi if writeIp "ip" "$publicIp" && writeIp "ip_local" "$privateIp"; then result=0 sed -i -e "s/^\(cdn_ip[ \t]*=\).*\$/\1$privateIp/" $wcsConfig fi return $result } # IP configuration main function function setIp() { local override=$1 local confirm="no" local result=0 local msgFail="Cannot detect IP addresses automatically, please edit flashphoner.properties file to set them manually or run 'webcallserver set-ip' command" local msgSuccess="IP addresses are set" local msgAskRestart="$msgSuccess, please restart WCS to apply" declareIp countLocalIfaces if isIpsEmpty; then confirm="yes" elif [[ "$override" == "override" ]]; then read -p "IP adresses are already set, re-configure them [yes/no] ? " confirm fi if [[ $confirm = y* ]]; then detectIps $override writeIps "$(getInternalIp)" "$(getExternalIp)" result=$? else # Cancelled or no need to change IPs, just return return 0 fi if [[ $result -eq 0 ]]; then [[ "$override" == "override" ]] && echo "$msgAskRestart" logInfo "$msgSuccess" $(getStartupLogFile) else logError "$msgFail" $(getStartupLogFile) echo "$msgFail" fi return $result } # WCS update functions # Declare update globals function declareUpdate() { SITE=${SITE:-flashphoner.com} LOCAL_VERSION=${LOCAL_VERSION:-} REMOTE_VERSION=${REMOTE_VERSION:-} UPDATE_LOG_FILE=${UPDATE_LOG_FILE:-"/tmp/wcs_update.log"} UPDATE_FULL_URL=${UPDATE_FULL_URL:-} UPDATE_LOGIN=${UPDATE_LOGIN:-} UPDATE_PASSWD=${UPDATE_PASSWD:-} START_AS_SERVICE=${START_AS_SERVICE:-false} setLocalVersion setRemoteVersion } # Get site domain name function getSite() { echo "$SITE" } # Get site URL function getSiteUrl() { echo "https://$SITE" } # Check if site available function isSiteUp() { ping -c1 -W1 -q $(getSite) &>/dev/null if [[ $? -eq 0 ]]; then true; return else false; return fi } # Get local version function getLocalVersion() { echo "$LOCAL_VERSION" } # Get major local version function getMajorVersion() { local localVersion=$(getLocalVersion) echo "${localVersion:0:3}" } # Set local version function setLocalVersion() { local localVersionFile="$(getHome)/conf/WCS.version" local localVersion="" if [[ -z $LOCAL_VERSION ]]; then localVersion=`cat $localVersionFile | cut -f1 -d-` LOCAL_VERSION=$localVersion fi } # Get remote version function getRemoteVersion() { echo "$REMOTE_VERSION" } # Set remote version function setRemoteVersion() { local remoteVersion=$1 local remoteVersionFile="$(getSiteUrl)/downloads/builds/WCS/$(getMajorVersion)/currentVersion" if [[ -z $remoteVersion ]]; then [[ -z $REMOTE_VERSION && isSiteUp ]] && REMOTE_VERSION=`curl -s --connect-timeout 5 -m 5 $remoteVersionFile` else # Set to predefined build REMOTE_VERSION=$remoteVersion fi } # Get update log file name function getUpdateLog() { echo "$UPDATE_LOG_FILE" } # Get full url to download build function getFullUpdateUrl() { echo "$UPDATE_FULL_URL" } # Set full url to download build function setFullUpdateUrl() { local fullUrl=$1 if [[ ! -z $fullUrl ]]; then UPDATE_FULL_URL=$fullUrl fi } # Get login to download build function getLogin() { echo "$UPDATE_LOGIN" } # Set login to download build function setLogin() { local credentials=$1 if [[ ! -z $credentials ]]; then UPDATE_LOGIN=$credentials fi } # Get passwd to download build function getPasswd() { echo "$UPDATE_PASSWD" } # Set passwd to download build function setPasswd() { local credentials=$1 if [[ ! -z $credentials ]]; then UPDATE_PASSWD=$credentials fi } # Get start as service status function getRunService() { $START_AS_SERVICE; return } # Set start as service status function setRunService() { START_AS_SERVICE=$1 } # Stop server carefully before update function stopBeforeUpdate() { logDebug "Stopping before update" if isService; then # We should carefully stop service before updating #WCS-3024 systemctl stop webcallserver setRunService true else stop fi } # Start server carefully after update function startAfterUpdate() { logDebug "Starting after update" if getRunService; then # We should carefully start service after updating #WCS-3024 systemctl restart webcallserver else # Re-init environment to update PID and lock file paths #WCS-3024 setUpEvironment start fi } # Ask user to stop server if running function tryToStopServer() { local arg="" local confirm="" # Stop if @yes" is passed in commandline for arg in "$@"; do if [[ $arg == "yes" ]]; then stopBeforeUpdate return 0 fi done # Ask user to stop echo ">>> You have to stop $(getProduct) before update." read -p ">>> Stop now [yes/no] ? " confirm if [[ $confirm = y* ]]; then stopBeforeUpdate else echo " Abort updating" return 1 fi return 0 } # Execute download command function executeDownloadCommand() { local url=$1 local login=$2 local passwd=$3 logDebug "Downloading $url" wget $login $passwd --timeout=10 --no-check-certificate $url -O wcs5-server.tar.gz -o $(getUpdateLog) } # Execute build extstance check command function executeCheckCommand() { local url=$1 local login=$2 local passwd=$3 logDebug "Checking $url" wget $login $passwd --timeout=5 --tries=1 --waitretry=0 --no-check-certificate -S --spider $url 2>&1 | grep 'HTTP/1.1 200 OK' > /dev/nul 2>&1 } # Prepare enterprise download URL and credentials function prepareEnterpriseDownload() { local build=$1 local url="" local majorVersion=$(getMajorVersion) local enterpriseUrl=$(getEnterpriseUrl) local enterpriseLogin=$(getEnterpriseLogin) local enterprisePasswd=$(getEnterprisePasswd) if [[ "$enterpriseUrl" != "" ]]; then setRemoteVersion $majorVersion.$build-enterprise url=`echo $enterpriseUrl | sed s/build-enterprise/$build-enterprise/` setFullUpdateUrl $url setLogin "--user=$(echo $enterpriseLogin | base64 --decode)" setPasswd "--password=$(echo $enterprisePasswd | base64 --decode)" else echo ">>> You have no access to enterprise builds" fi } # Prepare certain build doenload URL function prepareBuildDownload() { local build=$1 local enterprise=$2 local url="" local majorVersion=$(getMajorVersion) if [[ "$enterprise" == "enterprise" ]]; then prepareEnterpriseDownload $build else setRemoteVersion $majorVersion.$build url=$(getSiteUrl)/downloads/builds/WCS/$majorVersion/FlashphonerWebCallServer-$majorVersion.$build.tar.gz setFullUpdateUrl $url fi } # Check if there is update function checkUpdate() { local localVersion="" local remoteVersion="" declareUpdate if ! isSiteUp; then echo ">>> $(getSiteUrl) is not available, cannot check new version" return 1; fi localVersion=$(getLocalVersion) remoteVersion=$(getRemoteVersion) logDebug "Checking for update: local $localVersion, remote $remoteVersion" if [[ $remoteVersion == "" ]]; then echo ">>> Remote version is not available, cannot check new version" return 1 elif [[ $localVersion < $remoteVersion ]]; then echo ">>> New version available: $remoteVersion" echo ">>> Your version: $localVersion" else echo ">>> You have latest version: $localVersion" fi return 0 } # Main update function function update() { local restart=false declareUpdate if ! isScriptRunningFromRoot; then echo ">>> You must be root to update, try to use sudo" return 1 fi if ! isSiteUp; then echo ">>> $(getSiteUrl) is not available, cannot update" return 1 fi if [ "$1" -eq "$1" ] 2>/dev/null; then # A build number is set as first parameter, get download command for it prepareBuildDownload "$@" else # Check for a new version checkUpdate # Return if there is no updates [ $? -ne 0 ] && return 1 setFullUpdateUrl $(getSiteUrl)/download-wcs5.2-server.tar.gz fi if [[ -z $(getFullUpdateUrl) ]]; then echo ">>> Cannot build download URL, abort update" return 1 fi # Check if build is available to download if executeCheckCommand $(getFullUpdateUrl) $(getLogin) $(getPasswd); then echo ">>> Version $(getRemoteVersion) is available, try to update" else echo ">>> Version $(getRemoteVersion) is not available" return 1 fi # Check if server is running if isServerRunning; then restart=true tryToStopServer $@ # Return if server is not stopped [ $? -ne 0 ] && return 1 fi echo ">>> Updating $(getProduct)" cd /tmp echo ">>> Downloading $(getRemoteVersion) build" executeDownloadCommand $(getFullUpdateUrl) $(getLogin) $(getPasswd) if [ $? -eq 0 ]; then mkdir -p /tmp/wcs_latest && rm -rf /tmp/wcs_latest/* && tar xzf wcs5-server.tar.gz -C /tmp/wcs_latest --strip-components 1 cd /tmp/wcs_latest chmod +x install.sh /bin/bash ./install.sh -silent cd /tmp rm -rf /tmp/wcs_latest /tmp/wcs5-server.tar.gz echo -e ">>> $(getProduct) updated to $(getRemoteVersion)\n" else echo ">>> Error during downloading tar, please, check $(getUpdateLog)" return 1 fi # Restart server only if it was running before update #WCS-3034 if $restart; then echo -e ">>> Starting $(getProduct)\n" startAfterUpdate fi return 0 } # Main module # Usage displaying function usage() { echo "Usage: $(basename $0) [OPTIONS]" echo -e " start [standalone]\t\t\tstart WCS (add standalone to display stdout for debugging purposes)" echo -e " stop\t\t\t\t\tstop WCS" echo -e " restart\t\t\t\trestart WCS" echo -e " status\t\t\t\tdisplay WCS status" echo -e " check_update\t\t\t\tcheck if WCS update available" echo -e " update [<build> [enterprise]] [yes]\tupdate WCS (add build number to update to this build)" echo -e " set-ip\t\t\t\tdetect and set IP parameters" return 1 } # Main script function function main() { local action="" local standalone="" local build="" local enterprise="" local forceUpdate="" declareGlobals setUpEvironment declareLog $(getStartupLogFile) # Parse command line arguments action=$1 shift while [[ $# -gt 0 ]]; do case $1 in standalone) [[ "$action" == "start" ]] && standalone=$1 shift ;; --debug) enableDebug shift ;; [0-9]*) [[ "$action" == "update" ]] && build=$1 shift ;; enterprise) [[ "$action" == "update" ]] && enterprise=$1 shift ;; yes) [[ "$action" == "update" ]] && forceUpdate=$1 shift ;; *) usage return 1 ;; esac done # Do the action case $action in start) start $standalone ;; stop) stop ;; status) localstatus ;; restart) stop start ;; check_update) checkUpdate ;; update) update $build $enterprise $forceUpdate ;; set-ip) setIp override ;; *) usage ;; esac } main "$@" exit $?