NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.29k stars 13.54k forks source link

Can't set multiple targets with Btrbk #241662

Open Sepero opened 1 year ago

Sepero commented 1 year ago

Describe the bug

It's important to have more than one backup, yet I can't seem to configure more than 1 backup target. I apologize if this is due to my incompetence somehow. Without luck, I have spent hours reading through Btrbk docs, NixOS Btrbk Wiki, NixOS code https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/backup/btrbk.nix

Expected behavior

It would be good if the target value accepted a String or List [], then I could unambiguously add more backup targets without nesting.

Notify maintainers

@tu-maurice @oxalica @symphorien

Sepero commented 1 year ago

I'm still working on getting my backups going. Are there any thoughts on this? Or any suggested work arounds? (other than manually writing a an /etc file)

oxalica commented 1 year ago

target is a subsection which can contain further suboptions. It accepts attrset already. You should be able to write target."ssh:/target/path" = { /* sub options */ }; like in tests.

https://github.com/NixOS/nixpkgs/blob/c8e9615acd48e3523bc62fe7ad55176c23fb1a62/nixos/tests/btrbk-section-order.nix#L14-L28

Alternatively, if you want to have different backup period for each target, you can write multiple services.btrbk.instances for the same volume.

Sepero commented 1 year ago

Thank you for your help. I must admit I'm a bit confused by the suboptions within subsections. Below is an example of what I'm trying to achieve. Simply. Notice in the target option, I'm trying to achieve 2 targets. I can't figure out how to achieve this with the current nesting scheme used.

btrbk-d = {
  onCalendar = "hourly";
  settings = {
    snapshot_create       = "onchange";
    snapshot_preserve     = "24h 14d 12w *m";
    snapshot_preserve_min = "1h";
    target_preserve       = "24h 14d 12w *m";
    target_preserve_min   = "1h";
    subvolume    = "/mnt/btrbk-d/d";
    snapshot_dir = "/mnt/btrbk-d/snaps";
    target       = [ "/mnt/back1/snaps" "/mnt/back2/snaps" ];
  };
};
oxalica commented 1 year ago

I want to reemphasize that volume, subvolume and target are subsections, "eating" multiple options below as its own children, instead of an option in the raw config file. This is explicitly mentioned in btrbk.conf(5). But in Nix, defs in attrsets are position-independent, so we define this sections-subsection-option relationship as nested ones to match its logical meaning.

Probably you want:

{
  onCalendar = "hourly";
  settings = {
    snapshot_create       = "onchange";
    snapshot_preserve     = "24h 14d 12w *m";
    snapshot_preserve_min = "1h";
    target_preserve       = "24h 14d 12w *m";
    target_preserve_min   = "1h";
    subvolume."/mnt/btrbk-d/d" = {
      snapshot_dir = "/mnt/btrbk-d/snaps";
      target."/mnt/back1/snaps" = {}; # In case of no sub-options.
      target."/mnt/back2/snaps" = {};
    };
  };
}

Typically btrbk also need a top-level volume including every subvolumes inside. But I guess you do not have a btrfs root and only mount them in /mnt. Probably omitting volume also works but I'm not sure.

Sepero commented 1 year ago

I'm using your solution and it's working fantastic! Please include something like it as an example in the documentation for others. Thank you 🎉