519 lines
21 KiB
YAML
519 lines
21 KiB
YAML
- name: Initialize homeserver
|
|
hosts: "{{ chosen_host | default('staging1.test') }}"
|
|
remote_user: "{{ chosen_user | default('senpai') }}"
|
|
vars_files:
|
|
- vars/local_facts.yml # REQUIRED
|
|
- vars/email_settings.yml
|
|
- vars/podpose_settings.yml # REQUIRED
|
|
- vars/source_code.yml # REQUIRED
|
|
- vars/iptables_settings@homeserver.yml
|
|
- vars/caddy_settings.yml
|
|
- vars/certbot_settings@homeserver.yml # REQUIRED
|
|
- vars/mysql_settings.yml
|
|
- vars/redis_settings.yml
|
|
- vars/nextcloud_settings.yml
|
|
- vars/forgejo_settings.yml
|
|
- vars/opengist_settings.yml
|
|
- vars/nodebb_settings.yml
|
|
- vars/syncplay_settings.yml
|
|
- vars/vpn_settings.yml
|
|
- vars/headscale_settings.yml
|
|
- vars/tailscale_settings.yml
|
|
- vars/glance_settings.yml
|
|
- vars/surge_settings.yml
|
|
- vars/aria_settings.yml
|
|
- vars/soulseek_settings.yml
|
|
- vars/flexget_settings.yml # REQUIRED
|
|
- vars/actual_settings.yml
|
|
- vars/kavita_settings.yml
|
|
- vars/stash_settings.yml
|
|
- vars/git_aliases.yml # REQUIRED
|
|
- vars/vim_settings.yml # REQUIRED
|
|
- vars/tor_settings.yml # REQUIRED
|
|
- vars/openpgp_settings.yml # REQUIRED
|
|
- vars/config@{{ inventory_hostname | default('homeserver') }}.yml
|
|
tasks:
|
|
- name: Acquiring home of current user
|
|
when: ansible_facts["system"] == "Linux"
|
|
ansible.builtin.shell:
|
|
cmd: "echo ~{{ ansible_user }}"
|
|
register: ansible_user_home
|
|
- name: Acquiring current user
|
|
when: ansible_facts["system"] == "Linux"
|
|
ansible.builtin.shell:
|
|
cmd: "echo {{ ansible_user }}"
|
|
register: current_user
|
|
- name: Reorganizing userspace package groups into single list
|
|
ansible.builtin.set_fact:
|
|
all_userspace_pkgs: "{{ pkgs | dict2items(key_name='pkg_group', value_name='pkgs') | map(attribute='pkgs') | list | map(attribute='userspace', default='no_userspace') | list | flatten | reject('search', 'no_userspace') | map(attribute='name') | list }}"
|
|
- name: Reorganizing core package groups into single list
|
|
ansible.builtin.set_fact:
|
|
all_core_pkgs: "{{ pkgs | dict2items(key_name='pkg_group', value_name='pkgs') | map(attribute='pkgs') | list | map(attribute='core', default='no_core') | list | flatten | reject('search', 'no_core') | map(attribute='name') | list }}"
|
|
- name: Saving HTTP/(S)FTP credentials
|
|
ansible.builtin.include_role:
|
|
name: init-server
|
|
tasks_from: netrc.yml
|
|
handlers_from: userspace
|
|
- name: Transferring OpenPGP / GPG keyring to managed node
|
|
block:
|
|
- name: Finding GPG keyrings for user
|
|
delegate_facts: true
|
|
delegate_to: localhost
|
|
become: true
|
|
become_user: "{{ local_facts['user_id'] }}"
|
|
ansible.builtin.find:
|
|
paths: "{{ local_facts['user_dir'] }}/.gnupg"
|
|
patterns: ["^pubring\\.kbx$"]
|
|
file_type: file
|
|
use_regex: true
|
|
register: gpg_keys
|
|
- name: Creating user directory for OpenPGP / GPG keyring
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.gnupg"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "700"
|
|
- name: Emitting file content as file in managed node
|
|
become: true
|
|
become_user: "{{ current_user.stdout }}"
|
|
ansible.builtin.copy:
|
|
content: "{{ lookup('file', item.path) }}"
|
|
dest: "{{ ansible_user_home.stdout }}/.gnupg/{{ (((fqdn | default(inventory_hostname)) | split('.'))[:-1] | join('.')) + (idx | string) }}.kbx"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "664"
|
|
force: true
|
|
backup: true
|
|
loop: "{{ gpg_keys.files }}"
|
|
loop_control:
|
|
index_var: idx
|
|
- name: Creating an OpenPGP / GPG batch file for OpenPGP / GPG key pair creation
|
|
become: true
|
|
ansible.builtin.blockinfile:
|
|
path: "/tmp/gpg-key{{ idx | string }}"
|
|
block: |
|
|
Key-Type: {{ item.encryption_method }}
|
|
Key-Length: {{ item.length | string }}
|
|
Subkey-Type: {{ item.primary_subkey.encryption_method }}
|
|
Subkey-Length: {{ item.primary_subkey.length | string }}
|
|
Name-Real: {{ item.name }}
|
|
Name-Comment: {{ item.alias }}
|
|
Name-Email: {{ item.email }}
|
|
Expire-Date: {{ item.expiration }}
|
|
Passphrase: {{ item.password }}
|
|
%pubring pubring.kbx
|
|
%secring trustdb.gpg
|
|
%commit
|
|
%echo GPG key pair created
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
create: true
|
|
backup: true
|
|
loop: "{{ gpg.keypairs }}"
|
|
loop_control:
|
|
index_var: idx
|
|
register: gpg_key_requests
|
|
- name: Creating OpenPGP / GPG key pair
|
|
ansible.builtin.command:
|
|
argv:
|
|
- gpg
|
|
- "--batch"
|
|
- "--gen-key"
|
|
- "/tmp/gpg-key{{ idx | string }}"
|
|
loop: "{{ gpg.keypairs }}"
|
|
loop_control:
|
|
index_var: idx
|
|
- name: Saving OpenPGP / GPG key pair passphrases
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ item.password }}"
|
|
dest: "/tmp/gpg-key-pass{{ idx | string }}"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
loop: "{{ gpg.keypairs }}"
|
|
loop_control:
|
|
index_var: idx
|
|
# @TODO add "show" (debug task module) option task, as counterpart to below fetch module task
|
|
- name: Acquiring the OpenPGP / GPG key pair passphrases
|
|
when: true
|
|
ansible.builtin.fetch:
|
|
src: "/tmp/gpg-key-pass{{ idx | string }}"
|
|
dest: "./.tmp/{{ inventory_hostname }}-openpgp/openpgp.pass{{ idx | string }}"
|
|
flat: true
|
|
loop: "{{ gpg.keypairs }}"
|
|
loop_control:
|
|
index_var: idx
|
|
- name: Installing requisite packages
|
|
ansible.builtin.include_role:
|
|
name: init-server
|
|
tasks_from: userspace@install-pkgs
|
|
handlers_from: userspace
|
|
- name: Configuring aliases for using git
|
|
when: "'git' in all_core_pkgs or 'git' in all_userspace_pkgs"
|
|
community.general.git_config:
|
|
name: "alias.{{ item[0] }}"
|
|
scope: global
|
|
value: "{{ item[1] }}"
|
|
loop: "{{ git_aliases }}"
|
|
- name: Checking presence of dependency for SoulSeek CLI
|
|
when: "('nvm' in all_core_pkgs or 'nvm' in all_userspace_pkgs) and not soulseek.containerized"
|
|
block:
|
|
- name: Installing SoulSeek CLI
|
|
community.general.npm:
|
|
name: "soulseek-cli"
|
|
global: true
|
|
state: present
|
|
- name: Checking presence of dependency for GoCryptFS
|
|
# when: "'gocryptfs' in all_core_pkgs or 'gocryptfs' in all_userspace_pkgs"
|
|
when: false
|
|
block:
|
|
- name: Allowing users ability to allow others for FUSE mount
|
|
become: true
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/fuse.conf
|
|
regexp: "^#user_allow_other"
|
|
insertafter: EOF
|
|
line: "user_allow_other"
|
|
- name: Creating prerequisite directories for GoCryptFS cipher configuration files
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.config/gocryptfs"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "755"
|
|
state: directory
|
|
register: cipher_configs
|
|
- name: Creating prerequisite directories for GoCryptFS XXX cipher
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.ciphers/.xxx"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "755"
|
|
state: directory
|
|
register: xxx_cipher
|
|
- name: Creating password for GoCryptFS XXX cipher
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ lookup('password', './.tmp/' + inventory_hostname + '-xxx@gocryptfs.pass', chars=['ascii_lowercase', 'digits'], length=32) }}"
|
|
dest: /xxx-pass
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
- name: Creating GoCryptFS XXX cipher
|
|
ansible.builtin.command:
|
|
argv:
|
|
- gocryptfs
|
|
- "--init"
|
|
- "--sharedstorage"
|
|
- "--passfile"
|
|
- /xxx-pass
|
|
- "{{ xxx_cipher.path }}"
|
|
register: xxx_master_key
|
|
- name: Creating file containing XXX master key
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ xxx_master_key.stdout }}"
|
|
dest: /tmp/xxx-master-key
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
- name: Copying GoCryptFS XXX cipher configuration file over to corresponding directory
|
|
ansible.builtin.copy:
|
|
src: "{{ ansible_user_home.stdout }}/.ciphers/.xxx/gocryptfs.conf"
|
|
remote_src: true
|
|
dest: "{{ ansible_user_home.stdout }}/.config/gocryptfs/xxx.conf"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
- name: Removing GoCryptFS XXX cipher configuration file
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.ciphers/.xxx/gocryptfs.conf"
|
|
state: absent
|
|
- name: Creating prerequisite directories for XXX downloads cipher
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.ciphers/downloads/.xxx"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "755"
|
|
state: directory
|
|
register: xxx_downloads_cipher
|
|
- name: Creating password for XXX downloads cipher
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ lookup('password', './.tmp/' + inventory_hostname + '-downloads_xxx@gocryptfs.pass', chars=['ascii_lowercase', 'digits'], length=32) }}"
|
|
dest: /xxx-downloads-pass
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
- name: Creating GoCryptFS XXX downloads cipher
|
|
ansible.builtin.command:
|
|
argv:
|
|
- gocryptfs
|
|
- "--init"
|
|
- "--sharedstorage"
|
|
- "--passfile"
|
|
- /xxx-downloads-pass
|
|
- "{{ xxx_downloads_cipher.path }}"
|
|
register: xxx_downloads_master_key
|
|
- name: Creating file containing XXX downloads master key
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ xxx_downloads_master_key.stdout }}"
|
|
dest: /tmp/xxx-downloads-master-key
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
- name: Copying GoCryptFS XXX downloads cipher configuration file over to corresponding directory
|
|
ansible.builtin.copy:
|
|
src: "{{ ansible_user_home.stdout }}/.ciphers/downloads/.xxx/gocryptfs.conf"
|
|
remote_src: true
|
|
dest: "{{ ansible_user_home.stdout }}/.config/gocryptfs/downloads-xxx.conf"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
mode: "600"
|
|
force: true
|
|
backup: true
|
|
- name: Removing GoCryptFS XXX downloads cipher configuration file
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.ciphers/downloads/.xxx/gocryptfs.conf"
|
|
state: absent
|
|
- name: Pausing to inquire about how to proceed
|
|
ansible.builtin.pause:
|
|
prompt: "Type \"fetch\" to get the cipher master keys, or \"show\" to see contents for manual copying instead"
|
|
echo: true
|
|
register: data_method
|
|
- name: Providing XXX cipher master key to control node machine
|
|
when: data_method.user_input == "fetch"
|
|
ansible.builtin.fetch:
|
|
src: /tmp/xxx-master-key
|
|
dest: "./.tmp/{{ inventory_hostname }}-xxx@gocryptfs.key"
|
|
flat: true
|
|
- name: Providing XXX downloads cipher master key to control node machine
|
|
when: data_method.user_input == "fetch"
|
|
ansible.builtin.fetch:
|
|
src: /tmp/xxx-downloads-master-key
|
|
dest: "./.tmp/{{ inventory_hostname }}-downloads_xxx@gocryptfs.key"
|
|
flat: true
|
|
- name: Presenting XXX cipher master key to control node machine
|
|
when: data_method.user_input == "show"
|
|
ansible.builtin.debug:
|
|
msg: "{{ xxx_master_key.stdout }}"
|
|
- name: Presenting XXX downloads cipher master key to control node machine
|
|
when: data_method.user_input == "show"
|
|
ansible.builtin.debug:
|
|
msg: "{{ xxx_downloads_master_key.stdout }}"
|
|
- name: Giving opportunity to manually copy contents of GoCryptFS cipher master keys
|
|
when: data_method.user_input == "show"
|
|
ansible.builtin.pause:
|
|
- name: Creating requisite hidden XXX directory for NSFW video torrent links file
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.xxx"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
# - name: Mounting GoCryptFS XXX cipher
|
|
# ansible.builtin.command:
|
|
# argv:
|
|
# - gocryptfs
|
|
# - "--rw"
|
|
# - "--allow_other"
|
|
# - "--config"
|
|
# - "{{ ansible_user_home.stdout }}/.config/gocryptfs/xxx.conf"
|
|
# - "--passfile"
|
|
# - /xxx-pass
|
|
# - "{{ xxx_cipher.path }}"
|
|
# - "{{ ansible_user_home.stdout }}/.xxx"
|
|
- name: Mounting GoCryptFS XXX cipher
|
|
ansible.posix.mount:
|
|
path: "{{ ansible_user_home.stdout }}/.xxx"
|
|
src: "{{ xxx_cipher.path }}"
|
|
fstype: fuse./usr/bin/gocryptfs
|
|
opts: "rw,allow_other,quiet,config={{ ansible_user_home.stdout }}/.config/gocryptfs/xxx.conf,passfile=/xxx-pass"
|
|
dump: "0"
|
|
passno: "0"
|
|
state: mounted
|
|
- name: Creating requisite hidden file for NSFW video torrent links
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.xxx/.vids.csv"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: touch
|
|
mode: "644"
|
|
- name: Creating requisite hidden XXX download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/.xxx"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
# - name: Mounting GoCryptFS XXX downloads cipher
|
|
# ansible.builtin.command:
|
|
# argv:
|
|
# - gocryptfs
|
|
# - "--rw"
|
|
# - "--allow_other"
|
|
# - "--config"
|
|
# - "{{ ansible_user_home.stdout }}/.config/gocryptfs/downloads-xxx.conf"
|
|
# - "--passfile"
|
|
# - /xxx-downloads-pass
|
|
# - "{{ xxx_downloads_cipher.path }}"
|
|
# - "{{ ansible_user_home.stdout }}/downloads/.xxx"
|
|
- name: Mounting GoCryptFS XXX downloads cipher
|
|
ansible.posix.mount:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/.xxx"
|
|
src: "{{ xxx_downloads_cipher.path }}"
|
|
fstype: fuse./usr/bin/gocryptfs
|
|
opts: "rw,allow_other,quiet,config={{ ansible_user_home.stdout }}/.config/gocryptfs/downloads-xxx.conf,passfile=/xxx-downloads-pass"
|
|
dump: "0"
|
|
passno: "0"
|
|
state: mounted
|
|
- name: Creating requisite hidden download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/.xxx/flexget/vids/torrents"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
- name: Creating requisite hidden download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/.xxx/media/vids"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
- name: Checking presence of dependency for flexget
|
|
when: "('uv' in all_core_pkgs or 'uv' in all_userspace_pkgs) and flexget.enabled and not flexget.containerized"
|
|
block:
|
|
- name: Installing flexget
|
|
become: true
|
|
become_user: "{{ current_user.stdout }}"
|
|
ansible.builtin.command:
|
|
argv:
|
|
- uv
|
|
- tool
|
|
- install
|
|
- "flexget[locked,ftp,sftp]"
|
|
- "--with"
|
|
- pysocks
|
|
- name: Creating requisite download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/media/vids/{{ item }}"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
loop:
|
|
- series
|
|
- features
|
|
- name: Creating requisite download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/flexget/vids/series/torrents"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
- name: Creating requisite download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/flexget/vids/torrents"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
- name: Creating requisite hidden download paths
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/media/vids/{{ item }}"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
loop:
|
|
- series
|
|
- features
|
|
- name: Creating requisite hidden file for film torrent links
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/downloads/media/vids/features/.films.csv"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: touch
|
|
mode: "644"
|
|
- name: Creating requisite directory for NSFW video torrent links file
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.xxx"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
- name: Creating requisite directory for flexget
|
|
ansible.builtin.file:
|
|
path: "{{ ansible_user_home.stdout }}/.flexget"
|
|
recurse: true
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
state: directory
|
|
mode: "755"
|
|
- name: Configuring flexget
|
|
become: true
|
|
become_user: "{{ current_user.stdout }}"
|
|
ansible.builtin.template:
|
|
src: roles/init-server/templates/user/flexget/config.yml.j2
|
|
variable_start_string: "<<"
|
|
variable_end_string: ">>"
|
|
dest: "{{ ansible_user_home.stdout }}/.flexget/config.yml"
|
|
owner: "{{ ansible_user }}"
|
|
group: "{{ ansible_user }}"
|
|
force: true
|
|
backup: true
|
|
# validate: "flexget check"
|
|
- name: Creating a CRON job for flexget
|
|
ansible.builtin.cron:
|
|
name: Run flexget
|
|
minute: "*/60"
|
|
hour: "4-15"
|
|
weekday: "1-5"
|
|
job: "{{ ansible_user_home.stdout }}/.local/bin/flexget --cron execute"
|
|
- name: Configure installed packages
|
|
ansible.builtin.meta: flush_handlers
|
|
- name: Disabling root user shell login
|
|
become: true
|
|
ansible.builtin.user:
|
|
name: root
|
|
shell: /sbin/nologin
|
|
tags:
|
|
- disable_root_shell
|
|
- name: Disable login for root user altogether
|
|
become: true
|
|
ansible.builtin.user:
|
|
name: root
|
|
password: "'*'"
|
|
tags:
|
|
- disable_root_login
|
|
|