Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
rtcds.in 7.69 KiB
#!/bin/bash -e

log() {
    echo "$@" >&2
}

RTS_VERSION=${RTS_VERSION:-__VERSION__}
if [[ "$RTS_VERSION" =~ ._VERSION_. ]] ; then
    log "RTS_VERSION variable not set."
    exit 1
fi

# this should define all USER_VARS (see below)
ENV_FILE=${RTS_ENV:-/etc/advligorts/env}
source "$ENV_FILE" 2>/dev/null || true

SITE=${SITE^^*}
site=${SITE,,*}
IFO=${IFO^^*}
ifo=${IFO,,*}

RCG_SRC=${RCG_SRC:-/usr/share/advligorts/src}
RCG_BUILDD=${RCG_BUILDD:-/var/cache/advligorts/rcg-$RTS_VERSION}
# FIXME: the RCG hard-codes /opt/rtcds as the root
RCG_TARGET=/opt/rtcds/${site}/${ifo}
RTS_USER=${RTS_USER:-controls}

# search paths for C source code
CDS_SRC=${CDS_SRC:-$RCG_LIB_PATH}
CDS_IFO_SRC=${CDS_IFO_SRC:-$CDS_SRC}

# add RCG module source to lib path
# FIXME: rename RCG_MOD_PATH
RCG_LIB_PATH=$RCG_LIB_PATH:${RCG_SRC}/src/epics/simLink/:${RCG_SRC}/src/epics/simLink/lib

USER_VARS=(SITE IFO RCG_LIB_PATH)
LIST_VARS=(RTS_VERSION ${USER_VARS[@]} RCG_SRC RCG_BUILDD RCG_TARGET RTS_USER)
EXPORT_VARS=(${USER_VARS[@]} site ifo CDS_SRC CDS_IFO_SRC)

##################################################

check_env() {
    for var in ${USER_VARS[*]} ; do
	if [ ! "${!var}" ] ; then
	    log "ERROR: variable '$var' not set."
	    log "The following environment variables must be set (in e.g. $ENV_FILE):"
	    for vv in ${USER_VARS[*]} ; do
		log "   $vv"
	    done
	    exit 1
	fi
    done
    for var in ${LIST_VARS[*]} ; do
	log "$var=${!var}"
    done
    for var in ${EXPORT_VARS[*]} ; do
	export $var
    done
}

prep_buildd() {
    if [ -d "$RCG_BUILDD" ] ; then
        return
    fi
    log "creating RCG_BUILDD $RCG_BUILDD..."
    if sudo -u $RTS_USER mkdir -p "$RCG_BUILDD" 2>/dev/null ; then
        sudo -u $RTS_USER chown $RTS_USER:$RTS_USER "$RCG_BUILDD"
    elif sudo mkdir -p "$RCG_BUILDD" 2>/dev/null ; then
        sudo chown $RTS_USER:$RTS_USER "$RCG_BUILDD"
    else
        log "Could not create build directory '$RCG_BUILDD' (owner: $RTS_USER:$RTS_USER)."
        log "Please create manually to continue."
        exit 1
    fi
    log "configuring RCG_BUILDD $RCG_BUILDD..."
    cd "$RCG_BUILDD"
    sudo -u $RTS_USER "$RCG_SRC"/configure
}

prep_target(){
    if [ -d "$RCG_TARGET" ] ; then
        return
    fi
    log "creating RCG_TARGET $RCG_TARGET..."
    if sudo -u $RTS_USER mkdir -p "$RCG_TARGET" 2>/dev/null ; then
        sudo -u $RTS_USER chown $RTS_USER:$RTS_USER "$RCG_TARGET"
    elif sudo mkdir -p "$RCG_TARGET" 2>/dev/null ; then
        sudo chown $RTS_USER:$RTS_USER "$RCG_TARGET"
    else
        log "Could not create target directory '$RCG_TARGET' (owner: $RTS_USER:$RTS_USER)."
        log "Please create manually to continue."
        exit 1
    fi
    sudo -u $RTS_USER mkdir -p ${RCG_TARGET}/{target,chans/tmp}
}

########

_systemctl_list_units() {
    systemctl list-units --all --full --plain --no-legend --no-pager rts@*.target \
	| awk '{print $1}' \
	| sed 's/^rts@\([a-z0-9]*\)\.target$/\1/'
}

list_host_sys() {
    _systemctl_list_units | grep 'iop' || true
    _systemctl_list_units | grep -v 'iop' || true
}

check_host_sys() {
    for sys ; do
	if ! systemctl is-enabled "$sys" ; then
	    log "System '$sys' is not enabled on this system (enable first)."
	    exit 4
	fi
    done
}

########

build_sys() {
    cd $RCG_BUILDD
    for sys ; do
	log "### building $sys..."
	make $sys
    done
}

install_sys() {
    cd $RCG_BUILDD
    for sys ; do
	log "### installing $sys..."
	make install-$sys
    done
}

start_sys() {
    for sys ; do
	log "### starting $sys..."
	sudo systemctl start rts@${sys}.target
    done
}

stop_sys() {
    for sys ; do
	log "### stopping $sys..."
	#${SCRIPTD}/kill${sys}
	sudo systemctl stop rts@${sys}.target
    done
}

enable_sys() {
    for sys ; do
	log "### enabling $sys..."
	sudo systemctl enable rts@${sys}.target
    done
}

disable_sys() {
    for sys ; do
	log "### disabling $sys..."
	sudo systemctl disable rts@${sys}.target
    done
}

_lsmod() {
    local systems=($(list_host_sys))
    local rts=(mbuf gpstime)
    local omx=(open_mx)
    local dis=(dis_kosif dis_dx dis_irm)

    # FIXME: how to test for needed modules?
    modules=(${rts[*]} ${omx[*]} ${dis[*]})
    
    local allloaded=
    for m in ${modules[*]}; do
	md=$(lsmod | grep "^${m}") || true
	if [ -z "$md" ] ; then
	    printf "%-18s ***NOT LOADED***\n" "$m"
	    allloaded=1
	else
	    echo "$md"
	fi
    done
    if [ "$systems" ] ; then
	echo
	for m in ${systems[*]}; do
	    md=$(lsmod | grep "^${m}") || true
	    if [ -z "$md" ] ; then
		printf "%-18s ***NOT LOADED***\n" "$m"
		allloaded=1
	    else
		echo "$md"
	    fi
	done
    fi
    if [ "$allloaded" ] ; then
	return 4
    fi
}

############################################################

usage() {
    echo "Usage: $(basename $0) <command> [args]

Advanced LIGO Real Time System control interface.

Available commands:

  build|make <sys>           build system
  install <sys>              install system

  list|ls                    list systems for host
  start <sys>...|--all       start systems
  restart <sys>...|--all     restart running systems
  stop|kill <sys>...|--all   stop running systems
  enable <sys>...|--all      enable system start at boot
  disable <sys>...|--all     disable system start at boot

  blog <sys>                 show last build log for system
    -i                         print log paths
  lsmod                      list loaded RTS kernel modules
  env                        print system environment info
  version|--version|-v       print version
  help|--help|-h             this help
"
}

if [ "$1" ] ; then
    cmd=$1
    shift
else
    log "You must specify a command."
    log
    usage
    exit 1
fi

case $cmd in
    'build'|'make')
	if [ -z "$1" ] ; then
	    log "You must specify at least one system to build."
	    exit 2
	fi
	check_env
	prep_buildd
	build_sys $@
	;;
    'install')
	if [ -z "$1" ] ; then
	    log "You must specify at least one system to install."
	    exit 2
	fi
	check_env
	prep_target
	install_sys $@
	;;
    'start')
	if [ -z "$1" ] ; then
	    log "You must specify at least one system to start (or '--all')."
	    exit 2
	fi
	if [[ "$1" == '--all' ]] ; then
	    start_sys $(list_host_sys)
	else
	    check_host_sys $@
	    start_sys $@
	fi
	;;
    'restart')
	if [ -z "$1" ] ; then
	    log "You must specify at least one system to restart (or '--all')."
	    exit 2
	fi
	if [[ "$1" == '--all' ]] ; then
	    # we do this in reverse so the IOP is stopped last
	    stop_sys $(list_host_sys | tac)
	    start_sys $(list_host_sys)
	else
	    check_host_sys $@
	    stop_sys $@
	    start_sys $@
	fi
	;;
    'stop'|'kill')
	if [ -z "$1" ] ; then
	    log "You must specify at least one system to stop (or '--all')."
	    exit 2
	fi
	if [[ "$1" == '--all' ]] ; then
	    # we do this in reverse so the IOP is stopped last
	    stop_sys $(list_host_sys | tac)
	else
	    check_host_sys $@
	    stop_sys $@
	fi
	;;
    'enable'|'disable')
	if [ -z "$1" ] ; then
	    log "You must specify at least one system to $cmd (or '--all')."
	    exit 2
	fi
	if [[ "$1" == '--all' ]] ; then
	    # we do this in reverse so the IOP is stopped last
	    ${cmd}_sys $(list_host_sys | tac)
	else
	    ${cmd}_sys $@
	fi
	;;
    'blog')
	format=full
	if [[ "$1" == '-i' ]] ; then
	    format=info
	    shift
	fi
	if [ -z "$1" ] ; then
	    log "You must specify system to view."
	    exit 2
	fi
	olog="${RCG_BUILDD}/${1}.log"
	elog="${RCG_BUILDD}/${1}_error.log"
	echo $olog
	case "$format" in
	    info)
		ls -al "$olog" "$elog"
		;;
	    full)
		sed 's/^/stdout:/' < "$olog"
		sed 's/^/stderr:/' < "$elog"
		;;
	esac
	;;
    'list'|'ls')
	list_host_sys
	;;
    'lsmod'|'lsmods')
	_lsmod
	;;
    'env')
	check_env
	;;
    'version'|'v'|'vers'|'-v'|'--version')
	echo $RTS_VERSION
	;;
    'help'|'-h'|'--help')
	usage
	;;
    *)
	log "Unknown command: $cmd"
	log
	usage
	exit 1
	;;
esac