OK I’ve been meaning to write about this but I don’t have time rn. Let me just say, I finally have a KDE system that acts just like Gnome when you hit the Meta key (or super, or win, or whatever you call that key between left Ctrl and Alt). I’ve been using it for a couple weeks now and it totally works great. Hit me up in the comments if you want to light a fire under my arse to explain how I did it. Otherwise, stay tuned!
Category: Random
Name Your Distro: Flatpaks irritatingly don’t follow desktop theme (written specific to KDE / Plasma-Desktop 6)
This is not an issue with any Linux distro specifically, but with all distros in general. If anyone out there’s had this issue, I’m sure you’ve shared my pain. I’d struggled with getting flatpaks to follow the (dark) system theme I set for a while, and I finally just got it fixed, so I thought I’d run through the process real quick:
- make sure you’re setting a theme that has a flatpak version available (I chose
adw-gtk3{,-dark}
) - install the flatpak versions: as of writing,
gtk3
flatpak themes are the only ones you need to download, but if your theme doesn’t include agtk4
variant, YMMV - install the
gtk
themes for your desktop environment and ensure they are in the proper location - enable
gtk
themes ingsettings
- A couple last-ditch effort recommendations if 1-4 doesn’t work
Here’s the steps expanded:
Choose a theme you can get in a desktop version – a good place to see if you can find the theme you want is gnome-look.org. Make sure if you use both user and system flatpaks you have a theme for both (I personally only use userspace flatpaks from flathub to avoid complications) Here’s the current list of flatpak theme runtimes as of writing:
❯ clear && flatpak search --user --columns=app theme | grep org.gtk | sort -n
org.gtk.Gtk3theme.Adapta
org.gtk.Gtk3theme.Adapta-Brila
org.gtk.Gtk3theme.Adapta-Brila-Eta
org.gtk.Gtk3theme.Adapta-Eta
org.gtk.Gtk3theme.Adapta-Nokto
org.gtk.Gtk3theme.Adapta-Nokto-Eta
org.gtk.Gtk3theme.Adementary
org.gtk.Gtk3theme.Adwaita-dark
org.gtk.Gtk3theme.adw-gtk3
org.gtk.Gtk3theme.adw-gtk3-dark
org.gtk.Gtk3theme.Akwa
org.gtk.Gtk3theme.Akwa-dark
org.gtk.Gtk3theme.Akwa-light
org.gtk.Gtk3theme.Ambiance
org.gtk.Gtk3theme.Arc
org.gtk.Gtk3theme.Arc-Dark
org.gtk.Gtk3theme.Arc-Darker
org.gtk.Gtk3theme.Arc-Darker-solid
org.gtk.Gtk3theme.Arc-Dark-solid
org.gtk.Gtk3theme.Arc-Lighter
org.gtk.Gtk3theme.Arc-Lighter-solid
org.gtk.Gtk3theme.Arc-solid
org.gtk.Gtk3theme.Breeze
org.gtk.Gtk3theme.Catppuccin-blue
org.gtk.Gtk3theme.Catppuccin-green
org.gtk.Gtk3theme.Catppuccin-orange
org.gtk.Gtk3theme.Catppuccin-pink
org.gtk.Gtk3theme.Catppuccin-purple
org.gtk.Gtk3theme.Catppuccin-red
org.gtk.Gtk3theme.Catppuccin-teal
org.gtk.Gtk3theme.Catppuccin-yellow
org.gtk.Gtk3theme.Chicago95
org.gtk.Gtk3theme.Communitheme
org.gtk.Gtk3theme.CrosAdapta
org.gtk.Gtk3theme.deepin
org.gtk.Gtk3theme.deepin-dark
org.gtk.Gtk3theme.elementary
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Dark
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Darker
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Darker-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Darkest
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Darkest-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Darkest-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Darkest-Solid-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Dark-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Blue-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Green
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Dark
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Darker
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Darker-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Darkest
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Darkest-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Darkest-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Darkest-Solid-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Dark-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Green-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Red
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Dark
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Darker
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Darker-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Darkest
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Darkest-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Darkest-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Darkest-Solid-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Dark-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Red-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Dark
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Darker
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Darker-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Darkest
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Darkest-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Darkest-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Darkest-Solid-NoBorder
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Dark-Solid
org.gtk.Gtk3theme.Flat-Remix-GTK-Yellow-Solid
org.gtk.Gtk3theme.Greybird
org.gtk.Gtk3theme.Greybird
org.gtk.Gtk3theme.Greybird-dark
org.gtk.Gtk3theme.Greybird-Geeko-Dark
org.gtk.Gtk3theme.Greybird-Geeko-Light
org.gtk.Gtk3theme.Helium
org.gtk.Gtk3theme.Helium-dark
org.gtk.Gtk3theme.High-Sierra
org.gtk.Gtk3theme.High-Sierra-Dark
org.gtk.Gtk3theme.Jade-1
org.gtk.Gtk3theme.Jade-1-Amber
org.gtk.Gtk3theme.Jade-1-Aqua
org.gtk.Gtk3theme.Jade-1-Blue
org.gtk.Gtk3theme.Jade-1-Gray
org.gtk.Gtk3theme.Jade-1-Green
org.gtk.Gtk3theme.Jade-1-Indigo
org.gtk.Gtk3theme.Jade-1-Purple
org.gtk.Gtk3theme.Jade-1-Red
org.gtk.Gtk3theme.Jade-1-Teal
org.gtk.Gtk3theme.Lounge
org.gtk.Gtk3theme.Lounge-compact
org.gtk.Gtk3theme.Lounge-night
org.gtk.Gtk3theme.Lounge-night-compact
org.gtk.Gtk3theme.Matcha-aliz
org.gtk.Gtk3theme.Matcha-azul
org.gtk.Gtk3theme.Matcha-dark-aliz
org.gtk.Gtk3theme.Matcha-dark-azul
org.gtk.Gtk3theme.Matcha-dark-pueril
org.gtk.Gtk3theme.Matcha-dark-sea
org.gtk.Gtk3theme.Matcha-light-aliz
org.gtk.Gtk3theme.Matcha-light-azul
org.gtk.Gtk3theme.Matcha-light-pueril
org.gtk.Gtk3theme.Matcha-light-sea
org.gtk.Gtk3theme.Matcha-pueril
org.gtk.Gtk3theme.Matcha-sea
org.gtk.Gtk3theme.Materia
org.gtk.Gtk3theme.Materia-compact
org.gtk.Gtk3theme.Materia-dark
org.gtk.Gtk3theme.Materia-dark-compact
org.gtk.Gtk3theme.Materia-light
org.gtk.Gtk3theme.Materia-light-compact
org.gtk.Gtk3theme.Materia-nord
org.gtk.Gtk3theme.Materia-nord-compact
org.gtk.Gtk3theme.Mint-Y
org.gtk.Gtk3theme.Mint-Y-Aqua
org.gtk.Gtk3theme.Mint-Y-Blue
org.gtk.Gtk3theme.Mint-Y-Brown
org.gtk.Gtk3theme.Mint-Y-Dark
org.gtk.Gtk3theme.Mint-Y-Dark-Aqua
org.gtk.Gtk3theme.Mint-Y-Dark-Blue
org.gtk.Gtk3theme.Mint-Y-Dark-Brown
org.gtk.Gtk3theme.Mint-Y-Darker
org.gtk.Gtk3theme.Mint-Y-Darker-Aqua
org.gtk.Gtk3theme.Mint-Y-Darker-Blue
org.gtk.Gtk3theme.Mint-Y-Darker-Brown
org.gtk.Gtk3theme.Mint-Y-Darker-Grey
org.gtk.Gtk3theme.Mint-Y-Darker-Orange
org.gtk.Gtk3theme.Mint-Y-Darker-Pink
org.gtk.Gtk3theme.Mint-Y-Darker-Purple
org.gtk.Gtk3theme.Mint-Y-Darker-Red
org.gtk.Gtk3theme.Mint-Y-Darker-Sand
org.gtk.Gtk3theme.Mint-Y-Darker-Teal
org.gtk.Gtk3theme.Mint-Y-Dark-Grey
org.gtk.Gtk3theme.Mint-Y-Dark-Orange
org.gtk.Gtk3theme.Mint-Y-Dark-Pink
org.gtk.Gtk3theme.Mint-Y-Dark-Purple
org.gtk.Gtk3theme.Mint-Y-Dark-Red
org.gtk.Gtk3theme.Mint-Y-Dark-Sand
org.gtk.Gtk3theme.Mint-Y-Dark-Teal
org.gtk.Gtk3theme.Mint-Y-Grey
org.gtk.Gtk3theme.Mint-Y-Orange
org.gtk.Gtk3theme.Mint-Y-Pink
org.gtk.Gtk3theme.Mint-Y-Purple
org.gtk.Gtk3theme.Mint-Y-Red
org.gtk.Gtk3theme.Mint-Y-Sand
org.gtk.Gtk3theme.Mint-Y-Teal
org.gtk.Gtk3theme.Mojave-light
org.gtk.Gtk3theme.Numix
org.gtk.Gtk3theme.Numix-Frost
org.gtk.Gtk3theme.Numix-Frost-Light
org.gtk.Gtk3theme.Obsidian-2
org.gtk.Gtk3theme.Obsidian-2-Amber
org.gtk.Gtk3theme.Obsidian-2-Aqua
org.gtk.Gtk3theme.Obsidian-2-Gray
org.gtk.Gtk3theme.Obsidian-2-Green
org.gtk.Gtk3theme.Obsidian-2-Indigo
org.gtk.Gtk3theme.Obsidian-2-Mint
org.gtk.Gtk3theme.Obsidian-2-Purple
org.gtk.Gtk3theme.Obsidian-2-Red
org.gtk.Gtk3theme.Obsidian-2-Teal
org.gtk.Gtk3theme.Plata
org.gtk.Gtk3theme.Plata
org.gtk.Gtk3theme.Plata-Compact
org.gtk.Gtk3theme.Plata-Compact
org.gtk.Gtk3theme.Plata-Lumine
org.gtk.Gtk3theme.Plata-Lumine
org.gtk.Gtk3theme.Plata-Lumine-Compact
org.gtk.Gtk3theme.Plata-Lumine-Compact
org.gtk.Gtk3theme.Plata-Noir
org.gtk.Gtk3theme.Plata-Noir
org.gtk.Gtk3theme.Plata-Noir-Compact
org.gtk.Gtk3theme.Plata-Noir-Compact
org.gtk.Gtk3theme.Pop
org.gtk.Gtk3theme.Pop-dark
org.gtk.Gtk3theme.Pop-light
org.gtk.Gtk3theme.Pop-slim-dark
org.gtk.Gtk3theme.Pop-slim-light
org.gtk.Gtk3theme.Qogir
org.gtk.Gtk3theme.Qogir
org.gtk.Gtk3theme.Qogir-dark
org.gtk.Gtk3theme.Qogir-light
org.gtk.Gtk3theme.Qogir-light
org.gtk.Gtk3theme.Qogir-manjaro
org.gtk.Gtk3theme.Qogir-manjaro
org.gtk.Gtk3theme.Qogir-manjaro-dark
org.gtk.Gtk3theme.Qogir-manjaro-dark
org.gtk.Gtk3theme.Qogir-manjaro-light
org.gtk.Gtk3theme.Qogir-manjaro-light
org.gtk.Gtk3theme.Qogir-manjaro-win
org.gtk.Gtk3theme.Qogir-manjaro-win
org.gtk.Gtk3theme.Qogir-manjaro-win-dark
org.gtk.Gtk3theme.Qogir-manjaro-win-dark
org.gtk.Gtk3theme.Qogir-manjaro-win-light
org.gtk.Gtk3theme.Qogir-manjaro-win-light
org.gtk.Gtk3theme.Qogir-ubuntu
org.gtk.Gtk3theme.Qogir-ubuntu
org.gtk.Gtk3theme.Qogir-ubuntu-dark
org.gtk.Gtk3theme.Qogir-ubuntu-dark
org.gtk.Gtk3theme.Qogir-ubuntu-light
org.gtk.Gtk3theme.Qogir-ubuntu-light
org.gtk.Gtk3theme.Qogir-ubuntu-win
org.gtk.Gtk3theme.Qogir-ubuntu-win
org.gtk.Gtk3theme.Qogir-ubuntu-win-dark
org.gtk.Gtk3theme.Qogir-ubuntu-win-dark
org.gtk.Gtk3theme.Qogir-ubuntu-win-light
org.gtk.Gtk3theme.Qogir-ubuntu-win-light
org.gtk.Gtk3theme.Qogir-win
org.gtk.Gtk3theme.Qogir-win
org.gtk.Gtk3theme.Qogir-win-dark
org.gtk.Gtk3theme.Qogir-win-dark
org.gtk.Gtk3theme.Qogir-win-light
org.gtk.Gtk3theme.Qogir-win-light
org.gtk.Gtk3theme.Sierra-Negra
org.gtk.Gtk3theme.SolArc-Dark
org.gtk.Gtk3theme.Yaru
org.gtk.Gtk3theme.Yaru-Amber
org.gtk.Gtk3theme.Yaru-Amber
org.gtk.Gtk3theme.Yaru-Amber-dark
org.gtk.Gtk3theme.Yaru-Amber-dark
org.gtk.Gtk3theme.Yaru-Amber-light
org.gtk.Gtk3theme.Yaru-Amber-light
org.gtk.Gtk3theme.Yaru-Aqua
org.gtk.Gtk3theme.Yaru-Aqua
org.gtk.Gtk3theme.Yaru-Aqua-dark
org.gtk.Gtk3theme.Yaru-Aqua-dark
org.gtk.Gtk3theme.Yaru-Aqua-light
org.gtk.Gtk3theme.Yaru-Aqua-light
org.gtk.Gtk3theme.Yaru-Aubergine
org.gtk.Gtk3theme.Yaru-Aubergine-dark
org.gtk.Gtk3theme.Yaru-Aubergine-light
org.gtk.Gtk3theme.Yaru-bark
org.gtk.Gtk3theme.Yaru-bark-dark
org.gtk.Gtk3theme.Yaru-Blue
org.gtk.Gtk3theme.Yaru-Blue
org.gtk.Gtk3theme.Yaru-Blue-dark
org.gtk.Gtk3theme.Yaru-Blue-dark
org.gtk.Gtk3theme.Yaru-Blue-light
org.gtk.Gtk3theme.Yaru-Blue-light
org.gtk.Gtk3theme.Yaru-Brown
org.gtk.Gtk3theme.Yaru-Brown
org.gtk.Gtk3theme.Yaru-Brown-dark
org.gtk.Gtk3theme.Yaru-Brown-dark
org.gtk.Gtk3theme.Yaru-Brown-light
org.gtk.Gtk3theme.Yaru-Brown-light
org.gtk.Gtk3theme.Yaru-Cinnamon
org.gtk.Gtk3theme.Yaru-Cinnamon
org.gtk.Gtk3theme.Yaru-Cinnamon-dark
org.gtk.Gtk3theme.Yaru-Cinnamon-dark
org.gtk.Gtk3theme.Yaru-Cinnamon-light
org.gtk.Gtk3theme.Yaru-Cinnamon-light
org.gtk.Gtk3theme.Yaru-dark
org.gtk.Gtk3theme.Yaru-Deepblue
org.gtk.Gtk3theme.Yaru-Deepblue
org.gtk.Gtk3theme.Yaru-Deepblue-dark
org.gtk.Gtk3theme.Yaru-Deepblue-dark
org.gtk.Gtk3theme.Yaru-Deepblue-light
org.gtk.Gtk3theme.Yaru-Deepblue-light
org.gtk.Gtk3theme.Yaru-Green
org.gtk.Gtk3theme.Yaru-Green
org.gtk.Gtk3theme.Yaru-Green-dark
org.gtk.Gtk3theme.Yaru-Green-dark
org.gtk.Gtk3theme.Yaru-Green-light
org.gtk.Gtk3theme.Yaru-Green-light
org.gtk.Gtk3theme.Yaru-Grey
org.gtk.Gtk3theme.Yaru-Grey
org.gtk.Gtk3theme.Yaru-Grey-dark
org.gtk.Gtk3theme.Yaru-Grey-dark
org.gtk.Gtk3theme.Yaru-Grey-light
org.gtk.Gtk3theme.Yaru-Grey-light
org.gtk.Gtk3theme.Yaru-Lavender
org.gtk.Gtk3theme.Yaru-Lavender-dark
org.gtk.Gtk3theme.Yaru-Lavender-light
org.gtk.Gtk3theme.Yaru-light
org.gtk.Gtk3theme.Yaru-magenta
org.gtk.Gtk3theme.Yaru-magenta-dark
org.gtk.Gtk3theme.Yaru-MATE
org.gtk.Gtk3theme.Yaru-MATE
org.gtk.Gtk3theme.Yaru-MATE-dark
org.gtk.Gtk3theme.Yaru-MATE-dark
org.gtk.Gtk3theme.Yaru-MATE-light
org.gtk.Gtk3theme.Yaru-MATE-light
org.gtk.Gtk3theme.Yaru-olive
org.gtk.Gtk3theme.Yaru-olive-dark
org.gtk.Gtk3theme.Yaru-Orange
org.gtk.Gtk3theme.Yaru-Orange
org.gtk.Gtk3theme.Yaru-Orange-dark
org.gtk.Gtk3theme.Yaru-Orange-dark
org.gtk.Gtk3theme.Yaru-Orange-light
org.gtk.Gtk3theme.Yaru-Orange-light
org.gtk.Gtk3theme.Yaru-Pink
org.gtk.Gtk3theme.Yaru-Pink
org.gtk.Gtk3theme.Yaru-Pink-dark
org.gtk.Gtk3theme.Yaru-Pink-dark
org.gtk.Gtk3theme.Yaru-Pink-light
org.gtk.Gtk3theme.Yaru-Pink-light
org.gtk.Gtk3theme.Yaru-prussiangreen
org.gtk.Gtk3theme.Yaru-prussiangreen-dark
org.gtk.Gtk3theme.Yaru-Purple
org.gtk.Gtk3theme.Yaru-Purple
org.gtk.Gtk3theme.Yaru-Purple-dark
org.gtk.Gtk3theme.Yaru-Purple-dark
org.gtk.Gtk3theme.Yaru-Purple-light
org.gtk.Gtk3theme.Yaru-Purple-light
org.gtk.Gtk3theme.Yaru-Red
org.gtk.Gtk3theme.Yaru-Red
org.gtk.Gtk3theme.Yaru-Red-dark
org.gtk.Gtk3theme.Yaru-Red-dark
org.gtk.Gtk3theme.Yaru-Red-light
org.gtk.Gtk3theme.Yaru-Red-light
org.gtk.Gtk3theme.Yaru-remix
org.gtk.Gtk3theme.Yaru-remix-dark
org.gtk.Gtk3theme.Yaru-remix-light
org.gtk.Gtk3theme.Yaru-sage
org.gtk.Gtk3theme.Yaru-sage-dark
org.gtk.Gtk3theme.Yaru-Teal
org.gtk.Gtk3theme.Yaru-Teal
org.gtk.Gtk3theme.Yaru-Teal-dark
org.gtk.Gtk3theme.Yaru-Teal-dark
org.gtk.Gtk3theme.Yaru-Teal-light
org.gtk.Gtk3theme.Yaru-Teal-light
org.gtk.Gtk3theme.Yaru-Yellow
org.gtk.Gtk3theme.Yaru-Yellow-dark
org.gtk.Gtk3theme.Yaru-Yellow-dark
org.gtk.Gtk3theme.Yaru-Yellow-light
org.gtk.Gtk3theme.Yaru-Yellow-light
org.gtk.Gtk3theme.Zukitre
org.gtk.Gtk3theme.Zukitwo
You can see at the top of the list adw-gtk3
and adw-gtk3-dark
are separate packages, so if you wanted to support both light and dark modes, install them both:
❯ for T in adw-gtk3 adw-gtk3-dark; do flatpak install -uy org.gtk.Gtk3theme.$T; done
Code language: Bash (bash)
See if there’s a packaged or scripted version of the same theme on your distro before installing from Gnome Look – I lucked out and there was one already in the AUR (number 3 looked good to me!):
❯ paru -Ss adw-gtk3
<strong>aur</strong>/<strong>adw-gtk35.3-1</strong> [<strong>+43 ~3.15</strong>]
The theme from libadwaita ported to GTK-3
<strong>aur</strong>/<strong>adw-gtk3-git1.0.r2.a2a0114-1</strong> [<strong>+15 ~1.21</strong>]
The theme from libadwaita ported to GTK-3
<strong>aur</strong>/<strong>adw-gtk-theme1.1-2</strong> [<strong>+12 ~1.00</strong>]
LibAdwaita Theme for all GTK3 and GTK4 Apps. NOTE: This is a meta package
which uses adw-gtk3 for GTK3 and official LibAdwaita theme for GTK4
Code language: Bash (bash)
If you do have to install a theme package manually, just remember they can go in either /usr/share/themes/.
(system-wide) or $HOME/.local/share/themes
(user), but not both!
Go to kcm_style
in your KDE settings panel and choose “Configure GNOME/GTK Application Style” (top right)
❯ systemsettings <strong>kcm</strong>_style
Code language: Bash (bash)
Last step (hopefully):
Tell gsettings
your defaults – this has to be done from the command line unless you have dconf-editor
or gnome-tweaks
installed for some reason (unusual and unnecessary for a KDE-centric system). Here’s the key-value pairs:
❯ gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark';
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
Code language: Bash (bash)
Replace the values at the end with your particular theme and preference, of course (again, I choose adw-gtk3-dark
, mostly because I knew it would be the best supported theme). Obviously, if you don’t 'prefer-dark'
that second line is optional.
OK now try starting one of the flatpaks you’ve been having issues with and see how it went!
If it’s still not loading in your preferred theme, I’d go back and check the steps to make sure you covered them properly. You can try gsettings get
on org.gnome.desktop.interface gtk-theme
to check that it has your proper value, or check /usr/share/themes
to make sure a folder exists with the name of the theme you thought you installed (manually or with a package manager) or $HOME/.local/share/themes/
if you installed it manually to your user folder.
If those all seem legit, check out xsettingsd
: It looks like it’s a dependency of kde-gtk-config
on Arch Linux currently, so you might already have it:
❯ pacman -Qi xsettingsd
Name : xsettingsd
Version : 1.0.2-1
Description : Provides settings to X11 applications via the XSETTINGS specification
Architecture : x86_64
URL : https://github.com/derat/xsettingsd
Licenses : custom:BSD
Groups : None
Provides : None
Depends On : libx11 gcc-libs
Optional Deps : None
Required By : kde-gtk-config
Optional For : None
Conflicts With : None
Replaces : None
Installed Size : 78.82 KiB
Packager : Antonio Rojas <arojas@archlinux.org>
Build Date : Mon 09 Aug 2021 04:16:10 AM PDT
Install Date : Sat 16 Mar 2024 10:31:30 PM PDT
Install Reason : Installed as a dependency for another package
Install Script : No
Validated By : Signature
Code language: Bash (bash)
Do the usual checks to make sure it’s running (it’s only visible using systemctl --user
in Arch):
❯ systemctl --user status xsettingsd.service
● xsettingsd.service - XSETTINGS-protocol daemon
Loaded: loaded (/usr/lib/systemd/user/xsettingsd.service; static)
Active: active (running) since Sat 2024-03-23 14:35:18 PDT; 1h 52min ago
Main PID: 469119 (xsettingsd)
Tasks: 1 (limit: 9084)
Memory: 156.0K (peak: 696.0K swap: 344.0K swap peak: 344.0K zswap: 55.8K)
CPU: 4ms
CGroup: /user.slice/user-1000.slice/user@1000.service/session.slice/xsettingsd.service
└─469119 /usr/bin/xsettingsd
Mar 23 14:35:18 purplehippo systemd[1283]: Started XSETTINGS-protocol daemon.
Mar 23 14:35:18 purplehippo xsettingsd[469119]: xsettingsd: Loaded 14 settings from /home/avery/.config/xsettingsd/xsettingsd.conf
Mar 23 14:35:18 purplehippo xsettingsd[469119]: xsettingsd: Created window 0xc00001 on screen 0 with timestamp 5373106
Mar 23 14:35:18 purplehippo xsettingsd[469119]: xsettingsd: Selection _XSETTINGS_S0 is owned by 0x0
Mar 23 14:35:18 purplehippo xsettingsd[469119]: xsettingsd: Took ownership of selection _XSETTINGS_S0
Mar 23 14:53:07 purplehippo xsettingsd[469119]: xsettingsd: Reloading configuration
Mar 23 14:53:07 purplehippo xsettingsd[469119]: xsettingsd: Loaded 14 settings from /home/avery/.config/xsettingsd/xsettingsd.conf
Code language: JavaScript (javascript)
If it’s having an issue, try restarting it, or you can examine the configuration file it creates automatically in your $XDG_CONFIG_HOME
dir and make sure it all looks reasonable:
❯ bat $XDG_CONFIG_HOME/xsettingsd/xsettingsd.conf
──────┬──────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: /home/avery/.config/xsettingsd/xsettingsd.conf
──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ Gdk/UnscaledDPI 98304
2 │ Gdk/WindowScalingFactor 1
3 │ Gtk/EnableAnimations 1
4 │ Gtk/DecorationLayout "icon:minimize,maximize,close"
5 │ Net/ThemeName "adw-gtk3-dark"
6 │ Gtk/PrimaryButtonWarpsSlider 0
7 │ Gtk/ToolbarStyle 3
8 │ Gtk/MenuImages 1
9 │ Gtk/ButtonImages 1
10 │ Gtk/CursorThemeSize 64
11 │ Gtk/CursorThemeName "Posy_Cursor_125_175"
12 │ Net/SoundThemeName "ocean"
13 │ Net/IconThemeName "Papirus"
14 │ Gtk/FontName "Noto Sans, 10"
15 │
──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────
Code language: JavaScript (javascript)
if THAT all looks fine, there was one last thing on wiki.archlinux.org that looked like it might work (especially with Window Manager-type setups like minimal tiling desktop such as sway and dwm – although, if you’re into minimal WMs, not sure if you’d like flatpaks – in any event, nobody’s a monolith…). You could put something like this in $HOME/bin
and call it refresh-flatpak-themes
(etc.) then run it when you see one getting dodgy:
#!/usr/bin/env bash
for FLATPAK_APP in "$HOME/.var/app/*"; do
[ -d "$HOME/.var/app/$FLATPAK_APP/config/gtk-3.0" ] ||
/usr/bin/ln -s "$HOME/.config/gtk-3.0" "$HOME/.var/app/$FLATPAK_APP/config/"
done
Code language: JavaScript (javascript)
Which basically just loops through each flatpak app you have in your user’s .var
folder, checks to see if it has a gtk-3.0
definition folder, and if not, makes a symbolic link to where one usually lives in your $XDG_CONFIG_HOME
. You could try making the symlink to one manually to see if it works before setting up a script, but if it works out, hey, go for it.
Another option I saw which looks pretty elegant is outlined here on a xerolinux-specific BB, but should apply to pretty much any distro using the xdg user-dirs
spec:
❯ export GTK3_THEME=(name of preferred theme);
flatpak --user override --filesystem=$HOME/.local/share/themes;
flatpak --user override --filesystem=$XDG_CONFIG_HOME/gtk-3.0:ro;
for FLATPAK_APP in $HOME/.var/app/*; do flatpak --user override \
$FLATPAK_APP --env=GTK_THEME=$GTK3_THEME; done
Code language: PHP (php)
Quick pointers for troubleshooting:
- The
user-dirs.dirs
file usually lives at $HOME/.config/user-dirs.dirs
- Any
$VARIABLE
can be echoed to the screen using echo $VARNAME
(make sure they’re properly set)
Windows Server Core: Setting a New IP Address For Your DC (including IPv6 & Client DNS)
I’ve been working on moving to Windows Server Core for my DCs, and getting adjusted to PowerShell has been slightly daunting, as the only CLI I’m really familiar with is Unix-based, and, while there are similarties to be sure, they are also very different in a lot of respects. There’s a plethora of remote-based GUI programs for configuring Core servers available that are useful as “training wheels”, like Windows Admin Center (aka Webmin for Windows) and the ever-ubiquitous RSAT tools, which are desktop applications that, by using WinRM, can manage remote machines – programs like Server Manager, ADUC, PSRemoting (aka MS-SSH – hint: just use SSH), and time-tested (old) MMC snap-ins.
But what if you just want to get something essential done, especially if you don’t have remote access available? Well, there’s actually a lot of options still: The Sconfig TUI program, which is always included, but it’s extremely limited in scope, and I’ve realized through difficult experiences can be problematic (more later).
You actually can use MMC locally on a Server Core machine, but it’s more limited in snap-ins, and often these don’t cover what you need.
I’ve learned through installing RocketDock for giggles (honorable mention) there actually is an instance of the control panel on Windows Server Core (I had read otherwise), but it’s pretty :sad trombone:.
If none of those fit your necessities, you’re looking at using netsh
, wmic
, or PowerShell. Thankfully, they are all fairly comprehensive and easy to learn, even if they have completely different syntax from anything you’ve had to rely on CLI commands over the past few decades.
OK, enough rant and external links. Here’s something I discovered pawing through the MS wiki and random blog posts about configuring my DCs IP addresses.
I’ve had to re-configure the IPs on my DCs now a couple times since I’ve been migrating them between hosts to deal with hardware upgrades. Every time I clone one and start it on a new machine, it either resets the NIC to DHCP or a link-local address, so I have to re-set the static IP manually and (sometimes) re-authorize the connection to the domain (on the domain controller … irony?).
Setting your IP address is obviously trivial on a Server instance with Desktop Experience. Observe:
Server Core should be even easier since the SConfig menu pops up whenever you log in, but Sconfig routinely fails to accept a static configuration. Observe:
Note, if you hate that SConfig pops up when you log in, you can disable it with the cmdlet Set-SConfig, ala:
Set-SConfig -AutoLaunch $false
Code language: JavaScript (javascript)
TL;DR
That was an incredibly long wind-up to say, here’s how to set the NetIPAddress
and DnsClientServerAddress
in Windows Server Core
Synopsis:
- If you’ve got a pre-existing static IP, be sure to delete it first (
Remove-NetIPAddress
) - If you’ve got DHCP configured, disable it first (
Set-NetIPInterface
) - Use
New-NetIPAddress
to create your new address (notSet-NetIPInterface
) - Use
Set-DnsClientServerAddress
to point to your DNS forwarders – which, in my case, are these very DCs I’m configuring
Basics – gathering necessary info: Get-NetIPInterface
will give you a list of network adapters inside your machine currently (including loopback
):
PS C:\Users\administrator.DOMAIN> Get-NetIPInterface
ifIndex InterfaceAlias AddressFamily NlMtu(Bytes) InterfaceMetric
------- -------------- ------------- ------------ ---------------
4 Ethernet0 IPv6 1500 15
1 Loopback Pseudo-Interface 1 IPv6 4294967295 75
4 Ethernet0 IPv4 1500 15
1 Loopback Pseudo-Interface 1 IPv4 4294967295 75
Code language: CSS (css)
Get-NetIPConfiguration
will give you more info about a given interface (you can identify it with -InterfaceIndex
(e.g. 4
), or -InterfaceAlias
(e.g. Ethernet0
)
PS C:\Users\administrator.DOMAIN> Get-NetIPConfiguration
InterfaceAlias : Ethernet0
InterfaceIndex : 4
InterfaceDescription : vmxnet3 Ethernet Adapter
NetProfile.Name : webtool.space
IPv6Address : 2601::dead
2601::beef
IPv4Address : 10.0.0.33
IPv6DefaultGateway : fe80::f00d
IPv4DefaultGateway : 10.0.0.1
DNSServer : ::1
10.0.0.3
10.0.0.33
Code language: CSS (css)
Removing an old configured IP address:Remove-NetIPAddress
can help you get rid of that old, pesky address that might be stopping you from employing a new one (if they’re on the same subnet, they’ll probably co-exist peacefully, but different subnets = food for gremlins)
Remove-NetIPAddress -AddressFamily IPv4 -IPAddress '192.168.21.3' -Confirm:$false
Code language: JavaScript (javascript)
You can pipe these commands to some extent with Get-
and Set-NetIPInterface
– here’s an example (albeit, not a very good one since it requires more typing):
Get-NetIPInterface -InterfaceIndex 4 | Set-NetIPInterface -AddressFamily IPv6 -Dhcp Disabled
Code language: JavaScript (javascript)
The one you’re probably really after isn’t Set-NetIPInterface
, but New-NetIPInterface
. That kind of threw me off at first, but it’s reflected in how the workflow expects you to delete prior addresses (before creating a new one, right?)
PS C:\Users\administrator.DOMAIN> New-NetIPAddress -InterfaceIndex 4 -AddressFamily IPv6 -IPAddress '2601::dc01' -PrefixLength 64 -DefaultGateway '2601::beef'
IPAddress : 2601::dc01
InterfaceIndex : 4
InterfaceAlias : Ethernet0
AddressFamily : IPv6
Type : Unicast
PrefixLength : 64
PrefixOrigin : Manual
SuffixOrigin : Manual
AddressState : Tentative
ValidLifetime : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource : False
PolicyStore : ActiveStore
IPAddress : 2601::dc01
InterfaceIndex : 4
InterfaceAlias : Ethernet0
AddressFamily : IPv6
Type : Unicast
PrefixLength : 64
PrefixOrigin : Manual
SuffixOrigin : Manual
AddressState : Invalid
ValidLifetime : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource : False
PolicyStore : PersistentStore
Code language: PHP (php)
DNS Client configuration:
Now that your IP and Gateway are set, the only thing missing is your DNS settings, right? Since this is a DC, I’m going to point it towards myself and the other DC.
Set-DnsClientServerAddress -InterfaceIndex 4 -ServerAddresses ('2601::dc01','2601::dc02')
InterfaceAlias : Ethernet0
InterfaceIndex : 4
InterfaceDescription : vmxnet3 Ethernet Adapter
NetProfile.Name : webtool.space
IPv6Address : 2601::dc01
IPv4Address : 10.0.0.33
IPv6DefaultGateway : {2601::f00d,
fe80::f00d}
IPv4DefaultGateway : 10.0.0.1
DNSServer : 2601::dc01
2601::dc02
10.0.0.3
10.0.0.33
Code language: PHP (php)
OK, this post ended up being way longer than I anticipated, but that’s how you get the basics of your network adapter working again if SConfig takes the ultimate dump when trying to use it to configure your Server Core network interfaces. Enjoy!
Simple HTTP Server for sending local images to Rancher’s Harvester HCI OS
I haven’t gotten very far with Harvester yet, having taken down the first cluster I built to re-purpose resources, but I thought I’d explore it again for running some VMS (security video recording) packages at a local business so we can avoid ESXi license costs and potentially scale-out (add servers) in the future without having to get even more licenses for vCenter and use up even more resources.
Harvester’s concept is super cool – set up Kubernetes infrastructure and use it for “legacy workloads” (aka VMs). Contrary to what a lot of other bloggers have written, Harvester does not run containers, so don’t get it twisted. That’s what Rancher is for. (side note: This misinformation got me running down a rabbit hole months ago when I stood up my first Harvester cluster thinking I was going to run a container for my TV recorder. I couldn’t figure out why there was no way to access the container layer, until finally I wrote the developers and they informed me there was no way to access it because it doesn’t exist.)
“Legacy workloads” are completely what we’d planned to run at this business anyway, so that’s just fine. Most decent VMS (video management systems) run in Windows, but we’d like to have some of the features only available via hypervisors, like cloning and testing new systems, or performing updates, without having to take the VM currently in production down or buy another physical machine. Harvester brings it to another level with the easy scale-out (adding more servers), and having cluster-awareness and high-availability embedded by design.
Of course, none of that matters if you can’t get your damn VMs to run, which is the first problem I ran into when I started the thing up. How do I get these clones of existing machines into the storage layer so I can create some new VMs around them?
Harvester only offers two options for creating an image:
- Provide a URL that responds to an HTTP GET request for a file that’s a consumable disk-image format (currently qcow2, raw/img or iso)
- Upload one of the aforementioned images via a web browser
I was pretty bummed these were the only options when I started out, as I had already connected a disk with my images to the host machine, thinking I could just copy the files from the disk to a particular location on the host filesystem. I should have probably RTFM, as this option (which is the most intuitive to me, but, alas) totally does not exist.
So I turned off the host and dug the NVMe with my images out, and popped it in a USB enclosure, thinking I’d use the upload option from my laptop. I watched the progress bar for long enough to know when to walk away – the file was 23GB, so I knew it should take a while – but the whole thing left me feeling uneasy that the process wouldn’t work. Sure enough, when I returned to the upload page, there was a “context cancelled” error. I tried it two more times, but Harvester kept thinking I had cancelled the upload at 99% finished. I am fairly certain I encountered a bug, but no time to file an issue, I’ve gotta see if this thing will even function for our workloads, and this wasn’t instilling me with the utmost confidence.
It seems like the “URL” option for providing disk images is the more mature of the two options, so I thought I’d look into running a local web server that would respond to a GET request with my image files. This turned out to be super easy, as basically every computer has or can get a copy of python without any trouble. Python has a built-in web server that simply provides whatever files are in the same directory in which it’s run by responding to GET requests and serving them up.
If you’ve got python installed, try it out. On my “server” machine, which in my case was my laptop, I had to do a few things to get it ready. Namely, make sure port 80 was open in my firewall, and make sure I was using the correct zone on my WIFI connection (for the port I had just opened) – I’m on Fedora 37, so if you’re using another OS, you should probably read this instead:
# check current connection:
nmcli con show
NAME UUID TYPE DEVICE
rabbit_hole e130190c-0c3b-4e22-8dc3-ebedc31a7d75 wifi wlp58s0
EastsideBigTom a51d9139-89bf-4a4f-9cad-25aaf3a8a2b0 wifi --
lan on the run 83afc4e0-a0bb-4b62-9437-59478a523da9 wifi --
Wired connection 1 eadbe5cc-ad09-4e43-8ad1-b24412a8610e ethernet --
# check to see if current connection is configured for a zone:
nmcli con show rabbit_hole | grep zone
connection.zone: --
# assign a zone to the current connection since it's not configured:
sudo nmcli con mod rabbit_hole connection.zone home
# make sure it worked:
nmcli con show rabbit_hole | grep zone
connection.zone: home
# open the port in the firewall - you can use any number up to 65536, but I chose 80 so I wouldn't have to use the port notation:
sudo firewall-cmd --zone=home --add-port=80/tcp --permanent
sudo firewall-cmd --reload
Code language: PHP (php)
If you are OK with this hole being open in your firewall indefinitely, use the --permanent
flag for firewall-cmd
, otherwise leave it out, and once your firewall is restarted it should be closed.
Now I set up a very rudimentary test to make sure the web server is responding to GET requests, since the machine will respond to a ping, but that’s not very helpful, considering ICMP is a completely different protocol than HTTP:
### on "server" machine (aka laptop, etc.) ###
# navigate to the folder with the files you want to send to Harvester:
cd /path/to/disk/images/you/are/going/to/transfer
# put some gibberish in a file to be served up on a GET request:
echo 'server working' > index.html
# start the actual http server (needs root privileges to attach to socket):
sudo python -m http.server 80
### in Harvester node console ###
# make GET request to "server" for the test gibberish file you created:
curl http://10.0.0.207/index.html
Code language: PHP (php)
You should see the words “server working
” in your Harvester console. If it didn’t work, make sure you spelled everything right, etc. If you don’t know the IP address of your “server”, you can run ip a
in your console and it’ll let you know. If you’re not sure which network you’re on, you should probably get a new hobby.
Anyway, now go back to the image menu in Harvester’s web UI, and provide the ip address of your “server” to create images from your files on your node. Make sure you spell everything properly, including using eXaCt SaMe CaSe. Unlike Google, Harvester won’t figure out what you meant if there’s tyops.
This method has proven far more reliable (well, in my case, actually worked) than trying to upload a local file, which is kind of hilarious given it is still uploading the files from the same machine (go figure). Providing files from a local URL also lets you queue a bunch of them to send at once, a definite time-saver. The upload function has an ominous warning not to leave the page or refresh your browser, so in this case you can navigate away from the page without fear of trashing (and painfully re-initiating) your arduously instigated multi-GB transfer process.
Give it a shot!
Install Fedora 36 from RAW disk image on WSL – for free – by using WSL
Some people are charging for Fedora in the Windows store. I guess it’s good work if you can get it (?) Charging for someone else’s free OS seems kinda lame to me, but I don’t mind getting my hands dirty.
I could see this process being intimidating for some people, for them $5.99 might be a worthwhile investment to be able to not do what I explain herein. But if that’s the case, it’s probably better you just don’t use Linux to begin with. Those are the people for whom paying like 2000% more for a Macintosh is like, totally worth it. You know who you are.
Note: you do need a working installation of WSL (like the Ubuntu base image), or a linux machine to do this on to start with. Or you could try a util like imdisk
in Windows, but I couldn’t figure it out, so I used WSL since I already knew how this process could be achieved in Linux (fairly easily).
Open up a command prompt in Windows and find suitable dir for downloading a large file, such as:
cd %USERPROFILE%\Downloads
download raw – e.g.:
wget https://mirror.sfo12.us.leaseweb.net/fedora/linux/releases/36/Cloud/x86_64/images/Fedora-Cloud-Base-36-1.5.x86_64.raw.xz
Code language: JavaScript (javascript)
I chose Fedora Cloud, which is pretty cool, mainly just because it was available in a .raw
file, while Fedora Server was only available in .iso
. I don’t know much about it, but I noticed it uses systemd-networkd
instead of NetworkManager
, which makes sense for a cloud-centric OS. That’s a plus in my book.
Choose a distro to invoke, enter wsl
from cmd
, and you should be in same dir as you were previously:
wsl -l -v
NAME STATE VERSION
* Ubuntu Running 2
wsl -d ubuntu # you can just invoke wsl unless need to specify distro
Code language: PHP (php)
Once you’re in wsl, you can use bash
to save an environment variable for your username and copy these commands straight across (except /dev/loop
– make sure you’re using the right loop number and partitions, those are unique to your system, unlikely to be the same, esp if you use a dif distro or release).
export USERNAME=<your username on the PC>
Code language: JavaScript (javascript)
Decompress the raw from any archive. E.g.:
xz -d Fedora-Cloud-Base-36-1.5.x86_64.raw.xz
Code language: CSS (css)
xz
deletes the original, so no need to worry about that. Now create a loop for all the partitions, and list those mounts :
losetup -f -P ./Fedora-Cloud-Base-36-1.5.x86_64.raw<br>losetup -l
Code language: HTML, XML (xml)
At e.g. /dev/loop0
you should have your .raw
file mounted as a device. Now you actually have to mount it as one image (as if it were booted). Create a working subdirectory:
mkdir -p /media/raw
list the partitions on your loop device:
fdisk -l /dev/loop0
Disk /dev/loop0: 5 GiB, 5368709120 bytes, 10485760 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: BF6BA5C6-0688-4AB6-B09C-942136A8C104
Device Start End Sectors Size Type
/dev/loop0p1 2048 4095 2048 1M BIOS boot
/dev/loop0p2 4096 2052095 2048000 1000M Linux filesystem
/dev/loop0p3 2052096 2256895 204800 100M EFI System
/dev/loop0p4 2256896 2265087 8192 4M PowerPC PReP boot
/dev/loop0p5 2265088 10483711 8218624 3.9G Linux filesystem
The root partition is going to go first, and then boot, and finally efi, so in that order.
mount /dev/loop0p5 /media/raw # largest partition generally indicates root
Code language: PHP (php)
Look at what you’re working with, sometimes there’s a root subdir, but usually there isn’t:
ls /media/raw<br>home root
Code language: HTML, XML (xml)
This time there was a subdir named root
, so base the subsequent mounts off of your new information:
mount /dev/loop0p2 /media/raw/root/boot<br>mount /dev/loop0p3 /media/raw/root/boot/efi
Code language: HTML, XML (xml)
Now you can go to the root folder of the filesystem and archive the image in one go – the trick to making the syntax simple is being inside the directory but saving the .tar
elsewhere (in this example, we’ll use the parent folder):
cd /media/raw/root
tar -cvf ../fedora-cloud-36.tar . # notice these periods, they indicate $pwd
Code language: PHP (php)
And in the parent directory will be your tar. Now move it out to C:
mv -v /media/raw/fedora-cloud-36.tar /mnt/c/Users/$USERNAME/Downloads/.
Code language: PHP (php)
exit WSL, but stay at command prompt:
exit
Code language: PHP (php)
cd your save location:
cd %USERPROFILE%\Downloads
Import .tar
into WSL:
mkdir %PROGRAMDATA%\wsl
C:\Users\avery\Downloads>wsl --import Fedora-Server %PROGRAMDATA%\wsl\fedora-server .\fedora-cloud-36.tar
Code language: JavaScript (javascript)
Run it to see if it works:
wsl -d fedora-server
cat /etc/os-release
NAME="Fedora Linux"
VERSION="36 (Cloud Edition)"
ID=fedora
VERSION_ID=36
VERSION_CODENAME=""
PLATFORM_ID="platform:f36"
PRETTY_NAME="Fedora Linux 36 (Cloud Edition)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:36"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f36/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=36
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=36
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Cloud Edition"
VARIANT_ID=cloud
Code language: JavaScript (javascript)
BTW, you can safely remove the kernel, since WSL always uses the one installed through Windows:
dnf remove -y kernel-core
Enjoy Fedora …
PS: for homework, you could figure out what else you don’t need you could uninstall or replace, depending on what distro you choose. Systemd comes to mind, or whatever init system you’re using, since you can’t use that in WSL, either… fun fact: you use task scheduler in Windows to schedule stuff to run in WSL instead of cron
…
Rambling about stuff probably nobody else cares about
I’ve noticed this blog is really less about the info I’m trying to share with people, and more of a collection of me rambling on about the stuff I’ve fixed or put together.
I’m not sure what’s wrong with me. I just spent an hour going off on another blog about this case I owned I made a firewall out of. Since I put so much time and energy into it, I thought I’d bring it here and add it to the collection: http://disq.us/p/2p7i6zw
Orignal on site Baptiste Wicht Norco RPC 230 case review: https://baptiste-wicht.com/posts/2013/08/norco-rpc-230-case-review.html
I have one of those Norco RPC-230 cases, I’ve had it since 2011. It’s crossed 2 states during 4 moves, and at least 6 different configurations, so it’s seen a thing or two.
I suffered through using it longest for a TV recorder PC case, running HDHomeRun for at least a year or two, with 4x HGST 7K2000s in it, which are power-hungry, fast-spinning 7200RPM, hot, old drives. The thermal design of this case is garbage, the fans only hit 2 out of 4 of the drives, so the two coolest HDDs ran 50+ deg C 24/7 that entire time, the other two 55-60+ deg. It was a major testament to HGST’s enterprise line, as they were refurbished, so undoubtedly they were tormented mercilessly before I even got them. The case I got new, but was chipped and scraped after the first of my builds it endured. The front USB connector broke in the middle within a year after normal use. It still works, but is difficult to plug into. As far as quality, amazing drives, crap case, both still work, only one deserves praise.
I also used this case for a desktop PC for a while, with a i5-3570K 77w TDP processor. With stock CPU cooler it would idle at 65 deg C within 5 minutes, which was unacceptable. A Thermaltake Gravity cooler got it under 50 deg C, but the clearance was only a couple mm so it probably could have been more efficient had there been more room, or perhaps a shorter cooler. The Gravity is 3-pin non-PWM, though, which in this case is probably better since the case was never not too hot under any circumstances, so there’s no reason to give a PWM fan any time to decide to rev up.
I thought about drilling some holes in the side near where the CPU would usually sit, since it doesn’t have any airflow from either the side or the back to speak of, but have you ever tried to drill through sheet metal? It’s not as easy as it sounds, even with a specialized drill bit. Even the aluminum foil-like character of the RPC-230’s build quality would present a painstaking chore. I’m glad I decided not to, because I ended up putting a board in it where the CPU isn’t even in the back, it’s in the front, so it wouldn’t have made any difference for my current config, other than to look hideously abused.
Anything over 40 deg C consistently makes me nervous personally, so I was never at ease running any equipment in the Norco RPC-230 case that wasn’t meant to be low-powered, cool, designed for minimal energy consumption, etc. So I finally took a server board X9SPU-F meant for proprietary cases that are near impossible to find, and put it in the RPC with a very low-TDP CPU. I chose the RPC-230 mainly because the motherboard wouldn’t fit in anything else I owned at the time, but also because I finally had a very low-TDP processor I intended to use with it. I’d been watching prices of the E3-1220Lv2 for a couple years and they plummeted from being around $150 to around $35 at the time (and now, virtually worthless). Finally, I had the type of components that wouldn’t make you think you could fry an egg on the top of this thing.
To fit the X9SPU-F in the RPC-230, I had to rip the drive tray out of the front. There’s no use putting drives in the RPC-230 anyway, unless you want to make fried hard drive souffle. Then, I equipped this odd-shaped server board with an E3-1220Lv2 which is 17w TDP, butchered a heatsink out of a CPU cooler from a Dell SFF Optiplex 7020 and tightly zip-tied a Noctua NF-A8 to it (works great). Then, I velcroed a couple mSATA SSDs to the bottom of the case in a single 2-port mSATA to SATA adapter board for a RAID1-ish config designed to keep the system from being taken down by an IO shit-nado of network log files.
Now it’s an edge router + firewall! Has dual Intel NICs and IPMI, too, so it’s fancy. Pulls less than 40w at the wall, does up to 2.4Gbps as tested with an 82599 (possibly faster if not using FreeBSD/pfSense, which has terrible Intel NIC driver and kernel regressions, and less-than-ideal for 10GbE `sysctl` defaults).
For a network device SSD application, I’ve tended to think size and speed are secondary to being able to take a very certain and constant beating. I’ve been using these 24GB Intel 313 SLC mSATA SSDs on dual-SATA daughterboards and putting them in some kind of SDS version of RAID1 (either with mdadm or ZFS). The key is they’re SLC, which is
hard to find and weren’t made very long for cost reasons. However, you’d be hard-pressed to find another SSD that’ll take a beating like these. They were designed to be cache devices for an old Windows 7 + RST config that never really caught on in I want to say like 2014. The plus side, is you can find a bunch of them around for cheap, and they’re pretty unlikely to die. They only get about 120MB/s read, 60MB/s write, but it doesn’t matter, and if you use a mSATA to SATA converter board like mine that has one port per drive, you can reap some benefit in throughput from running your SDS RAID1-ish mirror-type config (in this device’s case, it’s running ZFS).
And such is the tale of the long and winding life of my poor, beat-up, ill-equipped for most tasks I envisioned, but still utilized, and now humbly revered for being able to fit my bizarrely-shaped server board, Norco RPC-230.
— Good lord, I am such a nerd 🤓
Booting Fedora 36 on default btrfs partition structure from the grub prompt
Hey
I ran into an issue where I had an unpopulated grub menu on a Fedora 36 Workstation installation. It ended up only booting to the empty menu, but at least I could drop to a prompt to try and figure out how to get through it.
The usual booting with a live USB, mounting the affected drive to /mnt
and the other partitions and bind mounts respectively, and rebuilding grub.cfg
from chroot
didn’t appear to be functional due to an error in the chroot environment that makes it unable to see /dev
and use any of the usual tools to build the file.
TL;DR –
All you really need to read in this article to boot from grub prompt is in the 2nd codeblock below (some people just here for the lols)
So booting from the grub prompt was necessary in order to be in an environment where /dev
would be recognized and grub.cfg
could be rebuilt – since grub.cfg
isn’t anything that can be edited manually, unfortunately (it looks like it could be the way it’s named, but if you know anything about how grub works, you know it’s definitely not. Not even a little bit…)
I had written a while back about how to use the grub prompt in general here: The GRUB prompt: Demystified
The example I gave in the last article was done on Ubuntu. It looks like pretty much any other grub rescue operation using EXT4, XFS, etc. but it’s actually a homebrew ZFS initrd- I used to make my own ZFS built-in kernels regularly, and threw together a script for automating the process if you’re interested: https://github.com/averyfreeman/zfs-kernel-builder
But lately I’ve been dabbling with Fedora so this article’s related to Fedora. It’s upstream for some great software, what can I say. I had an NVMe from a Thinkpad I’ve had for a couple years I tried to swap into a newer Thinkpad I was upgrading to, because Thinkpads. For some reason grub.cfg
got hosed in the process and I couldn’t boot from it.
Not wanting to take too much time troubleshooting, I fresh-installed a new copy of Fedora 36 to another NVMe in the new laptop and copied as much as I could from /home
and a package list from repoquery -a --installed
run using chroot
from the old NVMe in an external enclosure (gee willikers, I sure love my external NVMe with Thunderbolt 3, by golly).
Since I still had the old installation all set up, I thought I’d try and rescue it eventually, so when I got a moment I booted it from the external NVMe enclosure on another laptop with Thunderbolt using VMware Workstation and the enclosure as a physical disk .vmdk
(hypervisors are awesome).
After failing with the tried-and-true live USB chroot
rescue method, at least I could get into the grub menu without issue. That poor, empty menu, so lonely feeling with its 0 boot loader entries. I knew the OS was still there, but how to get into it without the entries? What’s a nerd to do? Start messing around with the prompt to explore how to crack open the damn thing!
Since this was btrfs, of course, it was a little different, and since each distro uses a different subvolume layout, none of the info about any of them translate to the others very well. At the time of writing, I didn’t see any definitive info on how to boot from grub prompt on stock btrfs Fedora Workstation, which is kind of surprising since it’s been btrfs default for 3-4 years now, since version 33.
There’s a great guide here about Ubutntu using btrfs on “nixventure”, which I admit I’d never heard of before, but appears very thorough, and I saw one from Debian (I believe) that I’m not going to reference because it was less remarkable, but Fedora there were just a bunch of forums with people flailing about trying to figure out the same thing I was, and ending up being unsuccessful and presumably giving up from the look of their abruptly truncated threads. So that was concerning, to say the last.
I even tried “rescatux” automated rescue tool, if you can believe that, because I was being lazy and kind of running out of ideas. I can’t say I give it a glowing review, but it tries. That statement probably indicates how well it worked for my needs. I had to suck it up and adapt what I knew about using the grub prompt to the new partition layout and filesystem. Thankfully, it all turned out well in the end.
Here’s some notes I took while I was working through the process:
# Fedora's variant of grub has some helpful btrfs-specific commands:
grub> help
. . . commands . . .
btrfs-get-default-subvol (hd0,gpt3)
btrfs-info
btrfs-list-subvols (hd0,gpt3)
btrfs-mount-subvol
. . . more commands . . .
# so you get information like this:
grub> btrfs-list-subvols (hd0,gpt3)
ID 256 path home
ID 257 path root
ID 258 path var
# and this:
grub> btrfs-info (hd0,gpt3)
Label: 'fedora_treygouty' uuid: 7caff388-2bb3-434a-a927-096dac2dc892
Total devices 1 FS bytes used 298520481792
# Intuitively, I thought this would work, but I was mistaken:
grub> linux /vmlinuz-5.17.9-300 <tab-tab works> root=UUID=7caff388-2bb3-434a-a927-096dac2dc892 ro rootflags=subvol=root
# You'd probably have to write all that out by hand, so be thankful I'm telling you ahead of time it didn't work for me
Code language: PHP (php)
TL;DR #2 – you’re getting closer …
Anyway, I’ll cut to the chase and show how I did it. Note, again, for the record, this is the bare-minimum default partition structure on an Anaconda installed Fedora 36 Workstation setup. No LUKS or other encryption, no LVM.
Note: For the record, this is the first Anaconda (RedHat’s) installer where LVM hasn’t been enabled for the default partition configuration. LVM is marginally useful for btrfs, I’ve tried it before on OpenSUSE, but comparitively it’s much less of a crutch than it is for EXT4 or XFS filesystems. So if RH’s installer says don’t bother with LVM, don’t bother… It’s RH, you know how they LOVE their LVM, if they’re not recommending it it really must not be necessary. /rant
# Quick grub prompt recap --
# First, list your storage devices:
grub> ls
(proc) (hd0) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1) (cd0) (cd0,msdos2)
# If you're lucky like me and you only have one drive connected, /boot will be easy to find. /boot is almost always gpt2, and there's only one hard drive, so...:
grub> set root=(hd0,gpt2)
grub> ls /
config-5.17.9-300.fc36.x86_64
efi
extlinux
grub2
initramfs-0-rescue-334f7d6e8a0942d388bafdab5fa2a0a1.img
initramfs-5.17.9-300.fc36.x86_64.img
loader
lost+found
symvers-5.17.9-300.fc36.x86_64.gz
System.map-5.17.9-300.fc36.x86_64
vmlinuz-0-rescue-334f7d6e8a0942d388bafdab5fa2a0a1
vmlinuz-5.17.9-300.fc36.x86_64
# Set your vmlinuz and root device + partition. Here (hd0,gpt3) corresponds with /dev/sda3:
grub> linux /vmlinuz-5.17.9-300.fc36.x86_64 root=/dev/sda3 ro rootflags=subvol=root
# Then boot 'er up:
grub> boot
Code language: PHP (php)
That’s really all there is to it. It’s not too bad once you know what you’re doing. Since the process is so short, you might want to poke around some more to try and get more info, or to try and give your life meaning. There’s the (hd0,gpt2)/grub/grub.cfg
file, or the /loader/entries folder
– you can cat
anything in either of those. Type help
or something. Go wild.
Coincidentally, all the loaders were in the loader directory the entire time, but none of them would load all of the things. Such a bummer when one cannot load all of the things. So, frustrating, but glad it all worked out in the end. Hope this helps someone else, too.
VMware Upgrade renders Workstation 16.2.1 useless, thanks to Houdini-like disappearance of DLLs
Hey,
I just came across an issue many people have been experiencing after upgrading VMware Workstation to 16.2.1 in Windows. It looks like the installer has a bug that deletes two necessary files by accident, and their absence prevents the programs from running, beginning with vmware-tray.exe
, which is the precursor to all things Workstation.
The lawnmowered files are two dynamic link libraries (“DLLs”) responsible for encryption. Their names are libssl-1_1.dll
and libcrypto-1_1.dll
. Thankfully, I’ve managed to gather them from a reliable source and have re-packaged them for your convenience. Below is an archive containing both missing files for you to download, in hopes that you may use them to remedy this rank insipidity:
The organization responsible for storing and distributing DLL files such as these is named dll-files.com, located at https://www.dll-files.com in lovely Tilf AB, Sweden. Their website offers a surprisingly painless, hassle-free download (full disclosure: no affiliation).
I actually visited a few other sites looking for these DLL files before I found dll-files.com, but all the other sites “provided” were dubious “utilities” containing code that made my antivirus software blush a deep shade of “seriously?”.
Speaking of malware, everything I am providing today has been scanned with Malwarebytes, the best antivirus software in the biz (full disclosure: no affiliation), which reports these DLLs, and obligatory license + attribution document, are as squeaky-clean as a newborn antelope (devouring placenta does have advantages). I installed them on my laptop, the one I’m using now, and it’s been smoother sailing than vacationing on Velveeta.
Installing random files with these kinds of file names actually can be a little scary, considering all the ransomware thieves who were wreaking havoc across the US a couple years ago, but legitimate programs use cryptographic libraries just often as cyber-criminals, perhaps even more. So never you be a’ feared of them scary ol’ names, now, their bark a’ far worse than their soo-eey.
Come to think of it, in contrast to the wrath of cryptographic criminals a couple years ago, it seems that recently the media is more likely to associate “crypto” with blockchain currency. At least wealth is a more pleasant association than robbery… <dentist office music>
To install the files above after you download them, unzip the .7z
file using 7zip archive software, and move the two .dll
files contained therein to the folder located at C:\Program Files (x86)\VMware\VMware Workstation\<files go here>
I used an admin command prompt to move mine, but you could just as easily open your file explorer to drag-and-drop them, I’m sure. Once Meta gets off their behinds and releases the first telekinesis controller, we’ll all be able to will our files across our hard drives with sheer focus and determination, but until then it’s a flail across our mice and keyboards. Sorry to remind you we’re still savages with disappearing DLLs.
Mount Ubuntu 22.04 ZFS partitions using live ISO for disaster recovery
My system runs ZFS and lately has been dropping to the initramfs / busybox prompt on boot. I had a hard time finding a fleshed-out guide on how to mount ZFS in a live environment for performing disaster recovery tasks like chroot and grub repair, so I thought I’d write something up.
My system was dropping to the busybox prompt after GRUB menu. I started experiencing the issue after a routine apt upgrade, I rebooted and wasn’t able to get any of my initramfs to boot. It seems a little strange, because usually the inability to boot will be limited to a new initramfs – e.g. an older version of the kernel will still have the ZFS drivers, or other necessary components to boot, while the newer versions (the ones just installed) will be lacking these necessary components for whatever reason.
First of all, burn yourself a copy of a live USB, and boot into it. Luckily, the newest version of Ubuntu (22.04 – Jammy Jellyfish) has the ZFS drivers and executables installed by default, unlike prior versions where you had to add the multiverse repo manually, download the packages, and enable the ZFS drivers using modprobe
.
A peek at lsmod
shows the ZFS drivers are indeed loaded, and lo-and-behold, there’s the zpool
and zfs
executables:
ubuntu@ubuntu:~$ lsmod | grep zfs
zfs 3751936 29
zunicode 348160 1 zfs
zzstd 487424 1 zfs
zlua 155648 1 zfs
zavl 20480 1 zfs
icp 319488 1 zfs
zcommon 102400 2 zfs,icp
znvpair 94208 2 zfs,zcommon
spl 122880 6 zfs,icp,zzstd,znvpair,zcommon,zavl
ubuntu@ubuntu:~$ which {zpool,zfs}
/usr/sbin/zpool
/usr/sbin/zfs
The drive I am diagnosing is the internal NVMe, so there’s no need to attach it. One question I had was how to mount the two pools, and in what order. By default, Ubuntu creates an rpool
for the root partition, and a bpool
for the boot partition.
Generally, on an EFI system, one would mount the root partition in a clean directory like /mnt
first, and subsequently mount boot at /mnt/boot
once it is provided by the previously mounted root partition, and then mount efi at /mnt/boot/efi
once that’s provided by the boot partition. As you can see, the order of mounting these partitions is therefore of paramount importance, but as there are only 3 options, it’s not too complicated.
You’ll need to be root for basically all these commands. Using sudo su
without a password will typically get you to a root prompt (#
) in a live environment.
TL;DR – probably way more than you ever wanted to know about an lsblk
device list:
First, we should identify the storage devices using lsblk -f
(the -f
flag includes the filesystem information, which is important for our purposes):
# lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0
squash 4.0 0 100% /rofs
loop1
squash 4.0 0 100% /snap/bare/5
loop2
squash 4.0 0 100% /snap/core20/1405
loop3
squash 4.0 0 100% /snap/snapd/15177
loop4
squash 4.0 0 100% /snap/snap-store/575
loop5
squash 4.0 0 100% /snap/gtk-common-themes/1534
loop6
squash 4.0 0 100% /snap/firefox/1232
loop7
squash 4.0 0 100% /snap/snapd-desktop-integration/10
loop8
squash 4.0 0 100% /snap/gnome-3-38-2004/99
sda iso966 Jolie Ubuntu 22.04 LTS amd64
│ 2022-04-19-10-23-19-00
├─sda1
│ iso966 Jolie Ubuntu 22.04 LTS amd64
│ 2022-04-19-10-23-19-00 0 100% /cdrom
├─sda2
│ vfat FAT12 ESP 8D6C-A9F8
├─sda3
│
└─sda4
ext4 1.0 writable
bb277d84-75cc-473b-b327-fd885d85889a 24.5G 0% /var/crash
/var/log
zd0 btrfs b6239f8a-058b-4a6c-8258-b9a7b50f6c23
zd16
└─zd16p1
btrfs d6074499-b9aa-47e0-a08a-58e27c73e771
zd32 btrfs c68aa9ca-933a-48cb-9adb-22fd6a8ca8c8
zd48
└─zd48p1
btrfs f52702bd-c805-4edc-87d1-6fb877ee6738
nvme1n1
│
├─nvme1n1p1
│ vfat FAT32 B045-5C3B
├─nvme1n1p2
│ swap 1 584b9b78-7d8d-4a5a-9263-d6f6a48adc6b
├─nvme1n1p3
│ zfs_me 5000 bpool 11241115695889536197
└─nvme1n1p4
zfs_me 5000 rpool 16130566787573079380
nvme0n1
│
├─nvme0n1p1
│ vfat FAT32 EC9D-0344
├─nvme0n1p2
│
├─nvme0n1p3
│ ntfs A4EEBDB4EEBD7F5C
└─nvme0n1p4
ntfs 989EE7E99EE7BDBE
Code language: PHP (php)
OK, there’s a lot there, so what are we looking at? Well, the first 9 devices that say loop
are snaps, since we’re on Ubuntu. Those are responsible for storing some of the programs being run by the OS. Each one gets their own virtual storage device, sometimes referred to as an “overlay”. They create a fair amount of clutter in our device list, but that’s about all. You can ignore them.
Then, /dev/sda
is our copy of Ubuntu ISO we booted from – you can see how it says cdrom
there, and iso9660
(the cdrom spec). It’s read-only, so we couldn’t do anything with it if we wanted to, and we don’t, so let’s move on…
There’s a device for log
and crash
log, so that’s kind of interesting. I imagine the live ISO makes those since you can’t write to the USB drive, seeing as the ISO is a virtual CD-ROM, and CD-ROMs are read-only. Then there’s a bunch of what are called “zvols” (the zd0
, zd16
, etc. devices – see those?). Those are devices created with ZFS that are isolated from the rest of the filesystem. zvols are virtual block devices you can use just like any other block device, but in this context they’re typically either formatted with a different filesystem, or mounted via iSCSI for block-level filesharing (filesystem-sharing?). You can see these ones say btrfs
, they were actually created for use with container runtimes, namely podman
and systemd-container
, both of which support btrfs very well and ZFS either nominally or not at all.
Now we get to nvme1n1
– this is the first NVMe drive listed. Generally 0
would be listed first, but for some reason it’s listed second. n1
is the number of the drive (the second NVMe drive in the laptop), after that the partitions are listed as p1
, p2
, p3
, and so on. Here’s the drive in isolation:
nvme1n1
│
├─nvme1n1p1
│ vfat FAT32 B045-5C3B
├─nvme1n1p2
│ swap 1 584b9b78-7d8d-4a5a-9263-d6f6a48adc6b
├─nvme1n1p3
│ zfs_me 5000 bpool 11241115695889536197
└─nvme1n1p4
zfs_me 5000 rpool 16130566787573079380
The canonical address for this drive is: /dev/nvme1n1p{1,2,3,4}
. The /dev
(device) folder, while not listed in this output, is important to reference, as the full path is required for mounting a partition. Typically one would only mount a single partition at a time, but you could conceivably chain them in a single command by using curly braces, as shown. This is not common, as you will probably need to mount different partitions in different locations (e.g. /mnt
, /mnt/boot
), and usually either in descending order, or with no pattern at all.
If you remember back at the start, I mentioned the rpool
and bpool
. These are seen on /dev/nvme1n1p4
and /dev/nvme1n1p3
respectively. If the disk were formatted in a block filesystem such as EXT4 (Ubuntu’s default filesystem), the root partition could be mounted by attaching /dev/nvme0n1p4
to an empty folder. The command would therefore be:
# mount /dev/nvme1n1p4 /mnt
Code language: PHP (php)
And then you’d be able to ls /mnt
and see the files contained on your newly mounted root partition. E.g.:
# ls /mnt
Qogir boot dev home lib32 libx32 mnt proc run snap sys usr
bin cdrom etc lib lib64 media opt root sbin srv tmp var
Code language: PHP (php)
But this NVMe is formatted using ZFS. So what to do? That’s the process I was having difficulty finding that inspired this blog post.
End TL;DR – here’s the ZFS-specific stuff again:
First, after you confirm that you have your ZFS modules loaded by referencing your list of loaded kernel modules, and confirming that your ZFS executables are available in PATH
(here’s the syntax again so you don’t have to scroll back):
# lsmod | grep zfs
zfs 3751936 29
zunicode 348160 1 zfs
zzstd 487424 1 zfs
zlua 155648 1 zfs
zavl 20480 1 zfs
icp 319488 1 zfs
zcommon 102400 2 zfs,icp
znvpair 94208 2 zfs,zcommon
spl 122880 6 zfs,icp,zzstd,znvpair,zcommon,zavl
# which {zpool,zfs}
/usr/sbin/zpool
/usr/sbin/zfs
Code language: PHP (php)
Here’s where it’s different than your typical mount. You use zpool
to import rpool
, but you need to mount it using an alternate root (at /mnt
) – otherwise it’ll try to mount itself over your live environment! Then confirm that the import worked.
# zpool import -f rpool -R /mnt
# ls /mnt
Qogir boot dev home lib32 libx32 mnt proc run snap sys usr
bin cdrom etc lib lib64 media opt root sbin srv tmp var
Code language: PHP (php)
OK, that went well. You can see that now we have a /mnt/boot
folder, which is boot
inside rpool
– that’s where initramfs lives, but they’re stored in the bpool
. We needed that folder to be available to mount our bpool
into. So, let’s import bpool
into /mnt/boot
as an alternate root (if we didn’t, it’d try and overwrite our currently mounted /boot
partition:
# zpool import -f bpool -R /mnt/boot
# ls /mnt/boot
config-5.15.32-xanmod1 memtest86+_multiboot.bin
config-5.15.34-xanmod1 System.map-5.15.32-xanmod1
config-5.15.36-xanmod1 System.map-5.15.34-xanmod1
config-5.17.0-xanmod1 System.map-5.15.36-xanmod1
config-5.17.1-xanmod1 System.map-5.17.0-xanmod1
config-5.17.3-xanmod1 System.map-5.17.1-xanmod1
config-5.17.5-xanmod1 System.map-5.17.3-xanmod1
config-5.17.9-xanmod1 System.map-5.17.5-xanmod1
config-5.17.9-xanmod1-x64v2 System.map-5.17.9-xanmod1
efi System.map-5.17.9-xanmod1-x64v2
grub vmlinuz
initrd.img vmlinuz-5.15.32-xanmod1
initrd.img-5.15.32-xanmod1 vmlinuz-5.15.34-xanmod1
initrd.img-5.15.34-xanmod1 vmlinuz-5.15.36-xanmod1
initrd.img-5.17.0-xanmod1 vmlinuz-5.17.0-xanmod1
initrd.img-5.17.1-xanmod1 vmlinuz-5.17.1-xanmod1
initrd.img-5.17.3-xanmod1 vmlinuz-5.17.3-xanmod1
initrd.img-5.17.5-xanmod1 vmlinuz-5.17.5-xanmod1
initrd.img.old vmlinuz-5.17.9-xanmod1
memtest86+.bin vmlinuz-5.17.9-xanmod1-x64v2
memtest86+.elf vmlinuz.old
Code language: PHP (php)
That looks like a bunch of initramfs files to me! Good, so that means those kickstarter runtimes that load from grub are available.
If you look in that list, you’ll also see both efi and grub folders. Both of those are empty and waiting for storage to be attached. The efi partition lives in the first partition of the same NVMe drive, and is formatted with FAT, and grub is a bind-mount (you can see it in /etc/fstab):
# mount -t msdos /dev/nvme1n1p1 /mnt/boot/efi
Can also use UUID from lsblk if prefer (just use one or other, not both):
# mount -t msdos UUID=B045-5C3B /mnt/boot/efi
# ls /mnt/boot/efi
efi grub system~1 (confirm it's mounted)
# grep grub /mnt/etc/fstab
/boot/efi/grub /boot/grub none defaults,bind 0 0
(we'll bind-mount this in next step)
Code language: PHP (php)
Then you’ll want to mount a few system folders inside your drive’s filesystem so you can access them inside the chroot (required for things to work OK):
# for i in proc dev sys dev/pts; do mount -v --bind /$i /mnt/$i; done
mount: /proc bound on /mnt/proc.
mount: /dev bound on /mnt/dev.
mount: /sys bound on /mnt/sys.
mount: /dev/pts bound on /mnt/dev/pts.
# mount -v --bind /mnt/boot/efi/grub /mnt/boot/grub
mount: /mnt/boot/efi/grub bound on /mnt/boot/grub.
Code language: PHP (php)
“chroot
ing”: Now that all 3 partitions are mounted together in a cohesive filesystem tree, and you’ve got all your necessary bind mounts, one of the most effective ways to diagnose issues as if you’re running the affected disk, is to chroot into the filesystem. Run # chroot /mnt
and now you’ll see /mnt
as /
(root), and you can run your programs as if you booted the computer using that drive (from the terminal, anyway):
# chroot /mnt
# apt update (failed)
# cd /etc
# ls -la resolv.conf
lrwxrwxrwx 1 root root 39 Feb 17 12:09 resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
Code language: PHP (php)
If your network connection fails inside the chroot
like mine did, go to /etc
and delete resolv.conf
if it’s a symlink to systemd-resolved
(as shown above). Then point /etc/resolv.conf
to a known good dns forwarder (e.g. 1.1.1.1
, 8.8.8.8
, etc.)
# echo 'nameserver 8.8.8.8' > resolv.conf
# apt update (works)
# apt list --installed | grep dkms
dkms/jammy,now 2.8.7-2ubuntu2 all [installed,automatic]
zfs-dkms/jammy-proposed,now 2.1.4-0ubuntu0.1 all [installed]
Code language: PHP (php)
I was really hoping zfs-dkms
got uninstalled somehow, because I thought that might have been why my initramfs files didn’t have zfs modules. So unfortunately I still have to keep looking to figure out what’s wrong…
Note, you’ll probably see this error a lot, but it’s safe to ignore:
ERROR couldn't connect to zsys daemon: connection error: desc = "transport: Error while dialing dial unix /run/zsysd.sock: connect: connection refused"
Let’s try upgrading the packages and see what shakes out:
# apt upgrade
The following packages were automatically installed and are no longer required:
linux-headers-5.15.32-xanmod1 linux-headers-5.15.34-xanmod1
linux-headers-5.15.36-xanmod1 linux-headers-5.17.0-xanmod1
linux-headers-5.17.1-xanmod1 linux-headers-5.17.3-xanmod1
linux-headers-5.17.5-xanmod1 linux-image-5.15.32-xanmod1
linux-image-5.15.34-xanmod1 linux-image-5.15.36-xanmod1
linux-image-5.17.0-xanmod1 linux-image-5.17.1-xanmod1
linux-image-5.17.3-xanmod1 linux-image-5.17.5-xanmod1
Use 'sudo apt autoremove' to remove them.
Code language: PHP (php)
That was … interesting … and then the issue presented itself next while I ran apt autoremove
:
Setting up linux-image-5.17.9-xanmod1 (5.17.9-xanmod1-0~git20220518.d88d798) ...
* dkms: running auto installation service for kernel 5.17.9-xanmod1 [ OK ]
update-initramfs: Generating /boot/initrd.img-5.17.9-xanmod1
<span style="text-decoration: underline;"><strong>zstd: error 25 : Write error : No space left on device (cannot write compressed</strong> </span>
block)
(emphasis added)
Code language: HTML, XML (xml)
bpool
has no space left. That’s almost certainly the problem. I’m going to remove a couple kernels and rebuild all my initramfs, that ought to do it. I’m also noticing my bpool
is full of snapshots. List current snapshots with this first command, and then destroy them with the second one:
// This lists the snapshots:
# zfs list -H -o name -t snapshot | grep bpool
...auto-snapshots look like pool/BOOT/ubuntu_pd3ehl<strong>@autozsys_xxxx</strong>,
<strong>snapshots have @ symbol - no @ symbol, not a snapshot, don't delete it!</strong>
// This destroys the snapshots:
# zfs list -H -o name -t snapshot | grep bpool | xargs -n1 zfs destroy -r
What this does:
(list only snapshots by full name) | (list only bpool) | (delete by ea line)
It's the same as what's above, but with the delete command, destroy.
Make sure you understand what's going on with this command, as you can delete stuff you don't want to <em>really</em> easily. Please be careful.
Code language: PHP (php)
… looks pretty good to me – much more tidy:
# ls /boot
config-5.15.0-33-generic memtest86+.elf
config-5.15.40-xanmod1-tt memtest86+_multiboot.bin
efi System.map-5.15.0-33-generic
grub System.map-5.15.40-xanmod1-tt
initrd.img vmlinuz
initrd.img-5.15.0-33-generic vmlinuz-5.15.0-33-generic
initrd.img-5.15.40-xanmod1-tt vmlinuz-5.15.40-xanmod1-tt
initrd.img.old vmlinuz.old
memtest86+.bin
Code language: PHP (php)
Install some generic kernel to make sure you have one available, check that zfs-initramfs
is installed if all you’re going to use is generic kernel (or zfs-dkms
if using xanmod
, other 3rd-party kernel). E.g. I got rid of my xanmod kernels just so I wouldn’t have to deal with building custom dkms
modules:
# apt list --installed | grep xanmod
linux-headers-5.15.40-xanmod1-tt/unknown,now 5.15.40-xanmod1-tt-0~git20220515.867e3cb amd64 [installed,automatic]
linux-image-5.15.40-xanmod1-tt/unknown,now 5.15.40-xanmod1-tt-0~git20220515.867e3cb amd64 [installed,automatic]
linux-xanmod-tt/unknown,now 5.15.40-xanmod1-tt-0 amd64 [installed]
xanmod-repository/unknown,now 1.0.5 all [installed]
# apt remove linux-headers-5.15.40-xanmod1-tt linux-image-5.15.40-xanmod1-tt xanmod-repository linux-xanmod-tt zfs-dkms
. . .
The following packages will be REMOVED:
linux-headers-5.15.40-xanmod1-tt linux-image-5.15.40-xanmod1-tt
linux-xanmod-tt xanmod-repository zfs-dkms
Do you want to continue? [Y/n]
. . .
# apt autoremove -y
... install a couple kernels...
# apt install -y linux-{image,headers}-5.15.0-28-generic linux-{image,headers}-5.15.0-33-generic
. . . using versions that are most current & 2nd most current now . . .
Code language: PHP (php)
Then update all the initramfs one last time, just in case. I’ll probably re-install grub, too, just bc, but one thing at a time…
# update-initramfs -uvk all
. . . lots of output . . . that's how you know it's working . . .
Code language: PHP (php)
Let’s re-install grub and run update-grub
# grub-install --bootloader-id=ubuntu --recheck --target=x86_64-efi --efi-directory=/boot/efi --no-floppy
Installing for x86_64-efi platform.
grub-install: warning: EFI variables cannot be set on this system.
grub-install: warning: You will have to complete the GRUB setup manually.
Installation finished. No error reported.
Code language: PHP (php)
When you get this error, it just means you can’t set the UEFI boot order while you’re in a chroot. I also like to run update-grub
for good measure (this is grub2-mkconfig -o /boot/grub/grub.cfg
on most other systems if that’s more familiar sounding to you). Update-grub
rebuilds the entries in your grub menu, along with their parameters detailed in /etc/default/grub
.
Speaking of which, you can always take a peek at /etc/default/grub
before you run this command – just in case.
# which update-grub
/usr/sbin/update-grub
# cat /usr/sbin/update-grub
// update-grub:
#!/bin/sh
set -e
exec grub-mkconfig -o /boot/grub/grub.cfg "$@"
# update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: vmlinuz-5.15.0-33-generic in rpool/ROOT/ubuntu_pd3ehl
Found initrd image: initrd.img-5.15.0-33-generic in rpool/ROOT/ubuntu_pd3ehl
Found linux image: vmlinuz-5.15.0-28-generic in rpool/ROOT/ubuntu_pd3ehl
Found initrd image: initrd.img-5.15.0-28-generic in rpool/ROOT/ubuntu_pd3ehl
Found linux image: vmlinuz-5.15.0-33-generic in rpool/ROOT/ubuntu_pd3ehl@autozsys_yg50xc
. . . snapshot menu entries . . .
Code language: PHP (php)
Now leave the chroot now, remove the system folder redirects and bind mounts, and reboot, like so:
# exit
# for i in proc dev/pts dev sys boot/grub; do umount -v /mnt/$i; done
umount: /mnt/proc unmounted
umount: /mnt/dev/pts unmounted
umount: /mnt/dev unmounted
umount: /mnt/sys unmounted
umount: /mnt/boot/grub unmounted
# umount -v /dev/nvme1n1p1
umount: /mnt/boot/efi (/dev/nvme1n1p1) unmounted
# zpool export bpool
# zpool export rpool
Code language: PHP (php)
One last quick thing you can do before rebooting is check out efibootmgr
and see which order your system will start up in. This is a little easier and more predictable, as you can make sure you boot from the right efi file, rather than mashing the startup menu button to make sure it loads the correct disk / efi.
Some stuff I was messing with trying cover all the bases. efibootmgr
reference: https://wiki.archlinux.org/title/GRUB/EFI_examples#Asus
# efibootmgr -v
Boot0000* ubuntu HD(1,GPT,544a9120-eef7-4aae-8311-cd6ca6929213,0x800,0x100000)/File(\EFI\ubuntu\shimx64.efi)
. . .
# efibootmgr -B Boot0000 -b 0
# efibootmgr --create /dev/nvme1n1 --part 1 --write-signature --loader /EFI/GRUB/grubx64.efi --label "GRUB" --verbose
BootCurrent: 0002
Timeout: 0 seconds
BootOrder: 0000,0001,0002
Boot0001* UEFI: Samsung SSD 980 1TB, Partition 1 HD(1,GPT,6afa5e93-54a5-4628-978f-313a0dcfe27b,0x800,0xfa000)/File(\EFI\Microsoft\Boot\bootmgfw.efi)..BO
Boot0002* UEFI: Samsung Flash Drive DUO 1100, Partition 2 PciRoot(0x0)/Pci(0x14,0x0)/USB(16,0)/HD(2,GPT,a09db2b8-b5f6-43ae-afb1-91e0a90189a1,0x6cc954,0x2130)..BO
Boot0003 Windows Boot Manager HD(1,GPT,6afa5e93-54a5-4628-978f-313a0dcfe27b,0x800,0xfa000)/File(\EFI\Microsoft\Boot\bootmgfw.efi)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}....................
Boot0000* GRUB HD(1,GPT,a09db2b8-b5f6-43ae-afb2-91e0a90189a1,0x40,0x6cc914)/File(\EFI\GRUB\grubx64.efi)/dev/nvme1n1
Code language: PHP (php)
A troubleshooting tip: If you have issues using the pool names with zpool for some reason, the UUIDs are listed in lsblk. While technically interchangeable, the UUID can coax some commands into to working correctly when the name can’t.
If it doesn’t boot from the ZFS drive again, boot it into the live ISO and go through everything all over … 😉 Good luck!!
dpdk 22.03 rpm packages for Fedora 36: a dependency of openvswitch
I meant to post this over a month ago, but got sidetracked, so I’m coming in a little late. Unfortunately, it looks like even though Fedora 36 has officially been released, the dpdk 22.03 rpms still aren’t available.
Back when I compiled these, I realized there were no official dpdk 22.03 rpms available in the yum repos, despite being required for openvswitch. So I compiled them so I could install openvswitch for use with virt-manager.
Dpdk on Fedora has an official maintainer, they probably just got sidetracked themselves – I can relate. But I had these packages already and wanted to help other people install openvswitch, so I posted the resulting packages in a github repo case other people want to download it.
So if you (like me) want to run openvswitch on your fancy new officially-released non-beta Fedora 36 workstation (or server, or silverblue, kinoite or iot using rpm-ostree), and you don’t want to wait or downgrade, you’d have to either have to compile dpdk 22.03 for yourself, or now you can download them from my repo.
I’ve got all the instructions to go through the build process if you’d like to get your hands dirty with compilation (it’s pretty straightforward): https://github.com/averyfreeman/dpdk-2203-for-fedora36
The .rpm files are also there if you don’t care for all the fuss of compilation. You can use them as openvswitch dependencies, just install them before you try and install openvswitch using dnf.
I should have made this post sooner so people knew the rpms were available, but at least I put a note or two in on reddit in a couple key places (now that I think about it, probably just /r/fedora). Nothing beats the officialism of posting a fancy notice on your wordpress blog, though, amirite?
Speaking of which, I think I will be looking at a way of integrating this blog with my repo – I’m hoping I can figure out a way to produce and update posts on wordpress automatically by creating a gist or a new repo. Then the two would be more tightly integrated, and could avoid this whole getting sidetracked issue…
The less people get sidetracked, the sooner they use software…