# Workstation

- [Workstation](#workstation)
  - [Pacman Packages](#pacman-packages)
    - [Upgrade/Downgrade](#upgradedowngrade)
    - [Freeze package](#freeze-package)
  - [Fingerprint Reader Support](#fingerprint-reader-support)
    - [Setup](#setup)
    - [Turn Off Fingerprint When Laptop Lid Closed](#turn-off-fingerprint-when-laptop-lid-closed)
  - [SSH](#ssh)
  - [Templates](#templates)
  - [Ungoogled Chromium](#ungoogled-chromium)
    - [Ungoogled Chromium AUR](#ungoogled-chromium-aur)
    - [Ungoogled Chromium Manual Build](#ungoogled-chromium-manual-build)
  - [Firefox](#firefox)
    - [Gnome Extensions](#gnome-extensions)
  - [Avahi (Bonjour)](#avahi-bonjour)
  - [CUPS Printing](#cups-printing)
  - [Toolbox](#toolbox)
  - [Podman](#podman)
  - [Docker](#docker)
  - [QEMU/KVM](#qemukvm)
    - [Arch Guests](#arch-guests)
  - [Kubernetes](#kubernetes)
  - [VSCode](#vscode)
  - [Wireguard](#wireguard)
  - [Remote Desktop](#remote-desktop)
  - [Transmission](#transmission)
  - [VLC](#vlc)
  - [Bitwarden](#bitwarden)
  - [Nextcloud](#nextcloud)
  - [Insomnia](#insomnia)
  - [QMK](#qmk)
    - [Initialization](#initialization)
    - [Development](#development)
  - [Cura](#cura)
  - [Creality Print](#creality-print)
  - [Bambu Studio](#bambu-studio)
    - [Firewall Rules for LAN Printer](#firewall-rules-for-lan-printer)
    - [Adding LAN printer via config](#adding-lan-printer-via-config)
    - [Custom Filament Profiles](#custom-filament-profiles)
  - [Orca Slicer](#orca-slicer)
  - [AWS CLI](#aws-cli)
  - [NSlookup](#nslookup)
  - [rpi-imager](#rpi-imager)
  - [qFlipper](#qflipper)
  - [Nextcloud Talk](#nextcloud-talk)
  - [FFMpeg](#ffmpeg)
  - [Youtube-dlp](#youtube-dlp)
  - [Iperf3](#iperf3)
  - [Glances](#glances)
  - [VirtualBox](#virtualbox)
  - [Email](#email)
  - [Traffic Usage](#traffic-usage)
  - [Wine](#wine)
  - [KDE Connect (GSConnect)](#kde-connect-gsconnect)
  - [Python](#python)
    - [Pyenv](#pyenv)
    - [Poetry](#poetry)
  - [Note Taking](#note-taking)
  - [Calculator](#calculator)
  - [Disk Usqage](#disk-usqage)

## Pacman Packages

### Upgrade/Downgrade

The [Arch Linux Archive](https://archive.archlinux.org/packages/) keeps snapshots of all packages
from history. Search for your package on the site, copy the link for the `pkg.tar.zst` file, and run
the following:

```bash
# Replace link with the one you copied
pacman -U https://archive.archlinux.org/packages/g/gdm/gdm-46.2-1-x86_64.pkg.tar.zst
```

### Freeze package

You can freeze a package by adding it to the list of ignores in `/etc/pacman.conf`:

```conf
...
IgnorePkg  = nano vim linux
...
```

## Fingerprint Reader Support

### Setup

1. `pacman -S fprintd`
2. `systemctl enable --now fprintd`
3. `fprintd-enroll ducoterra`
4. Install <https://aur.archlinux.org/pam-fprint-grosshack.git> to use fingerprint with gnome

In order to use fingerprint auth with gnome for privileged system stuff with gdm, edit
`/etc/pam.d/system-auth` to include `auth sufficient pam_fprintd_grosshack.so`.

```conf
#%PAM-1.0

auth       required                    pam_shells.so # User must have shell in /etc/shells
auth       requisite                   pam_nologin.so # Prevents users from loging in if /etc/nologin exists
auth       required                    pam_faillock.so      preauth # Timeout after certain number of fails
# Optionally use requisite above if you do not want to prompt for the password
# on locked accounts.
auth       sufficient                  pam_fprintd_grosshack.so
-auth      [success=2 default=ignore]  pam_systemd_home.so
auth       [success=1 default=bad]     pam_unix.so          try_first_pass nullok
auth       [default=die]               pam_faillock.so      authfail
auth       optional                    pam_permit.so
auth       required                    pam_env.so
auth       required                    pam_faillock.so      authsucc
# If you drop the above call to pam_faillock.so the lock will be done also
# on non-consecutive authentication failures.

-account   [success=1 default=ignore]  pam_systemd_home.so
account    required                    pam_unix.so
account    optional                    pam_permit.so
account    required                    pam_time.so

-password  [success=1 default=ignore]  pam_systemd_home.so
password   required                    pam_unix.so          try_first_pass nullok shadow
password   optional                    pam_permit.so

-session   optional                    pam_systemd_home.so
session    required                    pam_limits.so
session    required                    pam_unix.so
session    optional                    pam_permit.so
```

### Turn Off Fingerprint When Laptop Lid Closed

**NOTE: This may break fingerprint unlock. Testing in progress.**

To disable fingerprint authentication when the laptop lid is closed, and re-enable when it is
reopened, we will use acpid to bind to the button/lid.* event to a custom script that will comment
out fprintd auth in /etc/pam.d/sudo.

Usually we'd just `systemctl mask fprintd` but this breaks gdm (as of 08/06/23). See
<https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2267> and
<https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6585>.

1. `pacman -S acpid` and then `systemctl enable --now acpid`
2. Create file /etc/acpi/laptop-lid.sh with the following contents:

    ```bash
    #!/bin/bash

    if grep -Fq closed /proc/acpi/button/lid/LID0/state # &&
        # This is used to detect if a display is connected.
        # For USB C displayport use: 
        # grep -Fxq connected /sys/class/drm/card1-DP-2/status
        # For hdmi use:
        # grep -Fxq connected /sys/class/drm/card0-HDMI-A-1/status
    then
        # comment out fprintd
        sed -i -E 's/^([^#].*pam_fprintd.so)/#\1/g' /etc/pam.d/sudo
    else
        # uncomment fprintd
        sed -i -E 's/#(.*pam_fprintd.so)/\1/g' /etc/pam.d/sudo

    fi
    ```

3. Make the file executable with

    `chmod +x /etc/acpi/laptop-lid.sh`

4. Create file /etc/acpi/events/laptop-lid with the following contents:

    ```bash
    event=button/lid.*
    action=/etc/acpi/laptop-lid.sh
    ```

5. Restart the acpid service with:

    `systemctl restart acpid`

Now the fingerprint will be used only when the lid is open.

In order to ensure the correct state after suspend we need a service file which runs our script on
wake.

1. Create a file named /etc/systemd/system/laptop-lid.service with the following contents:

    ```bash
    [Unit]
    Description=Laptop Lid
    After=suspend.target

    [Service]
    ExecStart=/etc/acpi/laptop-lid.sh

    [Install]
    WantedBy=multi-user.target
    WantedBy=suspend.target
    ```

2. Reload the systemd config files with

    `sudo systemctl daemon-reload`

3. Start and enable the service with

    `sudo systemctl enable --now laptop-lid.service`

Now the status should be correct even after connecting/disconnecting when the computer is off.

## SSH

Generate a key with password protection:

```bash
# Omit "-N 'password'" to have it prompt you
ssh-keygen -f ~/.ssh/test-key -N 'PASSWORD'
```

Change the password for an ssh key:

```bash
# Use "-N ''" to remove the password
ssh-keygen -p -N 'PASSWORD' -f ~/.ssh/test-key
```

This is an example config entry in `~/.ssh/config`:

```conf
Host my-host
    Hostname my-host.reeselink.com
    User root
    ProxyCommand none
    ForwardAgent no
    ForwardX11 no
    Port 22
    KeepAlive yes
    IdentityFile ~/.ssh/id_my-host_rsa
```

You can ssh to that host with `ssh my-host` after adding a config entry.

## Templates

You can add files in `~/Templates` to give yourself quick-create options in the gnome
file browser context menu.

```bash
mkdir ~/Templates
touch ~/Templates/text.txt
```

## Ungoogled Chromium

<https://github.com/ungoogled-software/ungoogled-chromium-archlinux>

### Ungoogled Chromium AUR

<https://aur.archlinux.org/packages/ungoogled-chromium-bin>

Make sure to `pacman -S gnome-browser-connector` and grab the [Gnome Shell Integration](https://chromewebstore.google.com/detail/gnome-shell-integration/gphhapmejobijbbhgpjhcjognlahblep)

Install the [chromium-web-store](https://github.com/NeverDecaf/chromium-web-store) extension to use
chrome web store extensions.

### Ungoogled Chromium Manual Build

<https://github.com/ungoogled-software/ungoogled-chromium-archlinux>

```bash
# Install required dependencies. Make sure your user has access to sudo
sudo pacman -S base-devel

# Clone this repository
git clone https://github.com/ungoogled-software/ungoogled-chromium-archlinux

# Navigate into the repository
cd ungoogled-chromium-archlinux

# Check out the latest tag
git checkout $(git describe --abbrev=0 --tags)

# Start the build, this will download all necessary dependencies automatically
makepkg -s

# Install
makepkg --install
```

## Firefox

You'll want firefox and gnome-browser-connector (for gnome extension management).

```bash
pacman -S firefox gnome-browser-connector
```

Choose noto-fonts

### Gnome Extensions

1. AlphabeticalAppGrid@stuarthayhurst
2. <Vitals@CoreCoding.com>
3. <dash-to-dock@micxgx.gmail.com>
4. <tactile@lundal.io>
5. GSConnect

## Avahi (Bonjour)

1. `pacman -S avahi`
2. `vim /etc/nsswitch.conf`

    ```conf
    hosts: mymachines mdns [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns
    ```

3. `vim /etc/mdns.allow`

```conf
.local.
.local
```

## CUPS Printing

Note: you need [avahi](#avahi-bonjour) for auto-discovery.

1. `pacman -S cups cups-pdf system-config-printer gutenprint foomatic-db-gutenprint-ppds`
2. `cups-genppdupdate`
3. `usermod -aG lp ducoterra`
4. `systemctl enable --now cups`

To add a new printer:

<https://github.com/OpenPrinting/cups/?tab=readme-ov-file#setting-up-printers>

`lpadmin -p printer-name -E -v "ipp://1.2.3.4/ipp/print" -m everywhere`

## Toolbox

<https://wiki.archlinux.org/title/Toolbox>

Toolbox is a containerized workstation service via podman.

```bash
# select "crun" when prompted
pacman -S toolbox

toolbox create

toolbox enter

sudo pacman -S zsh grml-zsh-config zsh-syntax-highlighting zsh-autosuggestions pkgfile
```

## Podman

Install with the following

`pacman -S podman buildah cni-plugins slirp4netns podman-dnsname aardvark-dns`

Then you can run rootless containers like so:

```bash
podman pull docker.io/library/python:3.11
podman run -it python:3.11 bash

podman network create test
podman pod create --network test --publish 8000:8000 test1
podman run -it --pod test1 python:3.11 bash
```

You can also deploy pods with kubernetes yamls.

```bash
podman network create test
podman kube play --network test podman-deploy.yaml --replace
```

## Docker

```bash
pacman -Sy docker docker-compose
usermod -aG docker ducoterra
```

logout, log back in to use docker as non-root user.

You can use btrfs as your storage driver by following these instructions:

<https://docs.docker.com/storage/storagedriver/btrfs-driver/>

## QEMU/KVM

Install virtualization capabilties

```bash
# DNSMasq is required - do not start it with systemd, qemu will handle that.
pacman -S qemu-full dnsmasq virt-manager
systemctl enable --now libvirtd
virsh net-autostart default
```

Then edit `/etc/libvirt/network.conf` and add:

```conf
firewall_backend="iptables"
```

Make sure to restart libvirtd with `systemctl restart libvirtd`.

If you get a blank screen when launching a VM check that you've used the correct bios -
either secboot or not secboot. This is the most common problem.

### Arch Guests

In order to get drivers for spice you'll need the guest spice drivers:

```bash
sudo pacman -S qemu-guest-agent spice-vdagent
```

## Kubernetes

```bash
pacman -S kubectl helm
```

## VSCode

For the open source version of code install `code`:

```bash
sudo pacman -S code
```

This version of code does not render with wayland by default. If using
fractional scaling this causes blurriness. To fix this you'll need to modify the
.desktop file and add the wayland argument:

```bash
cp /usr/share/applications/code-oss.desktop ~/.local/share/applications/
vim ~/.local/share/applications/code-oss.desktop
```

Add `--ozone-platform=wayland` to the `Exec` section:

```conf
[Desktop Entry]
...
Exec=code-oss --ozone-platform=wayland %F
...
[Desktop Action new-empty-window]
...
Exec=code-oss --ozone-platform=wayland --new-window %F
...
```

For the proprietary version of vscode use the AUR:

<https://aur.archlinux.org/packages/visual-studio-code-bin>

```bash
cd ~/aur
git clone https://aur.archlinux.org/visual-studio-code-bin.git
cd visual-studio-code-bin
makepkg -si
```

## Wireguard

Wireguard requires `linux-headers`. If that isn't installed or is misconfigured your
vpn likely won't activate.

```bash
pacman -S wireguard-tools
```

## Remote Desktop

```bash
pacman -S remmina freerdp
```

## Transmission

```bash
pacman -S gtk4 transmission-gtk
```

## VLC

```bash
pacman -S vlc
```

## Bitwarden

```bash
pacman -S bitwarden
```

Enable fractional scaling support:

```bash
cp /usr/share/applications/bitwarden.desktop ~/.local/share/applications/
vim ~/.local/share/applications/bitwarden.desktop
```

bitwarden.desktop

```conf
[Desktop Entry]
...
Exec=bitwarden-desktop --ozone-platform=wayland
...
```

## Nextcloud

<https://wiki.archlinux.org/title/Nextcloud#Desktop>

```bash
pacman -S nextcloud-client
```

For app icon support, install <https://extensions.gnome.org/extension/615/appindicator-support/>

## Insomnia

<https://github.com/Kong/insomnia/releases/tag/core@2023.5.7>

```bash
mv ~/Downloads/Insomnia*.AppImage ~/Applications/Insomnia.AppImage
chmod +x ~/Applications/*.AppImage
```

```conf
[Desktop Entry]
Name=Insomnia
Exec=/home/ducoterra/Applications/Insomnia.AppImage
Icon=/home/ducoterra/.icons/insomnia.png
Type=Application
```

## QMK

### Initialization

I have a mirror and a fork of the mirror on my personal Gitea. For this strategy you'll
need to checkout the fork and add the mirror. This ensures I'll always have an up-to-date
mirror of qmk while also giving me a repo to make changes for my personal keyboards.

```bash
git clone git@gitea.reeseapps.com:ducoterra/qmk_firmware.git
cd qmk_firmware
git remote add mirror git@gitea.reeseapps.com:mirrors/qmk_firmware.git
git fetch mirror
git rebase mirror/master
pacman -S qmk
qmk setup
sudo cp /home/ducoterra/qmk_firmware/util/udev/50-qmk.rules /etc/udev/rules.d/
qmk config user.keyboard=keychron/q11/ansi_encoder
qmk config user.keymap=ducoterra
```

### Development

Every time you start a project you'll want to sync with the mirror.

```bash
git fetch mirror
git rebase mirror/master
```

Commit to master while you're in the fork.

## Cura

<https://ultimaker.com/software/ultimaker-cura/#links>

```bash
mv ~/Downloads/*Cura*.AppImage ~/Applications/Cura.AppImage
chmod +x ~/Applications/*.AppImage
```

```conf
[Desktop Entry]
Name=Cura
Exec=/home/ducoterra/Applications/Cura.AppImage
Icon=/home/ducoterra/.icons/cura.png
Type=Application
```

## Creality Print

<https://www.creality.com/pages/download-software?spm=..page_11657537.creality_print_1.1>

```bash
mv ~/Downloads/Creality_Print*.AppImage ~/Applications/Creality_Print.AppImage
chmod +x ~/Applications/*.AppImage
```

```conf
[Desktop Entry]
Name=Creality Print
Exec=/home/ducoterra/Applications/Creality_Print.AppImage
Icon=/home/ducoterra/.icons/creality_print.png
Type=Application
```

## Bambu Studio

Install with flatpak.

```bash
flatpak install com.bambulab.BambuStudio
```

### Firewall Rules for LAN Printer

For local LAN discovery allow 2021/udp

```bash
sudo ufw allow 2021/udp
sudo ufw reload
```

### Adding LAN printer via config

The config is located at `~/.var/app/com.bambulab.BambuStudio/config/BambuStudio/BambuStudio.conf`

At the very top of the config you can add a pin for a printer permanently with:

```json
"access_code": {
    "printer serial number": "access code here"
},
```

### Custom Filament Profiles

Custom profiles are located at
`.var/app/com.bambulab.BambuStudio/config/BambuStudio/user/default/filament/base`

Sync this with something like Nextcloud.


## Orca Slicer

<https://github.com/SoftFever/OrcaSlicer>

This is an open source fork of Bambu Slicer with more features.

```bash
# You might need to install webkit2gtk
pacman -S webkit2gtk
```

```bash
mv ~/Downloads/OrcaSlicer*.AppImage ~/Applications/OrcaSlicer.AppImage
chmod +x ~/Applications/*.AppImage
```

```conf
[Desktop Entry]
Name=Orca Slicer
Exec=/home/ducoterra/Applications/OrcaSlicer.AppImage
Icon=/home/ducoterra/.icons/orca_slicer.png
Type=Application
```

## AWS CLI

<https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html>

```bash
# Install less if you don't have it already
pacman -S less

cd ~/Downloads
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```

Add the following to your .zshrc:

```bash
complete -C '/usr/local/bin/aws_completer' aws
```

## NSlookup

```bash
# Do this in a toolbox
toolbox enter

# Install
pacman -S bind
```

## rpi-imager

<https://github.com/raspberrypi/rpi-imager>

```bash
toolbox create -d ubuntu -r 24.04
toolbox enter toolbox enter ubuntu-toolbox-24.04
sudo apt install rpi-imager
```

## qFlipper

<https://flipperzero.one/update>

```bash
mv ~/Downloads/*qFlipper*.AppImage ~/Applications/qFlipper.AppImage
chmod +x ~/Applications/*.AppImage
```

```conf
[Desktop Entry]
Name=qFlipper
Exec=/home/ducoterra/Applications/qFlipper.AppImage
Icon=/home/ducoterra/.icons/qFlipper.png
Type=Application
```

## Nextcloud Talk

<https://github.com/nextcloud-releases/talk-desktop/releases>

```bash
unzip ~/Downloads/Nextcloud.Talk-linux*.zip -d ~/Downloads
rm -rf ~/Applications/NextcloudTalk
mv ~/Downloads/'Nextcloud Talk-linux-x64' ~/Applications/NextcloudTalk
```

vim ~/.local/share/applications/nextcloud-talk.desktop

```conf
[Desktop Entry]
Name=Nextcloud Talk
Exec="/home/ducoterra/Applications/NextcloudTalk/Nextcloud Talk" --ozone-platform=wayland %U
Icon=/home/ducoterra/.icons/NextcloudTalk.png
Type=Application
```

```bash
update-desktop-database
```

## FFMpeg

```bash
# Select pipewire-jack when prompted
pacman -S ffmpeg
```

## Youtube-dlp

<https://github.com/yt-dlp/yt-dlp>

1. Download `yt-dlp_linux`
2. `clamdscan yt-dlp_linux`
3. `cp yt-dlp_linux /usr/local/bin/yt-dlp`
4. Install ffmpeg `pacman -S ffmpeg`

Download the best quality video:

```bash
yt-dlp -f "bv+ba/b" https://...
```

Download a playlist:

```bash
yt-dlp -f "bv+ba/b" --write-thumbnail https://www.youtube.com/watch?v=l-unefmAo9k&list=PLuYLhuXt4HrQqnfSceITmv6T_drx1hN84
```

## Iperf3

```bash
pacman -S iperf3
```

## Glances

```bash
pacman -S glances
```

## VirtualBox

<https://wiki.archlinux.org/title/VirtualBox>

For the linux kernel, choose virtualbox-host-modules-arch

```bash
pacman -S virtualbox

# Required reboot to load the kernel modules
reboot
```

## Email

- Download Proton Mail Bridge PKGBUILD: <https://proton.me/mail/bridge>

```bash
makepkg -si
```

- Open protonmail bridge and login
- Install geary email client

```bash
pacman -S geary
```

- Open geary
- Add the account following protonmail bridge's instructions

## Traffic Usage

Nethogs shows per-app network utilization.

```bash
pacman -S nethogs

# You'll need to run this with sudo if you aren't root
nethogs
```

## Wine

```bash
pacman -S wine
```

You can adjust the dpi scaling for wine with `winecfg`.

## KDE Connect (GSConnect)

Install the GSConnect extension for Gnome.

Open the firewall for connecting devices <https://userbase.kde.org/KDEConnect#Troubleshooting>

```bash
sudo ufw allow 1714:1764/udp
sudo ufw allow 1714:1764/tcp
sudo ufw reload
```

## Python

### Pyenv

<https://github.com/pyenv/pyenv?tab=readme-ov-file#installation>

```bash
curl https://pyenv.run | bash
```

Add to `~/.zshrc`:

```bash
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

Install and use a Python version:

```bash
pyenv install 3.13
pyenv global 3.13
```

### Poetry

<https://python-poetry.org/docs/>

```bash
python -m pip install --user pipx
python -m pipx ensurepath

pipx install poetry
pipx ensurepath # source ~/.zshrc or ~/.bashrc
```

Create a new project in the current directory

```bash
poetry new .
```

## Note Taking

```bash
flatpak install org.kde.marknote
```

## Calculator

```bash
flatpak install org.gnome.Calculator
```

## Disk Usqage

```bash
flatpak install org.gnome.baobab
```
