diff --git a/playbooks/backup/Justfile b/playbooks/backup/Justfile new file mode 100644 index 0000000..dfdb3ce --- /dev/null +++ b/playbooks/backup/Justfile @@ -0,0 +1,4 @@ +check: + ansible-playbook --check -i inventory.ini -v --become-method community.general.run0 main.yaml +run: + ansible-playbook -i inventory.ini -v --become-method community.general.run0 main.yaml diff --git a/playbooks/backup/inventory.ini b/playbooks/backup/inventory.ini new file mode 100644 index 0000000..df8b5f6 --- /dev/null +++ b/playbooks/backup/inventory.ini @@ -0,0 +1,2 @@ +[all] +localhost ansible_connection=local diff --git a/playbooks/backup/main.yaml b/playbooks/backup/main.yaml new file mode 100644 index 0000000..856d30b --- /dev/null +++ b/playbooks/backup/main.yaml @@ -0,0 +1,47 @@ +- name: backup stuff + hosts: all + vars: + backup_directory: /var/backups/{{ ansible_date_time.date }} + pre_tasks: + + - name: create backup directory + become: true + file: + state: directory + owner: root + group: root + mode: '0770' + path: "{{ backup_directory }}" + + - name: "let {{ ansible_user_id }} write to backup directory" + register: setfacl + failed_when: + - setfacl.rc != 140 + - setfacl.rc != 0 + changed_when: setfacl.rc != 140 + become: true + shell: | + if { getfacl -tn {{ backup_directory }} | tr -d ' ' | grep -Fq 'user{{ansible_user_uid}}rwxrwx' ; }; then + exit 140 + fi + setfacl -dRmu:{{ ansible_user_id }}:rwX {{ backup_directory }} + setfacl -mu:{{ ansible_user_id }}:rwX {{ backup_directory }} + + - name: structure the backup directory + file: + state: directory + path: "{{ backup_directory }}/{{ item }}" + with_items: + - disks + - "system-{{ ansible_hostname }}/users" + + roles: + - storefacts + - disks + + tasks: + - name: turn it into an archive + community.general.archive: + path: "{{ backup_directory }}" + dest: "{{ backup_directory | dirname }}/{{ backup_directory | basename }}.tar" + format: tar diff --git a/playbooks/setup-workstation/Justfile b/playbooks/setup-workstation/Justfile new file mode 100644 index 0000000..35f5c7c --- /dev/null +++ b/playbooks/setup-workstation/Justfile @@ -0,0 +1,4 @@ +setup: + ansible all -a 'ansible-galaxy collection install community.general' +play: + ansible-playbook desktop-playbook.yml -v diff --git a/playbooks/setup-workstation/Vagrantfile b/playbooks/setup-workstation/Vagrantfile new file mode 100644 index 0000000..61da762 --- /dev/null +++ b/playbooks/setup-workstation/Vagrantfile @@ -0,0 +1,12 @@ +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do | config | + config.vm.box = "fedora/41-cloud-base" + config.vm.provider :libvirt do | v | + end + config.ssh.insert_key = false + config.vm.define "desktop" do | client | + client.vm.hostname = "desktop" + # client.vm.network :private_network, ip: "192.168.122.132" + end +end diff --git a/playbooks/setup-workstation/ansible.cfg b/playbooks/setup-workstation/ansible.cfg new file mode 100644 index 0000000..5673526 --- /dev/null +++ b/playbooks/setup-workstation/ansible.cfg @@ -0,0 +1,3 @@ +[defaults] +inventory = ./hosts.ini +vault_password_file = ./secrets-client diff --git a/playbooks/setup-workstation/desktop-playbook.yml b/playbooks/setup-workstation/desktop-playbook.yml new file mode 100644 index 0000000..57345f1 --- /dev/null +++ b/playbooks/setup-workstation/desktop-playbook.yml @@ -0,0 +1,368 @@ +--- + +- hosts: all + name: setup desktop + vars_files: + - secrets + tasks: + - name: remove fedora fluff + become: true + ansible.builtin.dnf: + allowerasing: true + autoremove: true + name: + - anaconda-core + - anaconda-live + - anaconda-install-env-deps + - cockpit-system + - python3-botocore + - firefox + - nodejs + state: absent + - name: install core components + become: true + dnf: + state: present + name: + - git + - git-crypt + - git-lfs + - gnupg2 + - tmux + - curl + - acl + - stow + - make + - just + - zsh + - neovim + - nnn + - openssh-clients + - openssh-server + - mosh + - unzip + - flatpak + - name: install pup + become: true + unarchive: + remote_src: yes + creates: /usr/local/bin/pup + dest: /usr/local/bin/ + src: https://github.com/ericchiang/pup/releases/download/v0.4.0/pup_v0.4.0_linux_amd64.zip + - name: install google-chrome dnf repository + become: true + copy: + dest: /etc/yum.repos.d/google-chrome.repo + content: | + [google-chrome] + name=google-chrome + baseurl=https://dl.google.com/linux/chrome/rpm/stable/x86_64 + enabled=1 + gpgcheck=1 + gpgkey=https://dl.google.com/linux/linux_signing_key.pub + - name: install tailscale dnf repository + become: true + copy: + dest: /etc/yum.repos.d/tailscale.repo + content: | + [tailscale] + name=Tailscale + baseurl=https://pkgs.tailscale.com/stable/fedora/$basearch + enabled=1 + type=rpm + repo_gpgcheck=1 + gpgcheck=1 + gpgkey=https://pkgs.tailscale.com/stable/fedora/repo.gpg + - name: install dnf packages + become: true + dnf: + state: present + name: + - aria2 + - bat + - bc + - btop + - btrfs-progs + - coreutils + - moreutils + - fcitx5-gtk4 + - file + - gh + - google-chrome-stable + - gparted + - jo + - jq + - jrnl + - kitty + - kitty-terminfo + - lshw + - mpv + - ncdu + - pandoc + - podman + - runc + - pass + - wtype + - tailscale + - rclone + - rsync + - seahorse + - timew + - toolbox + - tree + - fzf + - socat + - tree-sitter-cli + - waybar + - wkhtmltopdf + - yq + - ImageMagick + - name: install flatpak applications + become: true + flatpak: + state: present + name: + - https://valent.andyholmes.ca/valent.flatpakref + - com.nextcloud.desktopclient.nextcloud + - org.libreoffice.LibreOffice + - org.mozilla.Thunderbird + + - com.logseq.Logseq + - com.github.xournalpp.xournalpp + + - com.obsproject.Studio + + - com.yubico.yubioath + - com.github.tchx84.Flatseal + + - org.gnome.Loupe + - com.github.johnfactotum.Foliate + - org.gnome.Papers + - org.gnome.FileRoller + - org.gnome.SimpleScan + + - com.github.neithern.g4music + - info.febvre.Komikku + + - org.gimp.GIMP + - net.scribus.Scribus + - org.inkscape.Inkscape + - org.darktable.Darktable + - org.audacityteam.Audacity + - name: create group myself + become: true + group: + name: myself + gid: 690 + system: true + - name: create group rootlessmen + become: true + group: + name: rootlessmen + system: true + - name: create users + become: true + with_items: + - name: kevins + uid: 6901 + groups: ["myself", "rootlessmen"] + - name: kevinsamuel + uid: 6902 + groups: myself + - name: kevinnlsamuel + uid: 6903 + groups: ["myself", "rootlessmen"] + user: + state: present + name: "{{ item.name }}" + uid: "{{ item.uid }}" + groups: "{{ item.groups }}" + skeleton: /dev/null + append: true + password: $1$aBLdYKQI$iB3ZfYF.QPCwVhgnkROUX. + update_password: on_create + shell: /bin/zsh + + - name: use crun as podman engine + become: true + vars: + file: /etc/containers/containers.conf + block: + - lineinfile: + owner: root + group: root + mode: '0644' + create: true + path: "{{file}}" + line: "[engine]" + insertbefore: BOF + - lineinfile: + path: "{{file}}" + line: 'runtime = "/usr/bin/runc"' + search_string: 'runtime = ' + - name: create storage for rootlessmen + become: true + file: + path: /var/lib/rootlessmen + owner: root + group: rootlessmen + mode: "0770" + state: directory + - name: setup podman to use rootlessmen for storage + become: true + vars: + file: /etc/containers/storage.conf + block: + - name: create container storage config + lineinfile: + owner: root + group: root + mode: '0644' + create: true + path: "{{file}}" + line: "[storage]" + insertbefore: BOF + - name: setup storage config to use rootlessmen + with_items: + - line: 'driver_priority = ["btrfs", "overlay", "vfs"]' + search_string: 'driver_priority = ' + - line: 'rootless_storage_path = "/var/lib/rootlessmen/$USER/storage"' + search_string: 'rootless_storage_path = ' + lineinfile: + path: "{{file}}" + line: "{{item.line}}" + search_string: "{{item.search_string}}" + - name: set selinux fcontext for rootlessmen + become: true + with_items: + - pathspec: /var/lib/rootlessmen/[^/]+/storage/artifacts(/.*)? + type: container_ro_file_t + - pathspec: /var/lib/rootlessmen/[^/]+/storage/volumes/[^/]*/.* + type: container_file_t + sefcontext: + target: "{{item.pathspec}}" + setype: "{{item.type}}" + seuser: unconfined_u + + - name: enable tpm-tss in dracut + become: true + lineinfile: + path: /etc/dracut.conf.d/55-tpm.conf + line: "add_dracutmodules+=' tpm2-tss '" + owner: root + group: root + mode: "1644" + create: true + state: present + - name: tell PAM to unlock gnome-keyring in tty + become: true + with_items: + - type: auth + args: "" + - type: session + args: auto_start + pamd: + name: login + state: before + type: "{{item.type}}" + control: include + module_path: postlogin + new_type: "-{{item.type}}" + new_control: optional + new_module_path: pam_gnome_keyring.so + module_arguments: "{{item.args}}" + + - name: create wifi networks + become: true + loop: + - ssid: KEVINSAM_5 + zone: home + - ssid: KEVINSAM + zone: home + - ssid: askKevin + zone: work + community.general.nmcli: + state: present + type: wifi + zone: "{{ item.zone }}" + conn_name: "{{ item.ssid }}" + ssid: "{{ item.ssid }}" + autoconnect: true + wifi: + hidden: true + wifi_sec: + key-mgmt: wpa-psk + psk: "not really the key" + + - name: create tailscale firewall zone + become: true + shell: | + firewall-cmd --permanent --new-zone=tailscale + firewall-cmd --permanent --zone=tailscale --add-interface=tailscale0 + firewall-cmd --permanent --zone=tailscale --add-forward + firewall-cmd --permanent --zone=tailscale --set-target=ACCEPT + firewall-cmd --reload + + - name: other firewall rules + become: true + shell: | + firewall-cmd --permanent --zone public --remove-service ssh + firewall-cmd --permanent --zone public --add-service kdeconnect + firewall-cmd --permanent --zone home --add-service=kdeconnect --add-service=mosh --add-service=ssh + firewall-cmd --reload + + - name: create /home/myself + become: true + file: + state: directory + path: /home/myself + group: myself + owner: kevins + mode: '2770' + - name: check if HOME.git is cloned + become: true + become_user: kevins + register: home_repo + stat: + path: /home/myself/HOME.git/HEAD + - name: "clone HOME.git" + become: true + become_user: kevins + when: not home_repo.stat.exists + shell: | + mkdir -p /home/myself/HOME.git + cd /home/myself/HOME.git + git init --bare . + git remote add \ + origin \ + -t stable \ + -m stable \ + https://{{PAT}}@github.com/kevinnlsamuel/HOME.git + git fetch --set-upstream origin stable + + - name: clone HOME to my selves + vars: + src: /home/myself/HOME.git + dest: "/home/{{item}}/.local/state/HOME" + with_items: + - kevins + - kevinsamuel + - kevinnlsamuel + become_user: "{{item}}" + become: true + failed_when: + - result.rc != 140 + - result.rc != 0 + changed_when: "result.rc != 140" + register: result + shell: | + mkdir -p "{{dest}}" + cd "{{dest}}" + if [ -f ".git/HEAD" ]; then exit 140 2>/dev/null; fi + git init -b main + git config --add safe.directory "{{src}}" + git remote add myself "{{src}}" + git pull myself main + +# manually install: +# - sieve diff --git a/playbooks/setup-workstation/hosts.ini b/playbooks/setup-workstation/hosts.ini new file mode 100644 index 0000000..f252d5e --- /dev/null +++ b/playbooks/setup-workstation/hosts.ini @@ -0,0 +1,7 @@ +[all] +; set to whatever the vm is +172.35.1.142 + +[all:vars] +ansible_user = admin +ansible_ssh_private_key_file = ~/.ssh/keys/kevins.pub diff --git a/playbooks/setup-workstation/requirements.yml b/playbooks/setup-workstation/requirements.yml new file mode 100644 index 0000000..72fe72d --- /dev/null +++ b/playbooks/setup-workstation/requirements.yml @@ -0,0 +1,2 @@ +collections: + - name: community.general diff --git a/playbooks/setup-workstation/secrets b/playbooks/setup-workstation/secrets new file mode 100644 index 0000000..37a2c7b --- /dev/null +++ b/playbooks/setup-workstation/secrets @@ -0,0 +1,27 @@ +$ANSIBLE_VAULT;1.1;AES256 +38333432336134663937363161333833373365386635613338333761346662653566333439363132 +3437393431643233393133643133313963323134626465630a666565653234626630373837343933 +64633966303761333539633335393234396264616266323439303932623535396335663839323363 +3861643566303563610a333166363032636462353836303365333634643639353934386233353438 +31373664386332613637626663633030313232383435303966643835346536313737393030623038 +36616465653563366138633334343665363131313361343836383132346334306330636138666666 +35636631646431393130376232663665343736313466626235623032636462316438656238656463 +35396465643936613935646237373837373037333561393133633033303038373565386236336339 +36636666623835343662346461643735646237653236386132623334653734633431313735363765 +64323839663765326336336263323535373663323232323336386464623734373433353135393566 +30663130656336653832653862383464363261323831346632306539613139646632306133666132 +38363066666563383436316537626439313134363365326333623633383138346134356232646664 +31333834323138366635613933616363363131643330353166383234333236343833343432656163 +33663963333039303737386431396337636665633532373336383762363966343139346335353463 +33383632343630343134333062326138383562636666396336313530363939333965626130303332 +35306238663633613130616138613137393331343862666664613539346237616537376166303130 +62393633613666613235633736666361653764356161396532306135343162316262386136386538 +32353861633362323166616263656633346531336633323064336162323630343532323139366166 +64316130633436303230353133623036656337316232323538316562663663326438383736313261 +63633766326638363939346531643836616561366365326236393031643633633836353837613963 +35333532393435313435333935353935656631386264626535303265353732653832613935623238 +33643765633939343730636165313737393037343337653230313637306365303539636233643839 +35613463386439323965613763396535383730383431666437393338336562663035653461613035 +64346465313532373938383833343334666563333362643961626138653664623337383964383463 +64343031373534346161386134663933626335326337386634666133343533626662646136623134 +3536656133663039353436666339323437323162633139613632 diff --git a/playbooks/setup-workstation/secrets-client b/playbooks/setup-workstation/secrets-client new file mode 100755 index 0000000..7765c92 --- /dev/null +++ b/playbooks/setup-workstation/secrets-client @@ -0,0 +1,4 @@ +#!/bin/sh +set -e + +pass encryptions/com.kevinnlsamuel/playbooks/setup-workstations/secrets diff --git a/roles/disks/meta/main.yml b/roles/disks/meta/main.yml new file mode 100644 index 0000000..36b9858 --- /dev/null +++ b/roles/disks/meta/main.yml @@ -0,0 +1,35 @@ +#SPDX-License-Identifier: MIT-0 +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/disks/tasks/main.yml b/roles/disks/tasks/main.yml new file mode 100644 index 0000000..3097bb4 --- /dev/null +++ b/roles/disks/tasks/main.yml @@ -0,0 +1,48 @@ +- name: get list of disks + changed_when: false + shell: > + lsblk + --json + --paths + --filter 'MIN == 0 && TYPE == "disk" && MOUNTPOINT != "[SWAP]"' + | jq '.blockdevices' + register: disks + +- name: backup partition tables + become: true + shell: | + if [ {{ item.type }} != disk ]; then exit 0; fi + sfdisk --dump {{ item.name }} >{{ backup_directory }}/disks/{{ item.name | basename }}.sfdisk + loop: "{{ disks.stdout }}" + +- name: get list of luks devices + changed_when: false + shell: > + lsblk + --json + --paths + | jq '[ .blockdevices[]|.children[]?|select(recurse(.children[]?)|.type == "crypt") ]' + register: cryptdisks + +- name: backup luks2 headers + become: true + loop: "{{ cryptdisks.stdout }}" + shell: | + rm -f {{ backup_directory }}/disks/{{ item.children[0].name | basename }}.luks2header + cryptsetup luksHeaderBackup {{ item.name }} \ + --header-backup-file {{ backup_directory }}/disks/{{ item.children[0].name | basename }}.luks2header + +- name: backup lvm volume groups + become: true + shell: | + if [ ! -d /etc/lvm/backup ]; then exit 0; fi + for vg in /etc/lvm/backup/*; do + cp $vg {{backup_directory}}/disks/${vg##*/}.volumegroup + done + +# get list of disks +# run sfdisk on it +# get list of partitions with luks2 +# # backup their headers +# get list of partitions with lvm2 +# # copy the metadata diff --git a/roles/hello/meta/main.yml b/roles/hello/meta/main.yml new file mode 100644 index 0000000..9f28352 --- /dev/null +++ b/roles/hello/meta/main.yml @@ -0,0 +1,6 @@ +galaxy_info: + author: kevinnlsamuel + description: sayin hello +dependencies: + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/hello/tasks/main.yml b/roles/hello/tasks/main.yml new file mode 100644 index 0000000..1bba8cf --- /dev/null +++ b/roles/hello/tasks/main.yml @@ -0,0 +1,6 @@ +- name: register greeting + command: echo hello + register: greeting +- name: say greeting + debug: + msg: "{{ greeting.stdout }}" diff --git a/roles/storefacts/tasks/main.yml b/roles/storefacts/tasks/main.yml new file mode 100644 index 0000000..b1d90e5 --- /dev/null +++ b/roles/storefacts/tasks/main.yml @@ -0,0 +1,4 @@ +- name: store facts + template: + src: facts.jinja2 + dest: "{{ backup_directory }}/ansible_facts.json" diff --git a/roles/storefacts/templates/facts.jinja2 b/roles/storefacts/templates/facts.jinja2 new file mode 100644 index 0000000..5f4e064 --- /dev/null +++ b/roles/storefacts/templates/facts.jinja2 @@ -0,0 +1 @@ +{{ ansible_facts | to_nice_json }}