mirror of
https://github.com/osixia/container-openldap.git
synced 2026-11-06 12:40:36 -04:00
Fix bootstrap templates on read-only volumes
This commit is contained in:
@@ -16,6 +16,11 @@ Project-specific changes only. See upstream [OpenLDAP release notes](https://www
|
||||
- Test default behavior, automatic role creation and preservation of a group after
|
||||
deletion of its last real member.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Render bootstrap LDIF templates in a temporary writable copy, allowing read-only
|
||||
sources and Kubernetes projected-volume symlinks without modifying source files.
|
||||
|
||||
## 2.6.15-beta
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -21,6 +21,8 @@ own native runner, then publishes them together from their OCI archives
|
||||
After the shared version check, `tests/` runs integration scenarios on each built image:
|
||||
|
||||
- default bootstrap;
|
||||
- read-only bootstrap templates with projected-volume symlinks, custom overrides
|
||||
and temporary-copy cleanup on success and failure;
|
||||
- alternative schemas (`nis`, `virtualMail`);
|
||||
- auditlog: automatic module loading, writes, custom paths, rotation and restarts;
|
||||
- last successful binds: disabled by default, precision throttling, failed binds
|
||||
|
||||
@@ -15,6 +15,15 @@ const replicationPassword = `Repl passw0rd 'single' \ $HOME`
|
||||
|
||||
const defaultSchemas = "core.ldif cosine.ldif inetorgperson.ldif rfc2307bis.ldif"
|
||||
|
||||
//go:embed testdata/templates.sh
|
||||
var templatesCheck string
|
||||
|
||||
// ReadOnlyTemplates checks projected-volume sources and temporary-copy cleanup.
|
||||
func ReadOnlyTemplates(ctx context.Context, client *dagger.Client, image *dagger.Container) error {
|
||||
_, err := expect(ctx, image, true, nil, "container", "run", "--", "bash", "-c", templatesCheck)
|
||||
return err
|
||||
}
|
||||
|
||||
// allSchemas can be loaded together. Excluded:
|
||||
// - nis.ldif and virtualMail.ldif conflict with rfc2307bis.ldif and postfix-book.ldif,
|
||||
// they are tested by AlternativeSchemas;
|
||||
|
||||
@@ -19,6 +19,7 @@ type scenario struct {
|
||||
|
||||
var scenarios = []scenario{
|
||||
{"default bootstrap", Default},
|
||||
{"read-only bootstrap templates", ReadOnlyTemplates},
|
||||
{"alternative schemas", AlternativeSchemas},
|
||||
{"audit logging", AuditLog},
|
||||
{"last successful binds", LastBind},
|
||||
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# if container log level is trace:
|
||||
# print commands and their arguments as they are executed
|
||||
container log level eq trace && set -x
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
source "${OPENLDAP_TEST_HELPER:-/container/services/openldap-bootstrap/assets/scripts/helpers/common.sh}"
|
||||
|
||||
test_dir=$(mktemp -d)
|
||||
trap 'chmod -R u+rwX "${test_dir:?}"; rm -rf "${test_dir:?}"' EXIT
|
||||
|
||||
mkdir -p "${test_dir}/source/..revision" "${test_dir}/output" "${test_dir}/custom"
|
||||
printf 'dn: %s\n' "\${OPENLDAP_TEST_DN}" > "${test_dir}/source/..revision/10-entry.ldif.template"
|
||||
printf 'description: original\n' > "${test_dir}/source/..revision/20-plain.ldif"
|
||||
ln -s ..revision "${test_dir}/source/..data"
|
||||
ln -s ..data/10-entry.ldif.template "${test_dir}/source/10-entry.ldif.template"
|
||||
ln -s ..data/20-plain.ldif "${test_dir}/source/20-plain.ldif"
|
||||
chmod -R a-w "${test_dir}/source"
|
||||
export OPENLDAP_TEST_DN='dc=example,dc=org'
|
||||
|
||||
prepare_ldif_files "${test_dir}/source" "${test_dir}/output"
|
||||
test "$(cat "${test_dir}/output/10-entry.ldif")" = "dn: ${OPENLDAP_TEST_DN}"
|
||||
test "$(cat "${test_dir}/output/20-plain.ldif")" = 'description: original'
|
||||
test ! -e "${test_dir}/source/10-entry.ldif"
|
||||
test "$(cat "${test_dir}/source/10-entry.ldif.template")" = "dn: \${OPENLDAP_TEST_DN}"
|
||||
test -L "${test_dir}/source/10-entry.ldif.template"
|
||||
test -z "$(find "${test_dir}/output" -name '.templates.*')"
|
||||
|
||||
printf 'description: custom\n' > "${test_dir}/custom/20-plain.ldif"
|
||||
prepare_ldif_files "${test_dir}/custom" "${test_dir}/output"
|
||||
test "$(cat "${test_dir}/output/20-plain.ldif")" = 'description: custom'
|
||||
|
||||
printf 'dn: %s\ndescription: custom template\n' "\${OPENLDAP_TEST_DN}" > "${test_dir}/custom/10-entry.ldif.template"
|
||||
prepare_ldif_files "${test_dir}/custom" "${test_dir}/output"
|
||||
test "$(cat "${test_dir}/output/10-entry.ldif")" = "$(printf 'dn: %s\ndescription: custom template' "${OPENLDAP_TEST_DN}")"
|
||||
test ! -e "${test_dir}/custom/10-entry.ldif"
|
||||
|
||||
# On failure, the bootstrap's global EXIT trap removes the working directory.
|
||||
mkdir "${test_dir}/failure"
|
||||
(
|
||||
# Invoked by the child Bash process through the exported function.
|
||||
# shellcheck disable=SC2329
|
||||
container() {
|
||||
if [ "${1}" = envsubst ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
export -f container
|
||||
if bash -c 'set -euo pipefail; cleanup_dir=${3}; trap '\''rm -rf "${cleanup_dir:?}"'\'' EXIT; source "${1}"; prepare_ldif_files "${2}" "${3}"' -- \
|
||||
"${OPENLDAP_TEST_HELPER:-/container/services/openldap-bootstrap/assets/scripts/helpers/common.sh}" \
|
||||
"${test_dir}/source" "${test_dir}/failure"; then
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
test ! -e "${test_dir}/failure"
|
||||
test -z "$(find "${test_dir}/output" -name '.templates.*')"
|
||||
@@ -35,7 +35,7 @@ Utility functions shared across the bootstrap scripts.
|
||||
|----------|-------------|
|
||||
| `check_args` | Validates that a script was called with the expected operation (`env`/`ldif`) and argument count |
|
||||
| `prepare_env_file` | Appends exported variable assignments (safely shell-quoted) to an env file |
|
||||
| `prepare_ldif_files` | Renders `.ldif.template` files via `container envsubst templates` and copies all resulting `.ldif` files (sorted) to the output directory |
|
||||
| `prepare_ldif_files` | Copies sources to a temporary writable directory (dereferencing symlinks), renders `.ldif.template` files via `container envsubst templates`, then copies all resulting `.ldif` files (sorted) to the output directory. Sources can be mounted read-only. The function removes its working copy on success; the bootstrap's global EXIT trap cleans up on failure. |
|
||||
| `get_dn_attr` | Extracts the value of a named attribute from a DN string (e.g. `cn` from `cn=admin,dc=example,dc=com`) |
|
||||
|
||||
### `helpers/password.sh`
|
||||
|
||||
@@ -33,6 +33,7 @@ prepare_ldif_files() {
|
||||
|
||||
local source_dir="$1"
|
||||
local output_dir="$2"
|
||||
local work_dir
|
||||
|
||||
if [ ! -d "${source_dir}" ]; then
|
||||
container log debug "Directory not found: ${source_dir}"
|
||||
@@ -41,13 +42,23 @@ prepare_ldif_files() {
|
||||
|
||||
container log info "Load ${source_dir} LDIFs ..."
|
||||
|
||||
container log debug "Converting templates to LDIFs in ${source_dir} ..."
|
||||
container envsubst templates "${source_dir}" 2>&1 | container log debug
|
||||
work_dir=$(mktemp -d "${output_dir}/.templates.XXXXXX")
|
||||
# output_dir is inside BOOTSTRAP_TMP_DIR, whose EXIT trap also cleans up
|
||||
# this working copy if any command below fails.
|
||||
|
||||
# Dereference projected-volume symlinks and make read-only sources writable
|
||||
# only in the working copy.
|
||||
cp -RL "${source_dir}/." "${work_dir}"
|
||||
chmod -R u+rwX "${work_dir}"
|
||||
|
||||
container log debug "Converting templates to LDIFs in ${work_dir} ..."
|
||||
container envsubst templates "${work_dir}" 2>&1 | container log debug
|
||||
|
||||
while IFS= read -r file; do
|
||||
cp -frav "${file}" "${output_dir}" 2>&1 | container log debug
|
||||
done < <(find "${source_dir}" -type f -name "*.ldif" | sort -V)
|
||||
done < <(find "${work_dir}" -type f -name "*.ldif" | sort -V)
|
||||
|
||||
rm -rf "${work_dir:?}"
|
||||
}
|
||||
|
||||
get_dn_attr() {
|
||||
|
||||
Reference in New Issue
Block a user