From bf130d2c3ff7efa9bfdcca5bdfb8c5371c5d9ba7 Mon Sep 17 00:00:00 2001 From: dogeystamp Date: Mon, 4 Sep 2023 15:28:03 -0400 Subject: [PATCH] roles/syncthing, roles/containers: added syncthing --- group_vars/all/secret_template.yml | 3 + roles/containers/defaults/main.yml | 5 + roles/containers/tasks/main.yml | 23 ++++ .../templates/docker-compose.yml.j2 | 15 +++ roles/syncthing/defaults/main.yaml | 52 ++++++++ roles/syncthing/handlers/main.yaml | 5 + roles/syncthing/tasks/main.yml | 113 ++++++++++++++++++ run.yml | 5 + 8 files changed, 221 insertions(+) create mode 100644 roles/syncthing/defaults/main.yaml create mode 100644 roles/syncthing/handlers/main.yaml create mode 100644 roles/syncthing/tasks/main.yml diff --git a/group_vars/all/secret_template.yml b/group_vars/all/secret_template.yml index 20ca8cb..aaeb051 100644 --- a/group_vars/all/secret_template.yml +++ b/group_vars/all/secret_template.yml @@ -2,3 +2,6 @@ # password for ddclient ddclient_pass: "" + +# syncthing gui password +syncthing_gui_pass: "" diff --git a/roles/containers/defaults/main.yml b/roles/containers/defaults/main.yml index 71cfec0..6d5b203 100644 --- a/roles/containers/defaults/main.yml +++ b/roles/containers/defaults/main.yml @@ -6,3 +6,8 @@ docker_compose_dir: "/opt/services" gitea_domain: "git.{{ domain }}" + +# Paths for Syncthing folders +vault_path: "{{ dataroot }}/syncthing/vault" +archive_path: "{{ dataroot }}/syncthing/vault_a" +syncthing_conf_dir: "{{ dataroot }}/syncthing/config" diff --git a/roles/containers/tasks/main.yml b/roles/containers/tasks/main.yml index ba3b65d..f75d83a 100644 --- a/roles/containers/tasks/main.yml +++ b/roles/containers/tasks/main.yml @@ -30,6 +30,29 @@ register: user_syncthing when: '"syncthing" in groups' +- name: Create Syncthing vault directory + file: + path: "{{ vault_path }}" + state: directory + owner: syncthing + group: vault + mode: "u=rwX,g=rwX,o=" + +- name: Create Syncthing config directory + file: + path: "{{ syncthing_conf_dir }}" + state: directory + owner: syncthing + group: vault + mode: "u=rwX,g=,o=" + +- name: Add unpriviledged user to file management group + user: + name: "{{ username }}" + append: yes + groups: vault + when: '"syncthing" in groups' + - name: Create docker-compose directory ansible.builtin.file: path: "{{ docker_compose_dir }}" diff --git a/roles/containers/templates/docker-compose.yml.j2 b/roles/containers/templates/docker-compose.yml.j2 index 8db9754..b9c816e 100644 --- a/roles/containers/templates/docker-compose.yml.j2 +++ b/roles/containers/templates/docker-compose.yml.j2 @@ -30,3 +30,18 @@ services: - gitea {% endif %} +{% if "syncthing" in group_names %} + syncthing: + network_mode: host + container_name: syncthing + image: syncthing/syncthing + environment: + - PUID={{ user_syncthing.uid }} + - PGID={{ user_syncthing.group }} + restart: unless-stopped + volumes: + - {{ vault_path }}/:/vault + - {{ archive_path }}/:/vault_a + - {{ syncthing_conf_dir }}/:/var/syncthing/config + +{% endif %} diff --git a/roles/syncthing/defaults/main.yaml b/roles/syncthing/defaults/main.yaml new file mode 100644 index 0000000..87ad307 --- /dev/null +++ b/roles/syncthing/defaults/main.yaml @@ -0,0 +1,52 @@ +--- +# these are defaults +# change these in group/host vars + +docker_compose_dir: "/opt/services" + +syncthing_localannounce: true +syncthing_globalannounce: true + +# don't edit 8384 it's hardcoded +syncthing_guiaddress: 127.0.0.1:8384 +syncthing_listen: tcp://0.0.0.0:22000 +syncthing_gui_user: syncthing + +# Paths for Syncthing folders +vault_path: "{{ dataroot }}/syncthing/vault" +archive_path: "{{ dataroot }}/syncthing/vault_a" +syncthing_conf_dir: "{{ dataroot }}/syncthing/config" + +# Put this in the vault in cleartext: the playbook hashes it +syncthing_gui_pass: "" + +# 22 chars for bcrypt +syncthing_gui_salt: "{{ lookup('password', '/dev/null chars=ascii_letters,digit length=22', seed=inventory_hostname) }}" + +# Follows conventions of Syncthing's REST API: see https://docs.syncthing.net/dev/rest.html +# But write in YAML. +syncthing_devices: [] +# - name: "Example Device" +# deviceID: "AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA-AAAAAAA" +# - name: "Main Device" +# deviceID: "BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB-BBBBBBB" +# introducer: true + +# Also follows REST API convention +syncthing_folders: [] +# - label: "Example Folder" +# id: "example" +# path: "/vault/example/" + +# Settings to add to all folders if not specified otherwise +# Separated into default folder settings, and default device settings +# Follows REST API convention +syncthing_defaults: + folder: + devices: "{{ syncthing_devices }}" + versioning: + type: "staggered" + params: + cleanoutDays: "60" + maxAge: "31536000" + device: {} diff --git a/roles/syncthing/handlers/main.yaml b/roles/syncthing/handlers/main.yaml new file mode 100644 index 0000000..5d9957e --- /dev/null +++ b/roles/syncthing/handlers/main.yaml @@ -0,0 +1,5 @@ +- name: Restart syncthing + shell: + chdir: "{{ docker_compose_dir }}" + cmd: "docker compose restart syncthing" + become_user: docker diff --git a/roles/syncthing/tasks/main.yml b/roles/syncthing/tasks/main.yml new file mode 100644 index 0000000..293ecfd --- /dev/null +++ b/roles/syncthing/tasks/main.yml @@ -0,0 +1,113 @@ +- name: Install packages for syncthing + community.general.pacman: + name: + - python-lxml + state: present + +- name: Wait for configuration file to be created + wait_for: + path: "{{ syncthing_conf_dir }}/config.xml" + +- name: Configure globalannounce + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/options/globalAnnounceEnabled" + value: "{{ syncthing_globalannounce | lower}}" + notify: + - Restart syncthing + +- name: Configure localannounce + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/options/localAnnounceEnabled" + value: "{{ syncthing_localannounce | lower}}" + notify: + - Restart syncthing + +- name: Configure listen address + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/options/listenAddress" + value: "{{ syncthing_listen }}" + notify: + - Restart syncthing + +- name: Configure gui address + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/gui/address" + value: "{{ syncthing_guiaddress }}" + notify: + - Restart syncthing + +- name: Configure gui user + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/gui/user" + value: "{{ syncthing_gui_user }}" + notify: + - Restart syncthing + +- name: Configure gui password + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/gui/password" + value: "{{ syncthing_gui_pass | password_hash('bcrypt', syncthing_gui_salt) }}" + notify: + - Restart syncthing + +- name: Warn if gui password is empty + fail: + msg: "Syncthing has no configured password!" + when: syncthing_gui_pass is not defined or syncthing_gui_pass == '' + +- name: Get API key + xml: + file: "{{ syncthing_conf_dir }}/config.xml" + xpath: "/configuration/gui/apikey" + content: text + register: api_key + +- meta: flush_handlers + +- name: Wait for Syncthing API port + wait_for: + port: 8384 + +- name: Delete default Syncthing folder + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/folders/default" + method: DELETE + return_content: yes + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + +- name: Add known syncthing devices + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/devices" + method: PUT + return_content: yes + body_format: json + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + body: "{{ syncthing_devices }}" + +- name: Set default folder settings + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/defaults/folder" + method: PATCH + return_content: yes + body_format: json + body: "{{ syncthing_defaults.folder }}" + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + +- name: Add syncthing folders + uri: + url: "http://{{ syncthing_guiaddress }}/rest/config/folders" + method: PUT + return_content: yes + body_format: json + headers: + X-API-Key: "{{ api_key.matches[0].apikey }}" + body: "{{ syncthing_folders }}" diff --git a/run.yml b/run.yml index 180df8e..590d872 100644 --- a/run.yml +++ b/run.yml @@ -88,6 +88,11 @@ - containers when: '"fleet" in group_names' + - role: syncthing + tags: + - syncthing + when: '"syncthing" in group_names' + - role: dotfiles tags: - dotfiles