Simplify the Seriatim role

This commit is contained in:
2026-09-08 01:07:23 +00:00
parent 6fb1aa24cc
commit 325a5c7901
10 changed files with 200 additions and 916 deletions

View File

@@ -1,316 +0,0 @@
---
- name: Construct canonical Seriatim build inputs
ansible.builtin.set_fact:
seriatim_build_inputs: >-
{{ {
'source_commit': seriatim_source_commit,
'go_version': seriatim_go_version_result.stdout,
'go_binary': seriatim_go_binary,
'build_version': seriatim_build_version,
'build_flags': seriatim_go_build_flags,
'ldflags': seriatim_go_ldflags,
'package': seriatim_go_package,
'environment': {
'GOWORK': 'off',
'GOTOOLCHAIN': 'local',
'CGO_ENABLED': '0'
}
} | to_nice_json(indent=2, sort_keys=true) }}
- name: Calculate desired Seriatim build fingerprint
ansible.builtin.set_fact:
seriatim_desired_fingerprint: "{{ seriatim_build_inputs | hash('sha256') }}"
seriatim_stored_build_inputs: ""
seriatim_stored_fingerprint: ""
seriatim_stored_checksum: ""
- name: Inspect Seriatim binary parent directory
ansible.builtin.stat:
path: "{{ seriatim_binary_path | dirname }}"
register: seriatim_binary_parent_stat
- name: Require an existing Seriatim binary parent to be a directory
ansible.builtin.assert:
that:
- not seriatim_binary_parent_stat.stat.exists or seriatim_binary_parent_stat.stat.isdir
fail_msg: >-
Seriatim binary parent exists but is not a directory:
{{ seriatim_binary_path | dirname }}.
- name: Create missing Seriatim binary parent directory
ansible.builtin.file:
path: "{{ seriatim_binary_path | dirname }}"
state: directory
owner: root
group: root
mode: "0755"
when: not seriatim_binary_parent_stat.stat.exists
- name: Inspect installed Seriatim binary
ansible.builtin.stat:
path: "{{ seriatim_binary_path }}"
checksum_algorithm: sha256
register: seriatim_installed_binary_stat
- name: Require a regular installed Seriatim binary path
ansible.builtin.assert:
that:
- not seriatim_installed_binary_stat.stat.exists or seriatim_installed_binary_stat.stat.isreg
fail_msg: >-
Seriatim binary path exists but is not a regular file:
{{ seriatim_binary_path }}. Move the unexpected object before rerunning the role.
- name: Inspect Seriatim build state directory
ansible.builtin.stat:
path: "{{ seriatim_build_state_dir }}"
register: seriatim_build_state_dir_stat
- name: Remove malformed Seriatim build state directory object
ansible.builtin.file:
path: "{{ seriatim_build_state_dir }}"
state: absent
when:
- seriatim_build_state_dir_stat.stat.exists or
(seriatim_build_state_dir_stat.stat.islnk | default(false))
- not (seriatim_build_state_dir_stat.stat.isdir | default(false))
- name: Create missing Seriatim build state directory
ansible.builtin.file:
path: "{{ seriatim_build_state_dir }}"
state: directory
owner: root
group: root
mode: "0755"
when: not (seriatim_build_state_dir_stat.stat.isdir | default(false))
- name: Inspect Seriatim build input state
ansible.builtin.stat:
path: "{{ seriatim_build_state_dir }}/build-inputs.json"
register: seriatim_build_inputs_state_stat
- name: Inspect Seriatim fingerprint state
ansible.builtin.stat:
path: "{{ seriatim_build_state_dir }}/fingerprint.sha256"
register: seriatim_fingerprint_state_stat
- name: Inspect Seriatim checksum state
ansible.builtin.stat:
path: "{{ seriatim_build_state_dir }}/binary.sha256"
register: seriatim_checksum_state_stat
- name: Remove malformed Seriatim build state objects
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop:
- path: "{{ seriatim_build_state_dir }}/build-inputs.json"
exists: "{{ seriatim_build_inputs_state_stat.stat.exists }}"
is_regular: "{{ seriatim_build_inputs_state_stat.stat.isreg | default(false) }}"
- path: "{{ seriatim_build_state_dir }}/fingerprint.sha256"
exists: "{{ seriatim_fingerprint_state_stat.stat.exists }}"
is_regular: "{{ seriatim_fingerprint_state_stat.stat.isreg | default(false) }}"
- path: "{{ seriatim_build_state_dir }}/binary.sha256"
exists: "{{ seriatim_checksum_state_stat.stat.exists }}"
is_regular: "{{ seriatim_checksum_state_stat.stat.isreg | default(false) }}"
when:
- item.exists | bool
- not item.is_regular | bool
- name: Read stored Seriatim fingerprint
ansible.builtin.slurp:
src: "{{ seriatim_build_state_dir }}/fingerprint.sha256"
register: seriatim_stored_fingerprint_result
failed_when: false
when:
- seriatim_fingerprint_state_stat.stat.isreg | default(false)
- seriatim_fingerprint_state_stat.stat.readable | default(false)
- name: Read stored Seriatim build inputs
ansible.builtin.slurp:
src: "{{ seriatim_build_state_dir }}/build-inputs.json"
register: seriatim_stored_build_inputs_result
failed_when: false
when:
- seriatim_build_inputs_state_stat.stat.isreg | default(false)
- seriatim_build_inputs_state_stat.stat.readable | default(false)
- name: Read stored Seriatim checksum
ansible.builtin.slurp:
src: "{{ seriatim_build_state_dir }}/binary.sha256"
register: seriatim_stored_checksum_result
failed_when: false
when:
- seriatim_checksum_state_stat.stat.isreg | default(false)
- seriatim_checksum_state_stat.stat.readable | default(false)
- name: Record stored Seriatim state values
ansible.builtin.set_fact:
seriatim_stored_build_inputs: >-
{{ seriatim_stored_build_inputs_result.content | b64decode | trim }}
seriatim_stored_fingerprint: >-
{{ seriatim_stored_fingerprint_result.content | b64decode | trim }}
seriatim_stored_checksum: >-
{{ seriatim_stored_checksum_result.content | b64decode | trim }}
when:
- seriatim_build_inputs_state_stat.stat.isreg | default(false)
- seriatim_build_inputs_state_stat.stat.readable | default(false)
- seriatim_fingerprint_state_stat.stat.isreg | default(false)
- seriatim_fingerprint_state_stat.stat.readable | default(false)
- seriatim_checksum_state_stat.stat.isreg | default(false)
- seriatim_checksum_state_stat.stat.readable | default(false)
- not (seriatim_stored_build_inputs_result.failed | default(true))
- not (seriatim_stored_fingerprint_result.failed | default(true))
- not (seriatim_stored_checksum_result.failed | default(true))
- name: Read installed Seriatim version
ansible.builtin.command:
argv:
- "{{ seriatim_binary_path }}"
- --version
register: seriatim_installed_version_result
changed_when: false
failed_when: false
when: seriatim_installed_binary_stat.stat.exists
- name: Decide whether Seriatim requires rebuilding
ansible.builtin.set_fact:
seriatim_build_required: >-
{{ not seriatim_installed_binary_stat.stat.exists
or not seriatim_build_inputs_state_stat.stat.exists
or not seriatim_fingerprint_state_stat.stat.exists
or not seriatim_checksum_state_stat.stat.exists
or seriatim_stored_build_inputs != seriatim_build_inputs
or (seriatim_stored_build_inputs | hash('sha256')) != seriatim_stored_fingerprint
or (seriatim_stored_build_inputs | hash('sha256')) != seriatim_desired_fingerprint
or seriatim_stored_fingerprint != seriatim_desired_fingerprint
or seriatim_stored_checksum != (seriatim_installed_binary_stat.stat.checksum | default(''))
or (seriatim_installed_version_result.rc | default(1)) != 0
or (seriatim_installed_version_result.stdout | default('')) != 'seriatim version ' ~ seriatim_build_version }}
- name: Build, validate, and install Seriatim
when: seriatim_build_required
block:
- name: Create temporary Seriatim build directory
ansible.builtin.tempfile:
state: directory
prefix: ansible-seriatim-build-
register: seriatim_build_tempdir
- name: Build staged Seriatim binary
ansible.builtin.command:
argv: >-
{{ [seriatim_go_binary, 'build']
+ seriatim_go_build_flags
+ ['-ldflags', seriatim_go_ldflags,
'-o', seriatim_build_tempdir.path ~ '/seriatim',
seriatim_go_package] }}
chdir: "{{ seriatim_source_dir }}"
environment:
GOWORK: "off"
GOTOOLCHAIN: local
CGO_ENABLED: "0"
changed_when: true
- name: Validate staged Seriatim binary
ansible.builtin.command:
argv:
- "{{ seriatim_build_tempdir.path }}/seriatim"
- --version
register: seriatim_staged_version_result
changed_when: false
failed_when: >-
seriatim_staged_version_result.rc != 0 or
seriatim_staged_version_result.stdout != 'seriatim version ' ~ seriatim_build_version
- name: Install validated Seriatim binary
ansible.builtin.copy:
src: "{{ seriatim_build_tempdir.path }}/seriatim"
dest: "{{ seriatim_binary_path }}"
remote_src: true
owner: root
group: root
mode: "0755"
- name: Validate installed Seriatim binary
ansible.builtin.command:
argv:
- "{{ seriatim_binary_path }}"
- --version
register: seriatim_new_installed_version_result
changed_when: false
failed_when: >-
seriatim_new_installed_version_result.rc != 0 or
seriatim_new_installed_version_result.stdout != 'seriatim version ' ~ seriatim_build_version
- name: Calculate installed Seriatim checksum
ansible.builtin.stat:
path: "{{ seriatim_binary_path }}"
checksum_algorithm: sha256
register: seriatim_new_binary_stat
- name: Create Seriatim build state directory
ansible.builtin.file:
path: "{{ seriatim_build_state_dir }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Record Seriatim build inputs
ansible.builtin.copy:
content: "{{ seriatim_build_inputs }}\n"
dest: "{{ seriatim_build_state_dir }}/build-inputs.json"
owner: root
group: root
mode: "0644"
- name: Record Seriatim build fingerprint
ansible.builtin.copy:
content: "{{ seriatim_desired_fingerprint }}\n"
dest: "{{ seriatim_build_state_dir }}/fingerprint.sha256"
owner: root
group: root
mode: "0644"
- name: Record installed Seriatim checksum
ansible.builtin.copy:
content: "{{ seriatim_new_binary_stat.stat.checksum }}\n"
dest: "{{ seriatim_build_state_dir }}/binary.sha256"
owner: root
group: root
mode: "0644"
always:
- name: Remove temporary Seriatim build directory
ansible.builtin.file:
path: "{{ seriatim_build_tempdir.path }}"
state: absent
when: seriatim_build_tempdir.path is defined
- name: Converge installed Seriatim binary metadata
ansible.builtin.file:
path: "{{ seriatim_binary_path }}"
state: file
owner: root
group: root
mode: "0755"
- name: Converge Seriatim build state directory metadata
ansible.builtin.file:
path: "{{ seriatim_build_state_dir }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Converge Seriatim build state file metadata
ansible.builtin.file:
path: "{{ seriatim_build_state_dir }}/{{ item }}"
state: file
owner: root
group: root
mode: "0644"
loop:
- build-inputs.json
- fingerprint.sha256
- binary.sha256

View File

@@ -1,66 +0,0 @@
---
- name: Install Git build dependency
ansible.builtin.apt:
name: git
state: present
update_cache: true
cache_valid_time: 3600
when: seriatim_manage_build_dependencies
- name: Install Go build dependency
community.general.snap:
name: go
state: present
classic: true
channel: "{{ seriatim_go_snap_channel }}"
when: seriatim_manage_build_dependencies
- name: Resolve Git executable
ansible.builtin.command:
argv:
- /usr/bin/which
- git
register: seriatim_git_path_result
changed_when: false
failed_when: seriatim_git_path_result.rc != 0
- name: Verify configured Go executable exists
ansible.builtin.stat:
path: "{{ seriatim_go_binary }}"
follow: true
register: seriatim_go_binary_stat
- name: Require configured Go executable
ansible.builtin.assert:
that:
- seriatim_go_binary_stat.stat.exists
- seriatim_go_binary_stat.stat.isreg
- seriatim_go_binary_stat.stat.executable
fail_msg: "Configured Go executable is unavailable: {{ seriatim_go_binary }}"
- name: Read Go compiler version
ansible.builtin.command:
argv:
- "{{ seriatim_go_binary }}"
- version
register: seriatim_go_version_result
changed_when: false
- name: Extract Go compiler version components
ansible.builtin.set_fact:
seriatim_go_version_parts: >-
{{ seriatim_go_version_result.stdout
| regex_findall('go([0-9]+)\.([0-9]+)')
| first
| default([]) }}
- name: Require supported Go compiler version
ansible.builtin.assert:
that:
- seriatim_go_version_result.stdout is regex('^go version go[0-9]+\.[0-9]+(?:\.[0-9]+)? ')
- seriatim_go_version_parts | length == 2
- (seriatim_go_version_parts[0] | int > 1) or
(seriatim_go_version_parts[0] | int == 1 and seriatim_go_version_parts[1] | int >= 25)
fail_msg: >-
Seriatim requires Go 1.25 or newer; detected
{{ seriatim_go_version_result.stdout | default('no usable version output') }}.

View File

@@ -1,12 +1,109 @@
---
- name: Validate Seriatim role inputs
ansible.builtin.import_tasks: validate.yml
- 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: Seriatim supports Ubuntu 26.04 on x86_64 or aarch64.
- name: Manage Seriatim build dependencies
ansible.builtin.import_tasks: dependencies.yml
- name: Install Git
ansible.builtin.apt:
name: git
state: present
update_cache: true
when: seriatim_manage_build_dependencies
- name: Manage Seriatim source checkout
ansible.builtin.import_tasks: source.yml
- name: Install Go
community.general.snap:
name: go
channel: "{{ seriatim_go_snap_channel }}"
classic: true
state: present
when: seriatim_manage_build_dependencies
- name: Build and install Seriatim
ansible.builtin.import_tasks: build.yml
- name: Create installation parent directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
loop:
- "{{ seriatim_source_dir | dirname }}"
- "{{ seriatim_binary_path | dirname }}"
- name: Check out Seriatim source
ansible.builtin.git:
repo: "{{ seriatim_repository_url }}"
dest: "{{ seriatim_source_dir }}"
version: "{{ seriatim_version }}"
force: true
register: seriatim_checkout
- name: Inspect the installed binary
ansible.builtin.stat:
path: "{{ seriatim_binary_path }}"
register: seriatim_binary
- name: Read the installed Seriatim version
ansible.builtin.command:
argv:
- "{{ seriatim_binary_path }}"
- --version
register: seriatim_installed_version
changed_when: false
failed_when: false
when: seriatim_binary.stat.exists
- name: Build Seriatim
ansible.builtin.command:
argv:
- /snap/bin/go
- build
- -trimpath
- -ldflags
- "-s -w -X gitea.maximumdirect.net/eric/seriatim/internal/buildinfo.Version={{ seriatim_version }}"
- -o
- "{{ seriatim_binary_path }}"
- ./cmd/seriatim
chdir: "{{ seriatim_source_dir }}"
environment:
CGO_ENABLED: "0"
GOTOOLCHAIN: local
GOWORK: "off"
register: seriatim_build
changed_when: true
when: >-
seriatim_checkout.changed or
not seriatim_binary.stat.exists or
seriatim_installed_version.rc | default(1) != 0 or
seriatim_installed_version.stdout | default('') != 'seriatim version ' ~ seriatim_version
- name: Converge installed metadata
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: "{{ seriatim_source_dir }}"
state: directory
recurse: true
- path: "{{ seriatim_binary_path }}"
state: file
mode: "0755"
- name: Validate the built Seriatim version # noqa no-handler
ansible.builtin.command:
argv:
- "{{ seriatim_binary_path }}"
- --version
register: seriatim_built_version
changed_when: false
failed_when: >-
seriatim_built_version.rc != 0 or
seriatim_built_version.stdout != 'seriatim version ' ~ seriatim_version
when: seriatim_build.changed

View File

@@ -1,76 +0,0 @@
---
- name: Create Seriatim source parent directory
ansible.builtin.file:
path: "{{ seriatim_source_dir | dirname }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Check out selected Seriatim source
ansible.builtin.git:
repo: "{{ seriatim_repository_url }}"
dest: "{{ seriatim_source_dir }}"
version: "{{ seriatim_source_ref }}"
update: true
force: true
accept_hostkey: false
- name: Inspect Seriatim checkout cleanliness
ansible.builtin.command:
argv:
- "{{ seriatim_git_path_result.stdout }}"
- -C
- "{{ seriatim_source_dir }}"
- status
- --porcelain
- --untracked-files=all
- --ignored
register: seriatim_source_status
changed_when: false
- name: Reset tracked Seriatim source changes
ansible.builtin.command:
argv:
- "{{ seriatim_git_path_result.stdout }}"
- -C
- "{{ seriatim_source_dir }}"
- reset
- --hard
- HEAD
when: seriatim_source_status.stdout | length > 0
changed_when: true
- name: Remove untracked and ignored Seriatim source content
ansible.builtin.command:
argv:
- "{{ seriatim_git_path_result.stdout }}"
- -C
- "{{ seriatim_source_dir }}"
- clean
- -dffx
when: seriatim_source_status.stdout | length > 0
changed_when: true
- name: Enforce Seriatim source ownership
ansible.builtin.file:
path: "{{ seriatim_source_dir }}"
state: directory
owner: root
group: root
recurse: true
- name: Resolve selected Seriatim source commit
ansible.builtin.command:
argv:
- "{{ seriatim_git_path_result.stdout }}"
- -C
- "{{ seriatim_source_dir }}"
- rev-parse
- HEAD
register: seriatim_source_commit_result
changed_when: false
- name: Record selected Seriatim source commit
ansible.builtin.set_fact:
seriatim_source_commit: "{{ seriatim_source_commit_result.stdout }}"

View File

@@ -1,38 +0,0 @@
---
- name: Verify the managed host is supported
ansible.builtin.assert:
that:
- ansible_facts.distribution == 'Ubuntu'
- ansible_facts.distribution_version is version('26.04', '==')
- ansible_facts.architecture in ['x86_64', 'aarch64']
fail_msg: >-
Seriatim supports Ubuntu 26.04 on x86_64 and aarch64; detected
{{ ansible_facts.distribution }} {{ ansible_facts.distribution_version }}
on {{ ansible_facts.architecture }}.
- name: Verify required Seriatim values are nonempty
ansible.builtin.assert:
that:
- seriatim_version | length > 0
- seriatim_repository_url | length > 0
- seriatim_source_ref | length > 0
- seriatim_build_version | length > 0
- seriatim_go_snap_channel | length > 0
- seriatim_go_binary | length > 0
- seriatim_go_build_flags | length > 0
- seriatim_go_build_flags | select('equalto', '') | list | length == 0
- seriatim_go_ldflags | length > 0
- seriatim_go_package | length > 0
- seriatim_build_version is not regex('.*\s+.*')
fail_msg: Seriatim repository, revision, build, and Go values must be nonempty, and the build version cannot contain whitespace.
- name: Verify managed Seriatim paths are safe and distinct
ansible.builtin.assert:
that:
- seriatim_source_dir is match('^/')
- seriatim_binary_path is match('^/')
- seriatim_build_state_dir is match('^/')
- seriatim_source_dir != seriatim_binary_path
- seriatim_source_dir != seriatim_build_state_dir
- seriatim_binary_path != seriatim_build_state_dir
fail_msg: Seriatim source, binary, and state paths must be absolute and pairwise distinct.