Compare commits
4 Commits
devel
...
35bd74c55f
| Author | SHA1 | Date | |
|---|---|---|---|
| 35bd74c55f | |||
| 2faeeda22a | |||
| 82467adfef | |||
| 62bfaa7c49 |
@@ -1,9 +0,0 @@
|
||||
---
|
||||
skip_list:
|
||||
- line-length # don't yell about line length
|
||||
- meta-no-info # we don't publish to galaxy so stop yelling about it
|
||||
- package-latest # we install lots of latest stuff still 😢
|
||||
- experimental # no instability plz, give us a call when ur stable
|
||||
|
||||
warn_list:
|
||||
- no-handler # good to keep, but shouldn't be fatal
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,7 +5,3 @@ playbooks/testing.yml
|
||||
*.idea
|
||||
**/__pycache__/
|
||||
.venv/
|
||||
.ansible/
|
||||
.tox/
|
||||
.terraform/
|
||||
.terraform.lock.*
|
||||
|
||||
@@ -32,11 +32,3 @@ repos:
|
||||
- "--wrap=90"
|
||||
types:
|
||||
- markdown
|
||||
|
||||
- id: terraform
|
||||
name: terraform format
|
||||
entry: terraform
|
||||
language: system
|
||||
args:
|
||||
- fmt
|
||||
files: ".*\\.tf$"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
yaml-files:
|
||||
- "*.yml"
|
||||
- "*.yaml"
|
||||
|
||||
rules:
|
||||
line-length: disable
|
||||
9
Makefile
9
Makefile
@@ -1,9 +0,0 @@
|
||||
clean:
|
||||
rm --recursive --force .ansible/
|
||||
rm --recursive --force .tox/
|
||||
|
||||
dev:
|
||||
@poetry install --sync
|
||||
@poetry run pre-commit install
|
||||
@poetry run ansible-galaxy collection install --requirements-file ./requirements.yaml --collections-path ./.ansible
|
||||
@bash ./link-local-collections.sh
|
||||
14
README.md
14
README.md
@@ -2,17 +2,13 @@
|
||||
|
||||
Ansible configs for the Skylab Homelab
|
||||
|
||||
## Local workstation setup:
|
||||
Main entrypoint is through the `ansible` script in this repository. The script sets up
|
||||
basic environment variables to avoid conflicts with other environments and sets the
|
||||
inventory.
|
||||
|
||||
```bash
|
||||
make dev
|
||||
poetry run ansible-playbook ...
|
||||
```
|
||||
Bootstrap checklist:
|
||||
|
||||
## Boostraping remote system for management:
|
||||
|
||||
1. Install a supported operating system: [Rocky Linux](https://rockylinux.org),
|
||||
[Fedora](https://getfedora.org)
|
||||
1. Install a supported operating system: [Rocky Linux](https://rockylinux.org)
|
||||
2. During installation create a user named `ansible` with any password
|
||||
3. After installation copy SSH key to the `ansible` user
|
||||
4. Enable password-less sudo access for the `ansible` user with this command:
|
||||
|
||||
7
ansible
Executable file
7
ansible
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ANSIBLE_LIBRARY='' \
|
||||
ANSIBLE_FILTER_PLUGINS='' \
|
||||
ANSIBLE_CONFIG='' \
|
||||
ANSIBLE_INVENTORY=$(pwd)/inventory.yaml \
|
||||
"ansible-$1" ${@:2}
|
||||
@@ -1,10 +1,8 @@
|
||||
[defaults]
|
||||
host_key_checking = true
|
||||
collections_path = .ansible
|
||||
inventory = inventory/
|
||||
host_key_checking = false
|
||||
|
||||
[ssh_connection]
|
||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s"
|
||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes"
|
||||
|
||||
[inventory]
|
||||
enable_plugins = ansible.builtin.yaml
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
---
|
||||
workstation:
|
||||
hosts:
|
||||
voyager:
|
||||
skylab_description: Personal Workstation
|
||||
skylab_hostname: voyager.skylab.enp.one
|
||||
skylab_targets: [workstation]
|
||||
all:
|
||||
vars:
|
||||
skylab_state_dir: /var/lib/skylab
|
||||
skylab_ansible_venv: "{{ skylab_state_dir }}/ansible-runtime"
|
||||
skylab_pip_version: 19.3.1
|
||||
ansible_user: ansible
|
||||
ansible_ssh_common_args: "-o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes"
|
||||
|
||||
en1:
|
||||
vars:
|
||||
skylab_location: Newton MA
|
||||
skylab_dashboard: info.en1.local
|
||||
# gross hack for now, will be refactored later
|
||||
_skylab_adguard_nat_rule: 9
|
||||
_skylab_adguard_nat_rule: 8
|
||||
|
||||
hosts:
|
||||
core:
|
||||
@@ -58,14 +59,13 @@ en1:
|
||||
interface:
|
||||
access: bond0
|
||||
internal: bond0.99
|
||||
skylab_datastore_device: sdb
|
||||
skylab_networking:
|
||||
eno1:
|
||||
bond: bond0
|
||||
eno2:
|
||||
bond: bond0
|
||||
bond0:
|
||||
device: bond
|
||||
type: bond
|
||||
firewall: internal
|
||||
gateway: 10.42.101.1/24
|
||||
dns:
|
||||
@@ -75,7 +75,7 @@ en1:
|
||||
- 192.168.255.255/32
|
||||
dhcp: false
|
||||
bond0.99:
|
||||
device: vlan
|
||||
type: vlan
|
||||
firewall: trusted
|
||||
addresses:
|
||||
- 192.168.42.10/24
|
||||
@@ -101,7 +101,7 @@ en1:
|
||||
eno2:
|
||||
bond: bond0
|
||||
bond0:
|
||||
device: bond
|
||||
type: bond
|
||||
firewall: internal
|
||||
dhcp: false
|
||||
gateway: 10.42.101.1/24
|
||||
@@ -111,7 +111,7 @@ en1:
|
||||
dns:
|
||||
- 10.42.101.1
|
||||
bond0.99:
|
||||
device: vlan
|
||||
type: vlan
|
||||
firewall: trusted
|
||||
dhcp: false
|
||||
addresses:
|
||||
@@ -138,7 +138,7 @@ en1:
|
||||
eno2:
|
||||
bond: bond0
|
||||
bond0:
|
||||
device: bond
|
||||
type: bond
|
||||
firewall: internal
|
||||
gateway: 10.42.101.1/24
|
||||
dns:
|
||||
@@ -148,7 +148,7 @@ en1:
|
||||
- 192.168.255.255/32
|
||||
dhcp: false
|
||||
bond0.99:
|
||||
device: vlan
|
||||
type: vlan
|
||||
firewall: trusted
|
||||
addresses:
|
||||
- 192.168.42.30/24
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
en1:
|
||||
|
||||
vars:
|
||||
skylab_location: Cambridge
|
||||
|
||||
children:
|
||||
domain:
|
||||
children:
|
||||
|
||||
cluster:
|
||||
hosts:
|
||||
canaveral:
|
||||
ansible_host: 10.42.101.10
|
||||
skylab_description: Compute and Storage Node
|
||||
baikonur:
|
||||
ansible_host: 10.42.101.11
|
||||
skylab_description: Compute and Storage Node
|
||||
vandenberg:
|
||||
ansible_host: 10.42.101.12
|
||||
skylab_description: Compute and Storage Node
|
||||
andoya:
|
||||
ansible_host: 10.42.101.13
|
||||
skylab_description: Auxilary Compute Node
|
||||
jiuquan:
|
||||
ansible_host: 10.42.101.14
|
||||
skylab_description: Auxilary Compute Node
|
||||
|
||||
datastore:
|
||||
hosts:
|
||||
canaveral:
|
||||
skylab_datastore_block: /dev/sda
|
||||
baikonur:
|
||||
skylab_datastore_block: /dev/sda
|
||||
vandenberg:
|
||||
skylab_datastore_block: /dev/sda
|
||||
|
||||
hosts:
|
||||
3d-printer: {}
|
||||
mediastore: {}
|
||||
backstore: {}
|
||||
|
||||
local:
|
||||
hosts:
|
||||
core: {}
|
||||
switch-1: {}
|
||||
switch-2: {}
|
||||
wap-1: {}
|
||||
wap-2: {}
|
||||
wap-3: {}
|
||||
printer: {}
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
ansible_user: ansible
|
||||
|
||||
ansible_port: 4242
|
||||
|
||||
skylab_state_dir: /var/lib/skylab
|
||||
|
||||
skylab_ansible_venv: "{{ skylab_state_dir }}/ansible-runtime"
|
||||
|
||||
skylab_ansible_vault_password: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
61323762623165383963316238343539346336663864366631616339356564346636373561616237
|
||||
6666363531393234636337656431366365343236346536320a346163353935366636303131313661
|
||||
32623635363063383039363539303135393838376264356463646465376435616363376163373663
|
||||
6366633665373939380a373234633365376632376433643034336539346338613566353537663731
|
||||
34323464633165626133306464363464333539363761343831316565356266373833
|
||||
|
||||
skylab_tfstate_backend:
|
||||
hostname: cluster.lab.enp.one
|
||||
username: terraform
|
||||
schema: terraform
|
||||
port: 32421
|
||||
password: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
30313365393065316563323363663135313438616461356439366632303636343735653033363930
|
||||
6334613931376566363064663539643639326363663933610a306138616362376435386466306538
|
||||
30626330613932363339363438356430613461313335333536623931343436353330393433373630
|
||||
3631343463616631380a386661336534663033383637666538316665303962353034376232356235
|
||||
65323339353563623431666535366465353133343137653232326534326436323661636536373564
|
||||
3466633762303966366366653531613261336561356531636461
|
||||
|
||||
skylab_mgmt:
|
||||
sshport: 4242
|
||||
group: skylab
|
||||
user: ansible
|
||||
id: 1400
|
||||
sshkeys:
|
||||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5TGKururOa1Y+cbv8AWXYI5zhfZCDV0fsBG+33IYUc enpaul@ansible.voyager
|
||||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBf7i/8hSJDYnoD95noCJJVtSxxCp9N5EmnshALufiwm enpaul@ansible.opportunity
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PWD=$(pwd)
|
||||
ANSIBLE_NAMESPACE="skylab"
|
||||
ANSIBLE_COLLECTION_DIR="$PWD/.ansible/ansible_collections"
|
||||
|
||||
mkdir --parents "$ANSIBLE_COLLECTION_DIR/$ANSIBLE_NAMESPACE"
|
||||
|
||||
for collection_path in "$PWD"/"$ANSIBLE_NAMESPACE"/*; do
|
||||
collection=$(basename "$collection_path")
|
||||
if [[ ! -L "$ANSIBLE_COLLECTION_DIR/$ANSIBLE_NAMESPACE/$collection" ]]; then
|
||||
echo "Linking $ANSIBLE_NAMESPACE.$collection into $ANSIBLE_COLLECTION_DIR"
|
||||
rm --recursive --force "${ANSIBLE_COLLECTION_DIR:?}/$ANSIBLE_NAMESPACE/$collection"
|
||||
ln --symbolic "$PWD/$ANSIBLE_NAMESPACE/$collection" "$ANSIBLE_COLLECTION_DIR/$ANSIBLE_NAMESPACE/$collection"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Finished linking local collections"
|
||||
|
||||
LOCAL_COLLECTION_PATH=$(dirname "$ANSIBLE_COLLECTION_DIR")
|
||||
|
||||
if [ -z ${ANSIBLE_COLLECTIONS_PATH+x} ]; then
|
||||
echo "WARNING: Environment variable ANSIBLE_COLLECTIONS_PATH is not set, collections will not be callable"
|
||||
echo " HINT: export ANSIBLE_COLLECTIONS_PATH=$LOCAL_COLLECTION_PATH"
|
||||
elif [[ ${ANSIBLE_COLLECTIONS_PATH} != *"$LOCAL_COLLECTION_PATH"* ]]; then
|
||||
echo "WARNING: Environment variable ANSIBLE_COLLECTIONS_PATH does not include local collection directory"
|
||||
echo " HINT: export ANSIBLE_COLLECTIONS_PATH=\$ANSIBLE_COLLECTIONS_PATH:$LOCAL_COLLECTION_PATH"
|
||||
fi
|
||||
@@ -21,27 +21,20 @@
|
||||
hosts: linux:!workstation
|
||||
gather_facts: false
|
||||
roles:
|
||||
- role: skylab.core.server
|
||||
- role: server
|
||||
|
||||
|
||||
- name: Configure cluster
|
||||
hosts: linux:&cluster
|
||||
gather_facts: false
|
||||
roles:
|
||||
- role: skylab.core.datastore
|
||||
- role: skylab.core.swarm
|
||||
- role: datastore
|
||||
- role: swarm
|
||||
|
||||
|
||||
- name: Configure dashboard nodes
|
||||
hosts: iridium
|
||||
gather_facts: false
|
||||
roles:
|
||||
- role: skylab.core.dashboard
|
||||
- role: dashboard
|
||||
dashboard_hostname: "{{ skylab_dashboard }}"
|
||||
|
||||
|
||||
- name: Configure workstations
|
||||
hosts: workstation
|
||||
gather_facts: false
|
||||
roles:
|
||||
- role: skylab.core.workstation
|
||||
@@ -10,8 +10,6 @@
|
||||
- name: Clean up old orechestration data
|
||||
hosts: cluster
|
||||
gather_facts: false
|
||||
tags:
|
||||
- cleanup
|
||||
vars_files:
|
||||
- vars/services.yaml
|
||||
- vars/access.yaml
|
||||
@@ -55,19 +53,6 @@
|
||||
loop_control:
|
||||
label: "{{ item.Name }}"
|
||||
|
||||
- name: Fetch existing Nginx configs
|
||||
ansible.builtin.command:
|
||||
cmd: ls {{ local_datastore_mount }}/appdata/nginx/conf.d/
|
||||
changed_when: false
|
||||
register: _nginx_configs
|
||||
|
||||
- name: Remove legacy nginx configs
|
||||
when: item.replace('.conf', '') not in skylab_services
|
||||
ansible.builtin.file:
|
||||
path: "{{ local_datastore_mount }}/appdata/nginx/conf.d/{{ item }}.conf"
|
||||
state: absent
|
||||
loop: "{{ _nginx_configs.stdout_lines }}"
|
||||
|
||||
|
||||
- name: Deploy stack service{{ (' ' + service) if service is defined else 's' }}
|
||||
hosts: cluster
|
||||
@@ -98,15 +83,6 @@
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Create compose directory
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ skylab_compose_dir }}"
|
||||
state: directory
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ skylab_group_admin.name }}"
|
||||
mode: 0770
|
||||
|
||||
- name: Install compose file
|
||||
vars:
|
||||
app: "{{ item.value }}"
|
||||
@@ -148,53 +124,22 @@
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: Configure datastore directories
|
||||
run_once: true
|
||||
block:
|
||||
- name: Determine volume directories
|
||||
vars:
|
||||
_stack_volume_directories: []
|
||||
when: item.value.volumes is defined
|
||||
ansible.builtin.set_fact:
|
||||
_stack_volume_directories: "{{ _stack_volume_directories + [{'user': (item.value.user | default(ansible_user)), 'volumes': (item.value.volumes.values() | list)}] }}"
|
||||
loop: "{{ _services | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: Create service directories
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ local_datastore_mount }}{{ item.1 }}"
|
||||
state: directory
|
||||
owner: "{{ item.0.user }}"
|
||||
group: "{{ skylab_group_admin.name }}"
|
||||
mode: 0770
|
||||
loop: "{{ _stack_volume_directories | subelements('volumes') }}"
|
||||
|
||||
- name: Deploy stack
|
||||
- name: Determine volume directories
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ skylab_ansible_venv }}/bin/python"
|
||||
community.docker.docker_stack:
|
||||
name: "{{ item.key }}"
|
||||
compose:
|
||||
- "{{ skylab_compose_dir }}/{{ item.key }}.yaml"
|
||||
prune: false
|
||||
state: present
|
||||
_stack_volume_directories: []
|
||||
when: item.value.volumes is defined
|
||||
ansible.builtin.set_fact:
|
||||
_stack_volume_directories: "{{ _stack_volume_directories + [{'user': (item.value.user | default(ansible_user)), 'volumes': (item.value.volumes.values() | list)}] }}"
|
||||
loop: "{{ _services | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: Configure reverse proxy
|
||||
run_once: true
|
||||
block:
|
||||
- name: Create nginx config
|
||||
when: item.value.domain is defined
|
||||
ansible.builtin.template:
|
||||
src: stack-nginx.conf.j2
|
||||
dest: "{{ local_datastore_mount }}/appdata/nginx/conf.d/{{ item.key }}.conf"
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ skylab_group_admin.name }}"
|
||||
mode: 0464
|
||||
loop: "{{ _services | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.value.domain | default(item.key) }}"
|
||||
- name: Create service directories
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ local_datastore_mount }}{{ item.1 }}"
|
||||
state: directory
|
||||
owner: "{{ item.0.user }}"
|
||||
group: "{{ skylab_group_admin.name }}"
|
||||
mode: 0770
|
||||
loop: "{{ _stack_volume_directories | subelements('volumes') }}"
|
||||
1
playbooks/files
Symbolic link
1
playbooks/files
Symbolic link
@@ -0,0 +1 @@
|
||||
../resources
|
||||
@@ -2,9 +2,6 @@
|
||||
- name: Check cluster state
|
||||
hosts: cluster
|
||||
any_errors_fatal: true
|
||||
pre_tasks:
|
||||
- name: Configure remot execution environment
|
||||
ansible.builtin.import_tasks: tasks/meta/bootstrap-remote-env.yaml
|
||||
tasks:
|
||||
- name: Validate user input
|
||||
run_once: true
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- ansible.builtin.import_playbook: skylab.core.node_down
|
||||
- ansible.builtin.import_playbook: node-down.yaml
|
||||
|
||||
- name: Shutdown node
|
||||
hosts: "{{ node }}"
|
||||
@@ -5,11 +5,8 @@
|
||||
- name: skylab_datastore_encryption_password
|
||||
prompt: Enter datastore block decryption password
|
||||
private: true
|
||||
pre_tasks:
|
||||
- name: Configure remote execution environment
|
||||
ansible.builtin.import_tasks: tasks/meta/bootstrap-remote-env.yaml
|
||||
roles:
|
||||
- role: skylab.core.datastore
|
||||
- role: datastore
|
||||
tasks:
|
||||
- name: Fetch node swarm ID
|
||||
ansible.builtin.command:
|
||||
@@ -27,12 +24,12 @@
|
||||
- name: Determine node addresses
|
||||
vars:
|
||||
_node_addresses:
|
||||
- "{{ (lookup('vars', 'ansible_' + skylab_cluster.interface.access).ipv4.address + '/' + lookup('vars', 'ansible_' + skylab_cluster.interface.access).ipv4.netmask) | ansible.netcommon.ipaddr('host/prefix') }}"
|
||||
- "{{ lookup('vars', 'ansible_' + skylab_cluster.interface.access).ipv4.address | ansible.netcommon.ipaddr('host/prefix') }}"
|
||||
ansible.builtin.set_fact:
|
||||
_node_addresses: "{{ _node_addresses + [(item.address + '/' + item.netmask) | ansible.netcommon.ipaddr('host/prefix')] }}"
|
||||
_node_addresses: "{{ _node_addresses + [item.address | ansible.netcommon.ipaddr('host/prefix')] }}"
|
||||
loop: "{{ lookup('vars', 'ansible_' + skylab_cluster.interface.access).ipv4_secondaries }}"
|
||||
loop_control:
|
||||
label: "{{ (item.address + '/' + item.netmask) | ansible.netcommon.ipaddr('host/prefix') }}"
|
||||
label: "{{ item.address }}"
|
||||
|
||||
- name: Determine cluster access addresses
|
||||
run_once: true
|
||||
@@ -50,7 +50,9 @@
|
||||
key: https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }}
|
||||
|
||||
|
||||
- import_playbook: skylab.core.update
|
||||
|
||||
|
||||
- import_playbook: skylab.core.configure
|
||||
- import_playbook: update.yaml
|
||||
|
||||
|
||||
- import_playbook: configure.yaml
|
||||
1
playbooks/roles
Symbolic link
1
playbooks/roles
Symbolic link
@@ -0,0 +1 @@
|
||||
../roles
|
||||
1
playbooks/tasks
Symbolic link
1
playbooks/tasks
Symbolic link
@@ -0,0 +1 @@
|
||||
../tasks
|
||||
1
playbooks/templates
Symbolic link
1
playbooks/templates
Symbolic link
@@ -0,0 +1 @@
|
||||
../resources
|
||||
@@ -24,7 +24,7 @@
|
||||
- vars/packages.yaml
|
||||
tasks:
|
||||
- name: Update system packages via DNF
|
||||
when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora"
|
||||
when: ansible_distribution == "Rocky"
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
name: "*"
|
||||
@@ -39,7 +39,7 @@
|
||||
group: "{{ ansible_user }}"
|
||||
mode: 0644
|
||||
|
||||
- name: Install universal packages on Rocky
|
||||
- name: Install universal packages
|
||||
when: ansible_distribution == "Rocky"
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
@@ -47,14 +47,6 @@
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Install universal packages on Fedora
|
||||
when: ansible_distribution == "Fedora"
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
name: "{{ skylab_packages_global + skylab_packages_fedora }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
|
||||
- name: Update unix accounts
|
||||
hosts: linux
|
||||
@@ -140,7 +132,7 @@
|
||||
ansible.builtin.set_fact:
|
||||
_determined_member_groups: "{{ _determined_member_groups | default({}) | combine({item.name: [
|
||||
skylab_group.name,
|
||||
'wheel' if (item.admin | default(false) and ansible_os_family == 'RedHat') else '',
|
||||
'wheel' if (item.admin | default(false) and ansible_distribution == 'Rocky') else '',
|
||||
'sudo' if (item.admin | default(false) and ansible_os_family == 'Debian') else '',
|
||||
skylab_group_admin.name if item.admin | default(false) else '',
|
||||
skylab_group_automation.name if item.service | default(false) else '',
|
||||
@@ -159,11 +151,7 @@
|
||||
groups: "{{ _determined_member_groups[item.name] }}"
|
||||
comment: "{{ item.fullname | default('') }}"
|
||||
system: "{{ item.service | default(false) }}"
|
||||
generate_ssh_key: true
|
||||
ssh_key_bits: 4096
|
||||
ssh_key_passphrase: "{{ item.password }}"
|
||||
ssh_key_comment: "{{ item.name }}@{{ inventory_hostname }}"
|
||||
ssh_key_type: ed25519
|
||||
generate_ssh_key: false
|
||||
password: "{{ item.password }}"
|
||||
loop: "{{ _active_accounts }}"
|
||||
loop_control:
|
||||
1
playbooks/vars
Symbolic link
1
playbooks/vars
Symbolic link
@@ -0,0 +1 @@
|
||||
../vars/
|
||||
2620
poetry.lock
generated
2620
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -6,22 +6,22 @@ authors = ["Ethan Paul <me@enp.one>"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
ansible-core = "^2.14.3"
|
||||
docker = "^6.0.1"
|
||||
python = "^3.8"
|
||||
ansible = "^3.4.0"
|
||||
docker = "^4.2.0"
|
||||
docker-compose = "^1.25.4"
|
||||
paramiko = "^2.7.1"
|
||||
jsondiff = "^2.0.0"
|
||||
jsondiff = "^1.2.0"
|
||||
netaddr = "^0.8.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
ansible-lint = {version = "^6.14.0", markers = "platform_system != 'Windows'"}
|
||||
ipython = "^8.11.0"
|
||||
mdformat = "^0.7.16"
|
||||
mdformat-gfm = "^0.3.5"
|
||||
poetry = "^1.3.0"
|
||||
pre-commit = "^3.2.0"
|
||||
pre-commit-hooks = "^4.4.0"
|
||||
safety = "^2.3.5"
|
||||
ansible-lint = "^4.2.0"
|
||||
pre-commit = "^2.9.2"
|
||||
pre-commit-hooks = "^3.3.0"
|
||||
safety = "^1.9.0"
|
||||
tox = "^3.20.1"
|
||||
tox-poetry-installer = {extras = ["poetry"], version = "^0.10.0"}
|
||||
yamllint = "^1.29.0"
|
||||
tox-poetry-installer = "^0.8.1"
|
||||
yamllint = "^1.20.0"
|
||||
mdformat = "^0.7.9"
|
||||
mdformat-gfm = "^0.3.3"
|
||||
ipython = "^7.28.0"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
collections:
|
||||
- source: ./skylab/
|
||||
type: subdirs
|
||||
@@ -7,11 +7,11 @@ x-global-env: &globalenv
|
||||
LOCAL_GID: "{{ _app_account.uid }}"
|
||||
ASPNETCORE_ENVIRONMENT: Production
|
||||
globalSettings__selfHosted: "true"
|
||||
globalSettings__baseServiceUri__vault: https://{{ app.publish.domain }}
|
||||
globalSettings__baseServiceUri__api: https://{{ app.publish.domain }}/api
|
||||
globalSettings__baseServiceUri__identity: https://{{ app.publish.domain }}/identity
|
||||
globalSettings__baseServiceUri__admin: https://{{ app.publish.domain }}/admin
|
||||
globalSettings__baseServiceUri__notifications: https://{{ app.publish.domain }}/notifications
|
||||
globalSettings__baseServiceUri__vault: https://{{ app.domain }}
|
||||
globalSettings__baseServiceUri__api: https://{{ app.domain }}/api
|
||||
globalSettings__baseServiceUri__identity: https://{{ app.domain }}/identity
|
||||
globalSettings__baseServiceUri__admin: https://{{ app.domain }}/admin
|
||||
globalSettings__baseServiceUri__notifications: https://{{ app.domain }}/notifications
|
||||
globalSettings__baseServiceUri__internalNotifications: http://bitwarden_notifications:5000
|
||||
globalSettings__baseServiceUri__internalAdmin: http://bitwarden_admin:5000
|
||||
globalSettings__baseServiceUri__internalIdentity: http://bitwarden_identity:5000
|
||||
@@ -22,7 +22,7 @@ x-global-env: &globalenv
|
||||
globalSettings__sqlServer__connectionString: "Data Source=tcp:mssql,1433;Initial Catalog=vault;Persist Security Info=False;User ID=sa;Password=e934c0bb-3b5a-4e6b-b525-cd6d83004e1a;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=True;TrustServerCertificate=True"
|
||||
globalSettings__identityServer__certificatePassword: {{ app.settings.certificatePassword }}
|
||||
globalSettings__attachment__baseDirectory: /etc/bitwarden/core/attachments
|
||||
globalSettings__attachment__baseUrl: https://{{ app.publish.domain }}/attachments
|
||||
globalSettings__attachment__baseUrl: https://{{ app.domain }}/attachments
|
||||
globalSettings__dataProtection__directory: /etc/bitwarden/core/aspnet-dataprotection
|
||||
globalSettings__logDirectory: /etc/bitwarden/logs
|
||||
globalSettings__licenseDirectory: /etc/bitwarden/core/licenses
|
||||
@@ -45,7 +45,7 @@ services:
|
||||
USER_GID: "{{ _app_account.uid }}"
|
||||
APP_NAME: ENP Version Control System
|
||||
RUN_MODE: prod
|
||||
ROOT_URL: https://{{ app.publish.domain }}/
|
||||
ROOT_URL: https://{{ app.domain }}/
|
||||
DB_TYPE: sqlite3
|
||||
DISABLE_REGISTRATION: "true"
|
||||
deploy:
|
||||
@@ -76,24 +76,3 @@ services:
|
||||
restart_policy:
|
||||
condition: any
|
||||
delay: 24h
|
||||
|
||||
backup:
|
||||
image: rockylinux:latest
|
||||
hostname: backup
|
||||
command: bash /datastore/backup/mkbkup.sh /datastore/
|
||||
networks:
|
||||
- meta
|
||||
volumes:
|
||||
- type: volume
|
||||
source: meta-backup
|
||||
target: /datastore/backup
|
||||
read_only: false
|
||||
- type: volume
|
||||
source: meta-appdata
|
||||
target: /datastore/appdata
|
||||
read_only: true
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: any
|
||||
delay: 24h
|
||||
@@ -103,6 +103,6 @@ services:
|
||||
- cache
|
||||
- proxy
|
||||
environment:
|
||||
VIKUNJA_API_URL: https://{{ app.publish.domain }}/api/v1
|
||||
VIKUNJA_API_URL: https://{{ app.domain }}/api/v1
|
||||
deploy:
|
||||
replicas: 1
|
||||
@@ -5,9 +5,8 @@ function _parse_git_branch() {
|
||||
export PS1="\[\e[0;97m\]\[\e[37m\e[1m\]\u\[\e[1;94m\]@\[\e[94m\]\H\[\e[37m\]:\w\[\e[33m\]\[\e[0;33m\]\$(_parse_git_branch) \[\e[37m\]\[\e[0;97m\]$\[\e[0m\] "
|
||||
export rc=/home/$USERNAME/.bashrc
|
||||
export VIRTUALENV_DIR=/home/$USERNAME/.venvs
|
||||
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt
|
||||
|
||||
function random() {
|
||||
random() {
|
||||
if [[ $# -eq 0 ]]; then
|
||||
num=32
|
||||
else
|
||||
@@ -20,10 +19,9 @@ function up() { cd $(eval printf '../'%.0s {1..$1}); }
|
||||
|
||||
function pipin() { pip freeze | grep $1; }
|
||||
|
||||
function continuous () { while true; do ${@}; sleep 3; done; }
|
||||
|
||||
alias bk='cd -'
|
||||
alias fuck='sudo $(history -p \!\!)'
|
||||
alias ls='ls -lshF --color --group-directories-first --time-style=long-iso'
|
||||
alias version='uname -orp && lsb_release -a | grep Description'
|
||||
alias activate='source ./bin/activate'
|
||||
alias cls='clear'
|
||||
@@ -34,4 +32,3 @@ alias whatismyip='curl https://icanhazip.com/'
|
||||
alias uuid="python3 -c 'import uuid; print(uuid.uuid4());'"
|
||||
alias epoch="python3 -c 'import time; print(time.time());'"
|
||||
alias uptime="command uptime --pretty"
|
||||
alias unmount="umount"
|
||||
@@ -29,7 +29,6 @@
|
||||
listen_addr: "{{ lookup('vars', 'ansible_' + skylab_cluster.interface.internal).ipv4.address }}"
|
||||
remote_addrs: "{{ _docker_swarm_manager_addresses }}"
|
||||
join_token: "{{ _docker_swarm_join_token.stdout.strip() }}"
|
||||
timeout: 1200
|
||||
|
||||
- name: Fetch node swarm ID
|
||||
ansible.builtin.command:
|
||||
@@ -1,3 +0,0 @@
|
||||
# Ansible Collection - skylab.core
|
||||
|
||||
Documentation for the collection.
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
namespace: skylab
|
||||
name: core
|
||||
version: 0.0.0
|
||||
description: Network deployment procedures and configuration state management
|
||||
authors:
|
||||
- Ethan Paul <me@enp.one>
|
||||
license:
|
||||
- MIT
|
||||
readme: README.md
|
||||
tags: []
|
||||
repository: https://vcs.enp.one/skylab/skylab-ansible/
|
||||
build_ignore: []
|
||||
|
||||
# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
|
||||
# collection label 'namespace.name'. The value is a version range
|
||||
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
|
||||
# range specifiers can be set and are separated by ','
|
||||
dependencies:
|
||||
ansible.netcommon: ">=2.5.0,<3.0.0"
|
||||
ansible.posix: ">=1.3.0,<2.0.0"
|
||||
ansible.utils: ">=2.4.3,<3.0.0"
|
||||
community.docker: ">=2.0.2,<3.0.0"
|
||||
community.network: ">=3.0.0,<4.0.0"
|
||||
community.general: ">=4.1.0,<5.0.0"
|
||||
community.crypto: ">=1.0.0,<2.0.0"
|
||||
@@ -1,2 +0,0 @@
|
||||
---
|
||||
requires_ansible: ">=2.11,<2.15"
|
||||
@@ -1,137 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
declare FMT_RESET
|
||||
declare FMT_BOLD
|
||||
declare FMT_GREEN
|
||||
declare FMT_RED
|
||||
declare NL
|
||||
FMT_RESET=$(printf "\\e[0m")
|
||||
FMT_BOLD=$(printf "\\e[1m")
|
||||
FMT_GREEN=$(printf "\\e[32m")
|
||||
FMT_RED=$(printf "\\e[31m")
|
||||
NL=$'\n'
|
||||
readonly FMT_RESET
|
||||
readonly FMT_BOLD
|
||||
readonly FMT_GREEN
|
||||
readonly FMT_RED
|
||||
readonly NL
|
||||
|
||||
|
||||
function usage() {
|
||||
cat << __EOF__
|
||||
${FMT_GREEN}$(basename "$0")${FMT_RESET}: \
|
||||
|
||||
Ping hosts and print status
|
||||
|
||||
${FMT_BOLD}Usage:${FMT_RESET}
|
||||
$(basename "$0") [-h] [--service|--network]
|
||||
|
||||
${FMT_GREEN}-h --help${FMT_RESET}
|
||||
Print this message and exit.
|
||||
|
||||
${FMT_GREEN}--services${FMT_RESET}
|
||||
Report service status
|
||||
|
||||
${FMT_GREEN}--network${FMT_RESET}
|
||||
Report network status
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
function _fmt_online() { echo "${FMT_BOLD}${FMT_GREEN}ONLINE${FMT_RESET}"; }
|
||||
|
||||
function _fmt_offline() { echo "${FMT_BOLD}${FMT_RED}OFFLINE${FMT_RESET}"; }
|
||||
|
||||
function _test_cmd() { if eval "$1" &>/dev/null ; then echo "${2}~$(_fmt_online)"; else echo "${2}~$(_fmt_offline)"; fi }
|
||||
|
||||
function _test_ping() { _test_cmd "ping -W 2 -c 1 ${1}" "${2}"; }
|
||||
|
||||
function _test_curl_head() { _test_cmd "curl --fail --head ${1}" "${2}"; }
|
||||
|
||||
function _test_curl_get() { _test_cmd "curl --fail --get ${1}" "${2}"; }
|
||||
|
||||
function _test_curl_insecure() { _test_cmd "curl --fail --head --insecure ${1}" "${2}"; }
|
||||
|
||||
function _test_netcat() { _test_cmd "nc -z ${1} ${2}" "${3}"; }
|
||||
|
||||
function network() {
|
||||
local uplink_address="1.1.1.1"
|
||||
|
||||
declare -a infra=("core.en1.local" "switch.en1.local" "wap-1.en1.local" "wap-2.en1.local" "wap-3.en1.local" "printer.en1.local")
|
||||
declare -a infra_names=("Core Router" "Core Switch" "Wireless AP 1" "Wireless AP 2" "Wireless AP 3" "Printer")
|
||||
|
||||
declare -a lab=("cluster.skylab.enp.one" "pegasus.skylab.enp.one" "saturn.skylab.enp.one" "orion.skylab.enp.one" "iridium.skylab.enp.one" "en2.enp.one")
|
||||
declare -a lab_names=("Cluster" "Pegasus" "Saturn" "Orion" "Iridium" "Hubble")
|
||||
|
||||
local output=$(_test_ping "$uplink_address" "UPLINK")
|
||||
output+="${NL}";
|
||||
|
||||
output+="${NL}INFRASTRUCTURE~STATE${NL}"
|
||||
for (( index=0; index<"${#infra[@]}"; index++ )); do
|
||||
output+=$(_test_ping "${infra[$index]}" "${infra_names[$index]}")
|
||||
output+="${NL}"
|
||||
done
|
||||
|
||||
output+="${NL}HOMELAB~STATE${NL}"
|
||||
for (( index=0; index<"${#lab[@]}"; index++ )); do
|
||||
output+=$(_test_ping "${lab[$index]}" "${lab_names[$index]}")
|
||||
output+="${NL}"
|
||||
done
|
||||
|
||||
column -e -t -s '~' <<<"$output"
|
||||
}
|
||||
|
||||
function services() {
|
||||
local output="INTERNAL~STATE${NL}"
|
||||
|
||||
output+=$(_test_netcat "cluster.skylab.enp.one" "53" "AdGuard DNS")
|
||||
output+="${NL}"
|
||||
output+=$(_test_netcat "core.en1.local" "53" "Fallback DNS")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_insecure "https://cluster.skylab.enp.one:8443/status" "Ubiquiti WLC")
|
||||
output+="${NL}"
|
||||
|
||||
output+="${NL}PUBLIC~STATE${NL}"
|
||||
|
||||
output+=$(_test_curl_head "https://pms.enp.one/web/index.html" "Plex Media Server")
|
||||
output+="${NL}"
|
||||
output+=$(_test_netcat "cluster.skylab.enp.one" "25565" "Minecraft Server")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_get "https://vcs.enp.one/api/v1/version" "Version Control")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_get "https://ssv.enp.one/api/alive" "Bitwarden")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_head "https://cdn.enp.one/heartbeat" "Digital Ocean CDN")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_head "https://doc.enp.one/" "Documentation")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_head "https://enpaul.net/" "enpaul.net")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_head "https://allaroundhere.org/" "allaroundhere.org")
|
||||
output+="${NL}"
|
||||
output+=$(_test_curl_head "https://enp.one/" "enp.one")
|
||||
output+="${NL}"
|
||||
|
||||
column -e -t -s'~' <<<"$output"
|
||||
}
|
||||
|
||||
function main() {
|
||||
if [[ "$1" =~ ^(-h|--help)$ ]]; then
|
||||
usage;
|
||||
return 0
|
||||
fi
|
||||
if [[ "$1" = "--network" ]]; then
|
||||
network;
|
||||
return 0
|
||||
fi
|
||||
if [[ "$1" = "--services" ]]; then
|
||||
services;
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
||||
main "${@}"
|
||||
fi
|
||||
@@ -1,113 +0,0 @@
|
||||
---
|
||||
version: '3.7'
|
||||
|
||||
volumes:
|
||||
photoprism-database:
|
||||
name: datastore/appdata/photoprism/database
|
||||
driver: glusterfs
|
||||
photoprism-metadata:
|
||||
name: datastore/appdata/photoprism/metadata
|
||||
photoprism-originals:
|
||||
name: datastore/media/photoprism
|
||||
driver: glusterfs
|
||||
photoprism-import:
|
||||
name: datastore/media/upload
|
||||
driver: glusterfs
|
||||
|
||||
networks:
|
||||
photoprism:
|
||||
internal: true
|
||||
name: photoprism
|
||||
driver: overlay
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 192.168.109.0/24
|
||||
|
||||
services:
|
||||
app:
|
||||
image: photoprism/photoprism:latest
|
||||
hostname: app
|
||||
depends_on:
|
||||
- database
|
||||
networks:
|
||||
- photoprism
|
||||
ports:
|
||||
- published: 2342
|
||||
target: 2342
|
||||
protocol: tcp
|
||||
mode: ingress
|
||||
environment:
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "gm2auW34GNawZ8Dqiub8W8vOlvsHCnfj"
|
||||
PHOTOPRISM_SITE_URL: "http://cluster.skylab.enp.one:2342/"
|
||||
PHOTOPRISM_ORIGINALS_LIMIT: 5000
|
||||
PHOTOPRISM_HTTP_COMPRESSION: "gzip"
|
||||
PHOTOPRISM_DEBUG: "false"
|
||||
PHOTOPRISM_PUBLIC: "false"
|
||||
PHOTOPRISM_READONLY: "false"
|
||||
PHOTOPRISM_EXPERIMENTAL: "false"
|
||||
PHOTOPRISM_DISABLE_CHOWN: "false"
|
||||
PHOTOPRISM_DISABLE_WEBDAV: "false"
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false"
|
||||
PHOTOPRISM_DISABLE_TENSORFLOW: "false"
|
||||
PHOTOPRISM_DISABLE_FACES: "false"
|
||||
PHOTOPRISM_DISABLE_CLASSIFICATION: "false"
|
||||
PHOTOPRISM_DARKTABLE_PRESETS: "false"
|
||||
PHOTOPRISM_DETECT_NSFW: "false"
|
||||
PHOTOPRISM_UPLOAD_NSFW: "true"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql"
|
||||
PHOTOPRISM_DATABASE_SERVER: "database:3306"
|
||||
PHOTOPRISM_DATABASE_NAME: "photoprism"
|
||||
PHOTOPRISM_DATABASE_USER: "photoprism"
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "KcIKhME9OwWKVz4tGyqI4VXzyDBs33Xp" # MariaDB or MySQL database user password
|
||||
PHOTOPRISM_SITE_TITLE: "Skylab Images"
|
||||
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||
PHOTOPRISM_SITE_AUTHOR: "EN Paul"
|
||||
HOME: "/photoprism"
|
||||
PHOTOPRISM_UID: 1408
|
||||
PHOTOPRISM_GID: 1408
|
||||
## Hardware video transcoding config (optional)
|
||||
# PHOTOPRISM_FFMPEG_BUFFERS: "64" # FFmpeg capture buffers (default: 32)
|
||||
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
|
||||
# PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m" # Use Video4Linux for AVC transcoding (default: libx264)
|
||||
# PHOTOPRISM_FFMPEG_ENCODER: "h264_qsv" # Use Intel Quick Sync Video for AVC transcoding (default: libx264)
|
||||
# PHOTOPRISM_INIT: "intel-graphics tensorflow-amd64-avx2" # Enable TensorFlow AVX2 & Intel Graphics support
|
||||
## Enable TensorFlow AVX2 support for modern Intel CPUs (requires starting the container as root)
|
||||
# PHOTOPRISM_INIT: "tensorflow-amd64-avx2"
|
||||
user: "1408:1408"
|
||||
working_dir: "/photoprism"
|
||||
volumes:
|
||||
- type: volume
|
||||
source: photoprism-originals
|
||||
target: /photoprism/originals
|
||||
read_only: false
|
||||
- type: volume
|
||||
source: photoprism-metadata
|
||||
target: /photoprism/storage
|
||||
read_only: false
|
||||
- type: volume
|
||||
source: photoprism-import
|
||||
target: /photoprism/import
|
||||
read_only: true
|
||||
deploy:
|
||||
replicas: 1
|
||||
|
||||
database:
|
||||
image: mariadb:10.6
|
||||
hostname: database
|
||||
command: mysqld --innodb-buffer-pool-size=128M --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
|
||||
networks:
|
||||
- photoprism
|
||||
volumes:
|
||||
- type: volume
|
||||
source: photoprism-database
|
||||
target: /var/lib/mysql
|
||||
read_only: false
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: insecure
|
||||
MYSQL_DATABASE: photoprism
|
||||
MYSQL_USER: photoprism
|
||||
MYSQL_PASSWORD: KcIKhME9OwWKVz4tGyqI4VXzyDBs33Xp
|
||||
deploy:
|
||||
replicas: 1
|
||||
@@ -1,34 +0,0 @@
|
||||
# Ansible managed file - do not manually edit
|
||||
#
|
||||
server {
|
||||
server_name {{ app.publish.domain }};
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location / {
|
||||
proxy_pass http://dockerloopback:{{ app.publish.http }}/;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
listen 443 ssl;
|
||||
ssl_certificate /etc/letsencrypt/live/{{ app.publish.domain }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/{{ app.publish.domain }}/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{ app.publish.domain }};
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
proxy_pass http://dockerloopback:8088/.well-known/acme-challenge/;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# EOF
|
||||
@@ -1,2 +0,0 @@
|
||||
[org/gnome/login-screen]
|
||||
disable-user-list=true
|
||||
@@ -1,2 +0,0 @@
|
||||
[org/gnome/mutter]
|
||||
experimental-features=['scale-monitor-framebuffer']
|
||||
@@ -1,47 +0,0 @@
|
||||
if [ -f `which powerline-daemon` ]; then
|
||||
powerline-daemon -q
|
||||
POWERLINE_BASH_CONTINUATION=1
|
||||
POWERLINE_BASH_SELECT=1
|
||||
. /usr/share/powerline/bash/powerline.sh
|
||||
fi
|
||||
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
export PROJECTS_DIR="$HOME/projects"
|
||||
|
||||
function gg() {
|
||||
cd "$PROJECTS_DIR/$1";
|
||||
if [ -f "$PROJECTS_DIR/$1/ansible.cfg" ]; then
|
||||
ANSIBLE_CONFIG="$PROJECTS_DIR/$1/ansible.cfg" ANSIBLE_COLLECTIONS_PATH="$PROJECTS_DIR/$1/.ansible" poetry shell;
|
||||
elif [ -f "$PROJECTS_DIR/$1/pyproject.toml" ]; then
|
||||
poetry shell;
|
||||
fi
|
||||
}
|
||||
|
||||
mpw() {
|
||||
_copy() {
|
||||
if hash pbcopy 2>/dev/null; then
|
||||
pbcopy
|
||||
elif hash xclip 2>/dev/null; then
|
||||
xclip -selection clip
|
||||
else
|
||||
cat; echo 2>/dev/null
|
||||
return
|
||||
fi
|
||||
echo >&2 "Copied!"
|
||||
}
|
||||
|
||||
# Empty the clipboard
|
||||
:| _copy 2>/dev/null
|
||||
|
||||
# Ask for the user's name and password if not yet known.
|
||||
MPW_FULLNAME="Ethan Paul"
|
||||
|
||||
# Start Master Password and copy the output.
|
||||
printf %s "$(MPW_FULLNAME=$MPW_FULLNAME command mpw "$@")" | _copy
|
||||
}
|
||||
|
||||
alias explorer='nautilus'
|
||||
alias doc='cd ~/Documents'
|
||||
alias dn='cd ~/Downloads'
|
||||
alias prun="poetry run"
|
||||
alias psync="poetry install --remove-untracked"
|
||||
@@ -1,3 +0,0 @@
|
||||
user-db:user
|
||||
system-db:gdm
|
||||
file-db:/usr/share/gdm/greeter-dconf-defaults
|
||||
@@ -1,2 +0,0 @@
|
||||
user-db:user
|
||||
system-db:local
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 42 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 664 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 243 KiB |
@@ -1,6 +0,0 @@
|
||||
---
|
||||
- name: dconf-update
|
||||
become: true
|
||||
changed_when: true
|
||||
ansible.builtin.command:
|
||||
cmd: dconf update
|
||||
@@ -1,144 +0,0 @@
|
||||
---
|
||||
- name: Install user bashrc
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: bashrc.sh
|
||||
dest: ~{{ item }}/.bashrc_ansible
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ item }}"
|
||||
mode: 0644
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Configure user bashrc loading
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: ~{{ item }}/.bashrc
|
||||
line: source ~/.bashrc_ansible
|
||||
state: present
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Configure local bash completions loading
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: ~{{ item }}/.bashrc
|
||||
line: source ~/.config/bash_completions
|
||||
state: present
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Configure bash completions
|
||||
become: true
|
||||
ansible.builtin.blockinfile:
|
||||
path: ~{{ item }}/.config/bash_completions
|
||||
create: true
|
||||
block: >-
|
||||
function _gg_completion() {
|
||||
local cur=${COMP_WORDS[COMP_CWORD]};
|
||||
COMPREPLY=( $(compgen -W "$(command ls $PROJECTS_DIR)" -- $cur) );
|
||||
}
|
||||
|
||||
complete -F _gg_completion gg
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ item }}"
|
||||
mode: 0664
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Enforce ownership of the SSH keys
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: ~{{ item.0 }}/.ssh/id_ed25519{{ item.1 }}
|
||||
state: file
|
||||
owner: "{{ item.0 }}"
|
||||
group: "{{ item.0 }}"
|
||||
loop: "{{ _local_human_users | product(['', '.pub']) }}"
|
||||
|
||||
- name: Configure dconf setting
|
||||
become: true
|
||||
block:
|
||||
- name: Create dconf config directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: "{{ ansible_user }}"
|
||||
mode: 0755
|
||||
loop:
|
||||
- /etc/dconf/profile
|
||||
- /etc/dconf/db/gdm.d
|
||||
|
||||
- name: Create global dconf config
|
||||
ansible.builtin.copy:
|
||||
src: gdm-system
|
||||
dest: /etc/dconf/profile/gdm
|
||||
owner: root
|
||||
group: "{{ ansible_user }}"
|
||||
mode: 0644
|
||||
notify:
|
||||
- dconf-update
|
||||
|
||||
- name: Create user dconf config
|
||||
ansible.builtin.copy:
|
||||
src: gdm-user
|
||||
dest: /etc/dconf/profile/user
|
||||
owner: root
|
||||
group: "{{ ansible_user }}"
|
||||
mode: 0644
|
||||
notify:
|
||||
- dconf-update
|
||||
|
||||
- name: Disable user list
|
||||
ansible.builtin.copy:
|
||||
src: 00-disable-user-list
|
||||
dest: /etc/dconf/db/gdm.d/00-disable-user-list
|
||||
owner: root
|
||||
group: "{{ ansible_user }}"
|
||||
mode: 0644
|
||||
notify:
|
||||
- dconf-update
|
||||
|
||||
- name: Enable fractional scaling
|
||||
ansible.builtin.copy:
|
||||
src: 00-enable-fractional-scaling
|
||||
dest: /etc/dconf/db/local.d/00-enable-fractional-scaling
|
||||
owner: root
|
||||
group: "{{ ansible_user }}"
|
||||
mode: 0644
|
||||
notify:
|
||||
- dconf-update
|
||||
|
||||
- name: Install themes
|
||||
become: true
|
||||
block:
|
||||
- name: Create local themes directory
|
||||
ansible.builtin.file:
|
||||
path: ~{{ item }}/.themes
|
||||
state: directory
|
||||
owner: "{{ item }}"
|
||||
group: "{{ item }}"
|
||||
mode: 0750
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Unarchive LightningBug into local directory
|
||||
ansible.builtin.unarchive:
|
||||
src: lightningbug-dark.tar.gz
|
||||
dest: ~{{ item }}/.themes
|
||||
owner: "{{ item }}"
|
||||
group: "{{ item }}"
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Install wallpaper
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: wallpaper-{{ inventory_hostname }}.jpg
|
||||
dest: ~{{ item }}/Pictures/wallpaper.jpg
|
||||
owner: "{{ item }}"
|
||||
group: "{{ item }}"
|
||||
loop: "{{ _local_human_users }}"
|
||||
|
||||
- name: Link external media directory
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: ~{{ item }}/Drives
|
||||
src: /run/media/{{ item }}
|
||||
state: link
|
||||
force: true
|
||||
loop: "{{ _local_human_users }}"
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
- name: Check for MPW binary
|
||||
ansible.builtin.stat:
|
||||
path: /usr/local/bin/mpw
|
||||
register: _mpw_binary_stat
|
||||
|
||||
- name: Install MPW
|
||||
when: (not _mpw_binary_stat.stat.exists) or (force_reinstall | default(false))
|
||||
block:
|
||||
- name: Install build dependencies on Fedora
|
||||
when: ansible_distribution == "Fedora"
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- libsodium-devel
|
||||
state: present
|
||||
|
||||
- name: Create temporary build directory
|
||||
ansible.builtin.tempfile:
|
||||
prefix: ansible.build.mpw
|
||||
state: directory
|
||||
register: _mpw_build_dir
|
||||
|
||||
- name: Download MPW source
|
||||
ansible.builtin.git:
|
||||
repo: https://gitlab.com/MasterPassword/MasterPassword.git
|
||||
version: 344771db
|
||||
recursive: false # does *not* clone submodules
|
||||
dest: "{{ _mpw_build_dir.path }}"
|
||||
|
||||
# God I hate this
|
||||
- name: Patch .gitmodules to use HTTPS
|
||||
ansible.builtin.replace:
|
||||
path: "{{ _mpw_build_dir.path }}/.gitmodules"
|
||||
regexp: "url = git://"
|
||||
replace: "url = https://"
|
||||
|
||||
- name: Initialize submodules
|
||||
ansible.builtin.command:
|
||||
cmd: git submodule update --init
|
||||
chdir: "{{ _mpw_build_dir.path }}"
|
||||
|
||||
- name: Build MasterPassword binary
|
||||
ansible.builtin.command:
|
||||
cmd: bash build
|
||||
chdir: "{{ _mpw_build_dir.path }}/platform-independent/cli-c/"
|
||||
|
||||
- name: Copy binary to system path
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
remote_src: true
|
||||
src: "{{ _mpw_build_dir.path }}/platform-independent/cli-c/mpw"
|
||||
dest: "/usr/local/bin"
|
||||
mode: 0755
|
||||
always:
|
||||
- name: Remove temporary directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ _mpw_build_dir.path }}"
|
||||
state: absent
|
||||
@@ -1,79 +0,0 @@
|
||||
---
|
||||
- name: Check whether binary exists
|
||||
become: true
|
||||
ansible.builtin.stat:
|
||||
path: "~{{ local_username }}/.local/bin/MultiMC"
|
||||
register: _multimc_stat
|
||||
|
||||
- name: Install MultiMC
|
||||
when: (not _multimc_stat.stat.exists) or (force_reinstall | default(false))
|
||||
block:
|
||||
- name: Create temp dir
|
||||
ansible.builtin.tempfile:
|
||||
state: directory
|
||||
register: _multimc_tempdir
|
||||
|
||||
- name: Download and unpack distribution archive
|
||||
ansible.builtin.unarchive:
|
||||
src: https://files.multimc.org/downloads/mmc-stable-lin64.tar.gz
|
||||
remote_src: true
|
||||
dest: "{{ _multimc_tempdir.path }}"
|
||||
|
||||
- name: Ensure ~/.local/share/ exists
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: ~{{ local_username }}/.local/share
|
||||
state: directory
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0700
|
||||
|
||||
- name: Ensure ~/.local/bin/ exists
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: ~{{ local_username }}/.local/bin
|
||||
state: directory
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0700
|
||||
|
||||
- name: Copy MMC distribution to ~/.local/share/
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
remote_src: true
|
||||
src: "{{ _multimc_tempdir.path }}/MultiMC/"
|
||||
dest: "~{{ local_username }}/.local/share/multimc"
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0700
|
||||
|
||||
- name: Link MMC binary into ~/.local/bin/
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: ~{{ local_username }}/.local/share/multimc/MultiMC
|
||||
path: ~{{ local_username }}/.local/bin/MultiMC
|
||||
|
||||
- name: Copy application icon
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: multimc.png
|
||||
dest: ~{{ local_username }}/.local/share/icons/multimc.png
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0755
|
||||
|
||||
- name: Template application desktop entry
|
||||
become: true
|
||||
ansible.builtin.template:
|
||||
src: multimc.desktop.j2
|
||||
dest: ~{{ local_username }}/.local/share/applications/multimc.desktop
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0755
|
||||
|
||||
always:
|
||||
- name: Delete temp dir
|
||||
ansible.builtin.file:
|
||||
path: "{{ _multimc_tempdir.path }}"
|
||||
state: absent
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
- name: Create install directory
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /opt/pipx
|
||||
state: directory
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ skylab_group_admin.name }}"
|
||||
mode: 0755
|
||||
|
||||
- name: Create install venv
|
||||
ansible.builtin.command:
|
||||
cmd: python3 -m venv /opt/pipx
|
||||
creates: /opt/pipx/bin/python
|
||||
|
||||
- name: Install pipx
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- pipx
|
||||
executable: /opt/pipx/bin/pip
|
||||
|
||||
- name: Link pipx binary into system path
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: /opt/pipx/bin/pipx
|
||||
path: /usr/local/bin/pipx
|
||||
@@ -1 +0,0 @@
|
||||
---
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
- name: Check whether Tor Browser is already installed
|
||||
become: true
|
||||
ansible.builtin.stat:
|
||||
path: "~{{ local_username }}/.local/share/tor-browser/start-tor-browser.desktop"
|
||||
register: _torbrowser_stat
|
||||
|
||||
- name: Install Tor Browser
|
||||
when: not _torbrowser_stat.stat.exists
|
||||
block:
|
||||
- name: Create temp dir
|
||||
ansible.builtin.tempfile:
|
||||
state: directory
|
||||
register: _torbrowser_tempdir
|
||||
|
||||
- name: Download and unpack distribution archive
|
||||
ansible.builtin.unarchive:
|
||||
src: https://dist.torproject.org/torbrowser/11.0.10/tor-browser-linux64-11.0.10_en-US.tar.xz
|
||||
remote_src: true
|
||||
dest: "{{ _torbrowser_tempdir.path }}"
|
||||
|
||||
- name: Ensure ~/.local/share/ exists
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: ~{{ local_username }}/.local/share
|
||||
state: directory
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0700
|
||||
|
||||
- name: Copy Tor Browser distribution to ~/.local/share/
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
remote_src: true
|
||||
src: "{{ _torbrowser_tempdir.path }}/tor-browser_en-US/"
|
||||
dest: "~{{ local_username }}/.local/share/tor-browser"
|
||||
owner: "{{ local_username }}"
|
||||
group: "{{ local_username }}"
|
||||
mode: 0700
|
||||
|
||||
- name: Register application
|
||||
become: true
|
||||
become_user: "{{ local_username }}"
|
||||
changed_when: true
|
||||
ansible.builtin.command:
|
||||
cmd: ./start-tor-browser.desktop
|
||||
chdir: ~{{ local_username }}/.local/share/tor-browser
|
||||
|
||||
always:
|
||||
- name: Delete temp dir
|
||||
ansible.builtin.file:
|
||||
path: "{{ _torbrowser_tempdir.path }}"
|
||||
state: absent
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
- name: Include access vars
|
||||
ansible.builtin.include_vars:
|
||||
file: vars/access.yaml
|
||||
|
||||
- name: Determine local user accounts
|
||||
when: skylab_targets | intersect(item.targets | default([]))
|
||||
vars:
|
||||
_local_users: []
|
||||
ansible.builtin.set_fact:
|
||||
_local_users: "{{ _local_users + [item] }}"
|
||||
loop: "{{ skylab_accounts }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }},{{ item.uid }}"
|
||||
|
||||
- name: Determine local human user accounts
|
||||
when: not (item.service | default(false))
|
||||
vars:
|
||||
_local_human_users: []
|
||||
ansible.builtin.set_fact:
|
||||
_local_human_users: "{{ _local_human_users + [item.name] }}"
|
||||
loop: "{{ _local_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }},{{ item.uid }}"
|
||||
|
||||
- name: Determine local admin user accounts
|
||||
when: item.admin | default(false)
|
||||
vars:
|
||||
_local_admin_users: []
|
||||
ansible.builtin.set_fact:
|
||||
_local_admin_users: "{{ _local_admin_users + [item.name] }}"
|
||||
loop: "{{ _local_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }},{{ item.uid }}"
|
||||
|
||||
- name: Install software
|
||||
ansible.builtin.import_tasks: software.yml
|
||||
|
||||
- name: Configure environment
|
||||
ansible.builtin.import_tasks: environment.yml
|
||||
@@ -1,121 +0,0 @@
|
||||
---
|
||||
- name: Install repositories on Fedora
|
||||
become: true
|
||||
when: ansible_distribution == "Fedora"
|
||||
block:
|
||||
- name: Install RPMFusion repositories
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm
|
||||
- https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm
|
||||
state: present
|
||||
disable_gpg_check: true
|
||||
|
||||
- name: Install Docker CE repository
|
||||
ansible.builtin.yum_repository:
|
||||
name: docker-ce-stable
|
||||
description: Docker CE Stable - $basearch
|
||||
baseurl: https://download.docker.com/linux/fedora/$releasever/$basearch/stable
|
||||
enabled: true
|
||||
gpgcheck: true
|
||||
gpgkey: https://download.docker.com/linux/fedora/gpg
|
||||
|
||||
- name: Install VSCode repository
|
||||
ansible.builtin.yum_repository:
|
||||
name: vscode
|
||||
description: Visual Studio Code
|
||||
baseurl: https://packages.microsoft.com/yumrepos/vscode
|
||||
enabled: true
|
||||
gpgcheck: true
|
||||
gpgkey: https://packages.microsoft.com/keys/microsoft.asc
|
||||
|
||||
- name: Enable Signal-Desktop COPR repository
|
||||
community.general.copr:
|
||||
name: luminoso/Signal-Desktop
|
||||
state: enabled
|
||||
|
||||
- name: Install packages on Fedora
|
||||
become: true
|
||||
when: ansible_distribution == "Fedora"
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- arc-theme
|
||||
- cmake
|
||||
- code # visual studio code
|
||||
- deluge
|
||||
- docker-ce
|
||||
- gcc
|
||||
- gcc-c++
|
||||
- gnome-tweaks
|
||||
- gnome-shell-extension-material-shell
|
||||
- gnome-shell-extension-openweather
|
||||
- gnome-shell-extension-system-monitor-applet
|
||||
- gnome-shell-extension-vertical-overview
|
||||
- gnupg2
|
||||
- guvcview
|
||||
- java-17-openjdk
|
||||
- jq
|
||||
- libffi-devel
|
||||
- libvirt
|
||||
- libvirt-devel
|
||||
- libxml2-devel
|
||||
- mediawriter
|
||||
- ncurses-devel
|
||||
- NetworkManager-tui
|
||||
- pinta
|
||||
- powerline
|
||||
- python27
|
||||
- python36
|
||||
- python37
|
||||
- python38
|
||||
- python39
|
||||
- python310
|
||||
- ShellCheck
|
||||
- signal-desktop
|
||||
- steam
|
||||
- systemd-devel
|
||||
- texlive-fontawesome5
|
||||
- texlive-roboto
|
||||
- texlive-scheme-tetex
|
||||
- texlive-sourcesanspro
|
||||
- virt-manager
|
||||
- vlc
|
||||
- xclip
|
||||
- yarnpkg
|
||||
state: present
|
||||
|
||||
- name: Install unsigned packages on Fedora
|
||||
when: ansible_distribution == "Fedora"
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
# draw.io/diagrams.net
|
||||
- https://github.com/jgraph/drawio-desktop/releases/download/v17.4.2/drawio-x86_64-17.4.2.rpm
|
||||
# zoom
|
||||
- https://zoom.us/client/latest/zoom_x86_64.rpm
|
||||
state: present
|
||||
disable_gpg_check: true
|
||||
|
||||
- ansible.builtin.import_tasks: install_mpw.yml
|
||||
- ansible.builtin.import_tasks: install_nvm.yml
|
||||
- ansible.builtin.import_tasks: install_pipx.yml
|
||||
- ansible.builtin.import_tasks: install_poetry.yml
|
||||
- ansible.builtin.import_tasks: install_postman.yml
|
||||
- ansible.builtin.import_tasks: install_rustup.yml
|
||||
- ansible.builtin.import_tasks: install_typora.yml
|
||||
|
||||
# It is now day eight hundred and thirty nine of begging the ansible devs to let
|
||||
# me loop over blocks. pls bcoca i have a family
|
||||
- name: Install Tor Browser
|
||||
ansible.builtin.include_tasks:
|
||||
file: install_tor_browser.yml
|
||||
loop: "{{ _local_human_users }}"
|
||||
loop_control:
|
||||
loop_var: local_username
|
||||
|
||||
- name: Install MultiMC
|
||||
ansible.builtin.include_tasks:
|
||||
file: install_multimc.yml
|
||||
loop: "{{ _local_human_users }}"
|
||||
loop_control:
|
||||
loop_var: local_username
|
||||
@@ -1,9 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=MultiMC
|
||||
Comment=Minecraft environment manager
|
||||
Exec="/home/{{ local_username }}/.local/bin/MultiMC"
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon="/home/{{ local_username }}/.local/share/icons/multimc.png"
|
||||
Categories=Gaming;Graphics;
|
||||
TryExec="/home/{{ local_username }}/.local/bin/MultiMC"
|
||||
@@ -1,3 +0,0 @@
|
||||
# Ansible Collection - skylab.infra
|
||||
|
||||
Documentation for the collection.
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace: skylab
|
||||
name: core
|
||||
version: 0.0.0
|
||||
description: Network deployment procedures and configuration state management
|
||||
authors:
|
||||
- Ethan Paul <me@enp.one>
|
||||
license:
|
||||
- MIT
|
||||
readme: README.md
|
||||
tags: []
|
||||
repository: https://vcs.enp.one/skylab/skylab-ansible/
|
||||
build_ignore: []
|
||||
|
||||
dependencies:
|
||||
community.general: ">=6.5.0,<7.0"
|
||||
ansible.posix: ">=1.5.1,<2.0"
|
||||
@@ -1,2 +0,0 @@
|
||||
---
|
||||
requires_ansible: '>=2.9.10'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user