diff --git a/README.md b/README.md index b784bfb..399be86 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,71 @@ -# ansible-role-dnd-pipeline +# rakestraw.dnd_pipeline -An Ansible role to install the full D&D production pipeline (Narratio, Seriatim, Audita, Notarius, and Scriptorium, plus supporting assets). \ No newline at end of file +Installs the D&D transcript-processing application suite by composing the +standalone Seriatim, Audita, Notarius, Scriptorium, and Narratio roles. It +supports Ubuntu 26.04 and Ansible Core 2.18 or newer. Downstream roles perform +their own task-level privilege escalation, so a play does not need `become`. + +## Installation + +Install the role dependencies and their collection before applying this role: + +```sh +ansible-galaxy role install -r requirements.yml +ansible-galaxy collection install -r collections/requirements.yml +``` + +The dependency manifest installs the roles under their canonical names: +`rakestraw.seriatim`, `rakestraw.audita`, `rakestraw.notarius`, +`rakestraw.scriptorium`, and `rakestraw.narratio`. This standalone role is +named `rakestraw.dnd_pipeline`; a later collection release will expose it as +`rakestraw.dnd.pipeline`. + +```yaml +--- +- name: Install the D&D pipeline foundation + hosts: pipeline_hosts + gather_facts: true + roles: + - role: rakestraw.dnd_pipeline + vars: + dnd_pipeline_whisperx_transcribe_url: https://whisperx.example/transcribe +``` + +## Variables + +`dnd_pipeline_whisperx_transcribe_url` is required and is passed to Narratio. +The compatible application versions are selected through these variables: + +| Variable | Default | +| --- | --- | +| `dnd_pipeline_audita_version` | `v0.9.1` | +| `dnd_pipeline_narratio_version` | `v2.0.0` | +| `dnd_pipeline_notarius_version` | `v0.6.0` | +| `dnd_pipeline_seriatim_version` | `v1.5.0` | +| `dnd_pipeline_scriptorium_version` | `v0.13.0` | +| `dnd_pipeline_manage_build_dependencies` | `true` | +| `dnd_pipeline_go_snap_channel` | `1.26/stable` | +| `dnd_pipeline_go_binary` | `/snap/bin/go` | + +The common dependency-management switch controls whether every application +role installs Git and Go. The Go channel and executable are likewise passed to +all five roles. Advanced callers may supply unmapped standalone-role variables +directly through normal Ansible variable precedence. + +Narratio receives the standard Seriatim, Audita, Notarius, and Scriptorium +binary and configuration paths managed by the composed roles. Notarius is +installed but remains disabled in Narratio until a later feature supplies a +Notarius pipeline. Campaign content, prompt content, operator policy, and +secret delivery are intentionally deferred. + +## Validation + +`tests/integration` installs the pinned Git dependencies and collection into +private temporary paths, runs syntax and production-profile lint checks, then +applies the baseline suite with a local syntactically valid WhisperX URL. It +uses native application smoke/configuration commands, validates Narratio's +assembled configuration as the Narratio account, and requires an immediate +clean repeat. Cleanup reapplies the baseline suite and removes only the +driver's private temporary directory. + +An Ansible role to install the full D&D production pipeline (Narratio, Seriatim, Audita, Notarius, and Scriptorium, plus supporting assets). diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..2d4c5f9 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +roles_path = .. diff --git a/collections/requirements.yml b/collections/requirements.yml new file mode 100644 index 0000000..22c02b2 --- /dev/null +++ b/collections/requirements.yml @@ -0,0 +1,4 @@ +--- +collections: + - name: community.general + version: 13.3.0 diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..ca45536 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,9 @@ +--- +dnd_pipeline_audita_version: v0.9.1 +dnd_pipeline_narratio_version: v2.0.0 +dnd_pipeline_notarius_version: v0.6.0 +dnd_pipeline_seriatim_version: v1.5.0 +dnd_pipeline_scriptorium_version: v0.13.0 +dnd_pipeline_manage_build_dependencies: true +dnd_pipeline_go_snap_channel: 1.26/stable +dnd_pipeline_go_binary: /snap/bin/go diff --git a/meta/argument_specs.yml b/meta/argument_specs.yml new file mode 100644 index 0000000..f5cba9a --- /dev/null +++ b/meta/argument_specs.yml @@ -0,0 +1,41 @@ +--- +argument_specs: + main: + short_description: Compose the D&D transcript-processing application suite + options: + dnd_pipeline_audita_version: + type: str + required: true + description: Audita application revision for the compatible suite. + dnd_pipeline_narratio_version: + type: str + required: true + description: Narratio application revision for the compatible suite. + dnd_pipeline_notarius_version: + type: str + required: true + description: Notarius application revision for the compatible suite. + dnd_pipeline_seriatim_version: + type: str + required: true + description: Seriatim application revision for the compatible suite. + dnd_pipeline_scriptorium_version: + type: str + required: true + description: Scriptorium application revision for the compatible suite. + dnd_pipeline_manage_build_dependencies: + type: bool + required: true + description: Whether every application role manages Git and Go. + dnd_pipeline_go_snap_channel: + type: str + required: true + description: Go Snap channel passed to every application role. + dnd_pipeline_go_binary: + type: path + required: true + description: Go executable passed to every application role. + dnd_pipeline_whisperx_transcribe_url: + type: str + required: true + description: WhisperX transcription endpoint passed to Narratio. diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..062b42e --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,57 @@ +--- +galaxy_info: + role_name: dnd_pipeline + namespace: rakestraw + author: Eric Rakestraw + description: Compose the D&D transcript-processing application suite + license: CC0-1.0 + min_ansible_version: "2.18" + issue_tracker_url: https://gitea.maximumdirect.net/eric/ansible-role-dnd-pipeline/issues + platforms: + - name: Ubuntu + versions: + - resolute + galaxy_tags: + - dnd + - pipeline + - transcript + - processing +dependencies: + - role: rakestraw.seriatim + vars: + seriatim_version: "{{ dnd_pipeline_seriatim_version }}" + seriatim_manage_build_dependencies: "{{ dnd_pipeline_manage_build_dependencies }}" + seriatim_go_snap_channel: "{{ dnd_pipeline_go_snap_channel }}" + seriatim_go_binary: "{{ dnd_pipeline_go_binary }}" + - role: rakestraw.audita + vars: + audita_version: "{{ dnd_pipeline_audita_version }}" + audita_manage_build_dependencies: "{{ dnd_pipeline_manage_build_dependencies }}" + audita_go_snap_channel: "{{ dnd_pipeline_go_snap_channel }}" + audita_go_binary: "{{ dnd_pipeline_go_binary }}" + - role: rakestraw.notarius + vars: + notarius_version: "{{ dnd_pipeline_notarius_version }}" + notarius_manage_build_dependencies: "{{ dnd_pipeline_manage_build_dependencies }}" + notarius_go_snap_channel: "{{ dnd_pipeline_go_snap_channel }}" + notarius_go_binary: "{{ dnd_pipeline_go_binary }}" + - role: rakestraw.scriptorium + vars: + scriptorium_version: "{{ dnd_pipeline_scriptorium_version }}" + scriptorium_manage_build_dependencies: "{{ dnd_pipeline_manage_build_dependencies }}" + scriptorium_go_snap_channel: "{{ dnd_pipeline_go_snap_channel }}" + scriptorium_go_binary: "{{ dnd_pipeline_go_binary }}" + - role: rakestraw.narratio + vars: + narratio_version: "{{ dnd_pipeline_narratio_version }}" + narratio_manage_build_dependencies: "{{ dnd_pipeline_manage_build_dependencies }}" + narratio_go_snap_channel: "{{ dnd_pipeline_go_snap_channel }}" + narratio_go_binary: "{{ dnd_pipeline_go_binary }}" + narratio_whisperx_transcribe_url: "{{ dnd_pipeline_whisperx_transcribe_url }}" + narratio_seriatim_binary: /usr/local/bin/seriatim + narratio_audita_binary: /usr/local/bin/audita + narratio_audita_config_path: /usr/local/etc/audita/config.yml + narratio_notarius_binary: /usr/local/bin/notarius + narratio_notarius_config_path: /usr/local/etc/notarius/config.yml + narratio_scriptorium_binary: /usr/local/bin/scriptorium + narratio_scriptorium_config_path: /usr/local/etc/scriptorium/config.yml diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..2c85058 --- /dev/null +++ b/requirements.yml @@ -0,0 +1,22 @@ +--- +roles: + - name: rakestraw.seriatim + src: https://gitea.maximumdirect.net/eric/ansible-role-seriatim.git + scm: git + version: e08c63c0b078658bdfa2d10a2e6e1e4f9372a075 + - name: rakestraw.audita + src: https://gitea.maximumdirect.net/eric/ansible-role-audita.git + scm: git + version: d2d0b9d00b3b491ce7613ccfc8f686f3d1fa0896 + - name: rakestraw.notarius + src: https://gitea.maximumdirect.net/eric/ansible-role-notarius.git + scm: git + version: cfecf37261f2595d45113235c591ee102d6f181f + - name: rakestraw.scriptorium + src: https://gitea.maximumdirect.net/eric/ansible-role-scriptorium.git + scm: git + version: 8f47aa802a5e0c9dae9c0f43a1c70b3512b2c8b2 + - name: rakestraw.narratio + src: https://gitea.maximumdirect.net/eric/ansible-role-narratio.git + scm: git + version: 7feff4728a5968b6b1dd87e83add9fa1a9066b18 diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1 @@ +--- diff --git a/tests/converge.yml b/tests/converge.yml new file mode 100644 index 0000000..a3dffa8 --- /dev/null +++ b/tests/converge.yml @@ -0,0 +1,6 @@ +--- +- name: Converge the D&D pipeline role + hosts: localhost + gather_facts: true + roles: + - role: ansible-role-dnd-pipeline diff --git a/tests/integration b/tests/integration new file mode 100755 index 0000000..eb8bd6b --- /dev/null +++ b/tests/integration @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +set -euo pipefail + +repository_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +workspace_venv="$repository_root/../.venv" +test_tmp=$(mktemp -d) +chmod 0700 "$test_tmp" + +export ANSIBLE_COLLECTIONS_PATH="$test_tmp/collections" +export ANSIBLE_ROLES_PATH="$(dirname "$repository_root"):$test_tmp/roles" + +inventory="$repository_root/tests/inventory" +converge="$repository_root/tests/converge.yml" +ansible_playbook="$workspace_venv/bin/ansible-playbook" +baseline_args=(-e 'dnd_pipeline_whisperx_transcribe_url=http://127.0.0.1:8000/transcribe') +profile_dir="$test_tmp/profiles" + +cleanup() { + exit_status=$? + trap - EXIT + "$ansible_playbook" -i "$inventory" "${baseline_args[@]}" "$converge" >/dev/null 2>&1 || true + rm -rf -- "$test_tmp" + exit "$exit_status" +} +trap cleanup EXIT + +require_clean_recap() { + grep -Eq 'changed=0 .*failed=0' "$1" +} + +run_converge() { + output_file=$1 + shift + "$ansible_playbook" -i "$inventory" "$@" "$converge" | tee "$output_file" +} + +cd "$repository_root" +mkdir -p "$profile_dir" +printf '%s\n' \ + 'id: endpoint-profile' \ + 'endpoint: http://127.0.0.1:8000/v1' \ + 'model: offline-fixture' > "$profile_dir/endpoint-profile.yml" +"$workspace_venv/bin/ansible-galaxy" collection install \ + -r collections/requirements.yml \ + -p "$ANSIBLE_COLLECTIONS_PATH" +"$workspace_venv/bin/ansible-galaxy" role install \ + -r requirements.yml \ + -p "$test_tmp/roles" +"$ansible_playbook" -i "$inventory" --syntax-check "$converge" +"$workspace_venv/bin/ansible-lint" --offline --profile production "$converge" + +baseline_log="$test_tmp/baseline.log" +run_converge "$baseline_log" "${baseline_args[@]}" +/usr/local/bin/seriatim --version +/usr/local/bin/audita config validate --config /usr/local/etc/audita/config.yml +/usr/local/bin/notarius config validate --config /usr/local/etc/notarius/config.yml +/usr/local/bin/scriptorium inspect profile --config /usr/local/etc/scriptorium/config.yml \ + --profile-dir "$profile_dir" --profile endpoint-profile +/usr/bin/sudo -u narratio /usr/local/bin/narratio config validate \ + --config /usr/local/etc/narratio/pipeline.yml +baseline_repeat_log="$test_tmp/baseline-repeat.log" +run_converge "$baseline_repeat_log" "${baseline_args[@]}" +require_clean_recap "$baseline_repeat_log" diff --git a/tests/inventory b/tests/inventory new file mode 100644 index 0000000..2302eda --- /dev/null +++ b/tests/inventory @@ -0,0 +1 @@ +localhost ansible_connection=local