diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 364fe813..d931dd36 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -130,6 +130,9 @@ jobs: chmod 644 "${GITFS_KEYS_DIR}"/gitfs_ssh.pub tests/gitfs/test.sh + - name: Execute config-reloader tests + run: tests/config-reloader/test.sh + - name: Cleanup run: | docker stop registry diff --git a/CHANGELOG.md b/CHANGELOG.md index b327d7d0..8e3f70f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ This file only reflects the changes that are made in this image. Please refer to the [Salt 3004 Release Notes](https://docs.saltstack.com/en/latest/topics/releases/3004.html) for the list of changes in SaltStack. +**3004_2** + +- Support for automatically restart `salt-master` after config changes + **3004_1** - Install `libssh2 1.10.0` from source diff --git a/Dockerfile b/Dockerfile index 28c2b32f..50b18b32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ARG VCS_REF ENV SALT_VERSION="3004" \ PYTHON_VERSION="3.9" -ENV IMAGE_VERSION="${SALT_VERSION}_1" +ENV IMAGE_VERSION="${SALT_VERSION}_2" ENV SALT_DOCKER_DIR="/etc/docker-salt" \ SALT_ROOT_DIR="/etc/salt" \ @@ -35,7 +35,7 @@ RUN apt-get update \ sudo ca-certificates openssl apt-transport-https wget locales openssh-client \ python${PYTHON_VERSION} python3-dev libpython3-dev \ python3-pip python3-setuptools python3-wheel \ - supervisor logrotate git gettext-base tzdata \ + supervisor logrotate git gettext-base tzdata inotify-tools \ && DEBIAN_FRONTEND=noninteractive update-locale LANG=C.UTF-8 LC_MESSAGES=POSIX \ locale-gen en_US.UTF-8 \ dpkg-reconfigure locales \ diff --git a/README.md b/README.md index 7ad8e162..af3bb919 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,10 @@ docker run --name salt_master -d \ cdalvaro/docker-salt-master:latest ``` +This image provides support for automatically restart `salt-master` when configuration files change. +This support is disabled by default, but it can be enabled by setting the +`SALT_RESTART_MASTER_ON_CONFIG_CHANGE` environment variable to `true`. + ### Custom States In order to provide salt with your custom states you must mount the volume `/home/salt/data/srv/` with your `roots` directory inside it. @@ -502,27 +506,28 @@ Please refer the docker run command options for the `--env-file` flag where you Below you can find a list with the available options that can be used to customize your `docker-salt-master` installation. -| Parameter | Description | -| :--------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `DEBUG` | Set this to `true` to enable entrypoint debugging. | -| `TIMEZONE` | Set the container timezone. Defaults to `UTC`. Values are expected to be in Canonical format. Example: `Europe/Madrid`. See the list of [acceptable values](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). | -| `SALT_LOG_LEVEL` | The level of messages to send to the console. One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. Default: `warning` | -| `SALT_LOG_ROTATE_FREQUENCY` | Logrotate frequency for salt logs. Available options are 'daily', 'weekly', 'monthly', and 'yearly'. Default: `weekly` | -| `SALT_LOG_ROTATE_RETENTION` | Keep x files before deleting old log files. Defaults: `52` | -| `SALT_LEVEL_LOGFILE` | The level of messages to send to the log file. One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. Default: `warning` | -| `SALT_API_SERVICE_ENABLED` | Enable `salt-api` service. Default: `false` | -| `SALT_API_USER` | Set username for `salt-api` service. Default: `salt_api` | -| `SALT_API_USER_PASS` | `SALT_API_USER` password. Required if `SALT_API_SERVICE_ENBALED` is `true` and `SALT_API_USER` is not empty. _Unset_ by default | -| `SALT_API_CERT_CN` | Common name in the request. Default: `localhost` | -| `SALT_MASTER_SIGN_PUBKEY` | Sign the master auth-replies with a cryptographic signature of the master's public key. Possible values: 'True' or 'False'. Default: `False` | -| `SALT_MASTER_USE_PUBKEY_SIGNATURE` | Instead of computing the signature for each auth-reply, use a pre-calculated signature. This option requires `SALT_MASTER_SIGN_PUBKEY` set to 'True'. Possible values: 'True' or 'False'. Default: `True` | -| `SALT_MASTER_SIGN_KEY_NAME` | The customizable name of the signing-key-pair without suffix. Default: `master_sign` | -| `SALT_MASTER_PUBKEY_SIGNATURE` | The name of the file in the master's pki-directory that holds the pre-calculated signature of the master's public-key. Default: `master_pubkey_signature` | -| `SALT_MASTER_ROOT_USER` | Forces `salt-master` to be runned as `root` instead of `salt`. Default: `False` | -| `SALT_GITFS_SSH_PRIVATE_KEY` | The name of the ssh private key for gitfs. Default: `gitfs_ssh` | -| `SALT_GITFS_SSH_PUBLIC_KEY` | The name of the ssh public key for gitfs. Default: `gitfs_ssh.pub` | -| `USERMAP_UID` | Sets the uid for user `salt` to the specified uid. Default: `1000`. | -| `USERMAP_GID` | Sets the gid for user `salt` to the specified gid. Default: `1000`. | +| Parameter | Description | +| :------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `DEBUG` | Set this to `true` to enable entrypoint debugging. | +| `TIMEZONE` | Set the container timezone. Defaults to `UTC`. Values are expected to be in Canonical format. Example: `Europe/Madrid`. See the list of [acceptable values](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). | +| `SALT_RESTART_MASTER_ON_CONFIG_CHANGE` | Set this to `true` to restart `salt-master` service when configuration files change. Default: `false` | +| `SALT_LOG_LEVEL` | The level of messages to send to the console. One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. Default: `warning` | +| `SALT_LOG_ROTATE_FREQUENCY` | Logrotate frequency for salt logs. Available options are 'daily', 'weekly', 'monthly', and 'yearly'. Default: `weekly` | +| `SALT_LOG_ROTATE_RETENTION` | Keep x files before deleting old log files. Defaults: `52` | +| `SALT_LEVEL_LOGFILE` | The level of messages to send to the log file. One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. Default: `warning` | +| `SALT_API_SERVICE_ENABLED` | Enable `salt-api` service. Default: `false` | +| `SALT_API_USER` | Set username for `salt-api` service. Default: `salt_api` | +| `SALT_API_USER_PASS` | `SALT_API_USER` password. Required if `SALT_API_SERVICE_ENBALED` is `true` and `SALT_API_USER` is not empty. _Unset_ by default | +| `SALT_API_CERT_CN` | Common name in the request. Default: `localhost` | +| `SALT_MASTER_SIGN_PUBKEY` | Sign the master auth-replies with a cryptographic signature of the master's public key. Possible values: 'True' or 'False'. Default: `False` | +| `SALT_MASTER_USE_PUBKEY_SIGNATURE` | Instead of computing the signature for each auth-reply, use a pre-calculated signature. This option requires `SALT_MASTER_SIGN_PUBKEY` set to 'True'. Possible values: 'True' or 'False'. Default: `True` | +| `SALT_MASTER_SIGN_KEY_NAME` | The customizable name of the signing-key-pair without suffix. Default: `master_sign` | +| `SALT_MASTER_PUBKEY_SIGNATURE` | The name of the file in the master's pki-directory that holds the pre-calculated signature of the master's public-key. Default: `master_pubkey_signature` | +| `SALT_MASTER_ROOT_USER` | Forces `salt-master` to be runned as `root` instead of `salt`. Default: `False` | +| `SALT_GITFS_SSH_PRIVATE_KEY` | The name of the ssh private key for gitfs. Default: `gitfs_ssh` | +| `SALT_GITFS_SSH_PUBLIC_KEY` | The name of the ssh public key for gitfs. Default: `gitfs_ssh.pub` | +| `USERMAP_UID` | Sets the uid for user `salt` to the specified uid. Default: `1000`. | +| `USERMAP_GID` | Sets the gid for user `salt` to the specified gid. Default: `1000`. | Any parameter not listed in the above table and available in the following [link](https://docs.saltproject.io/en/latest/ref/configuration/examples.html#configuration-examples-master), can be set by creating the directory `config` and adding into it a `.conf` file with the desired parameters: diff --git a/assets/runtime/config/master.yml b/assets/runtime/config/master.yml index 98b09f22..63acfb16 100644 --- a/assets/runtime/config/master.yml +++ b/assets/runtime/config/master.yml @@ -117,20 +117,3 @@ log_level: {{SALT_LOG_LEVEL}} # One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. # If using 'log_granular_levels' this must be set to the highest desired level. log_level_logfile: {{SALT_LEVEL_LOGFILE}} - - -##### Windows Software Repo settings ##### -########################################### -# Location of the repo on the master: -winrepo_dir_ng: '{{SALT_BASE_DIR}}/salt/win/repo-ng' - - -##### Windows Software Repo settings - Pre 2015.8 ##### -######################################################## -# Legacy repo settings for pre-2015.8 Windows minions. -# -# Location of the repo on the master: -winrepo_dir: '{{SALT_BASE_DIR}}/salt/win/repo' -# -# Location of the master's repo cache file: -winrepo_mastercachefile: '{{SALT_BASE_DIR}}/salt/win/repo/winrepo.p' diff --git a/assets/runtime/env-defaults.sh b/assets/runtime/env-defaults.sh index 40ccdbf0..c3e50db2 100755 --- a/assets/runtime/env-defaults.sh +++ b/assets/runtime/env-defaults.sh @@ -11,6 +11,7 @@ SALT_LOG_ROTATE_FREQUENCY=${SALT_LOG_ROTATE_FREQUENCY:-weekly} SALT_LOG_ROTATE_RETENTION=${SALT_LOG_ROTATE_RETENTION:-52} # https://docs.saltstack.com/en/latest/ref/configuration/master.html +SALT_RESTART_MASTER_ON_CONFIG_CHANGE=${SALT_RESTART_MASTER_ON_CONFIG_CHANGE:-false} ##### Logging settings ##### # https://docs.saltstack.com/en/latest/ref/configuration/master.html#master-logging-settings diff --git a/assets/runtime/functions.sh b/assets/runtime/functions.sh index bb4d428d..be788245 100755 --- a/assets/runtime/functions.sh +++ b/assets/runtime/functions.sh @@ -217,6 +217,7 @@ function configure_salt_master() #---------------------------------------------------------------------------------------------------------------------- function configure_salt_api() { + rm -f /etc/supervisor/conf.d/salt-api.conf [[ ${SALT_API_SERVICE_ENABLED} == true ]] || return 0 if [[ -n "${SALT_API_USER}" ]]; then @@ -431,6 +432,27 @@ EOF } +function configure_config_reloader() +{ + rm -f /etc/supervisor/conf.d/config-reloader.conf + [ "${SALT_RESTART_MASTER_ON_CONFIG_CHANGE}" == true ] || return 0 + + echo "Configuring config reloader ..." + + # configure supervisord to start config-reloader + cat > /etc/supervisor/conf.d/config-reloader.conf </dev/null 2>&1 ; pwd -P )" + +# shellcheck source=assets/build/functions.sh +COMMON_FILE="${SCRIPT_PATH}/../lib/common.sh" +source "${COMMON_FILE}" +trap cleanup EXIT + +# Run test instance +echo "==> Starting docker-salt-master (${PLATFORM}) ..." +start_container_and_wait \ + --env SALT_RESTART_MASTER_ON_CONFIG_CHANGE=true \ + --volume "${SCRIPT_PATH}/config":/home/salt/data/config:ro \ +|| error "container started" +ok "container started" + +# Get initial configuration values +echo "==> Checking initial configuration values ..." +FILE_BUFFER_SIZE="$(salt-run config.get file_buffer_size)" +YAML_UTF8="$(salt-run config.get yaml_utf8)" + +FILE_BUFFER_SIZE_EXPECTED=1048576 +YAML_UTF8_EXPECTED= + +check_equal "${FILE_BUFFER_SIZE}" "${FILE_BUFFER_SIZE_EXPECTED}" "file_buffer_size" +check_equal "${YAML_UTF8}" "${YAML_UTF8_EXPECTED}" "yaml_utf8" + +# Update fileserver config +echo "==> Updating file_buffer_size config ..." +FILE_BUFFER_SIZE_EXPECTED=2097152 +sed -i "s/file_buffer_size:.*/file_buffer_size: ${FILE_BUFFER_SIZE_EXPECTED}/" "${SCRIPT_PATH}/config/fileserver.conf" +sleep 30 # Wait for the config to be reloaded + +FILE_BUFFER_SIZE="$(salt-run config.get file_buffer_size)" +check_equal "${FILE_BUFFER_SIZE}" "${FILE_BUFFER_SIZE_EXPECTED}" "file_buffer_size" + +# Create yaml_utf8 config +echo "==> Creating yaml_utf8 config ..." +YAML_UTF8_EXPECTED=True +cat > "${SCRIPT_PATH}/config/yaml_utf8.conf" < Starting docker-salt-master (${PLATFORM}) with RSA 4096 ssh key ..." start_container_and_wait \ - --volume "$(pwd)/tests/gitfs/config":/home/salt/data/config:ro \ + --volume "${SCRIPT_PATH}/config":/home/salt/data/config:ro \ --volume "$(pwd)/${GITFS_KEYS_DIR%%/gitfs}":/home/salt/data/keys \ || error "container started" ok "container started" diff --git a/tests/lib/common.sh b/tests/lib/common.sh index 0922eb3e..581e6c7b 100644 --- a/tests/lib/common.sh +++ b/tests/lib/common.sh @@ -30,7 +30,7 @@ export BOOTUP_WAIT_SECONDS=${BOOTUP_WAIT_SECONDS:-60} #---------------------------------------------------------------------------------------------------------------------- function cleanup() { - echo "==> Removing ${CONTAINER_NAME} ..." + echo "🧹 Removing ${CONTAINER_NAME} ..." docker container rm --force "${CONTAINER_NAME}" } @@ -43,6 +43,15 @@ function docker-exec() docker exec "${CONTAINER_NAME}" "$@" } +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: docker-logs +# DESCRIPTION: Get the logs of the container. +#---------------------------------------------------------------------------------------------------------------------- +function docker-logs() +{ + docker logs "${CONTAINER_NAME}" +} + #--- FUNCTION ------------------------------------------------------------------------------------------------------- # NAME: salt-run # DESCRIPTION: Execute the salt-run command inside the container. @@ -107,3 +116,27 @@ function error() master_log return 1 } + +#--- FUNCTION ------------------------------------------------------------------------------------------------------- +# NAME: check_equal +# DESCRIPTION: Check if the given value is equal to the expected value. +#---------------------------------------------------------------------------------------------------------------------- +function check_equal() +{ + local actual="$1" + local expected="$2" + local message="$3" + + output=$(cat < Starting docker-salt-master (${PLATFORM}) with salt-api config ..."