diff --git a/skylab/core/roles/workstation/files/00-disable-user-list b/skylab/core/roles/workstation/files/00-disable-user-list new file mode 100644 index 0000000..7db560a --- /dev/null +++ b/skylab/core/roles/workstation/files/00-disable-user-list @@ -0,0 +1,2 @@ +[org/gnome/login-screen] +disable-user-list=true diff --git a/skylab/core/roles/workstation/files/00-enable-fractional-scaling b/skylab/core/roles/workstation/files/00-enable-fractional-scaling new file mode 100644 index 0000000..eef356b --- /dev/null +++ b/skylab/core/roles/workstation/files/00-enable-fractional-scaling @@ -0,0 +1,2 @@ +[org/gnome/mutter] +experimental-features=['scale-monitor-framebuffer'] diff --git a/skylab/core/roles/workstation/files/bashrc.sh b/skylab/core/roles/workstation/files/bashrc.sh new file mode 100644 index 0000000..75ecc00 --- /dev/null +++ b/skylab/core/roles/workstation/files/bashrc.sh @@ -0,0 +1,44 @@ +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" + +function gg() { + cd ~/Git/$1; + if [ -f ~/Git/$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" diff --git a/skylab/core/roles/workstation/files/gdm-system b/skylab/core/roles/workstation/files/gdm-system new file mode 100644 index 0000000..817afc5 --- /dev/null +++ b/skylab/core/roles/workstation/files/gdm-system @@ -0,0 +1,3 @@ +user-db:user +system-db:gdm +file-db:/usr/share/gdm/greeter-dconf-defaults diff --git a/skylab/core/roles/workstation/files/gdm-user b/skylab/core/roles/workstation/files/gdm-user new file mode 100644 index 0000000..aca0641 --- /dev/null +++ b/skylab/core/roles/workstation/files/gdm-user @@ -0,0 +1,2 @@ +user-db:user +system-db:local diff --git a/skylab/core/roles/workstation/files/lightningbug-dark.tar.gz b/skylab/core/roles/workstation/files/lightningbug-dark.tar.gz new file mode 100644 index 0000000..724903a Binary files /dev/null and b/skylab/core/roles/workstation/files/lightningbug-dark.tar.gz differ diff --git a/skylab/core/roles/workstation/files/multimc.png b/skylab/core/roles/workstation/files/multimc.png new file mode 100644 index 0000000..473ce95 Binary files /dev/null and b/skylab/core/roles/workstation/files/multimc.png differ diff --git a/skylab/core/roles/workstation/files/wallpaper-discovery.jpg b/skylab/core/roles/workstation/files/wallpaper-discovery.jpg new file mode 100755 index 0000000..9316869 Binary files /dev/null and b/skylab/core/roles/workstation/files/wallpaper-discovery.jpg differ diff --git a/skylab/core/roles/workstation/handlers/main.yml b/skylab/core/roles/workstation/handlers/main.yml new file mode 100644 index 0000000..e9d4b7f --- /dev/null +++ b/skylab/core/roles/workstation/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: dconf-update + become: true + changed_when: true + ansible.builtin.command: + cmd: dconf update diff --git a/skylab/core/roles/workstation/tasks/environment.yml b/skylab/core/roles/workstation/tasks/environment.yml new file mode 100644 index 0000000..d7afd3d --- /dev/null +++ b/skylab/core/roles/workstation/tasks/environment.yml @@ -0,0 +1,110 @@ +--- +- 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: 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: "{{ inventory_hostname }}-wallpaper.jpg" + dest: ~{{ item }}/Pictures/wallpaper.jpg + owner: "{{ item }}" + group: "{{ item }}" + loop: "{{ _local_human_users }}" diff --git a/skylab/core/roles/workstation/tasks/install_mpw.yml b/skylab/core/roles/workstation/tasks/install_mpw.yml new file mode 100644 index 0000000..aacfd7e --- /dev/null +++ b/skylab/core/roles/workstation/tasks/install_mpw.yml @@ -0,0 +1,59 @@ +--- +- 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 diff --git a/skylab/core/roles/workstation/tasks/install_multimc.yml b/skylab/core/roles/workstation/tasks/install_multimc.yml new file mode 100644 index 0000000..5a72fd6 --- /dev/null +++ b/skylab/core/roles/workstation/tasks/install_multimc.yml @@ -0,0 +1,79 @@ +--- +- 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 diff --git a/skylab/core/roles/workstation/tasks/install_nvm.yml b/skylab/core/roles/workstation/tasks/install_nvm.yml new file mode 100644 index 0000000..e69de29 diff --git a/skylab/core/roles/workstation/tasks/install_pipx.yml b/skylab/core/roles/workstation/tasks/install_pipx.yml new file mode 100644 index 0000000..ed218bc --- /dev/null +++ b/skylab/core/roles/workstation/tasks/install_pipx.yml @@ -0,0 +1,27 @@ +--- +- 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 diff --git a/skylab/core/roles/workstation/tasks/install_poetry.yml b/skylab/core/roles/workstation/tasks/install_poetry.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/skylab/core/roles/workstation/tasks/install_poetry.yml @@ -0,0 +1 @@ +--- diff --git a/skylab/core/roles/workstation/tasks/install_postman.yml b/skylab/core/roles/workstation/tasks/install_postman.yml new file mode 100644 index 0000000..e69de29 diff --git a/skylab/core/roles/workstation/tasks/install_rustup.yml b/skylab/core/roles/workstation/tasks/install_rustup.yml new file mode 100644 index 0000000..e69de29 diff --git a/skylab/core/roles/workstation/tasks/install_tor_browser.yml b/skylab/core/roles/workstation/tasks/install_tor_browser.yml new file mode 100644 index 0000000..d8cff78 --- /dev/null +++ b/skylab/core/roles/workstation/tasks/install_tor_browser.yml @@ -0,0 +1,53 @@ +--- +- 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 diff --git a/skylab/core/roles/workstation/tasks/install_typora.yml b/skylab/core/roles/workstation/tasks/install_typora.yml new file mode 100644 index 0000000..e69de29 diff --git a/skylab/core/roles/workstation/tasks/main.yml b/skylab/core/roles/workstation/tasks/main.yml new file mode 100644 index 0000000..4ac3d9c --- /dev/null +++ b/skylab/core/roles/workstation/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- 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 diff --git a/skylab/core/roles/workstation/tasks/software.yml b/skylab/core/roles/workstation/tasks/software.yml new file mode 100644 index 0000000..f8d0081 --- /dev/null +++ b/skylab/core/roles/workstation/tasks/software.yml @@ -0,0 +1,120 @@ +--- +- 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: + - 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 diff --git a/skylab/core/roles/workstation/templates/multimc.desktop.j2 b/skylab/core/roles/workstation/templates/multimc.desktop.j2 new file mode 100644 index 0000000..736dc9b --- /dev/null +++ b/skylab/core/roles/workstation/templates/multimc.desktop.j2 @@ -0,0 +1,9 @@ +[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"