From 2f8ef9282cd4813e4058314845900e26a63a6a59 Mon Sep 17 00:00:00 2001 From: Austin Ziegler Date: Thu, 12 Oct 2023 01:12:20 -0400 Subject: [PATCH] 4.1.0 / 2023-10-12 - Upgraded to Ansible 8.4.0 - Renamed the `run` script to `kineticcafe-ansible` and fixed several issues: - Bash 4 or later is required for associative array support. Ensured that this would be respected on macOS by using `/usr/bin/env bash` instead of `/bin/bash`. - Updated the script to use the current version of the image. - Fixed various issues with file and directory mounts. Many more mountable files (`--become-password-file`, etc.) are supported than `--vault-password-file`. Note that not _all_ possible file parameters are supported, such as `--module-paths` or `--extra-vars @file`. Pull requests for supporting these would be considered. - Fixed an overzealous application of `--ask-vault-password`, even for commands that could not use it. - Changed the `sh` subcommand to execute `bash` and added `bash` as a known subcommand. - Added support for deriving the entry point from `basename $0`. - Updated the Docker image to use HEREDOC. - Added `less`, `nano`, and `vim-nox` packages. - Added an `install` script to install `kineticcafe-ansible` and optional symlinks. --- .github/workflows/build-test-image.yml | 2 +- Changelog.md | 33 ++ Dockerfile | 58 ++- README.md | 4 +- install | 135 +++++++ kineticcafe-ansible | 515 +++++++++++++++++++++++++ run | 187 --------- 7 files changed, 726 insertions(+), 208 deletions(-) create mode 100755 install create mode 100755 kineticcafe-ansible delete mode 100755 run diff --git a/.github/workflows/build-test-image.yml b/.github/workflows/build-test-image.yml index b22e3f4..30e0b04 100644 --- a/.github/workflows/build-test-image.yml +++ b/.github/workflows/build-test-image.yml @@ -25,6 +25,6 @@ jobs: push: false tags: kineticcafe/ansible:test - - run: ./run --version + - run: ./kineticcafe-ansible --version env: IMAGE: kineticcafe/ansible:test diff --git a/Changelog.md b/Changelog.md index e35ad15..f77b37b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,38 @@ # [ghcr.io/]kineticcafe/ansible Changelog +## 4.1.0 / 2023-10-12 + +- Upgraded to Ansible 8.4.0 + +- Renamed the `run` script to `kineticcafe-ansible` and fixed several issues: + + - Bash 4 or later is required for associative array support. Ensured that + this would be respected on macOS by using `/usr/bin/env bash` instead of + `/bin/bash`. + + - Updated the script to use the current version of the image. + + - Fixed various issues with file and directory mounts. Many more mountable + files (`--become-password-file`, etc.) are supported than + `--vault-password-file`. Note that not _all_ possible file parameters are + supported, such as `--module-paths` or `--extra-vars @file`. Pull requests + for supporting these would be considered. + + - Fixed an overzealous application of `--ask-vault-password`, even for + commands that could not use it. + + - Changed the `sh` subcommand to execute `bash` and added `bash` as a known + subcommand. + + - Added support for deriving the entry point from `basename $0`. + +- Updated the Docker image to use HEREDOC. + + - Added `less`, `nano`, and `vim-nox` packages. + +- Added an `install` script to install `kineticcafe-ansible` and optional + symlinks. + ## 4.0.0 / 2023-08-04 - Upgraded to Ansible 8.2.0 diff --git a/Dockerfile b/Dockerfile index fb7ac21..6de714f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,28 @@ +# syntax=docker/dockerfile:1 + FROM python:3.11-slim-bullseye AS builder ENV LC_ALL=C.UTF-8 \ LANG=C.UTF-8 \ EDITOR=nano -RUN apt-get -qqy update \ - && apt-get -qqy upgrade \ - && apt-get -qqy --no-install-recommends install \ - build-essential \ - python-dev \ - libffi-dev \ - rustc \ - && adduser --disabled-password --gecos '' ansible \ - && python3 -m pip install pip --upgrade \ - && mkdir -p /opt/ansible \ - && chown -R ansible:ansible /opt/ansible +RUN <&2 "error: '$1' is not a directory" + usage >&2 + exit 1 + fi + + if [[ -n "${target}" ]]; then + echo >&2 "warning: target '$target' is being replaced with '$1'" + fi + + target="$1" + ;; + esac + + shift +done + +target_script="${target}/${script}" + +download-script() { + if ! curl -sSL "${url}" -o "${target_script}"; then + echo >&2 "error: could not download ${url} into ${target_script}." + exit 1 + fi +} + +if "${no_download}"; then + if ! [[ -x "${target_script}" ]]; then + echo >&2 "error: ${target_script} does not exist and no download is set." + fi +elif [[ -x "${target_script}" ]]; then + if ! "${force}"; then + echo >&2 "error: ${target_script} already exists." + exit 1 + fi + + maybe-verbose download-script + + [[ -x "${target_script}" ]] || maybe-verbose chmod +x "${target_script}" +fi + +"${install_symlinks}" || exit 0 + +declare symlinked_command target_command canonical_target + +for symlinked_command in "${symlinked_commands[@]}"; do + target_command="${target}/${symlinked_command}" + + if [[ -f "${target_command}" ]]; then + canonical_target="$(canonicalize "${target_command}")" + + if [[ "${canonical_target}" != "${target_script}" ]]; then + "${force}" || continue + fi + fi + + maybe-verbose ln -sf "${target_script}" "${target_command}" +done diff --git a/kineticcafe-ansible b/kineticcafe-ansible new file mode 100755 index 0000000..7f96c88 --- /dev/null +++ b/kineticcafe-ansible @@ -0,0 +1,515 @@ +#! /usr/bin/env bash + +declare image user +image=${IMAGE:-ghcr.io/kineticcafe/ansible:4.1} +user="${USER-$(whoami)}" + +declare -A ask want galaxy +ask=( + [become_password]=false + [connection_password]=false + [vault_password]=false +) +want=( + [accept_host_key]=false + [become_password]=false + [config_file]=false + [connection_password]=false + [inventory_file]=false + [playbook_dir]=false + [private_key]=false + [tree_dir]=false + [vault_password]=false +) + +declare become_password_file config_file connection_password_file \ + inventory_file tree_dir vault_password_file + +declare -a passopt extra args interactive +interactive=(-it) + +home_dst=/home/ansible +if [[ "$(id -u "${user}")" -eq 0 ]]; then + home_dst=/root +fi +passopt+=(-e "HOME=${home_dst}") + +declare arg +for arg in \ + EDITOR \ + _ANSIBLE_COVERAGE_REMOTE_OUTPUT _ANSIBLE_COVERAGE_REMOTE_PATH_FILTER ACTION_WARNINGS AGNOSTIC_BECOME_PROMPT \ + ANSIBLE_ACTION_PLUGINS ANSIBLE_ACTION_WARNINGS ANSIBLE_AGNOSTIC_BECOME_PROMPT ANSIBLE_ANY_ERRORS_FATAL \ + ANSIBLE_ASK_PASS ANSIBLE_ASK_VAULT_PASS ANSIBLE_BECOME ANSIBLE_BECOME_ALLOW_SAME_USER ANSIBLE_BECOME_ASK_PASS \ + ANSIBLE_BECOME_EXE ANSIBLE_BECOME_FLAGS ANSIBLE_BECOME_METHOD ANSIBLE_BECOME_PLUGINS ANSIBLE_BECOME_USER \ + ANSIBLE_CACHE_PLUGIN ANSIBLE_CACHE_PLUGIN_CONNECTION ANSIBLE_CACHE_PLUGIN_PREFIX ANSIBLE_CACHE_PLUGIN_TIMEOUT \ + ANSIBLE_CACHE_PLUGINS ANSIBLE_CALLABLE_WHITELIST ANSIBLE_CALLBACK_PLUGINS ANSIBLE_CALLBACK_WHITELIST \ + ANSIBLE_CLICONF_PLUGINS ANSIBLE_COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH ANSIBLE_COLLECTIONS_PATH \ + ANSIBLE_COLLECTIONS_PATHS ANSIBLE_COLLECTIONS_SCAN_SYS_PATH ANSIBLE_COLOR_CHANGED ANSIBLE_COLOR_CONSOLE_PROMPT \ + ANSIBLE_COLOR_DEBUG ANSIBLE_COLOR_DEPRECATE ANSIBLE_COLOR_DIFF_ADD ANSIBLE_COLOR_DIFF_LINES \ + ANSIBLE_COLOR_DIFF_REMOVE ANSIBLE_COLOR_ERROR ANSIBLE_COLOR_HIGHLIGHT ANSIBLE_COLOR_OK ANSIBLE_COLOR_SKIP \ + ANSIBLE_COLOR_UNREACHABLE ANSIBLE_COLOR_VERBOSE ANSIBLE_COLOR_WARN ANSIBLE_COMMAND_WARNINGS \ + ANSIBLE_CONDITIONAL_BARE_VARS ANSIBLE_CONFIG ANSIBLE_CONNECTION_PATH ANSIBLE_CONNECTION_PLUGINS \ + ANSIBLE_COW_ACCEPTLIST ANSIBLE_COW_PATH ANSIBLE_COW_SELECTION ANSIBLE_COW_WHITELIST ANSIBLE_DEBUG \ + ANSIBLE_DEPRECATION_WARNINGS ANSIBLE_DEVEL_WARNING ANSIBLE_DIFF_ALWAYS ANSIBLE_DIFF_CONTEXT \ + ANSIBLE_DISPLAY_ARGS_TO_STDOUT ANSIBLE_DISPLAY_SKIPPED_HOSTS ANSIBLE_DOC_FRAGMENT_PLUGINS \ + ANSIBLE_DUPLICATE_YAML_DICT_KEY ANSIBLE_ERROR_ON_MISSING_HANDLER ANSIBLE_ERROR_ON_UNDEFINED_VARS \ + ANSIBLE_EXECUTABLE ANSIBLE_FACT_PATH ANSIBLE_FACTS_MODULES ANSIBLE_FILTER_PLUGINS ANSIBLE_FORCE_COLOR \ + ANSIBLE_FORCE_HANDLERS ANSIBLE_FORKS ANSIBLE_GALAXY_CACHE_DIR ANSIBLE_GALAXY_DISPLAY_PROGRESS \ + ANSIBLE_GALAXY_IGNORE ANSIBLE_GALAXY_ROLE_SKELETON ANSIBLE_GALAXY_ROLE_SKELETON_IGNORE ANSIBLE_GALAXY_SERVER \ + ANSIBLE_GALAXY_SERVER_LIST ANSIBLE_GALAXY_TOKEN_PATH ANSIBLE_GATHER_SUBSET ANSIBLE_GATHER_TIMEOUT \ + ANSIBLE_GATHERING ANSIBLE_HANDLER_INCLUDES_STATIC ANSIBLE_HASH_BEHAVIOUR ANSIBLE_HOST_KEY_CHECKING \ + ANSIBLE_HOST_PATTERN_MISMATCH ANSIBLE_HTTPAPI_PLUGINS ANSIBLE_INJECT_FACT_VARS \ + ANSIBLE_INVALID_TASK_ATTRIBUTE_FAILED ANSIBLE_INVENTORY ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED \ + ANSIBLE_INVENTORY_CACHE ANSIBLE_INVENTORY_CACHE_CONNECTION ANSIBLE_INVENTORY_CACHE_PLUGIN \ + ANSIBLE_INVENTORY_CACHE_PLUGIN_PREFIX ANSIBLE_INVENTORY_CACHE_TIMEOUT ANSIBLE_INVENTORY_EXPORT \ + ANSIBLE_INVENTORY_IGNORE ANSIBLE_INVENTORY_IGNORE_REGEX ANSIBLE_INVENTORY_PLUGINS \ + ANSIBLE_INVENTORY_UNPARSED_FAILED ANSIBLE_JINJA2_EXTENSIONS ANSIBLE_JINJA2_NATIVE ANSIBLE_KEEP_REMOTE_FILES \ + ANSIBLE_LIBRARY ANSIBLE_LIBVIRT_LXC_NOSECLABEL ANSIBLE_LOAD_CALLBACK_PLUGINS ANSIBLE_LOCAL_TEMP \ + ANSIBLE_LOCALHOST_WARNING ANSIBLE_LOG_FILTER ANSIBLE_LOG_PATH ANSIBLE_LOOKUP_PLUGINS ANSIBLE_MAX_DIFF_SIZE \ + ANSIBLE_MODULE_ARGS ANSIBLE_MODULE_IGNORE_EXTS ANSIBLE_MODULE_UTILS ANSIBLE_NETCONF_PLUGINS \ + ANSIBLE_NETCONF_SSH_CONFIG ANSIBLE_NETWORK_GROUP_MODULES ANSIBLE_NO_LOG ANSIBLE_NO_TARGET_SYSLOG ANSIBLE_NOCOLOR \ + ANSIBLE_NOCOWS ANSIBLE_NULL_REPRESENTATION ANSIBLE_OLD_PLUGIN_CACHE_CLEAR ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD \ + ANSIBLE_PARAMIKO_LOOK_FOR_KEYS ANSIBLE_PERSISTENT_COMMAND_TIMEOUT ANSIBLE_PERSISTENT_CONNECT_RETRY_TIMEOUT \ + ANSIBLE_PERSISTENT_CONNECT_TIMEOUT ANSIBLE_PERSISTENT_CONTROL_PATH_DIR ANSIBLE_PIPELINING \ + ANSIBLE_PLAYBOOK_VARS_ROOT ANSIBLE_POLL_INTERVAL ANSIBLE_PRECEDENCE \ + ANSIBLE_PRIVATE_ROLE_VARS ANSIBLE_PYTHON_INTERPRETER ANSIBLE_PYTHON_MODULE_RLIMIT_NOFILE ANSIBLE_REMOTE_PORT \ + ANSIBLE_REMOTE_USER ANSIBLE_RETRY_FILES_SAVE_PATH ANSIBLE_ROLES_PATH ANSIBLE_RUN_TAGS ANSIBLE_RUN_VARS_PLUGINS \ + ANSIBLE_SELINUX_SPECIAL_FS ANSIBLE_SHOW_CUSTOM_STATS ANSIBLE_SKIP_TAGS ANSIBLE_STDOUT_CALLBACK ANSIBLE_STRATEGY \ + ANSIBLE_STRATEGY_PLUGINS ANSIBLE_STRING_CONVERSION_ACTION ANSIBLE_STRING_TYPE_FILTERS ANSIBLE_SU \ + ANSIBLE_SYSLOG_FACILITY ANSIBLE_SYSTEM_WARNINGS ANSIBLE_TASK_DEBUGGER_IGNORE_ERRORS ANSIBLE_TASK_INCLUDES_STATIC \ + ANSIBLE_TASK_TIMEOUT ANSIBLE_TERMINAL_PLUGINS ANSIBLE_TEST_PLUGINS ANSIBLE_TIMEOUT \ + ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS ANSIBLE_TRANSPORT ANSIBLE_USE_PERSISTENT_CONNECTIONS ANSIBLE_VARS_PLUGINS \ + ANSIBLE_VAULT_ENCRYPT_IDENTITY ANSIBLE_VAULT_ID_MATCH ANSIBLE_VAULT_IDENTITY ANSIBLE_VAULT_IDENTITY_LIST \ + ANSIBLE_VERBOSE_TO_STDERR ANSIBLE_VERBOSITY ANSIBLE_WIN_ASYNC_STARTUP_TIMEOUT \ + ANSIBLE_WORKER_SHUTDOWN_POLL_COUNT ANSIBLE_WORKER_SHUTDOWN_POLL_DELAY ANSIBLE_YAML_FILENAME_EXT ANY_ERRORS_FATAL \ + BECOME_ALLOW_SAME_USER BECOME_PLUGIN_PATH CACHE_PLUGIN CACHE_PLUGIN_CONNECTION CACHE_PLUGIN_PREFIX \ + CACHE_PLUGIN_TIMEOUT CALLABLE_ACCEPT_LIST COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH COLLECTIONS_PATHS \ + COLLECTIONS_SCAN_SYS_PATH COLOR_CHANGED COLOR_CONSOLE_PROMPT COLOR_DEBUG COLOR_DEPRECATE COLOR_DIFF_ADD \ + COLOR_DIFF_LINES COLOR_DIFF_REMOVE COLOR_ERROR COLOR_HIGHLIGHT COLOR_OK COLOR_SKIP COLOR_UNREACHABLE \ + COLOR_VERBOSE COLOR_WARN COMMAND_WARNINGS CONDITIONAL_BARE_VARS COVERAGE_REMOTE_OUTPUT COVERAGE_REMOTE_PATHS \ + DEFAULT_ACTION_PLUGIN_PATH DEFAULT_ASK_PASS DEFAULT_ASK_VAULT_PASS DEFAULT_BECOME DEFAULT_BECOME_ASK_PASS \ + DEFAULT_BECOME_EXE DEFAULT_BECOME_FLAGS DEFAULT_BECOME_METHOD DEFAULT_BECOME_USER DEFAULT_CACHE_PLUGIN_PATH \ + DEFAULT_CALLBACK_PLUGIN_PATH DEFAULT_CLICONF_PLUGIN_PATH DEFAULT_CONNECTION_PLUGIN_PATH DEFAULT_DEBUG \ + DEFAULT_EXECUTABLE DEFAULT_FACT_PATH DEFAULT_FILTER_PLUGIN_PATH DEFAULT_FORCE_HANDLERS DEFAULT_FORKS \ + DEFAULT_GATHER_SUBSET DEFAULT_GATHER_TIMEOUT DEFAULT_GATHERING DEFAULT_HANDLER_INCLUDES_STATIC \ + DEFAULT_HASH_BEHAVIOUR DEFAULT_HOST_LIST DEFAULT_HTTPAPI_PLUGIN_PATH DEFAULT_INVENTORY_PLUGIN_PATH \ + DEFAULT_JINJA2_EXTENSIONS DEFAULT_JINJA2_NATIVE DEFAULT_KEEP_REMOTE_FILES DEFAULT_LIBVIRT_LXC_NOSECLABEL \ + DEFAULT_LOAD_CALLBACK_PLUGINS DEFAULT_LOCAL_TMP DEFAULT_LOG_FILTER DEFAULT_LOG_PATH DEFAULT_LOOKUP_PLUGIN_PATH \ + DEFAULT_MODULE_ARGS DEFAULT_MODULE_PATH DEFAULT_MODULE_UTILS_PATH DEFAULT_NETCONF_PLUGIN_PATH DEFAULT_NO_LOG \ + DEFAULT_NO_TARGET_SYSLOG DEFAULT_NULL_REPRESENTATION DEFAULT_POLL_INTERVAL \ + DEFAULT_PRIVATE_ROLE_VARS DEFAULT_REMOTE_PORT DEFAULT_REMOTE_USER DEFAULT_ROLES_PATH DEFAULT_SELINUX_SPECIAL_FS \ + DEFAULT_STDOUT_CALLBACK DEFAULT_STRATEGY DEFAULT_STRATEGY_PLUGIN_PATH DEFAULT_SU DEFAULT_SYSLOG_FACILITY \ + DEFAULT_TASK_INCLUDES_STATIC DEFAULT_TERMINAL_PLUGIN_PATH DEFAULT_TEST_PLUGIN_PATH DEFAULT_TIMEOUT \ + DEFAULT_TRANSPORT DEFAULT_UNDEFINED_VAR_BEHAVIOR DEFAULT_VARS_PLUGIN_PATH DEFAULT_VAULT_ENCRYPT_IDENTITY \ + DEFAULT_VAULT_ID_MATCH DEFAULT_VAULT_IDENTITY DEFAULT_VAULT_IDENTITY_LIST \ + DEFAULT_VERBOSITY DEPRECATION_WARNINGS DEVEL_WARNING DIFF_ALWAYS DIFF_CONTEXT DISPLAY_ARGS_TO_STDOUT \ + DISPLAY_SKIPPED_HOSTS DOC_FRAGMENT_PLUGIN_PATH DUPLICATE_YAML_DICT_KEY ERROR_ON_MISSING_HANDLER FACTS_MODULES \ + GALAXY_CACHE_DIR GALAXY_DISPLAY_PROGRESS GALAXY_IGNORE_CERTS GALAXY_ROLE_SKELETON GALAXY_ROLE_SKELETON_IGNORE \ + GALAXY_SERVER GALAXY_SERVER_LIST GALAXY_TOKEN_PATH HOST_KEY_CHECKING HOST_PATTERN_MISMATCH INJECT_FACTS_AS_VARS \ + INTERPRETER_PYTHON INVALID_TASK_ATTRIBUTE_FAILED INVENTORY_ANY_UNPARSED_IS_FAILED INVENTORY_CACHE_PLUGIN \ + INVENTORY_CACHE_PLUGIN_CONNECTION INVENTORY_CACHE_PLUGIN_PREFIX INVENTORY_CACHE_TIMEOUT INVENTORY_EXPORT \ + INVENTORY_IGNORE_EXTS INVENTORY_IGNORE_PATTERNS INVENTORY_UNPARSED_IS_FAILED LIBVIRT_LXC_NOSECLABEL \ + LOCALHOST_WARNING MAX_FILE_SIZE_FOR_DIFF MODULE_IGNORE_EXTS NETCONF_SSH_CONFIG NETWORK_GROUP_MODULES NO_COLOR \ + OLD_PLUGIN_CACHE_CLEARING PARAMIKO_HOST_KEY_AUTO_ADD PARAMIKO_LOOK_FOR_KEYS PERSISTENT_COMMAND_TIMEOUT \ + PERSISTENT_CONNECT_RETRY_TIMEOUT PERSISTENT_CONNECT_TIMEOUT PERSISTENT_CONTROL_PATH_DIR \ + PLAYBOOK_VARS_ROOT PYTHON_MODULE_RLIMIT_NOFILE RETRY_FILES_SAVE_PATH RUN_VARS_PLUGINS SHOW_CUSTOM_STATS \ + STRING_CONVERSION_ACTION STRING_TYPE_FILTERS SYSTEM_WARNINGS TAGS_RUN TAGS_SKIP TASK_DEBUGGER_IGNORE_ERRORS \ + TASK_TIMEOUT TRANSFORM_INVALID_GROUP_CHARS USE_PERSISTENT_CONNECTIONS VARIABLE_PRECEDENCE VERBOSE_TO_STDERR \ + WIN_ASYNC_STARTUP_TIMEOUT WORKER_SHUTDOWN_POLL_COUNT WORKER_SHUTDOWN_POLL_DELAY YAML_FILENAME_EXTENSIONS; do + [[ -n "${!arg}" ]] && passopt+=(-e "${arg}=${!arg}") +done + +case "$(basename "$0")" in +ansible | ansible-community | ansible-config) args+=("$(basename "$0")") ;; +ansible-connection | ansible-console) args+=("$(basename "$0")") ;; +ansible-doc | ansible-galaxy | ansible-inventory) args+=("$(basename "$0")") ;; +ansible-playbook | ansible-pull) args+=("$(basename "$0")") ;; +ansible-test | ansible-vault) args+=("$(basename "$0")") ;; +esac + +while (($#)); do + case "$1" in + --non-interactive) interactive=() ;; + --ask-become-pass | -K) ask[become_password]=true ;; + --ask-vault-password | --ask-vault-pass) ask[vault_password]=true ;; + --become-password-file | --become-pass-file) + become_password_file="$2" + shift + ;; + --connection-password-file | --conn-pass-file) + connection_password_file="$2" + shift + ;; + --inventory-file | --inventory | -i) + inventory_file="$2" + shift + ;; + --playbook-dir) + playbook_dir="$2" + shift + ;; + --private-key | --key-file) + private_key_file="$2" + shift + ;; + --vault-password-file | --vault-pass-file) + vault_password_file="$2" + shift + ;; + *) args+=("$1") ;; + esac + + shift +done + +set -- "${args[@]}" + +[[ -t 0 ]] || interactive=() + +declare entrypoint + +case "$1" in +sh | bash) entrypoint="bash" ;; +nano) entrypoint="$1" ;; +ansible) entrypoint="$1" ;; +ansible-community) entrypoint="$1" ;; +ansible-config) entrypoint="$1" ;; +ansible-connection) entrypoint="$1" ;; +ansible-console) entrypoint="$1" ;; +ansible-doc) entrypoint="$1" ;; +ansible-galaxy) entrypoint="$1" ;; +ansible-inventory) entrypoint="$1" ;; +ansible-playbook) entrypoint="$1" ;; +ansible-pull) entrypoint="$1" ;; +ansible-test) entrypoint="$1" ;; +ansible-vault) entrypoint="$1" ;; +version) + ask=( + [become_password]=false + [vault_password]=false + ) + shift + set -- --version "${@}" + ;; +esac + +if [[ -n "${entrypoint}" ]]; then + shift + passopt+=(--entrypoint "${entrypoint}") +fi + +case "${entrypoint:-ansible-playbook}" in +ansible) + want[become_password]=true + want[connection_password]=false + want[inventory_file]=true + want[playbook_dir]=true + want[private_key]=true + want[tree_dir]=true + want[vault_password]=true + + args=() + + while (($#)); do + case "$1" in + --tree | -T) + tree_dir="$2" + shift + ;; + *) args+=("$1") ;; + esac + shift + done + + set -- "${args[@]}" + ;; + +ansible-config) want[config_file]=true ;; +ansible-console) + want[become_password]=true + want[connection_password]=true + want[vault_password]=true + ;; +ansible-doc) + want[playbook_dir]=true + ;; +ansible-galaxy) + args=() + + declare subcommand + if [[ "$*" =~ \bcollection\b.*\b(download|init|build|install|list|verify)\b ]]; then + subcommand="collection-${BASH_REMATCH[1]}" + elif [[ "$*" =~ \brole\b.*\b(init|remove|delete|list|search|import|setup|info|install)\b ]]; then + subcommand="role-${BASH_REMATCH[1]}" + fi + + while (($#subcommand)) && (($#)); do + case "$1" in + --download-path) + if [[ "${subcommand}" == collection-download ]]; then + galaxy[download_path]="$2" + shift + else + args+=("$1") + fi + ;; + --init-path) + case "${subcommand}" in + collection-init | role-init) + galaxy[init_path]="$2" + shift + ;; + *) args+=("$1") ;; + esac + ;; + --collection-skeleton) + if [[ "${subcommand}" == collection-init ]]; then + galaxy[collection_skeleton]="$2" + shift + else + args+=("$1") + fi + ;; + --role-skeleton) + if [[ "${subcommand}" == role-init ]]; then + galaxy[role_skeleton]="$2" + shift + else + args+=("$1") + fi + ;; + --output-path) + if [[ "${subcommand}" == collection-build ]]; then + galaxy[build_output_path]="$2" + shift + else + args+=("$1") + fi + ;; + --collections-path) + case "${subcommand}" in + collection-install | collection-list | collection-verify) + galaxy[collections_path]="$2" + shift + ;; + *) args+=("$1") ;; + esac + ;; + --roles-path) + case "${subcommand}" in + role-remove | role-list | role-setup | role-info | role-install) + galaxy[roles_path]="$2" + shift + ;; + *) args+=("$1") ;; + esac + ;; + --keyring) + case "${subcommand}" in + collection-install | collection-verify) + galaxy[keyring]="$2" + shift + ;; + *) args+=("$1") ;; + esac + ;; + -p) + case "${subcommand}" in + collection-download) + galaxy[download_path]="$2" + shift + ;; + collection-install | collection-list | collection-verify) + galaxy[collections_path]="$2" + shift + ;; + role-remove | role-list | role-setup | role-info | role-install) + galaxy[roles_path]="$2" + shift + ;; + *) args+=("$1") ;; + esac + ;; + esac + done + + set -- "${args[@]}" + ;; +ansible-inventory) + want[inventory_file]=true + want[playbook_dir]=true + want[vault_password]=true + ;; +ansible-playbook) + want[become_password]=true + want[connection_password]=true + want[inventory_file]=true + want[private_key]=true + want[vault_password]=true + ;; +ansible-pull) + want[become_password]=true + want[connection_password]=true + want[inventory_file]=true + want[playbook_dir]=true + want[private_key]=true + want[vault_password]=true + + args=() + + while (($#)); do + case "$1" in + --accept-host-key) + want[accept_host_key]=true # add --accept-host-key and mount ~/.ssh/known_hosts as writable + ;; + *) args+=("$1") ;; + esac + + shift + done + + set -- "${args[@]}" + ;; + +ansible-vault) + want[vault_password]=true + ;; +esac + +if [[ "$*" =~ \b--version\b ]] || [[ "$*" =~ \b--help\b ]] || [[ "$*" =~ \b-h\b ]]; then + want=( + [accept_host_key]=false + [become_password]=false + [config_file]=false + [inventory_file]=false + [playbook_dir]=false + [private_key]=false + [tree_dir]=false + [vault_password]=false + ) +fi + +if [[ -d "${HOME}"/.ansible/roles ]]; then + passopt+=(--mount "type=bind,src=${HOME}/.ansible/roles,dst=${home_dst}/.ansible/roles,readonly") +fi + +if [[ -d "${HOME}"/.ssh ]]; then + passopt+=(--mount "type=bind,src=${HOME}/.ssh,dst=${home_dst}/.ssh,readonly") + + if "${want[accept_host_key]}" && [[ -f "${HOME}/.ssh/known_hosts" ]]; then + passopt+=(--mount "type=bind,src=${HOME}/.ssh/known_hosts,dst=${home_dst}/.ssh/known_hosts") + extra+=(--accept-host-key) + fi +fi + +mount-path() { + local parameter name + parameter="$1" + name="$2" + + if [[ -n "${name}" ]]; then + if [[ -d "${name}" ]]; then + passopt+=(--mount "type=bind,src=${name},dst=/tmp/${parameter#--}") + extra+=("${parameter}" "/tmp/${parameter#--}") + + return 0 + else + echo >&2 "Error: cannot find ${parameter} directory '${name}'." + exit 1 + fi + fi + + return 1 +} + +mount-file() { + local parameter name ro + parameter="$1" + name="$(eval "echo $2")" + ro=${3:+,readonly} + + if [[ -n "${name}" ]]; then + if [[ -s "${name}" ]]; then + passopt+=(--mount "type=bind,src=${name},dst=/tmp/${parameter#--}${ro}") + extra+=("${parameter}" "/tmp/${parameter#--}") + + return 0 + else + echo >&2 "Error: cannot find ${parameter} file '${name}'." + exit 1 + fi + fi + + return 1 +} + +if "${want[become_password]}" && ! mount-file --become-password-file "${become_password_file:-${ANSIBLE_BECOME_PASSWORD_FILE:-${DEFAULT_BECOME_PASSWORD_FILE}}}"; then + if "${ask[become_password]}"; then + if ((${#interactive[@]} == 0)); then + echo >&2 "Error: cannot ask become password in non-interactive mode. Use --become-password-file." + exit 1 + fi + + extra+=(--ask-become-password) + fi +fi + +if "${want[vault_password]}" && ! mount-file --vault-password-file "${vault_password_file:-${ANSIBLE_vault_PASSWORD_FILE:-${DEFAULT_vault_PASSWORD_FILE}}}"; then + if "${ask[vault_password]}"; then + if ((${#interactive[@]} == 0)); then + echo >&2 "Error: cannot ask vault password in non-interactive mode. Use --vault-password-file." + exit 1 + fi + + extra+=(--ask-vault-password) + fi +fi + +if "${want[config_file]}"; then + mount-file --config "${config_file:-${ANSIBLE_CONFIG_FILE:-${DEFAULT_CONFIG_FILE}}}" +fi + +if "${want[connection_password]}"; then + mount-file --connection-password-file "${connection_password_file:-${ANSIBLE_CONNECTION_PASSWORD_FILE:-${DEFAULT_CONNECTION_PASSWORD_FILE}}}" +fi + +if ((${#galaxy[@]})); then + mount-dir --download-path "${galaxy[download_path]}" + mount-dir --init-path "${galaxy[init_path]}" + mount-dir --collection-skeleton "${galaxy[collection_skeleton]}" + mount-dir --role-skeleton "${galaxy[role_skeleton]}" + mount-dir --output-path "${galaxy[build_output_path]}" + mount-dir --collections-path "${galaxy[collections_path]}" + mount-dir --roles-path "${galaxy[roles_path]}" + mount-file --keyring "${galaxy[keyring]}" +fi + +if "${want[inventory_file]}"; then + mount-file --inventory-file "${inventory_file}" +fi + +if "${want[playbook_dir]}"; then + mount-dir --playbook-dir "${playbook_dir:-${ANSIBLE_PLAYBOOK_DIR:-${PLAYBOOK_DIR}}}" +fi + +if "${want[private_key]}"; then + mount-file --private-key "${private_key_file:-${ANSIBLE_PRIVATE_KEY_FILE:-${DEFAULT_PRIVATE_KEY_FILE}}}" +fi + +if "${want[tree_dir]}"; then + mount-dir --tree "${tree_dir}" +fi + +if "${ask[vault_password]}"; then + if ((${#interactive[@]} == 0)); then + echo >&2 "Error: Cannot ask vault password in non-interactive mode. Use --vault-password-file." + exit 1 + fi + + extra+=(--ask-vault-password) +fi + +# shellcheck disable=SC2086 +docker run "${interactive[@]}" --rm --network host \ + --mount "type=bind,src=$(pwd),dst=/repo" \ + "${passopt[@]}" "${image}" "$@" "${extra[@]}" diff --git a/run b/run deleted file mode 100755 index 752b048..0000000 --- a/run +++ /dev/null @@ -1,187 +0,0 @@ -#! /bin/bash - -declare image user need_vault arg vault_password_file entrypoint -image=${IMAGE:-ghcr.io/kineticcafe/ansible:3.1} -user="${USER-$(whoami)}" -need_vault=true -vault_password_file= - -declare -a passopt extra args interactive -passopt=() -extra=() -args=() -interactive=(-it) - -home_dst=/home/ansible -if [[ "$(id -u "${user}")" -eq 0 ]]; then - home_dst=/root -fi -passopt+=(-e "HOME=${home_dst}") - -for arg in \ - _ANSIBLE_COVERAGE_REMOTE_OUTPUT _ANSIBLE_COVERAGE_REMOTE_PATH_FILTER ACTION_WARNINGS AGNOSTIC_BECOME_PROMPT \ - ANSIBLE_ACTION_PLUGINS ANSIBLE_ACTION_WARNINGS ANSIBLE_AGNOSTIC_BECOME_PROMPT ANSIBLE_ANY_ERRORS_FATAL \ - ANSIBLE_ASK_PASS ANSIBLE_ASK_VAULT_PASS ANSIBLE_BECOME ANSIBLE_BECOME_ALLOW_SAME_USER ANSIBLE_BECOME_ASK_PASS \ - ANSIBLE_BECOME_EXE ANSIBLE_BECOME_FLAGS ANSIBLE_BECOME_METHOD ANSIBLE_BECOME_PLUGINS ANSIBLE_BECOME_USER \ - ANSIBLE_CACHE_PLUGIN ANSIBLE_CACHE_PLUGIN_CONNECTION ANSIBLE_CACHE_PLUGIN_PREFIX ANSIBLE_CACHE_PLUGIN_TIMEOUT \ - ANSIBLE_CACHE_PLUGINS ANSIBLE_CALLABLE_WHITELIST ANSIBLE_CALLBACK_PLUGINS ANSIBLE_CALLBACK_WHITELIST \ - ANSIBLE_CLICONF_PLUGINS ANSIBLE_COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH ANSIBLE_COLLECTIONS_PATH \ - ANSIBLE_COLLECTIONS_PATHS ANSIBLE_COLLECTIONS_SCAN_SYS_PATH ANSIBLE_COLOR_CHANGED ANSIBLE_COLOR_CONSOLE_PROMPT \ - ANSIBLE_COLOR_DEBUG ANSIBLE_COLOR_DEPRECATE ANSIBLE_COLOR_DIFF_ADD ANSIBLE_COLOR_DIFF_LINES \ - ANSIBLE_COLOR_DIFF_REMOVE ANSIBLE_COLOR_ERROR ANSIBLE_COLOR_HIGHLIGHT ANSIBLE_COLOR_OK ANSIBLE_COLOR_SKIP \ - ANSIBLE_COLOR_UNREACHABLE ANSIBLE_COLOR_VERBOSE ANSIBLE_COLOR_WARN ANSIBLE_COMMAND_WARNINGS \ - ANSIBLE_CONDITIONAL_BARE_VARS ANSIBLE_CONFIG ANSIBLE_CONNECTION_PATH ANSIBLE_CONNECTION_PLUGINS \ - ANSIBLE_COW_ACCEPTLIST ANSIBLE_COW_PATH ANSIBLE_COW_SELECTION ANSIBLE_COW_WHITELIST ANSIBLE_DEBUG \ - ANSIBLE_DEPRECATION_WARNINGS ANSIBLE_DEVEL_WARNING ANSIBLE_DIFF_ALWAYS ANSIBLE_DIFF_CONTEXT \ - ANSIBLE_DISPLAY_ARGS_TO_STDOUT ANSIBLE_DISPLAY_SKIPPED_HOSTS ANSIBLE_DOC_FRAGMENT_PLUGINS \ - ANSIBLE_DUPLICATE_YAML_DICT_KEY ANSIBLE_ERROR_ON_MISSING_HANDLER ANSIBLE_ERROR_ON_UNDEFINED_VARS \ - ANSIBLE_EXECUTABLE ANSIBLE_FACT_PATH ANSIBLE_FACTS_MODULES ANSIBLE_FILTER_PLUGINS ANSIBLE_FORCE_COLOR \ - ANSIBLE_FORCE_HANDLERS ANSIBLE_FORKS ANSIBLE_GALAXY_CACHE_DIR ANSIBLE_GALAXY_DISPLAY_PROGRESS \ - ANSIBLE_GALAXY_IGNORE ANSIBLE_GALAXY_ROLE_SKELETON ANSIBLE_GALAXY_ROLE_SKELETON_IGNORE ANSIBLE_GALAXY_SERVER \ - ANSIBLE_GALAXY_SERVER_LIST ANSIBLE_GALAXY_TOKEN_PATH ANSIBLE_GATHER_SUBSET ANSIBLE_GATHER_TIMEOUT \ - ANSIBLE_GATHERING ANSIBLE_HANDLER_INCLUDES_STATIC ANSIBLE_HASH_BEHAVIOUR ANSIBLE_HOST_KEY_CHECKING \ - ANSIBLE_HOST_PATTERN_MISMATCH ANSIBLE_HTTPAPI_PLUGINS ANSIBLE_INJECT_FACT_VARS \ - ANSIBLE_INVALID_TASK_ATTRIBUTE_FAILED ANSIBLE_INVENTORY ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED \ - ANSIBLE_INVENTORY_CACHE ANSIBLE_INVENTORY_CACHE_CONNECTION ANSIBLE_INVENTORY_CACHE_PLUGIN \ - ANSIBLE_INVENTORY_CACHE_PLUGIN_PREFIX ANSIBLE_INVENTORY_CACHE_TIMEOUT ANSIBLE_INVENTORY_EXPORT \ - ANSIBLE_INVENTORY_IGNORE ANSIBLE_INVENTORY_IGNORE_REGEX ANSIBLE_INVENTORY_PLUGINS \ - ANSIBLE_INVENTORY_UNPARSED_FAILED ANSIBLE_JINJA2_EXTENSIONS ANSIBLE_JINJA2_NATIVE ANSIBLE_KEEP_REMOTE_FILES \ - ANSIBLE_LIBRARY ANSIBLE_LIBVIRT_LXC_NOSECLABEL ANSIBLE_LOAD_CALLBACK_PLUGINS ANSIBLE_LOCAL_TEMP \ - ANSIBLE_LOCALHOST_WARNING ANSIBLE_LOG_FILTER ANSIBLE_LOG_PATH ANSIBLE_LOOKUP_PLUGINS ANSIBLE_MAX_DIFF_SIZE \ - ANSIBLE_MODULE_ARGS ANSIBLE_MODULE_IGNORE_EXTS ANSIBLE_MODULE_UTILS ANSIBLE_NETCONF_PLUGINS \ - ANSIBLE_NETCONF_SSH_CONFIG ANSIBLE_NETWORK_GROUP_MODULES ANSIBLE_NO_LOG ANSIBLE_NO_TARGET_SYSLOG ANSIBLE_NOCOLOR \ - ANSIBLE_NOCOWS ANSIBLE_NULL_REPRESENTATION ANSIBLE_OLD_PLUGIN_CACHE_CLEAR ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD \ - ANSIBLE_PARAMIKO_LOOK_FOR_KEYS ANSIBLE_PERSISTENT_COMMAND_TIMEOUT ANSIBLE_PERSISTENT_CONNECT_RETRY_TIMEOUT \ - ANSIBLE_PERSISTENT_CONNECT_TIMEOUT ANSIBLE_PERSISTENT_CONTROL_PATH_DIR ANSIBLE_PIPELINING ANSIBLE_PLAYBOOK_DIR \ - ANSIBLE_PLAYBOOK_VARS_ROOT ANSIBLE_POLL_INTERVAL ANSIBLE_PRECEDENCE ANSIBLE_PRIVATE_KEY_FILE \ - ANSIBLE_PRIVATE_ROLE_VARS ANSIBLE_PYTHON_INTERPRETER ANSIBLE_PYTHON_MODULE_RLIMIT_NOFILE ANSIBLE_REMOTE_PORT \ - ANSIBLE_REMOTE_USER ANSIBLE_RETRY_FILES_SAVE_PATH ANSIBLE_ROLES_PATH ANSIBLE_RUN_TAGS ANSIBLE_RUN_VARS_PLUGINS \ - ANSIBLE_SELINUX_SPECIAL_FS ANSIBLE_SHOW_CUSTOM_STATS ANSIBLE_SKIP_TAGS ANSIBLE_STDOUT_CALLBACK ANSIBLE_STRATEGY \ - ANSIBLE_STRATEGY_PLUGINS ANSIBLE_STRING_CONVERSION_ACTION ANSIBLE_STRING_TYPE_FILTERS ANSIBLE_SU \ - ANSIBLE_SYSLOG_FACILITY ANSIBLE_SYSTEM_WARNINGS ANSIBLE_TASK_DEBUGGER_IGNORE_ERRORS ANSIBLE_TASK_INCLUDES_STATIC \ - ANSIBLE_TASK_TIMEOUT ANSIBLE_TERMINAL_PLUGINS ANSIBLE_TEST_PLUGINS ANSIBLE_TIMEOUT \ - ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS ANSIBLE_TRANSPORT ANSIBLE_USE_PERSISTENT_CONNECTIONS ANSIBLE_VARS_PLUGINS \ - ANSIBLE_VAULT_ENCRYPT_IDENTITY ANSIBLE_VAULT_ID_MATCH ANSIBLE_VAULT_IDENTITY ANSIBLE_VAULT_IDENTITY_LIST \ - ANSIBLE_VERBOSE_TO_STDERR ANSIBLE_VERBOSITY ANSIBLE_WIN_ASYNC_STARTUP_TIMEOUT \ - ANSIBLE_WORKER_SHUTDOWN_POLL_COUNT ANSIBLE_WORKER_SHUTDOWN_POLL_DELAY ANSIBLE_YAML_FILENAME_EXT ANY_ERRORS_FATAL \ - BECOME_ALLOW_SAME_USER BECOME_PLUGIN_PATH CACHE_PLUGIN CACHE_PLUGIN_CONNECTION CACHE_PLUGIN_PREFIX \ - CACHE_PLUGIN_TIMEOUT CALLABLE_ACCEPT_LIST COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH COLLECTIONS_PATHS \ - COLLECTIONS_SCAN_SYS_PATH COLOR_CHANGED COLOR_CONSOLE_PROMPT COLOR_DEBUG COLOR_DEPRECATE COLOR_DIFF_ADD \ - COLOR_DIFF_LINES COLOR_DIFF_REMOVE COLOR_ERROR COLOR_HIGHLIGHT COLOR_OK COLOR_SKIP COLOR_UNREACHABLE \ - COLOR_VERBOSE COLOR_WARN COMMAND_WARNINGS CONDITIONAL_BARE_VARS COVERAGE_REMOTE_OUTPUT COVERAGE_REMOTE_PATHS \ - DEFAULT_ACTION_PLUGIN_PATH DEFAULT_ASK_PASS DEFAULT_ASK_VAULT_PASS DEFAULT_BECOME DEFAULT_BECOME_ASK_PASS \ - DEFAULT_BECOME_EXE DEFAULT_BECOME_FLAGS DEFAULT_BECOME_METHOD DEFAULT_BECOME_USER DEFAULT_CACHE_PLUGIN_PATH \ - DEFAULT_CALLBACK_PLUGIN_PATH DEFAULT_CLICONF_PLUGIN_PATH DEFAULT_CONNECTION_PLUGIN_PATH DEFAULT_DEBUG \ - DEFAULT_EXECUTABLE DEFAULT_FACT_PATH DEFAULT_FILTER_PLUGIN_PATH DEFAULT_FORCE_HANDLERS DEFAULT_FORKS \ - DEFAULT_GATHER_SUBSET DEFAULT_GATHER_TIMEOUT DEFAULT_GATHERING DEFAULT_HANDLER_INCLUDES_STATIC \ - DEFAULT_HASH_BEHAVIOUR DEFAULT_HOST_LIST DEFAULT_HTTPAPI_PLUGIN_PATH DEFAULT_INVENTORY_PLUGIN_PATH \ - DEFAULT_JINJA2_EXTENSIONS DEFAULT_JINJA2_NATIVE DEFAULT_KEEP_REMOTE_FILES DEFAULT_LIBVIRT_LXC_NOSECLABEL \ - DEFAULT_LOAD_CALLBACK_PLUGINS DEFAULT_LOCAL_TMP DEFAULT_LOG_FILTER DEFAULT_LOG_PATH DEFAULT_LOOKUP_PLUGIN_PATH \ - DEFAULT_MODULE_ARGS DEFAULT_MODULE_PATH DEFAULT_MODULE_UTILS_PATH DEFAULT_NETCONF_PLUGIN_PATH DEFAULT_NO_LOG \ - DEFAULT_NO_TARGET_SYSLOG DEFAULT_NULL_REPRESENTATION DEFAULT_POLL_INTERVAL DEFAULT_PRIVATE_KEY_FILE \ - DEFAULT_PRIVATE_ROLE_VARS DEFAULT_REMOTE_PORT DEFAULT_REMOTE_USER DEFAULT_ROLES_PATH DEFAULT_SELINUX_SPECIAL_FS \ - DEFAULT_STDOUT_CALLBACK DEFAULT_STRATEGY DEFAULT_STRATEGY_PLUGIN_PATH DEFAULT_SU DEFAULT_SYSLOG_FACILITY \ - DEFAULT_TASK_INCLUDES_STATIC DEFAULT_TERMINAL_PLUGIN_PATH DEFAULT_TEST_PLUGIN_PATH DEFAULT_TIMEOUT \ - DEFAULT_TRANSPORT DEFAULT_UNDEFINED_VAR_BEHAVIOR DEFAULT_VARS_PLUGIN_PATH DEFAULT_VAULT_ENCRYPT_IDENTITY \ - DEFAULT_VAULT_ID_MATCH DEFAULT_VAULT_IDENTITY DEFAULT_VAULT_IDENTITY_LIST \ - DEFAULT_VERBOSITY DEPRECATION_WARNINGS DEVEL_WARNING DIFF_ALWAYS DIFF_CONTEXT DISPLAY_ARGS_TO_STDOUT \ - DISPLAY_SKIPPED_HOSTS DOC_FRAGMENT_PLUGIN_PATH DUPLICATE_YAML_DICT_KEY ERROR_ON_MISSING_HANDLER FACTS_MODULES \ - GALAXY_CACHE_DIR GALAXY_DISPLAY_PROGRESS GALAXY_IGNORE_CERTS GALAXY_ROLE_SKELETON GALAXY_ROLE_SKELETON_IGNORE \ - GALAXY_SERVER GALAXY_SERVER_LIST GALAXY_TOKEN_PATH HOST_KEY_CHECKING HOST_PATTERN_MISMATCH INJECT_FACTS_AS_VARS \ - INTERPRETER_PYTHON INVALID_TASK_ATTRIBUTE_FAILED INVENTORY_ANY_UNPARSED_IS_FAILED INVENTORY_CACHE_PLUGIN \ - INVENTORY_CACHE_PLUGIN_CONNECTION INVENTORY_CACHE_PLUGIN_PREFIX INVENTORY_CACHE_TIMEOUT INVENTORY_EXPORT \ - INVENTORY_IGNORE_EXTS INVENTORY_IGNORE_PATTERNS INVENTORY_UNPARSED_IS_FAILED LIBVIRT_LXC_NOSECLABEL \ - LOCALHOST_WARNING MAX_FILE_SIZE_FOR_DIFF MODULE_IGNORE_EXTS NETCONF_SSH_CONFIG NETWORK_GROUP_MODULES NO_COLOR \ - OLD_PLUGIN_CACHE_CLEARING PARAMIKO_HOST_KEY_AUTO_ADD PARAMIKO_LOOK_FOR_KEYS PERSISTENT_COMMAND_TIMEOUT \ - PERSISTENT_CONNECT_RETRY_TIMEOUT PERSISTENT_CONNECT_TIMEOUT PERSISTENT_CONTROL_PATH_DIR PLAYBOOK_DIR \ - PLAYBOOK_VARS_ROOT PYTHON_MODULE_RLIMIT_NOFILE RETRY_FILES_SAVE_PATH RUN_VARS_PLUGINS SHOW_CUSTOM_STATS \ - STRING_CONVERSION_ACTION STRING_TYPE_FILTERS SYSTEM_WARNINGS TAGS_RUN TAGS_SKIP TASK_DEBUGGER_IGNORE_ERRORS \ - TASK_TIMEOUT TRANSFORM_INVALID_GROUP_CHARS USE_PERSISTENT_CONNECTIONS VARIABLE_PRECEDENCE VERBOSE_TO_STDERR \ - WIN_ASYNC_STARTUP_TIMEOUT WORKER_SHUTDOWN_POLL_COUNT WORKER_SHUTDOWN_POLL_DELAY YAML_FILENAME_EXTENSIONS; do - [[ -n "${!arg}" ]] && passopt+=(-e "${var}=${!arg}") -done - -declare vpf -vpf="${vault_password_file:-"${ANSIBLE_VAULT_PASSWORD_FILE:-"${DEFAULT_VAULT_PASSWORD_FILE}"}"}" - -if [[ -n "${vpf}" ]]; then - if [[ -s "${vpf}" ]]; then - need_vault=false - passopt+=(--mount "type=bind,src=${vpf},dst=/tmp/vault_password_file,readonly") - extra+=(--vault-password-file /tmp/vault_password_file) - else - echo >&2 "Error: Cannot find vault password file '${vpf}'." - exit 1 - fi -fi - -if [[ -d "${HOME}"/.ansible/roles ]]; then - passopt+=(--mount "type=bind,src=${HOME}/.ansible/roles,dst=${home_dst}/.ansible/roles,readonly") -fi - -if [[ -d "${HOME}"/.ssh ]]; then - passopt+=(--mount "type=bind,src=${HOME}/.ssh,dst=${home_dst}/.ssh,readonly") -fi - -declare entrypoint - -while (($#)); do - case "$1" in - --non-interactive) - interactive=() - ;; - --ask-vault-password) - need_vault=false - args+=("$1") - ;; - --vault-password-file | --vault-pass-file) - vault_password_file="$2" - shift - ;; - *) - args+=("$1") - ;; - esac - - shift -done - -set -- "${args[@]}" - -[[ -t 0 ]] || interactive=() - -case "$1" in -sh | nano) entrypoint="$1" ;; -ansible-config | ansible-galaxy | ansible-test) entrypoint="$1" ;; -ansible-connection | ansible-inventory | ansible-vault) entrypoint="$1" ;; -ansible | ansible-console) entrypoint="$1" ;; -ansible-community | ansible-doc | ansible-pull) entrypoint="$1" ;; -version) - need_vault=false - shift - set -- --version "${@}" - ;; -esac - -if [[ -n "${entrypoint}" ]]; then - passopt+=(--entrypoint "${entrypoint}") - shift -fi - -if [[ "$*" =~ --version ]] || [[ "$*" =~ --help ]]; then - need_vault=false -fi - -if "${need_vault}"; then - if ((${#interactive[@]} == 0)); then - echo >&2 "Error: Cannot ask vault password file in non-interactive mode." - exit 1 - fi - - extra+=(--ask-vault-password) -fi - -# shellcheck disable=SC2086 -docker run "${interactive[@]}" --rm --network host \ - --mount "type=bind,src=$(pwd),dst=/repo" \ - "${passopt[@]}" "${image}" "${@}" "${extra[@]}"