Skip to content

Commit

Permalink
Merge pull request #114 from cdalvaro/feature/restar_salt_master_on_c…
Browse files Browse the repository at this point in the history
…onfig_changes

Restart `salt-master` on config changes
  • Loading branch information
cdalvaro authored Nov 28, 2021
2 parents 389db75 + c55302a commit 972c5d7
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 45 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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" \
Expand Down Expand Up @@ -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 \
Expand Down
47 changes: 26 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:

Expand Down
17 changes: 0 additions & 17 deletions assets/runtime/config/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
1 change: 1 addition & 0 deletions assets/runtime/env-defaults.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions assets/runtime/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 <<EOF
[program:config-reloader]
priority=20
directory=/tmp
command=/usr/local/sbin/config-reloader
user=root
autostart=true
autorestart=true
stdout_logfile=${SALT_LOGS_DIR}/supervisor/%(program_name)s.log
stderr_logfile=${SALT_LOGS_DIR}/supervisor/%(program_name)s.log
EOF
}

#--- FUNCTION -------------------------------------------------------------------------------------------------------
# NAME: initialize_system
# DESCRIPTION: Initialize the system.
Expand All @@ -444,6 +466,7 @@ function initialize_system()
configure_salt_master
configure_salt_api
configure_salt_formulas
configure_config_reloader
setup_salt_keys
setup_ssh_keys
rm -rf /var/run/supervisor.sock
Expand Down
17 changes: 17 additions & 0 deletions assets/sbin/config-reloader
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# shellcheck source=assets/runtime/functions.sh
FUNCTIONS_FILE="${SALT_RUNTIME_DIR}/functions.sh"
source "${FUNCTIONS_FILE}"

function check_for_config_changes()
{
inotifywait -qq --recursive \
--event modify,move,create,delete \
"${SALT_CONFS_DIR}"
}

while check_for_config_changes; do
log_info "Configuration changes detected. Reloading salt-master ..."
supervisorctl restart salt-master
done
6 changes: 4 additions & 2 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
set -e
set -o pipefail

source "${SALT_RUNTIME_DIR}/functions.sh"
# shellcheck source=assets/runtime/functions.sh
FUNCTIONS_FILE="${SALT_RUNTIME_DIR}/functions.sh"
source "${FUNCTIONS_FILE}"

[[ "${DEBUG}" == true ]] && set -x

Expand All @@ -28,7 +30,7 @@ case "${1}" in
case "${1}" in
salt-master|salt-api)
echo "Restarting ${1} service ..."
exec pkill "${1}"
exec supervisorctl restart "${1}"
;;
*)
log_error "Unable to restart ${1} serice. Service is unknown"
Expand Down
5 changes: 5 additions & 0 deletions tests/config-reloader/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Config Reloader Tests

Checks:

- `salt-master` is reloaded after config changes
2 changes: 2 additions & 0 deletions tests/config-reloader/config/fileserver.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# The buffer size in the file server can be adjusted here:
file_buffer_size: 1048576
54 changes: 54 additions & 0 deletions tests/config-reloader/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash

set -e
[ "${DEBUG}" == true ] && set -vx

echo "🧪 Running config-reloader tests ..."

# https://stackoverflow.com/a/4774063/3398062
SCRIPT_PATH="$( cd -- "$(dirname "$0")" >/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" <<EOF
# Enable extra routines for YAML renderer used states containing UTF characters.
yaml_utf8: ${YAML_UTF8_EXPECTED}
EOF
sleep 30 # Wait for the config to be reloaded

YAML_UTF8="$(salt-run config.get yaml_utf8)"
check_equal "${YAML_UTF8}" "${YAML_UTF8_EXPECTED}" "yaml_utf8"
2 changes: 1 addition & 1 deletion tests/gitfs/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ok "gitfs keys"
# Run test instance
echo "==> 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"
Expand Down
Loading

0 comments on commit 972c5d7

Please sign in to comment.