diff --git a/roles/s6-rc/handlers/main.yml b/roles/s6-rc/handlers/main.yml new file mode 100644 index 0000000..d7bed20 --- /dev/null +++ b/roles/s6-rc/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: Reload /etc/ttys + command: kill -HUP 1 diff --git a/roles/s6-rc/tasks/main.yml b/roles/s6-rc/tasks/main.yml new file mode 100644 index 0000000..3c2cf4e --- /dev/null +++ b/roles/s6-rc/tasks/main.yml @@ -0,0 +1,119 @@ +--- +- name: Install packages + package: + name: s6-rc + +- name: Create s6-rc directories + file: + path: '{{ item }}' + state: directory + owner: root + group: wheel + mode: 0755 + with_items: + - /etc/s6-rc + - /etc/s6-rc/service + - /etc/s6-rc/service/enabled + +- name: Define enabled services bundle + copy: + dest: /etc/s6-rc/service/enabled/type + content: bundle + owner: root + group: wheel + mode: 0444 + +- name: Default to an empty set of enabled servics + file: + path: /etc/s6-rc/service/enabled/contents + state: touch + owner: root + group: wheel + mode: 0644 + changed_when: false + +- name: Pick a UUID + command: uuidgen + register: uuidgen + changed_when: false + +- name: Expose the UUID as fact + set_fact: + s6_uuid: '{{ uuidgen.stdout }}' + changed_when: false + +- name: Compile the s6 service definitions + command: > + s6-rc-compile -v 2 .compiled.{{ s6_uuid }} service + args: + creates: /etc/s6-rc/compiled + chdir: /etc/s6-rc + +- name: Link to the latest service database + command: > + env ln -shf .compiled.{{ s6_uuid }} compiled + args: + creates: /etc/s6-rc/compiled + chdir: /etc/s6-rc + +- name: Make sure that tmpfs support is loaded early + lineinfile: + path: /boot/loader.conf + regexp: '^tmpfs_load=' + line: 'tmpfs_load="YES"' + +- name: Add /run to fstab + mount: + path: /run + src: tmpfs + fstype: tmpfs + opts: rw,size=128m,mode=755 + state: mounted + +- name: Generate s6-svscan startup script + template: + dest: /etc/s6-rc/scan + src: scan.j2 + owner: root + group: wheel + mode: 0555 + +- name: Start s6-svscan from /etc/ttys + lineinfile: + path: /etc/ttys + regexp: '^null' + line: 'null "/etc/s6-rc/scan" vt100 on secure' + notify: + - Reload /etc/ttys + +- name: Install s6-rc rc.d script + template: + dest: /usr/local/etc/rc.d/s6-rc + src: s6-rc.j2 + owner: root + group: wheel + mode: 0555 + +- name: Flush handlers + meta: flush_handlers + +- name: Starting s6-rc + service: + name: s6-rc + state: started + enabled: yes + +- name: Create s6-log group + group: + name: s6-log + gid: 20000 + +- name: Create s6-log user + user: + name: s6-log + uid: 20000 + group: s6-log + create_home: no + home: /var/empty + shell: /bin/sh + diff --git a/roles/s6-rc/templates/s6-rc.j2 b/roles/s6-rc/templates/s6-rc.j2 new file mode 100644 index 0000000..86dc163 --- /dev/null +++ b/roles/s6-rc/templates/s6-rc.j2 @@ -0,0 +1,124 @@ +#!/bin/sh +# {{ ansible_managed }} + +# PROVIDE: s6-rc +# REQUIRE: NETWORKING daemon +# KEYWORD: shutdown + +. /etc/rc.subr + +export PATH="$PATH:/usr/local/bin:/usr/local/sbin" + +name=s6-rc +rcvar=s6_rc_enable +extra_commands="reload" + +start_cmd="s6_rc_start &" +stop_cmd="s6_rc_stop" +reload_cmd="s6_rc_reload" +status_cmd="s6_rc_status" + +s6_timeout=300 # seconds +up_timeout=300000 # milliseconds +down_timeout=300000 # milliseconds +update_timeout=300000 # milliseconds + +s6_wait() +{ + local i=0 + + while ! s6-svscanctl -z /run/service 2>/dev/null; do + if [ $i -ge $s6_timeout ]; then + echo "Timeout waiting for s6-svscan." >&2 + return 1 + fi + if [ $i -eq 0 ]; then + echo -n "Waiting for s6-svscan." >&2 + else + echo -n . >&2 + fi + sleep 1 + i=$((i + 1)) + done + if [ $i -gt 0 ]; then + echo >&2 + fi + return 0 +} + +s6_rc_init() +{ + if [ ! -e /run/s6-rc ]; then + s6-rc-init /run/service + fi +} + +s6_rc_up() +{ + s6-rc -v 2 -u -t $up_timeout change enabled +} + +s6_rc_down() +{ + s6-rc -v 2 -d -a -t $down_timeout change +} + +s6_rc_start() +{ + if ! s6_wait; then + return 1 + fi + + s6_rc_init + s6_rc_up +} + +s6_rc_stop() +{ + s6_rc_down +} + +s6_rc_reload() +{ + local uuid="$(uuidgen)" + + cd /etc/s6-rc + echo "Compiling new s6-rc service database." + s6-rc-compile -v 2 ".compiled.$uuid" service + + if s6-rc-update -v 2 -t $update_timeout "/etc/s6-rc/.compiled.$uuid"; then + ln -shf ".compiled.$uuid" compiled + echo "Updated s6-rc service database." + fi + + echo "Deleting old service databases." + find -s . -mindepth 1 -maxdepth 1 -type d -name '.compiled.*' -not -name ".compiled.$uuid" -print0 | xargs -0 rm -r +} + +s6_rc_status() +{ + local result=0 + + if s6-svscanctl -z /run/service 2>/dev/null; then + echo "The s6-svscan supervisor is responsible." + else + echo "The s6-svscan supervisor is unavailable." + result=1 + fi + + if [ -e /run/s6-rc ]; then + echo "The s6-rc service manager is initialized." + + echo + echo "These services are currently active:" + s6-rc -a list + else + echo "The s6-rc service manager is uninitalized." + result=1 + fi + + return $result +} + +load_rc_config $name +run_rc_command "$1" diff --git a/roles/s6-rc/templates/scan.j2 b/roles/s6-rc/templates/scan.j2 new file mode 100644 index 0000000..31b11e7 --- /dev/null +++ b/roles/s6-rc/templates/scan.j2 @@ -0,0 +1,6 @@ +#!/bin/sh -e + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + +install -d -o root -g wheel -m 755 /run/service +exec s6-svscan -s /run/service