Add services:base:user

This commit is contained in:
Wojciech Kozlowski 2022-12-11 00:41:50 +01:00
parent 0b3542c414
commit 64fc6d748f
24 changed files with 272 additions and 237 deletions

View File

@ -1,19 +0,0 @@
iface {{ service_iface_name }} inet manual
pre-up mkdir -p /run/netns
pre-up ln -sfTv /proc/$(cat /var/lib/{{ ansible_hostname }}/containers/{{ service_user_name }}/pidfile)/ns/net /run/netns/{{ service_user_name }}
pre-up ip link add name $IFACE type veth peer name veth0 netns {{ service_user_name }}
pre-up ip link set $IFACE master br0
post-up ip -n {{ service_user_name }} link set veth0 up
post-up ip -n {{ service_user_name }} address add {{ service_bridge_address }}/24 dev veth0
post-up ip -n {{ service_user_name }} route add default via {{ service_bridge_gateway }} dev veth0
pre-down ip -n {{ service_user_name }} route del default via {{ service_bridge_gateway }} dev veth0
pre-down ip -n {{ service_user_name }} address del {{ service_bridge_address }}/24 dev veth0
pre-down ip -n {{ service_user_name }} link set veth0 down
post-down ip link set $IFACE nomaster
post-down ip link del dev $IFACE
post-down rm /run/netns/{{ service_user_name }}

View File

@ -1,8 +1,4 @@
- block:
- import_tasks: ../vars.yml
- import_tasks: service-user/00-vars.yml
- import_tasks: service-user/01-zfs-datasets.yml
when: is_zfs
- import_tasks: service-user/01-user.yml
- import_tasks: service-user/02-veth.yml
tags: "{{ service_name }}"

View File

@ -1,11 +0,0 @@
- name: Set service user variables
set_fact:
service_iface_name: "veth-{{ service_name }}"
service_bridge_address: "{{ services[service_name].address }}"
- name: Print service user variables
debug:
msg:
- "service_name: {{ service_name }}"
- "service_iface_name: {{ service_iface_name }}"
- "service_bridge_address: {{ service_bridge_address }}"

View File

@ -1,4 +0,0 @@
- include_tasks: _volumes.yml
with_items: "{{ volumes[service_name] }}"
loop_control:
loop_var: volume

View File

@ -1,22 +0,0 @@
- name: Create volume {{ volume }} for user {{ service_user_name }}
file:
path: "/var/lib/{{ ansible_hostname }}/data/{{ service_user_name }}/{{ volume }}"
state: directory
owner: "{{ service_user_name }}"
group: "{{ service_user_name }}"
mode: 0755
- name: Check if {{ volume }} mount directory exists for user {{ service_user_name }}
stat:
path: "/var/lib/{{ ansible_hostname }}/data/{{ service_user_name }}/{{ volume }}/_data"
register: volume_mount_directory
- name: Create {{ volume }} mount directory for user {{ service_user_name }}
file:
path: "/var/lib/{{ ansible_hostname }}/data/{{ service_user_name }}/{{ volume }}/_data"
state: directory
owner: "{{ service_user_name }}"
group: "{{ service_user_name }}"
mode: 0755
when:
not volume_mount_directory.stat.exists

View File

@ -1,4 +0,0 @@
- name: Set default shell for for {{ service_user_name }}
user:
name: "{{ service_user_name }}"
shell: "/usr/sbin/nologin"

View File

@ -1,4 +0,0 @@
- name: Set default shell for for {{ service_user_name }}
user:
name: "{{ service_user_name }}"
shell: "/usr/bin/rbash"

View File

@ -1,121 +0,0 @@
- name: Create system user for {{ service_name }}
user:
name: "{{ service_user_name }}"
create_home: yes
home: "{{ service_home }}"
system: yes
register: user_create
- include_tasks: "{{ item }}"
with_first_found:
- files:
- "01-user.d/shell/{{ service_name }}.yml"
- "01-user.d/shell/_default.yml"
- block:
- name: Ensure the home directory belongs to the user {{ service_user_name }}
file:
path: "{{ service_home }}"
state: directory
owner: "{{ service_user_name }}"
group: "{{ service_user_name }}"
recurse: yes
- name: Configure subuids and subgids for user {{ service_user_name }}
shell: |
export NEW_SUBUID=$(($(tail -1 /etc/subuid | awk -F ":" '{print $2}')+65536))
export NEW_SUBGID=$(($(tail -1 /etc/subgid | awk -F ":" '{print $2}')+65536))
usermod --add-subuids ${NEW_SUBUID}-$((${NEW_SUBUID}+65535)) \
--add-subgids ${NEW_SUBGID}-$((${NEW_SUBGID}+65535)) \
{{ service_user_name }}
- name: Ensure XDG_RUNTIME_DIR is set for user {{ service_user_name }}
shell: |
echo '\nexport XDG_RUNTIME_DIR=/run/user/$(id -u)' >> \
{{ service_home }}/.bashrc
- name: Enable lingering for user {{ service_user_name }}
command: loginctl enable-linger {{ service_user_name }}
when:
user_create is changed
- name: Create container directory for user {{ service_user_name }}
file:
path: "/var/lib/{{ ansible_hostname }}/containers/{{ service_user_name }}"
state: directory
owner: "{{ service_user_name }}"
group: "{{ service_user_name }}"
mode: 0755
- name: Create volume data directory for user {{ service_user_name }}
file:
path: "/var/lib/{{ ansible_hostname }}/data/{{ service_user_name }}"
state: directory
owner: "{{ service_user_name }}"
group: "{{ service_user_name }}"
mode: 0755
- include_tasks: "{{ item }}"
with_first_found:
- files:
- "01-user.d/data/{{ service_name }}.yml"
- "01-user.d/data/_default.yml"
- block:
- name: Create configuration directory for user {{ service_user_name }}
file:
path: "{{ service_home }}/.config"
state: directory
mode: 0755
- name: Create container configuration directory for user {{ service_user_name }}
file:
path: "{{ service_home }}/.config/containers"
state: directory
mode: 0755
- name: Configure storage.conf for user {{ service_user_name }}
template:
src: "./filesystem/common/var/lib/_hostname/home/_service_user_name/.config/containers/storage.conf.j2"
dest: "{{ service_home }}/.config/containers/storage.conf"
mode: 0644
register: user_containers_storage
- name: Reset podman
shell: "cd $HOME; yes | podman system reset"
when:
user_containers_storage is changed
- name: Create systemd directory for user {{ service_user_name }}
file:
path: "{{ service_home }}/.config/systemd"
state: directory
mode: 0755
- name: Create systemd service directory for user {{ service_user_name }}
file:
path: "{{ service_home }}/.config/systemd/user"
state: directory
mode: 0755
- name: SystemD daemon reload
systemd:
daemon_reload: true
scope: user
- name: Enable pod-service auto-update
systemd:
name: pod-service-auto-update.timer
enabled: yes
state: started
scope: user
- name: Enable podman image prune
systemd:
name: podman-image-prune.service
enabled: yes
scope: user
become_user: "{{ service_user_name }}"

View File

@ -1,20 +0,0 @@
- name: Configure veth interface for user {{ service_user_name }}
template:
src: "./filesystem/common/etc/network/interfaces.d/veth-_service.j2"
dest: "/etc/network/interfaces.d/{{ service_iface_name }}"
mode: 0644
validate: >
bash -c
'export NEWIF=%s;
if ! diff ${NEWIF} /etc/network/interfaces.d/{{ service_iface_name }} &&
ip link show dev {{ service_iface_name }} ;
then
ifdown {{ service_iface_name }} && ifup -i ${NEWIF} {{ service_iface_name }} ;
fi'
register: veth_service_intf
- name: Enable the path trigger service for {{ service_name }}
systemd:
name: "connect-pod-service@{{ service_name }}.path"
enabled: yes
state: started

View File

@ -0,0 +1,13 @@
argument_specs:
main:
options:
ansible_hostname:
type: "str"
required: true
services_host_services:
type: "list"
elem: "str"
required: true
services_bridge_gateway:
type: "str"
required: true

View File

@ -0,0 +1,19 @@
- name: "play:services : role:base : tasks:system:podman"
ansible.builtin.import_tasks: "system/podman.yml"
tags: "services:base:system:podman"
- name: "play:services : role:base : tasks:system:directories"
ansible.builtin.import_tasks: "system/directories.yml"
tags: "services:base:system:directories"
- name: "play:services : role:base : tasks:system:nameserver"
ansible.builtin.import_tasks: "system/nameserver.yml"
tags: "services:base:system:nameserver"
- name: "play:services : role:base : tasks:system:veth"
ansible.builtin.import_tasks: "system/veth.yml"
tags: "services:base:system:veth"
- name: "play:services : role:base : tasks:system:auto_update"
ansible.builtin.import_tasks: "system/auto_update.yml"
tags: "services:base:system:auto_update"

View File

@ -1,24 +1,24 @@
- name: "system : systemd : pod-service update script"
- name: "system : auto_update : pod-service update script"
ansible.builtin.copy:
src: "./system/systemd/pod-service-auto-update"
dest: "/usr/local/sbin/pod-service-auto-update"
mode: 0755
- name: "system : systemd : pod-service update service"
- name: "system : auto_update : pod-service update service"
ansible.builtin.copy:
src: "./system/systemd/pod-service-auto-update.service"
dest: "/etc/systemd/user/pod-service-auto-update.service"
mode: 0644
register: services_base_system_pod_service_auto_update_service_file
- name: "system : systemd : pod-service update timer"
- name: "system : auto_update : pod-service update timer"
ansible.builtin.copy:
src: "./system/systemd/pod-service-auto-update.timer"
dest: "/etc/systemd/user/pod-service-auto-update.timer"
mode: 0644
register: services_base_system_pod_service_auto_update_timer_file
- name: "system : systemd : image prune service"
- name: "system : auto_update : image prune service"
ansible.builtin.copy:
src: "./system/systemd/podman-image-prune.service"
dest: "/etc/systemd/user/podman-image-prune.service"
@ -27,7 +27,7 @@
# Include instead of import as otherwise the when clause is always applied which triggers errors if
# the above tasks haven't executed.
- name: "system : systemd : systemd daemon reload for each service"
- name: "system : auto_update : systemd daemon reload for each service"
ansible.builtin.include_role:
name: "include"
tasks_from: "daemon_reload"

View File

@ -0,0 +1,45 @@
- name: "user : {{ services_service_name }} : set variables"
ansible.builtin.import_role:
name: "include"
tasks_from: "vars"
tags:
- "services:base:user:setup"
- "services:base:user:{{ services_service_name }}:setup"
- "services:base:user:directories"
- "services:base:user:{{ services_service_name }}:directories"
- "services:base:user:podman"
- "services:base:user:{{ services_service_name }}:podman"
- "services:base:user:auto_update"
- "services:base:user:{{ services_service_name }}:auto_update"
- "services:base:user:veth"
- "services:base:user:{{ services_service_name }}:veth"
- name: "play:services : role:base : tasks:user:setup"
ansible.builtin.import_tasks: "user/setup.yml"
tags:
- "services:base:user:setup"
- "services:base:user:{{ services_service_name }}:setup"
- name: "play:services : role:base : tasks:user:directories"
ansible.builtin.import_tasks: "user/directories.yml"
tags:
- "services:base:user:directories"
- "services:base:user:{{ services_service_name }}:directories"
- name: "play:services : role:base : tasks:user:podman"
ansible.builtin.import_tasks: "user/podman.yml"
tags:
- "services:base:user:podman"
- "services:base:user:{{ services_service_name }}:podman"
- name: "play:services : role:base : tasks:user:auto_update"
ansible.builtin.import_tasks: "user/auto_update.yml"
tags:
- "services:base:user:auto_update"
- "services:base:user:{{ services_service_name }}:auto_update"
- name: "play:services : role:base : tasks:user:veth"
ansible.builtin.import_tasks: "user/veth.yml"
tags:
- "services:base:user:veth"
- "services:base:user:{{ services_service_name }}:veth"

View File

@ -0,0 +1,16 @@
- block:
- name: "user : {{ services_service_name }} : auto_update : enable auto-update timer"
ansible.builtin.systemd:
name: "pod-service-auto-update.timer"
enabled: true
state: "started"
scope: "user"
- name: "user : {{ services_service_name }} : auto_update : enable podman image prune"
ansible.builtin.systemd:
name: "podman-image-prune.service"
enabled: true
scope: "user"
become_user: "{{ services_service_user_name }}"

View File

@ -0,0 +1,31 @@
- name: "user : {{ services_service_name }} : directories : create containers directory"
ansible.builtin.file:
path: "/var/lib/{{ ansible_hostname }}/containers/{{ services_service_user_name }}"
state: "directory"
owner: "{{ services_service_user_name }}"
group: "{{ services_service_user_name }}"
mode: 0755
- name: "user : {{ services_service_name }} : directories : create data directory"
ansible.builtin.file:
path: "/var/lib/{{ ansible_hostname }}/data/{{ services_service_user_name }}"
state: "directory"
owner: "{{ services_service_user_name }}"
group: "{{ services_service_user_name }}"
mode: 0755
- name: "user : {{ services_service_name }} : directories : create volume directories"
ansible.builtin.include_tasks: "directories/volumes.yml"
loop: "{{ services[services_service_name].volumes }}"
loop_control:
loop_var: "services_service_volume"
- block:
- name: "user : {{ services_service_name }} : directories : create systemd directory"
ansible.builtin.file:
path: "{{ services_service_user_home }}/.config/systemd/user"
state: "directory"
mode: 0755
become_user: "{{ services_service_user_name }}"

View File

@ -0,0 +1,22 @@
- name: "user : {{ services_service_name }} : directories : create volume \"{{ services_service_volume.name }}\""
ansible.builtin.file:
path: "/var/lib/{{ ansible_hostname }}/data/{{ services_service_user_name }}/{{ services_service_volume.name }}"
state: "directory"
owner: "{{ services_service_user_name }}"
group: "{{ services_service_user_name }}"
mode: 0755
- name: "user : {{ services_service_name }} : directories : check if \"{{ services_service_volume.name }}\" mount exists"
ansible.builtin.stat:
path: "/var/lib/{{ ansible_hostname }}/data/{{ services_service_user_name }}/{{ services_service_volume.name }}/_data"
register: services_base_user_volume_mount
- name: "user : {{ services_service_name }} : directories : create \"{{ services_service_volume.name }}\" mount"
ansible.builtin.file:
path: "/var/lib/{{ ansible_hostname }}/data/{{ services_service_user_name }}/{{ services_service_volume.name }}/_data"
state: "directory"
owner: "{{ services_service_user_name }}"
group: "{{ services_service_user_name }}"
mode: 0755
when:
not services_base_user_volume_mount.stat.exists

View File

@ -0,0 +1,21 @@
- block:
- name: "user : {{ services_service_name }} : podman : create container configuration directory"
ansible.builtin.file:
path: "{{ services_service_user_home }}/.config/containers"
state: "directory"
mode: 0755
- name: "user : {{ services_service_name }} : podman : configure podman storage"
ansible.builtin.template:
src: "./user/podman/storage.conf.j2"
dest: "{{ services_service_user_home }}/.config/containers/storage.conf"
mode: 0644
register: services_base_user_containers_storage
- name: "user : {{ services_service_name }} : podman : reset podman"
ansible.builtin.shell: "cd $HOME; yes | podman system reset"
when:
services_base_user_containers_storage.changed
become_user: "{{ services_service_user_name }}"

View File

@ -0,0 +1,41 @@
- name: "user : {{ services_service_name }} : setup : create system user"
ansible.builtin.user:
name: "{{ services_service_user_name }}"
create_home: true
home: "{{ services_service_user_home }}"
system: true
register: services_base_user_create
- name: "user : {{ services_service_name }} : setup : set default shell"
ansible.builtin.user:
name: "{{ services_service_user_name }}"
shell: "{{ services[services_service_name].shell | default('/usr/sbin/nologin') }}"
- block:
- name: "user : {{ services_service_name }} : setup : set home directory ownership"
ansible.builtin.file:
path: "{{ services_service_user_home }}"
state: "directory"
owner: "{{ services_service_user_name }}"
group: "{{ services_service_user_name }}"
recurse: true
- name: "user : {{ services_service_name }} : setup : configure subuids and subgids"
ansible.builtin.shell: |
export NEW_SUBUID=$(($(tail -1 /etc/subuid | awk -F ":" '{print $2}')+65536))
export NEW_SUBGID=$(($(tail -1 /etc/subgid | awk -F ":" '{print $2}')+65536))
usermod --add-subuids ${NEW_SUBUID}-$((${NEW_SUBUID}+65535)) \
--add-subgids ${NEW_SUBGID}-$((${NEW_SUBGID}+65535)) \
{{ services_service_user_name }}
- name: "user : {{ services_service_name }} : setup : ensure XDG_RUNTIME_DIR is set"
ansible.builtin.shell: |
echo '\nexport XDG_RUNTIME_DIR=/run/user/$(id -u)' >> \
{{ services_service_user_home }}/.bashrc
- name: "user : {{ services_service_name }} : setup : enable lingering"
ansible.builtin.command: "loginctl enable-linger {{ services_service_user_name }}"
when:
services_base_user_create.changed

View File

@ -0,0 +1,23 @@
- name: "user : {{ services_service_name }} : veth : configure interface"
ansible.builtin.template:
src: "./user/veth/interface.j2"
dest: "/etc/network/interfaces.d/{{ services_service_iface_name }}"
mode: 0644
validate: >
bash -c
'export NEWIF=%s;
if ! diff ${NEWIF} /etc/network/interfaces.d/{{ services_service_iface_name }} &&
ip link show dev {{ services_service_iface_name }} ;
then
ifdown {{ services_service_iface_name }} &&
ifup -i ${NEWIF} {{ services_service_iface_name }} ;
fi'
vars:
services_service_iface_name: "veth-{{ services_service_name }}"
services_service_iface_address: "{{ services[services_service_name].address }}"
- name: "user : {{ services_service_name }} : veth : enable the path trigger"
ansible.builtin.systemd:
name: "connect-pod-service@{{ services_service_name }}.path"
enabled: true
state: "started"

View File

@ -1,19 +1,15 @@
- name: "play:services : role:base : tasks:system:podman"
ansible.builtin.import_tasks: "include/system/podman.yml"
tags: "services:base:system:podman"
- name: "play:services : role:base : tasks:system"
ansible.builtin.import_tasks: "include/system.yml"
tags: "services:base:system"
- name: "play:services : role:base : tasks:system:directories"
ansible.builtin.import_tasks: "include/system/directories.yml"
tags: "services:base:system:directories"
- name: "play:services : role:base : tasks:system:nameserver"
ansible.builtin.import_tasks: "include/system/nameserver.yml"
tags: "services:base:system:nameserver"
- name: "play:services : role:base : tasks:system:veth"
ansible.builtin.import_tasks: "include/system/veth.yml"
tags: "services:base:system:veth"
- name: "play:services : role:base : tasks:system:systemd"
ansible.builtin.import_tasks: "include/system/systemd.yml"
tags: "services:base:system:systemd"
- name: "play:services : role:base : tasks:user"
ansible.builtin.include_tasks: "include/user.yml"
tags: "always"
args:
apply:
tags:
- "services:base:user"
- "services:base:user:{{ services_service_name }}"
loop: "{{ services_host_services }}"
loop_control:
loop_var: "services_service_name"

View File

@ -1,5 +1,5 @@
[storage]
graphroot = "/var/lib/{{ ansible_hostname }}/containers/{{ service_user_name }}/storage"
graphroot = "/var/lib/{{ ansible_hostname }}/containers/{{ services_service_user_name }}/storage"
driver = "overlay"
[storage.options]

View File

@ -0,0 +1,19 @@
iface {{ services_service_iface_name }} inet manual
pre-up mkdir -p /run/netns
pre-up ln -sfTv /proc/$(cat /var/lib/{{ ansible_hostname }}/containers/{{ services_service_user_name }}/pidfile)/ns/net /run/netns/{{ services_service_user_name }}
pre-up ip link add name $IFACE type veth peer name veth0 netns {{ services_service_user_name }}
pre-up ip link set $IFACE master br0
post-up ip -n {{ services_service_user_name }} link set veth0 up
post-up ip -n {{ services_service_user_name }} address add {{ services_service_iface_address }}/24 dev veth0
post-up ip -n {{ services_service_user_name }} route add default via {{ services_bridge_gateway }} dev veth0
pre-down ip -n {{ services_service_user_name }} route del default via {{ services_bridge_gateway }} dev veth0
pre-down ip -n {{ services_service_user_name }} address del {{ services_service_iface_address }}/24 dev veth0
pre-down ip -n {{ services_service_user_name }} link set veth0 down
post-down ip link set $IFACE nomaster
post-down ip link del dev $IFACE
post-down rm /run/netns/{{ services_service_user_name }}

View File

@ -26,8 +26,7 @@
- name: "user : {{ services_service_name }} : create volume datasets"
community.general.zfs:
name: >-
rpool/var/lib/{{ ansible_hostname }}/data/{{ services_service_user_name }}/{{ item.name }}
name: "rpool/var/lib/{{ ansible_hostname }}/data/{{ services_service_user_name }}/{{ item.name }}"
state: "present"
extra_zfs_properties: "{{ item.properties | default({}) }}"
loop: "{{ services[services_service_name].volumes }}"

View File

@ -4,5 +4,4 @@
- name: "vars : {{ services_service_name }} : set user home variable"
set_fact:
services_service_user_home: >-
/var/lib/{{ ansible_hostname }}/home/{{ services_service_user_name }}
services_service_user_home: "/var/lib/{{ ansible_hostname }}/home/{{ services_service_user_name }}"