I installed opensuse on my laptop
School had just ended. During the school year, I had been using a hybrid graphics (dual-gpu) laptop, that otherwise worked normally, but had horrible, terrible battery life. I had struggled to get 2 hours out of it, because the dedicated nvidia gpu would not get turned off properly.
So I decided to switch to my second laptop, which has been unused so far. But it has pure intel graphics, and the laptop has much better linux support, and consequently, a much better battery life.
Before setting it up, I had a few requiremnts.
Security. Previously, I didn’t care about this, because I carried my laptop around with me at all times, but now I was going to be leaving my laptop unattended, maybe for extended periods of time. That meant I needed full disk encryption, and secure/trusted boot. However, I had limited time to set this up, so I neede to find a distro that did this the easiest way possible. I eventually settled on opensuse, which had an option to set up secure boot and encryption in the installer, under guided partitioning. After some hiccups, it installed just fine.
And the other, is my tools and packages. I didn’t worry too much about this, because I had decided beforehand on using nix and home-manager to install packages not available in the repositories. Home manager is a tool that allows for declarative configuration of a user environmetn, including packages, configuration files, or environment variables, using the nix programming language. Notably, it can be useed on almost all linux distros.
Here is my current home.nix, as of writing this, the file home-manager takes as an input.
Show
home.nix
{
pkgs ? import <nixpkgs> {},
config,
lib,
...
}:
let
nixgl = import <nixgl> {};
nixGlWrapper = import ./nixglwrapper.nix {inherit nixgl pkgs lib config;};
in
with import ./quarto.nix {inherit pkgs config lib;};
with import ./nixglwrapper.nix {inherit pkgs config lib nixgl;};
{
# Home Manager needs a bit of information about you and the paths it should
# manage.
home.username = "moonpie";
home.homeDirectory = "/home/moonpie";
targets.genericLinux.enable = true;
nixpkgs.config.allowUnfree = true;
nix.settings.experimental-features = ["nix-command" "flakes"];
# This value determines the Home Manager release that your configuration is
# compatible with. This helps avoid breakage when a new Home Manager release
# introduces backwards incompatible changes.
#
# You should not change this value, even if you update Home Manager. If you do
# want to update the value, then make sure to first check the Home Manager
# release notes.
nix.package = pkgs.nix;
home.stateVersion = "23.11"; # Please read the comment before changing.
# The home.packages option allows you to install Nix packages into your
# environment.
#fonts.fontconfig.enable = true;
xdg.mime.enable = true;
home.packages = [
#nixgl
nixgl.nixGLIntel
nixgl.nixVulkanIntel
(nixGLWrap pkgs.vscode)
(nixGLWrap pkgs.microsoft-edge)
(nixGLWrap pkgs.firefox)
pkgs.micro
pkgs.calibre
pkgs.languagetool
pkgs.git
pkgs.soundwireserver
quarto
pkgs.jupyter
pkgs.python3
pkgs.yt-dlp
pkgs.macchanger
pkgs.nmap
pkgs.wireshark
pkgs.gocryptfs# # Adds the 'hello' command to your environment. It prints a friendly
# # "Hello, world!" when run.
# pkgs.hello
# # It is sometimes useful to fine-tune packages, for example, by applying
# # overrides. You can do that directly here, just don't forget the
# # parentheses. Maybe you want to install Nerd Fonts with a limited number of
# # fonts?
# (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })
# # You can also create simple shell scripts directly inside your
# # configuration. For example, this adds a command 'my-hello' to your
# # environment:
# (pkgs.writeShellScriptBin "my-hello" ''
# echo "Hello, ${config.home.username}!"
# '')
];
# Home Manager is pretty good at managing dotfiles. The primary way to manage
# plain files is through 'home.file'.
home.file = {};
home.sessionVariables = {
# EDITOR = "emacs";
};
# Let Home Manager install and manage itself.
programs = {
home-manager.enable = true;
bash.enable = true;
gh.enable = true;
};
}
Of course, the home.nix file isn’t all there is too it. There are also some imports, which take info from files that aren’t home.nix.
I have two imports, as of right now.
Using nix to run applications on non-nixos distros mostly works, but has some quirks. One quirk is that hardware accelerated graphics (opengl, vulkan) is lacking. In order to get around this, I use a program called nixgl. However, nixgl is essentially a wrapper, and it works by calling hte program you want to run as a command line argument. Someone automated that in nix, and I integrated that into my code.
Show
nixglwrapper.nix
{ config, pkgs, lib, nixgl } :
{
nixGLWrap = pkg: pkgs.runCommand "${pkg.name}-nixgl-wrapper" {} ''
mkdir $out
ln -s ${pkg}/* $out
rm $out/bin
mkdir $out/bin
for bin in ${pkg}/bin/*; do
wrapped_bin=$out/bin/$(basename $bin)
echo "exec ${lib.getExe nixgl.nixGLIntel} $bin \"\$@\"" > $wrapped_bin
chmod +x $wrapped_bin
done
'';
nixVulkanWrap = pkg: pkgs.runCommand "${pkg.name}-nixgl-wrapper" {} ''
mkdir $out
ln -s ${pkg}/* $out
rm $out/bin
mkdir $out/bin
for bin in ${pkg}/bin/*; do
wrapped_bin=$out/bin/$(basename $bin)
echo "exec ${lib.getExe nixgl.nixVulkanIntel} $bin \"\$@\"" > $wrapped_bin
chmod +x $wrapped_bin
done
'';
}
And of course, finally my custom quarto package that I had made in another post
Show
quarto.nix
{ pkgs, config, lib, ... } :
let
pandoc = null;
extraRPackages = [];
extraPythonPackages = ps: with ps; [];
in
{
quarto = (pkgs.quarto.overrideAttrs (oldAttrs: rec {
version = "1.3.361";
src = pkgs.fetchurl {
url = "https://github.com/quarto-dev/quarto-cli/releases/download/v${version}/quarto-${version}-linux-amd64.tar.gz";
sha256 = "sha256-vvnrIUhjsBXkJJ6VFsotRxkuccYOGQstIlSNWIY5nuE=";
};
buildInputs = with pkgs; [ ];
preFixup = ''
wrapProgram $out/bin/quarto \
--prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.deno ]} \
--prefix QUARTO_PANDOC : $out/bin/tools/pandoc \
--prefix QUARTO_ESBUILD : ${pkgs.esbuild}/bin/esbuild \
--prefix QUARTO_DART_SASS : $out/bin/tools/dart-sass/sass \
--prefix QUARTO_R : ${pkgs.rWrapper.override { packages = [ pkgs.rPackages.rmarkdown ] ++ extraRPackages; }}/bin/R \
--prefix QUARTO_PYTHON : ${pkgs.python3}/bin/python3
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin $out/share
mv bin/* $out/bin
mv share/* $out/share
'';
})).override {inherit pandoc extraPythonPackages extraRPackages;};
}
However, in order for running some programs with sudo to work, I had to edit opensuse’s default sudo configuration to keep environment variables, and not change the default path. This is an understandable thing to do on a multi user system, but on my single user system where I want to use some packages installed via nix with sudo, it is just annoying.
/etc/sudoers
...
##
## Defaults specification
##
## Prevent environment variables from influencing programs in an
## unexpected or harmful way (CVE-2005-2959, CVE-2005-4158, CVE-2006-0151)
#Defaults always_set_home
## Use this PATH instead of the user's to find commands.
#Defaults secure_path="/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin"
Defaults !env_reset
## Change env_reset to !env_reset in previous line to keep all environment variables ....
I’ve now uploaded my home.nix to a github repo: https://github.com/moonpiedumplings/home-manager
Here is the home.nix that is currently in the main
branch of my github repo (this is dynamically rendered and updated every update of this blog)
home.nix
{ config, pkgs, pkgs-kbctl, ... }:
{
# Home Manager needs a bit of information about you and the paths it should
# manage.
home.username = "moonpie";
home.homeDirectory = "/home/moonpie";
# This value determines the Home Manager release that your configuration is
# compatible with. This helps avoid breakage when a new Home Manager release
# introduces backwards incompatible changes.
#
# You should not change this value, even if you update Home Manager. If you do
# want to update the value, then make sure to first check the Home Manager
# release notes.
home.stateVersion = "24.05"; # Please read the comment before changing.
# The home.packages option allows you to install Nix packages into your
# environment.
home.packages = [
pkgs-kbctl.kubectl
pkgs.fluxcd
pkgs.nixgl.nixGLIntel pkgs.nixgl.nixVulkanIntel
pkgs.gzdoom
pkgs.age
pkgs.sops];
programs.man = {
enable = true;
generateCaches = true;
};
# Home Manager is pretty good at managing dotfiles. The primary way to manage
# plain files is through 'home.file'.
home.file = {
# # Building this configuration will create a copy of 'dotfiles/screenrc' in
# # the Nix store. Activating the configuration will then make '~/.screenrc' a
# # symlink to the Nix store copy.
# ".screenrc".source = dotfiles/screenrc;
# # You can also set the file content immediately.
# ".gradle/gradle.properties".text = ''
# org.gradle.console=verbose
# org.gradle.daemon.idletimeout=3600000
# '';
};
# Home Manager can also manage your environment variables through
# 'home.sessionVariables'. These will be explicitly sourced when using a
# shell provided by Home Manager. If you don't want to manage your shell
# through Home Manager then you have to manually source 'hm-session-vars.sh'
# located at either
#
# ~/.nix-profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
#
# or
#
# /etc/profiles/per-user/moonpie/etc/profile.d/hm-session-vars.sh
#
home.sessionVariables = {
# EDITOR = "emacs";
};
# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
}