From 2fce529edcefa5c14e1eed887d56fa814d3561a9 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 28 Sep 2026 03:50:09 +0000 Subject: [PATCH] Expose Scriptorium imports and transient retry settings --- README.md | 18 +++++++++++++++++ defaults/main.yml | 2 ++ meta/argument_specs.yml | 7 +++++++ templates/config.yml.j2 | 22 ++++++++++++++++++++- tests/integration | 44 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8257399..0939847 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ scriptorium_config_owner: root scriptorium_config_group: root scriptorium_config_directory_mode: "0755" scriptorium_config_file_mode: "0644" +scriptorium_configkit_imports: null scriptorium_prompt_dir: null scriptorium_profile_dir: null scriptorium_schema_dir: null @@ -30,6 +31,7 @@ scriptorium_server_max_artifact_bytes: null scriptorium_server_max_response_bytes: null scriptorium_defaults_render_format: null scriptorium_backends: null +scriptorium_transient_retries: null ``` When `scriptorium_manage_build_dependencies` is `false`, Git and the executable @@ -62,6 +64,22 @@ Backend entries may name a credential environment variable through does not install prompt, profile, or schema content and does not manage a service. +`scriptorium_configkit_imports` accepts a list of native ConfigKit import +mappings. Paths and globs are interpreted by Scriptorium relative to the +configuration root; the caller supplies and owns the referenced files. For +example, an inventory may select a caller-managed fragment: + +```yaml +scriptorium_configkit_imports: + - path: fragments/server.yml +scriptorium_transient_retries: 0 +``` + +Both settings are omitted when `null`. Setting `scriptorium_transient_retries` +to `0` disables additional transient attempts; omission leaves the retry +budget with Scriptorium and PromptKit. Leave these newer fields unset when +selecting an older Scriptorium version that does not support them. + ## Example ```yaml diff --git a/defaults/main.yml b/defaults/main.yml index c8a7fa7..6e62cb4 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -11,6 +11,7 @@ scriptorium_config_owner: root scriptorium_config_group: root scriptorium_config_directory_mode: "0755" scriptorium_config_file_mode: "0644" +scriptorium_configkit_imports: null scriptorium_prompt_dir: null scriptorium_profile_dir: null scriptorium_schema_dir: null @@ -21,3 +22,4 @@ scriptorium_server_max_artifact_bytes: null scriptorium_server_max_response_bytes: null scriptorium_defaults_render_format: null scriptorium_backends: null +scriptorium_transient_retries: null diff --git a/meta/argument_specs.yml b/meta/argument_specs.yml index 427bb44..c765194 100644 --- a/meta/argument_specs.yml +++ b/meta/argument_specs.yml @@ -39,6 +39,10 @@ argument_specs: scriptorium_config_file_mode: type: str required: true + scriptorium_configkit_imports: + type: list + elements: dict + required: false scriptorium_prompt_dir: type: path required: false @@ -69,3 +73,6 @@ argument_specs: scriptorium_backends: type: dict required: false + scriptorium_transient_retries: + type: int + required: false diff --git a/templates/config.yml.j2 b/templates/config.yml.j2 index 0f603bc..59006d2 100644 --- a/templates/config.yml.j2 +++ b/templates/config.yml.j2 @@ -1,6 +1,23 @@ -{% if scriptorium_prompt_dir is none and scriptorium_profile_dir is none and scriptorium_schema_dir is none and scriptorium_server_addr is none and scriptorium_server_artifact_root is none and scriptorium_server_max_request_bytes is none and scriptorium_server_max_artifact_bytes is none and scriptorium_server_max_response_bytes is none and scriptorium_defaults_render_format is none and scriptorium_backends is none %} +{% if ( + scriptorium_configkit_imports is none + and scriptorium_prompt_dir is none + and scriptorium_profile_dir is none + and scriptorium_schema_dir is none + and scriptorium_server_addr is none + and scriptorium_server_artifact_root is none + and scriptorium_server_max_request_bytes is none + and scriptorium_server_max_artifact_bytes is none + and scriptorium_server_max_response_bytes is none + and scriptorium_defaults_render_format is none + and scriptorium_backends is none + and scriptorium_transient_retries is none +) %} {} {% else %} +{% if scriptorium_configkit_imports is not none %} +configkit: + imports: {{ scriptorium_configkit_imports | to_json }} +{% endif %} {% if scriptorium_prompt_dir is not none %} prompt_dir: {{ scriptorium_prompt_dir | to_json }} {% endif %} @@ -35,4 +52,7 @@ defaults: {% if scriptorium_backends is not none %} backends: {{ scriptorium_backends | to_json }} {% endif %} +{% if scriptorium_transient_retries is not none %} +transient_retries: {{ scriptorium_transient_retries | to_json }} +{% endif %} {% endif %} diff --git a/tests/integration b/tests/integration index 65d4a21..cf672f6 100755 --- a/tests/integration +++ b/tests/integration @@ -16,6 +16,8 @@ ansible_playbook="$workspace_venv/bin/ansible-playbook" binary_path=/usr/local/bin/scriptorium config_path=/usr/local/etc/scriptorium/config.yml profile_dir="$test_tmp/profiles" +import_root="$test_tmp/config-root" +import_config_path="$import_root/config.yml" cleanup() { exit_status=$? @@ -56,6 +58,14 @@ cd "$repository_root" baseline_log="$test_tmp/baseline.log" run_converge "$baseline_log" "$binary_path" config validate --config "$config_path" +"$workspace_venv/bin/python" -c ' +import sys +import yaml +with open(sys.argv[1], encoding="utf-8") as config_file: + config = yaml.safe_load(config_file) +assert "configkit" not in config +assert "transient_retries" not in config +' "$config_path" "$binary_path" inspect profile --config "$config_path" \ --profile-dir "$profile_dir" --profile endpoint-profile baseline_repeat_log="$test_tmp/baseline-repeat.log" @@ -98,3 +108,37 @@ run_converge "$representative_log" "${representative_args[@]}" representative_repeat_log="$test_tmp/representative-repeat.log" run_converge "$representative_repeat_log" "${representative_args[@]}" require_clean_recap "$representative_repeat_log" + +mkdir -p "$import_root/fragments" +printf '%s\n' \ + 'server:' \ + ' addr: 127.0.0.1:18081' > "$import_root/fragments/server.yml" +import_args=( + -e "scriptorium_config_path=$import_config_path" + -e "scriptorium_config_owner=$(id -un)" + -e "scriptorium_config_group=$(id -gn)" + -e '{"scriptorium_configkit_imports": [{"path": "fragments/server.yml"}], "scriptorium_transient_retries": 0}' +) +import_log="$test_tmp/import.log" +run_converge "$import_log" "${import_args[@]}" +"$binary_path" config validate --config "$import_config_path" +"$workspace_venv/bin/python" -c ' +import sys +import yaml +with open(sys.argv[1], encoding="utf-8") as config_file: + config = yaml.safe_load(config_file) +assert config["configkit"]["imports"] == [{"path": "fragments/server.yml"}] +assert config["transient_retries"] == 0 +assert "server" not in config +' "$import_config_path" +"$binary_path" config show --config "$import_config_path" | \ + "$workspace_venv/bin/python" -c ' +import sys +import yaml +config = yaml.safe_load(sys.stdin) +assert config["server"]["addr"] == "127.0.0.1:18081" +assert config["transient_retries"] == 0 +' +import_repeat_log="$test_tmp/import-repeat.log" +run_converge "$import_repeat_log" "${import_args[@]}" +require_clean_recap "$import_repeat_log"