Skip to content

Commit 96c2293

Browse files
committed
tons of fixes
1 parent 7bf42c8 commit 96c2293

52 files changed

Lines changed: 4487 additions & 537 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ansible/roles/backups/templates/terrarium-syncoid.service.j2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ Wants=network-online.target
55

66
[Service]
77
Type=oneshot
8-
ExecStart=/usr/sbin/syncoid --recursive --no-sync-snap --sshkey {{ terrarium_syncoid_ssh_key }} {{ terrarium_lxd_pool_name }}/containers {{ terrarium_syncoid_target }}:{{ terrarium_syncoid_target_dataset }}
8+
Environment=HOME=/root
9+
ExecStart=/usr/sbin/syncoid --recursive --sshkey {{ terrarium_syncoid_ssh_key }} {{ terrarium_lxd_pool_name }}/containers {{ terrarium_syncoid_target }}:{{ terrarium_syncoid_target_dataset }}

ansible/roles/cockpit_plugins/tasks/main.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,31 @@
5959
- terrarium_cockpit_plugin_bundle_enabled
6060
- terrarium_cockpit_plugin_bundle_arch | length > 0
6161

62+
- name: Check downloaded cockpit-zfs bundle
63+
ansible.builtin.stat:
64+
path: "{{ terrarium_cockpit_zfs_bundle_download.dest }}"
65+
register: terrarium_cockpit_zfs_bundle_file
66+
when:
67+
- terrarium_cockpit_zfs_bundle_download is defined
68+
- terrarium_cockpit_zfs_bundle_download.dest is defined
69+
70+
- name: Check downloaded cockpit-s3 bundle
71+
ansible.builtin.stat:
72+
path: "{{ terrarium_cockpit_s3_bundle_download.dest }}"
73+
register: terrarium_cockpit_s3_bundle_file
74+
when:
75+
- terrarium_cockpit_s3_bundle_download is defined
76+
- terrarium_cockpit_s3_bundle_download.dest is defined
77+
6278
- name: Determine whether prebuilt cockpit-zfs bundle is usable
6379
ansible.builtin.set_fact:
6480
terrarium_cockpit_zfs_bundle_usable: >-
6581
{{
6682
terrarium_cockpit_zfs_bundle_download is defined
6783
and terrarium_cockpit_zfs_bundle_download is succeeded
6884
and terrarium_cockpit_zfs_bundle_download.dest is defined
85+
and terrarium_cockpit_zfs_bundle_file.stat.exists | default(false)
86+
and (terrarium_cockpit_zfs_bundle_file.stat.size | default(0) | int) > 0
6987
}}
7088
7189
- name: Determine whether prebuilt cockpit-s3 bundle is usable
@@ -75,6 +93,8 @@
7593
terrarium_cockpit_s3_bundle_download is defined
7694
and terrarium_cockpit_s3_bundle_download is succeeded
7795
and terrarium_cockpit_s3_bundle_download.dest is defined
96+
and terrarium_cockpit_s3_bundle_file.stat.exists | default(false)
97+
and (terrarium_cockpit_s3_bundle_file.stat.size | default(0) | int) > 0
7898
}}
7999
80100
- name: Install prebuilt cockpit-zfs bundle

ansible/roles/idp_zitadel/tasks/main.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@
4848
creates: /etc/terrarium/secrets/zitadel_postgres_password
4949

5050
- name: Generate ZITADEL bootstrap admin password
51-
ansible.builtin.shell: "umask 077 && tr -dc 'A-Za-z0-9' </dev/urandom | head -c 32 > /etc/terrarium/secrets/zitadel_admin_password"
51+
ansible.builtin.shell: |
52+
umask 077
53+
pw="$(tr -dc 'A-Z' </dev/urandom | head -c 1)$(tr -dc 'a-z' </dev/urandom | head -c 1)$(tr -dc '0-9' </dev/urandom | head -c 1)!$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 28)"
54+
printf '%s' "$pw" > /etc/terrarium/secrets/zitadel_admin_password
5255
args:
5356
creates: /etc/terrarium/secrets/zitadel_admin_password
5457

ansible/roles/idp_zitadel/templates/docker-compose.yml.j2

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ services:
2828
ZITADEL_EXTERNALSECURE: "true"
2929
ZITADEL_TLS_ENABLED: "false"
3030
ZITADEL_LOGSTORE_ACCESS_STDOUT_ENABLED: "true"
31-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_USERNAME: "admin"
32-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_FIRSTNAME: "Terrarium"
33-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_LASTNAME: "Admin"
34-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS: "{{ terrarium_zitadel_admin_email | default(terrarium_email, true) }}"
35-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_EMAIL_VERIFIED: "true"
36-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_PASSWORD: "{{ terrarium_zitadel_admin_password }}"
37-
ZITADEL_DEFAULTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: "false"
31+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: "{{ terrarium_zitadel_admin_email | default(terrarium_email, true) }}"
32+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_FIRSTNAME: "Terrarium"
33+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_LASTNAME: "Admin"
34+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS: "{{ terrarium_zitadel_admin_email | default(terrarium_email, true) }}"
35+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_VERIFIED: "true"
36+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: "{{ terrarium_zitadel_admin_password }}"
37+
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: "false"
3838
ZITADEL_FIRSTINSTANCE_MACHINEKEYPATH: /zitadel/bootstrap/admin-sa.json
3939
ZITADEL_FIRSTINSTANCE_PATPATH: /zitadel/bootstrap/admin-sa.pat
4040
ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME: terrarium-automation

ansible/roles/lxd/tasks/main.yml

Lines changed: 122 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,117 @@
1-
- name: Install LXD snap
2-
community.general.snap:
3-
name: lxd
4-
channel: "{{ terrarium_lxd_snap_channel }}"
5-
state: present
1+
- name: Check whether LXD snap is already installed
2+
ansible.builtin.command: snap list lxd
3+
register: terrarium_lxd_snap_list
4+
failed_when: false
5+
changed_when: false
6+
7+
- name: Install LXD snap when missing
8+
ansible.builtin.command: snap install lxd --channel={{ terrarium_lxd_snap_channel }}
69
register: terrarium_lxd_snap_install
7-
until: terrarium_lxd_snap_install is succeeded
10+
until:
11+
- terrarium_lxd_snap_install.rc == 0
12+
or 'already installed' in (terrarium_lxd_snap_install.stdout | lower)
13+
or 'already installed' in (terrarium_lxd_snap_install.stderr | lower)
814
retries: 30
915
delay: 10
16+
changed_when:
17+
- terrarium_lxd_snap_install.rc == 0
18+
- "'already installed' not in (terrarium_lxd_snap_install.stdout | lower)"
19+
- "'already installed' not in (terrarium_lxd_snap_install.stderr | lower)"
20+
when: terrarium_lxd_snap_list.rc != 0
21+
22+
- name: Wait for active snap changes to settle after LXD install
23+
ansible.builtin.shell: |
24+
set -u
25+
26+
active_changes="$(snap changes --no-legend 2>/dev/null | awk '$2 ~ /^(Doing|Undoing)$/ { print $1 }')"
27+
if [ -z "$active_changes" ]; then
28+
exit 0
29+
fi
30+
31+
for change_id in $active_changes; do
32+
echo "Waiting for snap change ${change_id} to settle"
33+
/usr/bin/timeout 120s snap watch "$change_id"
34+
rc=$?
35+
if [ "$rc" -ne 0 ]; then
36+
echo "snap change ${change_id} did not settle:" >&2
37+
snap change "$change_id" >&2 || true
38+
exit "$rc"
39+
fi
40+
done
41+
args:
42+
executable: /bin/bash
43+
register: terrarium_lxd_snap_changes_after_install
44+
until: terrarium_lxd_snap_changes_after_install.rc == 0
45+
retries: 6
46+
delay: 10
47+
changed_when: false
48+
49+
- name: Wait for LXD daemon to be ready after snap install
50+
ansible.builtin.command: /usr/bin/timeout 120s /snap/bin/lxd waitready
51+
register: terrarium_lxd_waitready_after_install
52+
until: terrarium_lxd_waitready_after_install.rc == 0
53+
retries: 5
54+
delay: 10
55+
changed_when: false
56+
57+
- name: Verify LXD client can reach daemon after snap install
58+
ansible.builtin.command: /snap/bin/lxc info
59+
register: terrarium_lxd_info_after_install
60+
until: terrarium_lxd_info_after_install.rc == 0
61+
retries: 12
62+
delay: 10
63+
changed_when: false
1064

1165
- name: Enable LXD UI
1266
ansible.builtin.command: snap set lxd ui.enable=true
67+
register: terrarium_lxd_ui_enable
68+
until: terrarium_lxd_ui_enable.rc == 0
69+
retries: 12
70+
delay: 10
71+
changed_when: false
72+
73+
- name: Wait for active snap changes to settle after LXD UI configuration
74+
ansible.builtin.shell: |
75+
set -u
76+
77+
active_changes="$(snap changes --no-legend 2>/dev/null | awk '$2 ~ /^(Doing|Undoing)$/ { print $1 }')"
78+
if [ -z "$active_changes" ]; then
79+
exit 0
80+
fi
81+
82+
for change_id in $active_changes; do
83+
echo "Waiting for snap change ${change_id} to settle"
84+
/usr/bin/timeout 120s snap watch "$change_id"
85+
rc=$?
86+
if [ "$rc" -ne 0 ]; then
87+
echo "snap change ${change_id} did not settle:" >&2
88+
snap change "$change_id" >&2 || true
89+
exit "$rc"
90+
fi
91+
done
92+
args:
93+
executable: /bin/bash
94+
register: terrarium_lxd_snap_changes_after_ui
95+
until: terrarium_lxd_snap_changes_after_ui.rc == 0
96+
retries: 6
97+
delay: 10
1398
changed_when: false
1499

15-
- name: Wait for LXD unix socket
16-
ansible.builtin.wait_for:
17-
path: /var/snap/lxd/common/lxd/unix.socket
18-
timeout: 120
100+
- name: Wait for LXD daemon to be ready after UI configuration
101+
ansible.builtin.command: /usr/bin/timeout 120s /snap/bin/lxd waitready
102+
register: terrarium_lxd_waitready_after_ui
103+
until: terrarium_lxd_waitready_after_ui.rc == 0
104+
retries: 5
105+
delay: 10
106+
changed_when: false
107+
108+
- name: Verify LXD client can reach daemon after UI configuration
109+
ansible.builtin.command: /snap/bin/lxc info
110+
register: terrarium_lxd_info_after_ui
111+
until: terrarium_lxd_info_after_ui.rc == 0
112+
retries: 12
113+
delay: 10
114+
changed_when: false
19115

20116
- name: Check whether LXD storage pool exists
21117
ansible.builtin.command: /snap/bin/lxc storage show {{ terrarium_lxd_pool_name }}
@@ -35,6 +131,22 @@
35131
executable: /bin/bash
36132
when: terrarium_lxd_storage_pool.rc != 0
37133

134+
- name: Wait for LXD daemon to be ready after preseed
135+
ansible.builtin.command: /usr/bin/timeout 120s /snap/bin/lxd waitready
136+
register: terrarium_lxd_waitready_after_preseed
137+
until: terrarium_lxd_waitready_after_preseed.rc == 0
138+
retries: 5
139+
delay: 10
140+
changed_when: false
141+
142+
- name: Verify LXD client can reach daemon after preseed
143+
ansible.builtin.command: /snap/bin/lxc info
144+
register: terrarium_lxd_info_after_preseed
145+
until: terrarium_lxd_info_after_preseed.rc == 0
146+
retries: 12
147+
delay: 10
148+
changed_when: false
149+
38150
- name: Pin LXD API to loopback
39151
ansible.builtin.command: /snap/bin/lxc config set core.https_address 127.0.0.1:8443
40152
changed_when: false

ansible/roles/oauth2_proxy/tasks/main.yml

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,23 +110,61 @@
110110
else terrarium_oidc_issuer
111111
) | default('', true)
112112
}}
113-
terrarium_oauth2_proxy_cookie_domain_effective: >-
114-
{{
115-
(
116-
terrarium_root_domain
117-
if terrarium_root_domain | length > 0
118-
else (terrarium_manage_domain | regex_replace('^[^.]+\\.', ''))
119-
)
120-
}}
113+
114+
- name: Derive oauth2-proxy cookie domain
115+
ansible.builtin.command:
116+
argv:
117+
- python3
118+
- -c
119+
- |
120+
import sys
121+
122+
explicit_root = sys.argv[1].strip()
123+
domains = [item.strip() for item in sys.argv[2:] if item.strip()]
124+
if explicit_root:
125+
print(explicit_root)
126+
raise SystemExit(0)
127+
if not domains:
128+
print("")
129+
raise SystemExit(0)
130+
131+
suffix = domains[0].split(".")
132+
for domain in domains[1:]:
133+
labels = domain.split(".")
134+
common = []
135+
for left, right in zip(reversed(suffix), reversed(labels)):
136+
if left != right:
137+
break
138+
common.append(left)
139+
suffix = list(reversed(common))
140+
if not suffix:
141+
break
142+
143+
candidate = ".".join(suffix)
144+
if not candidate or candidate == domains[0]:
145+
labels = domains[0].split(".")
146+
candidate = ".".join(labels[1:]) if len(labels) > 1 else domains[0]
147+
print(candidate)
148+
- "{{ terrarium_root_domain }}"
149+
- "{{ terrarium_manage_domain }}"
150+
- "{{ terrarium_proxy_domain }}"
151+
- "{{ terrarium_auth_domain | default('') }}"
152+
register: terrarium_oauth2_proxy_cookie_domain_raw
153+
changed_when: false
154+
155+
- name: Persist derived oauth2-proxy cookie domain
156+
ansible.builtin.set_fact:
157+
terrarium_oauth2_proxy_cookie_domain_effective: "{{ terrarium_oauth2_proxy_cookie_domain_raw.stdout | trim }}"
121158

122159
- name: Assert oauth2-proxy client credentials are present
123160
ansible.builtin.assert:
124161
that:
125162
- terrarium_oauth2_proxy_client_id_effective | length > 0
126163
- terrarium_oauth2_proxy_client_secret_effective | length > 0
127164
- terrarium_oauth2_proxy_oidc_issuer_effective | length > 0
165+
- terrarium_oauth2_proxy_cookie_domain_effective | length > 0
128166
- terrarium_admin_group | length > 0
129-
fail_msg: oauth2-proxy requires an OIDC issuer, client credentials, and terrarium_admin_group
167+
fail_msg: oauth2-proxy requires an OIDC issuer, client credentials, a cookie domain, and terrarium_admin_group
130168

131169
- name: Render oauth2-proxy config
132170
ansible.builtin.template:

ansible/roles/oauth2_proxy/templates/docker-compose.yml.j2

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ services:
44
user: "0:0"
55
network_mode: host
66
restart: unless-stopped
7+
{% if terrarium_idp_mode == 'local' %}
8+
environment:
9+
SSL_CERT_FILE: /etc/ssl/certs/terrarium-bootstrap.crt
10+
{% endif %}
711
command:
812
- --config=/etc/oauth2-proxy/oauth2-proxy.cfg
913
volumes:
1014
- "{{ terrarium_oauth2_proxy_dir }}/oauth2-proxy.cfg:/etc/oauth2-proxy/oauth2-proxy.cfg:ro"
15+
{% if terrarium_idp_mode == 'local' %}
16+
- "{{ terrarium_traefik_config_dir }}/bootstrap-certs/terrarium-bootstrap.crt:/etc/ssl/certs/terrarium-bootstrap.crt:ro"
17+
{% endif %}

ansible/roles/oauth2_proxy/templates/oauth2-proxy.cfg.j2

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ oidc_groups_claim = "groups"
77
client_id = "{{ terrarium_oauth2_proxy_client_id }}"
88
client_secret = "{{ terrarium_oauth2_proxy_client_secret }}"
99
cookie_secret = "{{ terrarium_oauth2_proxy_cookie_secret }}"
10+
cookie_name = "_terrarium_admin_oauth2_proxy"
1011
cookie_secure = true
11-
cookie_domains = [ "{{ terrarium_oauth2_proxy_cookie_domain }}" ]
12-
whitelist_domains = [ "{{ terrarium_manage_domain }}", "{{ terrarium_proxy_domain }}", "{{ terrarium_oauth2_proxy_cookie_domain }}" ]
12+
cookie_domains = [ ".{{ terrarium_oauth2_proxy_cookie_domain | regex_replace('^\\.', '') }}" ]
13+
whitelist_domains = [ "{{ terrarium_manage_domain }}", "{{ terrarium_proxy_domain }}", ".{{ terrarium_oauth2_proxy_cookie_domain | regex_replace('^\\.', '') }}" ]
1314
email_domains = [ "*" ]
1415
allowed_groups = [ "{{ terrarium_admin_group }}" ]
1516
upstreams = [ "static://202" ]

ansible/roles/traefik/handlers/main.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
name: traefik
88
state: restarted
99

10-
- name: reload traefik sync timer
10+
- name: reload traefik sync systemd
1111
ansible.builtin.systemd:
12-
name: terrarium-traefik-sync.timer
13-
enabled: true
14-
state: restarted
1512
daemon_reload: true

0 commit comments

Comments
 (0)