Truncated history

This commit is contained in:
2024-12-28 12:04:44 +01:00
parent a0fd43e8c6
commit ea1fe23d8d
74 changed files with 3111 additions and 34 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.passwords

5
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"recommendations": [
"william-voyek.vscode-nginx"
]
}

View File

@@ -1,4 +1,4 @@
[defaults]
inventory = inventory
remote_user = ansible
# Will use yubikey for ssh authentication
# Will use yubikey or bitwarden for ssh authentication

8
decrypt-vault.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
./helpers/get-passwords.sh
ansible-vault decrypt vars/bootstrap.yaml --vault-password-file ./.passwords/vault
ansible-vault decrypt vars/bigboi.yaml --vault-password-file ./.passwords/vault
ansible-vault decrypt vars/smolboi.yaml --vault-password-file ./.passwords/vault
./helpers/delete-passwords.sh

8
encrypt-vault.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
./helpers/get-passwords.sh
ansible-vault encrypt vars/bootstrap.yaml --vault-password-file ./.passwords/vault
ansible-vault encrypt vars/bigboi.yaml --vault-password-file ./.passwords/vault
ansible-vault encrypt vars/smolboi.yaml --vault-password-file ./.passwords/vault
./helpers/delete-passwords.sh

16
git-hooks/commit-msg Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
# TODO: Clean this up so it iterates over the vars files
if grep -qE "vault_decrypted: true" "./vars/bigboi.yaml";then
echo "The vault isn't encrypted, run './encrypt-vault.sh' before committing."
exit 1
fi
if grep -qE "vault_decrypted: true" "./vars/bootstrap.yaml";then
echo "The vault isn't encrypted, run './encrypt-vault.sh' before committing."
exit 1
fi
if grep -qE "vault_decrypted: true" "./vars/smolboi.yaml";then
echo "The vault isn't encrypted, run './encrypt-vault.sh' before committing."
exit 1
fi

9
helpers/delete-passwords.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
if [[ -d "./.passwords" ]]
then
rm -rf "./.passwords"
echo "Deleted passwords"
else
echo "There were no passwords to delete"
fi

2
helpers/generate-password.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
mkpasswd --method=sha-512

14
helpers/get-passwords.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash
if ! [[ -d "./.passwords" ]]
then
mkdir "./.passwords"
echo "Created passwords directory"
fi
bw get password "ansible vault encryption" > ./.passwords/vault
echo "Fetched vault password"
bw get password "linux user ansible@bigboi" > ./.passwords/become
echo "Fetched ansible user password"
bw get password "linux user wholteza@bigboi" > ./.passwords/bootstrap_become
echo "Fetched bootstrap user password"

8
install-requirements.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
sudo apt update \
&& sudo apt install whois ansible \
&& ansible-galaxy collection install community.general \
&& ansible-galaxy collection install community.libvirt \
&& ansible-galaxy collection install ansible.posix
cp ./git-hooks/commit-msg ./.git/hooks/commit-msg

View File

@@ -1,5 +1,5 @@
[nas]
temp.zacke.xyz
[production_main]
bigboi.zacke.xyz
[reverse-proxy]
temp.zacke.xyz
[production_first_backup]
smolboi.zacke.xyz

View File

@@ -1,11 +1,46 @@
---
# - hosts: all
# become: true
# remote_user: wholteza
# roles:
# - role: shared/bootstrap
# vars_files:
# - vars/bootstrap.yaml
- hosts: all
become: true
roles:
- role: base
- hosts: nas
- hosts: production_main
become: true
roles:
- role: nas
# - role: shared/update
# - role: bigboi/users
# - role: bigboi/network
# - role: shared/avahi
# - role: bigboi/nginx
# - role: shared/ssmtp
# - role: bigboi/zfs
# - role: shared/zfs-zed
# - role: bigboi/samba
# - role: bigboi/sanoid
# - role: shared/powertop
# - role: bigboi/apcupsd
# - role: bigboi/libvirt
# - role: bigboi/kvm-homeassistant
- role: bigboi/docker
# - role: artis3n.tailscale
# - role: shared/various-cli-tools
vars_files:
- vars/bigboi.yaml
- hosts: production_first_backup
become: true
roles:
# - role: shared/update
# - role: shared/powertop
# - role: shared/avahi
# - role: shared/ssmtp
# - role: shared/zfs-install
# - role: smolboi/zfs
# - role: shared/zfs-zed
# - role: smolboi/sanoid
# - role: shared/various-cli-tools
vars_files:
- vars/smolboi.yaml

27
readme.md Normal file
View File

@@ -0,0 +1,27 @@
## Installing and running
Prior to following the steps below you need to set up the ssh agent to work with the gpg key from your yubikey and also the `pass` password store.
1. Install the required packages with `install-requirements.sh`
2. Run the playbook `run-playbook.sh`
- The script automatically fetches the required passwords from the password store
The playbook requires the user `ansible` to be present on the target systems with the yubikey ssh key as authorized key and member of the sudoers group.
The required password to be set on the ansible user can be found in `pass wholteza/network/lilleback/ansible/ansible`.
While running fetched passwords will be placed in the `.temp` directory. Any script that creates that directory must delete it afterwards.
## Making changes to the vault
The vault encryption is managed by `ansible-vault` + passwords from `pass`.
Use `./decrypt-vault.sh` and `./encrypt-vault.sh` to make the file into clear text and the other way around.
There is a pre-commit git hook that will prevent you from committing if the file is clear text.
Be careful because even if you have a non-encrypted version of the vault staged and the unstaged file is encrypted you will be able to commit atm.
## Generating passwords for the vault file
1. Use `generate-password.sh` to generate a hash of your password.

View File

@@ -0,0 +1,343 @@
## apcupsd.conf v1.1 ##
#
# "apcupsd" POSIX config file
#
# Note that the apcupsd daemon must be restarted in order for changes to
# this configuration file to become active.
#
#
# ========= General configuration parameters ============
#
# UPSNAME xxx
# Use this to give your UPS a name in log files and such. This
# is particulary useful if you have multiple UPSes. This does not
# set the EEPROM. It should be 8 characters or less.
#UPSNAME
# UPSCABLE <cable>
# Defines the type of cable connecting the UPS to your computer.
#
# Possible generic choices for <cable> are:
# simple, smart, ether, usb
#
# Or a specific cable model number may be used:
# 940-0119A, 940-0127A, 940-0128A, 940-0020B,
# 940-0020C, 940-0023A, 940-0024B, 940-0024C,
# 940-1524C, 940-0024G, 940-0095A, 940-0095B,
# 940-0095C, 940-0625A, M-04-02-2000
#
UPSCABLE usb
# To get apcupsd to work, in addition to defining the cable
# above, you must also define a UPSTYPE, which corresponds to
# the type of UPS you have (see the Description for more details).
# You must also specify a DEVICE, sometimes referred to as a port.
# For USB UPSes, please leave the DEVICE directive blank. For
# other UPS types, you must specify an appropriate port or address.
#
# UPSTYPE DEVICE Description
# apcsmart /dev/tty** Newer serial character device, appropriate for
# SmartUPS models using a serial cable (not USB).
#
# usb <BLANK> Most new UPSes are USB. A blank DEVICE
# setting enables autodetection, which is
# the best choice for most installations.
#
# net hostname:port Network link to a master apcupsd through apcupsd's
# Network Information Server. This is used if the
# UPS powering your computer is connected to a
# different computer for monitoring.
#
# snmp hostname:port:vendor:community
# SNMP network link to an SNMP-enabled UPS device.
# Hostname is the ip address or hostname of the UPS
# on the network. Vendor can be can be "APC" or
# "APC_NOTRAP". "APC_NOTRAP" will disable SNMP trap
# catching; you usually want "APC". Port is usually
# 161. Community is usually "private".
#
# netsnmp hostname:port:vendor:community
# OBSOLETE
# Same as SNMP above but requires use of the
# net-snmp library. Unless you have a specific need
# for this old driver, you should use 'snmp' instead.
#
# dumb /dev/tty** Old serial character device for use with
# simple-signaling UPSes.
#
# pcnet ipaddr:username:passphrase:port
# PowerChute Network Shutdown protocol which can be
# used as an alternative to SNMP with the AP9617
# family of smart slot cards. ipaddr is the IP
# address of the UPS management card. username and
# passphrase are the credentials for which the card
# has been configured. port is the port number on
# which to listen for messages from the UPS, normally
# 3052. If this parameter is empty or missing, the
# default of 3052 will be used.
#
# modbus /dev/tty** Serial device for use with newest SmartUPS models
# supporting the MODBUS protocol.
# modbus <BLANK> Leave the DEVICE setting blank for MODBUS over USB
# or set to the serial number of the UPS to ensure
# that apcupsd binds to that particular unit
# (helpful if you have more than one USB UPS).
#
UPSTYPE usb
#DEVICE /dev/ttyS0
# POLLTIME <int>
# Interval (in seconds) at which apcupsd polls the UPS for status. This
# setting applies both to directly-attached UPSes (UPSTYPE apcsmart, usb,
# dumb) and networked UPSes (UPSTYPE net, snmp). Lowering this setting
# will improve apcupsd's responsiveness to certain events at the cost of
# higher CPU utilization. The default of 60 is appropriate for most
# situations.
#POLLTIME 60
# LOCKFILE <path to lockfile>
# Path for device lock file for UPSes connected via USB or
# serial port. This is the directory into which the lock file
# will be written. The directory must already exist; apcupsd will not create
# it. The actual name of the lock file is computed from DEVICE.
# Not used on Win32.
LOCKFILE /var/lock
# SCRIPTDIR <path to script directory>
# Directory in which apccontrol and event scripts are located.
SCRIPTDIR /etc/apcupsd
# PWRFAILDIR <path to powerfail directory>
# Directory in which to write the powerfail flag file. This file
# is created when apcupsd initiates a system shutdown and is
# checked in the OS halt scripts to determine if a killpower
# (turning off UPS output power) is required.
PWRFAILDIR /etc/apcupsd
# NOLOGINDIR <path to nologin directory>
# Directory in which to write the nologin file. The existence
# of this flag file tells the OS to disallow new logins.
NOLOGINDIR /etc
#
# ======== Configuration parameters used during power failures ==========
#
# The ONBATTERYDELAY is the time in seconds from when a power failure
# is detected until we react to it with an onbattery event.
#
# This means that, apccontrol will be called with the powerout argument
# immediately when a power failure is detected. However, the
# onbattery argument is passed to apccontrol only after the
# ONBATTERYDELAY time. If you don't want to be annoyed by short
# powerfailures, make sure that apccontrol powerout does nothing
# i.e. comment out the wall.
ONBATTERYDELAY 6
#
# Note: BATTERYLEVEL, MINUTES, and TIMEOUT work in conjunction, so
# the first that occurs will cause the initation of a shutdown.
#
# If during a power failure, the remaining battery percentage
# (as reported by the UPS) is below or equal to BATTERYLEVEL,
# apcupsd will initiate a system shutdown.
BATTERYLEVEL 10
# If during a power failure, the remaining runtime in minutes
# (as calculated internally by the UPS) is below or equal to MINUTES,
# apcupsd, will initiate a system shutdown.
MINUTES 5
# If during a power failure, the UPS has run on batteries for TIMEOUT
# many seconds or longer, apcupsd will initiate a system shutdown.
# A value of 0 disables this timer.
#
# Note, if you have a Smart UPS, you will most likely want to disable
# this timer by setting it to zero. That way, you UPS will continue
# on batteries until either the % charge remaing drops to or below BATTERYLEVEL,
# or the remaining battery runtime drops to or below MINUTES. Of course,
# if you are testing, setting this to 60 causes a quick system shutdown
# if you pull the power plug.
# If you have an older dumb UPS, you will want to set this to less than
# the time you know you can run on batteries.
TIMEOUT 0
# Time in seconds between annoying users to signoff prior to
# system shutdown. 0 disables.
ANNOY 300
# Initial delay after power failure before warning users to get
# off the system.
ANNOYDELAY 60
# The condition which determines when users are prevented from
# logging in during a power failure.
# NOLOGON <string> [ disable | timeout | percent | minutes | always ]
NOLOGON disable
# If KILLDELAY is non-zero, apcupsd will continue running after a
# shutdown has been requested, and after the specified time in
# seconds attempt to kill the power. This is for use on systems
# where apcupsd cannot regain control after a shutdown.
# KILLDELAY <seconds> 0 disables
KILLDELAY 0
#
# ==== Configuration statements for Network Information Server ====
#
# NETSERVER [ on | off ] on enables, off disables the network
# information server. If netstatus is on, a network information
# server process will be started for serving the STATUS and
# EVENT data over the network (used by CGI programs).
NETSERVER on
# NISIP <dotted notation ip address>
# IP address on which NIS server will listen for incoming connections.
# This is useful if your server is multi-homed (has more than one
# network interface and IP address). Default value is 0.0.0.0 which
# means any incoming request will be serviced. Alternatively, you can
# configure this setting to any specific IP address of your server and
# NIS will listen for connections only on that interface. Use the
# loopback address (127.0.0.1) to accept connections only from the
# local machine.
NISIP 127.0.0.1
# NISPORT <port> default is 3551 as registered with the IANA
# port to use for sending STATUS and EVENTS data over the network.
# It is not used unless NETSERVER is on. If you change this port,
# you will need to change the corresponding value in the cgi directory
# and rebuild the cgi programs.
NISPORT 3551
# If you want the last few EVENTS to be available over the network
# by the network information server, you must define an EVENTSFILE.
EVENTSFILE /var/log/apcupsd.events
# EVENTSFILEMAX <kilobytes>
# By default, the size of the EVENTSFILE will be not be allowed to exceed
# 10 kilobytes. When the file grows beyond this limit, older EVENTS will
# be removed from the beginning of the file (first in first out). The
# parameter EVENTSFILEMAX can be set to a different kilobyte value, or set
# to zero to allow the EVENTSFILE to grow without limit.
EVENTSFILEMAX 10
#
# ========== Configuration statements used if sharing =============
# a UPS with more than one machine
#
# Remaining items are for ShareUPS (APC expansion card) ONLY
#
# UPSCLASS [ standalone | shareslave | sharemaster ]
# Normally standalone unless you share an UPS using an APC ShareUPS
# card.
UPSCLASS standalone
# UPSMODE [ disable | share ]
# Normally disable unless you share an UPS using an APC ShareUPS card.
UPSMODE disable
#
# ===== Configuration statements to control apcupsd system logging ========
#
# Time interval in seconds between writing the STATUS file; 0 disables
STATTIME 0
# Location of STATUS file (written to only if STATTIME is non-zero)
STATFILE /var/log/apcupsd.status
# LOGSTATS [ on | off ] on enables, off disables
# Note! This generates a lot of output, so if
# you turn this on, be sure that the
# file defined in syslog.conf for LOG_NOTICE is a named pipe.
# You probably do not want this on.
LOGSTATS off
# Time interval in seconds between writing the DATA records to
# the log file. 0 disables.
DATATIME 0
# FACILITY defines the logging facility (class) for logging to syslog.
# If not specified, it defaults to "daemon". This is useful
# if you want to separate the data logged by apcupsd from other
# programs.
#FACILITY DAEMON
#
# ========== Configuration statements used in updating the UPS EPROM =========
#
#
# These statements are used only by apctest when choosing "Set EEPROM with conf
# file values" from the EEPROM menu. THESE STATEMENTS HAVE NO EFFECT ON APCUPSD.
#
# UPS name, max 8 characters
#UPSNAME UPS_IDEN
# Battery date - 8 characters
#BATTDATE mm/dd/yy
# Sensitivity to line voltage quality (H cause faster transfer to batteries)
# SENSITIVITY H M L (default = H)
#SENSITIVITY H
# UPS delay after power return (seconds)
# WAKEUP 000 060 180 300 (default = 0)
#WAKEUP 60
# UPS Grace period after request to power off (seconds)
# SLEEP 020 180 300 600 (default = 20)
#SLEEP 180
# Low line voltage causing transfer to batteries
# The permitted values depend on your model as defined by last letter
# of FIRMWARE or APCMODEL. Some representative values are:
# D 106 103 100 097
# M 177 172 168 182
# A 092 090 088 086
# I 208 204 200 196 (default = 0 => not valid)
#LOTRANSFER 208
# High line voltage causing transfer to batteries
# The permitted values depend on your model as defined by last letter
# of FIRMWARE or APCMODEL. Some representative values are:
# D 127 130 133 136
# M 229 234 239 224
# A 108 110 112 114
# I 253 257 261 265 (default = 0 => not valid)
#HITRANSFER 253
# Battery charge needed to restore power
# RETURNCHARGE 00 15 50 90 (default = 15)
#RETURNCHARGE 15
# Alarm delay
# 0 = zero delay after pwr fail, T = power fail + 30 sec, L = low battery, N = never
# BEEPSTATE 0 T L N (default = 0)
#BEEPSTATE T
# Low battery warning delay in minutes
# LOWBATT 02 05 07 10 (default = 02)
#LOWBATT 2
# UPS Output voltage when running on batteries
# The permitted values depend on your model as defined by last letter
# of FIRMWARE or APCMODEL. Some representative values are:
# D 115
# M 208
# A 100
# I 230 240 220 225 (default = 0 => not valid)
#OUTPUTVOLTS 230
# Self test interval in hours 336=2 weeks, 168=1 week, ON=at power on
# SELFTEST 336 168 ON OFF (default = 336)
#SELFTEST 336

View File

@@ -0,0 +1,22 @@
---
- name: Install apcupsd
apt:
name: apcupsd
state: present
- name: Copy config
copy:
src: apcupsd.conf
dest: /etc/apcupsd/apcupsd.conf
mode: 0644
owner: root
group: root
register: apcupsd_config
- name: Restart service
systemd:
name: apcupsd
state: restarted
enabled: yes
when: apcupsd_config.changed

View File

@@ -0,0 +1,134 @@
# Frigate directories
- name: Ensure frigate root dir
file:
path: "{{docker.frigate.root_volume}}"
state: directory
owner: docker
group: root
- name: Ensure frigate config dir
file:
path: "{{docker.frigate.config_volume}}"
state: directory
owner: docker
group: root
- name: Ensure frigate media dir
file:
path: "{{docker.frigate.media_volume}}"
state: directory
owner: docker
group: root
- name: Ensure frigate config file
template:
src: frigate-config.yml
dest: "{{docker.frigate.config_volume}}/config.yml"
owner: docker
group: root
register: frigate_config_file
# Grafana directory
- name: Ensure grafana config dir
file:
path: "{{docker.grafana.data_volume}}"
state: directory
owner: docker
group: root
# InfluxDB directory
- name: Ensure influxdb config dir
file:
path: "{{docker.influxdb.data_volume}}"
state: directory
owner: docker
group: root
- name: Ensure photoprism config dir
file:
path: "{{docker.photoprism.data_volume}}"
state: directory
owner: photoprism
group: root
- name: Ensure mariadb config dir
file:
path: "{{docker.mariadb.data_volume}}"
state: directory
owner: photoprism
group: root
- name: Ensure vaultwarden config dir
file:
path: "{{docker.vaultwarden.data_volume}}"
state: directory
owner: docker
group: root
- name: Ensure letsencrypt config dir
file:
path: "{{docker.letsencrypt.data_volume}}"
state: directory
owner: docker
group: root
# Docker service setup
- name: Install requirements
apt:
name:
- docker.io
- docker-compose
- python3-pip
state: present
- name: install requirements
ansible.builtin.pip:
name: docker
- name: Enable docker
systemd:
name: docker
enabled: yes
- name: Ensure docker project dir
file:
path: "{{docker.project_path}}"
state: directory
owner: docker
group: docker
- name: Ensure docker-compose file
template:
src: docker-compose.yml
dest: "{{docker.project_path}}"
owner: ansible
group: ansible
register: docker_compose_file
- name: Tear down existing project
community.docker.docker_compose:
project_src: "{{ docker.project_path }}"
state: absent
remove_orphans: yes
when: docker_compose_file.changed
- name: Set up project
register: docker_project
community.docker.docker_compose:
project_src: "{{docker.project_path}}"
state: present
remove_orphans: yes
when: docker_compose_file.changed
- name: debug
ansible.builtin.debug:
var: docker_project
when: docker_compose_file.changed
# Restart frigate if needed
- name: Restart frigate
when: frigate_config_file.changed
community.docker.docker_container:
name: frigate
restart: true
state: started

View File

@@ -0,0 +1,256 @@
version: "3.1"
services:
unifi-controller:
image: lscr.io/linuxserver/unifi-controller:7.2.92
environment:
- PUID=1400
- MEM_LIMIT=1024
- MEM_STARTUP=1024
volumes:
- "{{docker.volumes_path}}/unifi_controller:/config"
ports:
- 8443:8443
- 3478:3478/udp
- 10001:10001/udp
- 8080:8080
- 1900:1900/udp
- 8843:8843
- 8880:8880
- 6789:6789
- 5514:5514/udp
restart: always
plex:
image: lscr.io/linuxserver/plex:latest
container_name: plex
environment:
- PUID=1400 # docker
- PGID=1202 # warez
- TZ=Etc/UTC
- VERSION=docker
volumes:
- "{{docker.plex.config_volume}}/plex:/config"
- "{{docker.plex.tv_volume}}:/tv"
- "{{docker.plex.movies_volume}}:/movies"
restart: unless-stopped
# This makes the instance claiming a lot easier since you can access the host on the same subnet.
network_mode: host
frigate:
container_name: frigate
privileged: true # this may not be necessary for all setups
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:0.14.1
shm_size: "150mb" # update for your cameras based on calculation in docs
devices:
#- /dev/bus/usb:/dev/bus/usb # passes the USB Coral, needs to be modified for other versions
# /dev/apex_0:/dev/apex_0 # passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
- /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware
volumes:
- /etc/localtime:/etc/localtime:ro
- "{{docker.frigate.config_volume}}/config.yml:/config/config.yml"
- "{{docker.frigate.media_volume}}:/media/frigate"
- type: tmpfs # Optional: 2GB of memory, reduces SSD/SD Card wear
target: /tmp/cache
tmpfs:
size: 2000000000
ports:
- "5000:5000"
- "8554:8554" # RTSP feeds
- "8555:8555/tcp" # WebRTC over tcp
- "8555:8555/udp" # WebRTC over udp
environment:
FRIGATE_RTSP_PASSWORD: "{{docker.frigate.rtsp_password}}"
influxdb:
image: influxdb:1.8-alpine
container_name: influxdb
restart: always
environment:
- INFLUXDB_DB=influx
- INFLUXDB_ADMIN_USER=admin
- "INFLUXDB_ADMIN_PASSWORD={{docker.influxdb.admin_password}}"
ports:
- "8086:8086"
volumes:
- "{{docker.influxdb.data_volume}}:/var/lib/influxdb"
grafana:
image: grafana/grafana
container_name: grafana
restart: always
depends_on:
- influxdb
environment:
- GF_SECURITY_ADMIN_USER=admin
- "GF_SECURITY_ADMIN_PASSWORD={{docker.grafana.admin_password}}"
- GF_INSTALL_PLUGINS=
links:
- influxdb
ports:
- "3000:3000"
volumes:
- "{{docker.grafana.data_volume}}:/var/lib/grafana"
user: "1400" # docker
photoprism:
container_name: photoprism
user: "1401:1201" # photoprism
image: photoprism/photoprism:latest
# restart: unless-stopped
stop_grace_period: 10s
depends_on:
- mariadb
security_opt:
- seccomp:unconfined
- apparmor:unconfined
ports:
- "2342:2342" # HTTP port (host:container)
environment:
PHOTOPRISM_ADMIN_USER: "wholteza" # admin login username
PHOTOPRISM_ADMIN_PASSWORD: "{{docker.photoprism.admin_password}}" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://bigboi.zacke.xyz:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "warning" # log level: trace, debug, info, warning, error, fatal, or panic
PHOTOPRISM_READONLY: "false" # do not modify originals directory (reduced functionality)
PHOTOPRISM_EXPERIMENTAL: "false" # enables experimental features
PHOTOPRISM_DISABLE_CHOWN: "false" # disables updating storage permissions via chmod and chown on startup
PHOTOPRISM_DISABLE_WEBDAV: "false" # disables built-in WebDAV server
PHOTOPRISM_DISABLE_SETTINGS: "false" # disables settings UI and API
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # disables all features depending on TensorFlow
PHOTOPRISM_DISABLE_FACES: "false" # disables face detection and recognition (requires TensorFlow)
PHOTOPRISM_DISABLE_CLASSIFICATION: "false" # disables image classification (requires TensorFlow)
PHOTOPRISM_DISABLE_VECTORS: "false" # disables vector graphics support
PHOTOPRISM_DISABLE_RAW: "false" # disables indexing and conversion of RAW images
PHOTOPRISM_RAW_PRESETS: "false" # enables applying user presets when converting RAW images (reduces performance)
PHOTOPRISM_JPEG_QUALITY: 85 # a higher value increases the quality and file size of JPEG images and thumbnails (25-100)
PHOTOPRISM_DETECT_NSFW: "false" # automatically flags photos as private that MAY be offensive (requires TensorFlow)
PHOTOPRISM_UPLOAD_NSFW: "true" # allows uploads that MAY be offensive (no effect without TensorFlow)
# PHOTOPRISM_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that doesn't require a server
PHOTOPRISM_DATABASE_DRIVER: "mysql" # use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB or MySQL database server (hostname:port)
PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB or MySQL database schema name
PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB or MySQL database user name
PHOTOPRISM_DATABASE_PASSWORD: "{{docker.mariadb.database_password}}" # MariaDB or MySQL database user password
PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
PHOTOPRISM_SITE_DESCRIPTION: "" # meta site description
PHOTOPRISM_SITE_AUTHOR: "" # meta site author
## Video Transcoding (https://docs.photoprism.app/getting-started/advanced/transcoding/):
# PHOTOPRISM_FFMPEG_ENCODER: "software" # H.264/AVC encoder (software, intel, nvidia, apple, raspberry, or vaapi)
# PHOTOPRISM_FFMPEG_SIZE: "1920" # video size limit in pixels (720-7680) (default: 3840)
# PHOTOPRISM_FFMPEG_BITRATE: "32" # video bitrate limit in Mbit/s (default: 50)
## Run/install on first startup (options: update https gpu tensorflow davfs clitools clean):
# PHOTOPRISM_INIT: "https gpu tensorflow"
## Run as a non-root user after initialization (supported: 0, 33, 50-99, 500-600, and 900-1200):
# PHOTOPRISM_UID: 1000
# PHOTOPRISM_GID: 1000
# PHOTOPRISM_UMASK: 0000
## Start as non-root user before initialization (supported: 0, 33, 50-99, 500-600, and 900-1200):
# user: "1000:1000"
## Share hardware devices with FFmpeg and TensorFlow (optional):
# devices:
# - "/dev/dri:/dev/dri" # Intel QSV
# - "/dev/nvidia0:/dev/nvidia0" # Nvidia CUDA
# - "/dev/nvidiactl:/dev/nvidiactl"
# - "/dev/nvidia-modeset:/dev/nvidia-modeset"
# - "/dev/nvidia-nvswitchctl:/dev/nvidia-nvswitchctl"
# - "/dev/nvidia-uvm:/dev/nvidia-uvm"
# - "/dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools"
# - "/dev/video11:/dev/video11" # Video4Linux Video Encode Device (h264_v4l2m2m)
working_dir: "/photoprism" # do not change or remove
## Storage Folders: "~" is a shortcut for your home directory, "." for the current directory
volumes:
# "/host/folder:/photoprism/folder" # Example
- "{{docker.photoprism.image_volumes.lilleback}}:/photoprism/originals" # Original media files (DO NOT REMOVE)
- "{{docker.photoprism.image_volumes.ellen}}:/photoprism/originals/ellen" # Original media files (DO NOT REMOVE)
# - "/example/family:/photoprism/originals/family" # *Additional* media folders can be mounted like this
# - "~/Import:/photoprism/import" # *Optional* base folder from which files can be imported to originals
- "{{docker.photoprism.data_volume}}:/photoprism/storage" # *Writable* storage folder for cache, database, and sidecar files (DO NOT REMOVE)
mariadb:
container_name: mariadb
user: "1401" # photoprism
image: mariadb:11
restart: unless-stopped
stop_grace_period: 5s
security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239
- seccomp:unconfined
- apparmor:unconfined
command: --innodb-buffer-pool-size=512M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
volumes:
- "{{docker.mariadb.data_volume}}:/var/lib/mysql"
environment:
MARIADB_AUTO_UPGRADE: "1"
MARIADB_INITDB_SKIP_TZINFO: "1"
MARIADB_DATABASE: "photoprism"
MARIADB_USER: "photoprism"
MARIADB_PASSWORD: "{{docker.mariadb.database_password}}"
MARIADB_ROOT_PASSWORD: "{{docker.mariadb.database_password}}"
vaultwarden:
image: vaultwarden/server:1.32.7
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vaultwarden.zacke.xyz"
EXPERIMENTAL_CLIENT_FEATURE_FLAGS: "autofill-v2,ssh-key-vault-item,ssh-agent"
volumes:
- "{{docker.vaultwarden.data_volume}}:/data"
ports:
- 8081:80
labels:
traefik.enable: true
# redirect scheme
traefik.http.middlewares.vaultwarden-redirect.redirectscheme.scheme: https
traefik.http.middlewares.vaultwarden-redirect.redirectscheme.permanent: true
# http
traefik.http.routers.vaultwarden-web.rule: Host(`vaultwarden.zacke.xyz`)
traefik.http.routers.vaultwarden-web.entrypoints: web
traefik.http.routers.vaultwarden-web.middlewares: vaultwarden-redirect
# https
traefik.http.routers.vaultwarden-websecure.rule: Host(`vaultwarden.zacke.xyz`)
traefik.http.routers.vaultwarden-websecure.entrypoints: websecure
traefik.http.routers.vaultwarden-websecure.tls.certresolver: myresolver
traefik.http.routers.vaultwarden-websecure.middlewares: vaultwarden-redirect
# services
traefik.http.services.vaultwarden-websecure.loadbalancer.server.port: 80
reverse-proxy:
container_name: "reverse-proxy"
image: traefik:v3.2
command:
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.myresolver.acme.dnschallenge=true
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=linodev4
#- --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
- --certificatesresolvers.myresolver.acme.email=hosting@montell.com
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
ports:
# The Web UI (enabled by --api.insecure=true)
- "8082:8080"
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- "{{docker.letsencrypt.data_volume}}:/letsencrypt"
environment:
LINODE_TOKEN: "{{docker.letsencrypt.linode_token}}"
labels:
traefik.enable: true
# redirect scheme
traefik.http.middlewares.traefik-redirect.redirectscheme.scheme: https
traefik.http.middlewares.traefik-redirect.redirectscheme.permanent: true
# http
traefik.http.routers.traefik-web.rule: Host(`traefik.zacke.xyz`)
traefik.http.routers.traefik-web.entrypoints: web
traefik.http.routers.traefik-web.middlewares: traefik-redirect
# https
traefik.http.routers.traefik-websecure.rule: Host(`traefik.zacke.xyz`)
traefik.http.routers.traefik-websecure.entrypoints: websecure
traefik.http.routers.traefik-websecure.tls.certresolver: myresolver
traefik.http.routers.traefik-websecure.middlewares: traefik-redirect
# services
traefik.http.services.traefik-websecure.loadbalancer.server.port: 8080

View File

@@ -0,0 +1,87 @@
mqtt:
enabled: False
detectors:
cpu1:
type: cpu
num_threads: 2
cameras:
house_camera:
objects:
filters:
car:
mask:
- 1065,47,998,316,658,266,694,0
# Optional: list of objects to track from labelmap.txt (default: shown below)
track:
- person
- bicycle
- car
- motorcycle
- bus
- car
- dog
- horse
- sheep
- cow
- knife
ffmpeg:
inputs:
- path: "{{docker.frigate.house_camera.rtsp_mrl}}/Streaming/Channels/101"
roles:
- record
- path: "{{docker.frigate.house_camera.rtsp_mrl}}/Streaming/Channels/102"
roles:
- detect
detect:
enabled: True # <---- disable detection until you have a working camera feed
width: 2560 # <---- update for your camera's resolution
height: 1440 # <---- update for your camera's resolution
snapshots:
enabled: true
record:
enabled: true
events:
retain:
default: 10
garage_camera: # <------ Name the camera
objects:
filters:
car:
mask:
- 1616,193,1602,331,1297,322,1309,199 # Stallet
- 393,472,783,402,769,202,359,234 # Car porten
# Optional: list of objects to track from labelmap.txt (default: shown below)
track:
- person
- bicycle
- car
- motorcycle
- bus
- car
- dog
- horse
- sheep
- cow
- knife
ffmpeg:
inputs:
- path: "{{docker.frigate.garage_camera.rtsp_mrl}}/Streaming/Channels/101" # <----- The stream you want to use for detection
roles:
- record
- path: "{{docker.frigate.garage_camera.rtsp_mrl}}/Streaming/Channels/102" # <----- The stream you want to use for detection
roles:
- detect
detect:
enabled: True # <---- disable detection until you have a working camera feed
width: 2560 # <---- update for your camera's resolution
height: 1440 # <---- update for your camera's resolution
snapshots:
enabled: true
record:
enabled: true
events:
retain:
default: 10
### IVMS4200 linux build

View File

@@ -0,0 +1,80 @@
- name: install requirements
apt:
name: xz-utils
state: present
- name: retrieve list of all vms
community.libvirt.virt:
command: list_vms
register: all_vms
- name: print list of vms
debug:
var: all_vms
- name: ensure homeassistant directory
file:
state: directory
path: "{{homeassistant.disk_image_path_root}}"
owner: libvirt-qemu
group: kvm
- name: check if the homeassistant disk image exists
stat:
path: "{{homeassistant.disk_image_path_decompressed}}"
register: homeassistant_disk_file
- name: create helper variables
set_fact:
hass_disk_image_does_not_exist: "{{homeassistant_disk_file.stat.exists is false}}"
- name: download homeassistant disk image
when: hass_disk_image_does_not_exist
shell: "curl {{homeassistant.disk_image_download_url}} -o {{homeassistant.disk_image_path_compressed}} -L"
args:
executable: "/bin/bash"
- name: decompress disk image
when: hass_disk_image_does_not_exist
shell: "xz --decompress {{homeassistant.disk_image_path_compressed}}"
args:
executable: "/bin/bash"
- name: set permissions on file
when: hass_disk_image_does_not_exist
file:
path: "{{homeassistant.disk_image_path_decompressed}}"
state: file
owner: libvirt-qemu
group: kvm
- name: create helper variables
set_fact:
hass_kvm_does_not_exist: "{{'hass' not in all_vms.list_vms}}"
- name: define vm
when: hass_kvm_does_not_exist
community.libvirt.virt:
command: define
xml: "{{ lookup('template', 'templates/hass-kvm.xml.j2') }}"
autostart: yes
- name: start vm
community.libvirt.virt:
name: hass
state: running
- name: List all VMs
community.libvirt.virt:
command: list_vms
register: all_vms
- name: print vms
debug:
var: all_vms
failed_when: "'hass' not in all_vms.list_vms"
- name: ensure compressed source image is removed
file:
path: "{{homeassistant.disk_image_path_compressed}}"
state: absent

View File

@@ -0,0 +1,109 @@
<domain type="kvm">
<name>hass</name>
<uuid>959513bb-d405-44a9-8090-c6d0bf6bbf1c</uuid>
<memory unit="KiB">2097152</memory>
<currentMemory unit="KiB">2097152</currentMemory>
<vcpu placement="static">2</vcpu>
<os>
<type arch="x86_64" machine="pc-i440fx-jammy">hvm</type>
<loader readonly="yes" type="pflash">/usr/share/OVMF/OVMF_CODE_4M.fd</loader>
<nvram>/var/lib/libvirt/qemu/nvram/vm1_VARS.fd</nvram>
<boot dev="hd"/>
</os>
<features>
<acpi/>
<apic/>
<vmport state="off"/>
</features>
<cpu mode="host-passthrough" check="none" migratable="on"/>
<clock offset="utc">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
<timer name="hpet" present="no"/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2"/>
<source file="{{homeassistant.disk_image_path_decompressed}}"/>
<target dev="hda" bus="ide"/>
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>
<controller type="usb" index="0" model="ich9-ehci1">
<address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x7"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci1">
<master startport="0"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0" multifunction="on"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci2">
<master startport="2"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x1"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci3">
<master startport="4"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x2"/>
</controller>
<controller type="pci" index="0" model="pci-root"/>
<controller type="ide" index="0">
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
</controller>
<controller type="virtio-serial" index="0">
<address type="pci" domain="0x0000" bus="0x00" slot="0x06" function="0x0"/>
</controller>
<interface type="bridge">
<source bridge="brlan"/>
<model type="virtio"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0"/>
</interface>
<serial type="pty">
<target type="isa-serial" port="0">
<model name="isa-serial"/>
</target>
</serial>
<console type="pty">
<target type="serial" port="0"/>
</console>
<channel type="spicevmc">
<target type="virtio" name="com.redhat.spice.0"/>
<address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
<channel type="unix">
<target type="virtio" name="org.qemu.guest_agent.0"/>
<address type="virtio-serial" controller="0" bus="0" port="2"/>
</channel>
<input type="tablet" bus="usb">
<address type="usb" bus="0" port="1"/>
</input>
<input type="mouse" bus="ps2"/>
<input type="keyboard" bus="ps2"/>
<graphics type="spice" autoport="yes">
<listen type="address"/>
<image compression="off"/>
</graphics>
<sound model="ich6">
<address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x0"/>
</sound>
<audio id="1" type="spice"/>
<video>
<model type="qxl" ram="65536" vram="65536" vgamem="16384" heads="1" primary="yes"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0"/>
</video>
<redirdev bus="usb" type="spicevmc">
<address type="usb" bus="0" port="2"/>
</redirdev>
<redirdev bus="usb" type="spicevmc">
<address type="usb" bus="0" port="3"/>
</redirdev>
<memballoon model="virtio">
<address type="pci" domain="0x0000" bus="0x00" slot="0x07" function="0x0"/>
</memballoon>
</devices>
</domain>

View File

@@ -0,0 +1,5 @@
<network>
<name>brlan</name>
<forward mode="bridge"/>
<bridge name="brlan"/>
</network>

View File

@@ -0,0 +1,44 @@
- name: install requirements (apt)
apt:
name:
- qemu-kvm
- libvirt-daemon-system
- python3-pip
- libvirt-clients
- libvirt-dev
- pkg-config
state: present
- name: install requirements (pip)
pip:
name:
- libvirt-python
- lxml
state: present
- name: remove network default
community.libvirt.virt_net:
name: default
state: absent
- name: remove network brlan
community.libvirt.virt_net:
name: brlan
state: absent
- name: define network brlan
community.libvirt.virt_net:
command: define
name: brlan
xml: '{{ lookup("file", "files/lan-bridge.xml") }}'
- name: ensure brlan is active
community.libvirt.virt_net:
name: brlan
state: active
autostart: yes
- name: ensure brlan autostarts
community.libvirt.virt_net:
name: brlan
autostart: yes

View File

@@ -0,0 +1,36 @@
- name: ensure ipv4 ip forwarding is enabled in the kernel
ansible.posix.sysctl:
name: "net.ipv4.ip_forward"
state: present
value: 1
sysctl_set: yes
- name: ensure iptables policy for FORWARD is ACCEPT
ansible.builtin.iptables:
chain: FORWARD
policy: ACCEPT
- name: copy netplan config
template:
src: 00-installer-config.yaml
dest: /etc/netplan/00-installer-config.yaml
owner: root
group: root
mode: 0644
register: netplan_config
- name: information for first run
debug:
msg: "If this is the first time network is being set up on this machine then ansible will loose connection to the machine after the next step. The network interface is going to switch from enp2s0 to the bridge brlan which means that it gets a new mac address. When this happens, edit the static lease in the router to point to the new mac address. You should then be able to re-run ansible to continue using the new interface. Alternatively just use hostnames to communicate to the server and flush your dns using resolvectl flush-caches."
- name: apply netplan
when: netplan_config.changed
shell: "sudo netplan apply"
args:
executable: /bin/bash
- name: reload network daemon
when: netplan_config.changed
systemd:
name: systemd-networkd
state: restarted

View File

@@ -0,0 +1,13 @@
network:
version: 2
renderer: networkd
ethernets:
enp2s0:
dhcp4: no
dhcp6: no
bridges:
brlan:
dhcp4: yes
dhcp6: no
interfaces:
- enp2s0

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,88 @@
html {
background-color: rgba(0, 0, 0, 0.95);
color: #ddd;
}
h1 {
color: #eee;
}
@media (min-width: 1200px){
body {
width: 800px;
}
}
@media (max-width: 1199px){
body {
width: 80%;
}
}
body {
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
.container{
margin: 0 auto;
width: 100%;
display: flex;
flex-direction: column;
}
.row{
display: flex;
flex-direction: row;
background-color: rgba(255, 255, 255, 0.1);
padding: 1em;
margin-bottom: 1em;
}
.icon {
max-width: 120px;
min-width: 120px;
max-height: 120px;
min-height: 120px;
}
.icon svg {
max-width: 120px;
min-width: 120px;
max-height: 120px;
min-height: 120px;
}
.icon {
width: 100%;
}
.icon img {
display: block;
position: relative;
width: 100%;
}
.info{
width: 90%;
display: flex;
flex-direction: column;
padding-left: 2em;
}
.info-title {
font-size: 2em;
font-weight: 800;
}
.info-value a{
color: rgba(255, 100, 0, 0.95);
font-size: 1.5em;
font-weight: 600;
text-decoration: none;
}
.info-value a::before{
content: "->";
margin-right: 0.5em;
}
.info-value a:visited {
text-decoration: none;
}

View File

@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html>
<head>
<title>Bigboi</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<h1>Welcome to Bigboi!</h1>
<p>This is the landing page for all web services hosted on this network.</p>
<p>Press any of the links below to go to the service</p>
<div class="container">
<div class="row">
<div class="icon"><img src="opnsense.png" /></div>
<div class="info">
<div class="info-title">OPNSense</div>
<div class="info-value"><a href="https://opnsense.zacke.xyz" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="https://192.168.2.1" target="_blank">LAN IP</a></div>
</div>
</div>
<div class="row">
<div class="icon"><img src="homeassistant.png" /></div>
<div class="info">
<div class="info-title">Homeassistant</div>
<div class="info-value"><a href="http://homeassistant.zacke.xyz:8123" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="https://opnsense.zacke.xyz" target="_blank">LAN IP</a></div>
</div>
</div>
<div class="row">
<div class="icon"><svg viewBox="0 0 512 512" class="fill-current">
<path
d="M130 446.5C131.6 459.3 145 468 137 470C129 472 94 406.5 86 378.5C78 350.5 73.5 319 75.5 301C77.4999 283 181 255 181 247.5C181 240 147.5 247 146 241C144.5 235 171.3 238.6 178.5 229C189.75 214 204 216.5 213 208.5C222 200.5 233 170 235 157C237 144 215 129 209 119C203 109 222 102 268 83C314 64 460 22 462 27C464 32 414 53 379 66C344 79 287 104 287 111C287 118 290 123.5 288 139.5C286 155.5 285.76 162.971 282 173.5C279.5 180.5 277 197 282 212C286 224 299 233 305 235C310 235.333 323.8 235.8 339 235C358 234 385 236 385 241C385 246 344 243 344 250C344 257 386 249 385 256C384 263 350 260 332 260C317.6 260 296.333 259.333 287 256L285 263C281.667 263 274.7 265 267.5 265C258.5 265 258 268 241.5 268C225 268 230 267 215 266C200 265 144 308 134 322C124 336 130 370 130 385.5C130 399.428 128 430.5 130 446.5Z">
</path>
</svg></div>
<div class="info">
<div class="info-title">Frigate NVR</div>
<div class="info-value"><a href="http://bigboi.zacke.xyz:5000" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="http://192.168.2.5:5000" target="_blank">LAN IP</a></div>
<div class="info-value"><a href="http://bigboi.ocelot-pirate.ts.net:5000" target="_blank">Tailscale DNS</a>
</div>
</div>
</div>
<div class="row">
<div class="icon"><img src="unifi.png" /></div>
<div class="info">
<div class="info-title">Unifi</div>
<div class="info-value"><a href="http://bigboi.zacke.xyz:8080" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="http://192.168.2.5:8080" target="_blank">LAN IP</a></div>
<div class="info-value"><a href="http://bigboi.ocelot-pirate.ts.net:8080" target="_blank">Tailscale DNS</a>
</div>
</div>
</div>
<div class="row">
<div class="icon"><img src="plex.png" /></div>
<div class="info">
<div class="info-title">Plex</div>
<div class="info-value"><a href="http://bigboi.zacke.xyz:32400" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="http://192.168.2.5:32400" target="_blank">LAN IP</a></div>
<div class="info-value"><a href="http://bigboi.ocelot-pirate.ts.net:32400" target="_blank">Tailscale DNS</a>
</div>
</div>
</div>
<div class="row">
<div class="icon"><img src="photoprism.svg" /></div>
<div class="info">
<div class="info-title">Photoprism</div>
<div class="info-value"><a href="http://bigboi.zacke.xyz:2342" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="http://192.168.2.5:2342" target="_blank">LAN IP</a></div>
<div class="info-value"><a href="http://bigboi.ocelot-pirate.ts.net:2342" target="_blank">Tailscale DNS</a>
</div>
</div>
</div>
<div class="row">
<div class="icon"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="351px" height="365px" viewBox="0 0 351 365"
style="enable-background:new 0 0 351 365;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: url(#SVGID_1_);
}
</style>
<g id="Layer_1_1_">
</g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="175.5" y1="30%" x2="175.5" y2="99%">
<stop offset="0" style="stop-color:#F05A28" />
<stop offset="1" style="stop-color:#FBCA0A" />
</linearGradient>
<path class="st0" d="M342,161.2c-0.6-6.1-1.6-13.1-3.6-20.9c-2-7.7-5-16.2-9.4-25c-4.4-8.8-10.1-17.9-17.5-26.8
c-2.9-3.5-6.1-6.9-9.5-10.2c5.1-20.3-6.2-37.9-6.2-37.9c-19.5-1.2-31.9,6.1-36.5,9.4c-0.8-0.3-1.5-0.7-2.3-1
c-3.3-1.3-6.7-2.6-10.3-3.7c-3.5-1.1-7.1-2.1-10.8-3c-3.7-0.9-7.4-1.6-11.2-2.2c-0.7-0.1-1.3-0.2-2-0.3
c-8.5-27.2-32.9-38.6-32.9-38.6c-27.3,17.3-32.4,41.5-32.4,41.5s-0.1,0.5-0.3,1.4c-1.5,0.4-3,0.9-4.5,1.3c-2.1,0.6-4.2,1.4-6.2,2.2
c-2.1,0.8-4.1,1.6-6.2,2.5c-4.1,1.8-8.2,3.8-12.2,6c-3.9,2.2-7.7,4.6-11.4,7.1c-0.5-0.2-1-0.4-1-0.4c-37.8-14.4-71.3,2.9-71.3,2.9
c-3.1,40.2,15.1,65.5,18.7,70.1c-0.9,2.5-1.7,5-2.5,7.5c-2.8,9.1-4.9,18.4-6.2,28.1c-0.2,1.4-0.4,2.8-0.5,4.2
C18.8,192.7,8.5,228,8.5,228c29.1,33.5,63.1,35.6,63.1,35.6c0,0,0.1-0.1,0.1-0.1c4.3,7.7,9.3,15,14.9,21.9c2.4,2.9,4.8,5.6,7.4,8.3
c-10.6,30.4,1.5,55.6,1.5,55.6c32.4,1.2,53.7-14.2,58.2-17.7c3.2,1.1,6.5,2.1,9.8,2.9c10,2.6,20.2,4.1,30.4,4.5
c2.5,0.1,5.1,0.2,7.6,0.1l1.2,0l0.8,0l1.6,0l1.6-0.1l0,0.1c15.3,21.8,42.1,24.9,42.1,24.9c19.1-20.1,20.2-40.1,20.2-44.4l0,0
c0,0,0-0.1,0-0.3c0-0.4,0-0.6,0-0.6l0,0c0-0.3,0-0.6,0-0.9c4-2.8,7.8-5.8,11.4-9.1c7.6-6.9,14.3-14.8,19.9-23.3
c0.5-0.8,1-1.6,1.5-2.4c21.6,1.2,36.9-13.4,36.9-13.4c-3.6-22.5-16.4-33.5-19.1-35.6l0,0c0,0-0.1-0.1-0.3-0.2
c-0.2-0.1-0.2-0.2-0.2-0.2c0,0,0,0,0,0c-0.1-0.1-0.3-0.2-0.5-0.3c0.1-1.4,0.2-2.7,0.3-4.1c0.2-2.4,0.2-4.9,0.2-7.3l0-1.8l0-0.9
l0-0.5c0-0.6,0-0.4,0-0.6l-0.1-1.5l-0.1-2c0-0.7-0.1-1.3-0.2-1.9c-0.1-0.6-0.1-1.3-0.2-1.9l-0.2-1.9l-0.3-1.9
c-0.4-2.5-0.8-4.9-1.4-7.4c-2.3-9.7-6.1-18.9-11-27.2c-5-8.3-11.2-15.6-18.3-21.8c-7-6.2-14.9-11.2-23.1-14.9
c-8.3-3.7-16.9-6.1-25.5-7.2c-4.3-0.6-8.6-0.8-12.9-0.7l-1.6,0l-0.4,0c-0.1,0-0.6,0-0.5,0l-0.7,0l-1.6,0.1c-0.6,0-1.2,0.1-1.7,0.1
c-2.2,0.2-4.4,0.5-6.5,0.9c-8.6,1.6-16.7,4.7-23.8,9c-7.1,4.3-13.3,9.6-18.3,15.6c-5,6-8.9,12.7-11.6,19.6c-2.7,6.9-4.2,14.1-4.6,21
c-0.1,1.7-0.1,3.5-0.1,5.2c0,0.4,0,0.9,0,1.3l0.1,1.4c0.1,0.8,0.1,1.7,0.2,2.5c0.3,3.5,1,6.9,1.9,10.1c1.9,6.5,4.9,12.4,8.6,17.4
c3.7,5,8.2,9.1,12.9,12.4c4.7,3.2,9.8,5.5,14.8,7c5,1.5,10,2.1,14.7,2.1c0.6,0,1.2,0,1.7,0c0.3,0,0.6,0,0.9,0c0.3,0,0.6,0,0.9-0.1
c0.5,0,1-0.1,1.5-0.1c0.1,0,0.3,0,0.4-0.1l0.5-0.1c0.3,0,0.6-0.1,0.9-0.1c0.6-0.1,1.1-0.2,1.7-0.3c0.6-0.1,1.1-0.2,1.6-0.4
c1.1-0.2,2.1-0.6,3.1-0.9c2-0.7,4-1.5,5.7-2.4c1.8-0.9,3.4-2,5-3c0.4-0.3,0.9-0.6,1.3-1c1.6-1.3,1.9-3.7,0.6-5.3
c-1.1-1.4-3.1-1.8-4.7-0.9c-0.4,0.2-0.8,0.4-1.2,0.6c-1.4,0.7-2.8,1.3-4.3,1.8c-1.5,0.5-3.1,0.9-4.7,1.2c-0.8,0.1-1.6,0.2-2.5,0.3
c-0.4,0-0.8,0.1-1.3,0.1c-0.4,0-0.9,0-1.2,0c-0.4,0-0.8,0-1.2,0c-0.5,0-1,0-1.5-0.1c0,0-0.3,0-0.1,0l-0.2,0l-0.3,0
c-0.2,0-0.5,0-0.7-0.1c-0.5-0.1-0.9-0.1-1.4-0.2c-3.7-0.5-7.4-1.6-10.9-3.2c-3.6-1.6-7-3.8-10.1-6.6c-3.1-2.8-5.8-6.1-7.9-9.9
c-2.1-3.8-3.6-8-4.3-12.4c-0.3-2.2-0.5-4.5-0.4-6.7c0-0.6,0.1-1.2,0.1-1.8c0,0.2,0-0.1,0-0.1l0-0.2l0-0.5c0-0.3,0.1-0.6,0.1-0.9
c0.1-1.2,0.3-2.4,0.5-3.6c1.7-9.6,6.5-19,13.9-26.1c1.9-1.8,3.9-3.4,6-4.9c2.1-1.5,4.4-2.8,6.8-3.9c2.4-1.1,4.8-2,7.4-2.7
c2.5-0.7,5.1-1.1,7.8-1.4c1.3-0.1,2.6-0.2,4-0.2c0.4,0,0.6,0,0.9,0l1.1,0l0.7,0c0.3,0,0,0,0.1,0l0.3,0l1.1,0.1
c2.9,0.2,5.7,0.6,8.5,1.3c5.6,1.2,11.1,3.3,16.2,6.1c10.2,5.7,18.9,14.5,24.2,25.1c2.7,5.3,4.6,11,5.5,16.9c0.2,1.5,0.4,3,0.5,4.5
l0.1,1.1l0.1,1.1c0,0.4,0,0.8,0,1.1c0,0.4,0,0.8,0,1.1l0,1l0,1.1c0,0.7-0.1,1.9-0.1,2.6c-0.1,1.6-0.3,3.3-0.5,4.9
c-0.2,1.6-0.5,3.2-0.8,4.8c-0.3,1.6-0.7,3.2-1.1,4.7c-0.8,3.1-1.8,6.2-3,9.3c-2.4,6-5.6,11.8-9.4,17.1
c-7.7,10.6-18.2,19.2-30.2,24.7c-6,2.7-12.3,4.7-18.8,5.7c-3.2,0.6-6.5,0.9-9.8,1l-0.6,0l-0.5,0l-1.1,0l-1.6,0l-0.8,0
c0.4,0-0.1,0-0.1,0l-0.3,0c-1.8,0-3.5-0.1-5.3-0.3c-7-0.5-13.9-1.8-20.7-3.7c-6.7-1.9-13.2-4.6-19.4-7.8
c-12.3-6.6-23.4-15.6-32-26.5c-4.3-5.4-8.1-11.3-11.2-17.4c-3.1-6.1-5.6-12.6-7.4-19.1c-1.8-6.6-2.9-13.3-3.4-20.1l-0.1-1.3l0-0.3
l0-0.3l0-0.6l0-1.1l0-0.3l0-0.4l0-0.8l0-1.6l0-0.3c0,0,0,0.1,0-0.1l0-0.6c0-0.8,0-1.7,0-2.5c0.1-3.3,0.4-6.8,0.8-10.2
c0.4-3.4,1-6.9,1.7-10.3c0.7-3.4,1.5-6.8,2.5-10.2c1.9-6.7,4.3-13.2,7.1-19.3c5.7-12.2,13.1-23.1,22-31.8c2.2-2.2,4.5-4.2,6.9-6.2
c2.4-1.9,4.9-3.7,7.5-5.4c2.5-1.7,5.2-3.2,7.9-4.6c1.3-0.7,2.7-1.4,4.1-2c0.7-0.3,1.4-0.6,2.1-0.9c0.7-0.3,1.4-0.6,2.1-0.9
c2.8-1.2,5.7-2.2,8.7-3.1c0.7-0.2,1.5-0.4,2.2-0.7c0.7-0.2,1.5-0.4,2.2-0.6c1.5-0.4,3-0.8,4.5-1.1c0.7-0.2,1.5-0.3,2.3-0.5
c0.8-0.2,1.5-0.3,2.3-0.5c0.8-0.1,1.5-0.3,2.3-0.4l1.1-0.2l1.2-0.2c0.8-0.1,1.5-0.2,2.3-0.3c0.9-0.1,1.7-0.2,2.6-0.3
c0.7-0.1,1.9-0.2,2.6-0.3c0.5-0.1,1.1-0.1,1.6-0.2l1.1-0.1l0.5-0.1l0.6,0c0.9-0.1,1.7-0.1,2.6-0.2l1.3-0.1c0,0,0.5,0,0.1,0l0.3,0
l0.6,0c0.7,0,1.5-0.1,2.2-0.1c2.9-0.1,5.9-0.1,8.8,0c5.8,0.2,11.5,0.9,17,1.9c11.1,2.1,21.5,5.6,31,10.3
c9.5,4.6,17.9,10.3,25.3,16.5c0.5,0.4,0.9,0.8,1.4,1.2c0.4,0.4,0.9,0.8,1.3,1.2c0.9,0.8,1.7,1.6,2.6,2.4c0.9,0.8,1.7,1.6,2.5,2.4
c0.8,0.8,1.6,1.6,2.4,2.5c3.1,3.3,6,6.6,8.6,10c5.2,6.7,9.4,13.5,12.7,19.9c0.2,0.4,0.4,0.8,0.6,1.2c0.2,0.4,0.4,0.8,0.6,1.2
c0.4,0.8,0.8,1.6,1.1,2.4c0.4,0.8,0.7,1.5,1.1,2.3c0.3,0.8,0.7,1.5,1,2.3c1.2,3,2.4,5.9,3.3,8.6c1.5,4.4,2.6,8.3,3.5,11.7
c0.3,1.4,1.6,2.3,3,2.1c1.5-0.1,2.6-1.3,2.6-2.8C342.6,170.4,342.5,166.1,342,161.2z" />
</svg></div>
<div class="info">
<div class="info-title">Grafana</div>
<div class="info-value"><a href="http://bigboi.zacke.xyz:3000" target="_blank">LAN DNS
</a></div>
<div class="info-value"><a href="http://192.168.2.5:3000" target="_blank">LAN IP</a></div>
<div class="info-value"><a href="http://bigboi.ocelot-pirate.ts.net:3000" target="_blank">Tailscale DNS</a>
</div>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1 @@
<svg data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 266 266"><defs><linearGradient id="a" x1="45.04" y1="231.72" x2="231.72" y2="45.04" gradientUnits="userSpaceOnUse" gradientTransform="translate(-5.38 -5.38)"><stop offset="0" stop-color="#fff"/><stop offset="0" stop-color="#b8edff"/><stop offset="1" stop-color="#d4b8ff"/></linearGradient></defs><circle cx="133" cy="133" r="132" style="fill:url(#a)"/><path data-name="Logo Pfad" d="m224.19 176.51-4 24.19M41.91 177.5l14.81 14m95.76-137.65L56.62 191.31a.09.09 0 0 0 .07.15l163.41 9.37a.09.09 0 0 0 .09-.13L152.62 53.87a.1.1 0 0 0-.14-.02zm-19.74-13.29L41.8 177.31a.13.13 0 0 0 .11.19l182.18-.8a.12.12 0 0 0 .1-.19L132.95 40.56a.12.12 0 0 0-.21 0zm.11-.16 19.77 13.32" style="fill:none;stroke:#1d1d1b;stroke-miterlimit:10;stroke-width:6px"/></svg>

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -0,0 +1,47 @@
---
# Nginx setup
- name: Install nginx
apt:
name: nginx
register: install_nginx
# Copy static website files
- name: Remove default nginx html
file:
path: /var/www/html/index.nginx-debian.html
state: absent
- name: ensure bigboi landing page static website files
ansible.posix.synchronize:
src: html
dest: /var/www
register: html_bigboi
- name: Remove default nginx site
file:
path: /etc/nginx/sites-enabled/default
state: absent
when: install_nginx.changed
- name: Copy default bigboi landing page site file
template:
src: bigboi.zacke.xyz.nginx
dest: /etc/nginx/sites-enabled/default
owner: root
group: root
register: site_bigboi
# - name: Set up certbot and request certificates
- name: Restart nginx
systemd:
name: nginx
enabled: yes
state: restarted
when: site_bigboi.changed or html_bigboi.changed
- name: Stop nginx
systemd:
name: nginx
enabled: yes
state: started

View File

@@ -0,0 +1,8 @@
server {
listen 80 default_server;
location / {
add_header Content-Type text/html;
return 200 "<html><body><h1>bepis</h1></body></html>";
}
}

View File

@@ -0,0 +1,91 @@
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 8083 default_server;
listen [::]:8083 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}

View File

@@ -0,0 +1,33 @@
server {
server_name ellenshorselife.se;
proxy_redirect off;
client_max_body_size 10G;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://192.168.2.22;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/ellenshorselife.se/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ellenshorselife.se/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = ellenshorselife.se) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name ellenshorselife.se;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,19 @@
server {
listen 80;
server_name plex.zacke.xyz;
return 301 https://plex.zacke.xyz$request_uri;
}
server {
listen 443 ssl;
server_name plex.zacke.xyz;
ssl_certificate /etc/letsencrypt/live/zacke.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zacke.xyz/privkey.pem;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://192.168.2.22:32400;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View File

@@ -0,0 +1,25 @@
server {
listen 80;
server_name proxmox.zacke.xyz;
return 301 https://proxmox.zacke.xyz$request_uri;
}
server {
listen 443 ssl;
server_name proxmox.zacke.xyz;
ssl_certificate /etc/letsencrypt/live/zacke.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zacke.xyz/privkey.pem;
proxy_redirect off;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass https://192.168.2.4:8006;
proxy_buffering off;
client_max_body_size 0;
proxy_connect_timeout 3600s;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
send_timeout 3600s;
}
}

View File

@@ -0,0 +1,4 @@
---
packages:
- name: samba

View File

@@ -0,0 +1,35 @@
---
- name: Install packages
apt:
name: "{{ item.name }}"
loop: "{{ packages }}"
- name: Copy samba config
template:
src: smb.conf
dest: /etc/samba/smb.conf
register: smb_conf
- name: Restart samba daemon
systemd:
name: smbd
state: restarted
enabled: yes
when: smb_conf.changed
- name: Create Samba users if they don't exist yet
shell: >
set -o nounset -o pipefail -o errexit &&
(pdbedit --user={{ item.name }} 2>&1 > /dev/null) \
|| (echo {{ item.samba_password }}; echo {{ item.samba_password }}) \
| smbpasswd -s -a {{ item.name }}
args:
executable: /bin/bash
loop: "{{ nas_users|rejectattr('samba_password', 'undefined') }}"
loop_control:
label: "{{ item.name }}"
no_log: true
register: create_user_output
changed_when: "'Added user' in create_user_output.stdout"
tags: samba

View File

@@ -0,0 +1,57 @@
[global]
workgroup = lilleback
server string = lilleback-prod
security = user
guest ok = yes
map to guest = Bad Password
log file = /var/log/samba/%m.log
max log size = 50
printcap name = /dev/null
load printers = no
{% for item in nas_groups|rejectattr('filesystems','undefined')|map(attribute='filesystems')|flatten(levels=1)|rejectattr('samba', 'undefined') %}
[{{ item.samba_name }}]
comment = {{ item.samba_name }}
path = {{ item.mount_point }}
browseable = yes
read only = no
guest ok = no
valid users = @{{ item.group }}
create mask = 774
directory mask = 774
force user = {{ item.user }}
force group = {{ item.group }}
{% endfor %}
{% for item in nas_users|rejectattr('filesystems','undefined')|map(attribute='filesystems')|flatten(levels=1)|rejectattr('samba', 'undefined') %}
[{{ item.samba_name }}]
comment = {{ item.samba_name }}
path = {{ item.mount_point }}
valid users = {{ item.user }}
browseable = yes
read only = no
guest ok = no
create mask = 700
directory mask = 700
force user = {{ item.user }}
force group = {{ item.group }}
{% endfor %}
{% for item in nas_service_users|rejectattr('filesystems','undefined')|map(attribute='filesystems')|flatten(levels=1)|rejectattr('samba', 'undefined') %}
[{{ item.samba_name }}]
comment = {{ item.samba_name }}
path = {{ item.mount_point }}
valid users = {{ item.user }} @{{ item.group }}
browseable = yes
read only = no
guest ok = no
create mask = 770
directory mask = 770
force user = {{ item.user }}
force group = {{ item.group }}
{% endfor %}

View File

@@ -0,0 +1,4 @@
---
packages:
- name: sanoid

View File

@@ -0,0 +1,16 @@
---
- name: Install packages
apt:
name: "{{ item.name }}"
loop: "{{ packages }}"
- name: Create sanoid directory
file:
path: /etc/sanoid
state: directory
- name: Copy sanoid config
template:
src: sanoid.conf
dest: /etc/sanoid/sanoid.conf

View File

@@ -0,0 +1,37 @@
{% for filesystem in nas_groups|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) %}
[{{ filesystem.name }}]
use_template = production
recursive = no
{% endfor %}
{% for filesystem in nas_users|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) %}
[{{ filesystem.name }}]
use_template = production
recursive = no
{% endfor %}
{% for filesystem in nas_service_users|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) %}
[{{ filesystem.name }}]
use_template = production
recursive = no
{% endfor %}
{% for filesystem in local_service_users|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) %}
[{{ filesystem.name }}]
use_template = production
recursive = no
{% endfor %}
#############################
# templates below this line #
#############################
[template_production]
frequently = 0
hourly = 36
daily = 14
monthly = 1
yearly = 0
autosnap = yes
autoprune = yes

View File

@@ -0,0 +1,29 @@
- name: Add groups
group:
name: "{{ item.name }}"
gid: "{{ item.gid }}"
state: present
loop: "{{ nas_groups|flatten(levels=1) }}"
loop_control:
label: "{{ item.name }}"
- name: Add users
user:
name: "{{ item.name }}"
password: "{{ item.password|default('!') }}"
state: present
shell: "{{ item.shell|default('/bin/noshell') }}"
uid: "{{ item.uid }}"
groups: "{{ item.groups|default('') }}"
create_home: "{{ item.create_home|default('no') }}"
loop: "{{ nas_users|community.general.lists_mergeby(nas_service_users, 'name')|community.general.lists_mergeby(local_service_users, 'name') }}"
loop_control:
label: "{{ item.name }}"
- name: Add public ssh keys
authorized_key:
user: "{{ item.name }}"
key: "{{ item.public_ssh_key }}"
loop: "{{ nas_users|community.general.lists_mergeby(nas_service_users, 'name')|flatten(levels=1)|rejectattr('public_ssh_key', 'undefined') }}"
loop_control:
label: "{{ item.name }}"

View File

@@ -0,0 +1,4 @@
---
packages:
- zfsutils-linux

View File

@@ -0,0 +1,123 @@
---
- name: Install packages
apt:
name: "{{ item }}"
loop: "{{ packages }}"
# Tank
- name: Check that zfs root filesystem exists and is mounted in the right place
zfs_facts:
name: "{{ zfs_root_filesystem.name }}"
properties: mountpoint
register: zpool
failed_when: "zpool.ansible_facts.ansible_zfs_datasets[0].mountpoint != zfs_root_filesystem.mount_point"
- name: Set properties on root zfs filesystem
zfs:
name: "{{ zfs_root_filesystem.name }}"
extra_zfs_properties:
compression: on
dedup: off
state: present
- name: Create group zfs filesystems
zfs:
name: "{{ item.name }}"
extra_zfs_properties:
compression: on
dedup: off
state: present
loop: "{{ nas_groups|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) }}"
- name: Set permissions on group zfs filesystems
file:
owner: "{{ item.user }}"
group: "{{ item.group }}"
mode: "{{ item.permission_mode }}"
path: "{{ item.mount_point }}"
state: directory
recurse: yes
loop: "{{ nas_groups|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) }}"
- name: Create user zfs filesystems
zfs:
name: "{{ item.name }}"
extra_zfs_properties:
compression: on
dedup: off
state: present
loop: "{{ nas_users|community.general.lists_mergeby(nas_service_users, 'name')|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) }}"
- name: Set permissions on user zfs filesystems
file:
owner: "{{ item.user }}"
group: "{{ item.group }}"
mode: "{{ item.permission_mode }}"
path: "{{ item.mount_point }}"
state: directory
recurse: yes
loop: "{{ nas_users|community.general.lists_mergeby(nas_service_users, 'name')|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) }}"
- name: Enable weekly zpool scrub
systemd:
name: "zfs-scrub-weekly@{{ zfs_root_filesystem.name }}.timer"
enabled: yes
state: started
# Services
- name: Check that zfs services filesystem exists and is mounted in the right place
zfs_facts:
name: "{{ zfs_services_pool.name }}"
properties: mountpoint
register: zpool
failed_when: "zpool.ansible_facts.ansible_zfs_datasets[0].mountpoint != zfs_services_pool.mount_point"
- name: Set properties on services zfs filesystem
zfs:
name: "{{ zfs_services_pool.name }}"
extra_zfs_properties:
compression: on
dedup: off
state: present
- name: Create user zfs filesystems
zfs:
name: "{{ item.name }}"
extra_zfs_properties:
compression: on
dedup: off
state: present
loop: "{{ local_service_users|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) }}"
- name: Set permissions on user zfs filesystems
file:
owner: "{{ item.user }}"
group: "{{ item.group }}"
mode: "{{ item.permission_mode }}"
path: "{{ item.mount_point }}"
state: directory
recurse: yes
loop: "{{ local_service_users|rejectattr('filesystems', 'undefined')|map(attribute='filesystems')|flatten(levels=1) }}"
- name: Enable weekly zpool scrub
systemd:
name: "zfs-scrub-monthly@{{ zfs_services_pool.name }}.timer"
enabled: yes
state: started
# permissions
- name: Grant `zfs send,receive` to users `syncoid` on tank
community.general.zfs_delegate_admin:
name: tank
descendents: true
local: true
users: syncoid
permissions: send,hold,bookmark
- name: Grant `zfs send,receive` to users `syncoid` on services
community.general.zfs_delegate_admin:
name: services
descendents: true
local: true
users: syncoid
permissions: send,hold,bookmark

View File

@@ -1,21 +0,0 @@
---
- name: Check that zfs pool "moon" exists and is mounted in the right place
zfs_facts:
name: moon
register: zpool
# This is probably not the correct way to do this
failed_when: zpool.ansible_zfs_pools.mountpoint != "/moon"
- name: Check if zfs filesystems exist
- name: Create zfs filesystems if they don't exist
- name: Create users for shares
- name: Give users read and write permissions recursivly in their own zfs filesystems
- name: Install packages necessary for creating samba shares
- name: Set up samba shares

View File

@@ -0,0 +1,9 @@
- name: install requirements
apt:
name: avahi-daemon
- name: enable avahi daemon
systemd:
name: avahi-daemon
enabled: yes
state: started

View File

@@ -0,0 +1 @@
ansible ALL=(ALL) NOPASSWD:ALL

View File

@@ -0,0 +1 @@
wholteza ALL=(ALL) NOPASSWD:ALL

View File

@@ -0,0 +1,31 @@
---
- name: Create ansible user
user:
name: "{{ bootstrap.user.name }}"
password: "{{ bootstrap.user.password }}"
shell: /bin/bash
groups: sudo
create_home: yes
state: present
- name: Add public ssh key
authorized_key:
user: "{{ bootstrap.user.name }}"
key: "{{ bootstrap.user.public_ssh_key }}"
- name: Enable ansible user to run sudo without password
copy:
src: ansible.sudoers
dest: /etc/sudoers.d/ansible
owner: root
group: root
mode: 0440
# TODO: remove?
- name: Enable myself to run sudo without password
copy:
src: wholteza.sudoers
dest: /etc/sudoers.d/wholteza
owner: root
group: root
mode: 0440

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Powertop tunings
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/powertop --auto-tune
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,19 @@
---
- name: Install powertop
apt:
name: powertop
- name: Copy systemd service
copy:
src: powertop.service
dest: /etc/systemd/system/powertop.service
owner: root
group: root
mode: 0777
- name: Enable powertop service
systemd:
name: powertop
state: started
enabled: yes

View File

@@ -0,0 +1,6 @@
---
- name: Install smartmontools
apt:
name: smartmontools
state: present

View File

@@ -0,0 +1,3 @@
packages:
- ssmtp
- mailutils

View File

@@ -0,0 +1,34 @@
---
- name: install mail packages
apt:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
tags: email
- name: Setup ssmtp server config
template:
src: ssmtp.conf
dest: /etc/ssmtp/ssmtp.conf
owner: root
group: mail
mode: 0770
tags: email
- name: Setup 'send as' aliases
template:
src: revaliases
dest: /etc/ssmtp/revaliases
owner: root
group: mail
mode: 0770
tags: email
- name: Send test email
shell: "echo 'Testing ssmtp service as part of ansible playbook' | mail -s 'Email notifications are working' {{ ssmtp.test_email }}"
args:
executable: /bin/bash
tags: email
changed_when: false

View File

@@ -0,0 +1,9 @@
# sSMTP aliases
#
# Format: local_account:outgoing_address:mailhub
#
# Example: root:your_login@your.domain:mailhub.your.domain[:port]
# where [:port] is an optional port number that defaults to 25.
root:{{ ssmtp.send_as }}:{{ ssmtp.mailhub }}
wholteza:{{ ssmtp.send_as }}:{{ ssmtp.mailhub }}
syncoid:{{ ssmtp.send_as }}:{{ ssmtp.mailhub }}

View File

@@ -0,0 +1,15 @@
#
# Config file for sSMTP sendmail
#
root=postmaster
AuthUser={{ ssmtp.auth_user }}
AuthPass={{ ssmtp.auth_pass }}
mailhub={{ ssmtp.mailhub }}
UseTLS=YES
UseSTARTTLS=YES
AuthMethod=plain
FromLineOverride=YES
rewriteDomain={{ ssmtp.rewrite_domain }}
hostname={{ ssmtp.hostname }}

View File

@@ -5,4 +5,4 @@
autoclean: true
autoremove: true
update_cache: true
update: dist
upgrade: dist

View File

@@ -0,0 +1,7 @@
---
- name: "install various cli tools"
apt:
name:
- bashtop
- htop
state: present

View File

@@ -0,0 +1,5 @@
---
- name: Install zfs
apt:
name: zfsutils-linux
state: present

View File

@@ -0,0 +1,20 @@
---
- name: Install packages
apt:
name: zfs-zed
state: present
- name: Enable zpool monitoring
template:
src: zed.rc
dest: /etc/zfs/zed.d/zed.rc
owner: root
mode: 0600
register: zed_conf
- name: Restart zfs-zed daemon
systemd:
name: zfs-zed
state: restarted
enabled: yes
when: zed_conf.changed

View File

@@ -0,0 +1,143 @@
##
# zed.rc
#
# This file should be owned by root and permissioned 0600.
##
##
# Absolute path to the debug output file.
#
#ZED_DEBUG_LOG="/tmp/zed.debug.log"
##
# Email address of the zpool administrator for receipt of notifications;
# multiple addresses can be specified if they are delimited by whitespace.
# Email will only be sent if ZED_EMAIL_ADDR is defined.
# Enabled by default; comment to disable.
#
ZED_EMAIL_ADDR="{{ zfs_zed.email }}"
##
# Name or path of executable responsible for sending notifications via email;
# the mail program must be capable of reading a message body from stdin.
# Email will only be sent if ZED_EMAIL_ADDR is defined.
#
ZED_EMAIL_PROG="mail"
##
# Command-line options for ZED_EMAIL_PROG.
# The string @ADDRESS@ will be replaced with the recipient email address(es).
# The string @SUBJECT@ will be replaced with the notification subject;
# this should be protected with quotes to prevent word-splitting.
# Email will only be sent if ZED_EMAIL_ADDR is defined.
#
ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
##
# Default directory for zed lock files.
#
ZED_LOCKDIR="/var/lock"
##
# Minimum number of seconds between notifications for a similar event.
#
ZED_NOTIFY_INTERVAL_SECS={{ zfs_zed.min_notify_interval_secs }}
##
# Notification verbosity.
# If set to 0, suppress notification if the pool is healthy.
# If set to 1, send notification regardless of pool health.
#
ZED_NOTIFY_VERBOSE=1
##
# Send notifications for 'ereport.fs.zfs.data' events.
# Disabled by default, any non-empty value will enable the feature.
#
#ZED_NOTIFY_DATA=
##
# Pushbullet access token.
# This grants full access to your account -- protect it accordingly!
# <https://www.pushbullet.com/get-started>
# <https://www.pushbullet.com/account>
# Disabled by default; uncomment to enable.
#
#ZED_PUSHBULLET_ACCESS_TOKEN=""
##
# Pushbullet channel tag for push notification feeds that can be subscribed to.
# <https://www.pushbullet.com/my-channel>
# If not defined, push notifications will instead be sent to all devices
# associated with the account specified by the access token.
# Disabled by default; uncomment to enable.
#
#ZED_PUSHBULLET_CHANNEL_TAG=""
##
# Slack Webhook URL.
# This allows posting to the given channel and includes an access token.
# <https://api.slack.com/incoming-webhooks>
# Disabled by default; uncomment to enable.
#
#ZED_SLACK_WEBHOOK_URL=""
##
# Pushover token.
# This defines the application from which the notification will be sent.
# <https://pushover.net/api#registration>
# Disabled by default; uncomment to enable.
# ZED_PUSHOVER_USER, below, must also be configured.
#
#ZED_PUSHOVER_TOKEN=""
##
# Pushover user key.
# This defines which user or group will receive Pushover notifications.
# <https://pushover.net/api#identifiers>
# Disabled by default; uncomment to enable.
# ZED_PUSHOVER_TOKEN, above, must also be configured.
#ZED_PUSHOVER_USER=""
##
# Default directory for zed state files.
#
#ZED_RUNDIR="/var/run"
##
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
# device mapper and multipath devices as well. This works with JBOD enclosures
# and NVMe PCI drives (assuming they're supported by Linux in sysfs).
#
ZED_USE_ENCLOSURE_LEDS=1
##
# Run a scrub after every resilver
# Disabled by default, 1 to enable and 0 to disable.
#ZED_SCRUB_AFTER_RESILVER=0
##
# The syslog priority (e.g., specified as a "facility.level" pair).
#
ZED_SYSLOG_PRIORITY="daemon.notice"
##
# The syslog tag for marking zed events.
#
ZED_SYSLOG_TAG="zed"
##
# Which set of event subclasses to log
# By default, events from all subclasses are logged.
# If ZED_SYSLOG_SUBCLASS_INCLUDE is set, only subclasses
# matching the pattern are logged. Use the pipe symbol (|)
# or shell wildcards (*, ?) to match multiple subclasses.
# Otherwise, if ZED_SYSLOG_SUBCLASS_EXCLUDE is set, the
# matching subclasses are excluded from logging.
#ZED_SYSLOG_SUBCLASS_INCLUDE="checksum|scrub_*|vdev.*"
ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
##
# Use GUIDs instead of names when logging pool and vdevs
# Disabled by default, 1 to enable and 0 to disable.
#ZED_SYSLOG_DISPLAY_GUIDS=1

View File

@@ -0,0 +1,9 @@
- name: install requirements
apt:
name: avahi-daemon
- name: enable avahi daemon
systemd:
name: avahi-daemon
enabled: yes
state: started

View File

@@ -0,0 +1,52 @@
---
- name: Install packages
apt:
name: sanoid
state: present
- name: Create sanoid directory
file:
path: /etc/sanoid
state: directory
- name: Copy sanoid config
template:
src: sanoid.conf
dest: /etc/sanoid/sanoid.conf
- name: Copy syncoid private ssh key
template:
src: syncoid_id_rsa.jinja2
dest: /root/.ssh/syncoid_id_rsa
mode: 0600
- name: Copy ssh config file
template:
src: config.jinja2
dest: /root/.ssh/config
- name: Build syncoid cron job command
set_fact:
syncoid_commands: "{{ syncoid_commands|default([]) + [ '/usr/sbin/syncoid --no-privilege-elevation --recursive --no-sync-snap --create-bookmark syncoid@bigboi.zacke.xyz:' ~ item.remote_path ~ ' ' ~ item.local_path ] }}"
loop: "{{ zfs.to_pull }}"
- name: Ensure syncoid sync bash file
copy:
dest: "/usr/sbin/syncoid-bigboi"
content: "{{ syncoid_commands|join(' && ') }}"
mode: 0700
- name: Ensure syncoid cron job
ansible.builtin.cron:
name: "Syncoid pull snapshots"
minute: "0"
hour: "0"
job: "/usr/sbin/syncoid-bigboi"
# - name: Ensure syncoid cron job
# ansible.builtin.cron:
# name: Syncoid pull snapshots {{ item.remote_path }}
# minute: "0"
# hour: "0"
# job: "/usr/sbin/syncoid --quiet --no-privilege-elevation --recursive --no-sync-snap --create-bookmark syncoid@bigboi.zacke.xyz:{{ item.remote_path }} {{ item.local_path }}"
# loop: "{{ zfs.to_pull }}"

View File

@@ -0,0 +1,3 @@
Host bigboi.zacke.xyz
User syncoid
IdentityFile ~/.ssh/syncoid_id_rsa

View File

@@ -0,0 +1,17 @@
[backup]
use_template = production
recursive = yes
#############################
# templates below this line #
#############################
[template_production]
frequently = 0
hourly = 36
daily = 21
monthly = 2
yearly = 0
autoprune = yes
autosnap = no

View File

@@ -0,0 +1 @@
{{ syncoid_private_ssh_key }}

View File

@@ -0,0 +1,30 @@
---
- name: Check that zfs root filesystem exists and is mounted in the right place
zfs_facts:
name: "backup"
properties: mountpoint
register: zpool
failed_when: "zpool.ansible_facts.ansible_zfs_datasets[0].mountpoint != zfs.root.mountpoint"
- name: Set properties on root zfs filesystem
zfs:
name: "backup"
extra_zfs_properties:
compression: lz4
dedup: off
state: present
- name: Enable weekly zpool scrub
systemd:
name: "zfs-scrub-weekly@backup.timer"
enabled: yes
state: started
- name: Create backup datasets
zfs:
name: "{{ item.path }}"
extra_zfs_properties:
compression: lz4
dedup: off
state: present
loop: "{{ zfs.to_create }}"

24
run-playbook.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/sh
if ! grep -qE "vault_decrypted: true" "./vars/bootstrap.yaml";
then
echo "Decrypt vaults using './decrypt-vault.sh' first!"
exit 1
fi
if ! grep -qE "vault_decrypted: true" "./vars/bigboi.yaml";
then
echo "Decrypt vaults using './decrypt-vault.sh' first!"
exit 1
fi
if ! grep -qE "vault_decrypted: true" "./vars/smolboi.yaml";
then
echo "Decrypt vaults using './decrypt-vault.sh' first!"
exit 1
fi
./helpers/get-passwords.sh
ansible-playbook main.yaml --become-method sudo --extra-vars "ansible_become_pass=$(cat .passwords/bootstrap_become)"
./helpers/delete-passwords.sh

4
todo.md Normal file
View File

@@ -0,0 +1,4 @@
- smb passwords are not updating
- improve structure for users
- concat lists?

338
vars/bigboi.yaml Normal file
View File

@@ -0,0 +1,338 @@
$ANSIBLE_VAULT;1.1;AES256
34353734636566333066336231633735353134636466626234643763663833373163393937396666
6264666433643336663334663439346434333964626335610a366165666466336530613761346134
39326131316266313164313832636562383037343664396430386135336564366466663339626165
3634653830343232380a313938393633653536663562636266623936323165386231383861653034
37623765613062653462383030333036366361333137316635353831383264633435663335393937
62633038653639396363623638636662303063376664383565643536353432613163376139313265
66313862663431656463363165313235633636363430376430366631376637353964613864613264
62653634316161623833653162663237356535333564633030376366363461323639303364666235
61663538663737643634636130646664323533636239653133626662303536663336343937316635
66613132383466633732323136376566623466316230363239323064363136323564656434303563
38333532653265326366323164323631313935633536326236326239383634656532316433666265
36383832363537313936313837623236393034626631653231383333356634306561616532396130
63633863393462383739616338653733316136366664643563396463303165643961363930363239
66346562663863653038653262336633323236353834323161653531313165663162316338303837
37653033333236356339356531346163626133356563633665623035636462306239633834383465
32303838306133356166616565313664383363313138613733646632643261643064626136346132
37366333373138623432343236393533333662396336373663386137656432653134626161353936
62303737613635336364333964616163303966366333633634386662656363343339623765613732
61353935323838383663636330396236383133396538643831633830616330303162653037343963
34616130663636333337386439633463663733353236613031616338376434316432616233326463
35626131386662623464666435623833623636626231653266646538653438666161353535363166
31313637373238373361366365636162396665376466616534633539366132346434656134393466
36363633303036346339623330376634666632363238323634623738616230306531393138666232
31386438613831623436393637623335356465326135623161656639326439386637376164666236
61386633366361306431346336616633616234663332613161613936653063306530386365373637
62356230613566666635613430646134383739383931633864623431663231623138613062613365
63306163323831333966623538313934313030383232376239333965636439663236366161623462
61656530326637616665336138393439653365393835326137626666653931373333376131366364
31623734666664356531646338623031646566363964613062336530326134363532333533383736
35353830656466393563363431383339653333383564663863643065646663633063383336636239
37316464326630653062613933653536356537626536326662363766626466663935343131643161
37353161613539363630376232643339393762323030323062333330396439393264363135653865
38343030643437643033623838656136303237326166643037313363623162313663396338373366
39303235613964643537396563613265353064323638393139353536663435383964323061393631
38343936306664343536313062373334653662623761363931386533623466306432306134626164
62363739366263633963373136373764636335326430363039383462646566373930356564366530
32636439313131306134633265633231643531663061616139373337643762336130353330346339
33323938663931326632323539613432663839633433363063303965383736366232386265623363
30633732633838313833323637666338396337636630626530613831383134666563313338373930
63303634663639656264623230633234633537636435643635313534396438343235313434363265
38353636666535643735633266386532323030303132666561666130656535373635366234303464
30346264383736353163396138366261363834353630643666383532663265366432313939303335
62303538333831353030323438313064303039383738316366373639626266306336316463656335
39316532376561393734646436356532643536306539646631346435363364356530356564663039
32343865636331376365373265633835636634636336663561313231663562623434363565303764
66613736313832393339396130366464383663616531656265653065613836623961616534353037
34373634646564353434303666333336316361366132653862643436343063653931376266623664
39663333643038356236383063306536393864613834343562663030323865383733613663376165
36346365393437373937383463333731656334626231623663336332396536393936313330323937
38396661343833336639376564333639623231643865356238653438333638636338313935373134
36623637653065363834353431396531613031623036326433323062396262346237346237613862
61343736303262663434373936623166373564356465323864323330353036316638366531623630
65663564363031643033643938356535336562666436373230666265316238613030663136326233
36613264376461333835643035623262623437326464303765333735313362306563656530346535
64663231646161376431343362393632656462666531613331643937313461396430663337376637
32366130373162363463316461633566343766326564336137333261666635623662366236366537
65353631353366386434656137656533663534643334343664396130366339383937336163633462
37366631613137383962326366366163323963343739366231623564383064303437396333323636
38343632623038303435323664613330323864366461313830376233666330376533323861613736
64633838393832313263323163653830656539616633626539356431346237396630613132303837
31336166363937626432396638616530333531303538656234366335393137636636353564326630
33666264333261396538653538376339376231376566363866306430363133636562336138343665
66303465373636653863333336346331336134373934316535636363353437306331306234623036
34643164623562643737646435336331366266383132616635326532663039626533643530636136
65646664366635373534383165626564636338323831653166333433663938613466363738666630
61653537623130613232346533363736303663373137366432383331393732303061643062343631
36643833636366646132323266636563393034663264353632663965323861336537633436363630
64336339383866366236623730613234323566323965666236333338333834333237353931646135
37643937653437633036373432333932383932356265326332633230323539366439316438643065
35396139353339626534373431653235623233626266633433636332313634663039323066316463
36383437313339353734356539643965653036663934343565653135333263666632623433653965
31336566393631623539393162353161643631386233303637313736343565333966333633656238
36653561393866346236356435653939646638346162383433316631333930653131653966656465
35343231636534633933623037323232306539343135663338303731623039323933396464323166
30663337353137383332663164343536623861353733616336333265613939373833653636666434
31623563633431373365613335383034303833303135373561303036313332306531643166336563
62396165303232323131356134326337386536366531376235663235313530303336383435666661
65316265313630306630343864663361333064373839306139313138393264343466613037646331
38376239373538643339356466666131393561353062333038336162383431633831333338303739
31343335653531653634326165393638373038303166316231353234653563663334666438396363
31646138643939333432663333323038643232306266646439623538663330633532393835613735
64363437386636633737636236323734376136366266666232313931373936333064343161613939
30313835323831616333613430346164316638326462313663383237653131663064346362663635
62366336336363663361663961383430333362316336633737333865633865373266383930386163
62336334303138623235653562626665646636623235323732333535366230383464616333613737
63663163643837316637326138363534353263626563633439363230613837396434396661386531
66326232643435383638333037323730366430643161663130383130356539636135663865333962
36356164326365323336623864383639366466383430326530316437343634393431353765353232
63353365626662396361383635356564363736373930323631656663393662306465383335633562
30623666373035623337633438323836376232353139353635316262333661663437336137323064
64663134373461336535633833303064653434366131333239633964353630376566386631376462
32633237656165623061343634646430646434653462313364663838616335373863613264306434
65666433626135636465383332656233396133616239633535393834613138373237373239353231
35333837353236316531653661646361393961653732373066393734623437383435343233333065
33626237323263353038366165396637303337306532366238633330336165643866653661313966
39353431333762303435636631346337333234633462306161333330303061646262633631656265
34666566653166313035363335373138316234663964633766383663623866383332666561613164
37353133366530393462633462656363343538353264366131336162353966353465313765336462
35666137376466353836633330353465356262643535643039623463316439393038393032656634
39653537646532303239303931386632653232396436613739636561323936663637323838626531
39383764363432633337646162363931336332363464633432333038633838613365613262613232
37323233373737393536623961646661623336306566383636323338653631396636383338656361
37653233613263326630663533633338383233623933393538616266383263643332383561646431
33636464653933656239343466343661646361643137616634333939316633636331383161353533
36373431346462323062373639616666653035336432666332666331326532353336363734653938
34336630346665376235333930343336663363643930303865656635383833353439323964326434
39666565363234396564386261396134363534376235313239663362383639343663326633626331
34326231316434383932313538383466386263303033623038303066333462623736366363303631
31633933646562623065366630366261316639383633356630363164656362653838393061386564
64623664326430626430396664376461346431376636346330636535663430346163643235383434
66636532343164313365303339373362383336643231656661353539373261373734346264633539
38383932363339336537653139653032333437363439646461333939323133633031326464386565
33613638633137356336373664633030636461616636333563346163636436623432633136636561
37393263373631626333613033386633313831616661366263303731363762326365376432313134
61363739333664353862636531633733626531633031356635643565663337646131643161373930
63313664653639346464326339626262363331623466373066396134383334323339333734356532
38616363616236666238383231666265376531613164666261396534343564303361633038333634
31373563396563363731633733303932336335326265336466353833383333336337323934336536
37326237366435663635353765383864373136623133336136633762323934613437653930646239
38306161383635613238646634633565313063363036343230666461366139313765636133666565
62363039303638393366303866353465373839323566626536366338383964653463643336313732
38623932323034636664383661373061323766373063346331303761356136663362346232343065
62303865303831633062633630346336393038663332336465333231366133653231343030663066
62393939626139356661343965346665336338666539313230363238633163623030633363393139
63303337653434663838316266643163336538643235383965316131653930303266623530333630
65376366376262343332303138313034323533386331343632383731613037333635366138313363
32323762613265626637336232373236323766613333656461393735323762383330303831323036
36396361623762396131663963623233313861303439393664356332356534323235316138626132
32353435626338633533353535643532316163646463393961333638306337323065373561366430
64376263373330623331353031636165656238653533376336623761336435333764636564633065
35663664373265356631633639656435313238636633393962393738343762376438633561623465
30653837666435313438636234663961373630343737653938333338333830343835326131633965
37383535383831653634613534303931633830356562343763313864313730343634386136313135
65386634393735656535643833393131396239623562366233363931326635336538396636393232
32663936333363643433646134653931323338303736346431376139663265663864393838366166
63333666386165373062626162383466646630306131346332383462393234376232663137383666
34663733636461643963373835356535313861326138653437306438613534393266383861373538
63393164653735393435363465343733663330383865386432623061623634326437636163313833
66643930363132646437666133383030363734326165393730343739633932626431373639363361
37366339653537346537393035366233303062363264653238386133363836363339313132303639
37333066613462323661373530373136343539356466306163663830383963326662653464333638
32393933363262623830323136313333346665326233656566643834643961323932363531353361
63626462623835306161316437346231623663383335303931393465366536343631333262336265
65336332653530663339646533373738353661376334376331326561336535373861646232633037
35626137316163366537313665373466366662366561383339626464343133623138636533303739
30326337623765366162353235396530373964323261623461373337663565343366633333383339
33633866383933653734643135303034393562376632346431306335376234393764363463333862
65626365623234343962646532643261393262393439366166313138373330373566643064396234
30376237373736303564383036366461636339363631616633383862383664363135653137666633
31353363616538353635666338336565373739666261373232353934373965656465656163393331
39323439303532343438306163336164313138303833313737333666623464383363313039393234
35363233633236356563306562343662396638346562383235633166653433396537383565343337
33313437346130646539666230633265663065336439663836306262363665373864633765653038
37393664646662633036373635323161313936636533346266373337393034646361373935643364
38633939393533356334303635343466303063613561326465383165663431303738313263623861
64353939333739623130396233383331373935666431316264303733346634376333383138383731
38663463396465373463656530393136613037343462396562306435373930646161323363363037
38633266653939613565383161326265303161666139613539363962363230623266613264616136
37376661353337323963343561386439376230623634353764326662643436393439363034323761
33393130366134336338393337653332653138303135393862383963386233643339323765393033
61323039303335316165363830623632396164626662646164323431363838346562333862376532
38396163343462656461376465323231336265326530636338313063356337633235646635656630
34373562373563383361356637393266633862383634356539316430383336653936323437636534
34336334393564343161613464326661343934333235363530636431636564383732323761643130
38653437643036613932363562313735326161643639303165616631653832383433636434313832
30653138623732393564373865656434333265316230633365336532626336303464306234363833
34646539623930653131363064323833626165343237333035623631353833626563333036653434
30313866373366373963323731376233323035386637636136363364316638656237383863346162
64363834376433333538396139613963633331343366366565396434373433623464346434313962
66393662316132346338623636633930383166376338396134636532646534646233663238633634
62326565373234333832333166653633363338623064663165613162383962656563373538623337
32313739353365626537343464356138353336636332316261646336336433313032333166633232
61333237636664363963663662396638366461373637393661643232313432343936653663613632
65303761353331616638343865303635626636336139363339343131313865613764313865323137
36633964623736663163326138396631386232373331313731396239316637306135326166336430
66653238393839303866396434386162633131356139313430356238613534663430393362633765
36386537616638663838326537323536356662373035383765663538386436353466656361396363
61396438343435646633356362646437353832393931643064613364333366633234346132343736
37353133323832613964653535663534383561373765393132313562393539623839616237626631
35383134356463666237336237343732386231656232326334666261616264636435636337313930
33366439626636353031636235366664376566393033313231373862343363666233323064646439
31663639343437343630396430633338316534306664623462333461666438376162393035353166
33323664356239626238346436613339363464316137623339623736633737636231623162393439
63633931643030386635666234666334663438616335323130313434333839373131656338366139
61643238383539333264646637333439653265653936346462393730656134646432363165663566
63323964363562353431393335356262623335333161343730353963646338363538303566373836
65363634613337623162656336626436643163353961363635343863383432343734333337366438
33626137303365613539376531343231373563356531343662393061616239383232636434396139
38636361383064326331313463613761643163656665643330383432653137383331623432336265
62376431316461303365636533393231326638373838313639376431643730616335346239333163
37623265643133366362373266306533633635346363646436653037393633343837616434356339
37313938353936633664323461336632343930343230313638613164333730643031343136353062
34373430333433363265303863333033383662356639636233343137373237393433623635626635
66653238393734336133333438383537616433353035623462663539386634383761383766326263
30633236346130323631356534366633656663653262313165386566656365633636643936663937
62623266663862663531346632623932316534356532396561383263636635316131623831376231
65323666333239333365316435366535666537633463393362333236613161383531313264343135
33666438633966373332363530653766363535333161333764343761356562643265623866613866
39363833336334383138613338363538646462366663326134303261656566343932366430646332
66643933363436303837633064613362613439316130616432373235613831633831343235343962
32323261663839653131666639643939336266396264656237636134636131386233623663363931
65646137323664633333306163346364663436303031653837663532373034636639636366663033
30643430303533323330353566656538306363613336373265666163303762623362306138323964
34633366323338326530336166646434346665626334623230336162326362323931393231646330
64333466643164343162343531613535346661646137356565336134313030343663646231633035
63393163353230656139326531373562323862373735636366343162376262313063353965656438
33633361373336343434396139616539363232393130366531323163313036663462653735306138
31376532643032373262636134646162656338386365373866363038623661636334633661373330
38306531323134643036656335663638623230313938376662393762666166656237646665633564
35393233376238333661643832316239316137373537643661343736393533346334643134343861
62653263326266653837323339323062336430636465613131623630326664336266613365386265
64363936323237633665623162396234646132653034626432353264323435663738323737656132
37346332636437386639656463636635366263393131653061643131353861343433393935353261
33643966323166303664353732616237313632326336393035393231316139316162393938333265
32343837323237326639356531393830613838383534646662663830393832373063373134353464
37383835613163643762616439346165323938623863333066346136353638646632646139643330
31383333633532323037643535396438326635376133623636633335353231343934393439336133
66393131306364393832393766326338373634343833663039666132326439346134393761643236
30333030373438636666313730363931303335613462373134626662346264303238663930633934
31643937646666356135363564663931616266633834353032353766303864323533356663373733
66633731643961653565303734313362656665323239346631333331636135383133643565306533
31393733616532346633323132653437636166326265633665376361643731306137323437303539
32356335653764643763393962613964326335353762393665373332653632626165666232336239
65356562643863346464633039333062353134616233376338343166343730643530646535383731
61656162623331646362386437313534366463643461653366306635333038366239336233663736
37386134366431356138393565633338656165656333376464393139646533643136316232613136
31346266653931623862303264373737383963633837663365633634343336303238396234666565
62303732313164333038626166613733323235633862656161353233646636303137666531393032
66653764653061346333626239386262333439653530343365623861356532656533316338636334
38333139306539663033313931313435636138376435343431353439316132633566376164336637
61393637316132383037306264366637323131643436633162366261323933323036376562663034
31396364386536666466396438666536656138316264323531393263656130363961343538626539
62363639363064633731626235386563303535313931346361656137386466343661646366613763
39643233353331626436616637653463643663616435626365646132303638633933643337383262
35393161636365316662626535643436663735613065666235636232336239316638346636373465
30353434326330633432313664303835653639303136333565303635316166653261313930326638
39646431316339313436353261633265393238373963343135323137313639393436333535323937
31643435353438373662333433623039303932326237623834623837333137303138383935333763
64306236393561383666353138316265616430663661663435653064343833323639623436363539
65666665316638626238643963646538326337386130376162663338363531633031376162316464
66346630386165656435653866633634376236303935313032363363613064393962633064326135
64643337636639316236333035636666323562326130396662376231616231323135336337323561
31356461616534343362386434636630333231303034336662626532616263353061366536333637
30326138383238326631666331623939306165366265646138633030656232323030316530643165
32626535316263326131356262353731656337626463356366666333633466353034316161343434
38336465653931366237623431316365306637646562653530333334393237383633663336363933
39346139326534313236626434306331363839613534376664316136363937346264643735386164
30393830363935653936376138393866313563383733303064343330613162663763626165376534
39383662353061653762643638383065616636313836336530306363643732646639643431626330
39633631336436303034633666393166626433373261393363393737316233626634383263666637
34323332323063356339613135383530653363616363663737633037643639626237656264383730
37643239623963386663656233383634643339643364633763333030396433626634346435623239
62353865633262643339613063383130343832633330343233383039323334643237626433613763
32666235623639313666663138323161613933633462376439656639393030303766613462666530
65663137383139356230323064386264643533356335323538363766353937656163613232613635
63643338383563323632323031613036616437643232636630376262383863633137356335613362
62396262333330623061303864373861396239303737326636656438376265623730303039316132
30333536383837336534393864386333313763353764653130353530343137643863633064623238
39623237616465633063316664393361306165313063663665626532353338633337636234353334
62346235663363666266343235323037333039376235336438616132646639333666366333313366
63653262333934656634663862303535636335633666653838663939663538383562346233633234
34393739616139613332346538633439376338393039333262326231373537333435666162343338
33363664393530346261666362343034613063313636313935616432613234353330656538303661
36636230376139643064346339323138376264333638313765393431356665343564633061613032
33393135383738623761663461313530373264323235666236626166356363623435303966643636
66663731353930646361336538643730356462643561353938343634393837333238326261383738
65623436343961386165373539643036353865366136393338393438366637303138333636343432
39663938353733383737383536626438313565393236663530353439353265666239616465353062
33666535316139343261633731383863666231663761653538316634386237616466323466393561
66326332303264653266393232393364356531653661376238383633616632323931643835313163
62616235346230396538623164323337383064346432643139313337303435326666393337633133
33636238646430383836333766376636643337623330313538346239353937323436396132333331
65333365393738396165336466393933323636663834333234303233353234303162623564623065
35366163643166386365336563366131356632636334653236636237623830646533343063623066
62383533396662633431363361643735396636666131333339656334613762323536643763646566
38643136623966393035323265376633613834326531303934643139323265363339336137623166
35616463316532326334633037643937383333636333313566366538613036646433356139663961
37613133376633663961333965306439663934313936663736616235353063643437356134646635
37376133363131333334643032336236313939383066373263313439396237373263353837323839
36656333643132653662313961336233613336616533636339303266316236623936626163383962
63643736646332313037616231356564643133666538323430633462376163303033343364313436
39366638633332636263663131306439323361346633633333333663626230613835306331623663
62303138646538373762633235323761326139663634313530663731643532366164353237626635
30366464646462353336313832373631393838653836303066643633366639663430643033633633
38633764663433383330326632353734633061633138333162663334656333633861393339633436
32306130356637313436366435626130326235303733366633376165336661346265653465363165
32356233383065643631386438353264323536633130383139396239336139346563303962383765
35396230653232626530376435333635316263343632303137663338333434626232356535633035
37653866383133393964393834396239393738663433313435643462353630633539313465393061
61353362363639346161656663646161333266383161663334393661376139393364653236323466
64316563313335356637356662623930386162333831353137316538636564373565343738646337
65306637656333613865643930626535383234326636373363616331626364636635393964323432
33616630646562626633356438333461383332646131323731303939623961666133363265333262
62363238376330656365636139646139336630666463663835616466303965383135363562333462
32356533373564633263343565643263333061653034316538316465616461383463376330646237
66346662386264346635633435393130633264343131333531326132623335663635343866633434
30613463343064613135656136396636613332666336353235643839633063376335356661326365
32323962393939646563363864366261653862623935626630303436663264326365633061383738
36383136633331383963376632386433643436316566623232323130643566623363623131306161
32376535626130313361306331386664626139663262616633343833663935393461333937643063
32383038666338316432333531623961663739656366646537646562633335633061346536653762
35353335393365666430646436646264336135333539323538376339633034323339353938333638
39343662656533303638353064336336386330626264373239363939366131613738633439356433
31343364303961613131306332313766313336343262313435363839363763326434393566383230
35373861333531306162633164376566353464376336633335313437633963353164363764656461
63643066646337313464643832626230383965626434653162636666363435646365333266656134
36393336353963653961336263613839393932663136343034383330386663616536313362663762
31306231643434303535633561333966623239353730636636353139663466653830356132663534
64636430653933643832376134656236376363623134623161656534313034393764336333343264
38343332326266633561653536343465366431656663303265326135386664643965303837373661
64663435666539613134393663643535386533636363663662393862353232316465386166303631
65303730353165643530303738643266393135633237346337376530663036623065363862633330
65663562633438313062316232623136393530383063656133613864373338303334623663313138
35636333356261383861303337373337346164313039663738643135386437663435643130343662
37643232303734343633626237303038356661363364663238356461653030306236313636623333
36373864326430326134353432643238633734336363313365633537333635313936343936353134
34373439303338336236666436323333333838633863326661393239353064343136616462643835
63633530663462323338306531323061376364616133633639383465663936373938616134626431
61306361626236356465366131646561666135306633343864613362313133306636363934343065
31363332383463333232316565383334333635336463636266656338646163663634313637636362
31393161663236366436363932323132656231623761353439633762623661333365393461393666
30333162303763626363333730613862333234303838653337303838313365646365333661663031
66326463353635623139343261373338316535323465663864396633393731396530393633396562
63393536393262383939633937386232353936396163303964313331303532326165343065663665
31393936666530353731316639636361633762393936363731363534666664626138643137613466
37333166646561626163353437633834336331666233656138396539663638346437356530663439
34623333323163616638316539346334343063313636306364626338336130363031303066626364
32363262306331306538396639376263313966323333393333323031323337303938383231323861
33313963343537616461303666643163653663336336663134303862303534303062363961623662
63653164303232666436636161396337613562383139316534633462353032336166653039313261
30623261663936666639306138343734663038326436313966323631623564663431313664356562
61376237613738383537366130363230643264323932356531613763663536633439613866633536
62376462356364383536646638373661373039333238386265346330373731373239386163633437
32376464643637636666633239613038313738343134306636396564363162366234353064663362
61666462393734613432316566343066613632323765376236323966383834346665393633656431
61643635623035363466663437326139366132393231343064343461313931343734346262383464
30646434653732663633353236633232666434656262303231306436323865353062

37
vars/bootstrap.yaml Normal file
View File

@@ -0,0 +1,37 @@
$ANSIBLE_VAULT;1.1;AES256
63656564646333373937666437643466663366343136316332376465613639656364343865336136
6463363262616163353261616265663530376536626361660a613965363531626633643431353565
39626365616533636430383664663339373164376634613339363463323037386630303235353834
3635346633393132300a383238326538656134343161623431356530323462653863663033383731
30353765623162333062353635363537653365656264326632313039343838313738316332326533
36663031396535623064363362643232336635663135616634323239626631343665343430393263
62363630323030313565633834326530653233623339373965316563313034663530383566623864
61633739396632303865656437363338653739373465383762623235623235393464323630623737
63636330306630633731336338323731653835393963633639616139373764666235363062653838
61336664356265386332346366373537396136653636626138633866313631336531616535633335
62303265353161323134306463336166383665636637623631366635346163383562366339653761
38346564313234393832333836376266343661323964636136613662303534636439333531376634
35616463306335393432313132306137616164366133376533393334616336333233636539623836
30666333343134303939333866623934653331663634313531386535636632623266366665643335
31333836623533376236613663356136396634666663306632306230366438376635333239623032
65316263323034343035666264626236643232396365376535373966633031356164616132326133
39303931616335656536633462616261636362393130373834346335646261353766613861626237
65383738613965396539386533666436386238656361303933383739353931353938333938333365
39393039636466356139623434626363343062326164386136636234636436353934383764316165
64653235316130336137393439383730313065643131333230663533346133646136343133316237
31353061343631396162643664383864313163396662616262333762313534353166346137363337
38313138373263366230336334326135616536363564653665663162366237616436626633333066
30313663363532613439323364646639386465393565363531376233393266383261333739633034
32313938626464353033393537373866646439353463386265346239373432323333326331396234
35326462613037323531303764316632383435393038616232333434356562396434333837623933
32376435373131663863373865366261356431666531663262303036373762336261333866353732
32336237643365393664643236386335383235636537336465623434626630653931363863396637
66633235313738643638663038306338373537336161326337383031663930336536616463323033
66333434613035393432393130353136333866613263383664636137613934363631356562623061
35346338666137613331383862623036353532393163373530333337623131376663373962366637
34616234616430306632353331383562353231306632373163666332666534346263363866326564
39623438666566663731326162353661363932306538343530653564306534303533306236306661
63346462623939333337333066343937386662616262393361613561643435383566343439633061
36373638373763363365303936636561376536306439346633653534653036353261386239366131
34663235383235663338356138376466356662613366356632313666376538346136353533326161
35626266633132373636

234
vars/smolboi.yaml Normal file
View File

@@ -0,0 +1,234 @@
$ANSIBLE_VAULT;1.1;AES256
36396536613364623566346362356133383162613331643632326236616230343166663463633834
3362373961343964636530356632393035373038666262620a643435366537613536653230646439
62623531323437336564623230383836653332363339666432313335623036613062333036643034
3633313836336165650a343531303265653564376232326433393338663964636133326463316261
64346561663464373935313731346365323634323539633336653666333565306133353935303932
31356435323661653531336162336138353362623366313934383337303235313263626366316530
63383539343632623530393364333436646235326536396130353336356432396639386137666631
34373439346136353034396565383764333935346139633838663230623836613332353231366233
31303765346632393532386538666438393831303164616638653165306439336364626266656636
62326361326437623539313933343539306533373630383237393933633338306362623062383461
64383461303432393437613433623164363465613439353536626262623966336361303831383836
65336338343039336134613836393866373737616161653766623330336631306264323861333937
66613930346538636137353266666264336539643930316434353664333639303635333562333534
34633030383032363061643966336530653636633239653433656638393736663064333263373366
63316634623137323830613837333366393865356133343231393236303633356335323530383735
36366363613966653266353561326164333837303366646533346366356266636162313964363939
34343865376437316262336264623465383965653039656534313436303035663464363738623730
63323965343966663965393663363864376133356230326530363938363032346561386335303834
31306637306237306561336434343236663262366534353165636439313836636561663637636337
61663834613461343836656634626662373362643635373138353863303361366330643232393438
33393031363537313534333533613339383839623536363161623635316135396430366131646666
66363230356164353930326662383131383431326165623663613837373066383434633933343630
35656236373066656130333239306136653562323638623363336166316365326535643061393735
34333539653436303139623463363065373036323961393939323761343866363732363833633563
31313066333430323537363735323631663265623764663735396639326638393864313435653235
39646265343035663663613035313338393430653632373631656261393461646536656233306161
32643133626639316630303463393437373633336635303533656265373834613361333163386238
33656166656139666365353434363632383562303232393835303963663134353333353839663166
65383833303838303039363639303034333966363965363238383532373335393564623034356636
39643938303633353134333430376134343363333839633464303864646131663230613562323461
39326166333639646635323539363933393565316631343830353839616534363439303130366565
39623736306264313935616461636534303931643635376139323731633939373334303932303532
32383561376138653237623239376466383862393362373831363236623062636134323463323637
62306133366539623335366433326461346664346465653166383533626132663532656434663866
33633764306432646232663936333261306639333237653433326435636366663363353337316665
65353162333439653238306461656437626364306664623864373838323938316666326463313432
62356338303433333466386531653965613338303862626632616637656261326131366261616462
65303336636630623062666161386336333763383431363062346131636530623339353535663565
65336437316133346430343739393261363633626536653361613235626463633334663431346136
38393461343165363234663461663135396439613637663861353331333833366634653230613262
31653939623134666431343065333061306239633431326338373337646237393332303236666433
62323562663832343630653733346636623535663533313933313061316230373030613036316134
65386336633635313064646533633030663233613737666234633235326363343765303238356231
38363764323064373861336166633962616335663137373463343733343336303764633765623664
62643563343738623261396635653734303238363063643136373561316630653732313166366136
30343534663830666434343537386464363162616137363836386566393464363730643738316266
39323835653164386562313334353839363163663830376432306165383036386430363431303436
38323861316637653061336431356436303464643664613535626137316364646666663639636432
34663934623031396161613733343031623031333235373436303332613332333338396636313162
66616663376363373334663430376634366431343538313734353839386639346234653730323038
35323831323062653434313231356538663064383038306435623963653337313436376564653963
66663338616532323235313463613963623533383731336137633263313239363435396537323233
36633761313663393139383361613566623261356131653166393561383532316532383635336438
35666262373336393633333866666362363163663435656464663235626533323034396139376661
63333565376131623565313733393735396532326638613436656666623762633163336462353765
30356466336337336262393930353036353435373032663133323761313134636436363735353565
35393233353766333530633533656561666165343935363566636462313563383533383930383635
31353534616337643632393335643435353438316532663330646336303262316434303364303137
64366634306637323033636665373832666636396131326663323362643031363763353033343739
38633261643266393132633232333766343034373233313730303533653563663464353334346261
62616462653333366661373863376536333734613138636564653631356435386561343264316339
62396532396363333232333834316531366264303332393739323464306434353862663032343435
64653862616638363536653838353931366263636538393433343431333834653966623934356661
33633038656265343733656266386164333731366337663936363262383930333034353564303230
35323635386464653837343562646161356661663434656164353263343134343563396466656661
34386637656137313435343235343066393130656530666639376361393539653036626664353738
30346433393930363865663933373963663632366638306463626466353463393361343663636335
30623335643635393165623932666263333739633436616262616466646435616663386135303363
31323363303063376333313734636338363436633737393034336239363762353362616462346235
38663832383139326432633565623563636539396465346537336431383931353739646438613337
64366462383839323836303737633339663937353734316463643439663166363465333465336432
33313438376537383437623161303563666162633366653133623866623931396164363063386461
32396264383331396335643932653234353764646135333562313834306462383731363733663966
63386238643339373138326430656630653439306538623636383965383836613963623131666138
63666435386266393661633863373931316333613331393165643737306437323830333638623263
38373738366630646162653231313763313737666235326234663633336430663761613238313639
37323537663366393136613466333938323531616636326230343331343366346330623737373534
38663438373165366538376438646639373130353065656362326130666538343965666337353539
62353436396137396337326162633566636632343462613430316133303539303734656665363338
61373436636631636266376466633766313637303965663465383938653061356430393763313865
63663536633930306663636261383036656436306664343837393163326463303064316434323566
33323565643837353232623661666230376564373837633537623663373431633038343263346638
32323134373535353263326666393239323663623564303766613230353563383732373630366532
33383661663565323632613031353864393335356363666466393535663535653565353436303133
36333732343731653562316365336363613965636336383634393039646139613766656163323936
32356662636332613031363932383339326333323532626530636137623031633765373533643933
65356239346233376632383166313937386464316538393134636666326538343763383431633338
66666135393037623838616435336137663539346566356164353665306231613739313166663631
32626666336662303066653031393935313834613766363964626131663434306636386632653332
65633434306138666162646563643839343631616637653135653438383538393838343733636538
34616366636233646432616234373761343466623963333035626433316264353164383763393330
39396439643663323063303162393334613733643836636335396361633733303664363163623865
31623964343632353535333839666435383438653034306164393039363766653231353939323834
39353438313764626538663565396134366632616134336430303966373963663265383636383734
33393566366466386438316133656364316338303039666135623938646665353530353533313538
34393336343433376339353736303861623066323533333631373461383730656661386435643939
31653235366633663461316662356464633233373639336437396636356437303462663339313165
37323465386137393037346534383835393735386633613839303832363038356438303732383566
66653439666339653364646464663166346139313338323437656432333836633133643133346134
61623765306365383764396162383062623834633366636331663935366262326635343133303431
34396532306363646535326630323534623165383330323763633138336263373031313031346130
33393137316234383835333739366635383066656434633535346663323231623139343861313033
30643865636661353231353032653235653061343765613361643061663930653031303164363935
37363166666134623334366635613032623463313133323532303530333964326139636161363261
61643065303739653765633136383663393736393934396638613965353039383836383930643330
31356238666133373765303036613735373839396438373039616637386638376562623035633965
37666661626436643231313630336166373462303137333864626161353764643334356230643631
34346137636232326633326164663262376332626331343665643437393539313336303831373366
63623463336465353565373164616331366462323266613439626339396465343133626438323632
65613234346162636661346635343239626431373037326265303830326239303635666138663363
31636261656539323163336439633730356661663664353439633361633962613163666332363365
64343564373932353765663261616239323939313331346632303537353763363262323065326432
35376534636137346263656539323532653234663233363062323535326165386630656366643836
64633736376533633363653334646539346665653236636166343864616166616637393733366462
38343533626537336266666330363935313461663262353439353365396533313666643439643036
62666438656238626162666166326630643266396333643338396165653464633334363330323336
30346633356235636234303236383233363432646539393132326139363465633435333566393331
38626563663933623332383362653031653763663737323561333963316163643061363231376135
32656235386366343839356639363231386135653037393763646233663434326337393662653837
37366439306561323236393738663565343634313739326263356230623431393435393163643362
31386165623063376239386330636638353965623237333963393362376434396537353737653361
32636436313431373130636338613961643361643133616665363433386266363065306633306437
63666666633637306161346132323862653336373265363138633365653736663138633266626532
63373433623963303161383633343839336462633963356234333932643337643337666139313161
31333238366266646330623034343532373966396238346434343030613431666366316234363566
30386231623432653036653931653430643165313061353163326666326366306632343539666535
38323061303564623934356337333433633163386335346531313938303063656432663366613864
66343162363164656132383137363763353639613564323436383830393963396235656537633132
38356439333866646139646130356463396538316539373236366435316532306135623165313733
37313239396135646334386366636637363230643031633065376238313364656637303738633262
39333433396536393038353130393932373033356663663061656337646361353831303666303032
38303936643138666431366438613861653638646131303363356434643961373735656236366331
62316531663464373261616133363938643935636533326639616266323266346366643535363263
33623132373063663366363737326532656132306437373532666666366632636238613037666264
66366562306138353033316334383061396231343033643636353333343962613731373065373665
33666239393962313335383438313261373833653330336339376662663137323863623465353866
33366234306337633431303930326334343232356665303733376439643437386532363632363733
37333737633030303064336334313833653666363862343536333263336566383166366637623132
64313631346639633564373336633661646339636634613664366663346333613231333637643362
62313237343366383231656461633535383631653365666137363866653830353635333037653231
65613463326664363765356236373366636539393864326332613233336639663661346133656638
65386164666364343266343062626131303730363134643937313234353335373738383366386233
31336565633630643061653539383365653333343161626539643461656266383337623537383463
37396231643936353265633361356231616432346264313339326435633261613432383738316563
63626232633731656530626361336362313035336131313733333531376361396637656334316436
38323037373939666534386530623136363539333664346334663834353762353433656165346330
39633361653439323133303134376433643935346232636263623265363534613264363937366162
37623833616262653631376334363736363061346434366439623832626135306361316335666632
37396562303863303036386131363736363837323262663965323861363936356435306237306639
66306431613461383536343061313232396439303632336265363064393530333765633635636136
64616461653665313339633731373039666461666435313765616635356463373531623931326463
61386335636431336336623536316161353765653838363065393136373234313239383531323562
64303638383663663662326238623438663335366365656432353565373936633364326566313336
64306362356134353762363139383836333362313930663030633633313233636635623831663038
35633039383638343139616364663934353732616263373061666331633432323238653164303636
62376533353533323632393934613933633334306662363863633964343764616437666438613136
38373336303638386337316333376530396133333439653163666439643265303636373163383336
32633265306230306434646266316562373433616636303566663765356565376530373537656335
31386262303337633838393538303633383433656365643563363462303431353834643437616132
65373063383635666461636134396265393864336464326236363563323564336166623931326638
33376165376563303561393561313565343034333365643762373234336136636161356461333433
36326364363437643739393733353231393161313232633234353036663032336230626463303864
65343132383365623364663964643539613137396161343837613132623633663933643866393066
36616565313734346134386465656465396264373831346165643333663339303361663537653261
64626534626661306330663936383033653939306166386235366366353935363763303038653739
36303631383763333234653265333761623734643766656561666238336164666664653036366232
30666339633466383339393939663964646138623262363537346135303464623936356463323930
33626635353461336436393565626165303362343931333130633966303561356433393263623332
64333034306234343366623661303136333431323636346437356165613938386639306634346531
38363865326264356261396562393264623862396264666362353930326531623761343662343534
38636162353839363337346163316630383163383732386633373731626130316531396466326133
36396534396463623661646163643532646264326231616239376537643134343762363433663133
65376566333037363235643365326332623736613163663263326231336332363562633635326234
66373661646530346564373237353164613461626137396136303331343335663361316137636462
31666336663661623535666436376333646364666638646431643335393762363965613330626434
64366361306533636630663938353630336138303935666262373530666334626630303333333633
39613137646264353334316637333130356634323231633733326237373833626166636530626565
35306362393130366133333833353135353161613362353934346262646664623766333937303364
64653865303462666435363836366234316163326564613763366262366138623834306463663431
34363161346334366364326662356364383533343233333964636433373238396438653063373665
61643431393237336464653039383836643436316464663465303636613736646235613666623734
66633434346135313536346233316365393836363465313063336231386434626165373436616565
32313337353038663661393065663063633039626636373432663165646436306261373865353735
35653032386434336435336438303832663965653136303135336561373433313663393939363839
36663065306361636365323965373162383963663032316132616634333735343731636333363364
66653137386234366564323238643332333735373666333630663639643430623037623566626132
64376163386362303435316538623332653033643564356262336237343062333637313037653934
30646166316366616139313235623632393338663263303539393736353532386237656630623535
63366137326465643239373338623035326532623830303839613266363533336132303564376632
38373866623239353164636535636562393537626439346639356334303737666335656136643330
66303231626166613732643933346162616231303736386633613435303365653365336339356334
63326164666232333062323230303037303532323037613264636461633962333336613537346632
65653566346231616533306566363532323037366533663261653763333736323830343761306665
64356634393464653938653435356132663831656335623332623034333233363037393538326438
34333532316233393163353030646661333435613238663263373331633638346263646633646361
36363433353034353738616164623264333938383834646364663862353935663935646636643163
64643462343763363132316331363939363561633030626265663031333939383763326432383536
39313531313030313363373131353463366261383438316530333632623965393734636261353265
33613436633461383665303936353734616264336232643235393536313137353366393938653666
33343238653234376635343431353163626462623861333066613665356362633165333031656361
35623466343635386161346638303936613364396361623038666331633636313438626138633562
35376363616566346464313334386131666235626261313332633538303631346265396335353961
39643535326238383736393837336536313438376335373934383734323032306231613162613739
35353135386164393136666166643534393461396438616561383830326437653937353439333566
64656164653534343533353039613465666465666339323533633436353731653533363063353034
61356533303366663362323664303266626636393034653062646139303332363232623735643434
65373366343265383135613061366331613861316239336430306237356566663939653633373335
61343831376332633939383030323161616238313137356237643965386136623233373934326239
31363664643235396637333136313437623065633264303866313139326164626166343065316230
63373034386363636165663439373339613533646333633261656465313236373965663638376538
64313939663530363466666363653966663237333331663361393265323961326462356164363432
66643438353530396366333766333836326530316264393835653363353064663937353561343936
39313138333236393932616132646463376363366331383737333132643962656235626564613462
38333436353130653334656461613132306361346563653361383461663734386432346465346661
34383539353932316435336533653331613161363464613635323561353066363531323033616637
36306333393234393735633631626333663762313531343730333638353139633061383335646533
62303331633035353934353962316537643435343938333832376666333638363637666261326562
37356435656333383431663430313766623162333466636634373632356533346335396538666331
38663832356263643931633761613437383738363136373933306130663666633139643735376262
31336166306162363662326130303437653962373163373139363863376536326666396463313964
35333165383432303563333432633835346431326134386163343364353166613138346631633833
33393763636630386338646233656564646330383466326561333438373764626530306330303338
33363130363636393162363832336232366264353366343932356361343938333665303962363861
35363932663866393662323537333836376439333964306330626237393039396533373665343231
62393035363139643565393432353233366463653036363764383437616632336662313766323631
37363935376165653765393432393933666332333239666439393065663334653335633762373331
33396333383161646331333866396566376363663065303664623431663037393735353461633137
32353365333965383937653138643936383739313232396166646435353534376265333634393732
38333135336630373438653535623338386163376239666437623333306562653062336635333964
37323536613331653935653933353731303633613330626135333233663233613733323264636130
65646537306238636161333839313062326539303366663336356666333539363965363166626631
65636464386230613731343431666165393336613731316237343837316134613764656136636263
6135