- workload_accounts: gn-media (GID 970), gn-download (983), gn-dashboard (984); gn-media als primäre Gruppe der Pipeline-Konten — AUTH_SYS ueber NFSv4 wirkte serverseitig nicht mit Supplementary-Gruppen (Betriebsbefund 30.10.2026); Sudoers des Deploy-Kontos auf (ALL:ALL) verbreitert (become_user) - video_encoding: NFS-Client, Mount-Unit und Pipeline-Layout auf dem Export (10.0.0.2:/media/datenhdd3/Encoding -> /var/lib/ghostnet-pipeline, ausserhalb der Homes); Layout-Anlage als Dienstkonten wegen root_squash; Verifikation der Verzeichnisrechte als gn-encoding (2777/2770/0750/2750, Gruppe 970) - pve_media_cron: Legacy-Crontab (chown root:root + chmod -R 0777 auf allen Medienplatten, alle 10 min) entfernt — haette jedes echte Berechtigungsmodell plattgewalzt; Backup unter /var/backups/ghostnet/pve/; verify-production prueft das Fehlen ab - verify-pipeline-handover.yml: Handover-Simulation über alle Identitaeten (CT-101-.dlc-Drop -> gn-download -> queue -> gn-encoding -> output/state -> gn-dashboard); einmal vollstaendig bestanden (30.10.2026) - Doku: GNENC-000/001/002, GNAI-017 (6.10/6.11), GNMON-001 auf Stand gebracht Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
586 lines
20 KiB
YAML
586 lines
20 KiB
YAML
---
|
|
- name: Verify the target host before changing encoding state
|
|
ansible.builtin.assert:
|
|
that:
|
|
- ansible_facts["hostname"] == video_encoding_expected_hostname
|
|
- ansible_facts["distribution"] == video_encoding_expected_distribution
|
|
- >-
|
|
ansible_facts["distribution_major_version"] ==
|
|
video_encoding_expected_distribution_major_version
|
|
- >-
|
|
ansible_facts["default_ipv4"]["address"] ==
|
|
video_encoding_expected_ipv4_address
|
|
fail_msg: >-
|
|
The connected host does not match the declared Ghostnet AI server. No
|
|
encoding changes may be applied.
|
|
success_msg: The expected Debian host ghostnet-ki is connected.
|
|
|
|
- name: Verify encoding account declarations
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_account.name == "gn-encoding"
|
|
- video_encoding_account.uid | int == 982
|
|
- video_encoding_account.gid | int == 982
|
|
- video_encoding_account.home is match("^/")
|
|
- video_encoding_account.config_directory is match("^/")
|
|
- video_encoding_subid_count | int > 0
|
|
fail_msg: The encoding account declaration is invalid.
|
|
|
|
- name: Read the encoding service account entry
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/getent
|
|
- passwd
|
|
- gn-encoding
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_account_entry
|
|
failed_when: false
|
|
|
|
- name: Verify the encoding service account identity
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_account_entry.rc == 0
|
|
- >-
|
|
video_encoding_account_entry.stdout.split(":")[2] | int ==
|
|
video_encoding_account.uid | int
|
|
- >-
|
|
video_encoding_account_entry.stdout.split(":")[3] | int ==
|
|
video_encoding_account.primary_gid | int
|
|
- >-
|
|
video_encoding_account_entry.stdout.split(":")[5] ==
|
|
video_encoding_account.home
|
|
- >-
|
|
video_encoding_account_entry.stdout.split(":")[6] ==
|
|
video_encoding_account.shell
|
|
fail_msg: >-
|
|
The gn-encoding account is missing or does not match the declared
|
|
identity. Apply the shared host baseline
|
|
(llm-server/host/ansible playbooks/host.yml) first.
|
|
success_msg: The gn-encoding service account matches the declared identity.
|
|
|
|
- name: Read the shadow entry of the encoding account
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/getent
|
|
- shadow
|
|
- gn-encoding
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_shadow_entry
|
|
failed_when: false
|
|
|
|
- name: Verify the encoding account password is locked
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_shadow_entry.rc == 0
|
|
- video_encoding_shadow_entry.stdout.split(":")[1] == "!"
|
|
fail_msg: The gn-encoding account password is not locked.
|
|
|
|
- name: Read the subordinate UID range of the encoding account
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/grep
|
|
- -E
|
|
- "^gn-encoding:"
|
|
- /etc/subuid
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_subuid_entry
|
|
failed_when: false
|
|
|
|
- name: Read the subordinate GID range of the encoding account
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/grep
|
|
- -E
|
|
- "^gn-encoding:"
|
|
- /etc/subgid
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_subgid_entry
|
|
failed_when: false
|
|
|
|
- name: Verify the subordinate ID ranges of the encoding account
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_subuid_entry.rc == 0
|
|
- video_encoding_subgid_entry.rc == 0
|
|
- >-
|
|
video_encoding_subuid_entry.stdout ==
|
|
"gn-encoding:" ~ video_encoding_account.subid_start ~ ":"
|
|
~ video_encoding_subid_count
|
|
- >-
|
|
video_encoding_subgid_entry.stdout ==
|
|
"gn-encoding:" ~ video_encoding_account.subid_start ~ ":"
|
|
~ video_encoding_subid_count
|
|
fail_msg: >-
|
|
The subordinate ID ranges of gn-encoding are missing or do not match the
|
|
declared range. Apply the shared host baseline first.
|
|
|
|
- name: Read the supplementary groups of the encoding account
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/id
|
|
- -nG
|
|
- gn-encoding
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_groups
|
|
|
|
- name: Enforce CPU-only device isolation for the encoding account
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'render' not in video_encoding_groups.stdout.split()"
|
|
- "'video' not in video_encoding_groups.stdout.split()"
|
|
fail_msg: >-
|
|
gn-encoding must not be a member of a GPU device group. Encoding is
|
|
CPU-only; remove the supplementary group before applying encoding state.
|
|
success_msg: gn-encoding has no GPU device group membership.
|
|
|
|
- name: Manage the root-owned encoding configuration directory
|
|
ansible.builtin.file:
|
|
path: "{{ video_encoding_account.config_directory }}"
|
|
state: directory
|
|
owner: root
|
|
group: "{{ video_encoding_account.gid }}"
|
|
mode: "0750"
|
|
|
|
- name: Remove the superseded local pipeline directories when empty
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
changed=0
|
|
for dir in {{ video_encoding_legacy_local_directories | map('quote') | join(' ') }}; do
|
|
if [ -d "$dir" ]; then
|
|
if [ -n "$(find "$dir" -mindepth 1 -print -quit)" ]; then
|
|
echo "Refusing to remove non-empty legacy directory: $dir"
|
|
exit 1
|
|
fi
|
|
rmdir "$dir"
|
|
changed=1
|
|
fi
|
|
done
|
|
[ "$changed" = 0 ] || echo CHANGED
|
|
args:
|
|
executable: /bin/bash
|
|
register: video_encoding_legacy_cleanup
|
|
changed_when: "'CHANGED' in video_encoding_legacy_cleanup.stdout"
|
|
|
|
- name: Install the NFS client
|
|
ansible.builtin.apt:
|
|
name: "{{ video_encoding_pipeline_nfs_client_package }}"
|
|
state: present
|
|
update_cache: true
|
|
cache_valid_time: 3600
|
|
install_recommends: false
|
|
|
|
- name: Probe whether the pipeline mount is already active
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/findmnt
|
|
- --mountpoint
|
|
- "{{ video_encoding_pipeline_mount }}"
|
|
check_mode: false
|
|
changed_when: false
|
|
failed_when: false
|
|
register: video_encoding_pipeline_mountpoint_probe
|
|
|
|
- name: Create the pipeline mountpoint outside the service homes
|
|
ansible.builtin.file:
|
|
path: "{{ video_encoding_pipeline_mount }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
when: video_encoding_pipeline_mountpoint_probe.rc != 0
|
|
|
|
- name: Manage the pipeline NFS mount unit
|
|
ansible.builtin.copy:
|
|
content: |
|
|
[Unit]
|
|
Description=Ghostnet encoding pipeline NFS export (GNENC-002)
|
|
Requires=network-online.target
|
|
After=network-online.target
|
|
|
|
[Mount]
|
|
What={{ video_encoding_nfs_server }}:{{ video_encoding_nfs_export }}
|
|
Where={{ video_encoding_pipeline_mount }}
|
|
Type=nfs4
|
|
Options={{ video_encoding_pipeline_mount_options }}
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
dest: "/etc/systemd/system/{{ video_encoding_pipeline_mount_unit }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
|
|
- name: Reload systemd for the pipeline mount unit
|
|
ansible.builtin.systemd_service:
|
|
daemon_reload: true
|
|
when: not ansible_check_mode
|
|
|
|
- name: Enable and mount the pipeline NFS export
|
|
ansible.builtin.systemd_service:
|
|
name: "{{ video_encoding_pipeline_mount_unit }}"
|
|
enabled: true
|
|
state: started
|
|
when: not ansible_check_mode
|
|
|
|
- name: Verify the pipeline mount is active
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/systemctl
|
|
- is-active
|
|
- "{{ video_encoding_pipeline_mount_unit }}"
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_pipeline_mount_status
|
|
failed_when: video_encoding_pipeline_mount_status.stdout != "active"
|
|
when: not ansible_check_mode
|
|
|
|
- name: Stat the mounted export root
|
|
ansible.builtin.stat:
|
|
path: "{{ video_encoding_pipeline_mount }}"
|
|
register: video_encoding_export_root
|
|
when: not ansible_check_mode
|
|
|
|
- name: Verify the mounted export root ownership and mode
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_export_root.stat.isdir
|
|
- video_encoding_export_root.stat.uid == video_encoding_export_root_uid | int
|
|
- video_encoding_export_root.stat.gid == video_encoding_export_root_gid | int
|
|
- >-
|
|
'%04o' % (video_encoding_export_root.stat.mode | int(0, 8)) ==
|
|
video_encoding_export_root_mode
|
|
fail_msg: >-
|
|
The mounted export root must be {{ video_encoding_export_root_uid }}:{{ video_encoding_export_root_gid }}
|
|
{{ video_encoding_export_root_mode }} (PVE host side, GNAI-017 section 4.1);
|
|
found {{ video_encoding_export_root.stat.uid }}:{{ video_encoding_export_root.stat.gid }}
|
|
{{ video_encoding_export_root.stat.mode }}.
|
|
success_msg: The pipeline export root is mounted with the declared identity.
|
|
when: not ansible_check_mode
|
|
|
|
- name: Collect the HandBrake preset files from the profiles directory
|
|
ansible.builtin.set_fact:
|
|
video_encoding_profile_files: >-
|
|
{{ lookup('ansible.builtin.fileglob', role_path ~ '/../../../profiles/*.json', wantlist=True)
|
|
| map('basename') | map('regex_replace', '\.json$', '') | list }}
|
|
|
|
- name: Require the declared profiles to match the versioned preset files
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_profile_names | sort == video_encoding_profile_files | sort
|
|
fail_msg: >-
|
|
The declared video_encoding_profile_names do not match the preset files
|
|
under llm-server/encoding/profiles/ (found:
|
|
{{ video_encoding_profile_files | join(', ') }}).
|
|
success_msg: The declared profiles match the versioned preset files.
|
|
|
|
- name: Create the gn-download pipeline directories on the export
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
changed=0
|
|
while read -r mode path; do
|
|
[ -n "${path:-}" ] || continue
|
|
if [ ! -d "$path" ]; then
|
|
install -d -m "$mode" "$path"
|
|
changed=1
|
|
elif [ "$(stat -c '%a' "$path")" != "$mode" ]; then
|
|
chmod "$mode" "$path"
|
|
changed=1
|
|
fi
|
|
done <<'EOF'
|
|
{% for d in [
|
|
(video_encoding_pipeline_mount ~ '/input', '2777'),
|
|
(video_encoding_pipeline_mount ~ '/jd', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/jd/dlc_done', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/jd/failed', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/queue', '2770') ] %}
|
|
{{ d[1] }} {{ d[0] }}
|
|
{% endfor %}
|
|
{% for p in video_encoding_profile_names %}
|
|
2777 {{ video_encoding_pipeline_mount }}/input/{{ p }}
|
|
2770 {{ video_encoding_pipeline_mount }}/queue/{{ p }}
|
|
{% endfor %}
|
|
EOF
|
|
[ "$changed" = 0 ] || echo CHANGED
|
|
args:
|
|
executable: /bin/bash
|
|
become: true
|
|
become_user: gn-download
|
|
environment:
|
|
HOME: /var/lib/ghostnet-download
|
|
register: video_encoding_download_layout
|
|
changed_when: "'CHANGED' in video_encoding_download_layout.stdout"
|
|
when: not ansible_check_mode
|
|
|
|
- name: Create the gn-encoding pipeline directories on the export
|
|
ansible.builtin.shell: |
|
|
set -euo pipefail
|
|
changed=0
|
|
while read -r mode path; do
|
|
[ -n "${path:-}" ] || continue
|
|
if [ ! -d "$path" ]; then
|
|
install -d -m "$mode" "$path"
|
|
changed=1
|
|
elif [ "$(stat -c '%a' "$path")" != "$mode" ]; then
|
|
chmod "$mode" "$path"
|
|
changed=1
|
|
fi
|
|
done <<'EOF'
|
|
{% for d in [
|
|
(video_encoding_pipeline_mount ~ '/work', '0750'),
|
|
(video_encoding_pipeline_mount ~ '/output', '2777'),
|
|
(video_encoding_pipeline_mount ~ '/output/_failed', '2777'),
|
|
(video_encoding_pipeline_mount ~ '/state', '2750'),
|
|
(video_encoding_pipeline_mount ~ '/state/jobs', '0750'),
|
|
(video_encoding_pipeline_mount ~ '/state/tmp', '0750') ] %}
|
|
{{ d[1] }} {{ d[0] }}
|
|
{% endfor %}
|
|
{% for p in video_encoding_profile_names %}
|
|
2777 {{ video_encoding_pipeline_mount }}/output/{{ p }}
|
|
{% endfor %}
|
|
EOF
|
|
[ "$changed" = 0 ] || echo CHANGED
|
|
args:
|
|
executable: /bin/bash
|
|
become: true
|
|
become_user: gn-encoding
|
|
environment:
|
|
HOME: "{{ video_encoding_account.home }}"
|
|
register: video_encoding_worker_layout
|
|
changed_when: "'CHANGED' in video_encoding_worker_layout.stdout"
|
|
when: not ansible_check_mode
|
|
|
|
- name: Verify the pipeline directory layout on the export
|
|
ansible.builtin.shell: |
|
|
set -uo pipefail
|
|
failed=0
|
|
while read -r uid gid mode path; do
|
|
[ -n "${path:-}" ] || continue
|
|
if [ ! -d "$path" ]; then
|
|
echo "MISSING $path"
|
|
failed=1
|
|
continue
|
|
fi
|
|
read -r auid agid amode <<<"$(stat -c '%u %g %a' "$path")"
|
|
if [ "$auid" != "$uid" ] || [ "$agid" != "$gid" ] || [ "$amode" != "$mode" ]; then
|
|
echo "WRONG $path (expected $uid:$gid $mode, found $auid:$agid $amode)"
|
|
failed=1
|
|
fi
|
|
done <<'EOF'
|
|
{% for d in [
|
|
(video_encoding_pipeline_mount ~ '/input', '983', '2777'),
|
|
(video_encoding_pipeline_mount ~ '/jd', '983', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/jd/dlc_done', '983', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/jd/failed', '983', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/queue', '983', '2770'),
|
|
(video_encoding_pipeline_mount ~ '/work', '982', '0750'),
|
|
(video_encoding_pipeline_mount ~ '/output', '982', '2777'),
|
|
(video_encoding_pipeline_mount ~ '/output/_failed', '982', '2777'),
|
|
(video_encoding_pipeline_mount ~ '/state', '982', '2750'),
|
|
(video_encoding_pipeline_mount ~ '/state/jobs', '982', '0750'),
|
|
(video_encoding_pipeline_mount ~ '/state/tmp', '982', '0750') ] %}
|
|
{{ d[1] }} {{ d[2] }} {{ d[0] }}
|
|
{% endfor %}
|
|
{% for p in video_encoding_profile_names %}
|
|
983 970 2777 {{ video_encoding_pipeline_mount }}/input/{{ p }}
|
|
983 970 2770 {{ video_encoding_pipeline_mount }}/queue/{{ p }}
|
|
982 970 2777 {{ video_encoding_pipeline_mount }}/output/{{ p }}
|
|
{% endfor %}
|
|
EOF
|
|
if [ "$failed" = 1 ]; then
|
|
echo "Pipeline layout verification failed"
|
|
exit 1
|
|
fi
|
|
echo LAYOUT_OK
|
|
args:
|
|
executable: /bin/bash
|
|
become_user: gn-encoding
|
|
environment:
|
|
HOME: "{{ video_encoding_account.home }}"
|
|
changed_when: false
|
|
register: video_encoding_layout_verify
|
|
when: not ansible_check_mode
|
|
|
|
- name: Manage the administrator-managed rootless Quadlet directory
|
|
ansible.builtin.file:
|
|
path: "{{ video_encoding_quadlet_user_directory }}/{{ video_encoding_account.uid }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Verify the persistent user manager is enabled
|
|
ansible.builtin.stat:
|
|
path: "/var/lib/systemd/linger/{{ video_encoding_account.name }}"
|
|
register: video_encoding_linger
|
|
|
|
- name: Assert the persistent user manager is enabled
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_linger.stat.exists
|
|
fail_msg: >-
|
|
Linger is not enabled for gn-encoding. Enable it through the shared host
|
|
baseline so the rootless user manager survives logout.
|
|
|
|
- name: Wait for the running user manager
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/bin/systemctl
|
|
- is-active
|
|
- "user@{{ video_encoding_account.uid }}.service"
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_user_manager
|
|
retries: 5
|
|
delay: 1
|
|
until: video_encoding_user_manager.stdout == "active"
|
|
|
|
- name: Find DRM render nodes in sysfs
|
|
ansible.builtin.find:
|
|
paths: /sys/class/drm
|
|
patterns: "renderD*"
|
|
file_type: link
|
|
recurse: false
|
|
register: video_encoding_render_nodes
|
|
|
|
- name: Build the GPU device node list
|
|
ansible.builtin.set_fact:
|
|
video_encoding_gpu_device_nodes: >-
|
|
{{ ['/dev/kfd']
|
|
+ (video_encoding_render_nodes.files
|
|
| map(attribute="path")
|
|
| map("basename")
|
|
| map("regex_replace", "^", "/dev/dri/")
|
|
| list) }}
|
|
|
|
- name: Verify the host exposes the expected GPU device nodes
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_gpu_device_nodes | length == 3
|
|
fail_msg: >-
|
|
Expected /dev/kfd and two DRM render nodes on ghostnet-ki, found
|
|
{{ video_encoding_gpu_device_nodes }}.
|
|
|
|
- name: Probe GPU device node read access as the encoding account
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/sbin/runuser
|
|
- --user
|
|
- gn-encoding
|
|
- --
|
|
- /usr/bin/test
|
|
- -r
|
|
- "{{ video_encoding_device_node }}"
|
|
check_mode: false
|
|
changed_when: false
|
|
failed_when: false
|
|
register: video_encoding_device_access
|
|
loop: "{{ video_encoding_gpu_device_nodes }}"
|
|
loop_control:
|
|
loop_var: video_encoding_device_node
|
|
label: "{{ video_encoding_device_node }}"
|
|
|
|
- name: Enforce that the encoding account cannot read GPU device nodes
|
|
ansible.builtin.assert:
|
|
that:
|
|
- >-
|
|
video_encoding_device_access.results
|
|
| map(attribute="rc")
|
|
| select("equalto", 0)
|
|
| list | length == 0
|
|
fail_msg: >-
|
|
gn-encoding can read a GPU device node. Encoding is CPU-only; remove the
|
|
device access before applying encoding state.
|
|
success_msg: gn-encoding cannot access /dev/kfd or any DRM render node.
|
|
|
|
- name: Inspect the encoding rootless Podman store
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/sbin/runuser
|
|
- --user
|
|
- gn-encoding
|
|
- --
|
|
- /usr/bin/env
|
|
- "HOME={{ video_encoding_account.home }}"
|
|
- "XDG_RUNTIME_DIR=/run/user/{{ video_encoding_account.uid }}"
|
|
- /usr/bin/podman
|
|
- info
|
|
- --format=json
|
|
chdir: "{{ video_encoding_account.home }}"
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_podman_info_command
|
|
|
|
- name: Parse the encoding rootless Podman information
|
|
ansible.builtin.set_fact:
|
|
video_encoding_podman_info: >-
|
|
{{ video_encoding_podman_info_command.stdout | from_json }}
|
|
|
|
- name: Verify the isolated rootless Podman store
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_podman_info.host.security.rootless
|
|
- >-
|
|
video_encoding_podman_info.store.graphRoot ==
|
|
video_encoding_account.home + "/.local/share/containers/storage"
|
|
fail_msg: The gn-encoding Podman store is not rootless or not isolated.
|
|
success_msg: gn-encoding uses its own rootless Podman store.
|
|
|
|
- name: List Quadlet files for the encoding account
|
|
ansible.builtin.find:
|
|
paths: "{{ video_encoding_quadlet_user_directory }}/{{ video_encoding_account.uid }}"
|
|
file_type: file
|
|
register: video_encoding_quadlet_files
|
|
when: video_encoding_image | length == 0
|
|
|
|
- name: List containers in the encoding rootless store
|
|
ansible.builtin.command:
|
|
argv:
|
|
- /usr/sbin/runuser
|
|
- --user
|
|
- gn-encoding
|
|
- --
|
|
- /usr/bin/env
|
|
- "HOME={{ video_encoding_account.home }}"
|
|
- "XDG_RUNTIME_DIR=/run/user/{{ video_encoding_account.uid }}"
|
|
- /usr/bin/podman
|
|
- ps
|
|
- -a
|
|
- --format
|
|
- json
|
|
chdir: "{{ video_encoding_account.home }}"
|
|
check_mode: false
|
|
changed_when: false
|
|
register: video_encoding_podman_ps_command
|
|
when: video_encoding_image | length == 0
|
|
|
|
- name: Verify that no encoding workload is defined before the open decisions are made
|
|
ansible.builtin.assert:
|
|
that:
|
|
- video_encoding_quadlet_files.files | length == 0
|
|
- (video_encoding_podman_ps_command.stdout | from_json) | length == 0
|
|
fail_msg: >-
|
|
A Quadlet file or container exists for gn-encoding although no encoder
|
|
image has been selected. Remove it or complete the open decisions in
|
|
docs/platform/llm-server/encoding/GNENC-001 section 7 first.
|
|
success_msg: >-
|
|
No encoding workload is defined; the open decisions in GNENC-001 remain
|
|
the gate for images, Quadlets and timers.
|
|
when: video_encoding_image | length == 0
|
|
|
|
- name: Report the verified encoding baseline
|
|
ansible.builtin.debug:
|
|
msg:
|
|
account: "gn-encoding (UID/GID 982)"
|
|
config_directory: /etc/ghostnet-encoding
|
|
pipeline_mount: "{{ video_encoding_nfs_server }}:{{ video_encoding_nfs_export }} -> {{ video_encoding_pipeline_mount }}"
|
|
pipeline_profiles: "{{ video_encoding_profile_names | default([]) }}"
|
|
quadlet_directory: /etc/containers/systemd/users/982
|
|
podman_store: "{{ video_encoding_podman_info.store.graphRoot }}"
|
|
gpu_access: none (verified)
|
|
workload_defined: false
|