Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Table of Contents
* [Automatic](#automatic)
* [Details](#details)
* [Options](#options)
* [HTCondor jobs](#htcondor-jobs)
* [Caveats](#caveats)
* [bind_condor.sh](#bind_condorsh)
* [Usage](#usage-1)
Expand Down Expand Up @@ -147,10 +148,19 @@ or placed in a file `~/.callhostrc` (automatically detected and sourced by `call
```bash
CALL_HOST_STATUS=disable cmssw-el7 ...
```
* To enable debug printouts by default:
```bash
export CALL_HOST_DEBUG=enable
```
or to toggle debug printouts on or off during a session:
```bash
call_host_debug
```
(if you call this inside a container, it will not silence debug printouts from the host)

### Caveats
### HTCondor jobs

* cmslpc autodetection of the correct operating system for jobs is currently based on the host OS. Therefore, if you are submitting jobs in a container with a different OS, you will have to manually specify in your JDL file (the `X` in `condor_submit X`):
* On cmslpc, the container OS will automatically be detected (for RHEL-based containers) and used for HTCondor jobs. To specify the job OS manually instead, include in your JDL file (the `X` in `condor_submit X`):
```
+DesiredOS = SL7
```
Expand All @@ -160,6 +170,9 @@ or placed in a file `~/.callhostrc` (automatically detected and sourced by `call
+ApptainerImage = "/path/to/your/container"
```
* Using the `ENV()` function in the JDL file may not function as intended, since it will be evaluated on the host node, rather than inside the container with your environment set up.

### Caveats

* Commands that require tty input (such as `nano` or `emacs -nw`) will not work with `call_host`.
* Occasionally, if a command fails (especially when calling multiple commands separated by semicolons), the pipe will break and the terminal will appear to hang. The message "Interrupted system call" may be shown.
It is necessary to exit and reenter the container (in order to create a new pipe) if this occurs.
Expand Down
67 changes: 58 additions & 9 deletions call_host.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# shellcheck disable=SC2155
# shellcheck disable=SC2155,SC2223

# check for configuration
CALL_HOST_CONFIG=~/.callhostrc
Expand All @@ -8,14 +8,21 @@ if [ -f "$CALL_HOST_CONFIG" ]; then
source "$CALL_HOST_CONFIG"
fi

# validation
call_host_valid(){
VAR_TO_VALIDATE="$1"
# shellcheck disable=SC2076
if [[ ! " enable disable " =~ " ${!VAR_TO_VALIDATE} " ]]; then
echo "Warning: unsupported value ${!VAR_TO_VALIDATE} for $VAR_TO_VALIDATE; disabling"
eval "export $VAR_TO_VALIDATE=disable"
fi
}

# default values
# shellcheck disable=SC2076
if [ -z "$CALL_HOST_STATUS" ]; then
export CALL_HOST_STATUS=enable
elif [[ ! " enable disable " =~ " $CALL_HOST_STATUS " ]]; then
echo "Warning: unsupported value $CALL_HOST_STATUS for CALL_HOST_STATUS; disabling"
export CALL_HOST_STATUS=disable
fi
: ${CALL_HOST_STATUS:=enable}
call_host_valid CALL_HOST_STATUS
: ${CALL_HOST_DEBUG:=disable}
call_host_valid CALL_HOST_DEBUG
if [ -z "$CALL_HOST_DIR" ]; then
if [[ "$(uname -a)" == *cms*.fnal.gov* ]]; then
export CALL_HOST_DIR=~/nobackup/pipes
Expand Down Expand Up @@ -51,6 +58,42 @@ call_host_disable(){
export CALL_HOST_STATUS=disable
}
export -f call_host_disable
# single toggle for debug printouts
call_host_debug(){
if [ "$CALL_HOST_DEBUG" = "enable" ]; then
export CALL_HOST_DEBUG=disable
else
export CALL_HOST_DEBUG=enable
fi
}
export -f call_host_debug
# helper for debug printouts
call_host_debug_print(){
if [ "$CALL_HOST_DEBUG" = "enable" ]; then
echo "$@"
fi
}
export -f call_host_debug_print

call_host_plugin_01(){
# provide htcondor-specific info in container
declare -A CONDOR_OS
CONDOR_OS[7]="SL7"
CONDOR_OS[8]="EL8"
CONDOR_OS[9]="EL9"

# todo: only activate if function name (call_host args) includes condor?
if [[ "$(uname -a)" == *cms*.fnal.gov* ]]; then
OS_VERSION=$(sed -nr 's/[^0-9]*([0-9]+).*/\1/p' /etc/redhat-release 2>&1)
CONDOR_OS_VAL="${CONDOR_OS[$OS_VERSION]}"
if [ -n "$CONDOR_OS_VAL" ]; then
echo "export FERMIHTC_OS_OVERRIDE=$CONDOR_OS_VAL;"
else
call_host_debug_print "echo \"could not determine condor OS from $OS_VERSION\";"
fi
fi
}
export -f call_host_plugin_01

# concept based on https://stackoverflow.com/questions/32163955/how-to-run-shell-script-on-host-from-docker-container

Expand All @@ -63,6 +106,7 @@ listenhost(){
# using { bash -c ... } >& is less fragile than eval
tmpexit=0
cmd="$(cat "$1")"
call_host_debug_print "cmd: $cmd"
{
bash -c "$cmd" || tmpexit=$?
} >& "$2"
Expand Down Expand Up @@ -99,7 +143,12 @@ call_host(){
else
FUNCTMP="${FUNCNAME[0]}"
fi
echo "cd $PWD; $FUNCTMP $*" > "$HOSTPIPE"

# extra environment settings; set every time because commands are executed on host in subshell
# todo: evolve into full plugin system that executes detected functions/executables in order (like config.d)
EXTRA="$(call_host_plugin_01)"

echo "cd $PWD; $EXTRA $FUNCTMP $*" > "$HOSTPIPE"
cat < "$CONTPIPE"
return "$(cat < "$EXITPIPE")"
}
Expand Down