Skip to content

lf-/flakey-profile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flakey-profile

This is a trivial tool to create declarative profiles with Nix flakes. This is achieved with the same mechanisms as used by home-manager and NixOS: nix-env --set, nix-env --list-generations, and nix-env --rollback.

The purpose of this tool is that people stop stubbing their toes on nix profile and nix-env for non-declarative uses on non-NixOS systems by providing a declarative alternative using flakes to pin versions of things.

Non-goals

  • Support nix profile list as complained about here. We are in favour of the removal of nix profile from the Nix codebase in lieu of stabilization.

  • Compatibility with imperative package management: there is no clear way to share a profile with an imperative setup.

    We might write a migration script in the future that takes nix profile list --json and converts it into a flake.

  • Do similar things to home-manager for services or other things. This is just a replacement for nix-env and nix profile and nothing more.

Related work

  • home-mangler, which uses a few hundred lines of Rust to wrangle nix profile into having exactly the expected packages installed. Their approach makes nix profile list work. By comparison, this project consists of two lines of shell script that bypass nix profile altogether.
  • nixos-rebuild, which uses the same methods to achieve its goals.
  • home-manager which is implemented via inexplicable cursed crimes for nix profile or the same method as this otherwise.
  • Flakes as a unified format for profiles
  • Stop Using nix-env

Usage

To use it, see the template in templates/default, or included below, or run:

nix flake init -t github:lf-/flakey-profile#templates.default

Flake example:

# SPDX-FileCopyrightText: 2023 Jade Lovelace
#
# SPDX-License-Identifier: CC0-1.0

{
  description = "Basic usage of flakey-profile";

  inputs = {
    flakey-profile.url = "github:lf-/flakey-profile";
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils, flakey-profile }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs {
          inherit system;
        };
      in
      {
        # Any extra arguments to mkProfile are forwarded directly to pkgs.buildEnv.
        #
        # Usage:
        # Switch to this flake:
        #   nix run .#profile.switch
        # Revert a profile change (note: does not revert pins):
        #   nix run .#profile.rollback
        # Build, without switching:
        #   nix build .#profile
        # Pin nixpkgs in the flake registry and in NIX_PATH, so that
        # `nix run nixpkgs#hello` and `nix-shell -p hello --run hello` will
        # resolve to the same hello as below [should probably be run as root, see README caveats]:
        #   sudo nix run .#profile.pin
        packages.profile = flakey-profile.lib.mkProfile {
          inherit pkgs;
          # Specifies things to pin in the flake registry and in NIX_PATH.
          pinned = { nixpkgs = toString nixpkgs; };
          paths = with pkgs; [
            hello
          ];
        };
      });
}

Then, use the following commands to do things with the new profile:

Build the profile and switch to it

nix run .#profile.switch

Revert a profile change

Warning: This does not rollback the actions of profile.pin. To roll that back, revert to the previous version of the profile using a version control system and run profile.pin again.

nix run .#profile.rollback

Build, without switching

nix build .#profile

Update package versions

nix flake lock --update-input nixpkgs

or

nix flake update

then

nix run .#profile.switch

Pin nixpkgs in the flake registry and in NIX_PATH

This makes nix run nixpkgs#hello and nix-shell -p hello --run hello give you the same hello as if you listed it in your profile.

Important

We recommend only running this command as root, since by default the only channels used are on root's profile, and are used for nix upgrade-nix and other uses of nix as root.

Warning

This does not support revert internally; see below for more details. To revert pinning, use source control to get the previous version of the profile and run the pinning operation again.

nix run .#profile.pin

Context

The flake registry is used to resolve unqualified flake names such as nixpkgs in nix run nixpkgs#hello, and can be overridden on a per-user or system-wide basis. NIX_PATH is used to resolve <nixpkgs> and other references in angle brackets, and if not present, this procedure is used. By running profile.pin, both the flake registry and the channel of the running user will be overridden to point to the nixpkgs you used to build your profile.

Note

We don't provide an easy way of rolling back a pin, since the Nix flake registry is not managed with profiles and the semantics of keeping everything in sync when reverting don't really work out. We suggest rolling back pins by reverting to the previous version in your preferred version control system, then rerunning pin.

In a different implementation, we would just use an activation script to achieve this the same way as NixOS and home-manager, however, that conflicts with the goals of this project.

If it is useful to fixing a system, the things changed are in ~/.config/nix/registry.json (/etc/nix/registry.json if run as root), and linked to from ~/.nix-defexpr/. Channels can be rolled back with nix-env --profile $(readlink ~/.nix-defexpr/channels) --rollback or for root, sudo nix-env --profile $(readlink ~/.nix-defexpr/channels_root) --rollback. The former, not much can be done about, and it's probably easiest to just delete the registry.json if it's broken.

Common problems

It seems that often people run into an issue where /nix/var/nix/profiles/per-user/$USER does not exist. If this is the case, you can simply sudo mkdir -p /nix/var/nix/profiles/per-user/$USER && sudo chown $USER /nix/var/nix/profiles/per-user/$USER. Or, alternatively, nix-env -f '<nixpkgs>' -iA hello might fix it, but if it does not, try the other one.

This has so far been observed on macOS, however we are unsure if this is a Mac only bug.

About

Declarative profiles with nix flakes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages