Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create presets #108

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft

Conversation

KFearsoff
Copy link

@KFearsoff KFearsoff commented Nov 13, 2022

This PR addresses #10. Most of the design considerations are written down in that issue.

Roadmap (not necessarily in order):

  • Allow persisting an existent file. It should be copied to the target directory and then symlinked to it from source: currently we throw an error instead. This is of utmost importance for persisting files that are created before impermanence is ran, such as /etc/machine-id
  • Create essential preset. It should take care of things one absolutely must preserve between reboots
  • Create system preset. It should take care of persisting some nice-to-haves, such as NetworkManager's passwords, bluetooth connections, and so on
  • Create services preset. It should take care of persisting data that services use, such as Prometheus, Loki and so on
  • Write an API that is reasonably easy to extend
  • Write an API that allows opting out of subpresets. For example, it would allow the user to enable system preset and then turn off preserving bluetooth connections
  • Write NixOS tests that check that presets work as expected
  • Write modules for Home Manager
  • Write documentation on usage and design considerations
  • Gather community feedback, implement presets for services that have inevitably been forgotten by me
  • Write relevant warnings and assertions

@talyz
Copy link
Collaborator

talyz commented Nov 14, 2022

The first bullet point is not possible to implement in a safe fashion - the file or directory can be read or written to while it's being copied or moved. We should absolutely not do that. I'm not really sure why it would be needed anyway, since /etc/machine-id works fine on all my systems. Is this related to systemd in initramfs?

@KFearsoff
Copy link
Author

I'm not really sure why it would be needed anyway, since /etc/machine-id works fine on all my systems

Can you share how you achieved that? I can't reproduce it on NixOS Unstable, neither on my systems nor on VMs. /etc/machine-id gets initialized before bind-mounts from Impermanence are done. Then, the impermanence bind-mount service errors out, saying that a file already exists at /etc/machine-id.

Perhaps you can point to some things that I should also test while I'm at it? I feel like this behaviour comes up pretty consistently. It is also the case with host SSH keys: they are created before Impermanence is being ran.

@talyz
Copy link
Collaborator

talyz commented Nov 14, 2022

Well, my setup is here: https://github.com/talyz/nixos-config/blob/master/modules/ephemeral-root.nix#L103 - nothing fancy at all. I get the following messages on boot:

impermanence-mount-file[1163]: mount already exists at /etc/machine-id, ignoring
impermanence-mount-file[1164]: mount already exists at /etc/ssh/ssh_host_ed25519_key, ignoring
impermanence-mount-file[1166]: mount already exists at /etc/ssh/ssh_host_ed25519_key.pub, ignoring
impermanence-mount-file[1167]: mount already exists at /etc/ssh/ssh_host_rsa_key, ignoring
impermanence-mount-file[1168]: mount already exists at /etc/ssh/ssh_host_rsa_key.pub, ignoring

but they're expected, since they've already been mounted by the activation script.

@KFearsoff
Copy link
Author

Huh. I'm not sure what to think of it.

I'll research the problem in more detail and come back with a more detailed report on what really happens and what can be done about it. I am pretty positive that I'm not getting the same behaviour, though, running NixOS Unstable and latest Impermanence.

Perhaps the issue lies in my setup. I'm not actually deleting anything on boot yet. Perhaps machine-id and SSH keys are getting generated in stage 1, then the root is erased, and only then the bind mounts happen. That would be perfectly logical, but it would also mean that setups that don't yet erase anything are not supported. If so, then this caveat should be documented.

@talyz
Copy link
Collaborator

talyz commented Nov 14, 2022

If you're not using ephemeral storage, that's the issue, yes. To bind mount files, empty files are created to serve as bind mount endpoints; if they're still there on boot, they would be identified as already existing files and not overwritten / mounted over. I suppose we could check for zero length files and consider them safe to mount over, but it's not really a supported use-case. I think the readme is already pretty clear in this regard - it's listed as the first point in the premises at the very top ;)

As a side-note, if you're afraid to accidentally delete anything, you can use something like https://github.com/talyz/nixos-config/blob/master/machines/trace/configuration.nix#L77-L86 to create a new root subvolume on every boot. This assumes you're using btrfs, but similar things should be possible with zfs.

@KFearsoff
Copy link
Author

Thanks, your insight was very helpful. I reverted the "fix" I've done. The setup indeed works with the config snippet you provided for BTRFS. I'm not sure how to make it actually erase the system though, lol.

I might make a separate PR that would offload the whole "erasing" functionality to impermanence a bit later, feel like it's a good idea. In the meantime, I think we can start the process of naming things that I forgot to add to presets. There'll be lots of them.

@talyz
Copy link
Collaborator

talyz commented Nov 15, 2022

To erase old subvolumes, I just do the following:

sudo mkdir /mnt
sudo mount /dev/root_vg/root /mnt
sudo btrfs subvolume delete "/mnt/$(sudo btrfs subvolume list -o /mnt/old_root_2022-07-6_17:51:38/ | cut -f 9 -d ' ')"
sudo btrfs subvolume delete /mnt/old_root_2022-07-6_17:51:38

I don't think erasing the root should be the task of Impermanence - there are many ways to do it and it's highly setup specific. We could however list a few examples of how to do it in the readme. I'll look into doing so.

When it comes to presets, I want to keep the structure as simple as possible:

  • one option environment.persistence.presets.enable defaulting to false
  • one option per preset under environment.persistence.presets, e.g. environment.persistence.presets.docker, which has their default set based on whether the service is enabled or not (if possible)

@KFearsoff
Copy link
Author

When it comes to presets, I want to keep the structure as simple as possible

Any particular reason for this? I feel like there's clear value in separating out the different types of state we can preserve, because it allows better judgement on what to preserve, how, if it should be backed up, etc.

@rehno-lindeque
Copy link

rehno-lindeque commented Dec 21, 2022

I'm hesitant to mention this because it's mostly aspirational (mostly something that I wished existed but really don't have time to work on myself).

But anyway, I felt it might be worth pointing out my own persistence "presets" for NixOS for reference:
https://github.com/rehno-lindeque/nixos-impermanence

Here's the list of "supported" services:
https://github.com/rehno-lindeque/nixos-impermanence/blob/28127d77d46da2777e26cf6b0d26d36fb2927823/flake.nix#L32-L41

Here's a poorly documented list of persistence levels:
https://github.com/rehno-lindeque/nixos-impermanence/blob/28127d77d46da2777e26cf6b0d26d36fb2927823/nixos-modules/environment/persistence.nix#L42-L54

Aspirationally one would be able to persist "secret" level files to a different mount than other regular files, but I'm not sure this idea would prove out (or be useful).

(There's a companion repo for Home Manager "presets" too, which is unfortunately bare)

commit 89253fb
Merge: ec1a8e7 6f4fc9d
Author: Kim Lindberger <[email protected]>
Date:   Tue May 16 21:15:34 2023 +0200

    Merge pull request nix-community#125 from ReneHollander/master

    Skip generating bind mounts if no bind mounts are configured.

commit 6f4fc9d
Author: Rene Hollander <[email protected]>
Date:   Sat Apr 15 09:38:56 2023 +0200

    Skip generating bind mounts if no bind mounts are configured.

    This fixes nix-community#105 by no longer generating an empty bash function. Empty
    functions in bash are invalid, which cause the activation to fail.

commit ec1a8e7
Merge: df1692e 5a39142
Author: Kim Lindberger <[email protected]>
Date:   Mon May 15 11:54:52 2023 +0200

    Merge pull request nix-community#128 from lovesegfault/disable

    feat(nixos): allow persistant locations to be disabled

commit 5a39142
Author: Bernardo Meurer <[email protected]>
Date:   Sun May 14 16:59:19 2023 -0400

    feat(nixos): allow persistant locations to be disabled

commit df1692e
Merge: c3f7012 2d57522
Author: Kim Lindberger <[email protected]>
Date:   Sun Apr 23 18:46:51 2023 +0200

    Merge pull request nix-community#126 from alois31/assertion-hotfix

    nixos: Fix collision detection logic

commit 2d57522
Author: Alois Wohlschlager <[email protected]>
Date:   Sun Apr 23 16:14:43 2023 +0200

    nixos: Fix collision detection logic

    The logic for detecting whether a file or directory is specified
    multiple times was not updated to account for the recent
    file/filePath and directory/dirPath changes. This can lead to spurious
    failures like the following if the same home-relative path is persisted
    for different users:

           Failed assertions:
           - environment.persistence:
               The following directories were specified two or more
               times:
                 .cache
                 .config
                 .local/share
                 .local/state
                 .gnupg
                 .ssh

    In addition, the assertion may falsely not trigger in the contrived
    situation where the same entity is persisted both in a per-user
    configuration (using the relative path) and the global configuration
    (using the absolute path).

    Fix these situations by checking the absolute paths again using
    filePath and dirPath.

commit c3f7012
Merge: 6138eb8 170e9b1
Author: Kim Lindberger <[email protected]>
Date:   Sun Apr 23 08:20:41 2023 +0200

    Merge pull request nix-community#109 from nix-community/dir-creation-order

    nixos: Improve directory creation and permission and ownership assignment

commit 170e9b1
Author: talyz <[email protected]>
Date:   Sun Nov 13 22:26:04 2022 +0100

    README: Add matrix room link

    Also, remove the unrelated name explanation.

commit b4160ba
Author: talyz <[email protected]>
Date:   Sun Nov 13 18:18:15 2022 +0100

    nixos: Rewrite directory creation for saner default permissions

    Construct directory items for all parent directories of the user
    specified files and directories, assigning better default permissions
    and ownership to each and removing this responsibility from the
    create-directories script.

    This means that all parent directories of root directories will now
    have the default permissions and ownership, not inherit them from the
    child. User directories are assigned default user ownership. The home
    directory itself is handled specially to make sure it is owned by the
    user, not readable by anyone else and its parent gets default root
    ownership.

    To illustrate this with an example, here is a directory specification
    and the ownership and permissions that could potentially be assigned
    to the parent directories, given none of them yet exist in persistent
    storage:

    environment.persistence."/persistent" = {
      users.talyz = {
        directories = [
          { directory = ".local/share/secret"; mode = "0500"; }
        ];
      };
    };

    Before:
    /home                            talyz:talyz   0500
    /home/talyz                      talyz:talyz   0500
    /home/talyz/.local               talyz:talyz   0500
    /home/talyz/.local/share         talyz:talyz   0500
    /home/talyz/.local/share/secret  talyz:talyz   0500

    After:
    /home                            root:root     0755
    /home/talyz                      talyz:talyz   0700
    /home/talyz/.local               talyz:talyz   0755
    /home/talyz/.local/share         talyz:talyz   0755
    /home/talyz/.local/share/secret  talyz:talyz   0500

commit d30c421
Author: talyz <[email protected]>
Date:   Sun Nov 13 18:17:56 2022 +0100

    nixos: Change internal file and directory semantics

    This adds the new internal options `home`, `filePath` and
    `dirPath`. Whereas previously `file` and `directory` would be
    rewritten to the full path for user files and directories, they now
    keep the value specified by the user. The new `filePath` and `dirPath`
    options fill their previous use where the full path is required. In
    addition, the new `home` option can be used to get the path to the
    user's home directory for a specific file or directory item; for root
    items it's set to `null`.

commit cc00a2a
Author: talyz <[email protected]>
Date:   Sun Nov 13 18:17:21 2022 +0100

    nixos: Use coercedTo type rather than manually converting from str

    This simplifies the code quite a bit and should be easier to maintain.

commit d144e36
Author: talyz <[email protected]>
Date:   Sun Nov 13 18:16:57 2022 +0100

    all: Line up lib inherits vertically

commit a65d708
Author: talyz <[email protected]>
Date:   Sun Nov 13 18:16:18 2022 +0100

    nixos: Use mkDefault to set the default directory permissions

    This means we don't have to pass them around as function arguments,
    making things a bit cleaner.

commit 6138eb8
Merge: 3792c10 a0b6d84
Author: Kim Lindberger <[email protected]>
Date:   Thu Feb 2 18:40:54 2023 +0100

    Merge pull request nix-community#114 from mweinelt/persist-nixos-uidgidmap

    nixos: Recommend persisting /var/lib/nixos

commit 3792c10
Merge: 5df9108 ba22f42
Author: Kim Lindberger <[email protected]>
Date:   Thu Feb 2 18:38:53 2023 +0100

    Merge pull request nix-community#115 from Kranzes/master

    nixos: Mount binds after the persistent storage path

commit ba22f42
Author: Ilan Joselevich <[email protected]>
Date:   Thu Feb 2 19:28:09 2023 +0200

    nixos: Mount binds after the persistent storage path

commit a0b6d84
Author: Martin Weinelt <[email protected]>
Date:   Thu Feb 2 17:23:19 2023 +0100

    nixos: Recommend persisting /var/lib/nixos

    The `/var/lib/nixos` directory contains the uid and gid map for entities
    without a static id. Not persisting them means your user and group ids
    could change between reboots, which is likely undesirable.

commit 5df9108
Merge: cd56321 32a5793
Author: Kim Lindberger <[email protected]>
Date:   Thu Nov 17 08:08:35 2022 +0100

    Merge pull request nix-community#110 from ckiee/gate-verbose

    mount-file.bash: be quieter when debugging is off

commit 32a5793
Author: ckie <[email protected]>
Date:   Thu Nov 17 08:09:12 2022 +0200

    mount-file.bash: be quieter when debugging is off

commit cd56321
Author: talyz <[email protected]>
Date:   Tue Nov 15 18:32:06 2022 +0100

    home-manager: Add wrappers path for fusermount

    Since
    nix-community/home-manager@8866759
    the path no longer includes the wrappers, since it's reset. To fix
    this, add the wrappers to the path.
@KFearsoff
Copy link
Author

Wanted to give an update cos I saw the NixCon talk on Impermanence and it was mentioned that PR on presets is WIP (when it is, sadly, not in progress lmao)

So there are a few things to keep in mind here:

  1. A lot of the NixOS modules follow the same few patterns, so we can try to set up some mechanism to try and hook up directly to the upstream
  2. The code quality in this PR is less than ideal, and it would be nice if I found the energy to make it better
  3. I'm not very comfortable merging this PR as is, but all things considered, it might be a good idea to focus on some of the presets first and get the ball rolling
  4. The whole thing with presets is... risky. Imagine if we encounter some regression that makes users lose data in, say, Grafana - that would be horrible. I doubt we have even human resources to extensively test for that, too. So I think a failover must be in place first. NixCon talk highlight the "use BTRFS and keep last months' roots" idea: we should probably create presets for actually setting up the Impermanence itself with BTRFS/ZFS/etc. first, in order to be sure that we are providing ways to restore the data

ambroisie added a commit to ambroisie/nix-config that referenced this pull request Oct 25, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Oct 26, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Oct 26, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Oct 26, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 11, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 11, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 11, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 11, 2023
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Jul 2, 2024
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Jul 2, 2024
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Jul 2, 2024
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 7, 2024
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 28, 2024
TODO:
* Look at for more inspiration nix-community/impermanence#108
* Do home-manager
* Common files nix-community/impermanence#10
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 28, 2024
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 28, 2024
TODO:
* Do home-manager
* Look at for more inspiration github.com:nix-community/impermanence/pull/108
* Common files github.com:nix-community/impermanence/issues/10
* Useful config: github.com:chayleaf/dotfiles/blob/f77271b249e0c08368573c22a5c34f0737d3a766/system/modules/impermanence.nix
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 28, 2024
TODO:
* Do home-manager
* Look at for more inspiration github.com:nix-community/impermanence/pull/108
* Common files github.com:nix-community/impermanence/issues/10
* Useful config: github.com:chayleaf/dotfiles/blob/f77271b249e0c08368573c22a5c34f0737d3a766/system/modules/impermanence.nix
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 28, 2024
TODO:
* Do home-manager
* Look at for more inspiration github.com:nix-community/impermanence/pull/108
* Common files github.com:nix-community/impermanence/issues/10
* Useful config: github.com:chayleaf/dotfiles/blob/f77271b249e0c08368573c22a5c34f0737d3a766/system/modules/impermanence.nix
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 28, 2024
TODO:
* Do home-manager
* Look at for more inspiration github.com:nix-community/impermanence/pull/108
* Common files github.com:nix-community/impermanence/issues/10
* Useful config: github.com:chayleaf/dotfiles/blob/f77271b249e0c08368573c22a5c34f0737d3a766/system/modules/impermanence.nix
ambroisie added a commit to ambroisie/nix-config that referenced this pull request Nov 29, 2024
TODO:
* Do home-manager
* Look at for more inspiration github.com:nix-community/impermanence/pull/108
* Common files github.com:nix-community/impermanence/issues/10
* Useful config: github.com:chayleaf/dotfiles/blob/f77271b249e0c08368573c22a5c34f0737d3a766/system/modules/impermanence.nix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants