Support for custom shells
It is now possible to override and explicitly specify the shell you would like used when executing cron tasks. This is accomplished with the NEXTCLOUD_EXEC_SHELL environment variable, which defaults to bash. You can also override and customize the arguments provided to that shell executable via NEXTCLOUD_EXEC_SHELL_ARGS, which defaults to "-c". See documentation for more detail and examples. Fixes #6
This commit is contained in:
parent
08ec92f509
commit
faa77b77c8
7 changed files with 123 additions and 17 deletions
|
@ -6,6 +6,8 @@ ENV NEXTCLOUD_EXEC_USER=www-data
|
||||||
ENV NEXTCLOUD_CONTAINER_NAME=
|
ENV NEXTCLOUD_CONTAINER_NAME=
|
||||||
ENV NEXTCLOUD_PROJECT_NAME=
|
ENV NEXTCLOUD_PROJECT_NAME=
|
||||||
ENV NEXTCLOUD_CRON_MINUTE_INTERVAL=15
|
ENV NEXTCLOUD_CRON_MINUTE_INTERVAL=15
|
||||||
|
ENV NEXTCLOUD_EXEC_SHELL=bash
|
||||||
|
ENV NEXTCLOUD_EXEC_SHELL_ARGS=-c
|
||||||
|
|
||||||
COPY scripts/*.sh /
|
COPY scripts/*.sh /
|
||||||
COPY scripts/cron-scripts /cron-scripts
|
COPY scripts/cron-scripts /cron-scripts
|
||||||
|
|
66
README.md
66
README.md
|
@ -77,6 +77,17 @@ how this all works.
|
||||||
in the tasks being executed using the Nextcloud container's running user. Specifically, the
|
in the tasks being executed using the Nextcloud container's running user. Specifically, the
|
||||||
`--user` option will *not* be provided to the `docker exec` command.
|
`--user` option will *not* be provided to the `docker exec` command.
|
||||||
|
|
||||||
|
* `NEXTCLOUD_EXEC_SHELL`<br>
|
||||||
|
Allows specifying a custom shell program that will be used to execute cron tasks inside the
|
||||||
|
Nextcloud container. This shell program *must* exist inside the Nextcloud container itself
|
||||||
|
(validation happens on start up to ensure this). The default value if not specified is `bash`.
|
||||||
|
|
||||||
|
* `NEXTCLOUD_EXEC_SHELL_ARGS`<br>
|
||||||
|
Allows custom arguments to be passed to the shell program specified by `NEXTCLOUD_EXEC_SHELL`. See
|
||||||
|
the detailed documentation provided later on in this document for more information. At minimum,
|
||||||
|
the arguments passed to your shell program must allow for the execution of a series of string
|
||||||
|
commands. The default value if not specified is `-c`.
|
||||||
|
|
||||||
* `DEBUG`<br>
|
* `DEBUG`<br>
|
||||||
Enables more verbose logging in core scripts. Useful only for development. To get more verbose
|
Enables more verbose logging in core scripts. Useful only for development. To get more verbose
|
||||||
output in your own custom cron scripts, use `set -x` in the actual script.
|
output in your own custom cron scripts, use `set -x` in the actual script.
|
||||||
|
@ -103,15 +114,15 @@ in addition to the default `cron.php` task. To add your custom tasks, follow the
|
||||||
1. Write a shell script that runs the commands that will be part of your task. This shell script
|
1. Write a shell script that runs the commands that will be part of your task. This shell script
|
||||||
must have the `.sh` extension. An example of the contents of such a script is below. As an
|
must have the `.sh` extension. An example of the contents of such a script is below. As an
|
||||||
optional security measure, do not make this shell script executable. The contents of the file are
|
optional security measure, do not make this shell script executable. The contents of the file are
|
||||||
piped into `bash`, so the executable bit is not used.
|
piped into `sh`, so the executable bit and shebang line are not used or required.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
#!/usr/bin/env bash
|
|
||||||
php -f /var/www/html/cron.php
|
php -f /var/www/html/cron.php
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Mount this shell script inside the `/cron-scripts` directory. Here's an example if you're using
|
2. Mount this shell script inside the `/cron-scripts` directory. You may also choose to *replace*
|
||||||
`docker-compose.yml`:
|
this directory, but bear in mind that you will not be running the built-in cron tasks in that
|
||||||
|
case. Here's an example if you're using `docker-compose.yml`:
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
|
@ -139,11 +150,42 @@ services:
|
||||||
As an optional safety measure, mount the directory or files as read-only (via the `:ro` at the end).
|
As an optional safety measure, mount the directory or files as read-only (via the `:ro` at the end).
|
||||||
The container should not modify the files, but it doesn't hurt to be explicitly strict.
|
The container should not modify the files, but it doesn't hurt to be explicitly strict.
|
||||||
|
|
||||||
|
### Customizing the Shell
|
||||||
|
|
||||||
|
By default, all cron task scripts in the `/cron-scripts` directory are executed with `bash`.
|
||||||
|
However, not all Nextcloud containers have `bash`. In this case, you may want to override it with a
|
||||||
|
shell like `sh`. You can accomplish this (as well as customizing the arguments passed to the shell)
|
||||||
|
with `NEXTCLOUD_EXEC_SHELL` and `NEXTCLOUD_EXEC_SHELL_ARGS`.
|
||||||
|
|
||||||
|
The shell args are used when passing the contents of script files to the shell executable inside the
|
||||||
|
Nextcloud container. Customizing the args might be necessary depending on the shell program you
|
||||||
|
choose, or you may want to leverage options for debugging purposes (See "Debugging" section for
|
||||||
|
examples).
|
||||||
|
|
||||||
|
> **NOTE**<br>
|
||||||
|
> The arguments that are passed to the shell program must, at least, allow the execution of a string
|
||||||
|
> of commands. See the documentation on your chosen shell for which arguments these should be.
|
||||||
|
|
||||||
|
Here is an example of how you would override `bash` for `sh` using `docker-compose.yml` (again,
|
||||||
|
greatly simplified for example purposes; this is not a complete YAML):
|
||||||
|
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
cron:
|
||||||
|
image: rcdailey/nextcloud-cronjob
|
||||||
|
environment:
|
||||||
|
- NEXTCLOUD_EXEC_SHELL=sh
|
||||||
|
- NEXTCLOUD_EXEC_SHELL_ARGS=-c
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `-c` is the default for `NEXTCLOUD_EXEC_SHELL_ARGS`, so it isn't necessary to specify it
|
||||||
|
above. However, it is explicitly specified for example purposes.
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
|
|
||||||
* All cron task shell scripts run at the same interval defined by `NEXTCLOUD_CRON_MINUTE_INTERVAL`.
|
* All cron task shell scripts run at the same interval defined by `NEXTCLOUD_CRON_MINUTE_INTERVAL`.
|
||||||
* Modification of your own shell scripts on the host do not require that you restart/recreate the
|
* Modification of your own shell scripts on the host do not require that you restart/recreate the
|
||||||
container.
|
container (only when volume mappings change in the YAML file).
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
|
@ -161,3 +203,17 @@ Started crond
|
||||||
> Running Script: run_cron_php.sh
|
> Running Script: run_cron_php.sh
|
||||||
> Done
|
> Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can leverage `NEXTCLOUD_EXEC_SHELL_ARGS` to get more verbose output from your scripts. For
|
||||||
|
example, for `bash` you can specify `-x` for debug mode. So you could use this in your YAML:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
cron:
|
||||||
|
image: rcdailey/nextcloud-cronjob
|
||||||
|
environment:
|
||||||
|
- NEXTCLOUD_EXEC_SHELL_ARGS=-xc
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the addition of `-x` in the arguments. This will provide line-by-line output for each cron task
|
||||||
|
shell script executed.
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
php -f /var/www/html/cron.php
|
php -f /var/www/html/cron.php
|
||||||
|
|
|
@ -2,16 +2,12 @@
|
||||||
set -e
|
set -e
|
||||||
[[ ! -z "$DEBUG" ]] && set -x
|
[[ ! -z "$DEBUG" ]] && set -x
|
||||||
|
|
||||||
|
source /nextcloud-exec.sh
|
||||||
|
|
||||||
echo "-------------------------------------------------------------"
|
echo "-------------------------------------------------------------"
|
||||||
echo " Executing Cron Tasks: $(date)"
|
echo " Executing Cron Tasks: $(date)"
|
||||||
echo "-------------------------------------------------------------"
|
echo "-------------------------------------------------------------"
|
||||||
|
|
||||||
# If a user must be specified when executing the task, set up that option here.
|
|
||||||
# You may also leave NEXTCLOUD_EXEC_USER blank, in which case it will not be used.
|
|
||||||
if [[ -n "$NEXTCLOUD_EXEC_USER" ]]; then
|
|
||||||
exec_user="--user $NEXTCLOUD_EXEC_USER"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Obtain the ID of the container. We do this each iteration since the Nextcloud container may be
|
# Obtain the ID of the container. We do this each iteration since the Nextcloud container may be
|
||||||
# recreated while the cron container is still running. We will need to check for a new container ID
|
# recreated while the cron container is still running. We will need to check for a new container ID
|
||||||
# each time.
|
# each time.
|
||||||
|
@ -23,13 +19,17 @@ fi
|
||||||
|
|
||||||
echo "> Nextcloud Container ID: ${containerId}"
|
echo "> Nextcloud Container ID: ${containerId}"
|
||||||
|
|
||||||
|
run_scripts_in_dir() {
|
||||||
|
cd "$1"
|
||||||
|
for script in *.sh; do
|
||||||
|
echo "> Running Script: $script"
|
||||||
|
nextcloud_exec "$containerId" "$(< $script)"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# Loop through all shell scripts and execute the contents of those scripts in the Nextcloud
|
# Loop through all shell scripts and execute the contents of those scripts in the Nextcloud
|
||||||
# container. It's done this way so that the user may mount more scripts to be executed in addition
|
# container. It's done this way so that the user may mount more scripts to be executed in addition
|
||||||
# to the default ones.
|
# to the default ones.
|
||||||
cd /cron-scripts
|
run_scripts_in_dir /cron-scripts
|
||||||
for script in *.sh; do
|
|
||||||
echo "> Running Script: $script"
|
|
||||||
docker exec $exec_user -i "$containerId" bash < $script
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "> Done"
|
echo "> Done"
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
set -e
|
set -e
|
||||||
[[ ! -z "$DEBUG" ]] && set -x
|
[[ ! -z "$DEBUG" ]] && set -x
|
||||||
|
|
||||||
|
source /nextcloud-exec.sh
|
||||||
|
|
||||||
if [[ -z "$NEXTCLOUD_CONTAINER_NAME" ]]; then
|
if [[ -z "$NEXTCLOUD_CONTAINER_NAME" ]]; then
|
||||||
echo "NEXTCLOUD_CONTAINER_NAME is a required variable"
|
echo "NEXTCLOUD_CONTAINER_NAME is a required variable"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -24,6 +26,15 @@ else
|
||||||
echo "Found Nextcloud container with ID $containerId"
|
echo "Found Nextcloud container with ID $containerId"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Verify the chosen shell exists in the Nextcloud container
|
||||||
|
if ! nextcloud_exec_no_shell "$containerId" sh -c "command -v \"$NEXTCLOUD_EXEC_SHELL\"" >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
echo "ERROR: Shell \"$NEXTCLOUD_EXEC_SHELL\" does not exist in the Nextcloud container"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Chosen shell \"$NEXTCLOUD_EXEC_SHELL\" was found in the Nextcloud container"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "*/$NEXTCLOUD_CRON_MINUTE_INTERVAL * * * * /cron-tasks.sh" \
|
echo "*/$NEXTCLOUD_CRON_MINUTE_INTERVAL * * * * /cron-tasks.sh" \
|
||||||
> /var/spool/cron/crontabs/root
|
> /var/spool/cron/crontabs/root
|
||||||
|
|
||||||
|
|
18
scripts/nextcloud-exec.sh
Normal file
18
scripts/nextcloud-exec.sh
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
nextcloud_exec_no_shell() {
|
||||||
|
containerId="$1"; shift
|
||||||
|
|
||||||
|
# If a user must be specified when executing the task, set up that option here.
|
||||||
|
# You may also leave NEXTCLOUD_EXEC_USER blank, in which case it will not be used.
|
||||||
|
if [[ -n "$NEXTCLOUD_EXEC_USER" ]]; then
|
||||||
|
exec_user="--user $NEXTCLOUD_EXEC_USER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker exec $exec_user -i "$containerId" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
nextcloud_exec() {
|
||||||
|
containerId="$1"; shift
|
||||||
|
nextcloud_exec_no_shell "$containerId" "$NEXTCLOUD_EXEC_SHELL" $NEXTCLOUD_EXEC_SHELL_ARGS "$@"
|
||||||
|
}
|
20
test/shell-test/docker-compose.yml
Normal file
20
test/shell-test/docker-compose.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: nextcloud:19-fpm-alpine
|
||||||
|
|
||||||
|
cronjob:
|
||||||
|
build: ../..
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
environment:
|
||||||
|
- NEXTCLOUD_PROJECT_NAME=shell-test
|
||||||
|
- NEXTCLOUD_CONTAINER_NAME=app
|
||||||
|
- NEXTCLOUD_CRON_MINUTE_INTERVAL=1
|
||||||
|
- NEXTCLOUD_EXEC_SHELL=sh
|
||||||
|
- NEXTCLOUD_EXEC_SHELL_ARGS=-xc
|
||||||
|
- DEBUG=1
|
Loading…
Reference in a new issue