Compare commits
89
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3208cd0b09
|
||
|
|
e5f178e583
|
||
|
|
1accba1566
|
||
|
|
101c1cc0aa
|
||
|
|
a367b3c5e4
|
||
|
|
673e318824
|
||
|
|
71261e4017
|
||
|
|
9fb64cef30
|
||
|
|
29d4f33a46
|
||
|
|
80fd0ebb09
|
||
|
|
a4d46ada94
|
||
|
|
e04ed6f273
|
||
|
|
d44c67df42
|
||
|
|
7574b8f9b4
|
||
|
|
aa590effb2
|
||
|
|
5d1e073470
|
||
|
|
c7b1d2d30b
|
||
|
|
ba7283b583
|
||
|
|
1060724cf8
|
||
|
|
aae7b50c8d
|
||
|
|
36b293f923
|
||
|
|
7e1c8c3f46
|
||
|
|
c9ceb8e9cf
|
||
|
|
26eb7b38b9
|
||
|
|
35a2f98fc0
|
||
|
|
e53d6255e0
|
||
|
|
e8b29bb8e8
|
||
|
|
aa8d61aa09
|
||
|
|
2d6dcd3dab
|
||
|
|
2c66c3bd43
|
||
|
|
20d1cd21a3
|
||
|
|
83fa171341
|
||
|
|
240efbb713
|
||
|
|
bcf9eaebc9
|
||
|
|
125ec09c8f
|
||
|
|
b784b781d3
|
||
|
|
909682d74e
|
||
|
|
bd3029b914
|
||
|
|
57a3e876b8
|
||
|
|
1ce6879abf
|
||
|
|
9ea7fb37b0
|
||
|
|
7584027890
|
||
|
|
a78613920c
|
||
|
|
0dd0633166
|
||
|
|
9945330b82
|
||
|
|
f4399a2c8a
|
||
|
|
596b828e6f
|
||
|
|
13ef8fa459
|
||
|
|
52f98c1d57
|
||
|
|
c0d0203406
|
||
|
|
889b06bf21
|
||
|
|
5bfde90be9
|
||
|
|
f592a56c60
|
||
|
|
fc95904327
|
||
|
|
f43e420f66
|
||
|
|
a6fc067eb1
|
||
|
|
44c343dd7b
|
||
|
|
8894bd8925
|
||
|
|
7daf57da64
|
||
|
|
dc8dbcc43e
|
||
|
|
a4c26fd9c3
|
||
|
|
cf7612365a
|
||
|
|
3343f7ad69
|
||
|
|
7268245bb7
|
||
|
|
555c7d0a6a
|
||
|
|
5049210e25
|
||
|
|
0d7b0f0c66
|
||
|
|
691d85458e
|
||
|
|
8e1f5c6743
|
||
|
|
1fed9cf441
|
||
|
|
f5fa460e44
|
||
|
|
9d80fbb567
|
||
|
|
3fe4d9d5a2
|
||
|
|
17a921b551
|
||
|
|
ac4af5de3d
|
||
|
|
f455483d66
|
||
|
|
9942fd94f8
|
||
|
|
9d33b45dbc
|
||
|
|
0cee2cbb79
|
||
|
|
50c7b6a56d
|
||
|
|
fc565fa3ce
|
||
|
|
c31acb2dcc
|
||
|
|
55a5e956d4
|
||
|
|
a16351985f
|
||
|
|
ac1eb31926
|
||
|
|
19929405ba
|
||
|
|
f54545b1dd
|
||
|
|
4074eacb1f
|
||
|
|
af9fc3b4ca
|
+4
-2
@@ -4,10 +4,10 @@
|
|||||||
/hosts.yml
|
/hosts.yml
|
||||||
/hosts.yaml
|
/hosts.yaml
|
||||||
/hosts.json
|
/hosts.json
|
||||||
*.bak
|
uv.lock
|
||||||
/init@homeserver.yml
|
|
||||||
|
|
||||||
# Ansible runtime and backups
|
# Ansible runtime and backups
|
||||||
|
*.bak
|
||||||
*.original
|
*.original
|
||||||
*.tmp
|
*.tmp
|
||||||
/.tmp/
|
/.tmp/
|
||||||
@@ -20,12 +20,14 @@
|
|||||||
/.devcontainer/
|
/.devcontainer/
|
||||||
.lock
|
.lock
|
||||||
/.cache/
|
/.cache/
|
||||||
|
/roles/**/files/user/wg/containerized/*.conf
|
||||||
|
|
||||||
# Try tyo avoid any plain-text passwords
|
# Try tyo avoid any plain-text passwords
|
||||||
*pwd*
|
*pwd*
|
||||||
*pass*
|
*pass*
|
||||||
*password*
|
*password*
|
||||||
*secret*
|
*secret*
|
||||||
|
*.key
|
||||||
roles/**/vars/*
|
roles/**/vars/*
|
||||||
roles/**/vars/**
|
roles/**/vars/**
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,229 @@
|
|||||||
|
# SKATO ANSIBLE
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Make sure you have `git`, `venv`, and `uv` installed. On GNU/Linux Debian-based distros with pre-installed `apt` package manager, the corresponding packages are:
|
||||||
|
|
||||||
|
- `git`
|
||||||
|
- `python3-venv`
|
||||||
|
- [Follow this guide](https://docs.astral.sh/uv/getting-started/installation/) for installing `uv`
|
||||||
|
|
||||||
|
Ansible must also be installed on your system (see [this guide](https://docs.ansible.com/projects/ansible/latest/installation_guide/index.html)). Then, in your interactive bash shell session, run the following in order:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.sukaato.moe/admin/skato-ansible.git
|
||||||
|
cd ./skato-ansible
|
||||||
|
uv venv .venv
|
||||||
|
uv sync
|
||||||
|
source .venv/bin/activate
|
||||||
|
ansible-galaxy collections install -r ./collections/requirements.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Essential Background
|
||||||
|
|
||||||
|
### Software Management
|
||||||
|
|
||||||
|
The standard use-case, which we call the container routing case, of this Ansible library is to run its playbooks in such a way that one host ends up acting as a router (via VPN service) to services on another host.
|
||||||
|
|
||||||
|
In the container routing case these services are defined by a repository declared in `${ANSIBLE_PROJECT_ROOT}/vars/source_code.yml`, via setting `source_code.repos.compose.name` and `source_code.repos.compose.rpath`, respectively, to the name of a version-controlled source repository and to a desired path within that repository (that path written such that it treats the repository path as root, i.e. as `/`).
|
||||||
|
|
||||||
|
As can then be noted, the `source_code` dictionary holds an attribute `repos` with itself attributes of fixed name representing various services or utilities, each of whom must have a `name` attribute defined that represents the name of the corresponding version-controlled source repository for that service or utility.
|
||||||
|
|
||||||
|
The point of this set-up is to allow the repository name at its endpoint to change without requiring manual changes in the code using or deploying that repository as consequence. One unfortunate result of this is that adding a service or utiltiy from one's git bare repositories means making manual corresponding changes in `pkgs` software object groups in relevant [host variable files](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables), in `${ANSIBLE_PROJECT_ROOT}/roles/init-server/handlers/{core,userspace}.yml` for calling installation or post-installation actions, and in `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/${SOFTWARE_NAME}.yml` for executing those actions. The convention is for [handler](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) [notifiers](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers), [handler](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) [listeners](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers) and software names to all be equivalent, though the software name can deviate from this relational pattern.
|
||||||
|
|
||||||
|
Importantly, the following top-level attributes of the `source_code` variable or dictionary are necessary if your version-controlled source repository source requires authentication:
|
||||||
|
|
||||||
|
- `host`
|
||||||
|
- `user`/`ssh_user`
|
||||||
|
- `http_password`/`ssh_password`
|
||||||
|
|
||||||
|
If you wish to be able to use both SSH and HTTP authentication methods for the version-controlled source repository or change the default preference for HTTP credential use, you may edit `${ANSIBLE_PROJECT_ROOT}/roles/init-server/templates/user/netrc.j2`. See [the CURL docuemntation for more information on the NetRC file format](https://everything.curl.dev/usingcurl/netrc.html).
|
||||||
|
|
||||||
|
The point of the `source_code` dictionary is that it allows plugging in and executing custom code from one's own source repositories.
|
||||||
|
|
||||||
|
All other software is simply handled through the aforementioned patttern of adding an entry to any of the following in a given [host variables file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables):
|
||||||
|
|
||||||
|
- `pkgs.mngr.core` or `pkgs.mngr.userspace` (software installed by package manager--in this case, `apt` as most tasks assume a Linux Debian system at Ansible's managed node)
|
||||||
|
- `pkgs.script.core` or `pkgs.script.userspace` (since different installation shell scripts allow for different parameters, entries for installation shell scripts here are downloaded--for actual installation, the script has to be ran in a set of tasks specified in a YAML file under `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/`)
|
||||||
|
- `pkgs.archive.core` or `pkgs.archive.userspace` (similar as before, except things like path movement or specification, building/compilation, etc., are what take place via the set of tasks specified under the YAML file under `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/`)
|
||||||
|
- `pkgs.git_repos.core` or `pkgs.git_repos.userspace` (similar as before, fulfilling any arbitrary set of specified tasks for the pulled git source repository--you get the point)
|
||||||
|
|
||||||
|
Each entry item must have a `handler` attribute whose value will be used to [notify](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers) a [handler](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) [listener](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_handlers.html#notifying-handlers), whose `listen` attribute has that same value, that then includes tasks found in a YAML file under `${ANSIBLE_PROJECT_ROOT}/roles/init-server/tasks/contingent/pkg/` whose basename, conventionally, is the same as those `handler` and `listen` attribute values. All of which, again, also conventionally share the same value as the `name` attribute of the entry item.
|
||||||
|
|
||||||
|
The structure of entries within each `pkgs.${SOFTWARE_GROUP}.core`/`pkgs.${SOFTWARE_GROUP}.userspace` depends on `$SOFTWARE_GROUP` because it changes the semantics of installation. All entries are dictionary items.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> A table will be added at a later date, covering the attributes of the dictionary items for each `$SOFTWARE_GROUP`. For now, the [host variable files](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) for the staging hosts found in the [YAML inventory file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html) can be used as reference.
|
||||||
|
|
||||||
|
### Configuration Management
|
||||||
|
|
||||||
|
#### System Configuration
|
||||||
|
|
||||||
|
The most important configuration is that needed for each host. This involves software installation, though [that is already covered in the above section](#software-management). Other important [host variables](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) for any given [host variable file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) are:
|
||||||
|
|
||||||
|
variable name | type | default | semantics
|
||||||
|
--- | --- | --- | ---
|
||||||
|
`password` | `str` | auto-generated | the hashed password for the root user if the managed node had not spawned prior to playbook run
|
||||||
|
`ssh_keys` | `list` | `["ed25519@staging", "ecdsa@staging"]` | the basenames of the SSH key pairs for the root user
|
||||||
|
`admins` | `list` | `[{"username": "senpai", "services": None, "ssh_keys": ["ed25519@staging", "ecdsa@staging"], "password": ""} for d in admins]` | the list of Linux superusers, i.e. administrators, to exist
|
||||||
|
`token` | `str` | `None` | API key for cloud hosting account to spawn a VPS
|
||||||
|
`origin` | `str` | `us-east` | region or location of the VPS to determine timezones and locale; useful for Akamai Linode cloud hosting
|
||||||
|
`operating_system` | `str` | `None` | name or path to operating system for cloud hosted VPS or a VM / bare metal system
|
||||||
|
|
||||||
|
#### Software Configuration
|
||||||
|
|
||||||
|
Other configuration involves Ansible role templates or files, e.g. those found in `${ANSIBLE_PROJECT_ROOT}/roles/init-server/{templates,files}`. Generally, these Ansible role templates or files are sent over to the Ansible managed node by tasks provided by that same role, and referred to by tasks in the [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html).
|
||||||
|
|
||||||
|
The convention for templates is to set some desired though non- software native "defaults" and leave some settings or values to variables, grouped by the software for which they are relevant into variable files in `${ANSIBLE_PROJECT_ROOT}/vars/`, or what we may call the [playbook variable files](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-in-included-files-and-roles). These YAML variable files by convention have as their basename `${SOFTWARE_NAME}_settings` (with some exceptions), and must be listed (as paths relative to `$ANSIBLE_PROJECT_ROOT`) under `vars_files` on the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) that will be running the tasks/[handlers](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables), native to itself or taken from a role, that send the respective files or (after processing) templates over to the managed Ansible node(s). These kinds of files shall be called "settings files."
|
||||||
|
|
||||||
|
Inside each such settings file, the convention is for there to be a top-level variable (i.e., a single variable that takes a dictionary value) with a name of `$SOFTWARE_NAME`, whose value has attributes representing configuration options for the given software.
|
||||||
|
|
||||||
|
Some common, shared attributes for settings files are:
|
||||||
|
|
||||||
|
attribute name | type | default value | required? | semantics
|
||||||
|
--- | --- | --- | --- | ---
|
||||||
|
`containerized` | `bool` | `True` | only for services or software that is service-capable | determines whether the configuration is for a containerized or base system install
|
||||||
|
`mode` | `str` | "prod" | no | usefully allows for setting the mode for an individual piece of software rather than having it automatically agree with [the playbook mode](#essential-usage) or having it assume production mode
|
||||||
|
|
||||||
|
Other common ones, especially for services, are `port` (which can be an integer or string) and--for web servers--`scheme` (which can be either string "http" or "https", serving to toggle SSL/TLS DNS authentication for HTTP connections). These can exist at any nesting level under the top-level dictionary, based on the feature scope of the given software.
|
||||||
|
|
||||||
|
## Essential Usage
|
||||||
|
|
||||||
|
Before running any Ansible [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) in either development or production mode, make sure to specify the username and the home directory path of the user on the system you are currently using in `{ANSIBLE_PROJECT_ROOT}/vars/local_facts.yml`.
|
||||||
|
|
||||||
|
### Development Mode
|
||||||
|
|
||||||
|
For development purposes in the container routing case, either first manually set up two Debian virtual machines, or (**recommended**) change into the `${ANSIBLE_PROJECT_ROOT}/staging0.test/` directory then `${ANSIBLE_PROJECT_ROOT}/staging1.test/` directory, running `vagrant up` for each. Running the [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) in development mode also requires supplying "dev" as an argument for the extra `mode` parameter.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Vagrantfiles for neither staging host has yet been tested. Proceed by your own discretion.
|
||||||
|
|
||||||
|
If you intend to run the [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) in production, the argument for this extra parameter should be "prod" (skip to the [Production Mode](#production-mode) section). The additional extra parameter of `chosen_host` should be adjusted to reflect the name of the host enlisted in the [YAML inventory file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html) for production purposes.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> The names of hosts should be equivalent to their intended final domain name for services on any given host for the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) to work correctly.
|
||||||
|
|
||||||
|
Anyway, for *any* mode double-check that the correct values are set for `chosen_user`. The first playbook you run for each host or IP in each pair of `ansible-playbook` commands in the upcoming shell script should always have `chosen_user` as "root". The extra parameter `chosen_user` for the second `ansible-playbook` command of each pair of `ansible-playbook` commands shown below should take an argument whose value is the same as that of the `username` attribute of any of the items in the `admins` list in the [host variables file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) for the given host. With that in mind, execute the below for development mode for container routing case while in the `$ANSIBLE_PROJECT_ROOT` directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SSH_KEYS=()
|
||||||
|
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" init\@vps.yml
|
||||||
|
$SSH_KEYS | xargs -I %k ssh-add %k # ADD NEEDED SSH KEY FILEPATHS
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" administrate\@vps.yml
|
||||||
|
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" init\@homeserver.yml
|
||||||
|
# UNCOMMENT BELOW TO REASSIGN ENVIRONMENT VARIABLE FOR NEW ARRAY OF SSH KEYPAIR FILEPATHS
|
||||||
|
# SSH_KEYS=()
|
||||||
|
# UNCOMMENT BELOW TO ADD UPDATED SSH KEY PAIR FILEPATHS TO SSH_AGENT
|
||||||
|
# $SSH_KEYS | xargs -I %k ssh-add %k
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" administrate\@homeserver.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> In the container routing case, development mode may not supply an accurate test of the intended networking result if the virtual machines for staging were manually created, but the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) should run successfully. This is because apppropriate networking must be set for the virtual machine itself for VPN client containers in one virtual machine to "speak" with the VPN server in another virtual machine. The supplied Vagrantfiles are a WIP.
|
||||||
|
|
||||||
|
### Production Mode
|
||||||
|
|
||||||
|
Its important to note that the above shell script example for development mode would have to be modified in production mode for the container routing case such that every `ansible-playbook` call instance has its extra parameter `chosen_host` share the same value throughout. This is due to the combination of how SSL/TLS and domain names are set up in the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) and the requirements of the container routing case. Namely, the former treats the inventory hostname used for the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) as the [fully qualified domain name](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) of that server host, while the container routing case requires that both server hosts share that [fully qualified domain name](https://en.wikipedia.org/wiki/Fully_qualified_domain_name).
|
||||||
|
|
||||||
|
This means that `chosen_host`'s value being the same across all `ansible-playbook` commands does not mean that value should represent the same managed node or host [IP](https://en.wikipedia.org/wiki/IP_address) throughout. Whether it does so is of course determined by whatever is in the [YAML inventory file](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html), so that would need to be changed when running [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) against the second chosen host in the container routing case.
|
||||||
|
|
||||||
|
To drive all that home, in production we may instead need something like the following (again, executed while in the `$ANSIBLE_PROJECT_ROOT` directory):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SSH_KEYS=()
|
||||||
|
HOST_FQDN=web.site # a fully qualified domain name you own
|
||||||
|
CURRENT_IP= # whatever the current IP of the host $HOST_FQDN is
|
||||||
|
UPDATED_IP= # the desired new IP for the host $HOST_FQDN
|
||||||
|
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=root" --extra-vars "mode=prod" init\@vps.yml
|
||||||
|
$SSH_KEYS | xargs -I %k ssh-add %k # ADD NEEDED SSH KEY PAIR FILEPATHS TO SSH_AGENT
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=senpai" --extra-vars "mode=prod" administrate\@vps.yml
|
||||||
|
|
||||||
|
sed '/'"$HOST_FQDN"':{N;s/'"$HOST_FQDN"':\n {6}ansible_host: '"$CURRENT_IP"'/'"$HOST_FQDN"':\n ansible_host: '"$NEW_IP"'/g}' hosts.yml
|
||||||
|
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=root" --extra-vars "mode=prod" init\@homeserver.yml
|
||||||
|
# UNCOMMENT BELOW TO REASSIGN ENVIRONMENT VARIABLE FOR NEW ARRAY OF SSH KEYPAIR FILEPATHS
|
||||||
|
# SSH_KEYS=()
|
||||||
|
# UNCOMMENT BELOW TO ADD UPDATED SSH KEY PAIR FILEPATHS TO SSH_AGENT
|
||||||
|
# $SSH_KEYS | xargs -I %k ssh-add %k
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${HOST_FQDN}" --extra-vars "chosen_user=senpai" --extra-vars "mode=prod" administrate\@homeserver.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
**There *is* a way to avoid reassigning the IP address of the shared inventory hostname for each host the pair of playbooks is being run against in the container routing case under production.** This involves defining `fqdn` as a playbook variable or as an extra parameter for all `ansible-playbook` commands in the shell script, resulting in a shell script that looks more similar to our [development mode shell script](#development-mode):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SSH_KEYS=()
|
||||||
|
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" init\@vps.yml
|
||||||
|
$SSH_KEYS | xargs -I %k ssh-add %k # ADD NEEDED SSH KEY FILEPATHS
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging0.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" administrate\@vps.yml
|
||||||
|
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=root" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" init\@homeserver.yml
|
||||||
|
# UNCOMMENT BELOW TO REASSIGN ENVIRONMENT VARIABLE FOR NEW ARRAY OF SSH KEYPAIR FILEPATHS
|
||||||
|
# SSH_KEYS=()
|
||||||
|
# UNCOMMENT BELOW TO ADD UPDATED SSH KEY PAIR FILEPATHS TO SSH_AGENT
|
||||||
|
# $SSH_KEYS | xargs -I %k ssh-add %k
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=staging1.test" --extra-vars "chosen_user=senpai" --extra-vars "mode=dev" --extra-vars "fqdn=web.site" administrate\@homeserver.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Adding the extra parameter here to the `ansible-playbook` commands of the development mode execution for the container routing use-case may also improve the realism of its execution and final state, virtual machine network configurations notwithstanding. Consider doing so for more realistic networking tests under the container routing case.
|
||||||
|
|
||||||
|
### Custom Playbooks
|
||||||
|
|
||||||
|
As long as you are matching the appropriate set of [playbook variable files](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_variables.html#defining-variables-in-included-files-and-roles) or settings files with the [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) according to its need of those variable definitions/declarations, mostly determined by [the intended targeted hosts' own variables](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables) together with role [handlers](https://docs.ansible.com/projects/ansible/latest/inventory_guide/intro_inventory.html#host-variables), and as long as you have appropriately set up software installations, (see [Software Management](#software-management)) creating new/custom [playbooks](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) should be relatively easy.
|
||||||
|
|
||||||
|
Depending on what you are trying to do with a new [playbook](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html), the best approach may be to just copy/duplicate the extant [playbook files](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html) and then edit them, as this allows one to mitigate errors as well as have a reliable reference point for changes.
|
||||||
|
|
||||||
|
### CLI Tool
|
||||||
|
|
||||||
|
As an alternative, you can use the `skato-ansible` shell script in `$ANSIBLE_PROJECT_ROOT` as an abstraction of the `ansible-playbook` commands for the container routing case. I plan to replace it with a CLI app covering more intended use-cases.
|
||||||
|
|
||||||
|
When using the `skato-ansible.sh` script in development mode for the container routing use case:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
./skato-ansible.sh init vps -v 3 -m dev -n staging0.test
|
||||||
|
./skato-ansible.sh populate-agent staging
|
||||||
|
./skato-ansible.sh bootstrap vps -s 1 -v 3 -m dev -n staging0.test
|
||||||
|
|
||||||
|
./skato-ansible.sh init homeserver -v 3 -m dev -n staging1.test
|
||||||
|
# BELOW ONLY IF $SKANSIBLE_SSH_KEY ALTERED IN THE SHELL SCRIPT
|
||||||
|
# ./skato-ansible.sh populate-agent staging
|
||||||
|
./skato-ansible.sh bootstrap vps -s 1 -v 3 -m dev -n staging1.test
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise, in production mode:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
INVENTORY_HOSTNAMES=(web1 web2)
|
||||||
|
FQDN=web.site
|
||||||
|
|
||||||
|
./skato-ansible.sh init vps -v 3 -n "${INVENTORY_HOSTNAMES[0]}" -d "$FQDN"
|
||||||
|
./skato-ansible.sh populate-agent staging
|
||||||
|
./skato-ansible.sh bootstrap vps -s 1 -v 3 -n "${INVENTORY_HOSTNAMES[0]}" -d "$FQDN"
|
||||||
|
|
||||||
|
./skato-ansible.sh init homeserver -v 3 -n "${INVENTORY_HOSTNAMES[1]}" -d "$FQDN"
|
||||||
|
# BELOW ONLY IF $SKANSIBLE_SSH_KEY ALTERED IN THE SHELL SCRIPT
|
||||||
|
# ./skato-ansible.sh populate-agent staging
|
||||||
|
./skato-ansible.sh bootstrap vps -s 1 -v 3 -n "${INVENTORY_HOSTNAMES[1]}" -d "$FQDN"
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> If you have different SSH keypairs for staging, make sure to change the value of `SKANSIBLE_SSH_KEYS` environment variable in the `${ANSIBLE_PROJECT_ROOT}/skato-ansible.sh` shell script before running the above shell scripts from `$ANSIBLE_PROJECT_ROOT`.
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
- name: Initialize homeserver
|
||||||
|
hosts: "{{ chosen_host | default('staging1.test') }}"
|
||||||
|
remote_user: "{{ chosen_user | default('senpai') }}"
|
||||||
|
vars_files:
|
||||||
|
- vars/email_settings.yml
|
||||||
|
- vars/podpose_settings.yml # REQUIRED
|
||||||
|
- vars/source_code.yml # REQUIRED
|
||||||
|
- vars/caddy_settings.yml
|
||||||
|
- vars/certbot_settings@homeserver.yml # REQUIRED
|
||||||
|
- vars/mysql_settings.yml
|
||||||
|
- vars/redis_settings.yml
|
||||||
|
- vars/nextcloud_settings.yml
|
||||||
|
- vars/gitea_settings.yml
|
||||||
|
- vars/opengist_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/flexget_settings.yml # REQUIRED
|
||||||
|
- vars/git_aliases.yml # REQUIRED
|
||||||
|
- vars/vim_settings.yml # REQUIRED
|
||||||
|
- vars/tor_settings.yml # REQUIRED
|
||||||
|
- vars/config@{{ inventory_hostname | default('homeserver') }}.yml
|
||||||
|
tasks:
|
||||||
|
- name: Saving HTTP/(S)FTP credentials
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: netrc.yml
|
||||||
|
handlers_from: userspace
|
||||||
|
- name: Installing requisite packages
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: userspace@install-pkgs
|
||||||
|
handlers_from: userspace
|
||||||
|
- 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: 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
|
||||||
|
- 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') | 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') | list }}"
|
||||||
|
- 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 flexget
|
||||||
|
when: "'uv' in all_core_pkgs and flexget.enabled"
|
||||||
|
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 }}/downloads/flexget/vids/{{ item }}/torrents"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
mode: "755"
|
||||||
|
loop:
|
||||||
|
- series
|
||||||
|
- 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/.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/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 }}/media/vids/{{ item }}.csv"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: touch
|
||||||
|
mode: "644"
|
||||||
|
loop:
|
||||||
|
- features/.films
|
||||||
|
- 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: Creating requisite hidden file for NSFW video torrent links
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.xxx/.{{ item }}.csv"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: touch
|
||||||
|
mode: "644"
|
||||||
|
loop:
|
||||||
|
- vids
|
||||||
|
- name: Configuring flexget
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: 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: Checking presence of dependency
|
||||||
|
when: "'nvm' in all_core_pkgs or 'nvm' in all_userspace_pkgs"
|
||||||
|
block:
|
||||||
|
- name: Installing SoulSeek CLI
|
||||||
|
community.general.npm:
|
||||||
|
name: "soulseek-cli"
|
||||||
|
global: true
|
||||||
|
state: present
|
||||||
|
- name: Opening port 51820
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 51820
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 51820
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening port 443
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 443
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 443
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening ports
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: "{{ item }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: "Open up port {{ (item | string) }}"
|
||||||
|
loop:
|
||||||
|
- 80
|
||||||
|
- 465
|
||||||
|
- 587
|
||||||
|
- 995
|
||||||
|
- 993
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
- name: Initialize VPS
|
||||||
|
hosts: "{{ chosen_host | default('staging0.test') }}"
|
||||||
|
remote_user: "{{ chosen_user | default('senpai') }}"
|
||||||
|
vars_files:
|
||||||
|
- vars/surge_settings.yml
|
||||||
|
- vars/git_aliases.yml # REQUIRED
|
||||||
|
- vars/vim_settings.yml # REQUIRED
|
||||||
|
- vars/podpose_settings.yml # REQUIRED
|
||||||
|
- vars/certbot_settings.yml # REQUIRED
|
||||||
|
- vars/config@{{ inventory_hostname | default('vps') }}.yml
|
||||||
|
tasks:
|
||||||
|
- name: Installing requisite packages
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: userspace@install-pkgs
|
||||||
|
handlers_from: userspace
|
||||||
|
- 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
|
||||||
|
# - name: Debugging
|
||||||
|
# ansible.builtin.debug:
|
||||||
|
# msg: "{{ 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') | list }}"
|
||||||
|
# - name: Prematurely ending play
|
||||||
|
# ansible.builtin.meta: end_play
|
||||||
|
- 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') | 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') | list }}"
|
||||||
|
- name: Configuring aliases for using git
|
||||||
|
when: "'git' in all_core_pkgs"
|
||||||
|
community.general.git_config:
|
||||||
|
name: "alias.{{ item[0] }}"
|
||||||
|
scope: global
|
||||||
|
value: "{{ item[1] }}"
|
||||||
|
loop: "{{ git_aliases }}"
|
||||||
|
- name: Opening port 51820
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 51820
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 51820
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening port 443
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 443
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 443
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening ports
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: "{{ item }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: "Open up port {{ (item | string) }}"
|
||||||
|
loop:
|
||||||
|
- 80
|
||||||
|
- 465
|
||||||
|
- 587
|
||||||
|
- 995
|
||||||
|
- 993
|
||||||
+1
-1
@@ -508,7 +508,7 @@ pipelining=False
|
|||||||
# (int) For keys inserted into an agent defined by ``SSH_AGENT``, define a lifetime, in seconds, that the key may remain in the agent.
|
# (int) For keys inserted into an agent defined by ``SSH_AGENT``, define a lifetime, in seconds, that the key may remain in the agent.
|
||||||
;ssh_agent_key_lifetime=
|
;ssh_agent_key_lifetime=
|
||||||
|
|
||||||
ssh_args='-o ControlMaster=auto -o ControlPersist=300s -o PreferredAuthentications=publickey'
|
ssh_args='-o ControlMaster=auto -o ControlPersist=300s -o PreferredAuthentications=publickey -o ForwardAgent=yes'
|
||||||
|
|
||||||
|
|
||||||
[colors]
|
[colors]
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
---
|
---
|
||||||
collections:
|
collections:
|
||||||
|
- name: community.general
|
||||||
|
version: "12.6.1"
|
||||||
- name: linode.cloud
|
- name: linode.cloud
|
||||||
version: "0.46.0"
|
version: "0.46.0"
|
||||||
|
- name: containers.podman
|
||||||
|
version: "1.20.1"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
ansible-playbook --ask-pass --ask-become-pass -i hosts.yml init@homeserver.yml --check
|
|
||||||
@@ -1,340 +0,0 @@
|
|||||||
# @TODO create inventory group variables akin to structure of sukaato group's for homeserver
|
|
||||||
# <str<vault>> representing password for Linux root user account of VPS
|
|
||||||
password: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
32333335343939653231313938666134306338356633393035363039373465386165313666383262
|
|
||||||
6465313738316635633332623765336563626165336330370a616634393266366430363663333066
|
|
||||||
63373165346236386632393866316164623133373761303262643734356433646661636533666266
|
|
||||||
3834643765613937300a326365643961626236386261303933643965333565623836313231346537
|
|
||||||
3030
|
|
||||||
# <str> representing hostname for LAN server; same as host or group variable name
|
|
||||||
instance: armitage
|
|
||||||
# <str<enum>> representing Linux distro or OS image to be used for VPS
|
|
||||||
# operating_system: "tftp://hikiki.local:69/debian.iso"
|
|
||||||
operating_system: ~
|
|
||||||
# <list[<str>]> of control node or local SSH key basenames
|
|
||||||
ssh_keys:
|
|
||||||
- ed25519@sukaato.hikiki
|
|
||||||
- ecdsa@sukaato.hikiki
|
|
||||||
# <list<dict>> list of administrative users (in Linux, users that can use "sudo")
|
|
||||||
admins:
|
|
||||||
- username: admin # <str> arbitrary valid user name
|
|
||||||
services: ~ # <list[<str>]> if linux system user, assocated servce
|
|
||||||
# <list[<str>]> list of control node or local SSH key basenames for this user
|
|
||||||
ssh_keys:
|
|
||||||
- ecdsa-37851076-sk@sukaato.hikiki
|
|
||||||
- ecdsa-37851072-sk@sukaato.hikiki
|
|
||||||
# <str<vault?>> hashed (and maybe salted) password
|
|
||||||
password: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
31663265653031323833373663653132653532646638316465393364613961643130653330393062
|
|
||||||
6165386239303965386261363565353137636164356130370a336465353931373564393339363561
|
|
||||||
37353162333331663833656631663165356134633961323337663439663733316231666334336539
|
|
||||||
6537373334326634610a623037613462663733343230306538386561363838316638623365636533
|
|
||||||
32313931666439363435663161663665346266653763343265376366383837376436643163376430
|
|
||||||
39393861613037333766386138376335653334363737626664383236303234653461313230383564
|
|
||||||
33393834636165386562383435666233313664656233326364616237636230303264363732376639
|
|
||||||
64396564366335366430303031323865333635306536346463386334303235386438663061343934
|
|
||||||
37376466373566396130366330383834323332626166316661336339346462343466
|
|
||||||
# @TODO change 'key' attributes of package entres under 'mngr' section below to 'signkey'
|
|
||||||
# and edit 'roles/init-server/install-pks.yml' accordngly
|
|
||||||
# <dict[<str>:<dict>]> package groups
|
|
||||||
pkgs:
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by package manager via repositories
|
|
||||||
mngr:
|
|
||||||
# <list[<dict>]> representing system-level or essential packages
|
|
||||||
core:
|
|
||||||
- name: neovim
|
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: flatpak
|
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: snapd
|
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: git
|
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: fail2ban
|
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: crowdsec
|
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: glow
|
|
||||||
uri: ~
|
|
||||||
sigkey: "https://repo.charm.sh/apt/gpg.key"
|
|
||||||
sources: "https://repo.charm.sh/apt/"
|
|
||||||
types: deb
|
|
||||||
suites: "*"
|
|
||||||
comps: "*"
|
|
||||||
- name: vim-vimwiki
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: pandoc
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: tor
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: i2pd
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
# # @TODO troubleshoot radicle installation issue or change installation method for radicle to script
|
|
||||||
# - name: radicle-keyring
|
|
||||||
# uri: "https://radicle.dev/apt/radicle-archive-keyring.deb"
|
|
||||||
# sigkey: ~
|
|
||||||
# sources: ~
|
|
||||||
# types: ~
|
|
||||||
# suites: ~
|
|
||||||
# comps: ~
|
|
||||||
# - name: radicle
|
|
||||||
# uri: ~
|
|
||||||
# sigkey: "https://radicle.dev/apt/radicle-archive-keyring.deb"
|
|
||||||
# sources: "https://radicle.dev/apt"
|
|
||||||
# types: deb
|
|
||||||
# suites: release
|
|
||||||
# comps: main
|
|
||||||
# - name: syncthing
|
|
||||||
# uri: ~
|
|
||||||
# sigkey: ~
|
|
||||||
# sources: ~
|
|
||||||
# types: ~
|
|
||||||
# suites: ~
|
|
||||||
# comps: ~
|
|
||||||
userspace:
|
|
||||||
- name: podman
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: podman-compose
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: distrobox
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-core
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-doc
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-mod-crypto
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-mod-ldap
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-mod-sqlite
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: aria2
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: syncplay-server
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: caddy
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: erlang
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: erlang-hex
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: elixir
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: python3.13
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: python3-venv
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: python3-pip
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: golang
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: hugo
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: yt-dlp
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: syncthing-discosrv
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: syncthing-relaysrv
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
|
|
||||||
script:
|
|
||||||
# <list[<dict>]> representing user-level or supplemental shell script installations
|
|
||||||
userspace:
|
|
||||||
- name: nvm
|
|
||||||
src: "https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh"
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
- name: rustup
|
|
||||||
src: "https://sh.rustup.rs"
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
- name: julia
|
|
||||||
src: "https://install.julialang.org"
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
- name: uv
|
|
||||||
src: "https://astral.sh/uv/install.sh"
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source archives
|
|
||||||
archive:
|
|
||||||
# <list[<dict>]> representing user-level or supplemental source archives
|
|
||||||
userspace:
|
|
||||||
- name: surge
|
|
||||||
# @NOTE https://github.com/SurgeDM/Surge
|
|
||||||
src: "https://github.com/SurgeDM/Surge/releases/download/v0.8.6/Surge_0.8.6_linux_amd64.tar.gz"
|
|
||||||
deploy: ~
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source git repositories
|
|
||||||
git_repos:
|
|
||||||
userspace:
|
|
||||||
- name: quartz
|
|
||||||
src: "https://github.com/jackyzha0/quartz.git"
|
|
||||||
branch: main
|
|
||||||
deploy: ~
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
core_pkgs: "{{ (pkgs.mngr.core | default([])) + (pkgs.script.core | default([])) + (pkgs.archive.core | default([])) + (pkgs.git_repos.core | default([])) + (pkgs.containers.core | default([])) + (pkgs.snaps.core | default([])) + (pkgs.flatpaks.core | default([])) }}"
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
# <str<vault>> representing password for Linux root user account of LAN server on PC
|
|
||||||
password: ""
|
|
||||||
# <str<vault>> administrative API token or PXE server authentication key/password
|
|
||||||
token: ~
|
|
||||||
# <str> representing hostname for LAN server; same as host or group variable name
|
|
||||||
instance: ""
|
|
||||||
# <str<enum>> representing Linux distro or OS image to be used for VPS; can be PXE server URI/URL link
|
|
||||||
# Example-- operating_system: "tftp://hikiki.local:69/debian.iso"
|
|
||||||
operating_system: ~
|
|
||||||
# <list[<str>]> of control node or local SSH key basenames
|
|
||||||
ssh_keys: []
|
|
||||||
# @TODO change 'key' attributes of package entres under 'mngr' section below to 'signkey'
|
|
||||||
# and edit 'roles/init-server/install-pks.yml' accordngly
|
|
||||||
# <dict[<str>:<dict>]> package groups
|
|
||||||
pkgs:
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by package manager via repositories
|
|
||||||
mngr:
|
|
||||||
# <list[<dict>]> representing system-level or essential packages
|
|
||||||
core:
|
|
||||||
- name: ""
|
|
||||||
uri: ""
|
|
||||||
sigkey: ""
|
|
||||||
sources: ""
|
|
||||||
types: ""
|
|
||||||
suites: ""
|
|
||||||
comps: ""
|
|
||||||
# <list[<dict>]> representing user-level or supplemental packages
|
|
||||||
userspace:
|
|
||||||
- name: ""
|
|
||||||
uri: ""
|
|
||||||
sigkey: ""
|
|
||||||
sources: ""
|
|
||||||
types: ""
|
|
||||||
suites: ""
|
|
||||||
comps: ""
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
|
|
||||||
script:
|
|
||||||
# <list[<dict>]> representing system-level or essential shell script software installations
|
|
||||||
core:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path to software installation shell script
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or name of handler listener, for pre-installation actions
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or name of handler listener, for post-installation actions
|
|
||||||
# <list[<dict>]> representing user-level or supplemental shell script software installations
|
|
||||||
userspace:
|
|
||||||
- name: ""
|
|
||||||
src: ""
|
|
||||||
pre: ""
|
|
||||||
post: ""
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source archives
|
|
||||||
archive:
|
|
||||||
# <list[<dict>]> representing system-level or essential source archives
|
|
||||||
core:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path of archive file for software build
|
|
||||||
deploy: "" # <str> URI/URL or path to shell script, or handler listener name, to build software from archive
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take before software build
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take after software build
|
|
||||||
# <list[<dict>]> representing user-level or supplemental source archives
|
|
||||||
userspace:
|
|
||||||
- name: ""
|
|
||||||
src: ""
|
|
||||||
deploy: ""
|
|
||||||
pre: ""
|
|
||||||
post: ""
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source git repositories
|
|
||||||
git_repos:
|
|
||||||
# <list[<dict>]> representing system-level or essential git repositories
|
|
||||||
core:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path of git repository
|
|
||||||
src_path: "" # <str> path in which to place git repository clone
|
|
||||||
branch: "" # <str> specific branch to pull or otherwise to swtich into
|
|
||||||
deploy: "" # <str> URI/URL or path to shell script, or handler listener name, to build or run from source repository
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take before building or running from source repository
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take after building or running from source repository
|
|
||||||
# <list[<dict>]> representing user-level or supplemental git repositories
|
|
||||||
userspace:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path of git repository
|
|
||||||
src_path: "" # <str> path in which to place git repository clone
|
|
||||||
remote: "" # <str> the name of the remote source of the git repository
|
|
||||||
branch: "" # <str> specific branch to pull or otherwise to swtich into
|
|
||||||
deploy: "" # <str> URI/URL or path to shell script, or handler listener name, to build or run from source repository
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take before building or running from source repository
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take after building or running from source repository
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed via container engine
|
|
||||||
containers:
|
|
||||||
# <list[<dict>]> representing system-level or essential container images
|
|
||||||
core: []
|
|
||||||
# <list[<dict>]> representing user-level or supplemental container images
|
|
||||||
userspace: []
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed via snap package
|
|
||||||
snaps:
|
|
||||||
# <list[<dict>]> representing system-level or essential packages
|
|
||||||
core: []
|
|
||||||
# <list[<dict>]> representing user-level or supplemental packages
|
|
||||||
userspace: []
|
|
||||||
# <dict[<str>:<dict>]> representing flatpak groups installed via flatpak package
|
|
||||||
flatpaks:
|
|
||||||
# <list[<dict>]> representing system-level or essential flatpaks
|
|
||||||
core: []
|
|
||||||
# <list[<dict>]> representing user-level or supplemental flatpaks
|
|
||||||
userspace: []
|
|
||||||
core_pkgs: [] # @TODO document this
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
# <str<vault>> representing password for Linux root user account of VPS
|
|
||||||
password: ""
|
|
||||||
# <str<vault>> representing API token for VPS cloud service
|
|
||||||
token: ""
|
|
||||||
# <str> representing name and hostname of VPS to be made in VPS cloud service
|
|
||||||
instance: ""
|
|
||||||
# <str<enum>> representing region options from or for given VPS cloud service
|
|
||||||
origin: ""
|
|
||||||
# <str<enum>> representing Linux distro or OS image available in VPS service to be used for VPS
|
|
||||||
operating_system: ~
|
|
||||||
# <list[<str>]> of control node or local SSH key basenames
|
|
||||||
ssh_keys: []
|
|
||||||
# @TODO change 'key' attributes of package entres under 'mngr' section below to 'signkey'
|
|
||||||
# and edit 'roles/init-server/install-pks.yml' accordngly
|
|
||||||
# <dict[<str>:<dict>]> package groups
|
|
||||||
pkgs:
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by package manager via repositories
|
|
||||||
mngr:
|
|
||||||
# <list[<dict>]> representing system-level or essential packages
|
|
||||||
core:
|
|
||||||
- name: ""
|
|
||||||
uri: ""
|
|
||||||
sigkey: ""
|
|
||||||
sources: ""
|
|
||||||
types: ""
|
|
||||||
suites: ""
|
|
||||||
comps: ""
|
|
||||||
# <list[<dict>]> representing user-level or supplemental packages
|
|
||||||
userspace:
|
|
||||||
- name: ""
|
|
||||||
uri: ""
|
|
||||||
sigkey: ""
|
|
||||||
sources: ""
|
|
||||||
types: ""
|
|
||||||
suites: ""
|
|
||||||
comps: ""
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
|
|
||||||
script:
|
|
||||||
# <list[<dict>]> representing system-level or essential shell script software installations
|
|
||||||
core:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path to software installation shell script
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or name of handler listener, for pre-installation actions
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or name of handler listener, for post-installation actions
|
|
||||||
# <list[<dict>]> representing user-level or supplemental shell script software installations
|
|
||||||
userspace:
|
|
||||||
- name: ""
|
|
||||||
src: ""
|
|
||||||
pre: ""
|
|
||||||
post: ""
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source archives
|
|
||||||
archive:
|
|
||||||
# <list[<dict>]> representing system-level or essential source archives
|
|
||||||
core:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path of archive file for software build
|
|
||||||
deploy: "" # <str> URI/URL or path to shell script, or handler listener name, to build software from archive
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take before software build
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take after software build
|
|
||||||
# <list[<dict>]> representing user-level or supplemental source archives
|
|
||||||
userspace:
|
|
||||||
- name: ""
|
|
||||||
src: ""
|
|
||||||
deploy: ""
|
|
||||||
pre: ""
|
|
||||||
post: ""
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source git repositories
|
|
||||||
git_repos:
|
|
||||||
# <list[<dict>]> representing system-level or essential git repositories
|
|
||||||
core:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path of git repository
|
|
||||||
src_path: "" # <str> path in which to place git repository clone
|
|
||||||
branch: "" # <str> specific branch to pull or otherwise to swtich into
|
|
||||||
deploy: "" # <str> URI/URL or path to shell script, or handler listener name, to build or run from source repository
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take before building or running from source repository
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take after building or running from source repository
|
|
||||||
# <list[<dict>]> representing user-level or supplemental git repositories
|
|
||||||
userspace:
|
|
||||||
- name: "" # <str> arbitrary name, used by handler listener
|
|
||||||
src: "" # <str> URI/URL or path of git repository
|
|
||||||
src_path: "" # <str> path in which to place git repository clone
|
|
||||||
remote: "" # <str> the name of the remote source of the git repository
|
|
||||||
branch: "" # <str> specific branch to pull or otherwise to swtich into
|
|
||||||
deploy: "" # <str> URI/URL or path to shell script, or handler listener name, to build or run from source repository
|
|
||||||
pre: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take before building or running from source repository
|
|
||||||
post: "" # <str> URI/URL or path to shell script, or handler listener name, for actions to take after building or running from source repository
|
|
||||||
# <dict[<str>:<dict>]> representing container image groups installed via container engine
|
|
||||||
containers:
|
|
||||||
# <list[<dict>]> representing system-level or essential container images
|
|
||||||
core: []
|
|
||||||
# <list[<dict>]> representing user-level or supplemental container images
|
|
||||||
userspace: []
|
|
||||||
# <dict[<str>:<dict>]> representing package groups installed via snap package
|
|
||||||
snaps:
|
|
||||||
# <list[<dict>]> representing system-level or essential packages
|
|
||||||
core: []
|
|
||||||
# <list[<dict>]> representing user-level or supplemental packages
|
|
||||||
userspace: []
|
|
||||||
# <dict[<str>:<dict>]> representing flatpak groups installed via flatpak package
|
|
||||||
flatpaks:
|
|
||||||
# <list[<dict>]> representing system-level or essential flatpaks
|
|
||||||
core: []
|
|
||||||
# <list[<dict>]> representing user-level or supplemental flatpaks
|
|
||||||
userspace: []
|
|
||||||
core_pkgs: [] # @TODO document this
|
|
||||||
@@ -1,81 +1,232 @@
|
|||||||
# <str<vault>> representing password for Linux root user account of VPS
|
# <str<vault>> representing password for Linux root user account of VPS
|
||||||
password: !vault |
|
password: "{{ lookup('password', './.tmp/' + inventory_hostname + '.pass', seed=inventory_hostname, encrypt='sha512_crypt') }}"
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
66353462633933306537323461663665643234306166366663653163306436333037313032306338
|
|
||||||
3762653037396437633835356630656438623163656536310a306163663234383265386133396634
|
|
||||||
34363163343766623739646334643031373239373630663731376239333764346531396363636131
|
|
||||||
6163343335356337660a366337336632333236326532373032353332333636366638616265356562
|
|
||||||
66616534303035386134623535373935373065326539363065623230633034313433
|
|
||||||
# <str<vault>> representing API token for VPS cloud service
|
# <str<vault>> representing API token for VPS cloud service
|
||||||
token: !vault |
|
token: ~
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
33333839333337323062326231626534616166646666343261343966636464346630363033653130
|
|
||||||
3035653864396363376633346362353239643939663462370a323935353061313563336435366331
|
|
||||||
30393463653661326539326234646438663133616634663439303932656137633839656533376433
|
|
||||||
3666643635613039390a323138393033623131326438616331386539666333613630316263613636
|
|
||||||
66663263373665343662393638623064356234646165343835623966643761333562323132396466
|
|
||||||
63363436333463653130323531343139316466316131313031343232343039396261616231376232
|
|
||||||
66383938333661363532303166306563396634663132396166646132663131373738396131626633
|
|
||||||
34393265343061356531
|
|
||||||
# <str> representing name and hostname of VPS to be made in VPS cloud service
|
|
||||||
instance: sukaato
|
|
||||||
# <str<enum>> representing region options from or for given VPS cloud service
|
# <str<enum>> representing region options from or for given VPS cloud service
|
||||||
origin: us-east
|
origin: us-east
|
||||||
# <str<enum>> representing Linux distro or OS image available in VPS service to be used for VPS
|
# <str<enum>> representing Linux distro or OS image available in VPS service to be used for VPS
|
||||||
operating_system: linode/debian13
|
operating_system: linode/debian13
|
||||||
# <list[<str>]> list of control node or local SSH key basenames for root user
|
# <list[<str>]> list of control node or local SSH key basenames for root user
|
||||||
ssh_keys:
|
ssh_keys:
|
||||||
- ed25519@sukaato.hikiki
|
- ed25519@staging
|
||||||
- ecdsa@sukaato.hikiki
|
- ecdsa@staging
|
||||||
# <list<dict>> list of administrative users (in Linux, users that can use "sudo")
|
# <list<dict>> list of administrative users (in Linux, users that can use "sudo")
|
||||||
admins:
|
admins:
|
||||||
- username: senpai # <str> arbitrary valid user name
|
- username: senpai # <str> arbitrary valid user name
|
||||||
services: ~ # <list[<str>]> if linux system user, assocated servce
|
services: ~ # <list[<str>]> if linux system user, assocated servce
|
||||||
# <list[<str>]> list of control node or local SSH key basenames for this user
|
# <list[<str>]> list of control node or local SSH key basenames for this user
|
||||||
ssh_keys:
|
ssh_keys:
|
||||||
- ecdsa-37851076-sk@sukaato.hikiki
|
# @TODO add secondary and teriary Yubikeys
|
||||||
- ecdsa-37851072-sk@sukaato.hikiki
|
- ed25519@staging
|
||||||
|
- ecdsa@staging
|
||||||
# <str<vault?>> hashed (and maybe salted) password
|
# <str<vault?>> hashed (and maybe salted) password
|
||||||
password: !vault |
|
password: "{{ lookup('password', './.tmp/senpai@' + inventory_hostname + '.pass', seed='senpai@' + inventory_hostname, encrypt='sha512_crypt') }}"
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
31663265653031323833373663653132653532646638316465393364613961643130653330393062
|
|
||||||
6165386239303965386261363565353137636164356130370a336465353931373564393339363561
|
|
||||||
37353162333331663833656631663165356134633961323337663439663733316231666334336539
|
|
||||||
6537373334326634610a623037613462663733343230306538386561363838316638623365636533
|
|
||||||
32313931666439363435663161663665346266653763343265376366383837376436643163376430
|
|
||||||
39393861613037333766386138376335653334363737626664383236303234653461313230383564
|
|
||||||
33393834636165386562383435666233313664656233326364616237636230303264363732376639
|
|
||||||
64396564366335366430303031323865333635306536346463386334303235386438663061343934
|
|
||||||
37376466373566396130366330383834323332626166316661336339346462343466
|
|
||||||
# @TODO change 'key' attributes of package entres under 'mngr' section below to 'signkey'
|
|
||||||
# and edit 'roles/init-server/install-pks.yml' accordngly
|
|
||||||
# <dict[<str>:<dict>]> package groups
|
# <dict[<str>:<dict>]> package groups
|
||||||
pkgs:
|
pkgs:
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by package manager via repositories
|
# <dict[<str>:<dict>]> representing package groups installed by package manager via repositories
|
||||||
mngr:
|
mngr:
|
||||||
# <list[<dict>]> representing system-level or essential packages
|
# <list[<dict>]> representing system-level or essential packages
|
||||||
core:
|
core:
|
||||||
- name: neovim
|
- name: "zfsutils-linux"
|
||||||
uri: ~
|
uri: ~
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: flatpak
|
handler: default
|
||||||
|
- name: "zfs-dkms"
|
||||||
uri: ~
|
uri: ~
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: snapd
|
handler: default
|
||||||
|
- name: cron
|
||||||
uri: ~
|
uri: ~
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "cron-daemon-common"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "python3-certbot"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "python3-certbot-dns-standalone"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: certbot
|
||||||
|
- name: sudo
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "xz-utils"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: wireguard
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: wireguard
|
||||||
|
- name: "wireguard-tools"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: vagrant
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "vagrant-libvirt"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "qemu-system"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "qemu-kvm"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "bridge-utils"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: libvirt
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "libvirt-clients"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "libvirt-daemon-system"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "virt-install"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "virt-viewer"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: gcc
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "kitty-terminfo"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "git-doc"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "git-delta"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: fastfetch
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
- name: git
|
- name: git
|
||||||
uri: ~
|
uri: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
@@ -83,6 +234,7 @@ pkgs:
|
|||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
|
handler: git
|
||||||
- name: fail2ban
|
- name: fail2ban
|
||||||
uri: ~
|
uri: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
@@ -90,13 +242,7 @@ pkgs:
|
|||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: crowdsec
|
handler: default
|
||||||
uri: ~
|
|
||||||
sources: ~
|
|
||||||
sigkey: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: glow
|
- name: glow
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: "https://repo.charm.sh/apt/gpg.key"
|
sigkey: "https://repo.charm.sh/apt/gpg.key"
|
||||||
@@ -104,71 +250,113 @@ pkgs:
|
|||||||
types: deb
|
types: deb
|
||||||
suites: "*"
|
suites: "*"
|
||||||
comps: "*"
|
comps: "*"
|
||||||
- name: vim-vimwiki
|
handler: default
|
||||||
|
- name: whois
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: pandoc
|
handler: default
|
||||||
|
# @TODO make sure to create handler inclusion of tasks in file under/at `tasks/contingent/pkg` for below
|
||||||
|
- name: iptables
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: tor
|
handler: default
|
||||||
|
- name: gnupg
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: i2pd
|
handler: default
|
||||||
|
- name: "gnupg-agent"
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
# # @TODO troubleshoot radicle installation issue or change installation method for radicle to script
|
handler: default
|
||||||
# - name: radicle-keyring
|
- name: tmux
|
||||||
# uri: "https://radicle.dev/apt/radicle-archive-keyring.deb"
|
uri: ~
|
||||||
# sigkey: ~
|
sigkey: ~
|
||||||
# sources: ~
|
sources: ~
|
||||||
# types: ~
|
types: ~
|
||||||
# suites: ~
|
suites: ~
|
||||||
# comps: ~
|
comps: ~
|
||||||
# - name: radicle
|
handler: default
|
||||||
# uri: ~
|
- name: "cpu-checker"
|
||||||
# sigkey: "https://radicle.dev/apt/radicle-archive-keyring.deb"
|
uri: ~
|
||||||
# sources: "https://radicle.dev/apt"
|
sigkey: ~
|
||||||
# types: deb
|
sources: ~
|
||||||
# suites: release
|
types: ~
|
||||||
# comps: main
|
suites: ~
|
||||||
# - name: syncthing
|
comps: ~
|
||||||
# uri: ~
|
handler: default
|
||||||
# sigkey: ~
|
- name: libpam-doc
|
||||||
# sources: ~
|
uri: ~
|
||||||
# types: ~
|
sigkey: ~
|
||||||
# suites: ~
|
sources: ~
|
||||||
# comps: ~
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: headscale
|
||||||
|
uri: "https://github.com/juanfont/headscale/releases/download/v0.28.0/headscale_0.28.0_linux_amd64.deb"
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: headscale
|
||||||
userspace:
|
userspace:
|
||||||
- name: podman
|
- name: "libpam-google-authenticator"
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: podman-compose
|
handler: "libpam-google-authenticator"
|
||||||
|
- name: vim
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: vim
|
||||||
|
- name: "vim-vimwiki"
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "vim-doc"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: neovim
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: neovim
|
||||||
- name: distrobox
|
- name: distrobox
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
@@ -176,83 +364,15 @@ pkgs:
|
|||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: proftpd-core
|
handler: default
|
||||||
uri: ~
|
- name: smartmontools
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-doc
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-mod-crypto
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-mod-ldap
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: proftpd-mod-sqlite
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: aria2
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: syncplay-server
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: caddy
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: erlang
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: erlang-hex
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: elixir
|
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
|
handler: default
|
||||||
- name: python3.13
|
- name: python3.13
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
@@ -260,20 +380,23 @@ pkgs:
|
|||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: python3-venv
|
handler: default
|
||||||
|
- name: "python3-venv"
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: python3-pip
|
handler: default
|
||||||
|
- name: "python3-pip"
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
|
handler: default
|
||||||
- name: golang
|
- name: golang
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
@@ -281,73 +404,56 @@ pkgs:
|
|||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
- name: hugo
|
handler: default
|
||||||
uri: ~
|
- name: "golang-doc"
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: yt-dlp
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: syncthing-discosrv
|
|
||||||
uri: ~
|
|
||||||
sigkey: ~
|
|
||||||
sources: ~
|
|
||||||
types: ~
|
|
||||||
suites: ~
|
|
||||||
comps: ~
|
|
||||||
- name: syncthing-relaysrv
|
|
||||||
uri: ~
|
uri: ~
|
||||||
sigkey: ~
|
sigkey: ~
|
||||||
sources: ~
|
sources: ~
|
||||||
types: ~
|
types: ~
|
||||||
suites: ~
|
suites: ~
|
||||||
comps: ~
|
comps: ~
|
||||||
|
handler: default
|
||||||
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
|
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
|
||||||
script:
|
script:
|
||||||
# <list[<dict>]> representing user-level or supplemental shell script installations
|
# <list[<dict>]> representing user-level or supplemental shell script installations
|
||||||
userspace:
|
userspace:
|
||||||
- name: nodejs
|
- name: radicle
|
||||||
src: "https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh"
|
src: "https://radicle.dev/install"
|
||||||
pre: ~
|
pre: ~
|
||||||
post: ~
|
post: ~
|
||||||
|
handler: radicle
|
||||||
- name: rustup
|
- name: rustup
|
||||||
src: "https://sh.rustup.rs"
|
src: "https://sh.rustup.rs"
|
||||||
pre: ~
|
pre: ~
|
||||||
post: ~
|
post: ~
|
||||||
- name: julia
|
handler: rustup
|
||||||
src: "https://install.julialang.org"
|
|
||||||
pre: ~
|
|
||||||
post: ~
|
|
||||||
- name: uv
|
- name: uv
|
||||||
src: "https://astral.sh/uv/install.sh"
|
src: "https://astral.sh/uv/install.sh"
|
||||||
pre: ~
|
pre: ~
|
||||||
post: ~
|
post: ~
|
||||||
|
handler: uv
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source archives
|
# <dict[<str>:<dict>]> representing package groups installed from source archives
|
||||||
archive:
|
archive:
|
||||||
# <list[<dict>]> representing user-level or supplemental source archives
|
# <list[<dict>]> representing user-level or supplemental source archives
|
||||||
userspace:
|
userspace:
|
||||||
- name: surge
|
- name: difftastic
|
||||||
# @NOTE https://github.com/SurgeDM/Surge
|
src: "https://github.com/Wilfred/difftastic/releases/download/0.69.0/difft-x86_64-unknown-linux-gnu.tar.gz"
|
||||||
src: "https://github.com/SurgeDM/Surge/releases/download/v0.8.6/Surge_0.8.6_linux_amd64.tar.gz"
|
|
||||||
deploy: ~
|
deploy: ~
|
||||||
pre: ~
|
pre: ~
|
||||||
post: ~
|
post: ~
|
||||||
|
handler: difftastic
|
||||||
# <dict[<str>:<dict>]> representing package groups installed from source git repositories
|
# <dict[<str>:<dict>]> representing package groups installed from source git repositories
|
||||||
git_repos:
|
git_repos:
|
||||||
userspace:
|
# userspace:
|
||||||
- name: quartz
|
# - name: quartz
|
||||||
src: "https://github.com/jackyzha0/quartz.git"
|
# src: "https://github.com/jackyzha0/quartz.git"
|
||||||
src_path: "{{ ansible_facts['user_dir'] }}/repos/"
|
# branch: v5.0.0
|
||||||
remote: origin
|
# deploy: ~
|
||||||
branch: main
|
# pre: ~
|
||||||
deploy: ~
|
# post: ~
|
||||||
pre: ~
|
# handler: default
|
||||||
post: ~
|
binaries:
|
||||||
core_pkgs: "{{ (pkgs.mngr.core | default([])) + (pkgs.script.core | default([])) + (pkgs.archive.core | default([])) + (pkgs.git_repos.core | default([])) + (pkgs.containers.core | default([])) + (pkgs.snaps.core | default([])) + (pkgs.flatpaks.core | default([])) }}"
|
core:
|
||||||
|
- name: dsnet
|
||||||
|
src: "https://github.com/naggie/dsnet/releases/download/v0.8.1/dsnet-linux-amd64"
|
||||||
|
handler: dsnet
|
||||||
@@ -0,0 +1,768 @@
|
|||||||
|
# @TODO create inventory group variables akin to structure of sukaato group's for homeserver
|
||||||
|
# <str<vault>> representing password for Linux root user account of VPS
|
||||||
|
password: "{{ lookup('password', './.tmp/' + inventory_hostname + '.pass', seed=inventory_hostname, encrypt='sha512_crypt') }}"
|
||||||
|
# <str<enum>> representing Linux distro or OS image to be used for VPS
|
||||||
|
# operating_system: "tftp://hikiki.local:69/debian.iso"
|
||||||
|
operating_system: ~
|
||||||
|
# <list[<str>]> of control node or local SSH key basenames
|
||||||
|
ssh_keys:
|
||||||
|
- ed25519@staging
|
||||||
|
- ecdsa@staging
|
||||||
|
# <list<dict>> list of administrative users (in Linux, users that can use "sudo")
|
||||||
|
admins:
|
||||||
|
- username: senpai # <str> arbitrary valid user name
|
||||||
|
services: ~ # <list[<str>]> if linux system user, assocated servce
|
||||||
|
# <list[<str>]> list of control node or local SSH key basenames for this user
|
||||||
|
ssh_keys:
|
||||||
|
# @TODO add secondary and teriary Yubikeys
|
||||||
|
- ed25519@staging
|
||||||
|
- ecdsa@staging
|
||||||
|
# <str<vault?>> hashed (and maybe salted) password
|
||||||
|
password: "{{ lookup('password', './.tmp/senpai@' + inventory_hostname + '.pass', seed='senpai@' + inventory_hostname, encrypt='sha512_crypt') }}"
|
||||||
|
# <dict[<str>:<dict>]> package groups
|
||||||
|
pkgs:
|
||||||
|
# <dict[<str>:<dict>]> representing package groups installed by package manager via repositories
|
||||||
|
mngr:
|
||||||
|
# <list[<dict>]> representing system-level or essential packages
|
||||||
|
core:
|
||||||
|
- name: "zfsutils-linux"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "zfs-dkms"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: cron
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "cron-daemon-common"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "xz-utils"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: wireguard
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: wireguard
|
||||||
|
- name: "wireguard-tools"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: vagrant
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "vagrant-libvirt"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "qemu-system"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "qemu-kvm"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "bridge-utils"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: libvirt
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "libvirt-clients"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "libvirt-daemon-system"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "virt-install"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "virt-viewer"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: sudo
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "kitty-terminfo"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: whois
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: smartmontools
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: snapd
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: git
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: git
|
||||||
|
- name: "git-delta"
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "git-doc"
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "git-man"
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: fail2ban
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: glow
|
||||||
|
uri: ~
|
||||||
|
sigkey: "https://repo.charm.sh/apt/gpg.key"
|
||||||
|
sources: "https://repo.charm.sh/apt/"
|
||||||
|
types: deb
|
||||||
|
suites: "*"
|
||||||
|
comps: "*"
|
||||||
|
handler: default
|
||||||
|
- name: pandoc
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: curl
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "build-essential"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: fastfetch
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: gcc
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: dpkg-dev
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: ufw
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: avahi-daemon
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: avahi-utils
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: libpam-u2f
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: pamu2fcfg
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: pcscd
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: tftpd-hpa
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: gocryptfs
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: cryfs
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: tmux
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "cpu-checker"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "libpam-doc"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: gnupg
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "gnupg-agent"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: minidlna
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
userspace:
|
||||||
|
- name: aria2
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: aria
|
||||||
|
- name: "libpam-google-authenticator"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: "libpam-google-authenticator"
|
||||||
|
- name: vim
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: vim
|
||||||
|
- name: "vim-vimwiki"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "vim-doc"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: neovim
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: neovim
|
||||||
|
- name: sqlite3
|
||||||
|
uri: ~
|
||||||
|
sources: ~
|
||||||
|
sigkey: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: podman
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: podman
|
||||||
|
- name: passt
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "podman-compose"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: distrobox
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: python3.13
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "python3-venv"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "python3-pip"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "python3-doc"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: golang
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "golang-doc"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: hugo
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "yt-dlp"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "syncthing-discosrv"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "syncthing-relaysrv"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: burp
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: rsync
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: rclone
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: proftpd
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: reprepro
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: erlang
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "erlang-hex"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: erlang-doc
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: elixir
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
- name: "libsecret-1-dev"
|
||||||
|
uri: ~
|
||||||
|
sigkey: ~
|
||||||
|
sources: ~
|
||||||
|
types: ~
|
||||||
|
suites: ~
|
||||||
|
comps: ~
|
||||||
|
handler: default
|
||||||
|
# <dict[<str>:<dict>]> representing package groups installed by shell scripts
|
||||||
|
script:
|
||||||
|
# <list[<dict>]> representing user-level or supplemental shell script installations
|
||||||
|
userspace:
|
||||||
|
- name: radicle
|
||||||
|
src: "https://radicle.dev/install"
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: radicle
|
||||||
|
- name: rustup
|
||||||
|
src: "https://sh.rustup.rs"
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: rustup
|
||||||
|
- name: julia
|
||||||
|
src: "https://install.julialang.org"
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: julia
|
||||||
|
- name: uv
|
||||||
|
src: "https://astral.sh/uv/install.sh"
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: uv
|
||||||
|
# <dict[<str>:<dict>]> representing package groups installed from source archives
|
||||||
|
archive:
|
||||||
|
# <list[<dict>]> representing user-level or supplemental source archives
|
||||||
|
userspace:
|
||||||
|
- name: surge
|
||||||
|
src: "https://github.com/SurgeDM/Surge/releases/download/v0.8.6/Surge_0.8.6_linux_amd64.tar.gz"
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: surge
|
||||||
|
- name: nvm
|
||||||
|
src: "https://nodejs.org/dist/v24.16.0/node-v24.16.0-linux-x64.tar.xz"
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: nvm
|
||||||
|
- name: difftastic
|
||||||
|
src: "https://github.com/Wilfred/difftastic/releases/download/0.69.0/difft-x86_64-unknown-linux-gnu.tar.gz"
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: difftastic
|
||||||
|
# <dict[<str>:<dict>]> representing package groups installed from source git repositories
|
||||||
|
git_repos:
|
||||||
|
userspace:
|
||||||
|
# # @TODO use below to build Podman container instead, to deploy with podman-compose
|
||||||
|
# # @NOTE https://github.com/papis/papis and https://papis.readthedocs.io/en/latest/
|
||||||
|
# - name: papis
|
||||||
|
# src: "https://github.com/papis/papis.git"
|
||||||
|
# branch: main
|
||||||
|
# deploy: ~
|
||||||
|
# pre: ~
|
||||||
|
# post: ~
|
||||||
|
# handler: false
|
||||||
|
- name: "skato-compose"
|
||||||
|
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.compose.name }}.git"
|
||||||
|
branch: main
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: skato_compose
|
||||||
|
- name: skato-cli
|
||||||
|
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.cli.name }}.git"
|
||||||
|
branch: main
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: skato_cli
|
||||||
|
- name: "skato-blog-theme"
|
||||||
|
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.blog_theme.name }}.git"
|
||||||
|
branch: main
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: skato_blog_theme
|
||||||
|
- name: "skato-blog"
|
||||||
|
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.blog.name }}.git"
|
||||||
|
branch: main
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: skato_blog
|
||||||
|
- name: sukaato
|
||||||
|
src: "https://{{ source_code.host }}/{{ source_code.user }}/{{ source_code.repos.site.name }}.git"
|
||||||
|
branch: main
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: sukaato
|
||||||
|
- name: quartz
|
||||||
|
src: "https://github.com/jackyzha0/quartz.git"
|
||||||
|
branch: v5.0.0
|
||||||
|
deploy: ~
|
||||||
|
pre: ~
|
||||||
|
post: ~
|
||||||
|
handler: quartz
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# @TODO use hosts and host groupings that refer or point to VM or containerized servers for testing
|
|
||||||
ungrouped:
|
|
||||||
hosts: ~
|
|
||||||
sukaato:
|
|
||||||
hosts: ~
|
|
||||||
armitage:
|
|
||||||
hosts: ~
|
|
||||||
vps:
|
|
||||||
children: ~
|
|
||||||
homeserver:
|
|
||||||
children: ~
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# @NOTE run 'ansible-playbook' command on this using 'sudo'
|
||||||
|
- name: Initialize homeserver
|
||||||
|
hosts: "{{ chosen_host | default('staging1.test') }}"
|
||||||
|
remote_user: root
|
||||||
|
vars:
|
||||||
|
harden: true
|
||||||
|
vars_files:
|
||||||
|
# - vars/certbot_settings@homeserver.yml # REQUIRED
|
||||||
|
- vars/local_facts.yml # REQUIRED
|
||||||
|
- vars/wireguard_settings.yml # REQUIRED
|
||||||
|
- vars/podpose_settings.yml # REQUIRED
|
||||||
|
- vars/surge_settings.yml
|
||||||
|
- vars/users@{{ inventory_hostname | default('homeserver') }}.yml
|
||||||
|
- vars/config@{{ inventory_hostname | default('homeserver') }}.yml
|
||||||
|
tasks:
|
||||||
|
- name: Hardening SSH server
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server # required. The name of the role to be executed.
|
||||||
|
# apply: # not required. Accepts a hash of task keywords (e.g. C(tags), C(become)) that will be applied to all tasks within the included role.
|
||||||
|
tasks_from: harden # not required. File to load from a role's C(tasks/) directory.
|
||||||
|
# vars_from: main # not required. File to load from a role's C(vars/) directory.
|
||||||
|
# defaults_from: main # not required. File to load from a role's C(defaults/) directory.
|
||||||
|
# allow_duplicates: True # not required. Overrides the role's metadata setting to allow using a role more than once with the same parameters.
|
||||||
|
# handlers_from: main # not required. File to load from a role's C(handlers/) directory.
|
||||||
|
- name: Installing requisite packages
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: core@install-pkgs
|
||||||
|
handlers_from: core
|
||||||
|
- name: Initializing groups and users
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: ssh-users
|
||||||
|
- name: Updating hostname
|
||||||
|
become: true
|
||||||
|
ansible.builtin.hostname:
|
||||||
|
name: "{{ fqdn | default(inventory_hostname) }}"
|
||||||
|
- name: Updating hosts file
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/hosts
|
||||||
|
regexp: "^127\\.0\\.1\\.1"
|
||||||
|
line: "127.0.1.1 {{ fqdn | default(inventory_hostname) }}"
|
||||||
|
insertbefore: BOF
|
||||||
|
state: present
|
||||||
|
- name: Updating host icon name
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "hostnamectl set-icon-name computer-server"
|
||||||
|
- name: Notifying user that all processes have finished
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: All processes finished. Hit enter to reboot machine.
|
||||||
|
- name: Ensuring user has read prior message regarding upcoming reboot
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Rebooting machine for hostname change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: "Rebooting machine.."
|
||||||
|
connect_timeout: 0
|
||||||
|
test_command: ~
|
||||||
|
ignore_errors: true
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# @NOTE run 'ansible-playbook' command on this using 'sudo'
|
|
||||||
- name: Initialize homeserver
|
|
||||||
hosts: armitage
|
|
||||||
remote_user: root
|
|
||||||
vars:
|
|
||||||
harden: true
|
|
||||||
local_facts:
|
|
||||||
user_dir: ~
|
|
||||||
user_id: ~
|
|
||||||
tasks:
|
|
||||||
- name: Hardening SSH server
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: init-server # required. The name of the role to be executed.
|
|
||||||
# apply: # not required. Accepts a hash of task keywords (e.g. C(tags), C(become)) that will be applied to all tasks within the included role.
|
|
||||||
tasks_from: harden # not required. File to load from a role's C(tasks/) directory.
|
|
||||||
# vars_from: main # not required. File to load from a role's C(vars/) directory.
|
|
||||||
# defaults_from: main # not required. File to load from a role's C(defaults/) directory.
|
|
||||||
# allow_duplicates: True # not required. Overrides the role's metadata setting to allow using a role more than once with the same parameters.
|
|
||||||
# handlers_from: main # not required. File to load from a role's C(handlers/) directory.
|
|
||||||
- name: Initializing groups and users
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: init-server # required. The name of the role to be executed.
|
|
||||||
# apply: # not required. Accepts a hash of task keywords (e.g. C(tags), C(become)) that will be applied to all tasks within the included role.
|
|
||||||
tasks_from: ssh-users # not required. File to load from a role's C(tasks/) directory.
|
|
||||||
vars_from: main # not required. File to load from a role's C(vars/) directory.
|
|
||||||
defaults_from: main # not required. File to load from a role's C(defaults/) directory.
|
|
||||||
# allow_duplicates: True # not required. Overrides the role's metadata setting to allow using a role more than once with the same parameters.
|
|
||||||
# handlers_from: main # not required. File to load from a role's C(handlers/) directory.
|
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# @NOTE run 'ansible-playbook' command on this using 'sudo'
|
||||||
|
- name: Initialize VPS
|
||||||
|
hosts: "{{ chosen_host | default('staging0.test') }}"
|
||||||
|
remote_user: "{{ chosen_user | default('root') }}"
|
||||||
|
vars:
|
||||||
|
harden: true
|
||||||
|
vars_files:
|
||||||
|
- vars/local_facts.yml # REQUIRED
|
||||||
|
- vars/vpn_settings.yml # REQUIRED
|
||||||
|
- vars/wireguard_settings.yml # REQUIRED
|
||||||
|
- vars/headscale_settings.yml # REQUIRED
|
||||||
|
- vars/podpose_settings.yml # REQUIRED
|
||||||
|
- vars/certbot_settings@vps.yml # REQUIRED
|
||||||
|
- vars/users@{{ inventory_hostname | default('vps') }}.yml
|
||||||
|
- vars/config@{{ inventory_hostname | default('vps') }}.yml
|
||||||
|
tasks:
|
||||||
|
- name: Hardening SSH server
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server # required. The name of the role to be executed.
|
||||||
|
# apply: # not required. Accepts a hash of task keywords (e.g. C(tags), C(become)) that will be applied to all tasks within the included role.
|
||||||
|
tasks_from: harden # not required. File to load from a role's C(tasks/) directory.
|
||||||
|
# vars_from: main # not required. File to load from a role's C(vars/) directory.
|
||||||
|
# defaults_from: main # not required. File to load from a role's C(defaults/) directory.
|
||||||
|
# allow_duplicates: True # not required. Overrides the role's metadata setting to allow using a role more than once with the same parameters.
|
||||||
|
# handlers_from: main # not required. File to load from a role's C(handlers/) directory.
|
||||||
|
- name: Installing requisite packages
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: core@install-pkgs
|
||||||
|
handlers_from: core
|
||||||
|
- name: Initializing groups and users
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: init-server
|
||||||
|
tasks_from: ssh-users
|
||||||
|
- name: Flushing handlers
|
||||||
|
ansible.builtin.meta: flush_handlers
|
||||||
|
- name: Updating hostname
|
||||||
|
become: true
|
||||||
|
ansible.builtin.hostname:
|
||||||
|
name: "{{ fqdn | default(inventory_hostname) }}"
|
||||||
|
- name: Updating hosts file
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/hosts
|
||||||
|
regexp: "^127\\.0\\.1\\.1"
|
||||||
|
line: "127.0.1.1 {{ fqdn | default(inventory_hostname) }}"
|
||||||
|
insertbefore: BOF
|
||||||
|
state: present
|
||||||
|
- name: Updating host icon name
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "hostnamectl set-icon-name computer-server"
|
||||||
|
- name: Opening port 51820
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 51820
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 51820
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening port 443
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 443
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 443
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening ports
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: "{{ item }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: "Open up port {{ (item | string) }}"
|
||||||
|
loop:
|
||||||
|
- 80
|
||||||
|
- 465
|
||||||
|
- 587
|
||||||
|
- 995
|
||||||
|
- 993
|
||||||
|
- name: Notifying user that all processes have finished
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: All processes finished. Hit enter to reboot machine.
|
||||||
|
- name: Ensuring user has read prior message regarding upcoming reboot
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Rebooting machine for hostname change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: "Rebooting machine.."
|
||||||
|
connect_timeout: 0
|
||||||
|
test_command: ~
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
[project]
|
||||||
|
name = "skato-ansible"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.13"
|
||||||
|
dependencies = [
|
||||||
|
"ansible==13.7.0",
|
||||||
|
"ansible-builder==3.1.1",
|
||||||
|
"ansible-compat==26.3.0",
|
||||||
|
"ansible-core==2.20.6",
|
||||||
|
"ansible-lint==26.4.0",
|
||||||
|
"ansible-navigator==26.4.0",
|
||||||
|
"ansible-runner==2.4.3",
|
||||||
|
"ansible-specdoc==0.0.20",
|
||||||
|
"appdirs==1.4.4",
|
||||||
|
"attrs==26.1.0",
|
||||||
|
"baron==0.10.1",
|
||||||
|
"bindep==2.14.0",
|
||||||
|
"black==26.5.1",
|
||||||
|
"bracex==2.6",
|
||||||
|
"certifi==2026.5.20",
|
||||||
|
"cffi==2.0.0",
|
||||||
|
"charset-normalizer==3.4.7",
|
||||||
|
"click==8.4.1",
|
||||||
|
"cryptography==48.0.0",
|
||||||
|
"deprecated==1.3.1",
|
||||||
|
"distro==1.9.0",
|
||||||
|
"enrich==1.2.7",
|
||||||
|
"filelock==3.29.0",
|
||||||
|
"idna==3.16",
|
||||||
|
"jinja2==3.1.6",
|
||||||
|
"jsonschema==4.26.0",
|
||||||
|
"jsonschema-specifications==2025.9.1",
|
||||||
|
"linode-api4==5.44.0",
|
||||||
|
"lockfile==0.12.2",
|
||||||
|
"markdown-it-py==4.2.0",
|
||||||
|
"markupsafe==3.0.3",
|
||||||
|
"mdurl==0.1.2",
|
||||||
|
"molecule==26.4.0",
|
||||||
|
"mypy-extensions==1.1.0",
|
||||||
|
"onigurumacffi==1.5.0",
|
||||||
|
"packaging==26.2",
|
||||||
|
"parsley==1.3",
|
||||||
|
"passlib==1.7.4",
|
||||||
|
"pathspec==1.0.4",
|
||||||
|
"pbr==7.0.3",
|
||||||
|
"pexpect==4.9.0",
|
||||||
|
"pip==25.1.1",
|
||||||
|
"platformdirs==4.9.6",
|
||||||
|
"pluggy==1.6.0",
|
||||||
|
"polling==0.3.2",
|
||||||
|
"ptyprocess==0.7.0",
|
||||||
|
"pycparser==3.0",
|
||||||
|
"pygments==2.20.0",
|
||||||
|
"python-daemon==3.1.2",
|
||||||
|
"pytokens==0.4.1",
|
||||||
|
"pyyaml==6.0.3",
|
||||||
|
"redbaron==0.9.2",
|
||||||
|
"referencing==0.37.0",
|
||||||
|
"requests==2.34.2",
|
||||||
|
"resolvelib==1.2.1",
|
||||||
|
"rich==15.0.0",
|
||||||
|
"rpds-py==0.30.0",
|
||||||
|
"rply==0.7.8",
|
||||||
|
"ruamel-yaml==0.19.1",
|
||||||
|
"ruamel-yaml-clib==0.2.15",
|
||||||
|
"setuptools==82.0.1",
|
||||||
|
"subprocess-tee==0.4.2",
|
||||||
|
"tzdata==2026.2",
|
||||||
|
"urllib3==2.7.0",
|
||||||
|
"wcmatch==10.1",
|
||||||
|
"wrapt==2.2.1",
|
||||||
|
"yamllint==1.38.0",
|
||||||
|
]
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
ansible==13.7.0
|
|
||||||
ansible-builder==3.1.1
|
|
||||||
ansible-compat==26.3.0
|
|
||||||
ansible-core==2.20.6
|
|
||||||
ansible-lint==26.4.0
|
|
||||||
ansible-navigator==26.4.0
|
|
||||||
ansible-runner==2.4.3
|
|
||||||
ansible-specdoc==0.0.20
|
|
||||||
appdirs==1.4.4
|
|
||||||
attrs==26.1.0
|
|
||||||
baron==0.10.1
|
|
||||||
bindep==2.14.0
|
|
||||||
black==26.5.1
|
|
||||||
bracex==2.6
|
|
||||||
certifi==2026.5.20
|
|
||||||
cffi==2.0.0
|
|
||||||
charset-normalizer==3.4.7
|
|
||||||
click==8.4.1
|
|
||||||
cryptography==48.0.0
|
|
||||||
deprecated==1.3.1
|
|
||||||
distro==1.9.0
|
|
||||||
enrich==1.2.7
|
|
||||||
filelock==3.29.0
|
|
||||||
idna==3.16
|
|
||||||
jinja2==3.1.6
|
|
||||||
jsonschema==4.26.0
|
|
||||||
jsonschema-specifications==2025.9.1
|
|
||||||
linode-api4==5.44.0
|
|
||||||
lockfile==0.12.2
|
|
||||||
markdown-it-py==4.2.0
|
|
||||||
markupsafe==3.0.3
|
|
||||||
mdurl==0.1.2
|
|
||||||
molecule==26.4.0
|
|
||||||
mypy-extensions==1.1.0
|
|
||||||
onigurumacffi==1.5.0
|
|
||||||
packaging==26.2
|
|
||||||
parsley==1.3
|
|
||||||
pathspec==1.0.4
|
|
||||||
pbr==7.0.3
|
|
||||||
pexpect==4.9.0
|
|
||||||
platformdirs==4.9.6
|
|
||||||
pluggy==1.6.0
|
|
||||||
polling==0.3.2
|
|
||||||
ptyprocess==0.7.0
|
|
||||||
pycparser==3.0
|
|
||||||
pygments==2.20.0
|
|
||||||
python-daemon==3.1.2
|
|
||||||
pytokens==0.4.1
|
|
||||||
pyyaml==6.0.3
|
|
||||||
redbaron==0.9.2
|
|
||||||
referencing==0.37.0
|
|
||||||
requests==2.34.2
|
|
||||||
resolvelib==1.2.1
|
|
||||||
rich==15.0.0
|
|
||||||
rpds-py==0.30.0
|
|
||||||
rply==0.7.8
|
|
||||||
ruamel-yaml==0.19.1
|
|
||||||
ruamel-yaml-clib==0.2.15
|
|
||||||
setuptools==82.0.1
|
|
||||||
subprocess-tee==0.4.2
|
|
||||||
tzdata==2026.2
|
|
||||||
urllib3==2.7.0
|
|
||||||
wcmatch==10.1
|
|
||||||
wrapt==2.2.1
|
|
||||||
yamllint==1.38.0
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HTTP_SERVERS=()
|
||||||
|
HTTP_SERVERS_LEN="${#HTTP_SERVERS[@]}"
|
||||||
|
|
||||||
|
if command -v systemctl > /dev/null 2>&1; then
|
||||||
|
if (( HTTP_SERVERS_LEN > 0 )); then
|
||||||
|
for htserv in "${HTTP_SERVERS[@]}"
|
||||||
|
do
|
||||||
|
sudo systemctl start "$htserv"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if command -v podman > /dev/null 2>&1; then
|
||||||
|
podman start -a
|
||||||
|
fi
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HTTP_SERVERS=()
|
||||||
|
HTTP_SERVERS_LEN="${#HTTP_SERVERS[@]}"
|
||||||
|
|
||||||
|
if command -v systemctl > /dev/null 2>&1; then
|
||||||
|
if (( HTTP_SERVERS_LEN > 0 )); then
|
||||||
|
for htserv in "${HTTP_SERVERS[@]}"
|
||||||
|
do
|
||||||
|
sudo systemctl stop "$htserv"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if command -v podman > /dev/null 2>&1; then
|
||||||
|
podman stop -a
|
||||||
|
fi
|
||||||
@@ -4,4 +4,5 @@ PubkeyAuthentication yes
|
|||||||
KbdInteractiveAuthentication no # enable if implementing TOTP 2FA
|
KbdInteractiveAuthentication no # enable if implementing TOTP 2FA
|
||||||
UsePAM yes
|
UsePAM yes
|
||||||
PrintMotd yes
|
PrintMotd yes
|
||||||
|
AllowAgentForwarding yes
|
||||||
Banner /etc/banner
|
Banner /etc/banner
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=dsnet
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/dsnet up
|
||||||
|
ExecStop=/usr/bin/dsnet down
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecReload=/usr/bin/dsnet sync
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=surge
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=surge service start
|
||||||
|
ExecStop=surge service stop
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=thrunet
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/dsnet-forward.sh start
|
||||||
|
ExecStop=/usr/local/bin/dsnet-forward.sh stop
|
||||||
|
RemainAfterExit=yes
|
||||||
|
# ExecReload=/usr/bin/dsnet sync
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Search these registries when pulling images without full path
|
||||||
|
unqualified-search-registries = ["docker.io", "quay.io", "ghcr.io"]
|
||||||
|
|
||||||
|
# Registry-specific configuration
|
||||||
|
# [[registry]]
|
||||||
|
# location = "docker.io"
|
||||||
|
|
||||||
|
# [[registry.mirror]]
|
||||||
|
# location = "mirror.gcr.io"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
set runtimepath^=~/.vim runtimepath+=~/.vim/after
|
||||||
|
|
||||||
|
let &packpath = &runtimepath
|
||||||
|
|
||||||
|
source ~/.vimrc
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=aria2 Daemon
|
||||||
|
Requires=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
ExecStart=/usr/bin/aria2c -D
|
||||||
|
ExecReload=/usr/bin/kill -HUP $MAINPID
|
||||||
|
RestartSec=1min
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,139 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{.Host}}: {{ph "http.request.uri.path"}}</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url(./dark-matter.png);
|
||||||
|
animation: 7s infinite ease-in-out day-cycle-bg;
|
||||||
|
}
|
||||||
|
@keyframes day-cycle-bg {
|
||||||
|
0% {
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
15% {
|
||||||
|
background-color: #121212;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
background-color: #121212;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin: 3vh auto;
|
||||||
|
max-width: 25vw;
|
||||||
|
animation: 7s infinite alternate day-cycle-filter;
|
||||||
|
}
|
||||||
|
@keyframes day-cycle-filter {
|
||||||
|
0% {
|
||||||
|
filter: brightness(1.00) contrast(0.66) grayscale(0.75);
|
||||||
|
}
|
||||||
|
15% {
|
||||||
|
filter: brightness(1.33) contrast(1.00) grayscale(0.66);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
filter: brightness(1.33) contrast(1.10) grayscale(0.66);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
filter: brightness(1.00) contrast(0.66) grayscale(0.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#sun {
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
margin: 0 auto;
|
||||||
|
height: 10vw;
|
||||||
|
max-width: 100vw;
|
||||||
|
background-color: #993333;
|
||||||
|
box-shadow: 0 0 10px 5px #000 inset;
|
||||||
|
position: relative;
|
||||||
|
top: 3vh;
|
||||||
|
transform: rotateX(180deg) rotateY(180deg);
|
||||||
|
animation: 7s infinite linear day-cycle-celestial;
|
||||||
|
}
|
||||||
|
@keyframes day-cycle-celestial {
|
||||||
|
0% {
|
||||||
|
clip-path: circle(33px at 100% 0%);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
clip-path: circle(33px at 75% 25%);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
clip-path: circle(33px at center 66%);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
clip-path: circle(33px at 25% 25%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
clip-path: circle(33px at 0% 0%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#err-message, #err-trace {
|
||||||
|
display: block;
|
||||||
|
margin: 50px auto;
|
||||||
|
}
|
||||||
|
#err {
|
||||||
|
margin: 2vh auto;
|
||||||
|
max-width: 75vw;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #000;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 3%;
|
||||||
|
position: relative;
|
||||||
|
top: -50px;
|
||||||
|
z-index: -1;
|
||||||
|
animation: 7s infinite ease-in-out day-cycle-bxsh;
|
||||||
|
}
|
||||||
|
@keyframes day-cycle-bxsh {
|
||||||
|
0% {
|
||||||
|
box-shadow: 0 0 25px 15px #000 inset;
|
||||||
|
}
|
||||||
|
15% {
|
||||||
|
box-shadow: 0 0 25px 15px #121212 inset;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
box-shadow: 0 0 25px 15px #121212 inset;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 0 25px 15px #000 inset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#err-message {
|
||||||
|
max-width: 66%;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
#err-trace {
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
#err-summary {
|
||||||
|
text-align: center;
|
||||||
|
color: #993333;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="sun"></div>
|
||||||
|
<img src="mythe-sisyphus-klein.png" alt="Sisyphus carrying a boulder" srcset="https://kariannekirsten.com/wp-content/uploads/2022/12/mythe-klein.png"/>
|
||||||
|
<main>
|
||||||
|
<article id="err">
|
||||||
|
<section id="err-summary" class="post frontmatter">
|
||||||
|
<h1>Under Construction</h1>
|
||||||
|
<h2>Err. {{ph "http.error.status_code"}}: {{ph "http.error.status_text"}}</h2>
|
||||||
|
</section>
|
||||||
|
<section id="err-body" class="post body">
|
||||||
|
<p id="err-message" class="message">{{ph "http.error.message"}}</p>
|
||||||
|
<code id="err-trace" class="trace http">
|
||||||
|
{{ph "http.error.trace"}}
|
||||||
|
</code>
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 121 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,35 @@
|
|||||||
|
# SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# handlers file for roles/init-vps
|
||||||
|
- name: Skipping to next installaton
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "No post-installaton or additional installation steps needed--continuing..."
|
||||||
|
listen: default
|
||||||
|
- name: Setting up Git
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/git.yml
|
||||||
|
listen: git
|
||||||
|
- name: Setting up Certbot
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/certbot.yml
|
||||||
|
listen: certbot
|
||||||
|
- name: Setting up TOR
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/tor.yml
|
||||||
|
listen: tor
|
||||||
|
- name: Setting up Wireguard
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/wireguard.yml
|
||||||
|
listen: wireguard
|
||||||
|
- name: Setting up Crowdsec
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/crowdsec.yml
|
||||||
|
listen: crowdsec
|
||||||
|
- name: Setting up Headscale
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/headscale.yml
|
||||||
|
listen: headscale
|
||||||
|
- name: Setting up DSNet
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/dsnet.yml
|
||||||
|
listen: dsnet
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT-0
|
|
||||||
---
|
|
||||||
# handlers file for roles/init-vps
|
|
||||||
- name: Setting up Quartz
|
|
||||||
ansible.builtin.include_tasks:
|
|
||||||
file: tasks/contingent/pkg/quartz.yml
|
|
||||||
listen: quartz
|
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# handlers file for roles/init-vps
|
||||||
|
- name: Skipping to next installaton
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "No post-installaton or additional installation steps needed--continuing..."
|
||||||
|
listen: default
|
||||||
|
- name: Setting up ViM
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/vim.yml
|
||||||
|
listen: vim
|
||||||
|
- name: Settng up NeoViM
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/neovim.yml
|
||||||
|
listen: neovim
|
||||||
|
- name: Settng up Difftastic
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/difftastic.yml
|
||||||
|
listen: difftastic
|
||||||
|
- name: Settng up Git
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/git.yml
|
||||||
|
listen: git
|
||||||
|
- name: Setting up NodeJS
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/nvm.yml
|
||||||
|
listen: nvm
|
||||||
|
- name: Setting up Rust
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/rustup.yml
|
||||||
|
listen: rustup
|
||||||
|
- name: Setting up Julia
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/julia.yml
|
||||||
|
listen: julia
|
||||||
|
- name: Setting up UV
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/uv.yml
|
||||||
|
listen: uv
|
||||||
|
- name: Setting up Podman
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/podman.yml
|
||||||
|
listen: podman
|
||||||
|
- name: Setting up Podman Compose sources
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/skato_compose.yml
|
||||||
|
listen: skato_compose
|
||||||
|
- name: Setting up Quartz
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/quartz.yml
|
||||||
|
listen: quartz
|
||||||
|
- name: Setting up native CLI tools sources
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/skato_cli.yml
|
||||||
|
listen: skato_cli
|
||||||
|
- name: Setting up blog theme
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/skato_blog_theme.yml
|
||||||
|
listen: skato_blog_theme
|
||||||
|
- name: Setting up blog
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/skato_blog.yml
|
||||||
|
listen: skato_blog
|
||||||
|
- name: Setting up website sources
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/sukaato.yml
|
||||||
|
listen: sukaato
|
||||||
|
- name: Setting up Surge
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/surge.yml
|
||||||
|
listen: surge
|
||||||
|
- name: Setting up Aria2
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/aria.yml
|
||||||
|
listen: aria
|
||||||
|
- name: Setting up Radicle
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/radicle.yml
|
||||||
|
listen: radicle
|
||||||
|
- name: Setting up TOTP
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: tasks/contingent/pkg/libpam-google-authenticator.yml
|
||||||
|
listen: libpam-google-authenticator
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
- 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: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Setting the FQDN for development
|
||||||
|
# when: compose.mode == "dev"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# web_fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Setting the FQDN
|
||||||
|
# when: compose.mode == "prod"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
web_fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Creating directory to store configuration file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.aria2"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Configuring Aria2
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/aria2/aria2.conf.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.aria2/aria2.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
# validate: "aria2c --check"
|
||||||
|
- name: Setting up Aria2 as a service
|
||||||
|
when: aria.rpc.enabled and not aria.containerized
|
||||||
|
block:
|
||||||
|
- name: Creating a user SystemD service unit for Aria2
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: user/config/systemd/user/aria2cd.service
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/systemd/user/aria2cd.service"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Starting and enabling user SystemD service unit for Aria2
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: aria2cd
|
||||||
|
scope: user
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
daemon_reload: true
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
---
|
||||||
|
- name: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Modifying FQDN list for development
|
||||||
|
# when: "certbot.mode == 'dev'"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# web_fqdns: "{{ certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | list }}"
|
||||||
|
- name: Modifying FQDN list for development
|
||||||
|
# when: "certbot.mode == 'prod'"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
web_fqdns: "{{ certbot.domains }}"
|
||||||
|
- name: Creating domain arguments for certbot
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
certbot_domains: "{{ ['-d'] | product(web_fqdns) | map('join', '=') | list }}"
|
||||||
|
- name: Getting public IP
|
||||||
|
community.general.ipify_facts:
|
||||||
|
validate_certs: false
|
||||||
|
timeout: 20
|
||||||
|
- name: Starting domain name registration with standalone DNS
|
||||||
|
when: "certbot.auth_method == 'dns' and not certbot.containerized"
|
||||||
|
ignore_errors: true
|
||||||
|
block:
|
||||||
|
- name: Opening port 53
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: 53
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Opening up port 53
|
||||||
|
# @NOTE https://github.com/siilike/certbot-dns-standalone
|
||||||
|
- name: Exemplifying needed ACME record
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
acme_record: |
|
||||||
|
{{ fqdn | default(inventory_hostname) }} IN A {{ ipify_public_ip }}
|
||||||
|
_acme-challenge.{{ fqdn | default(inventory_hostname) }} IN CNAME {{ fqdn | default(inventory_hostname) }}.acme.{{ fqdn | default(inventory_hostname) }}.
|
||||||
|
acme.{{ fqdn | default(inventory_hostname) }} IN NS ns.acme.{{ fqdn | default(inventory_hostname) }}.
|
||||||
|
ns.acme.{{ fqdn | default(inventory_hostname) }} IN A {{ ipify_public_ip }}
|
||||||
|
- name: Informing user of need to set up ACME record
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Please set ACME record in domain name provider:\n {{ acme_record }}"
|
||||||
|
- name: Waiting for user to set up ACME records
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Running certbot to authenticate and acquire domain name certificates
|
||||||
|
become: true
|
||||||
|
when: "certbot.mode == 'dev'"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- certbot
|
||||||
|
- certonly
|
||||||
|
- "--staging"
|
||||||
|
- "--debug"
|
||||||
|
- "--authenticator=dns-standalone"
|
||||||
|
- "--email={{ certbot.email }}"
|
||||||
|
- "--agree-tos"
|
||||||
|
- "--non-interactive"
|
||||||
|
- "--dns-standalone-address={{ ipify_public_ip }}"
|
||||||
|
# - "--dns-standalone-ipv6-address={{ ansible_default_ipv6.address | default(ansible_all_ipv6_addresses[0]) }}"
|
||||||
|
- "--dns-standalone-port={{ certbot.port }}"
|
||||||
|
- "{{ certbot_domains[0] }}"
|
||||||
|
- "{{ certbot_domains[1] }}"
|
||||||
|
- name: Running certbot to authenticate and acquire domain name certificates
|
||||||
|
become: true
|
||||||
|
when: "certbot.mode == 'prod'"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- certbot
|
||||||
|
- certonly
|
||||||
|
- "--authenticator=dns-standalone"
|
||||||
|
- "--email={{ certbot.email }}"
|
||||||
|
- "--agree-tos"
|
||||||
|
- "--non-interactive"
|
||||||
|
- "--dns-standalone-address={{ ipify_public_ip }}"
|
||||||
|
# - "--dns-standalone-ipv6-address={{ ansible_default_ipv6.address | default(ansible_all_ipv6_addresses[0]) }}"
|
||||||
|
- "--dns-standalone-port={{ certbot.port }}"
|
||||||
|
- "{{ certbot_domains[0] }}"
|
||||||
|
- "{{ certbot_domains[1] }}"
|
||||||
|
- name: Starting domain name registration with standalone option
|
||||||
|
when: "certbot.auth_method == 'standalone' and not certbot.containerized"
|
||||||
|
ignore_errors: true
|
||||||
|
block:
|
||||||
|
- name: Opening port 80
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: 80
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 80
|
||||||
|
- name: Acquiring domain certificates
|
||||||
|
become: true
|
||||||
|
when: "certbot.mode == 'dev'"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- certbot
|
||||||
|
- certonly
|
||||||
|
- "--staging"
|
||||||
|
- "--debug"
|
||||||
|
- "--standalone"
|
||||||
|
- "--preferred-challenges=http-01"
|
||||||
|
- "--email={{ certbot.email }}"
|
||||||
|
- "--agree-tos"
|
||||||
|
- "--non-interactive"
|
||||||
|
- "{{ certbot_domains[0] }}"
|
||||||
|
- "{{ certbot_domains[1] }}"
|
||||||
|
- name: Acquiring domain certificates
|
||||||
|
become: true
|
||||||
|
when: "certbot.mode == 'dev'"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- certbot
|
||||||
|
- certonly
|
||||||
|
- "--standalone"
|
||||||
|
- "--email {{ certbot.email }}"
|
||||||
|
- "--agree-tos"
|
||||||
|
- "--non-interactive"
|
||||||
|
- "--preferred-challenges http-01"
|
||||||
|
- "{{ certbot_domains[0] }}"
|
||||||
|
- "{{ certbot_domains[1] }}"
|
||||||
|
- name: Creating needed directory for renewal pre- hooks
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/letsencrypt/renewal-hooks/pre
|
||||||
|
recurse: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Copying renewal pre- hook to renewal pre- hook path
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: letsencrypt/renewal-hooks/pre/down-dependents.sh
|
||||||
|
dest: /etc/letsencrypt/renewal-hooks/pre/
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating needed directory for renewal post- hooks
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/letsencrypt/renewal-hooks/post
|
||||||
|
recurse: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Copying renewal post- hook to renewal post- hook path
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: letsencrypt/renewal-hooks/post/up-dependents.sh
|
||||||
|
dest: /etc/letsencrypt/renewal-hooks/post/
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Starting domain name registration with webroot option
|
||||||
|
when: "certbot.auth_method == 'webroot' and not certbot.containerized"
|
||||||
|
block: []
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
- name: Preparing non-containerized Crowdsec
|
||||||
|
when: not crowdsec.containerized
|
||||||
|
block:
|
||||||
|
- name: Changing the address and port of the Crowdsec server
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/crowdsec/config.yaml
|
||||||
|
insertafter: EOF
|
||||||
|
regexp: "^ {4}listen_uri"
|
||||||
|
line: " listen_uri: localhost:{{ crowdsec.port }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
- name: Changing the address of the Crowdsec Prometheus server
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/crowdsec/config.yaml
|
||||||
|
regexp: "^ {2}listen_addr"
|
||||||
|
insertafter: EOF
|
||||||
|
line: " listen_addr: localhost"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
- name: Changing target or expected address for credentials of the Crowdsec local API
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/crowdsec/local_api_credentials.yaml
|
||||||
|
insertafter: EOF
|
||||||
|
regexp: "^url"
|
||||||
|
line: "url: http://localhost:{{ crowdsec.port }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
- name: Restarting SystemD service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: crowdsec
|
||||||
|
scope: system
|
||||||
|
state: restarted
|
||||||
|
- name: Adding remediation component or bouncer
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "cscli bouncers add {{ item }}"
|
||||||
|
loop: "{{ crowdsec.bouncers }}"
|
||||||
|
- name: Installing Crowdsec collections
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "cscli collections install {{ item }}"
|
||||||
|
loop: "{{ crowdsec.colls }}"
|
||||||
|
- name: Installing Crowdsec parsers
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "cscli parsers install {{ item }}"
|
||||||
|
loop: "{{ crowdsec.parsers }}"
|
||||||
|
- name: Installing Crowdsec scenarios
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "cscli scenarios install {{ item }}"
|
||||||
|
loop: "{{ crowdsec.scenarios }}"
|
||||||
|
- name: Installing Crowdsec postoverflows
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "cscli postoverflows install {{ item }}"
|
||||||
|
loop: "{{ crowdsec.postoverflows }}"
|
||||||
|
- name: Restarting SystemD service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: crowdsec
|
||||||
|
scope: system
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/downloads/archives/released/difftastic/{{ item }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.local/bin/{{ item }}"
|
||||||
|
state: hard
|
||||||
|
loop:
|
||||||
|
- difft
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
become: true
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/downloads/archives/released/difftastic/{{ item }}"
|
||||||
|
dest: "/usr/bin/{{ item }}"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- difft
|
||||||
|
- name: Configuring usage of Difftastic as default git difference tool for user
|
||||||
|
community.general.git_config:
|
||||||
|
name: diff.tool
|
||||||
|
scope: global
|
||||||
|
value: difftastic
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
- 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: Initializing DSNet
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: dsnet init
|
||||||
|
- name: Running DSNet VPN service interface
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: dsnet up
|
||||||
|
- name: Creating a directory to house VPN service client configurations
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Adding peer device for DSNet VPN service interface
|
||||||
|
become: true
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "dsnet add {{ item.name }}{{ idx }} --owner {{ current_user.stdout }} --description 'For {{ item.name }}--{{ item.desc }}' --confirm > {{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ idx }}.conf"
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Changing ownership of consequent DSNet VPN service client configurations
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "600"
|
||||||
|
state: file
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Pausing to inquire about how to proceed
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Type \"fetch\" to get the DSNet VPN service client configuration files, or \"show\" to see their contents for manual copying instead"
|
||||||
|
echo: true
|
||||||
|
register: data_method
|
||||||
|
- name: Presenting DSNet VPN service client configuration files to control node for copying
|
||||||
|
when: data_method.user_input == "show"
|
||||||
|
block:
|
||||||
|
- name: Acquiring contents of DSNet VPN service client configuration files
|
||||||
|
ansible.builtin.slurp:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
register: vpn_client_configs
|
||||||
|
- name: Presenting contents of DSNet VPN service client configurations to control node
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Copy this client configuration of the DSNet VPN service:\n {{ item.content | b64decode }}"
|
||||||
|
loop: "{{ vpn_client_configs.results }}"
|
||||||
|
- name: Giving opportunity to manually copy contents of DSNet VPN service client configuration files
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Providing DSNet VPN service client configuration files to control node machine
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
block:
|
||||||
|
- name: Informing user of inventory requirements for VPN clients
|
||||||
|
when: ((fqdn is undefined or fqdn == None) and item.name != fqdn) or not item.name in groups.homeserver
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: The VPN client must be the name of an inventory host in a homeserver group
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
- name: Dupliciating DSNet VPN service client configuration files to control node
|
||||||
|
when: ((fqdn is defined and fqdn != None) and item.name == fqdn) or item.name in groups.homeserver
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
dest: "./.tmp/{{ inventory_hostname }}-dsnet/"
|
||||||
|
flat: true
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Dupliciating DSNet VPN service client configuration files to control node
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
dest: "./roles/init-server/files/user/wg/containerized/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
flat: true
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Informing control node of acquired files
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "The DSNet VPS service client configuration files have been duplicated to \"{{ item }}\" at the control node."
|
||||||
|
loop:
|
||||||
|
- "./.tmp/{{ inventory_hostname }}-dsnet/"
|
||||||
|
- "./roles/init-server/files/user/wg/"
|
||||||
|
- name: Giving control node user time to read the aforementiioned message
|
||||||
|
ansible.builtin.pause:
|
||||||
|
seconds: 30
|
||||||
|
- name: Ensuring IP forwarding is allowed
|
||||||
|
become: true
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: "net.{{ item }}.ip_forward"
|
||||||
|
value: "1"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- ipv4
|
||||||
|
# - ipv6
|
||||||
|
- name: Creating SystemD unit for placing up DSNet interface
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: systemd/system/dsnet.service
|
||||||
|
dest: /etc/systemd/system/dsnet.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Reloading SystemD and enabling DSNet interface
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: dsnet
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
- name: Copying script for DSNet iptables rules
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: usr/local/bin/dsnet-forward.sh.j2
|
||||||
|
dest: /usr/local/bin/dsnet-forward.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating SystemD unit for DSNet iptables rules
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: systemd/system/thrunet.service
|
||||||
|
dest: /etc/systemd/system/thrunet.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Reloading SystemD
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: thrunet
|
||||||
|
daemon_reload: true
|
||||||
|
- name: Opening port 51820
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 51820
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 51820
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
- 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 }}"
|
||||||
|
- name: Configuring system-level git settings
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Making commit feedback more verbose
|
||||||
|
community.general.git_config:
|
||||||
|
name: commit.verbose
|
||||||
|
scope: system
|
||||||
|
value: "true"
|
||||||
|
state: present
|
||||||
|
- name: Setting default merge conflict approach algorithm
|
||||||
|
community.general.git_config:
|
||||||
|
name: merge.conflictstyle
|
||||||
|
scope: system
|
||||||
|
value: zdiff3
|
||||||
|
state: present
|
||||||
|
- name: Setting default merging tool for conflicts
|
||||||
|
community.general.git_config:
|
||||||
|
name: merge.tool
|
||||||
|
scope: system
|
||||||
|
value: nvimdiff
|
||||||
|
state: present
|
||||||
|
- name: Ensuring backups prior to merge solution implementation
|
||||||
|
community.general.git_config:
|
||||||
|
name: merge.keebbackup
|
||||||
|
scope: system
|
||||||
|
value: "true"
|
||||||
|
state: present
|
||||||
|
- name: Configuring rebase to autosquash
|
||||||
|
community.general.git_config:
|
||||||
|
name: rebase.autosquash
|
||||||
|
scope: system
|
||||||
|
value: "true"
|
||||||
|
state: present
|
||||||
|
- name: Enforcng error message for missing entries in local commit history
|
||||||
|
community.general.git_config:
|
||||||
|
name: rebase.missingCommitsCheck
|
||||||
|
scope: system
|
||||||
|
value: error
|
||||||
|
state: present
|
||||||
|
- name: Setting the default branch's default name on repository initialization
|
||||||
|
community.general.git_config:
|
||||||
|
name: init.defaultBranch
|
||||||
|
scope: system
|
||||||
|
value: main
|
||||||
|
state: present
|
||||||
|
- name: Setting default pager for, or called by, git
|
||||||
|
community.general.git_config:
|
||||||
|
name: core.pager
|
||||||
|
scope: system
|
||||||
|
value: delta
|
||||||
|
state: present
|
||||||
|
- name: Ensuring git push/pull space handling compatibility with non-Linux operating systems
|
||||||
|
community.general.git_config:
|
||||||
|
name: core.autocrlf
|
||||||
|
scope: system
|
||||||
|
value: "false"
|
||||||
|
state: present
|
||||||
|
- name: Setting default text editor for, or called by, git
|
||||||
|
community.general.git_config:
|
||||||
|
name: core.editor
|
||||||
|
scope: system
|
||||||
|
value: nvim
|
||||||
|
state: present
|
||||||
|
- name: Setting difference filtering tool to delta
|
||||||
|
community.general.git_config:
|
||||||
|
name: interactive.diffFilter
|
||||||
|
scope: system
|
||||||
|
value: delta
|
||||||
|
state: present
|
||||||
|
- name: Setting default difference- finding or presenting approach algorithm
|
||||||
|
community.general.git_config:
|
||||||
|
name: diff.algorithm
|
||||||
|
scope: system
|
||||||
|
value: histogram
|
||||||
|
state: present
|
||||||
|
- name: Setting difference tool for, or called by, git
|
||||||
|
community.general.git_config:
|
||||||
|
name: diff.tool
|
||||||
|
scope: system
|
||||||
|
value: nvimdiffs
|
||||||
|
state: present
|
||||||
|
- name: Setting the default amount of context for git to show around a difference
|
||||||
|
community.general.git_config:
|
||||||
|
name: diff.context
|
||||||
|
scope: system
|
||||||
|
value: "10"
|
||||||
|
state: present
|
||||||
|
- name: Ensuring data integrity and validity is checked prior to fetch or transfer actions
|
||||||
|
community.general.git_config:
|
||||||
|
name: "{{ item }}.fsckobjects"
|
||||||
|
scope: system
|
||||||
|
value: "true"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- transfer
|
||||||
|
- fetch
|
||||||
|
- name: Ensuring data integrity and validity is checked prior to reception of data
|
||||||
|
community.general.git_config:
|
||||||
|
name: receive.fsckObjects
|
||||||
|
scope: system
|
||||||
|
value: "true"
|
||||||
|
state: present
|
||||||
|
- name: Setting git TUI to have color
|
||||||
|
community.general.git_config:
|
||||||
|
name: color.ui
|
||||||
|
scope: system
|
||||||
|
value: "true"
|
||||||
|
state: present
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
---
|
||||||
|
- 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: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Setting the FQDN for development
|
||||||
|
# when: compose.mode == "dev"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# web_fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Setting the FQDN
|
||||||
|
# when: compose.mode == "prod"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
web_fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Configuring Headscale
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: headscale/config.yaml.j2
|
||||||
|
dest: /etc/headscale/config.yaml
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
# validate: "headscale configtest"
|
||||||
|
- name: Starting SystemD service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: headscale
|
||||||
|
scope: system
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
- name: Registering a headscale user
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "headscale users create {{ headscale.users.admin.username }} -d '{{ headscale.users.admin.dname }}' -e '{{ headscale.users.admin.email }}'"
|
||||||
|
register: headscale_registration
|
||||||
|
changed_when:
|
||||||
|
- "'User created' in headscale_registration.stdout"
|
||||||
|
- name: Creating an authentication key for this registered headscale user
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "headscale preauthkeys create -e 24h -u 1"
|
||||||
|
register: tailscale_admin_authkey
|
||||||
|
- name: Pausing to inquire about how to proceed
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Type \"fetch\" to get the DSNet VPN service client configuration files, or \"show\" to see their contents for manual copying instead"
|
||||||
|
echo: true
|
||||||
|
register: data_method
|
||||||
|
- name: Choosing Headscale authentication key to control node for copying
|
||||||
|
when: data_method.user_input == "show"
|
||||||
|
block:
|
||||||
|
- name: Presenting Headscale authentication key to Control Node
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Copy this client configuration of the headscale service:\n {{ tailscale_admin_authkey.stdout }}"
|
||||||
|
- name: Giving opportunity to manually copy Headscale authentication key
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Choosing Headscale service client configuration files to control node machine
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
block:
|
||||||
|
- name: Creating temporary file on managed node that stores Headscale authentication key
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ tailscale_admin_authkey.stdout }}"
|
||||||
|
dest: "/tmp/headscale.key"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
register: tailscale_admin_authkey_file
|
||||||
|
- name: Placing Headscale authentication key into file on control node
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ tailscale_admin_authkey_file.dest }}"
|
||||||
|
dest: "./.tmp/{{ inventory_hostname }}-{{ headscale.users.admin.username }}@headscale/headscale.key"
|
||||||
|
flat: true
|
||||||
|
- name: Placing Headscale authentication key into file on control node
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ tailscale_admin_authkey_file.dest }}"
|
||||||
|
dest: "./roles/init-server/files/{{ item.name }}-{{ headscale.users.admin.username }}@headscale/headscale{{ (idx | string) }}.key"
|
||||||
|
flat: true
|
||||||
|
loop: "{{ headscale.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Informing control node of acquired files
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "The Headscale authentication key files have been duplicated to './.tmp/{{ inventory_hostname }}-{{ headscale.users.admin.username }}@headscale/headscale.key' at the control node."
|
||||||
|
- name: Giving control node user time to read the aforementiioned message
|
||||||
|
ansible.builtin.pause:
|
||||||
|
seconds: 30
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- 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: Executing shell-scripted installation process for Julia
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "{{ ansible_user_home.stdout }}/.local/bin/julia-install.sh --yes"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/.juliaup/bin"
|
||||||
|
async: 900
|
||||||
|
poll: 5
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
become: true
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.juliaup/bin/{{ item }}"
|
||||||
|
dest: "/usr/bin/{{ item }}"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- julia
|
||||||
|
- julialauncher
|
||||||
|
- juliaup
|
||||||
|
# - name: Reboot machine for shell environment change
|
||||||
|
# ansible.builtin.reboot:
|
||||||
|
# msg: Rebooting machine
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Setting up TOTP using Google Authenticator
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "google-authenticator"
|
||||||
|
- "-t"
|
||||||
|
- "-d"
|
||||||
|
- "-f"
|
||||||
|
- "-C"
|
||||||
|
- "-q"
|
||||||
|
- "-l {{ ansible_user }}@{{ inventory_hostname }}"
|
||||||
|
- "-i {{ inventory_hostname }}"
|
||||||
|
- "--qr-mode=NONE"
|
||||||
|
- "-r 7"
|
||||||
|
- "-R 300"
|
||||||
|
- "-w 9"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/.google_authenticator"
|
||||||
|
- name: Pausing to inquire about how to proceed
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Type \"fetch\" to get the TOTP secret and backup codes, or \"show\" to see it for manual copying instead"
|
||||||
|
echo: true
|
||||||
|
register: data_method
|
||||||
|
- name: Choosing to present TOTP secret and backup codes to Control Node
|
||||||
|
when: data_method.user_input == "show"
|
||||||
|
block:
|
||||||
|
- name: Acquiring contents of file containing TOTP secret and backup codes
|
||||||
|
ansible.builtin.slurp:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.google_authenticator"
|
||||||
|
register: totp_token
|
||||||
|
- name: Presenting TOTP secret and backup codes to Control Node
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Make sure to store the following TOTP secret and backup codes for Google Authenticator:\n {{ totp_token.content | b64decode }}"
|
||||||
|
- name: Giving opportunity to manually copy TOTP secret and backup codes
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Choosing to provide file on control node containing TOTP secret and backup codes
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
block:
|
||||||
|
- name: Placing TOTP secret and backup codes into file on control node
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.google_authenticator"
|
||||||
|
dest: "./.tmp/{{ inventory_hostname }}-google-auth/google_auth.secret"
|
||||||
|
flat: true
|
||||||
|
- name: Informing control node of acquired files
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "The TOTP secret and backup codes file has been duplicated to './.tmp/{{ inventory_hostname }}-google-auth/google-auth.secret' at the control node."
|
||||||
|
- name: Giving control node user time to read the aforementiioned message
|
||||||
|
ansible.builtin.pause:
|
||||||
|
seconds: 30
|
||||||
|
- name: Adding Google Authenticator OTP module PAM authentication line for SSH
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/pam.d/sshd
|
||||||
|
line: "auth sufficient pam_google_authenticator.so nullok"
|
||||||
|
insertafter: "include common-auth$"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
- name: Prioritizing authentication methods in SSH
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config.d/auth.conf
|
||||||
|
line: "KbdInteractiveAuthentication yes # enable if implementing TOTP 2FA"
|
||||||
|
regexp: "^KbdInteractiveAuthentication"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
- name: Prioritizing authentication methods in SSH
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config.d/auth.conf
|
||||||
|
line: "AuthenticationMethods publickey keyboard-interactive:pam"
|
||||||
|
insertafter: "^KbdInteractiveAuthentication"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
# - name: Adding Google Authenticator OTP module PAM authentication line for SSH
|
||||||
|
# become: true
|
||||||
|
# ansible.builtin.lineinfile:
|
||||||
|
# path: /etc/pam.d/sudo
|
||||||
|
# line: "auth required pam_google_authenticator.so nullok"
|
||||||
|
# insertafter: "include common-auth$"
|
||||||
|
# owner: root
|
||||||
|
# group: root
|
||||||
|
# mode: "644"
|
||||||
|
# - name: Adding Google Authenticator OTP module PAM authentication line for SSH
|
||||||
|
# become: true
|
||||||
|
# ansible.builtin.lineinfile:
|
||||||
|
# path: /etc/pam.d/su
|
||||||
|
# line: "auth required pam_google_authenticator.so nullok"
|
||||||
|
# insertafter: "include common-auth$"
|
||||||
|
# owner: root
|
||||||
|
# group: root
|
||||||
|
# mode: "644"
|
||||||
|
- name: Restarting SystemD SSH service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
- 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: Creating directory tree for NeoViM configuration files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/nvim"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Configuring NeoViM
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: user/config/nvim/init.vim
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/nvim/init.vim"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Find all NVM pre-built binary (sub)directories
|
||||||
|
ansible.builtin.find:
|
||||||
|
paths: "{{ ansible_user_home.stdout }}/downloads/archives/released/nvm"
|
||||||
|
patterns: "^node-v[0-9]*\\."
|
||||||
|
file_type: directory
|
||||||
|
use_regex: true
|
||||||
|
register: prebuilt_nodes
|
||||||
|
- name: Bootstrapping NVM
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Grabbing only path information for pre-built binary (sub)directories
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
prebuilt_nodepaths: "{{ prebuilt_nodes.files | map(attribute='path') }}"
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/bin/{{ item[1] }}"
|
||||||
|
dest: "/usr/bin/{{ item[1] }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['node']) }}"
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/lib/node_modules/corepack/dist/{{ item[1] }}.js"
|
||||||
|
dest: "/usr/bin/{{ item[1] }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['corepack']) }}"
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/lib/node_modules/npm/bin/{{ item[1] }}-cli.js"
|
||||||
|
dest: "/usr/bin/{{ item[1] }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['npm','npx']) }}"
|
||||||
|
- name: Link includes to directories already recognized by system
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/include/{{ item[1] }}"
|
||||||
|
dest: "/usr/include/{{ item[1] }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['node']) }}"
|
||||||
|
- name: Link requisite libraries to directories already recognized by system
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/lib/{{ item[1] }}"
|
||||||
|
dest: "/usr/lib/{{ item[1] }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['node_modules']) }}"
|
||||||
|
- name: Create man1 subdirectory for man pages
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/share/man/man1
|
||||||
|
recurse: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
state: directory
|
||||||
|
- name: Link shared resources to directories already recognized by system
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/share/man/man1/{{ item[1] }}.1"
|
||||||
|
dest: "/usr/share/man/man1/{{ item[1] }}.1"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['node']) }}"
|
||||||
|
- name: Create man1 subdirectory for man pages
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/share/doc
|
||||||
|
recurse: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
state: directory
|
||||||
|
- name: Link shared resources to directories already recognized by system
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ item[0] }}/share/doc/{{ item[1] }}"
|
||||||
|
dest: "/usr/share/doc/{{ item[1] }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ prebuilt_nodepaths | product(['node']) }}"
|
||||||
|
# - name: Reboot machine for shell environment change
|
||||||
|
# ansible.builtin.reboot:
|
||||||
|
# msg: Rebooting machine
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
- 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: Ensuring user namespace support is enabled
|
||||||
|
become: true
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: kernel.unprivileged_userns_clone
|
||||||
|
value: "1"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
- name: Ensuring user namespace support is enabled
|
||||||
|
become: true
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.ip_unprivileged_port_start
|
||||||
|
value: "0"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
- name: Creating container directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/containers"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Configuring container storage
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/config/containers/storage.conf.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/containers/storage.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Configuring container image registries
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: user/config/containers/registries.conf
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/containers/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
# @NOTE https://oneuptime.com/blog/post/2026-01-27-podman-rootless/view#configuring-registries
|
||||||
|
# @NOTE https://github.com/podman-container-tools/podman/blob/main/docs/tutorials/rootless_tutorial.md#using-volumes
|
||||||
|
# @NOTE https://github.com/containers/podman-compose/issues/166#issuecomment-1550515230
|
||||||
|
- name: Enabling and starting SystemD unit service for automatic restart of containers/pods
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: podman-restart
|
||||||
|
scope: system
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
@@ -1,26 +1,183 @@
|
|||||||
---
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Setting the FQDN for development
|
||||||
|
# when: compose.mode == "dev"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# web_fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Setting the FQDN for production
|
||||||
|
# when: compose.mode == "prod"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
web_fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Linking repository to another path
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/repos/.foreign/quartz"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/skato-quartz"
|
||||||
|
state: link
|
||||||
- name: Installing NodeJS dependencies of quartz software
|
- name: Installing NodeJS dependencies of quartz software
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
community.general.npm:
|
community.general.npm:
|
||||||
executable: "{{ ansible_facts['user_dir'] }}/.nvm/versions/node/v24.11.1/lib/node_modules/npm"
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign/quartz"
|
||||||
path: "{{ ansible_facts['user_dir'] }}/repos/.foreign/quartz"
|
|
||||||
state: latest
|
state: latest
|
||||||
- name: Configuring quartz software
|
- name: Configuring quartz software
|
||||||
block:
|
block:
|
||||||
|
- name: Creating path for Quartz content files (path for Obsidian vaults)
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/journal/notes"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Creating some initial text content for Quartz
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "user/journal/notes/index.md.j2"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/journal/notes/index.md"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
backup: true
|
||||||
|
- name: Creating some initial image content for Quartz
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: user/journal/mythe-sisyphus-klein.png
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/journal/notes/mythe-sisyphus-klein.png"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
backup: true
|
||||||
- name: Initializing quartz website
|
- name: Initializing quartz website
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
chdir: "{{ ansible_facts['user_dir'] }}/repos/.foreign/quartz"
|
argv:
|
||||||
cmd: npx quartz create
|
- npx
|
||||||
register: stdout
|
- "-y"
|
||||||
changed_when: stdout.rc == 0
|
- quartz
|
||||||
|
- create
|
||||||
|
- "-b"
|
||||||
|
- notes.{{ web_fqdn }}"
|
||||||
|
- "-t"
|
||||||
|
- obsidian
|
||||||
|
- "-s"
|
||||||
|
- "{{ ansible_user_home.stdout }}/journal/notes"
|
||||||
|
- "-X"
|
||||||
|
- symlink
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/repos/.foreign/quartz"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/repos/.foreign/quartz/content/index.md"
|
||||||
- name: Installing quartz plugins referenced in website template
|
- name: Installing quartz plugins referenced in website template
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
chdir: "{{ ansible_facts['user_dir'] }}/repos/.foreign/quartz"
|
argv:
|
||||||
cmd: npx quartz plugin install --from-config
|
- npx
|
||||||
register: stdout
|
- "-y"
|
||||||
changed_when: stdout.rc == 0
|
- quartz
|
||||||
# - name: Starting quartz site web server
|
- plugin
|
||||||
# ansible.builtin.command:
|
- install
|
||||||
# chdir: "{{ ansible_facts['user_dir'] }}/repos/.foreign/quartz"
|
chdir: "{{ ansible_user_home.stdout }}/repos/.foreign/quartz"
|
||||||
# cmd: npx quartz build --serve
|
- name: Starting quartz site web server
|
||||||
# register: stdout
|
become: true
|
||||||
# changed_when: stdout
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- npx
|
||||||
|
- "-y"
|
||||||
|
- quartz
|
||||||
|
- build
|
||||||
|
- "-o"
|
||||||
|
- "{{ ansible_user_home.stdout }}/srv/notes.{{ web_fqdn }}"
|
||||||
|
- "--concurrency"
|
||||||
|
- "3"
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/repos/.foreign/quartz"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/srv/notes.{{ web_fqdn }}/index.html"
|
||||||
|
- name: Creating directory for caddy configuration
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "(caddy is defined and caddy != None) and caddy.containerized and mode == 'prod'"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
notes.{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/notes.{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED NOTES DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
create: true
|
||||||
|
state: present
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "(caddy is defined and caddy != None) and caddy.containerized and (mode == 'dev' or caddy.scheme == 'http')"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://notes.{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/notes.{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED NOTES DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
create: true
|
||||||
|
state: present
|
||||||
|
- name: Checking the status of podman containers
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- podman
|
||||||
|
- ps
|
||||||
|
register: podman_status
|
||||||
|
- name: Restarting webserver / reverse proxy container
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: "'revproxy0' in podman_status.stdout and (caddy is defined and caddy != None) and caddy.containerized"
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ compose.containers.webserver.name }}"
|
||||||
|
state: started
|
||||||
|
force_restart: true
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
- 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: Executing shell-scripted installation process for Radicle
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "{{ ansible_user_home.stdout }}/.local/bin/radicle-install.sh"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/.radicle"
|
||||||
|
async: 600
|
||||||
|
poll: 5
|
||||||
|
- name: Bootstrapping Radicle
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.radicle/bin/{{ item }}"
|
||||||
|
dest: "/usr/bin/{{ item }}"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- rad
|
||||||
|
- radicle-node
|
||||||
|
- git-remote-rad
|
||||||
|
- name: Create man1 subdirectory for man pages
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/share/man/man1
|
||||||
|
recurse: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
state: directory
|
||||||
|
- name: Link manpages to Linux manpage directories
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.radicle/man/man1/{{ item }}.1"
|
||||||
|
dest: "/usr/share/man/man1/{{ item }}.1"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- rad
|
||||||
|
- radicle-node
|
||||||
|
- git-remote-rad
|
||||||
|
- rad-id
|
||||||
|
- rad-patch
|
||||||
|
# - name: Reboot machine for shell environment change
|
||||||
|
# ansible.builtin.reboot:
|
||||||
|
# msg: Rebooting machine
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
- 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: Executing shell-scripted installation process for Rust
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "{{ ansible_user_home.stdout }}/.local/bin/rustup-install.sh -yq"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/.cargo/bin"
|
||||||
|
async: 600
|
||||||
|
poll: 5
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
become: true
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.cargo/bin/{{ item }}"
|
||||||
|
dest: "/usr/bin/{{ item }}"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- rustup
|
||||||
|
# - name: Reboot machine for shell environment change
|
||||||
|
# ansible.builtin.reboot:
|
||||||
|
# msg: Rebooting machine
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Setting the FQDN for development
|
||||||
|
# when: compose.mode == "dev"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# web_fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Setting the FQDN
|
||||||
|
# when: compose.mode == "prod"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
web_fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Moving git repository from initial path
|
||||||
|
block:
|
||||||
|
- name: Recursively copying directory and its contents to elsewhere
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.blog.name }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
register: new_blog_path
|
||||||
|
- name: Deleting directory at previous path
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.blog.name }}"
|
||||||
|
state: absent
|
||||||
|
- name: Creating directory for new bare repository
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating bare repository
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "git init --bare {{ source_code.repos.blog.name }}.git"
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/src/{{ source_code.repos.blog.name }}.git"
|
||||||
|
- name: Running Hugo blog
|
||||||
|
when: source_code.repos.blog.run
|
||||||
|
block:
|
||||||
|
- name: Creating path for Hugo content files
|
||||||
|
when: caddy.containerized and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/journal/blog"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Creating some initial text content for Hugo
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: caddy.containerized and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "user/journal/blog/_index.md.j2"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/journal/blog/index.md"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
backup: true
|
||||||
|
- name: Creating some initial image content for Hugo
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: caddy.containerized and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "user/journal/mythe-sisyphus-klein.png"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/journal/blog/mythe-sisyphus-klein.png"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
backup: true
|
||||||
|
- name: Creating subdirectory for blog website root
|
||||||
|
when: caddy.containerized and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/srv/blog.{{ web_fqdn }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Build Hugo blog at additional webroot
|
||||||
|
when: caddy.containerized and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- hugo
|
||||||
|
- "--quiet"
|
||||||
|
- "-b"
|
||||||
|
- "https://blog.{{ web_fqdn }}/"
|
||||||
|
- "-c"
|
||||||
|
- "{{ ansible_user_home.stdout }}/journal/blog"
|
||||||
|
- "-d"
|
||||||
|
- "{{ ansible_user_home.stdout }}/srv/blog.{{ web_fqdn }}"
|
||||||
|
- "--cleanDestinationDir"
|
||||||
|
chdir: "{{ new_blog_path.dest }}"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/srv/blog.{{ web_fqdn }}/index.html"
|
||||||
|
# @TODO write error Caddy template HTML file at the blog's web root
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: caddy.containerized and mode == 'prod' and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
blog.{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/blog.{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED BLOG DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: caddy.containerized and (mode == 'dev' or caddy.scheme == 'http') and (compose.containers.webserver is defined or compose.containers.webserver != None)
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://blog.{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/blog.{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED BLOG DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Checking the status of podman containers
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- podman
|
||||||
|
- ps
|
||||||
|
register: podman_status
|
||||||
|
- name: Restarting webserver / reverse proxy container
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: "'revproxy0' in podman_status.stdout and (caddy is defined and caddy != None) and caddy.containerized"
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ compose.containers.webserver.name }}"
|
||||||
|
state: started
|
||||||
|
force_restart: true
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Moving git repository from initial path
|
||||||
|
block:
|
||||||
|
- name: Recursively copying directory and its contents to elsewhere
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.blog_theme.name }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
register: new_compose_path
|
||||||
|
- name: Deleting directory at previous path
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.blog_theme.name }}"
|
||||||
|
state: absent
|
||||||
|
- name: Creating directory for new bare repository
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating bare repository
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "git init --bare {{ source_code.repos.blog_theme.name }}.git"
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/src/{{ source_code.repos.blog_theme.name }}.git"
|
||||||
|
- name: Running Hugo blog theme
|
||||||
|
when: source_code.repos.blog_theme.run
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
block:
|
||||||
|
- name: Warning about lack of implementation
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: Not yet implemented
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Moving git repository from initial path
|
||||||
|
block:
|
||||||
|
- name: Recursively copying directory and its contents to elsewhere
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.cli.name }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
register: new_compose_path
|
||||||
|
- name: Deleting directory at previous path
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.cli.name }}"
|
||||||
|
state: absent
|
||||||
|
- name: Creating directory for new bare repository
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating bare repository
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "git init --bare {{ source_code.repos.cli.name }}.git"
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/src/{{ source_code.repos.cli.name }}.git"
|
||||||
|
- name: Running CLI utility
|
||||||
|
when: source_code.repos.cli.run
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
block:
|
||||||
|
- name: Warning about lack of implementation
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: Not yet implemented
|
||||||
@@ -0,0 +1,836 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Setting the FQDN for development
|
||||||
|
# when: compose.mode == "dev"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# web_fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Setting the FQDN for production
|
||||||
|
# when: compose.mode == "prod"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
web_fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Moving git repository from initial path
|
||||||
|
block:
|
||||||
|
- name: Recursively copying directory and its contents to elsewhere
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.compose.name }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
register: new_compose_path
|
||||||
|
- name: Deleting directory at previous path
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.compose.name }}"
|
||||||
|
state: absent
|
||||||
|
- name: Creating directory for new bare repository
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating bare repository
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "git init --bare {{ source_code.repos.compose.name }}.git"
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/src/{{ source_code.repos.compose.name }}.git"
|
||||||
|
- name: Creating required SMTP-related container secret
|
||||||
|
become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
line: "{{ email.smtp.password }}"
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.podsecrets/email.pass"
|
||||||
|
insertafter: EOF
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
create: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating environment file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/all.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.all.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: environ
|
||||||
|
- name: Creating environment file for email
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/email.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.email.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: email_environ
|
||||||
|
- name: Creating a directory for container secrets
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.podsecrets"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
state: directory
|
||||||
|
- name: Creating directory for DBMS server configuration
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/{{ item }}"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
loop:
|
||||||
|
- caddy
|
||||||
|
- letsencrypt
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
- gitea
|
||||||
|
- opengist
|
||||||
|
- tailscale
|
||||||
|
- glance
|
||||||
|
- name: Creating directory for main website root
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/srv/{{ web_fqdn }}"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Creating directory for caddy configuration
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
# - name: Pulling all needed container images for Compose services
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
# ansible.builtin.command:
|
||||||
|
# cmd: podman-compose pull
|
||||||
|
# chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Calculating desired container states
|
||||||
|
block:
|
||||||
|
- name: Calculating desired container state for VPN client
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
# @TODO write case of at least one vpn client having a boolean attribute declaring whether it is a container
|
||||||
|
vpn_run: "{{ source_code.repos.compose.run and (vpn.clients | selectattr('name', 'in', web_fqdn) | length) == 1 and (compose.containers.vpn is defined and compose.containers.vpn != None) }}"
|
||||||
|
- name: Calculating desired container state for web server or reverse proxy server
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
server_run: "{{ source_code.repos.compose.run and caddy.containerized and (compose.containers.webserver is defined and compose.containers.webserver != None) }}"
|
||||||
|
- name: Calculatng desired container state for ACME challenge
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
ssl_run: "{{ server_run and certbot.containerized and (compose.containers.ssl is defined and compose.containers.ssl != None) }}"
|
||||||
|
- name: Calculating desired container state for database management
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
dbms_run: "{{ source_code.repos.compose.run and mysql.containerized and (compose.containers.db is defined and compose.containers.db != None) }}"
|
||||||
|
- name: Calculating desired container state for caching server
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
cache_run: "{{ source_code.repos.compose.run and redis.containerized and (compose.containers.cache is defined and compose.containers.cache != None) }}"
|
||||||
|
- name: Calculating desired container state for cloud server
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
cloud_run: "{{ source_code.repos.compose.run and nextcloud.containerized and (compose.containers.cloud is defined and compose.containers.cloud != None) }}"
|
||||||
|
- name: Calculating desired container state for forge server
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
forge_run: "{{ source_code.repos.compose.run and gitea.containerized and (compose.containers.forge is defined and compose.containers.forge != None ) }}"
|
||||||
|
- name: Calculating desired container state for pastebin server
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
pbin_run: "{{ source_code.repos.compose.run and gist.containerized and (compose.containers.pastebin is defined and compose.containers.pastebin != None) }}"
|
||||||
|
- name: Calculating desired container state for tailnet client
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
tail_run: "{{ source_code.repos.compose.run and tailscale.containerized and (compose.containers.tail is defined and compose.containers.tail != None) }}"
|
||||||
|
- name: Calculating desired container state for tailnet dashboard
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
dash_run: "{{ source_code.repos.compose.run and glance.containerized and (compose.containers.dash is defined and compose.containers.dash != None) }}"
|
||||||
|
- name: Running VPN client Compose files
|
||||||
|
when: vpn_run
|
||||||
|
block:
|
||||||
|
- name: Creating subdirectory for VPN client container specified by Compose file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.wg/containerized"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Copying VPN client configuration files
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: ((fqdn is defined and fqdn != None) and item.name == fqdn) or item.name == inventory_hostname
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "user/wg/containerized/{{ item.name }}{{ (idx | string) }}.conf"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.wg/containerized/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
loop: "{{ vpn.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Creating and deploying VPN client container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: source_code.repos.compose.run and (vpn.clients | selectattr("name", "in", web_fqdn) | length) == 1 and (compose.containers.vpn is defined and compose.containers.vpn != None)
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose up -d {{ compose.containers.vpn.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Opening port 51820
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 51820
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 51820
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Spinning up database management container specified by Compose file
|
||||||
|
when: dbms_run
|
||||||
|
block:
|
||||||
|
- name: Creating required container secret for DBMS server container's root account
|
||||||
|
become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
line: "{{ mysql.password }}"
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.podsecrets/root-mysql.pass"
|
||||||
|
insertafter: EOF
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
create: true
|
||||||
|
backup: true
|
||||||
|
- name: Creatng required container secret for DBMS server container's primary non-root account
|
||||||
|
become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
line: "{{ mysql.users.admin.password }}"
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.podsecrets/user-mysql.pass"
|
||||||
|
insertafter: EOF
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
create: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating environment file for DBMS server container specified in Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/mysql.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.mysql.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: mysql_environ
|
||||||
|
- name: Creating and deploying DBMS server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ mysql_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.db.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
# @TODO see if manual creation of additional databases is necessary for the DBMS server container
|
||||||
|
# REDIS
|
||||||
|
- name: Spinning up caching container specified by Compose file
|
||||||
|
when: cache_run
|
||||||
|
block:
|
||||||
|
- name: Creating environment file for DBMS server container specified in Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/redis.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.redis.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: redis_environ
|
||||||
|
- name: Creating and deploying cache server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ environ.dest }} up -d {{ compose.containers.cache.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Spinning up cloud container specified by Compose file
|
||||||
|
when: cloud_run
|
||||||
|
block:
|
||||||
|
- name: Creating database necessary for cloud server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: dbms_run
|
||||||
|
containers.podman.podman_container_exec:
|
||||||
|
name: "{{ compose.containers.db.name }}"
|
||||||
|
argv:
|
||||||
|
- mysql
|
||||||
|
- "-u"
|
||||||
|
- "{{ mysql.users.admin.username }}"
|
||||||
|
- "-p{{ mysql.users.admin.password }}"
|
||||||
|
- "-e"
|
||||||
|
- "'CREATE DATABASE IF NOT EXISTS {{ mysql.users.admin.databases.nextcloud.name }};'"
|
||||||
|
detach: true
|
||||||
|
- name: Creating required cache-related container secret for cloud server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
when: cache_run
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
line: "{{ redis.password }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.podsecrets/redis.pass"
|
||||||
|
insertafter: EOF
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
create: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating environment file for cloud server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/nextcloud.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.nextcloud.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: nextcloud_environ
|
||||||
|
- name: Creating and deploying DBMS server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ mysql_environ.dest }} --env-file {{ email_environ.dest }} --env-file {{ nextcloud_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.cloud.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "server_run and mode == 'prod'"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
{{ nextcloud.subdomain }}.{{ web_fqdn }} {
|
||||||
|
root /srv/{{ nextcloud.subdomain }}.{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
php_fastcgi localhost:9000
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
create: true
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "server_run and (mode == 'dev' or caddy.scheme == 'http')"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://{{ nextcloud.subdomain }}.{{ web_fqdn }} {
|
||||||
|
root /srv/{{ nextcloud.subdomain }}.{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
php_fastcgi localhost:9000
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
create: true
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
# - name: Restarting webserver / reverse proxy container
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
# when: server_run
|
||||||
|
# containers.podman.podman_container:
|
||||||
|
# name: "{{ compose.containers.webserver.name }}"
|
||||||
|
# state: started
|
||||||
|
# force_restart: true
|
||||||
|
- name: Spinning up forge container specified by Compose file
|
||||||
|
when: forge_run
|
||||||
|
block:
|
||||||
|
- name: Creating database necessary for forge server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: dbms_run
|
||||||
|
containers.podman.podman_container_exec:
|
||||||
|
name: "{{ compose.containers.db.name }}"
|
||||||
|
argv:
|
||||||
|
- mysql
|
||||||
|
- "-u"
|
||||||
|
- "{{ mysql.users.admin.username }}"
|
||||||
|
- "-p{{ mysql.users.admin.password }}"
|
||||||
|
- "-e"
|
||||||
|
- "'CREATE DATABASE IF NOT EXISTS {{ mysql.users.admin.databases.gitea.name }};'"
|
||||||
|
detach: true
|
||||||
|
- name: Creating environment file for forge server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/gitea.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.gitea.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: gitea_environ
|
||||||
|
- name: Creating and deploying forge server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ mysql_environ.dest }} --env-file {{ email_environ.dest }} --env-file {{ gitea_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.forge.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "server_run and mode == 'prod'"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
{{ gitea.subdomain }}.{{ web_fqdn }} {
|
||||||
|
reverse_proxy localhost:3000
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
file_server
|
||||||
|
templates
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
create: true
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "server_run and (mode == 'dev' or caddy.scheme == 'http')"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://{{ gitea.subdomain }}.{{ web_fqdn }} {
|
||||||
|
reverse_proxy localhost:3000
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
file_server
|
||||||
|
templates
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
create: true
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
# - name: Restarting webserver / reverse proxy container
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
# when: server_run
|
||||||
|
# containers.podman.podman_container:
|
||||||
|
# name: "{{ compose.containers.webserver.name }}"
|
||||||
|
# state: started
|
||||||
|
# force_restart: true
|
||||||
|
- name: Spinning up pastebin container specified by Compose file
|
||||||
|
when: pbin_run
|
||||||
|
block:
|
||||||
|
- name: Creating database necessary for pastebin server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: dbms_run
|
||||||
|
containers.podman.podman_container_exec:
|
||||||
|
name: "{{ compose.containers.db.name }}"
|
||||||
|
argv:
|
||||||
|
- mysql
|
||||||
|
- "-u"
|
||||||
|
- "{{ mysql.users.admin.username }}"
|
||||||
|
- "-p{{ mysql.users.admin.password }}"
|
||||||
|
- "-e"
|
||||||
|
- "'CREATE DATABASE IF NOT EXISTS {{ mysql.users.admin.databases.opengist.name }};'"
|
||||||
|
detach: true
|
||||||
|
- name: Creating environment file for pastebin server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: pbin_run
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/opengist.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.opengist.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: opengist_environ
|
||||||
|
- name: Creating gist configuration file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: pbin_run
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/config/opengist/config.yml.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/opengist/config.yml"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating and deploying pastebin server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: pbin_run
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ opengist_environ.dest }} --env-file {{ mysql_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.pastebin.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "server_run and mode == 'prod'"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
{{ gist.subdomain }}.{{ web_fqdn }} {
|
||||||
|
reverse_proxy localhost:6157
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
file_server
|
||||||
|
templates
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
create: true
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Adding Caddyfile subdomain entry
|
||||||
|
when: "server_run and (mode == 'dev' or caddy.scheme == 'http')"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://{{ gist.subdomain }}.{{ web_fqdn }} {
|
||||||
|
reverse_proxy localhost:6157
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
root /srv/{{ web_fqdn }}
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
file_server
|
||||||
|
templates
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
create: true
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
# - name: Restarting webserver / reverse proxy container
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
# when: server_run
|
||||||
|
# containers.podman.podman_container:
|
||||||
|
# name: "{{ compose.containers.webserver.name }}"
|
||||||
|
# state: started
|
||||||
|
# force_restart: true
|
||||||
|
- name: Spinning up web or reverse proxy server container specified by Compose file
|
||||||
|
when: server_run
|
||||||
|
block:
|
||||||
|
- name: Creating directory for website subdomains
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/srv/{{ item }}.{{ web_fqdn }}"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
loop:
|
||||||
|
- certbot
|
||||||
|
- notes
|
||||||
|
- blog
|
||||||
|
- name: Creating directory for Caddy configuration
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.caddy"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating and deploying webserver / reverse proxy server container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ environ.dest }} up -d {{ compose.containers.webserver.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Creating volume subdirectory for main website root's error pages
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/srv/{{ web_fqdn }}/error"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating image files for main website root's error path
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "user/srv/domain-root/error/{{ item }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/srv/{{ web_fqdn }}/error/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
backup: true
|
||||||
|
mode: "644"
|
||||||
|
loop:
|
||||||
|
- 503.html
|
||||||
|
- "mythe-sisyphus-klein.png"
|
||||||
|
- "dark-matter.png"
|
||||||
|
- name: Creating or updating Caddyfile at directory
|
||||||
|
when: "mode == 'prod' and ssl_run"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://{{ web_fqdn }} {
|
||||||
|
handle /.well-known/acme-challenge/* {
|
||||||
|
reverse_proxy localhost:80
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
redir https://{host}{uri} 308
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:80 {
|
||||||
|
root /srv/certbot.{{ web_fqdn }}
|
||||||
|
browse
|
||||||
|
}
|
||||||
|
{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
|
||||||
|
header /.well-known/openpgpkey/* {
|
||||||
|
Content-Type application/octet-stream
|
||||||
|
Access-Control-Allow-Origin *
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED ROOT DOMAIN -->"
|
||||||
|
create: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Creating or updating Caddyfile at directory
|
||||||
|
when: "mode == 'prod' and not ssl_run"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
|
||||||
|
header /.well-known/openpgpkey/* {
|
||||||
|
Content-Type application/octet-stream
|
||||||
|
Access-Control-Allow-Origin *
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED ROOT DOMAIN -->"
|
||||||
|
create: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Creating or updating Caddyfile at directory
|
||||||
|
when: "mode == 'dev' or caddy.scheme == 'http'"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile"
|
||||||
|
block: |
|
||||||
|
http://{{ web_fqdn }} {
|
||||||
|
respond 503
|
||||||
|
# root /srv/{{ web_fqdn }}
|
||||||
|
file_server
|
||||||
|
|
||||||
|
header /.well-known/openpgpkey/* {
|
||||||
|
Content-Type application/octet-stream
|
||||||
|
Access-Control-Allow-Origin *
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepend_newline: true
|
||||||
|
marker: "# <-- {mark} ANSIBLE MANAGED ROOT DOMAIN -->"
|
||||||
|
create: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
state: present
|
||||||
|
- name: Opening port 443
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: "{{ item }}"
|
||||||
|
destination_port: 443
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: Open up port 443
|
||||||
|
loop:
|
||||||
|
- udp
|
||||||
|
- tcp
|
||||||
|
- name: Opening ports
|
||||||
|
become: true
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: "{{ item }}"
|
||||||
|
jump: ACCEPT
|
||||||
|
comment: "Open up port {{ (item | string) }}"
|
||||||
|
loop:
|
||||||
|
- 80
|
||||||
|
# - name: Restarting webserver / reverse proxy container
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
# containers.podman.podman_container:
|
||||||
|
# name: "{{ compose.containers.webserver.name }}"
|
||||||
|
# state: started
|
||||||
|
# force_restart: true
|
||||||
|
- name: Spinning up ACME challenge container specified by Compose file
|
||||||
|
when: ssl_run
|
||||||
|
ignore_errors: true
|
||||||
|
block:
|
||||||
|
- name: Creating environment file for SSL/TLS certificate acquisition container specified in Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/certbot.env.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.certbot.env"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
register: certbot_environ
|
||||||
|
- name: Creating and deploying SSL/TLS certificate acquisition container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ certbot_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.ssl.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Spinning up tailnet container specified by Compose file
|
||||||
|
when: tail_run
|
||||||
|
block:
|
||||||
|
- name: Creating required tailnet container secret for tailnet container specified by Compose file
|
||||||
|
become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
when: ((fqdn is defined and fqdn != None) and item.name == fqdn) or item.name == inventory_hostname
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.name }}-{{ headscale.users.admin.username }}@headscale/headscale{{ (idx | string) }}.key"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.podsecrets/headscale.key"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
loop: "{{ headscale.clients }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Creating tailnet configuration file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/config/tailscale/conf.json.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/tailscale/conf.json"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating and deploying tailnet container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose --env-file {{ environ.dest }} up -d {{ compose.containers.tail.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Spinning up dashboard container specified by Compose file
|
||||||
|
when: tail_run and dash_run
|
||||||
|
block:
|
||||||
|
- name: Creating glance configuration file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/config/glance/glance.yml.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.config/glance/glance.yml"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Creating and deploying dashboard container specified by Compose file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "podman-compose up -d {{ compose.containers.dash.name }}"
|
||||||
|
chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}"
|
||||||
|
- name: Restarting webserver / reverse proxy container
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: server_run
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "{{ compose.containers.webserver.name }}"
|
||||||
|
state: started
|
||||||
|
force_restart: true
|
||||||
|
- name: Making running containers persist on user logout
|
||||||
|
become: true
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: loginctl enable-linger $(whoami)
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
|
- name: Moving git repository from initial path
|
||||||
|
block:
|
||||||
|
- name: Recursively copying directory and its contents to elsewhere
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.site.name }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
register: new_compose_path
|
||||||
|
- name: Deleting directory at previous path
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.site.name }}"
|
||||||
|
state: absent
|
||||||
|
- name: Creating directory for new bare repository
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating bare repository
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "git init --bare {{ source_code.repos.site.name }}.git"
|
||||||
|
chdir: "{{ ansible_user_home.stdout }}/src"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/src/{{ source_code.repos.site.name }}.git"
|
||||||
|
- name: Running website
|
||||||
|
when: source_code.repos.site.run
|
||||||
|
# become: true
|
||||||
|
# become_user: "{{ current_user.stdout }}"
|
||||||
|
block:
|
||||||
|
- name: Warning about lack of implementation
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: Not yet implemented
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
---
|
||||||
|
- name: Acquiring home of current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo ~{{ ansible_user }}"
|
||||||
|
register: ansible_user_home
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
become: true
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/downloads/archives/released/surge/{{ item }}"
|
||||||
|
dest: "/usr/bin/{{ item }}"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- surge
|
||||||
|
- name: Starting to spin up the Surge service
|
||||||
|
when: surge.service.enabled and not surge.containerized
|
||||||
|
block:
|
||||||
|
- name: Installing accompanying complementary Surge system service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: surge service install
|
||||||
|
- name: Creating corresponding SystemD service unit
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: systemd/system/surge.service
|
||||||
|
dest: /etc/systemd/system/surge.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Acquiring API token for remote Surge service control
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: surge token
|
||||||
|
register: surge_token
|
||||||
|
- name: Pausing to inquire about how to proceed
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Type \"fetch\" to get the Surge API token, or \"show\" to see it for manual copying instead"
|
||||||
|
echo: true
|
||||||
|
register: data_method
|
||||||
|
- name: Presenting Surge API token to Control Node
|
||||||
|
when: data_method.user_input == "show"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Make sure to store the following API token for Surge:\n {{ surge_token.stdout }}"
|
||||||
|
- name: Giving opportunity to manually copy Surge API token
|
||||||
|
when: data_method.user_input == "show"
|
||||||
|
ansible.builtin.pause:
|
||||||
|
- name: Creating temporary file on managed node that stores Surge API token
|
||||||
|
become: true
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ surge_token.stdout }}"
|
||||||
|
dest: /tmp/surge.secret
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "644"
|
||||||
|
register: surge_token
|
||||||
|
- name: Placing Surge API token into file on control node
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ surge_token.dest }}"
|
||||||
|
dest: "./.tmp/{{ inventory_hostname }}-surge/surge.secret"
|
||||||
|
flat: true
|
||||||
|
- name: Placing Surge API token into file on control node
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
ansible.builtin.fetch:
|
||||||
|
src: "{{ surge_token.dest }}"
|
||||||
|
dest: "./roles/init-server/files/{{ inventory_hostname }}-surge/surge.secret"
|
||||||
|
flat: true
|
||||||
|
- name: Informing control node of acquired files
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "The Surge API token file have been duplicated to './.tmp/{{ inventory_hostname }}-surge/surge.secret' at the control node."
|
||||||
|
- name: Giving control node user time to read the aforementiioned message
|
||||||
|
when: data_method.user_input == "fetch"
|
||||||
|
ansible.builtin.pause:
|
||||||
|
seconds: 30
|
||||||
|
- name: Starting and enabling Surge SystemD service unit
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: surge
|
||||||
|
scope: system
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
- name: Starting and enabling TOR daemon service
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: tor
|
||||||
|
scope: system
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
- 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: Executing a shell-scripted installation process
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "{{ ansible_user_home.stdout }}/.local/bin/uv-install.sh"
|
||||||
|
creates: "{{ ansible_user_home.stdout }}/.local/bin/uv"
|
||||||
|
async: 600
|
||||||
|
poll: 5
|
||||||
|
- name: Linking binaries to directories already in PATH environment variable
|
||||||
|
become: true
|
||||||
|
ignore_errors: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ ansible_user_home.stdout }}/.local/bin/{{ item }}"
|
||||||
|
dest: "/usr/bin/{{ item }}"
|
||||||
|
state: link
|
||||||
|
loop:
|
||||||
|
- uv
|
||||||
|
- uvx
|
||||||
|
# - name: Reboot machine for shell environment change
|
||||||
|
# ansible.builtin.reboot:
|
||||||
|
# msg: Rebooting machine
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
- 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: Preparing to create a directory structure for ViM paths
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
block:
|
||||||
|
- name: Creating directory structure for ViM paths
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.vim/{{ item }}"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
loop:
|
||||||
|
- autoload
|
||||||
|
- backup
|
||||||
|
- colors
|
||||||
|
- plugged
|
||||||
|
- name: Pulling and integrating ViM plugin manager
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.vim/autoload/plug.vim"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
force: true
|
||||||
|
mode: "644"
|
||||||
|
follow_redirects: safe
|
||||||
|
timeout: 300
|
||||||
|
- name: Configuring ViM
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/vimrc.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.vimrc"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
- name: Informing user of need to manually run PlugInstall in ViM
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Make sure to run \":PlugInstall\" the first time you open/use ViM"
|
||||||
|
- name: Pausing to ensure user has read message about needed manual PlugInstall execution for ViM
|
||||||
|
ansible.builtin.pause:
|
||||||
|
seconds: 30
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
- name: Enabling Wireguard kernel module
|
||||||
|
become: true
|
||||||
|
community.general.modprobe:
|
||||||
|
name: wireguard
|
||||||
|
persistent: present
|
||||||
|
state: present
|
||||||
|
- name: Enable IP forwarding
|
||||||
|
become: true
|
||||||
|
when: wireguard.ip_forward
|
||||||
|
block:
|
||||||
|
- name: Enabling IPv4 forwarding
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.ip_forward
|
||||||
|
value: "1"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
- name: Marking IPv4 forwarded traffic as valid
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv4.conf.all.src_valid_mark
|
||||||
|
value: "1"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
- name: Enabling IPv6 forwarding
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv6.conf.all.forwarding
|
||||||
|
value: "1"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
- name: Marking IPv6 traffic as valid
|
||||||
|
ansible.posix.sysctl:
|
||||||
|
name: net.ipv6.conf.all.src_valid_mark
|
||||||
|
value: "1"
|
||||||
|
sysctl_set: true
|
||||||
|
state: present
|
||||||
|
- name: Preparing to allow Wireguard logging
|
||||||
|
when: "wireguard.debug"
|
||||||
|
block:
|
||||||
|
- name: Creating subdirectory for system kernel debugging
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /sys/kernel/debug/dynamic_debug
|
||||||
|
recurse: true
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
- name: Enabling Wireguard system logging
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "module wireguard +p"
|
||||||
|
dest: /sys/kernel/debug/dynamic_debug/control
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "644"
|
||||||
|
force: true
|
||||||
|
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# tasks file for roles/init-vps
|
||||||
|
- 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: Creating prerequisite directory tree for installation scripts
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.local/bin"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating prerequisite directory tree for unarchived archives
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/downloads/archives/released"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating prerequisite directory tree for package installation executables
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.local_pkgs"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Installing Linux software
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
block:
|
||||||
|
- name: Installing software using Debian package manager
|
||||||
|
when: ansible_facts["os_family"] == "Debian"
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Creating core OS repository sources for package manager
|
||||||
|
when: ansible_facts["os_family"] == "Debian"
|
||||||
|
ansible.builtin.deb822_repository:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
uris: "{{ item.sources }}"
|
||||||
|
types: "{{ item.types }}"
|
||||||
|
suites: "{{ item.suites }}"
|
||||||
|
components: "{{ item.comps }}"
|
||||||
|
signed_by: "{{ item.sigkey }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- name: debian-trixie
|
||||||
|
sources: "http://deb.debian.org/debian/"
|
||||||
|
sigkey: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||||
|
types:
|
||||||
|
- deb-src
|
||||||
|
- deb
|
||||||
|
suites:
|
||||||
|
- trixie
|
||||||
|
- trixie-updates
|
||||||
|
comps:
|
||||||
|
- main
|
||||||
|
- non-free-firmware
|
||||||
|
- contrib
|
||||||
|
- name: debian-trixie-security
|
||||||
|
sources: "http://security.debian.org/debian-security"
|
||||||
|
sigkey: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||||
|
types:
|
||||||
|
- deb-src
|
||||||
|
- deb
|
||||||
|
suites: trixie-security
|
||||||
|
comps:
|
||||||
|
- main
|
||||||
|
- non-free-firmware
|
||||||
|
- contrib
|
||||||
|
- name: Remove previous core OS repository sources for package manager
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/apt/sources.list
|
||||||
|
state: absent
|
||||||
|
# @TODO uncomment below before continuing with testing previous task
|
||||||
|
# - name: Premature end of play
|
||||||
|
# ansible.builtin.meta: end_play
|
||||||
|
- name: Registering a package source
|
||||||
|
when: item.sources != None
|
||||||
|
ansible.builtin.deb822_repository:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
uris: "{{ item.sources }}"
|
||||||
|
types: "{{ item.types | default('deb') }}"
|
||||||
|
suites: "{{ item.suites | default('*') }}"
|
||||||
|
components: "{{ item.comps | default('*') }}"
|
||||||
|
signed_by: "{{ item.sigkey }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ ((pkgs.mngr.core | default([]))) }}"
|
||||||
|
- name: Updating package cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
- name: Upgrading
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
autoremove: true
|
||||||
|
- name: Installing a local package in managed node
|
||||||
|
when: item.uri != None
|
||||||
|
ansible.builtin.apt:
|
||||||
|
deb: "{{ item.uri }}"
|
||||||
|
state: present
|
||||||
|
notify: "{{ item.handler | default('default') }}"
|
||||||
|
loop: "{{ (pkgs.mngr.core | default([])) | selectattr('uri', 'search', '\\.deb$') }}"
|
||||||
|
- name: Installing a package
|
||||||
|
when: item.name != None and item.uri == None
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
state: present
|
||||||
|
notify: "{{ item.handler | default('default') }}"
|
||||||
|
async: 600
|
||||||
|
poll: 5
|
||||||
|
loop: "{{ ((pkgs.mngr.core | default([]))) | rejectattr('uri', 'search', '\\.deb$') }}"
|
||||||
|
tags:
|
||||||
|
- get_mngr_pkgs
|
||||||
|
- name: Installing software by executing installation shell scripts
|
||||||
|
block:
|
||||||
|
- name: Acquiring installation shell script
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.src != None and (((pkgs.script.core | default([]))) | length) > 0
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ item.src }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.local/bin/{{ item.name }}-install.sh"
|
||||||
|
follow_redirects: safe
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
force: true
|
||||||
|
mode: "755"
|
||||||
|
timeout: 300
|
||||||
|
notify: "{{ ((pkgs.script.core | default([])))[idx].handler | default('default') }}"
|
||||||
|
loop: "{{ (pkgs.script.core | default([])) }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
register: install_scripts
|
||||||
|
- name: Reboot machine for shell environment change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: Rebooting machine
|
||||||
|
tags:
|
||||||
|
- get_script_pkgs
|
||||||
|
- name: Installing software by building it from source archives
|
||||||
|
block:
|
||||||
|
- name: Acquiring software source archive
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.src != None
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ item.src }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/downloads/archives/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
mode: "644"
|
||||||
|
loop: "{{ (pkgs.archive.core | default([])) }}"
|
||||||
|
register: archived_builds
|
||||||
|
- name: Create subdirectories for unarchiving
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/downloads/archives/released/{{ ((pkgs.archive.core | default([])))[idx].name }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
loop: "{{ archived_builds.results }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Unarchiving software build archive
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.dest != None and (((pkgs.script.core | default([]))) | length) > 0
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: "{{ item.dest }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/downloads/archives/released/{{ ((pkgs.archive.core | default([])))[idx].name }}/"
|
||||||
|
notify: "{{ ((pkgs.archive.core | default([])))[idx].handler | default('default') }}"
|
||||||
|
loop: "{{ archived_builds.results }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Reboot machine for shell environment change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: Rebooting machine
|
||||||
|
tags:
|
||||||
|
- get_archive_pkgs
|
||||||
|
- name: Installing software from source git repositories
|
||||||
|
block:
|
||||||
|
- name: Clone git bare repository
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.src != None
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "{{ item.src }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ item.name }}"
|
||||||
|
version: "{{ item.branch }}"
|
||||||
|
clone: true
|
||||||
|
notify: "{{ item.handler | default('default') }}"
|
||||||
|
loop: "{{ (pkgs.git_repos.core | default([])) }}"
|
||||||
|
register: installation_repos
|
||||||
|
- name: Reboot machine for shell environment change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: Rebooting machine
|
||||||
|
tags:
|
||||||
|
- get_git_pkgs
|
||||||
|
- name: Installing software as pre-compiled binary
|
||||||
|
block:
|
||||||
|
- name: Grabbing software binary
|
||||||
|
become: true
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ item.src }}"
|
||||||
|
dest: "/usr/bin/{{ item.name }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
notify: "{{ item.handler }}"
|
||||||
|
timeout: 300
|
||||||
|
loop: "{{ (pkgs.binaries.core | default([])) }}"
|
||||||
|
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
#SPDX-License-Identifier: MIT-0
|
#SPDX-License-Identifier: MIT-0
|
||||||
---
|
---
|
||||||
# tasks file for roles/init-vps
|
# tasks file for roles/init-vps
|
||||||
|
- name: Acquiring current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
- name: Checking whether administrative login used
|
- name: Checking whether administrative login used
|
||||||
when: ansible_user not in (admins | map(attribute="username") | list) and ansible_user != "root"
|
when: ansible_user not in (admins | map(attribute="username") | list) and ansible_user != "root"
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
msg: Must use administrative user for subsequent tasks
|
msg: Must use administrative user for subsequent tasks
|
||||||
- name: Hardening SSH service
|
- name: Hardening SSH service
|
||||||
|
become: true
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: sshd_config.d/harden.conf
|
src: sshd_config.d/harden.conf
|
||||||
dest: /etc/ssh/sshd_config.d/harden.conf
|
dest: /etc/ssh/sshd_config.d/harden.conf
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
#SPDX-License-Identifier: MIT-0
|
|
||||||
---
|
|
||||||
# tasks file for roles/init-vps
|
|
||||||
- name: Creating prerequisite directory tree for installation scripts
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ ansible_facts['user_dir'] }}/.local/bin"
|
|
||||||
recurse: true
|
|
||||||
state: directory
|
|
||||||
- name: Creating prerequisite directory tree for unarchived archives
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ ansible_facts['user_dir'] }}/downloads/archives/released"
|
|
||||||
recurse: true
|
|
||||||
state: directory
|
|
||||||
- name: Creating prerequisite directory tree for package installation executables
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ ansible_facts['user_dir'] }}/.local_pkgs"
|
|
||||||
recurse: true
|
|
||||||
state: directory
|
|
||||||
- name: Installing Linux software
|
|
||||||
when: ansible_facts["system"] == "Linux"
|
|
||||||
block:
|
|
||||||
- name: Installing software using Debian package manager
|
|
||||||
when: ansible_facts["os_family"] == "Debian"
|
|
||||||
become: true
|
|
||||||
block:
|
|
||||||
- name: Registering a package source
|
|
||||||
when: item.sources != None
|
|
||||||
ansible.builtin.deb822_repository:
|
|
||||||
name: "{{ item.name }}"
|
|
||||||
uris: "{{ item.sources }}"
|
|
||||||
types: "{{ item.types | default('deb') }}"
|
|
||||||
suites: "{{ item.suites | default('*') }}"
|
|
||||||
components: "{{ item.comps | default('*') }}"
|
|
||||||
signed_by: "{{ item.sigkey }}"
|
|
||||||
state: present
|
|
||||||
loop: "{{ ((pkgs.mngr.core | default([])) + (pkgs.mngr.userspace | default([]))) }}"
|
|
||||||
- name: Installing a local package in managed node
|
|
||||||
when: item.uri != None
|
|
||||||
ansible.builtin.apt:
|
|
||||||
deb: "{{ item.uri }}"
|
|
||||||
update_cache: true
|
|
||||||
state: present
|
|
||||||
notify: "{{ item.name }}"
|
|
||||||
loop: "{{ ((pkgs.mngr.core | default([])) + (pkgs.mngr.userspace | default([]))) | selectattr('uri', 'search', '\\.deb$') }}"
|
|
||||||
- name: Installing a package
|
|
||||||
when: item.name != None and item.uri == None
|
|
||||||
ansible.builtin.package:
|
|
||||||
name: "{{ item.name }}"
|
|
||||||
update_cache: true
|
|
||||||
state: latest
|
|
||||||
# notify: "{{ item.name }}" # @TODO create corresponding roles/init-vps handlers
|
|
||||||
loop: "{{ ((pkgs.mngr.core | default([])) + (pkgs.mngr.userspace | default([]))) | rejectattr('uri', 'search', '\\.deb$') }}"
|
|
||||||
tags:
|
|
||||||
- get_mngr_pkgs
|
|
||||||
- name: Installing software by executing installation shell scripts
|
|
||||||
block:
|
|
||||||
- name: Acquiring installation shell script
|
|
||||||
when: item.src != None
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: "{{ item.src }}"
|
|
||||||
dest: "{{ ansible_facts['user_dir'] }}/.local/bin/{{ item.name }}-install.sh"
|
|
||||||
force: true
|
|
||||||
backup: true
|
|
||||||
mode: "744"
|
|
||||||
loop: "{{ (pkgs.script.core | default([])) + (pkgs.script.userspace | default([])) }}"
|
|
||||||
register: install_scripts
|
|
||||||
- name: Executing a shell-scripted installation process
|
|
||||||
when: item.src != None and (((pkgs.script.core | default([])) + (pkgs.script.userspace | default([]))) | length) > 0
|
|
||||||
become: true
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: "{{ item.dest }}"
|
|
||||||
notify: "{{ ((pkgs.script.core | default([])) + (pkgs.script.userspace | default([])))[idx].name }}"
|
|
||||||
loop: "{{ install_scripts.results }}"
|
|
||||||
loop_control:
|
|
||||||
index_var: idx
|
|
||||||
tags:
|
|
||||||
- get_script_pkgs
|
|
||||||
# @TODO complete below block task
|
|
||||||
- name: Installing software by building it from source archives
|
|
||||||
block:
|
|
||||||
- name: Acquiring software source archive
|
|
||||||
when: item.src != None
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: "{{ item.src }}"
|
|
||||||
dest: "{{ ansible_facts['user_dir'] }}/downloads/archives/"
|
|
||||||
force: true
|
|
||||||
backup: true
|
|
||||||
mode: "644"
|
|
||||||
loop: "{{ (pkgs.archive.core | default([])) + (pkgs.archive.userspace | default([])) }}"
|
|
||||||
register: archived_builds
|
|
||||||
- name: Unarchiving software build archive
|
|
||||||
when: item.dest != None and (((pkgs.script.core | default([])) + (pkgs.script.userspace | default([]))) | length) > 0
|
|
||||||
ansible.builtin.unarchive:
|
|
||||||
src: "{{ item.dest }}"
|
|
||||||
remote_src: true
|
|
||||||
dest: "{{ ansible_facts['user_dir'] }}/downloads/archives/released/{{ ((pkgs.archive.core | default([])) + (pkgs.archive.userspace | default([])))[idx].name }}/"
|
|
||||||
notify: "{{ ((pkgs.archive.core | default([])) + (pkgs.archive.userspace | default([])))[idx].name }}"
|
|
||||||
loop: "{{ archived_builds.results }}"
|
|
||||||
loop_control:
|
|
||||||
index_var: idx
|
|
||||||
tags:
|
|
||||||
- get_archive_pkgs
|
|
||||||
- name: Installing software from source git repositories
|
|
||||||
block:
|
|
||||||
- name: Clone git bare repository
|
|
||||||
when: item.src != None
|
|
||||||
ansible.builtin.git:
|
|
||||||
repo: "{{ item.src }}"
|
|
||||||
dest: "{{ ansible_facts['user_dir'] }}/repos/.foreign/{{ item.name }}"
|
|
||||||
version: "{{ item.branch }}"
|
|
||||||
clone: true
|
|
||||||
single_branch: true
|
|
||||||
notify: "{{ item.name }}"
|
|
||||||
loop: "{{ (pkgs.git_repos.core | default([])) + (pkgs.git_repos.userspace | default([])) }}"
|
|
||||||
register: installation_repos
|
|
||||||
tags:
|
|
||||||
- get_git_pkgs
|
|
||||||
@@ -2,6 +2,11 @@
|
|||||||
---
|
---
|
||||||
# tasks file for roles/init-vps
|
# tasks file for roles/init-vps
|
||||||
# @TODO complete below tasks
|
# @TODO complete below tasks
|
||||||
|
- name: Acquiring current user
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: "echo {{ ansible_user }}"
|
||||||
|
register: current_user
|
||||||
- name: Checking whether administrative login used
|
- name: Checking whether administrative login used
|
||||||
when: ansible_user not in (admins | map(attribute="username") | list)
|
when: ansible_user not in (admins | map(attribute="username") | list)
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
@@ -46,8 +51,6 @@
|
|||||||
when: ansible_facts["system"] == "Linux"
|
when: ansible_facts["system"] == "Linux"
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.blockinfile:
|
ansible.builtin.blockinfile:
|
||||||
# src: sshd_config.d/sftp.conf.j2
|
|
||||||
# dest: /etc/ssh/sshd_config.d/sftp.conf
|
|
||||||
path: /etc/ssh/sshd_config.d/sftp.conf
|
path: /etc/ssh/sshd_config.d/sftp.conf
|
||||||
block: |
|
block: |
|
||||||
Match Group {{ item.name }}
|
Match Group {{ item.name }}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
- 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: Copying NetRC file
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: user/netrc.j2
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.netrc"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "600"
|
||||||
@@ -2,11 +2,27 @@
|
|||||||
---
|
---
|
||||||
# tasks file for roles/init-vps
|
# tasks file for roles/init-vps
|
||||||
# @NOTE server deployment method is based on task tags compiled herein
|
# @NOTE server deployment method is based on task tags compiled herein
|
||||||
|
- name: Informing user of requirement of two main domains
|
||||||
|
when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Only two domains allowed and required
|
||||||
|
- name: Informing user of requirement at least one wildcard
|
||||||
|
when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: At least one of the FQDNs must have a wildcard
|
||||||
|
# - name: Setting the FQDN for development
|
||||||
|
# when: mode == "dev"
|
||||||
|
# ansible.builtin.set_fact:
|
||||||
|
# fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
|
- name: Setting the FQDN
|
||||||
|
# when: mode == "prod"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}"
|
||||||
- name: Finding SSH public keys for root
|
- name: Finding SSH public keys for root
|
||||||
delegate_facts: true
|
delegate_facts: true
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.find:
|
ansible.builtin.find:
|
||||||
paths: "{{ local_facts['user_dir'] }}/.ssh" # @TODO define 'cnode_homedir' in playbook
|
paths: "{{ local_facts['user_dir'] | default(lookup('env', 'HOME')) }}/.ssh" # @TODO define 'cnode_homedir' in playbook
|
||||||
patterns: "{{ ['^'] | product(ssh_keys) | map('join') | list }}"
|
patterns: "{{ ['^'] | product(ssh_keys) | map('join') | list }}"
|
||||||
file_type: file
|
file_type: file
|
||||||
use_regex: true
|
use_regex: true
|
||||||
@@ -18,20 +34,41 @@
|
|||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
root_pubkeys: "{{ root_pubkeys | default([]) + [lookup('file', item)] }}"
|
root_pubkeys: "{{ root_pubkeys | default([]) + [lookup('file', item)] }}"
|
||||||
loop: "{{ root_pubkey_paths }}"
|
loop: "{{ root_pubkey_paths }}"
|
||||||
|
- name: Ensuring password is defined for root user
|
||||||
|
when: prehashed_password is undefined or prehashed_password == None
|
||||||
|
block:
|
||||||
|
- name: Prompting for password for or of root user
|
||||||
|
when: password is undefined or password == None
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Provide a password for the root user"
|
||||||
|
echo: false
|
||||||
|
register: prompted_password
|
||||||
|
- name: Getting the inputted password for root user
|
||||||
|
when: prompted_password is defined or prompted_password != None
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
prehashed_password: "{{ prompted_password.user_input }}"
|
||||||
- name: Bootstrapping VPS
|
- name: Bootstrapping VPS
|
||||||
block:
|
block:
|
||||||
|
- name: Ensuring token is available for VPS service API
|
||||||
|
when: token is undefined or token == None
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Provide the API token for the given VPS service"
|
||||||
|
echo: false
|
||||||
|
register: prompted_token
|
||||||
- name: Creating VPS via Linode VPS service API
|
- name: Creating VPS via Linode VPS service API
|
||||||
block:
|
block:
|
||||||
- name: Creating the VPS
|
- name: Creating the VPS
|
||||||
linode.cloud.instance:
|
linode.cloud.instance:
|
||||||
api_token: "{{ token }}"
|
api_token: "{{ token | prompted_token.user_input }}"
|
||||||
label: "{{ instance }}"
|
label: "{{ fqdn }}"
|
||||||
type: g6-standard-2
|
type: g6-standard-2
|
||||||
image: "{{ operating_system }}"
|
image: "{{ operating_system }}"
|
||||||
disk_encryption: enabled
|
disk_encryption: enabled
|
||||||
region: "{{ origin }}"
|
region: "{{ origin }}"
|
||||||
private_ip: true
|
private_ip: true
|
||||||
root_pass: "{{ password }}"
|
# @TODO find out if 'root_pass' attribute takes in hashed or plaintext password
|
||||||
|
# root_pass: "{{ password | default((prehashed_password | lookup('password_hash', hashtype='sha512'))) }}" # IF HASHED
|
||||||
|
root_pass: "{{ password | default(prehashed_password) }}" # IF PLAINTEXT
|
||||||
authorized_keys: "{{ root_pubkeys }}"
|
authorized_keys: "{{ root_pubkeys }}"
|
||||||
state: present
|
state: present
|
||||||
register: new_instance
|
register: new_instance
|
||||||
@@ -43,7 +80,6 @@
|
|||||||
timeout: 300
|
timeout: 300
|
||||||
vars:
|
vars:
|
||||||
ansible_ssh_private_key_file: "{{ chosen_privkey | default(ssh_keypairs.files | rejectattr('path', 'search', '\\.pub$') | map(attribute='path') | list | random) }}" # @TODO define 'chosen_privkey'in playbook
|
ansible_ssh_private_key_file: "{{ chosen_privkey | default(ssh_keypairs.files | rejectattr('path', 'search', '\\.pub$') | map(attribute='path') | list | random) }}" # @TODO define 'chosen_privkey'in playbook
|
||||||
ansible_user: root
|
|
||||||
loop: "{{ new_instance.instance[ip_pref] }}"
|
loop: "{{ new_instance.instance[ip_pref] }}"
|
||||||
tags:
|
tags:
|
||||||
- linode
|
- linode
|
||||||
@@ -66,9 +102,7 @@
|
|||||||
ansible.builtin.wait_for_connection:
|
ansible.builtin.wait_for_connection:
|
||||||
delay: 20
|
delay: 20
|
||||||
timeout: 300
|
timeout: 300
|
||||||
vars:
|
loop: "{{ groups[fqdn] | default(hostvars[fqdn]) }}"
|
||||||
ansible_user: root
|
|
||||||
loop: "{{ groups[instance] | default(hostvars[instance]) }}"
|
|
||||||
- name: Checking if that server has required operating system
|
- name: Checking if that server has required operating system
|
||||||
delegate_to: "{{ item }}"
|
delegate_to: "{{ item }}"
|
||||||
delegate_facts: true
|
delegate_facts: true
|
||||||
@@ -76,9 +110,7 @@
|
|||||||
when: ansible_facts["system"] != "Linux" and item is ansible.utils['ip_pref']
|
when: ansible_facts["system"] != "Linux" and item is ansible.utils['ip_pref']
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
msg: Unsupported operating system found
|
msg: Unsupported operating system found
|
||||||
vars:
|
loop: "{{ groups[fqdn] | default(hostvars[fqdn]) }}"
|
||||||
ansible_user: root
|
|
||||||
loop: "{{ groups[instance] | default(hostvars[instance]) }}"
|
|
||||||
- name: Checking if that server has required Linux distro
|
- name: Checking if that server has required Linux distro
|
||||||
delegate_to: "{{ item }}"
|
delegate_to: "{{ item }}"
|
||||||
delegate_facts: true
|
delegate_facts: true
|
||||||
@@ -86,19 +118,16 @@
|
|||||||
when: ansible_facts["system"] == "Linux" and ansible_facts["os_family"] != "Debian" and item is ansible.utils['ip_pref']
|
when: ansible_facts["system"] == "Linux" and ansible_facts["os_family"] != "Debian" and item is ansible.utils['ip_pref']
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
msg: Unsupported Linux distro found
|
msg: Unsupported Linux distro found
|
||||||
vars:
|
loop: "{{ groups[fqdn] | default(hostvars[fqdn]) }}"
|
||||||
ansible_user: root
|
|
||||||
loop: "{{ groups[instance] | default(hostvars[instance]) }}"
|
|
||||||
- name: Providing authorized keys for server root account
|
- name: Providing authorized keys for server root account
|
||||||
delegate_to: "{{ item[0] }}"
|
delegate_to: "{{ item[0] }}"
|
||||||
delegate_facts: true
|
delegate_facts: true
|
||||||
|
become: true
|
||||||
remote_user: root
|
remote_user: root
|
||||||
ansible.posix.authorized_key:
|
ansible.posix.authorized_key:
|
||||||
user: "{{ ansible_user }}"
|
user: "{{ ansible_user }}"
|
||||||
key: "{{ lookup('file', item[1]) }}"
|
key: "{{ lookup('file', item[1]) }}"
|
||||||
state: present
|
state: present
|
||||||
vars:
|
loop: "{{ (groups[fqdn] | default(hostvars[fqdn])) | product(root_pubkey_paths) }}"
|
||||||
ansible_user: root
|
|
||||||
loop: "{{ (groups[instance] | default(hostvars[instance])) | product(root_pubkey_paths) }}"
|
|
||||||
tags:
|
tags:
|
||||||
- lan
|
- lan
|
||||||
|
|||||||
@@ -16,6 +16,27 @@
|
|||||||
register: remote_group
|
register: remote_group
|
||||||
tags:
|
tags:
|
||||||
- lan
|
- lan
|
||||||
|
- name: Managing passwords
|
||||||
|
when: prehashed_passwords is undefined or prehashed_passwords == None
|
||||||
|
block:
|
||||||
|
- name: Acquiring users lacking passwords
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
passwordless_admins: "{{ admins | selectattr('password', '==', 'null') | list }}"
|
||||||
|
- name: Pausing to acquire password for a user
|
||||||
|
when: item.password is undefined or item.password == None
|
||||||
|
ansible.builtin.pause:
|
||||||
|
prompt: "Provide a password for the administrative user, {{ item.username }}"
|
||||||
|
echo: false
|
||||||
|
loop: "{{ passwordless_admins }}"
|
||||||
|
register: prompted_passwords
|
||||||
|
- name: Processing inputted password per user
|
||||||
|
when: prompted_passwords is defined and prompted_passwords != None
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
prehashed_passwords: "{{ (prompted_passwords.results | default([])) | map(attribute='user_input') | list }}"
|
||||||
|
- name: Pairing inputted passwords with associated user
|
||||||
|
when: prehashed_passwords is defined or prehashed_passwords != None
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
prehashed_passwords: "{{ dict(passwordless_admins | map(attribute='username') | zip(prehashed_passwords) | list) }}"
|
||||||
- name: Creating an administrative user
|
- name: Creating an administrative user
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
@@ -27,7 +48,7 @@
|
|||||||
append: true
|
append: true
|
||||||
generate_ssh_key: true
|
generate_ssh_key: true
|
||||||
create_home: true
|
create_home: true
|
||||||
password: "{{ item.password }}"
|
password: "{{ item.password | default((prehashed_passwords[item.username] | password_hash(hashtype='sha512'))) }}"
|
||||||
shell: "/bin/bash"
|
shell: "/bin/bash"
|
||||||
loop: "{{ admins }}"
|
loop: "{{ admins }}"
|
||||||
register: admin_users
|
register: admin_users
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# tasks file for roles/init-vps
|
||||||
|
- 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: Creating prerequisite directory tree for installation scripts
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.local/bin"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating prerequisite directory tree for unarchived archives
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/downloads/archives/released"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating prerequisite directory tree for package installation executables
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/.local_pkgs"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Creating prerequisite directory tree for git repos
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/repos/.foreign"
|
||||||
|
recurse: true
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
state: directory
|
||||||
|
- name: Installing Linux software
|
||||||
|
when: ansible_facts["system"] == "Linux"
|
||||||
|
block:
|
||||||
|
- name: Installing software using Debian package manager
|
||||||
|
when: ansible_facts["os_family"] == "Debian"
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Creating core OS repository sources for package manager
|
||||||
|
when: ansible_facts["os_family"] == "Debian"
|
||||||
|
ansible.builtin.deb822_repository:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
uris: "{{ item.sources }}"
|
||||||
|
types: "{{ item.types }}"
|
||||||
|
suites: "{{ item.suites }}"
|
||||||
|
components: "{{ item.comps }}"
|
||||||
|
signed_by: "{{ item.sigkey }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- name: debian-trixie
|
||||||
|
sources: "http://deb.debian.org/debian/"
|
||||||
|
sigkey: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||||
|
types:
|
||||||
|
- deb-src
|
||||||
|
- deb
|
||||||
|
suites:
|
||||||
|
- trixie
|
||||||
|
- trixie-updates
|
||||||
|
comps:
|
||||||
|
- main
|
||||||
|
- non-free-firmware
|
||||||
|
- contrib
|
||||||
|
- name: debian-trixie-security
|
||||||
|
sources: "http://security.debian.org/debian-security"
|
||||||
|
sigkey: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||||
|
types:
|
||||||
|
- deb-src
|
||||||
|
- deb
|
||||||
|
suites: trixie-security
|
||||||
|
comps:
|
||||||
|
- main
|
||||||
|
- non-free-firmware
|
||||||
|
- contrib
|
||||||
|
- name: Remove previous core OS repository sources for package manager
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/apt/sources.list
|
||||||
|
state: absent
|
||||||
|
# @TODO uncomment below before continuing with testing previous task
|
||||||
|
# - name: Premature end of play
|
||||||
|
# ansible.builtin.meta: end_play
|
||||||
|
- name: Registering a package source
|
||||||
|
when: item.sources != None
|
||||||
|
ansible.builtin.deb822_repository:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
uris: "{{ item.sources }}"
|
||||||
|
types: "{{ item.types | default('deb') }}"
|
||||||
|
suites: "{{ item.suites | default('*') }}"
|
||||||
|
components: "{{ item.comps | default('*') }}"
|
||||||
|
signed_by: "{{ item.sigkey }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ (pkgs.mngr.userspace | default([])) }}"
|
||||||
|
- name: Updating package cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
- name: Upgrading
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
autoremove: true
|
||||||
|
- name: Installing a local package in managed node
|
||||||
|
when: item.uri != None
|
||||||
|
ansible.builtin.apt:
|
||||||
|
deb: "{{ item.uri }}"
|
||||||
|
state: present
|
||||||
|
notify: "{{ item.handler | default('default') }}"
|
||||||
|
loop: "{{ (pkgs.mngr.userspace | default([])) | selectattr('uri', 'search', '\\.deb$') }}"
|
||||||
|
- name: Installing a package
|
||||||
|
when: item.name != None and item.uri == None
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
state: latest
|
||||||
|
notify: "{{ item.handler | default('default') }}" # @TODO create corresponding roles/init-vps handlers
|
||||||
|
async: 600
|
||||||
|
poll: 5
|
||||||
|
loop: "{{ (pkgs.mngr.userspace | default([])) | rejectattr('uri', 'search', '\\.deb$') }}"
|
||||||
|
tags:
|
||||||
|
- get_mngr_pkgs
|
||||||
|
- name: Installing software by executing installation shell scripts
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Acquiring installation shell script
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.src != None and ((pkgs.script.userspace | default([])) | length) > 0
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ item.src }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/.local/bin/{{ item.name }}-install.sh"
|
||||||
|
follow_redirects: safe
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
force: true
|
||||||
|
mode: "755"
|
||||||
|
timeout: 300
|
||||||
|
notify: "{{ (pkgs.script.userspace | default([]))[idx].handler | default('default') }}"
|
||||||
|
loop: "{{ (pkgs.script.userspace | default([])) }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
register: install_scripts
|
||||||
|
- name: Reboot machine for shell environment change
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: Rebooting machine
|
||||||
|
tags:
|
||||||
|
- get_script_pkgs
|
||||||
|
- name: Installing software by building it from source archives
|
||||||
|
block:
|
||||||
|
- name: Acquiring software source archive
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.src != None
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ item.src }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/downloads/archives/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
mode: "644"
|
||||||
|
loop: "{{ (pkgs.archive.userspace | default([])) }}"
|
||||||
|
register: archived_builds
|
||||||
|
- name: Create subdirectories for unarchiving
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ansible_user_home.stdout }}/downloads/archives/released/{{ (pkgs.archive.userspace | default([]))[idx].name }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: "755"
|
||||||
|
state: directory
|
||||||
|
loop: "{{ archived_builds.results }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Unarchiving software build archive
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.dest != None and ((pkgs.script.userspace | default([])) | length) > 0
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: "{{ item.dest }}"
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/downloads/archives/released/{{ (pkgs.archive.userspace | default([]))[idx].name }}/"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
notify: "{{ (pkgs.archive.userspace | default([]))[idx].handler | default('default') }}"
|
||||||
|
loop: "{{ archived_builds.results }}"
|
||||||
|
loop_control:
|
||||||
|
index_var: idx
|
||||||
|
- name: Reboot machine for shell environment change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: Rebooting machine
|
||||||
|
tags:
|
||||||
|
- get_archive_pkgs
|
||||||
|
- name: Installing software from source git repositories
|
||||||
|
block:
|
||||||
|
- name: Clone git bare repository
|
||||||
|
become: true
|
||||||
|
become_user: "{{ current_user.stdout }}"
|
||||||
|
when: item.src != None
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "{{ item.src }}"
|
||||||
|
dest: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ item.name }}"
|
||||||
|
version: "{{ item.branch }}"
|
||||||
|
clone: true
|
||||||
|
notify: "{{ item.handler | default('default') }}"
|
||||||
|
loop: "{{ (pkgs.git_repos.userspace | default([])) }}"
|
||||||
|
register: installation_repos
|
||||||
|
- name: Reboot machine for shell environment change
|
||||||
|
become: true
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
msg: Rebooting machine
|
||||||
|
tags:
|
||||||
|
- get_git_pkgs
|
||||||
|
- name: Installing software as pre-compiled binary
|
||||||
|
block:
|
||||||
|
- name: Grabbing software binary
|
||||||
|
become: true
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "{{ item.src }}"
|
||||||
|
dest: "/usr/bin/{{ item.name }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "755"
|
||||||
|
force: true
|
||||||
|
backup: true
|
||||||
|
notify: "{{ item.handler }}"
|
||||||
|
timeout: 300
|
||||||
|
loop: "{{ (pkgs.binaries.userspace | default([])) }}"
|
||||||
@@ -0,0 +1,525 @@
|
|||||||
|
---
|
||||||
|
# headscale will look for a configuration file named `config.yaml` (or `config.json`) in the following order:
|
||||||
|
#
|
||||||
|
# - `/etc/headscale`
|
||||||
|
# - `~/.headscale`
|
||||||
|
# - current working directory
|
||||||
|
|
||||||
|
# The url clients will connect to.
|
||||||
|
# Typically this will be a domain like:
|
||||||
|
#
|
||||||
|
# https://myheadscale.example.com:443
|
||||||
|
#
|
||||||
|
{% if mode == 'prod' %}
|
||||||
|
{% if headscale.port is defined and headscale.port != None %}
|
||||||
|
server_url: {{ headscale.scheme + '://' + web_fqdn + ':' + (headscale.port | string) }}
|
||||||
|
{% else %}
|
||||||
|
server_url: {{ headscale.scheme + '://' + web_fqdn + ':80' }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if headscale.port is defined and headscale.port != None %}
|
||||||
|
server_url: {{ 'http://' + web_fqdn + ':' + (headscale.port | string) }}
|
||||||
|
{% else %}
|
||||||
|
server_url: {{ 'http://' + web_fqdn + ':443' }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Address to listen to / bind to on the server
|
||||||
|
#
|
||||||
|
# For production:
|
||||||
|
# listen_addr: 0.0.0.0:8080
|
||||||
|
{% if headscale.port is defined and headscale.port != None %}
|
||||||
|
listen_addr: {{ '0.0.0.0' + ':' + (headscale.port | string) }}
|
||||||
|
{% else %}
|
||||||
|
listen_addr: 0.0.0.0:80
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Address to listen to /metrics and /debug, you may want
|
||||||
|
# to keep this endpoint private to your internal network
|
||||||
|
# Use an empty value to disable the metrics listener.
|
||||||
|
metrics_listen_addr: 127.0.0.1:9090
|
||||||
|
|
||||||
|
# Address to listen for gRPC.
|
||||||
|
# gRPC is used for controlling a headscale server
|
||||||
|
# remotely with the CLI
|
||||||
|
# Note: Remote access _only_ works if you have
|
||||||
|
# valid certificates.
|
||||||
|
#
|
||||||
|
# For production:
|
||||||
|
# grpc_listen_addr: 0.0.0.0:50443
|
||||||
|
{% if headscale.grpc.expose %}
|
||||||
|
grpc_listen_addr: {{ '0.0.0.0' + ':' + (headscale.grpc.port | string) }}
|
||||||
|
{% else %}
|
||||||
|
grpc_listen_addr: 127.0.0.1:50443
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Allow the gRPC admin interface to run in INSECURE
|
||||||
|
# mode. This is not recommended as the traffic will
|
||||||
|
# be unencrypted. Only enable if you know what you
|
||||||
|
# are doing.
|
||||||
|
{% if headscale.grpc.secure %}
|
||||||
|
grpc_allow_insecure: false
|
||||||
|
{% else %}
|
||||||
|
grpc_allow_insecure: true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# CIDR(s) of reverse proxies (e.g. 127.0.0.1/32) whose
|
||||||
|
# True-Client-IP, X-Real-IP and X-Forwarded-For headers should
|
||||||
|
# be honoured. Empty (default) ignores those headers; setting
|
||||||
|
# this without a proxy in front lets clients spoof their logged
|
||||||
|
# source IP.
|
||||||
|
trusted_proxies: []
|
||||||
|
|
||||||
|
# The Noise section includes specific configuration for the
|
||||||
|
# TS2021 Noise protocol
|
||||||
|
noise:
|
||||||
|
# The Noise private key is used to encrypt the traffic between headscale and
|
||||||
|
# Tailscale clients when using the new Noise-based protocol. A missing key
|
||||||
|
# will be automatically generated.
|
||||||
|
private_key_path: /var/lib/headscale/noise_private.key
|
||||||
|
|
||||||
|
# List of IP prefixes to allocate tailaddresses from.
|
||||||
|
# Each prefix consists of either an IPv4 or IPv6 address,
|
||||||
|
# and the associated prefix length, delimited by a slash.
|
||||||
|
#
|
||||||
|
# WARNING: These prefixes MUST be subsets of the standard Tailscale ranges:
|
||||||
|
# - IPv4: 100.64.0.0/10 (CGNAT range)
|
||||||
|
# - IPv6: fd7a:115c:a1e0::/48 (Tailscale ULA range)
|
||||||
|
#
|
||||||
|
# Using a SUBSET of these ranges is supported and useful if you want to
|
||||||
|
# limit IP allocation to a smaller block (e.g., 100.64.0.0/24).
|
||||||
|
#
|
||||||
|
# Using ranges OUTSIDE of CGNAT/ULA is NOT supported and will cause
|
||||||
|
# undefined behaviour. The Tailscale client has hard-coded assumptions
|
||||||
|
# about these ranges and will break in subtle, hard-to-debug ways.
|
||||||
|
#
|
||||||
|
# See:
|
||||||
|
# IPv4: https://github.com/tailscale/tailscale/blob/22ebb25e833264f58d7c3f534a8b166894a89536/net/tsaddr/tsaddr.go#L33
|
||||||
|
# IPv6: https://github.com/tailscale/tailscale/blob/22ebb25e833264f58d7c3f534a8b166894a89536/net/tsaddr/tsaddr.go#LL81C52-L81C71
|
||||||
|
prefixes:
|
||||||
|
v4: 100.64.0.0/10
|
||||||
|
v6: fd7a:115c:a1e0::/48
|
||||||
|
|
||||||
|
# Strategy used for allocation of IPs to nodes, available options:
|
||||||
|
# - sequential (default): assigns the next free IP from the previous given
|
||||||
|
# IP. A best-effort approach is used and Headscale might leave holes in the
|
||||||
|
# IP range or fill up existing holes in the IP range.
|
||||||
|
# - random: assigns the next free IP from a pseudo-random IP generator (crypto/rand).
|
||||||
|
allocation: sequential
|
||||||
|
|
||||||
|
# DERP is a relay system that Tailscale uses when a direct
|
||||||
|
# connection cannot be established.
|
||||||
|
# https://tailscale.com/blog/how-tailscale-works/#encrypted-tcp-relays-derp
|
||||||
|
#
|
||||||
|
# Headscale needs a list of DERP servers that can be presented to the clients.
|
||||||
|
derp:
|
||||||
|
server:
|
||||||
|
# If enabled, runs the embedded DERP server and merges it into the rest of the DERP config
|
||||||
|
# The Headscale server_url defined above MUST be using https, DERP requires TLS to be in place
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# Region ID to use for the embedded DERP server.
|
||||||
|
# The local DERP prevails if the region ID collides with other region ID coming from
|
||||||
|
# the regular DERP config.
|
||||||
|
region_id: 999
|
||||||
|
|
||||||
|
# Region code and name are displayed in the Tailscale UI to identify a DERP region
|
||||||
|
region_code: "headscale"
|
||||||
|
region_name: "Headscale Embedded DERP"
|
||||||
|
|
||||||
|
# Only allow clients associated with this server access
|
||||||
|
verify_clients: true
|
||||||
|
|
||||||
|
# Listens over UDP at the configured address for STUN connections - to help with NAT traversal.
|
||||||
|
# When the embedded DERP server is enabled stun_listen_addr MUST be defined.
|
||||||
|
#
|
||||||
|
# For more details on how this works, check this great article: https://tailscale.com/blog/how-tailscale-works/
|
||||||
|
stun_listen_addr: "0.0.0.0:3478"
|
||||||
|
|
||||||
|
# Private key used to encrypt the traffic between headscale DERP and
|
||||||
|
# Tailscale clients. A missing key will be automatically generated.
|
||||||
|
private_key_path: /var/lib/headscale/derp_server_private.key
|
||||||
|
|
||||||
|
# This flag can be used, so the DERP map entry for the embedded DERP server is not written automatically,
|
||||||
|
# it enables the creation of your very own DERP map entry using a locally available file with the parameter DERP.paths
|
||||||
|
# If you enable the DERP server and set this to false, it is required to add the DERP server to the DERP map using DERP.paths
|
||||||
|
automatically_add_embedded_derp_region: true
|
||||||
|
|
||||||
|
# For better connection stability (especially when using an Exit-Node and DNS is not working),
|
||||||
|
# it is possible to optionally add the public IPv4 and IPv6 address to the Derp-Map using:
|
||||||
|
ipv4: 198.51.100.1
|
||||||
|
ipv6: 2001:db8::1
|
||||||
|
|
||||||
|
# List of externally available DERP maps encoded in JSON
|
||||||
|
urls:
|
||||||
|
- https://controlplane.tailscale.com/derpmap/default
|
||||||
|
|
||||||
|
# Locally available DERP map files encoded in YAML
|
||||||
|
#
|
||||||
|
# This option is mostly interesting for people hosting their own DERP servers:
|
||||||
|
# https://tailscale.com/docs/reference/derp-servers/custom-derp-servers
|
||||||
|
# https://headscale.net/stable/ref/derp/
|
||||||
|
#
|
||||||
|
# paths:
|
||||||
|
# - /etc/headscale/derp-example.yaml
|
||||||
|
paths: []
|
||||||
|
|
||||||
|
# If enabled, a worker will be set up to periodically
|
||||||
|
# refresh the given sources and update the derpmap
|
||||||
|
# will be set up.
|
||||||
|
auto_update_enabled: true
|
||||||
|
|
||||||
|
# How often should we check for DERP updates?
|
||||||
|
update_frequency: 3h
|
||||||
|
|
||||||
|
# Disables the automatic check for headscale updates on startup
|
||||||
|
disable_check_updates: false
|
||||||
|
|
||||||
|
# Node lifecycle configuration.
|
||||||
|
node:
|
||||||
|
# Default key expiry for non-tagged nodes, regardless of registration method
|
||||||
|
# (auth key, CLI, web auth). Tagged nodes are exempt and never expire.
|
||||||
|
#
|
||||||
|
# This is the base default. OIDC can override this via oidc.expiry.
|
||||||
|
# If a client explicitly requests a specific expiry, the client value is used.
|
||||||
|
#
|
||||||
|
# Setting the value to "0" means no default expiry (nodes never expire unless
|
||||||
|
# explicitly expired via `headscale nodes expire`).
|
||||||
|
#
|
||||||
|
# Tailscale SaaS uses 180d; set to a positive duration to match that behaviour.
|
||||||
|
#
|
||||||
|
# Default: 0 (no default expiry)
|
||||||
|
expiry: 0
|
||||||
|
|
||||||
|
ephemeral:
|
||||||
|
# Time before an inactive ephemeral node is deleted.
|
||||||
|
inactivity_timeout: 30m
|
||||||
|
|
||||||
|
# HA subnet router health probing.
|
||||||
|
#
|
||||||
|
# When HA routes exist (2+ nodes advertising the same prefix), headscale
|
||||||
|
# pings each HA node every probe_interval via the Noise channel. If a node
|
||||||
|
# fails to respond within probe_timeout it is marked unhealthy and the
|
||||||
|
# primary role moves to the next healthy node. A node that later responds
|
||||||
|
# is marked healthy again but does NOT reclaim primary (avoids flapping).
|
||||||
|
#
|
||||||
|
# Worst-case detection time is probe_interval + probe_timeout (15s default).
|
||||||
|
# No-op when no HA routes exist. Set probe_interval to 0 to disable.
|
||||||
|
routes:
|
||||||
|
ha:
|
||||||
|
# How often to ping HA subnet routers. Set to 0 to disable probing.
|
||||||
|
# Must be >= 2s when enabled.
|
||||||
|
probe_interval: 10s
|
||||||
|
|
||||||
|
# How long to wait for a ping response before marking a node unhealthy.
|
||||||
|
# Must be >= 1s and less than probe_interval.
|
||||||
|
probe_timeout: 5s
|
||||||
|
|
||||||
|
database:
|
||||||
|
# Database type. Available options: sqlite, postgres
|
||||||
|
# Please note that using Postgres is highly discouraged as it is only supported for legacy reasons.
|
||||||
|
# All new development, testing and optimisations are done with SQLite in mind.
|
||||||
|
type: sqlite
|
||||||
|
|
||||||
|
# Enable debug mode. This setting requires the log.level to be set to "debug" or "trace".
|
||||||
|
debug: false
|
||||||
|
|
||||||
|
# GORM configuration settings.
|
||||||
|
gorm:
|
||||||
|
# Enable prepared statements.
|
||||||
|
prepare_stmt: true
|
||||||
|
|
||||||
|
# Enable parameterized queries.
|
||||||
|
parameterized_queries: true
|
||||||
|
|
||||||
|
# Skip logging "record not found" errors.
|
||||||
|
skip_err_record_not_found: true
|
||||||
|
|
||||||
|
# Threshold for slow queries in milliseconds.
|
||||||
|
slow_threshold: 1000
|
||||||
|
|
||||||
|
# SQLite config
|
||||||
|
sqlite:
|
||||||
|
path: /var/lib/headscale/db.sqlite
|
||||||
|
|
||||||
|
# Enable WAL mode for SQLite. This is recommended for production environments.
|
||||||
|
# https://www.sqlite.org/wal.html
|
||||||
|
write_ahead_log: true
|
||||||
|
|
||||||
|
# Maximum number of WAL file frames before the WAL file is automatically checkpointed.
|
||||||
|
# https://www.sqlite.org/c3ref/wal_autocheckpoint.html
|
||||||
|
# Set to 0 to disable automatic checkpointing.
|
||||||
|
wal_autocheckpoint: 1000
|
||||||
|
|
||||||
|
# # Postgres config
|
||||||
|
# Please note that using Postgres is highly discouraged as it is only supported for legacy reasons.
|
||||||
|
# See database.type for more information.
|
||||||
|
# postgres:
|
||||||
|
# # If using a Unix socket to connect to Postgres, set the socket path in the 'host' field and leave 'port' blank.
|
||||||
|
# host: localhost
|
||||||
|
# port: 5432
|
||||||
|
# name: headscale
|
||||||
|
# user: foo
|
||||||
|
# pass: bar
|
||||||
|
# max_open_conns: 10
|
||||||
|
# max_idle_conns: 10
|
||||||
|
# conn_max_idle_time_secs: 3600
|
||||||
|
|
||||||
|
# # If other 'sslmode' is required instead of 'require(true)' and 'disabled(false)', set the 'sslmode' you need
|
||||||
|
# # in the 'ssl' field. Refers to https://www.postgresql.org/docs/current/libpq-ssl.html Table 34.1.
|
||||||
|
# ssl: false
|
||||||
|
|
||||||
|
{% if mode == 'prod' or headscale.scheme == 'https' %}
|
||||||
|
### TLS configuration
|
||||||
|
#
|
||||||
|
## Let's encrypt / ACME
|
||||||
|
#
|
||||||
|
# headscale supports automatically requesting and setting up
|
||||||
|
# TLS for a domain with Let's Encrypt.
|
||||||
|
#
|
||||||
|
|
||||||
|
{% if certbot is undefined or certbot == None %}
|
||||||
|
# URL to ACME directory
|
||||||
|
# acme_url: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
|
||||||
|
# Email to register with ACME provider
|
||||||
|
# acme_email: ""
|
||||||
|
|
||||||
|
# Domain name to request a TLS certificate for:
|
||||||
|
# tls_letsencrypt_hostname: ""
|
||||||
|
|
||||||
|
# Path to store certificates and metadata needed by
|
||||||
|
# letsencrypt
|
||||||
|
# For production:
|
||||||
|
# tls_letsencrypt_cache_dir: /var/lib/headscale/cache
|
||||||
|
|
||||||
|
# Type of ACME challenge to use, currently supported types:
|
||||||
|
# HTTP-01 or TLS-ALPN-01
|
||||||
|
# See: https://headscale.net/stable/ref/tls/
|
||||||
|
# tls_letsencrypt_challenge_type: HTTP-01
|
||||||
|
# When HTTP-01 challenge is chosen, letsencrypt must set up a
|
||||||
|
# verification endpoint, and it will be listening on:
|
||||||
|
# :http = port 80
|
||||||
|
# tls_letsencrypt_listen: ":http"
|
||||||
|
{% else %}
|
||||||
|
{% if not certbot.containerized %}
|
||||||
|
## Use already defined certificates:
|
||||||
|
tls_cert_path: {{ '/etc/letsencrypt/live/' + web_fqdn + '/fullchain.pem' }}
|
||||||
|
tls_key_path: {{ '/etc/letsencrypt/live/' + web_fqdn + '/privkey.pem' }}
|
||||||
|
{% else %}
|
||||||
|
tls_cert_path: {{ ansible_user_home.stdout + '/.config/letsencrypt/live/' + web_fqdn + '/fullchain.pem' }}
|
||||||
|
tls_key_path: {{ ansible_user_home.stdout + '/.config/letsencrypt/live/' + web_fqdn + '/privkey.pem' }}
|
||||||
|
## Use already defined certificates:
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
log:
|
||||||
|
# Valid log levels: panic, fatal, error, warn, info, debug, trace
|
||||||
|
level: info
|
||||||
|
|
||||||
|
# Output formatting for logs: text or json
|
||||||
|
format: text
|
||||||
|
|
||||||
|
## Policy
|
||||||
|
# Headscale supports a wide range of Tailscale policy features such as ACLs and
|
||||||
|
# Grants. Please have a look at their docs to better understand the concepts:
|
||||||
|
# ACLs: https://tailscale.com/docs/features/access-control/acls
|
||||||
|
# Grants: https://tailscale.com/docs/features/access-control/grants
|
||||||
|
policy:
|
||||||
|
# The mode can be "file" or "database" that defines
|
||||||
|
# where the policies are stored and read from.
|
||||||
|
mode: file
|
||||||
|
# If the mode is set to "file", the path to a HuJSON file containing policies.
|
||||||
|
path: ""
|
||||||
|
|
||||||
|
## DNS
|
||||||
|
#
|
||||||
|
# headscale supports Tailscale's DNS configuration and MagicDNS.
|
||||||
|
# Please have a look to their docs to better understand the concepts:
|
||||||
|
#
|
||||||
|
# - https://tailscale.com/docs/features/magicdns
|
||||||
|
# - https://tailscale.com/blog/2021-09-private-dns-with-magicdns
|
||||||
|
#
|
||||||
|
# Please note that for the DNS configuration to have any effect,
|
||||||
|
# clients must have the `--accept-dns=true` option enabled. This is the
|
||||||
|
# default for the Tailscale client. This option is enabled by default
|
||||||
|
# in the Tailscale client.
|
||||||
|
#
|
||||||
|
# Setting _any_ of the configuration and `--accept-dns=true` on the
|
||||||
|
# clients will integrate with the DNS manager on the client or
|
||||||
|
# overwrite /etc/resolv.conf.
|
||||||
|
# https://tailscale.com/docs/reference/faq/dns-resolv-conf
|
||||||
|
#
|
||||||
|
# If you want stop Headscale from managing the DNS configuration
|
||||||
|
# all the fields under `dns` should be set to empty values.
|
||||||
|
dns:
|
||||||
|
# Whether to use MagicDNS
|
||||||
|
magic_dns: true
|
||||||
|
|
||||||
|
# Defines the base domain to create the hostnames for MagicDNS.
|
||||||
|
# This domain _must_ be different from the server_url domain.
|
||||||
|
# `base_domain` must be a FQDN, without the trailing dot.
|
||||||
|
# The FQDN of the hosts will be
|
||||||
|
# `hostname.base_domain` (e.g., _myhost.example.com_).
|
||||||
|
base_domain: {{ headscale.magic_dns.domain }}
|
||||||
|
|
||||||
|
# Whether to use the local DNS settings of a node or override the local DNS
|
||||||
|
# settings (default) and force the use of Headscale's DNS configuration.
|
||||||
|
override_local_dns: true
|
||||||
|
|
||||||
|
# List of DNS servers to expose to clients.
|
||||||
|
nameservers:
|
||||||
|
global: {{ headscale.magic_dns.nameservers }}
|
||||||
|
|
||||||
|
# NextDNS (see https://tailscale.com/docs/integrations/nextdns).
|
||||||
|
# "abc123" is example NextDNS ID, replace with yours.
|
||||||
|
# - https://dns.nextdns.io/abc123
|
||||||
|
|
||||||
|
# Split DNS (see https://tailscale.com/docs/reference/dns-in-tailscale#restricted-nameservers),
|
||||||
|
# a map of domains and which DNS server to use for each.
|
||||||
|
split: {}
|
||||||
|
# foo.bar.com:
|
||||||
|
# - 1.1.1.1
|
||||||
|
# darp.headscale.net:
|
||||||
|
# - 1.1.1.1
|
||||||
|
# - 8.8.8.8
|
||||||
|
|
||||||
|
# Set custom DNS search domains. With MagicDNS enabled,
|
||||||
|
# your tailnet base_domain is always the first search domain.
|
||||||
|
search_domains: []
|
||||||
|
|
||||||
|
# Extra DNS records
|
||||||
|
# so far only A and AAAA records are supported (on the tailscale side)
|
||||||
|
# See: https://headscale.net/stable/ref/dns/
|
||||||
|
extra_records: []
|
||||||
|
# - name: "grafana.myvpn.example.com"
|
||||||
|
# type: "A"
|
||||||
|
# value: "100.64.0.3"
|
||||||
|
#
|
||||||
|
# # you can also put it in one line
|
||||||
|
# - { name: "prometheus.myvpn.example.com", type: "A", value: "100.64.0.3" }
|
||||||
|
#
|
||||||
|
# Alternatively, extra DNS records can be loaded from a JSON file.
|
||||||
|
# Headscale processes this file on each change.
|
||||||
|
# extra_records_path: /var/lib/headscale/extra-records.json
|
||||||
|
|
||||||
|
# Unix socket used for the CLI to connect without authentication
|
||||||
|
# Note: for production you will want to set this to something like:
|
||||||
|
unix_socket: /var/run/headscale/headscale.sock
|
||||||
|
unix_socket_permission: "0770"
|
||||||
|
|
||||||
|
# OpenID Connect
|
||||||
|
# https://headscale.net/stable/ref/oidc/
|
||||||
|
# oidc:
|
||||||
|
# # Block startup until the identity provider is available and healthy.
|
||||||
|
# only_start_if_oidc_is_available: true
|
||||||
|
#
|
||||||
|
# # OpenID Connect Issuer URL from the identity provider
|
||||||
|
# issuer: "https://your-oidc.issuer.com/path"
|
||||||
|
#
|
||||||
|
# # Client ID from the identity provider
|
||||||
|
# client_id: "your-oidc-client-id"
|
||||||
|
#
|
||||||
|
# # Client secret generated by the identity provider
|
||||||
|
# # Note: client_secret and client_secret_path are mutually exclusive.
|
||||||
|
# client_secret: "your-oidc-client-secret"
|
||||||
|
# # Alternatively, set `client_secret_path` to read the secret from the file.
|
||||||
|
# # It resolves environment variables, making integration to systemd's
|
||||||
|
# # `LoadCredential` straightforward:
|
||||||
|
# client_secret_path: "${CREDENTIALS_DIRECTORY}/oidc_client_secret"
|
||||||
|
#
|
||||||
|
# # Use the expiry from the token received from OpenID when the user logged
|
||||||
|
# # in. This will typically lead to frequent need to reauthenticate and should
|
||||||
|
# # only be enabled if you know what you are doing.
|
||||||
|
# # Note: enabling this will cause `node.expiry` to be ignored for
|
||||||
|
# # OIDC-authenticated nodes.
|
||||||
|
# use_expiry_from_token: false
|
||||||
|
#
|
||||||
|
# # The OIDC scopes to use, defaults to "openid", "profile" and "email".
|
||||||
|
# # Custom scopes can be configured as needed, be sure to always include the
|
||||||
|
# # required "openid" scope.
|
||||||
|
# scope: ["openid", "profile", "email"]
|
||||||
|
#
|
||||||
|
# # Only verified email addresses are synchronized to the user profile by
|
||||||
|
# # default. Unverified emails may be allowed in case an identity provider
|
||||||
|
# # does not send the "email_verified: true" claim or email verification is
|
||||||
|
# # not required.
|
||||||
|
# email_verified_required: true
|
||||||
|
#
|
||||||
|
# # Provide custom key/value pairs which get sent to the identity provider's
|
||||||
|
# # authorization endpoint.
|
||||||
|
# extra_params:
|
||||||
|
# domain_hint: example.com
|
||||||
|
#
|
||||||
|
# # Only accept users whose email domain is part of the allowed_domains list.
|
||||||
|
# allowed_domains:
|
||||||
|
# - example.com
|
||||||
|
#
|
||||||
|
# # Only accept users whose email address is part of the allowed_users list.
|
||||||
|
# allowed_users:
|
||||||
|
# - alice@example.com
|
||||||
|
#
|
||||||
|
# # Only accept users which are members of at least one group in the
|
||||||
|
# # allowed_groups list.
|
||||||
|
# allowed_groups:
|
||||||
|
# - /headscale
|
||||||
|
#
|
||||||
|
# # Optional: PKCE (Proof Key for Code Exchange) configuration
|
||||||
|
# # PKCE adds an additional layer of security to the OAuth 2.0 authorization code flow
|
||||||
|
# # by preventing authorization code interception attacks
|
||||||
|
# # See https://datatracker.ietf.org/doc/html/rfc7636
|
||||||
|
# pkce:
|
||||||
|
# # Enable or disable PKCE support (default: false)
|
||||||
|
# enabled: false
|
||||||
|
#
|
||||||
|
# # PKCE method to use:
|
||||||
|
# # - plain: Use plain code verifier
|
||||||
|
# # - S256: Use SHA256 hashed code verifier (default, recommended)
|
||||||
|
# method: S256
|
||||||
|
|
||||||
|
# Logtail configuration
|
||||||
|
# Logtail is Tailscales logging and auditing infrastructure, it allows the
|
||||||
|
# control panel to instruct tailscale nodes to log their activity to a remote
|
||||||
|
# server. To disable logging on the client side, please refer to:
|
||||||
|
# https://tailscale.com/docs/features/logging#opt-out-of-client-logging
|
||||||
|
logtail:
|
||||||
|
# Enable logtail for tailscale nodes of this Headscale instance.
|
||||||
|
# As there is currently no support for overriding the log server in Headscale, this is
|
||||||
|
# disabled by default. Enabling this will make your clients send logs to Tailscale Inc.
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# Taildrop configuration
|
||||||
|
# Taildrop is the file sharing feature of Tailscale, allowing nodes to
|
||||||
|
# send files to each other.
|
||||||
|
# https://tailscale.com/docs/features/taildrop
|
||||||
|
taildrop:
|
||||||
|
# Enable or disable Taildrop tailnet-wide. When disabled, headscale
|
||||||
|
# withholds `https://tailscale.com/cap/file-sharing` from every
|
||||||
|
# node's CapMap.
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# Default node auto-update behaviour. When enabled, every node's
|
||||||
|
# CapMap carries `default-auto-update: [true]` so clients that have
|
||||||
|
# not made a local opt-in / opt-out choice run auto-updates by
|
||||||
|
# default. Setting it back to false flips the default for future
|
||||||
|
# clients; clients that already stored the value locally keep their
|
||||||
|
# choice.
|
||||||
|
auto_update:
|
||||||
|
enabled: false
|
||||||
|
# Advanced performance tuning parameters.
|
||||||
|
# The defaults are carefully chosen and should rarely need adjustment.
|
||||||
|
# Only modify these if you have identified a specific performance issue.
|
||||||
|
#
|
||||||
|
# tuning:
|
||||||
|
# # Maximum number of pending registration entries in the auth cache.
|
||||||
|
# # Oldest entries are evicted when the cap is reached.
|
||||||
|
# #
|
||||||
|
# # register_cache_max_entries: 1024
|
||||||
|
#
|
||||||
|
# # NodeStore write batching configuration.
|
||||||
|
# # The NodeStore batches write operations before rebuilding peer relationships,
|
||||||
|
# # which is computationally expensive. Batching reduces rebuild frequency.
|
||||||
|
# #
|
||||||
|
# # node_store_batch_size: 100
|
||||||
|
# # node_store_batch_timeout: 500ms
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{% if compose.mode == "dev" %}
|
||||||
|
SERVER_FQDN_SCHEME=http
|
||||||
|
SERVER_FQDN={{ (certbot.domains | map("regex_replace", "\\.([^\\.]*)$", ".test") | reject("regex", "^\\*\\.") | list)[0] }}
|
||||||
|
{% elif compose.mode == "prod" %}
|
||||||
|
SERVER_FQDN_SCHEME=https
|
||||||
|
SERVER_FQDN={{ (certbot.domains | reject("regex", "^\\*\\.") | list)[0] }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if nextcloud.subdomain is defined and nextcloud != None %}
|
||||||
|
NEXTCLOUD_SUBDOMAIN={{ nextcloud.subdomain }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea is defined and gitea != None %}
|
||||||
|
GITEA_SUBDOMAIN={{ gitea.subdomain }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gist is defined and gist != None %}
|
||||||
|
OG_SUBDOMAIN={{ gist.subdomain }}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
# GENERAL
|
||||||
|
max-concurrent-downloads={{ aria.dl.max.concurrent | string }}
|
||||||
|
dir={{ ansible_user_home.stdout + "/downloads/aria2" }}
|
||||||
|
log={{ ansible_user_home.stdout + "/.aria2/aria2.log" }}
|
||||||
|
log-level={{ aria.log }}
|
||||||
|
console-log-level=notice
|
||||||
|
continue=true
|
||||||
|
|
||||||
|
{% if aria.dl.resume %}
|
||||||
|
always-resume=true
|
||||||
|
{% else %}
|
||||||
|
always-resume=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.dl.overwriting %}
|
||||||
|
allow-overwrite=true
|
||||||
|
{% else %}
|
||||||
|
allow-overwrite=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.dl.autorenaming %}
|
||||||
|
auto-file-renaming=true
|
||||||
|
{% else %}
|
||||||
|
auto-file-renaming=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
file-allocation={{ aria.alloc }}
|
||||||
|
disk-cache={{ aria.dcache | string }}
|
||||||
|
enable-mmap=true
|
||||||
|
enable-color=true
|
||||||
|
human-readable=true
|
||||||
|
keep-unfinished-download-result=true
|
||||||
|
max-download-result=500
|
||||||
|
max-resume-failure-tries=0
|
||||||
|
|
||||||
|
# RPC
|
||||||
|
{% if aria.rpc.enabled %}
|
||||||
|
enable-rpc=true
|
||||||
|
|
||||||
|
{% if mode == "prod" or aria.rpc.scheme == "https" %}
|
||||||
|
rpc-secure=true
|
||||||
|
|
||||||
|
{% if not certbot.containerized %}
|
||||||
|
rpc-certificate={{ "/etc/letsencrypt/live/" + web_fqdn + "/fullchain.pem" }}
|
||||||
|
rpc-private-key={{ "/etc/letsencrypt/live/" + web_fqdn + "/privkey.pem" }}
|
||||||
|
{% else %}
|
||||||
|
rpc-certificate={{ ansible_user_home.stdout + "/.config/letsencrypt/live/" + web_fqdn + "/fullchain.pem" }}
|
||||||
|
rpc-private-key={{ ansible_user_home.stdout + "/.config/letsencrypt/live/" + web_fqdn + "/privkey.pem" }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.rpc.listen_all %}
|
||||||
|
rpc-listen-all=true
|
||||||
|
{% else %}
|
||||||
|
rpc-listen-all=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
rpc-listen-port={{ aria.rpc.port | string }}
|
||||||
|
|
||||||
|
{% if aria.rpc.credentials is undefined or aria.rpc.credentials == None %}
|
||||||
|
rpc-secret={{ aria.rpc.secret | default(lookup('password', './.tmp/' + inventory_hostname + '-aria/aria.secret', chars=['ascii_lowercase', 'digits'], length=32)) }}
|
||||||
|
{% else %}
|
||||||
|
rpc-user={{ aria.rpc.credentials.username }}
|
||||||
|
rpc-password={{ aria.rpc.credentials.password }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
enable-rpc=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# (HT/SF/F)TP
|
||||||
|
{% if aria.conn.proxy.enabled %}
|
||||||
|
all-proxy={{ aria.conn.proxy.uri }}
|
||||||
|
no-proxy={{ aria.conn.proxy.excluded | join(",") }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
max-connection-per-server={{ aria.conn.max.per_server | string }}
|
||||||
|
split={{ aria.conn.split | string }}
|
||||||
|
max-tries={{ aria.conn.max.attempts | string }}
|
||||||
|
retry-wait=15
|
||||||
|
netrc-path={{ ansible_user_home.stdout + "/.netrc" }}
|
||||||
|
server-stat-if={{ ansible_user_home.stdout + "/.aria2/dl.log" }}
|
||||||
|
server-stat-of={{ ansible_user_home.stdout + "/.aria2/dl.log" }}
|
||||||
|
uri-selector={{ aria.dl.algorithm }}
|
||||||
|
|
||||||
|
|
||||||
|
# HTTP
|
||||||
|
{% if aria.http.gzip %}
|
||||||
|
http-accept-gzip=true
|
||||||
|
{% else %}
|
||||||
|
http-accept-gzip=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.http.cache %}
|
||||||
|
http-no-cache=true
|
||||||
|
{% else %}
|
||||||
|
http-no-cache=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.http.sustain %}
|
||||||
|
enable-http-keep-alive=true
|
||||||
|
{% else %}
|
||||||
|
enable-http-keep-alive=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.http.agent is defined and aria.http.agent != None %}
|
||||||
|
user-agent={{ aria.http.agent }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# (S)FTP
|
||||||
|
{% if aria.ftp.mode == "passive" %}
|
||||||
|
ftp-pasv=true
|
||||||
|
{% elif aria.ftp.mode == "active" %}
|
||||||
|
ftp-pasv=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
ftp-type={{ aria.ftp.data_type }}
|
||||||
|
|
||||||
|
|
||||||
|
# METALINKS/TORRENTS
|
||||||
|
|
||||||
|
|
||||||
|
# TORRENTS
|
||||||
|
bt-detach-seed-only=true
|
||||||
|
|
||||||
|
{% if aria.trnt.local_discovery %}
|
||||||
|
bt-enable-lpd=true
|
||||||
|
{% else %}
|
||||||
|
bt-enable-lpd=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.trnt.encrypt %}
|
||||||
|
bt-force-encryption=true
|
||||||
|
{% else %}
|
||||||
|
bt-force-encryption=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
bt-max-peers={{ aria.trnt.peers.max }}
|
||||||
|
|
||||||
|
{% if aria.trnt.trackers is defined and aria.trnt.trackers != None and (aria.trnt.trackers | length) > 0 %}
|
||||||
|
bt-tracker={{ aria.trnt.trackers | join(",") }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.trnt.dht.enabled %}
|
||||||
|
enable-dht=true
|
||||||
|
enable-dht6=true
|
||||||
|
dht-file-path={{ ansible_user_home.stdout + "/.aria2/dht.dat" }}
|
||||||
|
dht-file-path6={{ ansible_user_home.stdout + "/.aria2/dht6.dat" }}
|
||||||
|
|
||||||
|
{% if aria.trnt.dht.entrypoint is defined and aria.trnt.dht.entrypoint != None %}
|
||||||
|
dht-entry-point={{ aria.trnt.dht.entrypoint }}
|
||||||
|
dht-entry-point6={{ aria.trnt.dht.entrypoint }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
dht-listen-port={{ aria.trnt.dht.port | string }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.trnt.peers.agent is defined and aria.trnt.peers.agent != None %}
|
||||||
|
peer-agent={{ aria.trnt.peers.agent }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.trnt.peers.prefix is defined and aria.trnt.peers.prefix != None %}
|
||||||
|
peer-id-prefix={{ aria.trnt.peers.prefix }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if aria.trnt.peers.exchange %}
|
||||||
|
enable-peer-exchange=true
|
||||||
|
{% else %}
|
||||||
|
enable-peer-exchange=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
seed-ratio={{ aria.trnt.seeding.ratio | string }}
|
||||||
|
seed-time={{ aria.trnt.seeding.time | string }}
|
||||||
|
|
||||||
|
max-overall-upload-limit={{ aria.ul.max.overall | string }}
|
||||||
|
max-upload-limit={{ aria.ul.max.per_entry | string }}
|
||||||
|
|
||||||
|
# METALINK
|
||||||
|
{% if aria.meta.follow == "mem" %}
|
||||||
|
follow-metalink={{ aria.meta.follow }}
|
||||||
|
{% elif aria.meta.follow %}
|
||||||
|
follow-metalink=true
|
||||||
|
{% else %}
|
||||||
|
follow-metalink=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
metalink-language={{ aria.meta.lang }}
|
||||||
|
|
||||||
|
{% if aria.meta.locs is defined and aria.meta.locs != None and (aria.meta.locs | length) > 0 %}
|
||||||
|
metalink-location={{ aria.meta.locs | join(",") }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
metalink-preferred-protocol={{ aria.meta.protocol_pref }}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
CERTBOT_EMAIL="{{ certbot.email }}"
|
||||||
|
CERTBOT_AUTHENTICATOR={{ certbot.auth_method }}
|
||||||
|
SERVER_WEBROOT_PATH={{ ansible_user_home.stdout + "/srv/certbot." + (fqdn | default(inventory_hostname)) }}
|
||||||
|
{% if compose.mode == "dev" %}
|
||||||
|
# @TODO find a better way to have processed the below in Ansible
|
||||||
|
CERTBOT_CHALLENGE_DOMAINS={{ certbot.domains | map("regex_replace", "\\.([^\\.]*)$", ".test") | list | join(",") }}
|
||||||
|
STAGING=1
|
||||||
|
DEBUG=1
|
||||||
|
VERBOSE=1
|
||||||
|
RUN_ONCE=1
|
||||||
|
{% elif compose.mode == "prod" %}
|
||||||
|
CERTBOT_CHALLENGE_DOMAINS={{ certbot.domains | join(",") }}
|
||||||
|
CRON={{ certbot.cron }}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
http://<< web_fqdn >> {
|
||||||
|
handle /.well-known/acme-challenge/* {
|
||||||
|
reverse_proxy localhost:80
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
redir https://{host}{uri} 308
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:80 {
|
||||||
|
root /srv/certbot.<< web_fqdn >>
|
||||||
|
browse
|
||||||
|
}
|
||||||
|
<< web_fqdn >> {
|
||||||
|
respond 503
|
||||||
|
# root /srv/<< web_fqdn >>
|
||||||
|
file_server
|
||||||
|
|
||||||
|
header /.well-known/openpgpkey/* {
|
||||||
|
Content-Type application/octet-stream
|
||||||
|
Access-Control-Allow-Origin *
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
rewrite /error/{err.status_code}.html
|
||||||
|
templates
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[storage]
|
||||||
|
# Storage driver - use overlay with fuse-overlayfs for rootless
|
||||||
|
driver = "overlay"
|
||||||
|
|
||||||
|
# Root directory for storage (default: $HOME/.local/share/containers/storage)
|
||||||
|
# Uncomment to customize:
|
||||||
|
graphroot = "{{ ansible_user_home.stdout }}/volumes"
|
||||||
|
|
||||||
|
# Run directory for transient data
|
||||||
|
runroot = "/run/user/1000/containers"
|
||||||
|
|
||||||
|
[storage.options]
|
||||||
|
[storage.options.overlay]
|
||||||
|
# Use fuse-overlayfs for rootless overlay support on older kernels
|
||||||
|
mount_program = "/usr/bin/fuse-overlayfs"
|
||||||
@@ -0,0 +1,339 @@
|
|||||||
|
server:
|
||||||
|
port: {{ glance.port }}
|
||||||
|
{% if glance.proxied %}
|
||||||
|
proxied: true
|
||||||
|
{% endif %}
|
||||||
|
base-url: /
|
||||||
|
pages:
|
||||||
|
- name: home
|
||||||
|
head-widgets:
|
||||||
|
- type: search
|
||||||
|
search-engine: {{ glance.search.engine }}
|
||||||
|
bangs:
|
||||||
|
- title: Linux Kernel
|
||||||
|
shortcut: "@linuxkernel"
|
||||||
|
url: "https://www.kernel.org/doc/html/latest/search.html?q={QUERY}"
|
||||||
|
- title: Linux
|
||||||
|
shortcut: "@linux"
|
||||||
|
url: https://cse.google.com/cse?cx=017644269519104757279%3Agm62gtzaoky&q={QUERY}&sa=go
|
||||||
|
- title: Debian
|
||||||
|
shortcut: "@deb"
|
||||||
|
url: https://search.debian.org/cgi-bin/omega?DB=en&P={QUERY}
|
||||||
|
- title: C++
|
||||||
|
shortcut: "@cpp"
|
||||||
|
url: https://learn.microsoft.com/en-us/search/?scope=C%2B%2B&view=msvc-170&terms={QUERY}
|
||||||
|
- title: Rust
|
||||||
|
shortcut: "@rust"
|
||||||
|
url: https://doc.rust-lang.org/book/?search={QUERY}
|
||||||
|
- title: Python
|
||||||
|
shortcut: "@python"
|
||||||
|
url: https://docs.python.org/3/search.html?check_keywords=yes&area=default&q={QUERY}
|
||||||
|
- title: Python Click
|
||||||
|
shortcut: "@pyclick"
|
||||||
|
url: https://click.palletsprojects.com/en/stable/search/?q={QUERY}
|
||||||
|
- title: Ansible
|
||||||
|
shortcut: "@ansible"
|
||||||
|
url: https://docs.ansible.com/projects/ansible/latest/search.html?q={QUERY}&check_keywords=yes&area=default
|
||||||
|
- title: Podman
|
||||||
|
shortcut: "@podman"
|
||||||
|
url: https://docs.podman.io/en/latest/search.html?q={QUERY}
|
||||||
|
- title: Podman Compose
|
||||||
|
shortcut: "@podcompose"
|
||||||
|
url: https://docs.podman.io/en/latest/search.html?q={QUERY}
|
||||||
|
- title: Elixir
|
||||||
|
shortcut: "@elixir"
|
||||||
|
url: https://hexdocs.pm/?packages=elixir%3A1.20.2%2Ceex%3A1.20.2%2Cex_unit%3A1.20.2%2Ciex%3A1.20.2%2Clogger%3A1.20.2%2Cmix%3A1.20.2&q={QUERY}
|
||||||
|
- title: Elixir Phoenix
|
||||||
|
shortcut: "@exphoenix"
|
||||||
|
url: https://hexdocs.pm/?q={QUERY}&packages=plug%3Alatest%2Cphoenix%3Alatest%2Cphoenix_html%3Alatest%2Cphoenix_live_view%3Alatest%2Cphoenix_pubsub%3Alatest%2Cphoenix_template%3Alatest
|
||||||
|
- title: Javascript
|
||||||
|
shortcut: "@js"
|
||||||
|
shortcut: https://javascript.info/search?query={QUERY}
|
||||||
|
- title: MDN
|
||||||
|
shortcut: "@mdn"
|
||||||
|
url: https://developer.mozilla.org/en-US/search?q={QUERY}
|
||||||
|
- title: PHP
|
||||||
|
shortcut: "@php"
|
||||||
|
url: https://www.php.net/search.php#gsc.tab=0&gsc.q={QUERY}&gsc.sort=
|
||||||
|
- title: PostgreSQL
|
||||||
|
shortcut: "@pgsql"
|
||||||
|
url: https://www.postgresql.org/search/?q={QUERY}
|
||||||
|
- title: MySQL
|
||||||
|
shortcut: "@mysql"
|
||||||
|
url: https://dev.mysql.com/doc/search/?q={QUERY}
|
||||||
|
- title: Julia
|
||||||
|
shortcut: "@julia"
|
||||||
|
url: https://docs.julialang.org/en/v1/?q={QUERY}
|
||||||
|
- title: Gitea
|
||||||
|
shortcut: "@gitea"
|
||||||
|
url: https://docs.gitea.com/search/?q={QUERY}
|
||||||
|
- title: Git
|
||||||
|
shortcut: "@git"
|
||||||
|
url: https://git-scm.com/search/results?search={QUERY}&language=en
|
||||||
|
- title: Elixir Phoenix
|
||||||
|
shortcut: "@exphoenix"
|
||||||
|
url: https://hexdocs.pm/?q={QUERY}&packages=plug%3Alatest%2Cphoenix%3Alatest%2Cphoenix_html%3Alatest%2Cphoenix_live_view%3Alatest%2Cphoenix_pubsub%3Alatest%2Cphoenix_template%3Alatest
|
||||||
|
# @TODO add more documentation searches
|
||||||
|
- type: group
|
||||||
|
widgets:
|
||||||
|
- type: clock
|
||||||
|
hour-format: 24h
|
||||||
|
timezones:
|
||||||
|
- timezone: {{ glance.timezone.id}}
|
||||||
|
label: {{ glance.timezone.name }}
|
||||||
|
- type: weather
|
||||||
|
units: metric
|
||||||
|
hour-format: 24h
|
||||||
|
location: {{ glance.weather_loc }}
|
||||||
|
columns:
|
||||||
|
- size: small
|
||||||
|
widgets:
|
||||||
|
- type: calendar
|
||||||
|
first-day-of-week: sunday
|
||||||
|
- type: bookmarks
|
||||||
|
groups:
|
||||||
|
- title: strat
|
||||||
|
links:
|
||||||
|
- title: The New Oil
|
||||||
|
url: https://thenewoil.org/en/
|
||||||
|
- title: Resilient by Design
|
||||||
|
url: https://theanarchistlibrary.org/library/the-techno-anarchist-resilient-by-design
|
||||||
|
- title: complang dox
|
||||||
|
links:
|
||||||
|
- name: Raspberry Pi
|
||||||
|
url: https://www.raspberrypi.com/documentation/
|
||||||
|
- name: Arduino
|
||||||
|
url: https://docs.arduino.cc/
|
||||||
|
- name: NASM x86 Assembly
|
||||||
|
url: https://www.tutorialspoint.com/assembly_programming/index.htm
|
||||||
|
- name: WASM
|
||||||
|
url: https://webassembly.org/docs/faq/
|
||||||
|
- name: Linux Kernel
|
||||||
|
url: https://www.kernel.org/doc/html/latest/index.html
|
||||||
|
- name: Linux
|
||||||
|
url: https://tldp.org/guides.html
|
||||||
|
- name: Debian
|
||||||
|
url: https://www.debian.org/doc/
|
||||||
|
- name: Zig
|
||||||
|
url: https://ziglang.org/documentation/
|
||||||
|
- name: Rust
|
||||||
|
url: https://doc.rust-lang.org/
|
||||||
|
- name: Cargo
|
||||||
|
url: https://doc.rust-lang.org/cargo/
|
||||||
|
- name: C++
|
||||||
|
url: https://learn.microsoft.com/en-us/cpp/
|
||||||
|
- name: vcpkg
|
||||||
|
url: https://learn.microsoft.com/en-us/vcpkg/
|
||||||
|
- name: C#
|
||||||
|
url: https://learn.microsoft.com/en-us/dotnet/csharp/
|
||||||
|
- name: nuget
|
||||||
|
url: https://learn.microsoft.com/en-us/nuget/
|
||||||
|
- name: Python
|
||||||
|
url: https://docs.python.org/
|
||||||
|
- name: Python uv
|
||||||
|
url: https://docs.astral.sh/uv/
|
||||||
|
- name: Ansible
|
||||||
|
url: https://docs.ansible.com/projects/ansible/latest/
|
||||||
|
- name: Podman
|
||||||
|
url: https://docs.podman.io/en/latest/
|
||||||
|
- name: Podman Compose
|
||||||
|
url: https://docs.podman.io/en/latest/markdown/podman-compose.1.html
|
||||||
|
- name: Erlang
|
||||||
|
url: https://www.erlang.org/docs.html
|
||||||
|
- name: Elixir
|
||||||
|
url: https://elixir-lang.org/docs.html
|
||||||
|
- name: Hex
|
||||||
|
url: https://hex.pm/docs/usage
|
||||||
|
- name: Lua
|
||||||
|
url: https://www.lua.org/docs.html
|
||||||
|
- name: LuaRocks
|
||||||
|
url: https://luarocks.org/docs
|
||||||
|
- name: GDScript
|
||||||
|
url: https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/index.html
|
||||||
|
- name: Julia
|
||||||
|
url: https://docs.julialang.org/
|
||||||
|
- name: NodeJS
|
||||||
|
url: https://nodejs.org/docs/latest/api/
|
||||||
|
- name: NPMJS
|
||||||
|
url: https://docs.npmjs.com/
|
||||||
|
- name: Go
|
||||||
|
url: https://go.dev/doc/
|
||||||
|
- name: CSS
|
||||||
|
url: https://www.w3.org/Style/CSS/Overview.en.html
|
||||||
|
- name: HTML
|
||||||
|
url: https://html.spec.whatwg.org/multipage/
|
||||||
|
- name: Javascript
|
||||||
|
url: https://javascript.info/
|
||||||
|
- name: Javascript DOM
|
||||||
|
url: https://dom.spec.whatwg.org/
|
||||||
|
- name: JSON
|
||||||
|
url: https://www.json.org/json-en.html
|
||||||
|
- name: Client-Side Web Languages
|
||||||
|
url: https://developer.mozilla.org/en-US/
|
||||||
|
- name: PHP
|
||||||
|
url: https://www.php.net/docs.php
|
||||||
|
- name: PHP Composer
|
||||||
|
url: https://getcomposer.org/doc/
|
||||||
|
- name: SQL
|
||||||
|
url: https://www.postgresql.org/docs/current/sql.html
|
||||||
|
- name: SASS
|
||||||
|
url: https://sass-lang.com/documentation/
|
||||||
|
- name: YAML
|
||||||
|
url: https://www.yaml.info/
|
||||||
|
- name: TOML
|
||||||
|
url: https://toml.io/en/
|
||||||
|
- name: ActivityPub
|
||||||
|
url: https://activitypub.rocks/
|
||||||
|
- name: SuperCollider
|
||||||
|
url: https://doc.sccode.org/
|
||||||
|
- name: CSound
|
||||||
|
url: https://csound.com/docs/manual/index.html
|
||||||
|
- name: FAUST
|
||||||
|
url: https://faustdoc.grame.fr/
|
||||||
|
- name: regexp
|
||||||
|
url: https://regexbox.com/cheatsheet
|
||||||
|
- title: warez dox
|
||||||
|
links:
|
||||||
|
- name: glance
|
||||||
|
url: https://github.com/glanceapp/glance/tree/main/docs
|
||||||
|
- name: Nextcloud
|
||||||
|
url: https://docs.nextcloud.com/
|
||||||
|
- name: Wireguard
|
||||||
|
url: https://www.wireguard.com/#conceptual-overview
|
||||||
|
- name: Headscale
|
||||||
|
url: https://docs.headscale.org/
|
||||||
|
- name: Tailscale
|
||||||
|
url: https://tailscale.com/docs
|
||||||
|
- name: Gitea
|
||||||
|
url: https://docs.gitea.com/
|
||||||
|
- name: OpenGist
|
||||||
|
url: https://opengist.io/docs/
|
||||||
|
- name: Caddy
|
||||||
|
url: https://caddyserver.com/docs/
|
||||||
|
- name: MySQL
|
||||||
|
url: https://dev.mysql.com/doc/
|
||||||
|
- name: Certbot
|
||||||
|
url: https://eff-certbot.readthedocs.io/en/stable/
|
||||||
|
- name: git
|
||||||
|
url: https://git-scm.dev/doc
|
||||||
|
# - title: api
|
||||||
|
# - title: src
|
||||||
|
# - title: warez
|
||||||
|
- size: full
|
||||||
|
widgets:
|
||||||
|
- type: split-column
|
||||||
|
widgets:
|
||||||
|
- type: rss
|
||||||
|
title: technoscience
|
||||||
|
style: detailed-list
|
||||||
|
collapse-after: 5
|
||||||
|
feeds:
|
||||||
|
- url: https://feeds.arstechnica.com/arstechnica/features
|
||||||
|
title: arstechnica
|
||||||
|
- url: https://rss.slashdot.org/Slashdot/slashdotMain
|
||||||
|
title: slashdot
|
||||||
|
- url: https://torrentfreak.com/feed/
|
||||||
|
title: torrentfreak
|
||||||
|
- url: https://blog.p2pfoundation.net/feed/
|
||||||
|
title: p2p foundation
|
||||||
|
- url: https://www.wired.com/feed/category/backchannel/latest/rss
|
||||||
|
title: wired
|
||||||
|
- url: https://www.quantamagazine.org/feed/
|
||||||
|
title: quanta
|
||||||
|
- url: https://www.sciencedaily.com/rss/matter_energy/telecommunications.xml
|
||||||
|
title: scidaily - telecomms
|
||||||
|
- url: https://www.sciencedaily.com/rss/computers_math/quantum_computers.xml
|
||||||
|
title: scidaily - quancomp
|
||||||
|
- url: https://www.sciencedaily.com/rss/matter_energy/engineering_and_construction.xml
|
||||||
|
title: scidaily - engi
|
||||||
|
- url: https://www.sciencedaily.com/rss/matter_energy/energy_and_resources.xml
|
||||||
|
title: scidaily - energy & fuel
|
||||||
|
- url: https://www.sciencedaily.com/rss/earth_climate/energy.xml
|
||||||
|
title: scidaily - climate change
|
||||||
|
- url: https://www.sciencedaily.com/rss/earth_climate/global_warming.xml
|
||||||
|
title: scidaily - global warming
|
||||||
|
- url: https://www.sciencedaily.com/rss/earth_climate/sustainability.xml
|
||||||
|
title: scidaily - sustainability
|
||||||
|
- url: https://www.sciencedaily.com/rss/computers_math/computer_programming.xml
|
||||||
|
title: scidaily - compprog
|
||||||
|
- url: https://www.sciencedaily.com/rss/computers_math/information_technology.xml
|
||||||
|
title: scidaily - infotech
|
||||||
|
- url: https://phys.org/rss-feed/biology-news/ecology/
|
||||||
|
title: phys - ecology
|
||||||
|
- type: rss
|
||||||
|
title: politics
|
||||||
|
style: detailed-list
|
||||||
|
collapse-after: 5
|
||||||
|
feeds:
|
||||||
|
- url: https://www.democracynow.org/democracynow.rss
|
||||||
|
title: democracy now
|
||||||
|
- url: https://www.nakedcapitalism.com/feed
|
||||||
|
title: naked capitalism
|
||||||
|
- url: https://www.thenews.coop/feed/
|
||||||
|
title: co-operative news
|
||||||
|
- url: http://feeds.propublica.org/propublica/main
|
||||||
|
title: propublica
|
||||||
|
- url: https://unicornriot.ninja/feed/rss/
|
||||||
|
title: unicorn riot
|
||||||
|
- url: https://crimethinc.com/feed
|
||||||
|
title: crimethinc
|
||||||
|
- url: https://anarchistnews.org/rss.xml
|
||||||
|
title: anarchist news
|
||||||
|
- type: rss
|
||||||
|
title: misc
|
||||||
|
style: detailed-list
|
||||||
|
collapse-after: 5
|
||||||
|
feeds:
|
||||||
|
- url: https://www.radicalphilosophy.com/feed
|
||||||
|
title: radical philosophy
|
||||||
|
- url: http://spectrejournal.com/feed/rss
|
||||||
|
title: spectre
|
||||||
|
- url: https://nautil.us/feed
|
||||||
|
title: nautilus
|
||||||
|
- url: https://theconversation.com/us/home-page/articles.atom
|
||||||
|
title: the conversation
|
||||||
|
- url: https://thebaffler.com/latest/feed
|
||||||
|
title: the baffler
|
||||||
|
- type: videos
|
||||||
|
style: horizontal-cards
|
||||||
|
channels:
|
||||||
|
- UCjEDZ_R_ypSc-MUBRkiW1lw
|
||||||
|
- UCIZ5ZOeiXYbmKTl_85ghNPw
|
||||||
|
- UCdcemy56JtVTrsFIOoqvV8g
|
||||||
|
- UCSkzHxIcfoEr69MWBdo0ppg
|
||||||
|
- UCW6TXMZ5Pq6yL6_k5NZ2e0Q
|
||||||
|
- UC4a-Gbdw7vOaccHmFo40b9g
|
||||||
|
- UCwbyKKmjVdCpWzZZY-WnajA
|
||||||
|
- UCMMBpWfWUd3xlcOxrot_neA
|
||||||
|
- UCJXa3_WNNmIpewOtCHf3B0g
|
||||||
|
- UCmfF7JZv26UUKyRedViGIlw
|
||||||
|
- UCEmQRq5bxIUNGvAWj41AoaA
|
||||||
|
- UCHkYOD-3fZbuGhwsADBd9ZQ
|
||||||
|
- UCHa8J-xnRYOg5VuudfWpBgg
|
||||||
|
- UCJZv4d5rbIKd4QHMPkcABCw
|
||||||
|
- UCZUyPT9DkJWmS_DzdOi7RIA
|
||||||
|
- UChbS_z6KHQiIu9et38O37eQ
|
||||||
|
- UCxX9wt5FWQUAAz4UrysqK9A
|
||||||
|
- UCX6b17PVsYBQ0ip5gyeme-Q
|
||||||
|
- UCk0fGHsCEzGig-rSzkfCjMw
|
||||||
|
- UCYO_jab_esuFRV4b17AJtAw
|
||||||
|
- UChKIQpndVpX1ung-7IkGhzA
|
||||||
|
- UCaM7SQvF5q9sz4NgL16PNRA
|
||||||
|
- UC7pdnrWVj8eDfCI0bRe_0kQ
|
||||||
|
- UCtuXekfqj-paqsxtqVNCC2A
|
||||||
|
- UCgkjg1UbcQZHW40IO1BEt5A
|
||||||
|
- UCGKEMK3s-ZPbjVOIuAV8clQ
|
||||||
|
- UCbiGcwDWZjz05njNPrJU7jA
|
||||||
|
- UC6biysICWOJ-C3P4Tyeggzg
|
||||||
|
- UCbi3ei431gvBpgZ3R-_Wk5Q
|
||||||
|
- UCA5yXa0rDsGaJFOuj6pxw1w
|
||||||
|
- UCDG73pGqESS1XcEVY_0xwWw
|
||||||
|
- UCR2uRTQ53V_egXKFflMMaaw
|
||||||
|
- UCzGUT9PjV3SMBwjWXUYh4HA
|
||||||
|
- name: services
|
||||||
|
columns:
|
||||||
|
- size: full
|
||||||
|
widgets:
|
||||||
|
- type: docker-containers
|
||||||
|
title: status
|
||||||
|
hide-by-default: false
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
db-uri: {{ gist.db.type + "://" + mysql.users.admin.username + ":" + mysql.users.admin.password + "@localhost:3306/" + mysql.users.admin.databases.opengist.name }}
|
||||||
|
{% if mode == "dev" %}
|
||||||
|
log-level: debug
|
||||||
|
{% else %}
|
||||||
|
log-level: info
|
||||||
|
{% endif %}
|
||||||
|
custom.static-links:
|
||||||
|
- name: Playbooks
|
||||||
|
path: {{ "https://" + gitea.subdomain + "." + web_fqdn + "/admin/skato-ansible" }}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"TCP": {
|
||||||
|
<% if mode == "prod" %>
|
||||||
|
"443": {
|
||||||
|
"HTTPS": true
|
||||||
|
}
|
||||||
|
<% elif mode == "dev" or tailscale.scheme == "http" %>
|
||||||
|
"80": {
|
||||||
|
"HTTPS": false
|
||||||
|
}
|
||||||
|
<% endif %>
|
||||||
|
},
|
||||||
|
"Web": {
|
||||||
|
<% if mode == "prod" %>
|
||||||
|
"${TS_CERT_DOMAIN}:443": {
|
||||||
|
"Handlers": {
|
||||||
|
"/": {
|
||||||
|
"Proxy": "http://localhost:8080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<% elif mode == "dev" or tailscale.scheme == "http" %>
|
||||||
|
"${TS_CERT_DOMAIN}:80": {
|
||||||
|
"Handlers": {
|
||||||
|
"/": {
|
||||||
|
"Proxy": "http://localhost:8080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<% endif %>
|
||||||
|
},
|
||||||
|
"AllowFunnel": {
|
||||||
|
<% if mode == "prod" %>
|
||||||
|
"${TS_CERT_DOMAIN}:443": false
|
||||||
|
<% elif mode == "dev" or tailscale.scheme == "http" %>
|
||||||
|
"${TS_CERT_DOMAIN}:80": false
|
||||||
|
<% endif %>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{% if email.smtp is defined or email.smtp != None %}
|
||||||
|
EMAIL_SEND_PROTOCOL=smtp
|
||||||
|
EMAIL_SMTP_HOST={{ email.smtp.host }}
|
||||||
|
EMAIL_SMTP_PORT={{ email.smtp.port }}
|
||||||
|
EMAIL_SMTP_SECURE={{ email.smtp.conn_mode }}
|
||||||
|
EMAIL_SMTP_USERNAME={{ email.smtp.username }}
|
||||||
|
EMAIL_SMTP_AUTHTYPE={{ email.smtp.auth_meth.upper() }}
|
||||||
|
EMAIL_SMTP_USER_ALIAS={{ (email.smtp.alias | split("@"))[0] }}
|
||||||
|
EMAIL_SMTP_EMAIL_ALIAS={{ (email.smtp.alias | split("@"))[1] }}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
templates:
|
||||||
|
limited_series:
|
||||||
|
configure_series:
|
||||||
|
from:
|
||||||
|
filesystem:
|
||||||
|
path:
|
||||||
|
- ~/media/vids/series
|
||||||
|
# - ~/media/vids/features
|
||||||
|
recursive: false
|
||||||
|
retrieve: dirs
|
||||||
|
settings:
|
||||||
|
identified_by: ep
|
||||||
|
path: '~/media/vids/series/{{ series_name }}'
|
||||||
|
target: 1080p
|
||||||
|
timeframe: 2 weeks
|
||||||
|
parse_only: true
|
||||||
|
exists_series:
|
||||||
|
path: '~/media/vids/series/{{ series_name }}'
|
||||||
|
allow_different_qualities: better
|
||||||
|
feature_films:
|
||||||
|
csv:
|
||||||
|
url: 'file://%7e/media/vids/features/.films.csv'
|
||||||
|
values:
|
||||||
|
title: 1
|
||||||
|
url: 2
|
||||||
|
list_add:
|
||||||
|
- entry_list: films
|
||||||
|
porn_vids:
|
||||||
|
csv:
|
||||||
|
url: 'file://%7e/.xxx/.vids.csv'
|
||||||
|
values:
|
||||||
|
title: 1
|
||||||
|
url: 2
|
||||||
|
list_add:
|
||||||
|
- entry_list: pornos
|
||||||
|
tasks:
|
||||||
|
# @NOTE uncommenting aria2 block requires commenting out download and proxy blocks
|
||||||
|
populate_folders:
|
||||||
|
{% if download_mode == 'direct' %}
|
||||||
|
proxy:
|
||||||
|
https: 'socks5://<< tor.proxy.hostname >>:<< tor.proxy.port >>'
|
||||||
|
{% endif %}
|
||||||
|
if:
|
||||||
|
- "'batch' in title.lower()": reject
|
||||||
|
discover:
|
||||||
|
what:
|
||||||
|
- next_series_episodes:
|
||||||
|
from_start: true
|
||||||
|
backfill: false
|
||||||
|
from:
|
||||||
|
- nyaa:
|
||||||
|
category: anime eng
|
||||||
|
filter: trusted only
|
||||||
|
- search_rss:
|
||||||
|
url: 'https://nyaa.si/?f=2&c=1_2&q={{ search_term }}'
|
||||||
|
link:
|
||||||
|
- magneturi
|
||||||
|
- link
|
||||||
|
all_entries: false
|
||||||
|
- eztv: true
|
||||||
|
interval: 1 week
|
||||||
|
limit: 80
|
||||||
|
template: limited_series
|
||||||
|
{% if flexget.download_mode == 'aria2' %}
|
||||||
|
aria2:
|
||||||
|
server: << aria.rpc.hostname >>
|
||||||
|
port: << aria.rpc.port >>
|
||||||
|
{% if aria.rpc.secret != None and aria.rpc.secret is defined %}
|
||||||
|
secret: << aria.rpc.secret >>
|
||||||
|
{% elif aria.rpc.credentials != None and aria.rpc.credentials is defined %}
|
||||||
|
username: << aria.rpc.credentials.username >>
|
||||||
|
password: << aria.rpc.credentials.password >>
|
||||||
|
{% endif %}
|
||||||
|
{% if mode == 'prod' %}
|
||||||
|
scheme: << aria.rpc.scheme >>
|
||||||
|
{% else %}
|
||||||
|
scheme: http
|
||||||
|
{% endif %}
|
||||||
|
rpc_mode: json
|
||||||
|
rpc_path: jsonrpc
|
||||||
|
path: '~/downloads/media/vids/{{ series_name }}'
|
||||||
|
{% else %}
|
||||||
|
download:
|
||||||
|
temp: ~/.tmp
|
||||||
|
path: '~/downloads/flexget/vids/series/torrents/{{ series_name }}'
|
||||||
|
{% endif %}
|
||||||
|
# @NOTE uncommenting aria2 block requires commenting out download and proxy blocks
|
||||||
|
fap_queue:
|
||||||
|
{% if download_mode == 'direct' %}
|
||||||
|
proxy:
|
||||||
|
https: 'socks5://<< tor.proxy.hostname >>:<< tor.proxy.port >>'
|
||||||
|
{% endif %}
|
||||||
|
template: porn_vids
|
||||||
|
{% if flexget.download_mode == 'aria2' %}
|
||||||
|
aria2:
|
||||||
|
server: << aria.rpc.hostname >>
|
||||||
|
port: << aria.rpc.port >>
|
||||||
|
{% if aria.rpc.secret != None and aria.rpc.secret is defined %}
|
||||||
|
secret: << aria.rpc.secret >>
|
||||||
|
{% endif %}
|
||||||
|
{% if aria.rpc.credentials != None and aria.rpc.credentials is defined %}
|
||||||
|
username: << aria.rpc.credentials.username >>
|
||||||
|
password: << aria.rpc.credentials.password >>
|
||||||
|
{% endif %}
|
||||||
|
{% if mode == 'prod' %}
|
||||||
|
scheme: << aria.rpc.scheme >>
|
||||||
|
{% else %}
|
||||||
|
scheme: http
|
||||||
|
{% endif %}
|
||||||
|
rpc_mode: json
|
||||||
|
rpc_path: jsonrpc
|
||||||
|
path: ~/downloads/.xxx/media/vids
|
||||||
|
{% elif flexget.download_mode == 'direct' %}
|
||||||
|
download:
|
||||||
|
temp: ~/.tmp
|
||||||
|
path: ~/downloads/.xxx/flexget/vids/torrents
|
||||||
|
{% endif %}
|
||||||
|
# @NOTE uncommenting aria2 block requires commenting out download and proxy blocks
|
||||||
|
film_queue:
|
||||||
|
{% if download_mode == 'direct' %}
|
||||||
|
proxy:
|
||||||
|
https: 'socks5://<< tor.proxy.hostname >>:<< tor.proxy.port >>'
|
||||||
|
{% endif %}
|
||||||
|
template: feature_films
|
||||||
|
{% if flexget.download_mode == 'aria2' %}
|
||||||
|
aria2:
|
||||||
|
server: << aria.rpc.hostname >>
|
||||||
|
port: << aria.rpc.port >>
|
||||||
|
{% if aria.rpc.secret != None or aria.rpc.secret is defined %}
|
||||||
|
secret: << aria.rpc.secret >>
|
||||||
|
{% endif %}
|
||||||
|
{% if aria.rpc.credentials != None or aria.rpc.credentials is defined %}
|
||||||
|
username: << aria.rpc.credentials.username >>
|
||||||
|
password: << aria.rpc.credentials.password >>
|
||||||
|
{% endif %}
|
||||||
|
{% if mode == 'prod' %}
|
||||||
|
scheme: << aria.rpc.scheme >>
|
||||||
|
{% else %}
|
||||||
|
scheme: http
|
||||||
|
{% endif %}
|
||||||
|
rpc_mode: json
|
||||||
|
rpc_path: jsonrpc
|
||||||
|
path: ~/downloads/media/vids
|
||||||
|
{% elif flexget.download_mode == 'direct' %}
|
||||||
|
download:
|
||||||
|
temp: ~/.tmp
|
||||||
|
path: ~/downloads/flexget/vids/torrents
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
GITEA_MODE={{ mode | default("dev") }}
|
||||||
|
GITEA_NAME={{ (web_fqdn | split("."))[0].upper() + " Nous" }}
|
||||||
|
GITEA_SSH_PORT={{ gitea.ssh.port }}
|
||||||
|
GITEA_LANDING={{ gitea.site.landing }}
|
||||||
|
GITEA_TRUSTED_PROXIES={{ gitea.trusted.proxies | join(",") }}
|
||||||
|
|
||||||
|
{% if gitea.site.registration.enabled %}
|
||||||
|
GITEA_PROHIBIT_REGISTRATION=false
|
||||||
|
{% else %}
|
||||||
|
GITEA_PROHIBIT_REGISTRATION=true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
GITEA_DB_TYPE={{ gitea.db.type }}
|
||||||
|
|
||||||
|
{% if gitea.db.type == "mysql" %}
|
||||||
|
GITEA_DB_NAME={{ gitea.db.name }}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
+++
|
||||||
|
title = '{{ web_fqdn }}'
|
||||||
|
draft = false
|
||||||
|
+++
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Under Construction
|
||||||
|
|
||||||
|
### Err. 503: Service Unavailable
|
||||||
|
|
||||||
|
Working on building or migrating the content, layout or theme for this blog.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
title: {{ web_fqdn }}
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Under Construction
|
||||||
|
|
||||||
|
### Err. 503: Service Unavailable
|
||||||
|
|
||||||
|
Working on building or migrating Obsidian vault entries for this server.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -0,0 +1,3 @@
|
|||||||
|
MYSQL_DB_HOST=localhost
|
||||||
|
MYSQL_DB_USER={{ mysql.users.admin.username }}
|
||||||
|
MYSQL_DB_NAME={{ mysql.users.admin.databases.init.name }}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
machine {{ source_code.host }}
|
||||||
|
login {{ source_code.user | default(source_code.ssh_user) }}
|
||||||
|
password {{ source_code.http_password | default(source_code.ssh_password) }}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{% if nextcloud.db.type == "mysql" or nextcloud.db.type == "mariadb" %}
|
||||||
|
NEXTCLOUD_DB_NAME={{ nextcloud.db.name | default("nextcloud") }}
|
||||||
|
{% elif nextcloud.db.type == "sqlite" %}
|
||||||
|
SQLITE_DATABASE={{ nextcloud.db.name + ".db" }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not nextcloud.rewrite_ip %}
|
||||||
|
NEXTCLOUD_APACHE_DISABLE_REWRITE_IP=1
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
NEXTCLOUD_TRUSTED_PROXIES={{ nextcloud.trusted.proxies | join(" ") }}
|
||||||
|
NEXTCLOUD_TRUSTED_FQDNS={{ "cloud." + web_fqdn }}
|
||||||
|
{% if compose.mode == "prod" %}
|
||||||
|
NEXTCLOUD_URL_REWRITE={{ "https://cloud." + web_fqdn }}
|
||||||
|
NEXTCLOUD_PROTOCOL_REWRITE=https
|
||||||
|
{% elif compose.mode == "dev" %}
|
||||||
|
NEXTCLOUD_URL_REWRITE={{ "http://cloud." + web_fqdn }}
|
||||||
|
NEXTCLOUD_PROTOCOL_REWRITE=http
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
OG_DB_TYPE={{ gist.db.type }}
|
||||||
|
|
||||||
|
{% if gist.db.type == "mysql" %}
|
||||||
|
OG_DB_NAME={{ gist.db.name }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
OG_SEARCH_DEFAULT={{ gist.search.priority | join(",") }}
|
||||||
|
|
||||||
|
{% if ssh is defined and ssh != None %}
|
||||||
|
OG_SSH_PORT={{ gist.ssh.port }}
|
||||||
|
OG_SSH_GIT_ENABLED=true
|
||||||
|
{% else %}
|
||||||
|
OG_SSH_GIT_ENABLED=false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
OG_NAME={{ (web_fqdn | split("."))[0].upper() + " Grimoire" }}
|
||||||
|
OG_LOGO=logo.svg
|
||||||
|
OG_FAVICON=logo.ico
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
REDIS_PARAMS={{ "--requirepass " + redis.password + " --appendonly yes" }}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
" Disable compatibility with vi which can cause unexpected issues.
|
||||||
|
set nocompatible
|
||||||
|
|
||||||
|
" Enable type file detection. Vim will be able to try to detect the type of file in use.
|
||||||
|
filetype on
|
||||||
|
|
||||||
|
" Enable plugins and load plugin for the detected file type.
|
||||||
|
filetype plugin on
|
||||||
|
|
||||||
|
" Load an indent file for the detected file type.
|
||||||
|
filetype indent on
|
||||||
|
|
||||||
|
" Turn syntax highlighting on.
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
" Add numbers to each line on the left-hand side.
|
||||||
|
set number
|
||||||
|
|
||||||
|
" Jump to line by relative number
|
||||||
|
set relativenumber
|
||||||
|
{% if (vimrc.cursor.blocky | default(True)) %}
|
||||||
|
|
||||||
|
" Highlight cursor line underneath the cursor horizontally.
|
||||||
|
set cursorline
|
||||||
|
|
||||||
|
" Highlight cursor line underneath the cursor vertically.
|
||||||
|
set cursorcolumn
|
||||||
|
{% endif %}
|
||||||
|
{% if (vim.tabs.spatialize | default(True)) %}
|
||||||
|
|
||||||
|
" Use space characters instead of tabs.
|
||||||
|
set expandtab
|
||||||
|
|
||||||
|
" Set tab width to 4 columns.
|
||||||
|
set tabstop={{ vimrc.tabs.gap | default(2) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
" While searching though a file incrementally highlight matching characters as you type.
|
||||||
|
set incsearch
|
||||||
|
|
||||||
|
" Show the mode you are on the last line.
|
||||||
|
set showmode
|
||||||
|
|
||||||
|
" Show matching words during a search.
|
||||||
|
set showmatch
|
||||||
|
|
||||||
|
" Use highlighting when doing a search.
|
||||||
|
set hlsearch
|
||||||
|
|
||||||
|
" Set the commands to save in history default number is 20.
|
||||||
|
set history={{ vimrc.history_span | default(20) }}
|
||||||
|
{% if (vimrc.typed_paths.autocomplete | default(True)) %}
|
||||||
|
|
||||||
|
" Enable auto completion menu after pressing TAB.
|
||||||
|
set wildmenu
|
||||||
|
|
||||||
|
" Make wildmenu behave like similar to Bash completion.
|
||||||
|
set wildmode=list:longest
|
||||||
|
{% if vimrc.typed_paths.ignore is defined and vimrc.typed_paths.ignore != None %}
|
||||||
|
|
||||||
|
" There are certain files that we would never want to edit with Vim.
|
||||||
|
" Wildmenu will ignore files with these extensions.
|
||||||
|
set wildignore={{ vimrc.typed_paths.ignore | join(',') }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
" PLUGINS ----------------------------------------------------------------
|
||||||
|
|
||||||
|
" Plugin code goes here.
|
||||||
|
|
||||||
|
call plug#begin('~/.vim/plugged')
|
||||||
|
|
||||||
|
Plug 'flazz/vim-colorschemes'
|
||||||
|
{% if (vimrc.autodelimit | default(True)) %}
|
||||||
|
Plug 'tpope/vim-surround'
|
||||||
|
{% endif %}
|
||||||
|
{% if (vimrc.git_spice | default(True)) %}
|
||||||
|
Plug 'airblade/vim-gitgutter'
|
||||||
|
Plug 'tpope/vim-fugitive'
|
||||||
|
{% endif %}
|
||||||
|
{% if (vimrc.status_line | default(True)) %}
|
||||||
|
Plug 'vim-airline/vim-airline'
|
||||||
|
{% endif %}
|
||||||
|
{% if (vimrc.fancy_commenting | default(True)) %}
|
||||||
|
Plug 'scrooloose/nerdcommenter'
|
||||||
|
{% endif %}
|
||||||
|
{% if (vimrc.ide | default(True)) %}
|
||||||
|
Plug 'dense-analysis/ale'
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
call plug#end()
|
||||||
|
|
||||||
|
" MAPPINGS ---------------------------------------------------------------
|
||||||
|
|
||||||
|
" Mappings code goes here.
|
||||||
|
|
||||||
|
" VIMSCRIPT --------------------------------------------------------------
|
||||||
|
{% if (vimrc.origami | default(True)) %}
|
||||||
|
|
||||||
|
" This will enable code folding.
|
||||||
|
" Use the marker method of folding.
|
||||||
|
augroup filetype_vim
|
||||||
|
autocmd!
|
||||||
|
autocmd FileType vim setlocal foldmethod=marker
|
||||||
|
augroup END
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
" More Vimscripts code goes here.
|
||||||
|
|
||||||
|
" STATUS LINE ------------------------------------------------------------
|
||||||
|
|
||||||
|
" Status bar code goes here.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ "$1" == "start" ]]; then
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p tcp --sport 80 -j ACCEPT # HTTP
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p tcp --sport 443 -j ACCEPT # HTTPS (HTTP + SSL/TLS)
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p udp --sport 443 -j ACCEPT # HTTPS (HTTP + SSL/TLS)
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p tcp --sport 465 -j ACCEPT # SMTP (send)
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p tcp --sport 587 -j ACCEPT # SMTP (send)
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p tcp --sport 995 -j ACCEPT # POP3 (receive)
|
||||||
|
/usr/sbin/iptables -A FORWARD -i dsnet -p tcp --sport 993 -j ACCEPT # IMAP (receive)
|
||||||
|
/usr/sbin/iptables -t nat -A POSTROUTING -o dsnet -j MASQUERADE
|
||||||
|
elif [[ "$1" == "stop" ]]; then
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p tcp --sport 80 -j ACCEPT # HTTP
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p tcp --sport 443 -j ACCEPT # HTTPS (HTTP + SSL/TLS)
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p udp --sport 443 -j ACCEPT # HTTPS (HTTP + SSL/TLS)
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p tcp --sport 465 -j ACCEPT # SMTP (send)
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p tcp --sport 587 -j ACCEPT # SMTP (send)
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p tcp --sport 995 -j ACCEPT # POP3 (receive)
|
||||||
|
/usr/sbin/iptables -D FORWARD -i dsnet -p tcp --sport 993 -j ACCEPT # IMAP (receive)
|
||||||
|
/usr/sbin/iptables -t nat -D POSTROUTING -o dsnet -j MASQUERADE
|
||||||
|
fi
|
||||||
Executable
+181
@@ -0,0 +1,181 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
# @TODO long-term, turn this simple bash script into more complex Python Click project
|
||||||
|
|
||||||
|
SKANSIBLE_SCRIPT_PATH=$(dirname "$0")
|
||||||
|
|
||||||
|
export ANSIBLE_FORCE_COLOR=True
|
||||||
|
SKANSIBLE_STAGE=0
|
||||||
|
ANSIBLE_VERBOSITY=0
|
||||||
|
SKANSIBLE_UNITTEST=False
|
||||||
|
SKANSIBLE_MODE=prod
|
||||||
|
|
||||||
|
if [[ "$1" == "version" ]]; then
|
||||||
|
echo "26.07"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "show-defaults" ]]; then
|
||||||
|
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
|
||||||
|
printf "Private SSH keys available throufh SSH agent: |\n%s\n" "$(ssh-add -l)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "start-agent" ]]; then
|
||||||
|
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
|
||||||
|
eval "$(ssh-agent -s)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "list-agent" ]]; then
|
||||||
|
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
|
||||||
|
ssh-add -l
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "populate-agent" ]]; then
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
|
||||||
|
|
||||||
|
if [[ "$1" == "all" ]]; then
|
||||||
|
for SKANSIBLE_SSH_KEY in ~/.ssh/*; do
|
||||||
|
case $SKANSIBLE_SSH_KEY in
|
||||||
|
*.pub);;
|
||||||
|
*.old);;
|
||||||
|
*.bak);;
|
||||||
|
*/config);;
|
||||||
|
*/authorized_keys);;
|
||||||
|
*_hosts);;
|
||||||
|
*/agent);;
|
||||||
|
*) ssh-add "${SKANSIBLE_SSH_KEY}";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
elif [[ "$1" == "staging" ]]; then
|
||||||
|
SKANSIBLE_SSH_KEY_COLLECTION=(~/.ssh/ed25519\@staging ~/.ssh/ecdsa\@staging ~/.ssh/ed25519-37851076-sk\@staging ~/.ssh/ecdsa-37851076-sk\@staging)
|
||||||
|
shift 1
|
||||||
|
elif [[ "$1" == "prod" ]]; then
|
||||||
|
SKANSIBLE_SSH_KEY_COLLECTION=(~/.ssh/ed25519\@staging ~/.ssh/ecdsa\@staging ~/.ssh/ed25519-37851076-sk\@staging ~/.ssh/ecdsa-37851076-sk\@staging)
|
||||||
|
shift 1
|
||||||
|
elif [[ -n "$1" ]]; then
|
||||||
|
# @TODO improve by adding fuzzy querying or file finding pror
|
||||||
|
ssh-add "$1"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for key in "${SKANSIBLE_SSH_KEY_COLLECTION[@]}"; do
|
||||||
|
ssh-add "$key"
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "init" ]]; then
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
|
||||||
|
|
||||||
|
if [[ "$1" == "vps" ]]; then
|
||||||
|
SKANSIBLE_PLAY_HOST="$1"
|
||||||
|
shift 1
|
||||||
|
elif [[ "$1" == "homeserver" ]]; then
|
||||||
|
SKANSIBLE_PLAY_HOST="$1"
|
||||||
|
shift 1
|
||||||
|
else
|
||||||
|
echo "A playbook type must be specified"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while getopts "htd:m:s:n:v:u:" opt; do
|
||||||
|
case $opt in
|
||||||
|
h) Help "init";;
|
||||||
|
s) SKANSIBLE_STAGE="$OPTARG";;
|
||||||
|
n) SKANSIBLE_CONN_HOST="$OPTARG";;
|
||||||
|
v) export ANSIBLE_VERBOSITY="$OPTARG";;
|
||||||
|
t) SKANSIBLE_UNITTEST=True;;
|
||||||
|
u) export ANSIBLE_REMOTE_USER="$OPTARG";;
|
||||||
|
m) SKANSIBLE_MODE="$OPTARG";;
|
||||||
|
d) SKANSIBLE_FQDN="$OPTARG";;
|
||||||
|
*) echo "Err: Invalid option set"; exit 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$SKANSIBLE_STAGE" ]; then
|
||||||
|
# SKANSIBLE_CONN_HOST=staging${SKANSIBLE_STAGE}.test
|
||||||
|
if [[ "$SKANSIBLE_STAGE" == 0 ]]; then
|
||||||
|
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
|
||||||
|
sudo ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
else
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
fi
|
||||||
|
elif [[ "$SKANSIBLE_STAGE" == 1 ]]; then
|
||||||
|
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
|
||||||
|
sudo ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
else
|
||||||
|
sudo ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "init@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -z "$SKANSIBLE_CONN_HOST" ]] && [[ -z "$SKANSIBLE_FQDN" ]]; then
|
||||||
|
echo "When not doing staging, chosen or preferred host must be made explicit as well as desired FQDN"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=prod" --extra-vars "fqdn=${SKANSIBLE_FQDN}" "init@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$1" == "bootstrap" ]]; then
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
source "${SKANSIBLE_SCRIPT_PATH}/.venv/bin/activate"
|
||||||
|
|
||||||
|
if [[ "$1" == "vps" ]]; then
|
||||||
|
SKANSIBLE_PLAY_HOST="$1"
|
||||||
|
shift 1
|
||||||
|
elif [[ "$1" == "homeserver" ]]; then
|
||||||
|
SKANSIBLE_PLAY_HOST="$1"
|
||||||
|
shift 1
|
||||||
|
else
|
||||||
|
echo "A playbook type must be specified"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while getopts "htd:m:s:n:v:u:" opt; do
|
||||||
|
case $opt in
|
||||||
|
h) Help "bootstrap";;
|
||||||
|
s) SKANSIBLE_STAGE="$OPTARG";;
|
||||||
|
n) SKANSIBLE_CONN_HOST="$OPTARG";;
|
||||||
|
v) export ANSIBLE_VERBOSITY=4;;
|
||||||
|
t) SKANSIBLE_UNITTEST=True;;
|
||||||
|
u) export ANSIBLE_REMOTE_USER="$OPTARG";;
|
||||||
|
m) SKANSIBLE_MODE="$OPTARG";;
|
||||||
|
d) SKANSIBLE_FQDN="$OPTARG";;
|
||||||
|
*) echo "Err: Invalid option set"; exit 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$SKANSIBLE_STAGE" ]; then
|
||||||
|
# SKANSIBLE_CONN_HOST=staging${SKANSIBLE_STAGE}.test
|
||||||
|
if [[ "$SKANSIBLE_STAGE" == 0 ]]; then
|
||||||
|
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
|
||||||
|
ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
else
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
fi
|
||||||
|
elif [[ "$SKANSIBLE_STAGE" == 1 ]]; then
|
||||||
|
if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
|
||||||
|
ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
else
|
||||||
|
ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" --extra-vars "fqdn=${SKANSIBLE_FQDN:-staging.test}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -z "$SKANSIBLE_CONN_HOST" ]]; then
|
||||||
|
echo "When not doing staging, chosen or preferred host must be made explicit as well as desired FQDN"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=prod" --extra-vars "fqdn=${SKANSIBLE_FQDN}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
config.vm.box = "debian/trixie64"
|
||||||
|
config.vm.hostname = "staging0.test"
|
||||||
|
config.vm.network "private_network", ip: "192.168.122.234", bridge: "virbr0", ipv6: true
|
||||||
|
config.vm.network "forwarded_port", guest: 51820, host: 51820
|
||||||
|
config.vm.network "forwarded_port", guest: 80, host: 80
|
||||||
|
config.vm.network "forwarded_port", guest: 443, host: 443
|
||||||
|
config.ssh.username = "root"
|
||||||
|
config.ssh.password = "vagrant"
|
||||||
|
config.vm.provider "libvirt" do |lv|
|
||||||
|
lv.memory = 2048
|
||||||
|
lv.cpus = 3
|
||||||
|
lv.driver = "kvm"
|
||||||
|
end
|
||||||
|
config.vm.box_version = "13.20260519.1"
|
||||||
|
end
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
config.vm.box = "debian/trixie64"
|
||||||
|
config.vm.hostname = "staging0.test"
|
||||||
|
config.vm.network "private_network", ip: "192.168.200.201", bridge: "virbr0", ipv6: true
|
||||||
|
config.vm.network "forwarded_port", guest: 51820, host: 51820
|
||||||
|
# config.vm.network "forwarded_port", guest: 80, host: 80
|
||||||
|
# config.vm.network "forwarded_port", guest: 443, host: 443
|
||||||
|
config.ssh.username = "root"
|
||||||
|
config.ssh.password = "vagrant"
|
||||||
|
config.vm.provider "libvirt" do |lv|
|
||||||
|
lv.memory = 2048
|
||||||
|
lv.cpus = 3
|
||||||
|
lv.driver = "kvm"
|
||||||
|
end
|
||||||
|
config.vm.box_version = "13.20260519.1"
|
||||||
|
end
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
# @TODO use Ansible vault for secret and some credentials values
|
||||||
|
aria:
|
||||||
|
containerized: true
|
||||||
|
rpc:
|
||||||
|
enabled: false
|
||||||
|
listen_all: true
|
||||||
|
scheme: http
|
||||||
|
hostname: localhost
|
||||||
|
port: 6800
|
||||||
|
secret: ~
|
||||||
|
credentials: ~
|
||||||
|
# dest: "{{ ansible_user_home.stdout }}/downloads/aria2"
|
||||||
|
log: warn
|
||||||
|
alloc: falloc # choices are "falloc", "prealloc", "trunc", or "none"
|
||||||
|
dcache: 64M
|
||||||
|
conn:
|
||||||
|
# netrc:
|
||||||
|
# path: "{{ ansible_user_home.stdout }}/.netrc"
|
||||||
|
max:
|
||||||
|
attempts: 3
|
||||||
|
per_server: 3
|
||||||
|
split: 6
|
||||||
|
proxy:
|
||||||
|
enabled: true
|
||||||
|
uri: "localhost:9050"
|
||||||
|
excluded:
|
||||||
|
- "127.0.0.1"
|
||||||
|
- "::1"
|
||||||
|
dl:
|
||||||
|
max:
|
||||||
|
concurrent: 30
|
||||||
|
resume: true
|
||||||
|
overwriting: true
|
||||||
|
autorenaming: true
|
||||||
|
# stats:
|
||||||
|
# path: "{{ ansible_user_home.stdout }}/.aria2/dl.log"
|
||||||
|
algorithm: adaptive # choices are "inorder", "feedback", "adaptive"
|
||||||
|
ul:
|
||||||
|
max:
|
||||||
|
overall: 5M
|
||||||
|
per_entry: 0
|
||||||
|
http:
|
||||||
|
gzip: true
|
||||||
|
cache: false
|
||||||
|
sustain: true
|
||||||
|
agent: "Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0"
|
||||||
|
ftp:
|
||||||
|
mode: passive # choices are "passive" or "active"
|
||||||
|
data_type: binary # choices are "binary" or "ascii"
|
||||||
|
trnt:
|
||||||
|
dht:
|
||||||
|
enabled: true
|
||||||
|
port: 6881-6999
|
||||||
|
entrypoint: ~
|
||||||
|
# path: "{{ ansible_user_home.stdout }}/.aria2/dht.dat"
|
||||||
|
# path6: "{{ ansible_user_home.stdout }}/.aria2/dht6.dat"
|
||||||
|
local_discovery: true
|
||||||
|
encrypt: true
|
||||||
|
peers:
|
||||||
|
agent: "Deluge 1.3.15"
|
||||||
|
prefix: "-DE13F0-"
|
||||||
|
max: 100
|
||||||
|
exchange: true
|
||||||
|
seeding:
|
||||||
|
ratio: 2.0
|
||||||
|
time: 0
|
||||||
|
trackers:
|
||||||
|
- http://1337.abcvg.info:80/announce
|
||||||
|
- http://bt1.archive.org:6969/announce
|
||||||
|
- http://ipv4announce.sktorrent.eu:6969/announce
|
||||||
|
- http://nyaa.tracker.wf:7777/announce
|
||||||
|
- http://torrentsmd.com:8080/announce
|
||||||
|
- http://tracker.bt4g.com:2095/announce
|
||||||
|
- http://tracker.dhitechnical.com:6969/announce
|
||||||
|
- http://tracker.mywaifu.best:6969/announce
|
||||||
|
- http://tracker.renfei.net:8080/announce
|
||||||
|
- http://tracker.waaa.moe:6969/announce
|
||||||
|
- http://tracker.xn--djrq4gl4hvoi.top:80/announce
|
||||||
|
- http://www.wareztorrent.com:80/announce
|
||||||
|
- https://021912.xyz:443/announce
|
||||||
|
- https://1337.abcvg.info:443/announce
|
||||||
|
- https://banananetwork.qzz.io:443/announce
|
||||||
|
- https://orgtgju.org:443/announce
|
||||||
|
- https://t.213891.xyz:443/announce
|
||||||
|
- https://torrents.tmtime.dev:443/announce
|
||||||
|
- https://tr.abiir.top:443/announce
|
||||||
|
- https://tr.nyacat.pw:443/announce
|
||||||
|
- https://tr.zukizuki.org:443/announce
|
||||||
|
- https://tracker.7471.top:443/announce
|
||||||
|
- https://tracker.anibt.net:443/announce
|
||||||
|
- https://tracker.gcrenwp.top:443/announce
|
||||||
|
- https://tracker.kuroy.me:443/announce
|
||||||
|
- https://tracker.leechshield.link:443/announce
|
||||||
|
- https://tracker.manager.v6.navy:443/announce
|
||||||
|
- https://tracker.nekomi.cn:443/announce
|
||||||
|
- https://tracker.pmman.tech:443/announce
|
||||||
|
- https://tracker.zhuqiy.com:443/announce
|
||||||
|
- https://tracker1.520.jp:443/announce
|
||||||
|
- udp://anime-tracker.aruku.kro.kr:8081/announce
|
||||||
|
- udp://bittorrent-tracker.e-n-c-r-y-p-t.net:1337/announce
|
||||||
|
- udp://coeus.torrentonline.cc:42069/announce
|
||||||
|
- udp://evan.im:6969/announce
|
||||||
|
- udp://mail.segso.net:6969/announce
|
||||||
|
- udp://martin-gebhardt.eu:25/announce
|
||||||
|
- udp://ns575949.ip-51-222-82.net:6969/announce
|
||||||
|
- udp://open.demonii.com:1337/announce
|
||||||
|
- udp://open.ftorrent.com:443/announce
|
||||||
|
- udp://open.stealth.si:80/announce
|
||||||
|
- udp://open.tracker.ink:6969/announce
|
||||||
|
- udp://opentor.org:2710/announce
|
||||||
|
- udp://p4p.arenabg.com:1337/announce
|
||||||
|
- udp://seedpeer.net:6969/announce
|
||||||
|
- udp://t.overflow.biz:6969/announce
|
||||||
|
- udp://torrentclub.online:1984/announce
|
||||||
|
- udp://tracker-udp.gbitt.info:80/announce
|
||||||
|
- udp://tracker.004430.xyz:1337/announce
|
||||||
|
- udp://tracker.aruku.ovh:8081/announce
|
||||||
|
- udp://tracker.auctor.tv:6969/announce
|
||||||
|
- udp://tracker.bittor.pw:1337/announce
|
||||||
|
- udp://tracker.bluefrog.pw:2710/announce
|
||||||
|
- udp://tracker.breizh.pm:6969/announce
|
||||||
|
- udp://tracker.corpscorp.online:80/announce
|
||||||
|
- udp://tracker.dler.com:6969/announce
|
||||||
|
- udp://tracker.ducks.party:1984/announce
|
||||||
|
- udp://tracker.gmi.gd:6969/announce
|
||||||
|
- udp://tracker.hismz.cn:6969/announce
|
||||||
|
- udp://tracker.opentorrent.top:6969/announce
|
||||||
|
- udp://tracker.opentrackr.org:1337/announce
|
||||||
|
- udp://tracker.peerfect.org:6969/announce
|
||||||
|
- udp://tracker.publictracker.xyz:6969/announce
|
||||||
|
- udp://tracker.qu.ax:6969/announce
|
||||||
|
- udp://tracker.skyts.net:6969/announce
|
||||||
|
- udp://tracker.t-1.org:6969/announce
|
||||||
|
- udp://tracker.teambelgium.net:6969/announce
|
||||||
|
- udp://tracker.torrent.eu.org:451/announce
|
||||||
|
- udp://tracker.trackarr.org:6969/announce
|
||||||
|
- udp://tracker.tryhackx.org:6969/announce
|
||||||
|
- udp://tracker.wildkat.net:6969/announce
|
||||||
|
- udp://yuptracker-eu.gaijinent.com:27022/announce
|
||||||
|
- udp://zer0day.ch:1337/announce
|
||||||
|
- wss://tracker.openwebtorrent.com:443/announce
|
||||||
|
meta:
|
||||||
|
follow: mem
|
||||||
|
lang: en
|
||||||
|
protocol_pref: ftp # choices are "ftp", "http", "https"
|
||||||
|
locs: []
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
caddy:
|
||||||
|
containerized: true
|
||||||
|
scheme: http
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
certbot:
|
||||||
|
mode: "{{ mode | default('prod') }}"
|
||||||
|
containerized: true
|
||||||
|
auth_method: webroot
|
||||||
|
port: ~
|
||||||
|
email: ajt95@prole.biz
|
||||||
|
domains:
|
||||||
|
- "{{ fqdn | default(inventory_hostname) }}"
|
||||||
|
- "*.{{ fqdn | default(inventory_hostname) }}"
|
||||||
|
cron: "2 6 24 1 *"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
certbot:
|
||||||
|
mode: "{{ mode | default('prod') }}"
|
||||||
|
containerized: false
|
||||||
|
auth_method: dns
|
||||||
|
port: 53
|
||||||
|
email: ajt95@prole.biz
|
||||||
|
domains:
|
||||||
|
- "{{ fqdn | default(inventory_hostname) }}"
|
||||||
|
- "*.{{ fqdn | default(inventory_hostname) }}"
|
||||||
|
cron: ~
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
crowdsec:
|
||||||
|
containerized: false
|
||||||
|
port: 6050
|
||||||
|
colls:
|
||||||
|
- "crowdsecurity/base-http-scenarios"
|
||||||
|
- "crowdsecurity/proftpd"
|
||||||
|
parsers: []
|
||||||
|
scenarios: []
|
||||||
|
postoverflows: []
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
email:
|
||||||
|
smtp:
|
||||||
|
auth_meth: login
|
||||||
|
host: smtp.startmail.com
|
||||||
|
port: 465
|
||||||
|
conn_mode: ssl
|
||||||
|
username: rika@sukaato.moe
|
||||||
|
password: "{{ lookup('password', './.tmp/' + inventory_hostname + '-user@email/email.pass', chars=['ascii_lowercase', 'digits'], length=8) }}"
|
||||||
|
alias: admin@sukaato.moe
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
flexget:
|
||||||
|
enabled: true
|
||||||
|
download_mode: direct
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
git_aliases:
|
||||||
|
- [ckot, checkout]
|
||||||
|
- [chbr, checkout]
|
||||||
|
- [ch_br, checkout]
|
||||||
|
- [tch_br, "'checkout -b'"]
|
||||||
|
- [tchbr, "'checkout -b'"]
|
||||||
|
- [tchbr, "'checkout -b'"]
|
||||||
|
- [add_br, "'checkout -b'"]
|
||||||
|
- [addbr, "'checkout -b'"]
|
||||||
|
- [rm_br, "'branch -D'"]
|
||||||
|
- [rmbr, "'branch -D'"]
|
||||||
|
- [del_br, "'branch -D'"]
|
||||||
|
- [delbr, "'branch -D'"]
|
||||||
|
- [tch_rmt, "'remote add'"]
|
||||||
|
- [tchrmt, "'remote add'"]
|
||||||
|
- [add_rmt, "'remote add'"]
|
||||||
|
- [addrmt, "'remote add'"]
|
||||||
|
- [rm_rmt, "'remote remove'"]
|
||||||
|
- [rmrmt, "'remote remove'"]
|
||||||
|
- [del_rmt, "'remote remove'"]
|
||||||
|
- [delrmt, "'remote remove'"]
|
||||||
|
- [cfg, config]
|
||||||
|
- [psh, push]
|
||||||
|
- [snd, push]
|
||||||
|
- [send, push]
|
||||||
|
- [post, push]
|
||||||
|
- [pl, pull]
|
||||||
|
- [receive, pull]
|
||||||
|
- [get, pull]
|
||||||
|
- [fch, fetch]
|
||||||
|
- [hist, log]
|
||||||
|
- [scenes, log]
|
||||||
|
- [br, branch]
|
||||||
|
- [lsbr, "'branch -v'"]
|
||||||
|
- [ls_br, "'branch -v'"]
|
||||||
|
- [rmt, remote]
|
||||||
|
- [ls_rmt, "'remote -v'"]
|
||||||
|
- [lsrmt, "'remote -v'"]
|
||||||
|
- [cmmt, commit]
|
||||||
|
- [register, commit]
|
||||||
|
- [st, status]
|
||||||
|
- [stat, status]
|
||||||
|
- [state, status]
|
||||||
|
- [current, status]
|
||||||
|
- [restart, "reset --hard"]
|
||||||
|
- [undo, "'reset HEAD~1 --mixed'"]
|
||||||
|
- [unstage, "'reset HEAD --'"]
|
||||||
|
- [stage, add]
|
||||||
|
- [touch, add]
|
||||||
|
- [tch, add]
|
||||||
|
- [del, rm]
|
||||||
|
- [prev, "'log -1 HEAD'"]
|
||||||
|
- [last, "'log -1 HEAD'"]
|
||||||
|
- [finito, "'!git push origin HEAD'"]
|
||||||
|
- [chkpnt, "'!git add -A && git commit -m'"]
|
||||||
|
- [sgn, "'commit --amend --no-edit -S'"]
|
||||||
|
- [rvrt, revert]
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user