|
166 | 166 | _path: lhs: rhs:
|
167 | 167 | !(isAttrs lhs && isAttrs rhs)
|
168 | 168 | ) lhs rhs;
|
169 |
| - |
170 | 169 | in
|
171 | 170 | recursiveMerge left right;
|
172 | 171 |
|
|
357 | 356 | */
|
358 | 357 | maybeStr = x: lib.optionalString (x != null) x;
|
359 | 358 |
|
| 359 | + /* |
| 360 | + Check whenever `b` depends on `a` as a fileSystem |
| 361 | +
|
| 362 | + Note: copied from nixpkgs/nixos/utils.nix @ 47718fe8858fa4642cd6a4f0b5a1173bad9ce8df |
| 363 | + because the file that exports it is not meant to be used standalone. |
| 364 | + */ |
| 365 | + fsBefore = |
| 366 | + a: b: |
| 367 | + with lib; |
| 368 | + let |
| 369 | + # normalisePath adds a slash at the end of the path if it didn't already |
| 370 | + # have one. |
| 371 | + # |
| 372 | + # The reason slashes are added at the end of each path is to prevent `b` |
| 373 | + # from accidentally depending on `a` in cases like |
| 374 | + # a = { mountPoint = "/aaa"; ... } |
| 375 | + # b = { device = "/aaaa"; ... } |
| 376 | + # Here a.mountPoint *is* a prefix of b.device even though a.mountPoint is |
| 377 | + # *not* a parent of b.device. If we add a slash at the end of each string, |
| 378 | + # though, this is not a problem: "/aaa/" is not a prefix of "/aaaa/". |
| 379 | + normalisePath = path: "${path}${optionalString (!(hasSuffix "/" path)) "/"}"; |
| 380 | + normalise = |
| 381 | + mount: |
| 382 | + mount |
| 383 | + // { |
| 384 | + device = normalisePath (toString mount.device); |
| 385 | + mountPoint = normalisePath mount.mountPoint; |
| 386 | + depends = map normalisePath mount.depends; |
| 387 | + }; |
| 388 | + |
| 389 | + a' = normalise a; |
| 390 | + b' = normalise b; |
| 391 | + |
| 392 | + in |
| 393 | + hasPrefix a'.mountPoint b'.device |
| 394 | + || hasPrefix a'.mountPoint b'.mountPoint |
| 395 | + || any (hasPrefix a'.mountPoint) b'.depends; |
| 396 | + |
360 | 397 | /*
|
361 | 398 | Takes a Submodules config and options argument and returns a serializable
|
362 | 399 | subset of config variables as a shell script snippet.
|
|
956 | 993 | default =
|
957 | 994 | with lib;
|
958 | 995 | let
|
| 996 | + mountOrder = pipe cfg.config._config.fileSystems.contents [ |
| 997 | + (foldl' recursiveUpdate { }) |
| 998 | + (mapAttrsToList ( |
| 999 | + mountPoint: value: |
| 1000 | + value |
| 1001 | + // { |
| 1002 | + mountPoint = value.mountPoint or mountPoint; |
| 1003 | + depends = [ ]; |
| 1004 | + } |
| 1005 | + )) |
| 1006 | + (toposort diskoLib.fsBefore) |
| 1007 | + (getAttr "result") |
| 1008 | + (map (getAttr "mountPoint")) |
| 1009 | + ]; |
| 1010 | + |
959 | 1011 | fsMounts = diskoLib.deepMergeMap (dev: dev._mount.fs or { }) (
|
960 | 1012 | flatten (map attrValues (attrValues devices))
|
961 | 1013 | );
|
| 1014 | + |
962 | 1015 | sortedDeviceList = diskoLib.sortDevicesByDependencies (cfg.config._meta.deviceDependencies or { }
|
963 | 1016 | ) devices;
|
964 | 1017 | in
|
|
968 | 1021 | ${concatMapStrings (dev: (attrByPath (dev ++ [ "_mount" ]) { } devices).dev or "") sortedDeviceList}
|
969 | 1022 |
|
970 | 1023 | # and then mount the filesystems in alphabetical order
|
971 |
| - ${concatStrings (attrValues fsMounts)} |
| 1024 | + ${concatStrings (attrVals mountOrder fsMounts)} |
972 | 1025 | '';
|
973 | 1026 | };
|
974 | 1027 | _unmount = lib.mkOption {
|
|
0 commit comments