Just a basic programmer living in California

  • 15 Posts
  • 88 Comments
Joined 2 years ago
cake
Cake day: February 23rd, 2024

help-circle








  • The comma command is magic! Of course I use it often to run something that I don’t feel like I need listed in my main config - especially a command that I just want to run once. But there are also plenty of cases where I do want to add a package to a config, and I know the command that I want, but I don’t know which package it comes from. The comma is a real easy way to find out.

    I haven’t watched the video - maybe these tips are already in there. If you run a command like , dig you’ll often be prompted to choose which package to get the command from, if the same command is provided by multiple packages. So that’s one way to get a package name. If you don’t get that prompt you can use comma as a lookup tool like this:

    $ , --print-packages dig
    Packages that contain /bin/dig:
    - dig.dnsutils
    - bind.dnsutils
    

    Or you can ask comma to show you the path of the executable it would run, and infer the package name from the path:

    $ , --print-path dig
    /nix/store/qm1hvm2hfryx7xz9k3njsb6gksvs29is-bind-9.20.18-dnsutils/bin/dig
    

    The Nix store path format is /nix/store/<hash>-<pname>-<version>-<output> so that is the dnsutils output of bind, which is bind.dnsutils.

    So that gives me package names I can put in my NixOS config, or devshell, or whatever. In this case I could install any of dig, bind, dig.dnsutils, or bind.dnsutils. (They all end up pointing to that binary in bind.dnsutils.)





  • I’m not informed on all the details, but a key difference between the async_trait macro and a native async keyword is that async_trait gives you that boxed, trait object type. IIUC the thinking is native support should not automatically box futures, which implies it shouldn’t use dyn either. Using Box and dyn is an easy way to make sure the code works no matter what type of future a method returns. But the trade-off is some runtime overhead from heap allocation (due to Box), and dynamic dispatch (due to dyn).

    According to areweasyncyet.rs:

    async fn in trait method not stabilized yet

    • Workaround is available as an attribute macro: async-trait

  • With callPackage you need to specify an argument set to the package expression, like this:

    callPackage ../brei/package.nix {}
    

    Without the curly braces what you have is a function instead of a derivation, which is why the error message says it’s an invalid type.

    The argument set lets you override inputs to the package set, or pass in arguments that aren’t provided by nixpkgs. But if you want all package inputs to be automatically pulled from nixpkgs then you provide an empty set.


  • Whoops! Guess I was wrong. After some experimenting it looks like the flake system parses, but does not evaluate flake.nix to read inputs. I also experimented with string concatenation, and that failed with the same error:

    nixpkgs.url = "github:nixos/nixpkgs" ++ "/nixos-25.05"; # error: expected a string or path, but got a thunk
    

    A “thunk” is an expression whose evaluation has been delayed. It’s a key piece of lazy evaluation. Remember that every expression in Nix is lazily evaluated.

    It looks only literal attribute set, string, and path expressions will work in inputs. I think that means it is not possible to split inputs over multiple files.



  • I think you can use import to load the expression from each file, and the // operator to combine imported attribute sets. Like this:

    Edit: This doesn’t work - see replies

    # flake.nix
    {
      inputs =
        import ./inputs/nixpkgs.nix //
        import ./inputs/nix-index.nix;
    
      # ...
    }
    
    # inputs/nixpkgs.nix
    {
      nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
      nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
    }
    
    # inputs/nix-index.nix
    {
      nix-index-database = {
        url = "github:Mic92/nix-index-database";
        inputs.nixpkgs.follows = "nixpkgs";
      };
    }
    


  • No, if something goes wrong with the VPN then the confined service will be unable to reach the internet. The setup runs the confined process in a network namespace that does not have a route to your default wifi or ethernet interfaces. If the VPN interface isn’t set up correctly, or stops working there is no other route out.

    You can test this with or without setting up VPN-Confinement. To do a quick test without any VPN setup, create a test service like this:

    systemd.services.test-unit = {
      serviceConfig = {
        NetworkNamespacePath = "/run/netns/test";
        Type = "oneshot";
      };
      script = ''
        ${pkgs.iputils}/bin/ping 1.1.1.1
      '';
    };
    

    Create a matching network namespace that doesn’t route anywhere:

    sudo ip netns add test
    

    Then set the unit running, and watch its output:

    sudo systemctl start test-unit.service
    journalctl -u test-unit.service -f
    

    You’ll see ping report that the network is unreachable. If you delete the namespace while ping is running it will continue to report that the network is unreachable.

    sudo ip netns del test
    

    (If you don’t want to bother with a systemd unit, you can run a process in a given network namespace using sudo ip netns exec <namespace> <command>. For example, sudo ip netns exec test ping 1.1.1.1.)

    If the namespace wasn’t set up for whatever reason the confined service won’t start. (See the edit on the post.)

    I also did some tests with the VPN-Confinement setup with this test unit:

    systemd.services.test-unit = {
      serviceConfig = {
        Type = "oneshot";
      };
      script = ''
        while true; do
          ${pkgs.curl}/bin/curl https://am.i.mullvad.net/connected
          sleep 5
        done
      '';
      vpnConfinement = {
        enable = true;
        inherit vpnNamespace;
      };
    };
    

    If I set vpnNamespace to a name that doesn’t match a configured vpnNamespace then the service won’t start.

    If I bring down the VPN namespace while that curl loop is running with sudo systemctl stop wg.service then test-unit also stops, because of the systemd dependencies that systemd.services.<name>.vpnConfinement sets up.

    If I bring down the network namespace manually while the curl loop is running with sudo ip netns del wg then the curl loop keeps running, and continues to report that it is connected to Mullvad. I guess the network namespace continues to exist while a running process is using it.

    If I bring down the VPN network interface with sudo ip -n wg link set dev wg0 down then curl fails with status=6/NOTCONFIGURED



  • I haven’t gotten much into flake-parts, but my understanding is that it creates a module system very similar to NixOS modules and Home Manager modules. Except that instead of defining a system configuration, flake-parts modules define flake outputs.

    So I don’t think you would use it in your NixOS configuration. If your configuration uses a flake there might be use cases for using it at the flake level. For example your flake defines a nixosConfigurations output, which is a set with an attribute for each host. If you had some unusually complicated code in that flake output you might use flake-parts to modularize it.

    Or I suppose flake-parts is largely aimed at simplifying per-system outputs like packages and devShells. Once again, if you wanted to split those definitions over multiple files flake-parts can do that. Or you can use it just to get flake-parts’ eachDefaultSystem helper if you don’t want to use equivalent functionality from flake-utils, or the built-in genAttrs function.

    Although I love the NixOS module system, I haven’t used flake-parts because I haven’t had a case where I want reusable modules in the context of flake outputs. Usually my flakes are a pretty uncomplicated combination of genAttrs, basic devShells, basic overlays, and package expressions that I build with callPackage.


  • hallettj@leminal.spacetoLinux@lemmy.mlLinux Users- Why?
    link
    fedilink
    English
    arrow-up
    6
    ·
    1 year ago

    I also use Niri. Previously I basically used maximimized windows on dual monitors. But I really liked the idea of switching to one ultrawide display. Maximized windows wouldn’t work well in that setup. Tiling hadn’t really worked for me because you end up with a screen full of awkwardly skinny or short windows, or windows hidden away in tabs. I also didn’t like the idea of managing floating windows with… a mouse.

    So I looked for a better option. I found PaperWM, and I loved it! Exactly what I needed! But it has a number of quirks, being an extension that entirely reworks Gnome’s window management. For a long time I wished for a native scrolling wm. And then Niri came along! And it’s so polished!


  • hallettj@leminal.spacetoLinux@lemmy.mlOkay why is your distro the best?
    link
    fedilink
    English
    arrow-up
    5
    arrow-down
    1
    ·
    1 year ago

    Some more points about Nix:

    • It’s a fast way to get to a specific setup, like a particular DE or Vulkan gaming support, thanks to abstraction that NixOS modules provide
    • There are tons of packages
    • Because packages are installed by adding a config entry you don’t accumulate random software you forgot you installed
    • Immutable updates and rollbacks - this is similar to benefits of atomic ostree distros, but the nix solutions are more general, so you have one system that does more things with a consistent interface
      • in addition to updating the base system, rollbacks also roll back user-installed packages, and configurations if those are managed via Nix
      • devshells provide per-directory packages and configuration using the same package repos as the host system, without needing to manage docker images
    • Nix is portable - much of what it does on NixOS can also be used in other distros, or even on Macos or Windows with the Linux subsystem
      • Configurations often combine NixOS and Home Manager parts. The Home Manager part can be used à la carte on other OSes is a way that is fully isolated from the host OS package management. For example on Macos this is a much nicer alternative to Homebrew.
      • devshells also work on other OSes
    • similar to Guix - but NixOS uses systemd, and is (from what I understand) more tolerant of non-free software (whether these are pros or cons is up to individual interpretation)