Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename pipe_condor to call_host #33

Merged
merged 5 commits into from
Jun 6, 2024
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
48 changes: 32 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,66 @@
# lpc-scripts
scripts of use on the cmslpc cluster

## `pipe_condor.sh`
## `call_host.sh`

HTCondor commands are installed on cmslpc interactive nodes, but by default they are not accessible inside containers.
Many commands are installed on cmslpc interactive nodes but are not accessible inside containers.

The script [pipe_condor.sh](./pipe_condor.sh) enables calling HTCondor commands *on the host node* from inside a container.
The script [call_host.sh](./call_host.sh) enables calling these commands *on the host node* from inside a container.

This is particularly useful for HTCondor commands and EOS commands, among others.

### Usage

In your `.bashrc`:
In your `.bashrc` or `.bash_profile`:
```bash
source pipe_condor.sh
source call_host.sh
```

Whenever you edit your `.bashrc`, you should log out and log back in for the changes to take effect.
Whenever you edit your `.bashrc` or `.bash_profile`, you should log out and log back in for the changes to take effect.

To check if this line in your `.bashrc` is being executed when you log in, make sure the following command shows some output:
To check if this line in your `.bashrc` or `.bash_profile` is being executed when you log in, make sure the following command shows some output:
```bash
echo $APPTAINERENV_APPTAINER_ORIG
```

Starting a container (the arguments are necessary for your `.bashrc` to be loaded inside the container):
To start a container with this in your `.bashrc`:
```bash
cmssw-el7 -- /bin/bash
cmssw-el7 [options] -- /bin/bash
```

To start a container with this in your `.bash_profile`:
```bash
cmssw-el7 [options] -- /bin/bash -l
```

### Details

What happens:
* The `apptainer` command is replaced with a function that will create a set of pipes on the host node before running `apptainer`.
* Inside the container, all executables starting with `condor_` will automatically run on the host node.
* Inside the container, all executables starting with `condor_` and `eos` will automatically run on the host node.
* To run other commands on the host node, use `call_host cmd`, where `cmd` is the command you want to run (with any arguments).
* Nested containers are supported (the enable/disable status (see "Options" just below) is inherited from the top-level container and cannot be changed)

Options:
* Before sourcing the script in your `.bashrc`, you can add this line to change the directory where the pipes will be created (the default is `~/nobackup/pipes`):
* Before sourcing the script in your `.bashrc` or `.bash_profile`, you can add this line to change the directory where the pipes will be created (the default is `~/nobackup/pipes`):
```bash
export CALL_HOST_DIR=your_dir
```
* If you want to run additional executables or functions automatically on the host node, you can add a line like this with a space-separated list (replace the example commands with the commands you want):
```bash
export PIPE_CONDOR_DIR=your_dir
export CALL_HOST_USERFNS="display gs"
```
* If you want to disable this by default and only enable it on the fly, put this line in your `.bashrc`:
* If you want to disable this by default and only enable it on the fly, put this line in your `.bashrc` or `.bash_profile`:
```bash
export PIPE_CONDOR_STATUS=${PIPE_CONDOR_STATUS:=disable}
export CALL_HOST_STATUS=${CALL_HOST_STATUS:=disable}
```
Then to enable it temporarily:
```bash
PIPE_CONDOR_STATUS=enable cmssw-el7 ...
CALL_HOST_STATUS=enable cmssw-el7 ...
```
* Instead, if you have this enabled by default and you want to temporarily disable this for a specific container invocation:
```bash
PIPE_CONDOR_STATUS=disable cmssw-el7 ...
CALL_HOST_STATUS=disable cmssw-el7 ...
````

Caveats:
Expand All @@ -62,6 +73,11 @@ Caveats:
```
+ApptainerImage = "/path/to/your/container"
```
* Commands that require tty input (such as `nano` or `emacs -nw`) will not work with `call_host`.
* Calling multiple commands at once with `call_host` can break the pipe if the commands are separated by semicolons and a non-final command fails.
The symptom of this will be that subsequent host commands hang, and pressing ctrl+C will give the error message "Interrupted system call".
It is necessary to exit and reenter the container (in order to create a new pipe) if this occurs.
To avoid this, chain multiple commands using logical operators (`&&` or `||`), or surround all the commands in `()` (thereby running them in a subshell).
* CMS connect support is planned, but has not been tested yet.

## `bind_condor.sh`
Expand Down
35 changes: 19 additions & 16 deletions pipe_condor.sh → call_host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

# default values
# shellcheck disable=SC2076
if [ -z "$PIPE_CONDOR_STATUS" ]; then
export PIPE_CONDOR_STATUS=enable
elif [[ ! " enable disable " =~ " $PIPE_CONDOR_STATUS " ]]; then
echo "Warning: unsupported value $PIPE_CONDOR_STATUS for PIPE_CONDOR_STATUS; disabling"
export PIPE_CONDOR_STATUS=disable
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
if [ -z "$PIPE_CONDOR_DIR" ]; then
export PIPE_CONDOR_DIR=~/nobackup/pipes
if [ -z "$CALL_HOST_DIR" ]; then
export CALL_HOST_DIR=~/nobackup/pipes
fi
export PIPE_CONDOR_DIR=$(readlink -f "$PIPE_CONDOR_DIR")
mkdir -p "$PIPE_CONDOR_DIR"
export CALL_HOST_DIR=$(readlink -f "$CALL_HOST_DIR")
mkdir -p "$CALL_HOST_DIR"
# ensure the pipe dir is bound
export APPTAINER_BIND=${APPTAINER_BIND}${APPTAINER_BIND:+,}${PIPE_CONDOR_DIR}
export APPTAINER_BIND=${APPTAINER_BIND}${APPTAINER_BIND:+,}${CALL_HOST_DIR}

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

Expand All @@ -36,7 +36,7 @@ export -f listenhost
# creates randomly named pipe and prints the name
makepipe(){
PREFIX="$1"
PIPETMP=${PIPE_CONDOR_DIR}/${PREFIX}_$(uuidgen)
PIPETMP=${CALL_HOST_DIR}/${PREFIX}_$(uuidgen)
mkfifo "$PIPETMP"
echo "$PIPETMP"
}
Expand Down Expand Up @@ -80,17 +80,17 @@ fi
export APPTAINERENV_APPTAINER_ORIG=$APPTAINER_ORIG

apptainer(){
if [ "$PIPE_CONDOR_STATUS" = "disable" ]; then
if [ "$CALL_HOST_STATUS" = "disable" ]; then
(
# shellcheck disable=SC2030
export APPTAINERENV_PIPE_CONDOR_STATUS=disable
export APPTAINERENV_CALL_HOST_STATUS=disable
$APPTAINER_ORIG "$@"
)
else
# in subshell to contain exports
(
# shellcheck disable=SC2031
export APPTAINERENV_PIPE_CONDOR_STATUS=enable
export APPTAINERENV_CALL_HOST_STATUS=enable
# only start pipes on host
# i.e. don't create more pipes/listeners for nested containers
if [ -z "$APPTAINER_CONTAINER" ]; then
Expand All @@ -113,9 +113,12 @@ export -f apptainer

# on host: get list of condor executables
if [ -z "$APPTAINER_CONTAINER" ]; then
export APPTAINERENV_HOSTFNS=$(compgen -c | grep ^condor_)
export APPTAINERENV_HOSTFNS=$(compgen -c | grep '^condor_\|^eos')
if [ -n "$CALL_HOST_USERFNS" ]; then
export APPTAINERENV_HOSTFNS="$APPTAINERENV_HOSTFNS $CALL_HOST_USERFNS"
fi
# in container: replace with call_host versions
elif [ "$PIPE_CONDOR_STATUS" = "enable" ]; then
elif [ "$CALL_HOST_STATUS" = "enable" ]; then
# shellcheck disable=SC2153
for HOSTFN in $HOSTFNS; do
copy_function call_host "$HOSTFN"
Expand Down
Loading