Install and configure Scriptorium
This commit is contained in:
77
README.md
77
README.md
@@ -1,3 +1,78 @@
|
||||
# ansible-role-scriptorium
|
||||
# Ansible Role: Scriptorium
|
||||
|
||||
Installs and configures [Scriptorium](https://gitea.maximumdirect.net/eric/scriptorium)
|
||||
from source on Ubuntu 26.04 (`x86_64` or `aarch64`). The role requires gathered
|
||||
facts and uses privilege escalation only for dependency installation and
|
||||
root-owned application state.
|
||||
|
||||
## Variables
|
||||
|
||||
```yaml
|
||||
scriptorium_version: v0.13.0
|
||||
scriptorium_repository_url: https://gitea.maximumdirect.net/eric/scriptorium.git
|
||||
scriptorium_source_dir: /usr/local/src/scriptorium
|
||||
scriptorium_binary_path: /usr/local/bin/scriptorium
|
||||
scriptorium_manage_build_dependencies: true
|
||||
scriptorium_go_snap_channel: 1.26/stable
|
||||
scriptorium_go_binary: /snap/bin/go
|
||||
scriptorium_config_path: /usr/local/etc/scriptorium/config.yml
|
||||
scriptorium_prompt_dir: null
|
||||
scriptorium_profile_dir: null
|
||||
scriptorium_schema_dir: null
|
||||
scriptorium_server_addr: null
|
||||
scriptorium_server_artifact_root: null
|
||||
scriptorium_server_max_request_bytes: null
|
||||
scriptorium_server_max_artifact_bytes: null
|
||||
scriptorium_server_max_response_bytes: null
|
||||
scriptorium_defaults_render_format: null
|
||||
scriptorium_backends: null
|
||||
```
|
||||
|
||||
When `scriptorium_manage_build_dependencies` is `false`, Git and the executable
|
||||
selected by `scriptorium_go_binary` must already be available. Otherwise, the
|
||||
role installs Git with APT and the classic Go Snap from
|
||||
`scriptorium_go_snap_channel`. It checks out `scriptorium_version`
|
||||
authoritatively, builds `./cmd/scriptorium` directly to
|
||||
`scriptorium_binary_path`, and rebuilds only when that checkout changes or the
|
||||
binary is absent. The source tree is recursively owned by `root:root`; the
|
||||
binary is `root:root` mode `0755`.
|
||||
|
||||
Every application configuration variable defaults to `null`, so it and any
|
||||
empty parent section are omitted and Scriptorium retains ownership of its
|
||||
built-in defaults. When no values are selected, the role writes `{}` to
|
||||
`scriptorium_config_path` as `root:root` mode `0644`. Non-null falsey values
|
||||
are retained. `scriptorium_backends` is the native mapping supplied by the
|
||||
caller; the role does not merge or rewrite it. For example, inventory can
|
||||
compose fragments in the ordinary way:
|
||||
|
||||
```yaml
|
||||
scriptorium_backends: "{{ scriptorium_local_backends | combine(scriptorium_remote_backends) }}"
|
||||
```
|
||||
|
||||
Backend entries may name a credential environment variable through
|
||||
`api_key_env`; credential values themselves belong outside this role. The role
|
||||
does not install prompt, profile, or schema content and does not manage a
|
||||
service.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
- hosts: scriptorium_hosts
|
||||
roles:
|
||||
- role: ansible-role-scriptorium
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
The repository-local integration suite installs its pinned collection, runs
|
||||
syntax checking and production-profile lint, and applies the default role. It
|
||||
uses an offline native profile inspection with the managed configuration, then
|
||||
requires clean repeated convergence. It mutates only the managed source,
|
||||
binary, configuration, and a private temporary directory, then restores the
|
||||
default deployment during cleanup.
|
||||
|
||||
```sh
|
||||
tests/integration
|
||||
```
|
||||
|
||||
Ansible role to install the Scriptorium application.
|
||||
2
ansible.cfg
Normal file
2
ansible.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[defaults]
|
||||
roles_path = ..
|
||||
4
collections/requirements.yml
Normal file
4
collections/requirements.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
collections:
|
||||
- name: community.general
|
||||
version: 13.3.0
|
||||
19
defaults/main.yml
Normal file
19
defaults/main.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
scriptorium_version: v0.13.0
|
||||
scriptorium_repository_url: https://gitea.maximumdirect.net/eric/scriptorium.git
|
||||
scriptorium_source_dir: /usr/local/src/scriptorium
|
||||
scriptorium_binary_path: /usr/local/bin/scriptorium
|
||||
scriptorium_manage_build_dependencies: true
|
||||
scriptorium_go_snap_channel: 1.26/stable
|
||||
scriptorium_go_binary: /snap/bin/go
|
||||
scriptorium_config_path: /usr/local/etc/scriptorium/config.yml
|
||||
scriptorium_prompt_dir: null
|
||||
scriptorium_profile_dir: null
|
||||
scriptorium_schema_dir: null
|
||||
scriptorium_server_addr: null
|
||||
scriptorium_server_artifact_root: null
|
||||
scriptorium_server_max_request_bytes: null
|
||||
scriptorium_server_max_artifact_bytes: null
|
||||
scriptorium_server_max_response_bytes: null
|
||||
scriptorium_defaults_render_format: null
|
||||
scriptorium_backends: null
|
||||
59
meta/argument_specs.yml
Normal file
59
meta/argument_specs.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
argument_specs:
|
||||
main:
|
||||
short_description: Install and configure Scriptorium from source
|
||||
options:
|
||||
scriptorium_version:
|
||||
type: str
|
||||
required: true
|
||||
scriptorium_repository_url:
|
||||
type: str
|
||||
required: true
|
||||
scriptorium_source_dir:
|
||||
type: path
|
||||
required: true
|
||||
scriptorium_binary_path:
|
||||
type: path
|
||||
required: true
|
||||
scriptorium_manage_build_dependencies:
|
||||
type: bool
|
||||
required: true
|
||||
scriptorium_go_snap_channel:
|
||||
type: str
|
||||
required: true
|
||||
scriptorium_go_binary:
|
||||
type: path
|
||||
required: true
|
||||
scriptorium_config_path:
|
||||
type: path
|
||||
required: true
|
||||
scriptorium_prompt_dir:
|
||||
type: path
|
||||
required: false
|
||||
scriptorium_profile_dir:
|
||||
type: path
|
||||
required: false
|
||||
scriptorium_schema_dir:
|
||||
type: path
|
||||
required: false
|
||||
scriptorium_server_addr:
|
||||
type: str
|
||||
required: false
|
||||
scriptorium_server_artifact_root:
|
||||
type: str
|
||||
required: false
|
||||
scriptorium_server_max_request_bytes:
|
||||
type: int
|
||||
required: false
|
||||
scriptorium_server_max_artifact_bytes:
|
||||
type: int
|
||||
required: false
|
||||
scriptorium_server_max_response_bytes:
|
||||
type: int
|
||||
required: false
|
||||
scriptorium_defaults_render_format:
|
||||
type: str
|
||||
required: false
|
||||
scriptorium_backends:
|
||||
type: dict
|
||||
required: false
|
||||
18
meta/main.yml
Normal file
18
meta/main.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: scriptorium
|
||||
namespace: rakestraw
|
||||
author: Eric Rakestraw
|
||||
description: Install and configure Scriptorium from source
|
||||
license: CC0-1.0
|
||||
min_ansible_version: "2.18"
|
||||
issue_tracker_url: https://gitea.maximumdirect.net/eric/ansible-role-scriptorium/issues
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- resolute
|
||||
galaxy_tags:
|
||||
- scriptorium
|
||||
- promptkit
|
||||
- processing
|
||||
dependencies: []
|
||||
101
tasks/main.yml
Normal file
101
tasks/main.yml
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
- name: Validate the supported platform
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.distribution == "Ubuntu"
|
||||
- ansible_facts.distribution_version == "26.04"
|
||||
- ansible_facts.architecture in ["x86_64", "aarch64"]
|
||||
fail_msg: Scriptorium supports Ubuntu 26.04 on x86_64 or aarch64.
|
||||
|
||||
- name: Install Git
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
name: git
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
when: scriptorium_manage_build_dependencies
|
||||
|
||||
- name: Install Go
|
||||
become: true
|
||||
community.general.snap:
|
||||
name: go
|
||||
channel: "{{ scriptorium_go_snap_channel }}"
|
||||
classic: true
|
||||
state: present
|
||||
when: scriptorium_manage_build_dependencies
|
||||
|
||||
- name: Create installation parent directories
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ scriptorium_source_dir | dirname }}"
|
||||
- "{{ scriptorium_binary_path | dirname }}"
|
||||
- "{{ scriptorium_config_path | dirname }}"
|
||||
|
||||
- name: Check out Scriptorium source
|
||||
become: true
|
||||
ansible.builtin.git:
|
||||
repo: "{{ scriptorium_repository_url }}"
|
||||
dest: "{{ scriptorium_source_dir }}"
|
||||
version: "{{ scriptorium_version }}"
|
||||
force: true
|
||||
register: scriptorium_checkout
|
||||
|
||||
- name: Inspect the installed binary
|
||||
ansible.builtin.stat:
|
||||
path: "{{ scriptorium_binary_path }}"
|
||||
register: scriptorium_binary
|
||||
|
||||
- name: Build Scriptorium
|
||||
become: true
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- "{{ scriptorium_go_binary }}"
|
||||
- build
|
||||
- -trimpath
|
||||
- -ldflags
|
||||
- -s -w
|
||||
- -o
|
||||
- "{{ scriptorium_binary_path }}"
|
||||
- ./cmd/scriptorium
|
||||
chdir: "{{ scriptorium_source_dir }}"
|
||||
environment:
|
||||
CGO_ENABLED: "0"
|
||||
GOWORK: "off"
|
||||
GOTOOLCHAIN: local
|
||||
changed_when: true
|
||||
when: >-
|
||||
scriptorium_checkout.changed or
|
||||
not scriptorium_binary.stat.exists
|
||||
|
||||
- name: Converge installed metadata
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path }}"
|
||||
state: "{{ item.state }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "{{ item.mode | default(omit) }}"
|
||||
recurse: "{{ item.recurse | default(omit) }}"
|
||||
loop:
|
||||
- path: "{{ scriptorium_source_dir }}"
|
||||
state: directory
|
||||
recurse: true
|
||||
- path: "{{ scriptorium_binary_path }}"
|
||||
state: file
|
||||
mode: "0755"
|
||||
|
||||
- name: Write Scriptorium configuration
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: config.yml.j2
|
||||
dest: "{{ scriptorium_config_path }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
38
templates/config.yml.j2
Normal file
38
templates/config.yml.j2
Normal file
@@ -0,0 +1,38 @@
|
||||
{% 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 %}
|
||||
{}
|
||||
{% else %}
|
||||
{% if scriptorium_prompt_dir is not none %}
|
||||
prompt_dir: {{ scriptorium_prompt_dir | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_profile_dir is not none %}
|
||||
profile_dir: {{ scriptorium_profile_dir | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_schema_dir is not none %}
|
||||
schema_dir: {{ scriptorium_schema_dir | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_server_addr is not none or scriptorium_server_artifact_root is not none or scriptorium_server_max_request_bytes is not none or scriptorium_server_max_artifact_bytes is not none or scriptorium_server_max_response_bytes is not none %}
|
||||
server:
|
||||
{% if scriptorium_server_addr is not none %}
|
||||
addr: {{ scriptorium_server_addr | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_server_artifact_root is not none %}
|
||||
artifact_root: {{ scriptorium_server_artifact_root | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_server_max_request_bytes is not none %}
|
||||
max_request_bytes: {{ scriptorium_server_max_request_bytes | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_server_max_artifact_bytes is not none %}
|
||||
max_artifact_bytes: {{ scriptorium_server_max_artifact_bytes | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_server_max_response_bytes is not none %}
|
||||
max_response_bytes: {{ scriptorium_server_max_response_bytes | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if scriptorium_defaults_render_format is not none %}
|
||||
defaults:
|
||||
render_format: {{ scriptorium_defaults_render_format | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_backends is not none %}
|
||||
backends: {{ scriptorium_backends | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
6
tests/converge.yml
Normal file
6
tests/converge.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Converge Scriptorium role
|
||||
hosts: localhost
|
||||
gather_facts: true
|
||||
roles:
|
||||
- role: ansible-role-scriptorium
|
||||
56
tests/integration
Executable file
56
tests/integration
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/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")"
|
||||
|
||||
inventory="$repository_root/tests/inventory"
|
||||
converge="$repository_root/tests/converge.yml"
|
||||
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"
|
||||
|
||||
cleanup() {
|
||||
exit_status=$?
|
||||
trap - EXIT
|
||||
"$ansible_playbook" -i "$inventory" "$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
|
||||
"$ansible_playbook" -i "$inventory" "$converge" | tee "$output_file"
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
cd "$repository_root"
|
||||
"$workspace_venv/bin/ansible-galaxy" collection install \
|
||||
-r collections/requirements.yml \
|
||||
-p "$ANSIBLE_COLLECTIONS_PATH"
|
||||
"$ansible_playbook" -i "$inventory" --syntax-check "$converge"
|
||||
"$workspace_venv/bin/ansible-lint" "$converge"
|
||||
|
||||
baseline_log="$test_tmp/baseline.log"
|
||||
run_converge "$baseline_log"
|
||||
"$binary_path" inspect profile --config "$config_path" \
|
||||
--profile-dir "$profile_dir" --profile endpoint-profile
|
||||
baseline_repeat_log="$test_tmp/baseline-repeat.log"
|
||||
run_converge "$baseline_repeat_log"
|
||||
require_clean_recap "$baseline_repeat_log"
|
||||
1
tests/inventory
Normal file
1
tests/inventory
Normal file
@@ -0,0 +1 @@
|
||||
localhost ansible_connection=local
|
||||
Reference in New Issue
Block a user