1
1
mirror of https://github.com/divnix/digga.git synced 2024-12-22 15:41:46 +03:00

💎 style Format files

This commit is contained in:
Lord-Valen 2022-11-08 09:06:32 -05:00 committed by David Arnold
parent 57c2796774
commit 5d159417c6
85 changed files with 2032 additions and 1934 deletions

View File

@ -6,7 +6,7 @@
- A quick question. [\#428](https://github.com/divnix/digga/issues/428)
- infinite recursion error related to whether a git repo exists \#408 [\#413](https://github.com/divnix/digga/issues/413)
- Support aarch64-darwin [\#335](https://github.com/divnix/digga/issues/335)
- Support aarch64-darwin [\#335](https://github.com/divnix/digga/issues/335)
- pkgs in home-manager profiles [\#309](https://github.com/divnix/digga/issues/309)
- Allow the same user profile to behave differently based on hostname [\#308](https://github.com/divnix/digga/issues/308)
- Home-manager inside ./modules or ./profiles to set user settings in a user agnostic way [\#303](https://github.com/divnix/digga/issues/303)
@ -126,7 +126,7 @@
**Fixed bugs:**
- My emacsGcc overlay is not working [\#146](https://github.com/divnix/digga/issues/146)
- My emacsGcc overlay is not working [\#146](https://github.com/divnix/digga/issues/146)
- local flake registry freezes branches [\#142](https://github.com/divnix/digga/issues/142)
- nixos-option no longer works after collect garbage [\#138](https://github.com/divnix/digga/issues/138)
- Profiles imports are brittle, causing failure if imported twice [\#136](https://github.com/divnix/digga/issues/136)
@ -158,6 +158,4 @@
## [07092020](https://github.com/divnix/digga/tree/07092020) (2020-07-09)
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
\* _This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)_

View File

@ -2,7 +2,6 @@
[![NixOS](https://img.shields.io/badge/NixOS-unstable-blue.svg?style=flat&logo=NixOS&logoColor=white)](https://nixos.org)
[![Chat](https://img.shields.io/badge/chat-join%20us-brightgreen.svg?style=flat&logo=matrix&logoColor=white)](https://matrix.to/#/#devos:nixos.org)
Digga — slangy German for "good friend" — is a flake utility library
that helps you declaratively craft and manage all three layers of your system
environment within a single [nix flakes][flakes] repository:
@ -14,28 +13,32 @@ environment within a single [nix flakes][flakes] repository:
This library is based on [flake-utils-plus][].
# Status: Beta
Although this project has already matured quite a bit, a fair amount of api polishing is still
expected. There are unstable versions (0._x_._x_) to help users keep track
of changes and progress.
# Usage
The best way to make use of library is with the [Official template][template].
Check out the [guide](./doc/start/index.md) to get up and running.
Also have a look at devos's [_flake.nix_](./examples/devos/flake.nix).
If anything is not immediately discoverable via our [`mkFlake`][mk-flake], please file a bug report.
# Examples
Make sure to check out all the [examples](./examples) to see the different ways
to make use of the digga api.
## In the Wild
You can also see digga being actually used:
* @Pacman99: [Personal](https://gitlab.com/coffeetables/lower), [Server](https://gitlab.com/coffeetables/myrdd)
* [@danielphan2003](https://github.com/danielphan2003/flk) and make sure to also check out [devos-ext-lib](https://github.com/divnix/devos-ext-lib)
* [PubSolarOS](https://git.sr.ht/~b12f/pub-solar-os)
* @montchr: [Dotfield](https://github.com/montchr/dotfield) including darwin configurations
* [@sweenu](https://github.com/sweenu/nixfiles): pc, server and RaspberryPi deployment in one repo
You can also see digga being actually used:
- @Pacman99: [Personal](https://gitlab.com/coffeetables/lower), [Server](https://gitlab.com/coffeetables/myrdd)
- [@danielphan2003](https://github.com/danielphan2003/flk) and make sure to also check out [devos-ext-lib](https://github.com/divnix/devos-ext-lib)
- [PubSolarOS](https://git.sr.ht/~b12f/pub-solar-os)
- @montchr: [Dotfield](https://github.com/montchr/dotfield) including darwin configurations
- [@sweenu](https://github.com/sweenu/nixfiles): pc, server and RaspberryPi deployment in one repo
# Philosophy
@ -54,17 +57,19 @@ interface comprising four API containers that allow you to:
your projects.
## Modules, Profiles & Suites
For NixOS- & home-manager-modules, _Digga_ allows you to distinguish between
_modules_, _profiles_ and _suites_.
- **Modules** are abstract configurations that, while holding the implementation, do not
set any system state.
set any system state.
- **Profiles** are concrete configurations that set system state within the profile domain.
- **Suites** are a composable, clean and discoverable mechanism for profile aggregation.
## Internal Art vs External Art
Overlays and modules can be defined internally coming from your repo or externally
coming from an upstream flake. This distinction serves the library to only export
your own work as the public flake output.
@ -73,6 +78,7 @@ Downstream consumers of your flake can now more easily tell your art apart from
other upstream art.
# Contributing
We encourage contributions of any kind. The simplest way to get involved is to
join the [chat][] or report problems and ideas on the [issue thread][issues].
@ -81,19 +87,23 @@ To craft well thought out APIs we need all the thoughts regarding new ideas.
Pull Requests are just as amazing.
# Why _flakes_?
Flakes are a part of an explicit push to improve [Nix's UX](https://github.com/NixOS/nix/blob/master/doc/manual/src/contributing/cli-guideline.md), and have become an integral part of that effort.
Flakes are a part of an explicit push to improve [Nix's UX](https://github.com/NixOS/nix/blob/master/doc/manual/src/contributing/cli-guideline.md), and have become an integral part of that effort.
They also make [Nix expressions](https://nixos.org/manual/nix/unstable/expressions/expression-syntax.html) easier to distribute and reuse with convient [flake references](https://github.com/NixOS/nix/blob/master/src/nix/flake.md#flake-references) for building or using packages, modules, and whole systems.
# Shoulders
This work does not reinvent the wheel. It stands on the [shoulders of the
following giants][giants]:
## :onion: — like the layers of an onion
- [`gytis-ivaskevicius/flake-utils-plus`](https://github.com/gytis-ivaskevicius/flake-utils-plus)
- [`numtide/flake-utils`](https://github.com/numtide/flake-utils/)
## :family: — like family
- [`numtide/devshell`](https://github.com/numtide/devshell)
- [`serokell/deploy-rs`](https://github.com/serokell/deploy-rs)
- [`berberman/nvfetcher`](https://github.com/berberman/nvfetcher)
@ -102,6 +112,7 @@ following giants][giants]:
:heart:
### Inspiration & Art
- [hlissner/dotfiles](https://github.com/hlissner/dotfiles)
- [nix-user-chroot](https://github.com/nix-community/nix-user-chroot)
- [Nickel](https://github.com/tweag/nickel)
@ -109,6 +120,7 @@ following giants][giants]:
- [devshell](https://github.com/numtide/devshell)
# Divnix
The divnix org is an open space that spontaneously formed out of "the Nix".
It is really just a place where otherwise unrelated people work
together and get stuff done.
@ -121,6 +133,7 @@ It might eventually become a non-profit if that's not too complicated or, if tho
goals are sufficiently upstreamed into "the Nix", dissolved.
# License
Digga is licensed under the [MIT License][mit].
[mk-flake]: ./src/mkFlake
@ -136,4 +149,3 @@ Digga is licensed under the [MIT License][mit].
[nix]: https://nixos.org/manual/nix/stable
[nixpkgs]: https://github.com/nixos/nixpkgs
[template]: ./examples/devos

View File

@ -1,39 +1,38 @@
{ system ? builtins.currentSystem
, inputs ? (import ../.).inputs
}:
let
{
system ? builtins.currentSystem,
inputs ? (import ../.).inputs,
}: let
inherit (inputs) digga nixpkgs;
lib = nixpkgs.lib // digga.lib;
pkgs = nixpkgs.legacyPackages.${system};
in
{
libTests = pkgs.runCommandNoCC "devos-lib-tests"
in {
libTests =
pkgs.runCommandNoCC "devos-lib-tests"
{
buildInputs = [
pkgs.nix
(
let tests = import ./lib { inherit pkgs lib; }; in
if tests == [ ] then null
else throw (builtins.toJSON tests)
let
tests = import ./lib {inherit pkgs lib;};
in
if tests == []
then null
else throw (builtins.toJSON tests)
)
];
} ''
datadir="${pkgs.nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_BUILD_HOOK=
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
nix-store --init
touch $out
'';
datadir="${pkgs.nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_BUILD_HOOK=
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
nix-store --init
touch $out
'';
}

View File

@ -1,23 +1,26 @@
{ pkgs, lib }:
{
pkgs,
lib,
}:
with lib;
lib.runTests {
testRakeLeaves = {
expr = rakeLeaves ./profiles;
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
t = {
bar = ./profiles/t/bar.nix;
lib.runTests {
testRakeLeaves = {
expr = rakeLeaves ./profiles;
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
t = {
bar = ./profiles/t/bar.nix;
};
};
};
};
testFlattenTree = {
expr = flattenTree (rakeLeaves ./profiles);
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
"t.bar" = ./profiles/t/bar.nix;
testFlattenTree = {
expr = flattenTree (rakeLeaves ./profiles);
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
"t.bar" = ./profiles/t/bar.nix;
};
};
};
}
}

View File

@ -1 +1 @@
{ }
{}

View File

@ -1 +1 @@
{ }
{}

View File

@ -1,17 +1,22 @@
let
inherit (import
(
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{ src = ./.; }) defaultNix;
inherit
(import
(
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{src = ./.;})
defaultNix
;
in
# Pass this flake as inputs.digga
defaultNix // {
inputs = defaultNix.inputs // { digga = defaultNix; };
shell = import ./devShell.nix { };
}
# Pass this flake as inputs.digga
defaultNix
// {
inputs = defaultNix.inputs // {digga = defaultNix;};
shell = import ./devShell.nix {};
}

View File

@ -1,16 +1,17 @@
{ lib, importers }:
{
lib,
importers,
}:
lib.warn ''
You are accessing a deprecated item of the digga lib.
Please update timely, it will be remove soon.
''
rec {
importModules =
lib.warn ''
Deprecated Function: lib.importModules.
Use lib.importExportableModules instead to set `exportedModules` option
''
importers.importExportableModules;
importers.importExportableModules;
}

View File

@ -1,13 +1,13 @@
{ system ? builtins.currentSystem
, inputs ? (import ./.).inputs
}:
let
{
system ? builtins.currentSystem,
inputs ? (import ./.).inputs,
}: let
pkgs = inputs.nixpkgs.legacyPackages.${system};
unstablePkgs = inputs.nixpkgs-unstable.legacyPackages.${system};
devshell = import inputs.devshell { inherit system; };
devshell = import inputs.devshell {inherit system;};
nixBin = "${unstablePkgs.nix}/bin/nix";
withCategory = category: attrset: attrset // { inherit category; };
withCategory = category: attrset: attrset // {inherit category;};
utils = withCategory "utils";
docs = withCategory "docs";
@ -31,84 +31,81 @@ let
&& cp result "$PRJ_ROOT/doc/api-reference-nixos.md" \
&& chmod 755 "$PRJ_ROOT//doc/api-reference-nixos.md"
'';
};
test = type: name: withCategory "tests" {
name = "check-${name}";
help = "Checks ${name} ${type}";
command = ''
set -e
# set -x
test = type: name:
withCategory "tests" {
name = "check-${name}";
help = "Checks ${name} ${type}";
command = ''
set -e
# set -x
tempdigga=path:$PRJ_ROOT
tempdigga=path:$PRJ_ROOT
trap_err() {
local ret=$?
echo -e \
"\033[1m\033[31m""exit $ret: \033[0m\033[1m""command [$BASH_COMMAND] failed""\033[0m"
}
trap_err() {
local ret=$?
echo -e \
"\033[1m\033[31m""exit $ret: \033[0m\033[1m""command [$BASH_COMMAND] failed""\033[0m"
}
is () { [ "$1" -eq "0" ]; }
is () { [ "$1" -eq "0" ]; }
trap 'trap_err' ERR
trap 'trap_err' ERR
# --------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
cd $PRJ_ROOT/${type}/${name}
${nixBin} flake show "$@" --override-input digga $tempdigga
${nixBin} flake check "$@" --override-input digga $tempdigga
'';
};
cd $PRJ_ROOT/${type}/${name}
${nixBin} flake show "$@" --override-input digga $tempdigga
${nixBin} flake check "$@" --override-input digga $tempdigga
'';
};
in
devshell.mkShell {
name = "digga";
packages = with pkgs; [
fd
treefmt
alejandra
nodePackages.prettier
shellcheck
shfmt
# Use the latest stable version of nix
unstablePkgs.nix
];
devshell.mkShell {
name = "digga";
packages = with pkgs; [
fd
treefmt
alejandra
nodePackages.prettier
shellcheck
shfmt
# Use the latest stable version of nix
unstablePkgs.nix
];
env = [
{
name = "NIX_CONFIG";
value =
''extra-experimental-features = nix-command flakes
extra-substituters = https://nrdxp.cachix.org https://nix-community.cachix.org
extra-trusted-public-keys = nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs='';
}
];
env = [
{
name = "NIX_CONFIG";
value = '' extra-experimental-features = nix-command flakes
extra-substituters = https://nrdxp.cachix.org https://nix-community.cachix.org
extra-trusted-public-keys = nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs='';
}
];
commands = [
(utils {
command = "git rm --ignore-unmatch -f $PRJ_ROOT/{tests,examples}/*/flake.lock";
help = "Remove all lock files";
name = "rm-locks";
})
(utils {
name = "fmt";
help = "Check formatting";
command = "treefmt \${@} $PRJ_ROOT";
})
(utils {
name = "evalnix";
help = "Check Nix parsing";
command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null";
})
commands = [
(utils {
command = "git rm --ignore-unmatch -f $PRJ_ROOT/{tests,examples}/*/flake.lock";
help = "Remove all lock files";
name = "rm-locks";
})
(utils {
name = "fmt";
help = "Check formatting";
command = "treefmt \${@} $PRJ_ROOT";
})
(utils {
name = "evalnix";
help = "Check Nix parsing";
command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null";
})
(test "examples" "devos")
(test "examples" "groupByConfig")
(test "examples" "hmOnly")
(test "examples" "all" // { command = "check-devos && check-groupByConfig && check-hmOnly"; })
(docs { package = pkgs.mdbook; })
(docs makeDocs)
];
}
(test "examples" "devos")
(test "examples" "groupByConfig")
(test "examples" "hmOnly")
(test "examples" "all" // {command = "check-devos && check-groupByConfig && check-hmOnly";})
(docs {package = pkgs.mdbook;})
(docs makeDocs)
];
}

View File

@ -1,14 +1,15 @@
# TL;DR;
- **Target Branch**: `main`
- **Merge Policy**: green check: merge away. yellow circle: have patience. red x: try again.
- **Docs**: every change set is expected to contain doc updates
- **Commit Msg**: be a poet! Comprehensive and explanatory commit messages
- **Commit Msg**: be a poet! Comprehensive and explanatory commit messages
should cover the motivation and use case in an easily understandable manner
even when read after a few months.
- **Test Driven Development**: please default to test driven development you can
make use of the `./examples` & `./e2e` and wire test up in the devshell.
make use of the `./examples` & `./e2e` and wire test up in the devshell.
### Within the Devshell (`nix develop`)
- **Hooks**: please `git commit` within the devshell
- **Fail Early**: please run `check-all` from within the devshell on your local machine

View File

@ -1,91 +1,76 @@
# Channels API Container
Configure your channels that you can use throughout your configurations.
> #### ⚠ Gotcha ⚠
>
> Devshell & (non-host-specific) Home-Manager `pkgs` instances are rendered off the
> `nixos.hostDefaults.channelName` (default) channel.
## channels
nixpkgs channels to create
*_Type_*:
_*Type*_:
attribute set of submodules or path convertible to it
_*Default*_
*_Default_*
```
{}
```
## channels.\<name\>.config
nixpkgs config for this channel
*_Type_*:
_*Type*_:
attribute set or path convertible to it
_*Default*_
*_Default_*
```
{}
```
## channels.\<name\>.input
nixpkgs flake input to use for this channel
*_Type_*:
_*Type*_:
nix flake
_*Default*_
*_Default_*
```
"self.inputs.<name>"
```
## channels.\<name\>.overlays
overlays to apply to this channel
these will get exported under the 'overlays' flake output
as \<channel\>/\<name\> and any overlay pulled from \<inputs\>
will be filtered out
*_Type_*:
_*Type*_:
list of valid Nixpkgs overlay or path convertible to its or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```
## channels.\<name\>.patches
patches to apply to this channel
*_Type_*:
_*Type*_:
list of paths
_*Default*_
*_Default_*
```
[]
```

View File

@ -1,72 +1,59 @@
# Devshell API Container
Configure your devshell module collections of your environment.
## devshell
Modules to include in your DevOS shell. the `modules` argument
will be exported under the `devshellModules` output
*_Type_*:
_*Type*_:
submodule or path convertible to it
_*Default*_
*_Default_*
```
{}
```
## devshell.exportedModules
modules to include in all hosts and export to devshellModules output
*_Type_*:
_*Type*_:
list of valid module or path convertible to its or anything convertible to it
_*Default*_
*_Default_*
```
[]
```
## devshell.externalModules
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it
_*Default*_
*_Default_*
```
[]
```
## devshell.modules
modules to include that won't be exported
meant importing modules from external flakes
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```

View File

@ -1,119 +1,97 @@
# Home-Manager API Container
Configure your home manager modules, profiles & suites.
## home
hosts, modules, suites, and profiles for home-manager
*_Type_*:
_*Type*_:
submodule or path convertible to it
_*Default*_
*_Default_*
```
{}
```
## home.exportedModules
modules to include in all hosts and export to homeModules output
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```
## home.externalModules
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it
_*Default*_
*_Default_*
```
[]
```
## home.importables
Packages of paths to be passed to modules as `specialArgs`.
*_Type_*:
_*Type*_:
attribute set
_*Default*_
*_Default_*
```
{}
```
## home.importables.suites
collections of profiles
*_Type_*:
_*Type*_:
null or attribute set of list of paths or anything convertible to its or path convertible to it
_*Default*_
*_Default_*
```
null
```
## home.modules
modules to include that won't be exported
meant importing modules from external flakes
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```
## home.users
HM users that can be deployed portably without a host.
*_Type_*:
_*Type*_:
attribute set of HM user configs
_*Default*_
*_Default_*
```
{}
```

View File

@ -1,234 +1,191 @@
# NixOS API Container
Configure your nixos modules, profiles & suites.
## nixos
hosts, modules, suites, and profiles for NixOS
*_Type_*:
_*Type*_:
submodule or path convertible to it
_*Default*_
*_Default_*
```
{}
```
## nixos.hostDefaults
Defaults for all hosts.
the modules passed under hostDefaults will be exported
to the 'nixosModules' flake output.
They will also be added to all hosts.
*_Type_*:
_*Type*_:
submodule
_*Default*_
*_Default_*
```
{}
```
## nixos.hostDefaults.channelName
Channel this host should follow
*_Type_*:
_*Type*_:
channel defined in `channels`
## nixos.hostDefaults.exportedModules
modules to include in all hosts and export to nixosModules output
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```
## nixos.hostDefaults.externalModules
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it
_*Default*_
*_Default_*
```
[]
```
## nixos.hostDefaults.modules
modules to include that won't be exported
meant importing modules from external flakes
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```
## nixos.hostDefaults.system
system for this host
*_Type_*:
_*Type*_:
null or system defined in `supportedSystems`
_*Default*_
*_Default_*
```
null
```
## nixos.hosts
configurations to include in the nixosConfigurations output
*_Type_*:
_*Type*_:
attribute set of submodules
_*Default*_
*_Default_*
```
{}
```
## nixos.hosts.\<name\>.channelName
Channel this host should follow
*_Type_*:
_*Type*_:
null or channel defined in `channels`
_*Default*_
*_Default_*
```
null
```
## nixos.hosts.\<name\>.modules
modules to include
*_Type_*:
_*Type*_:
list of valid modules or anything convertible to it or path convertible to it
_*Default*_
*_Default_*
```
[]
```
## nixos.hosts.\<name\>.system
system for this host
*_Type_*:
_*Type*_:
null or system defined in `supportedSystems`
_*Default*_
*_Default_*
```
null
```
## nixos.hosts.\<name\>.tests
tests to run
*_Type_*:
_*Type*_:
list of valid NixOS test or path convertible to its or anything convertible to it
_*Default*_
*_Default_*
```
[]
```
_*Example*_
*_Example_*
```
{"_type":"literalExpression","text":"[\n {\n name = \"testname1\";\n machine = { ... };\n testScript = ''\n # ...\n '';\n }\n ({ corutils, writers, ... }: {\n name = \"testname2\";\n machine = { ... };\n testScript = ''\n # ...\n '';\n })\n ./path/to/test.nix\n];\n"}
```
## nixos.importables
Packages of paths to be passed to modules as `specialArgs`.
*_Type_*:
_*Type*_:
attribute set
_*Default*_
*_Default_*
```
{}
```
## nixos.importables.suites
collections of profiles
*_Type_*:
_*Type*_:
null or attribute set of list of paths or anything convertible to its or path convertible to it
_*Default*_
*_Default_*
```
null
```

View File

@ -1,4 +1,5 @@
# Top Level API
`digga`'s top level API. API Containers are documented in their respective sub-chapter:
- [Channels](./api-reference-channels.md)
@ -8,73 +9,55 @@
- [Darwin](./api-reference-darwin.md)
## channelsConfig
nixpkgs config for all channels
*_Type_*:
_*Type*_:
attribute set or path convertible to it
_*Default*_
*_Default_*
```
{}
```
## inputs
The flake's inputs
*_Type_*:
_*Type*_:
attribute set of nix flakes
## outputsBuilder
builder for flake system-spaced outputs
The builder gets passed an attrset of all channels
*_Type_*:
_*Type*_:
function that evaluates to a(n) attribute set or path convertible to it
_*Default*_
*_Default_*
```
"channels: { }"
```
## self
The flake to create the DevOS outputs for
*_Type_*:
_*Type*_:
nix flake
## supportedSystems
The systems supported by this flake
*_Type_*:
_*Type*_:
list of strings
_*Default*_
*_Default_*
```
["aarch64-linux","aarch64-darwin","i686-linux","x86_64-darwin","x86_64-linux"]
```

View File

@ -28,10 +28,10 @@ is best saved for [profile modules](./profiles.md).
This is a good place to import sets of profiles, called [suites](./suites.md),
that you intend to use on your machine.
## Example
flake.nix:
```nix
{
nixos = {
@ -47,6 +47,7 @@ flake.nix:
```
hosts/librem.nix:
```nix
{ suites, ... }:
{

View File

@ -1,8 +1,10 @@
# Overrides
Each NixOS host follows one channel. But many times it is useful to get packages
or modules from different channels.
## Packages
You can make use of `overlays/overrides.nix` to override specific packages in the
default channel to be pulled from other channels. That file is simply an example
of how any overlay can get `channels` as their first argument.
@ -10,6 +12,7 @@ of how any overlay can get `channels` as their first argument.
You can add overlays to any channel to override packages from other channels.
Pulling the manix package from the `latest` channel:
```nix
channels: final: prev: {
__dontExport = true;
@ -23,11 +26,12 @@ overrides and the property is already set for you.
## Modules
You can also pull modules from other channels. All modules have access to the
You can also pull modules from other channels. All modules have access to the
`modulesPath` for each channel as `<channelName>ModulesPath`. And you can use
`disabledModules` to remove modules from the current channel.
To pull zsh module from the `latest` channel this code can be placed in any module, whether its your host file, a profile, or a module in ./modules etc:
```nix
{ latestModulesPath }:
{
@ -37,6 +41,7 @@ To pull zsh module from the `latest` channel this code can be placed in any modu
```
> ##### _Note:_
>
> Sometimes a modules name will change from one branch to another.
[nixpkgs-modules]: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules

View File

@ -6,20 +6,23 @@ built into the NixOS module system for a reason: to elegantly provide a clear
separation of concerns.
## Creation
Profiles are created with the `rakeLeaves` function which recursively collects
`.nix` files from within a folder. The recursion stops at folders with a `default.nix`
`.nix` files from within a folder. The recursion stops at folders with a `default.nix`
in them. You end up with an attribute set with leaves(paths to profiles) or
nodes(attrsets leading to more nodes or leaves).
A profile is used for quick modularization of [interelated bits](./profiles.md#subprofiles).
> ##### _Notes:_
> * For _declaring_ module options, there's the [modules](../outputs/modules.md) directory.
> * This directory takes inspiration from
>
> - For _declaring_ module options, there's the [modules](../outputs/modules.md) directory.
> - This directory takes inspiration from
> [upstream](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/profiles)
> .
### Nested profiles
Profiles can be nested in attribute sets due to the recursive nature of `rakeLeaves`.
This can be useful to have a set of profiles created for a specific purpose. It is
sometimes useful to have a `common` profile that has high level concerns related
@ -28,6 +31,7 @@ to all its sister profiles.
### Example
profiles/develop/common.nix:
```nix
{
imports = [ ./zsh ];
@ -36,6 +40,7 @@ profiles/develop/common.nix:
```
profiles/develop/zsh.nix:
```nix
{ ... }:
{
@ -45,6 +50,7 @@ profiles/develop/zsh.nix:
```
The examples above will end up with a profiles set like this:
```nix
{
develop = {
@ -55,6 +61,7 @@ The examples above will end up with a profiles set like this:
```
## Conclusion
Profiles are the most important concept in DevOS. They allow us to keep our
Nix expressions self contained and modular. This way we can maximize reuse
across hosts while minimizing boilerplate. Remember, anything machine

View File

@ -1,4 +1,5 @@
# Suites
Suites provide a mechanism for users to easily combine and name collections of
profiles.
@ -8,6 +9,7 @@ argument (one that can be use in an `imports` line) to your hosts. All lists def
in `suites` are flattened and type-checked as paths.
## Definition
```nix
rec {
workstation = [ profiles.develop profiles.graphical users.nixos ];
@ -16,7 +18,9 @@ rec {
```
## Usage
`hosts/my-laptop.nix`:
```nix
{ suites, ... }:
{

View File

@ -1,5 +1,6 @@
> ##### _Note:_
> This section and its semantics need a conceptiual rework.
>
> This section and its semantics need a conceptiual rework.
> Since recently [portable home configurations][portableuser]
> that are not bound to any specific host are a thing.
@ -11,7 +12,9 @@ home manager is wired in by default so all you have to worry about is declaring
your users.
## Basic Usage
`users/myuser/default.nix`:
```nix
{ ... }:
{
@ -27,6 +30,7 @@ your users.
```
## Home Manager
Home Manager support follows the same principles as regular nixos configurations,
it even gets its own namespace in your `flake.nix` as `home`.
@ -36,7 +40,9 @@ User profiles can be collected in a similar fashion as system ones into a `suite
argument that gets passed to your home-manager users.
### Example
`flake.nix`
```nix
{
home.users.nixos = { suites, ... }: {
@ -45,10 +51,10 @@ argument that gets passed to your home-manager users.
}
```
## External Usage
You can easily use the defined home-manager configurations outside of NixOS
using the `homeConfigurations` flake output.
using the `homeConfigurations` flake output.
This is great for keeping your environment consistent across Unix-like systems,
including macOS.

View File

@ -1,4 +1,5 @@
# Cachix
The system will automatically pull a cachix.nix at the root if one exists.
This is usually created automatically by a `sudo cachix use`. If you're more
inclined to keep the root clean, you can drop any generated files in the

View File

@ -1,4 +1,5 @@
# deploy-rs
[Deploy-rs][d-rs] is a tool for managing NixOS remote machines. It was
chosen for devos after the author experienced some frustrations with the
stateful nature of nixops' db. It was also designed from scratch to support
@ -11,6 +12,7 @@ the command line.
## Usage
Just add your ssh key to the host:
```nix
{ ... }:
{
@ -21,6 +23,7 @@ Just add your ssh key to the host:
```
And the private key to your user:
```nix
{ ... }:
{
@ -39,16 +42,20 @@ And the private key to your user:
```
And run the deployment:
```sh
deploy '.#hostName' --hostname host.example.com
```
> ##### _Note:_
>
> Your user will need **passwordless** sudo access
### Home Manager
Digga's `lib.mkDeployNodes` provides only `system` profile.
In order to deploy your `home-manager` configuration you should provide additional profile(s) to deploy-rs config:
```nix
# Initially, this line looks like this: deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations { };
deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations
@ -67,10 +74,9 @@ deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations
};
```
Substitute `<HOSTNAME>`, `<HM_PROFILE>` and `<YOUR_USERNAME>` placeholders (omitting the `<>`).
Substitute `<HOSTNAME>`, `<HM_PROFILE>` and `<YOUR_USERNAME>` placeholders (omitting the `<>`).
`<ANOTHER_HM_PROFILE>` is there to illustrate deploying multiple `home-manager` configurations. Either substitute those as well,
or remove them altogether. Don't forget the `profileOrder` variable.
[d-rs]: https://github.com/serokell/deploy-rs

View File

@ -1,4 +1,5 @@
# Hercules CI
If you start adding your own packages and configurations, you'll probably have
at least a few binary artifacts. With hercules we can build every package in
our configuration automatically, on every commit. Additionally, we can have it
@ -8,6 +9,7 @@ This will work whether your copy is a fork, or a bare template, as long as your
repo is hosted on GitHub.
## Setup
Just head over to [hercules-ci.com](https://hercules-ci.com) to make an account.
Then follow the docs to set up an [agent][agent], if you want to deploy to a
@ -15,6 +17,7 @@ binary cache (and of course you do), be sure _not_ to skip the
[binary-caches.json][cache].
## Ready to Use
The repo is already set up with the proper _default.nix_ file, building all
declared packages, checks, profiles and shells. So you can see if something
breaks, and never build the same package twice!
@ -23,6 +26,7 @@ If you want to get fancy, you could even have hercules
[deploy your configuration](https://docs.hercules-ci.com/hercules-ci-effects/guide/deploy-a-nixos-machine/)!
> ##### _Note:_
>
> Hercules doesn't have access to anything encrypted in the
> [secrets folder](../../secrets), so none of your secrets will accidentally get
> pushed to a cache by mistake.

View File

@ -1,4 +1,5 @@
# Integrations
This section explores some of the optional tools included with devos to provide
a solution to common concerns such as ci and remote deployment. An effort is
made to choose tools that treat nix, and where possible flakes, as first class

View File

@ -1,4 +1,5 @@
# nvfetcher
[NvFetcher][nvf] is a workflow companion for updating nix sources.
You can specify an origin source and an update configuration, and
@ -15,6 +16,7 @@ and commit the results.
## Usage
Statically fetching (not tracking) a particular tag from a github repo:
```toml
[manix]
src.manual = "v0.6.3"
@ -22,6 +24,7 @@ fetch.github = "mlvzk/manix"
```
Tracking the latest github _release_ from a github repo:
```toml
[manix]
src.github = "mlvzk/manix" # responsible for tracking
@ -29,6 +32,7 @@ fetch.github = "mlvzk/manix" # responsible for fetching
```
Tracking the latest commit of a git repository and fetch from a git repo:
```toml
[manix]
src.git = "https://github.com/mlvzk/manix.git" # responsible for tracking
@ -36,6 +40,7 @@ fetch.git = "https://github.com/mlvzk/manix.git" # responsible for fetching
```
> ##### _Note:_
>
> Please refer to the [NvFetcher Readme][nvf-readme] for more options.
[nvf]: https://github.com/berberman/nvfetcher

View File

@ -1,3 +1,4 @@
# Layout
Each of the following sections is a directory whose contents are output to the
outside world via the flake's outputs. Check each chapter for details.

View File

@ -1,4 +1,5 @@
# Modules
The modules directory is a replica of nixpkg's NixOS [modules][nixpkgs-modules]
, and follows the same semantics. This allows for trivial upstreaming into
nixpkgs proper once your module is sufficiently stable.
@ -6,18 +7,21 @@ nixpkgs proper once your module is sufficiently stable.
All modules linked in _module-list.nix_ are automatically exported via
`nixosModules.<file-basename>`, and imported into all [hosts](../concepts/hosts.md).
> ##### _Note:_
>
> This is reserved for declaring brand new module options. If you just want to
> declare a coherent configuration of already existing and related NixOS options
> , use [profiles](../concepts/profiles.md) instead.
## Semantics
In case you've never written a module for nixpkgs before, here is a brief
outline of the process.
### Declaration
modules/services/service-category/my-service.nix:
```nix
{ config, lib, ... }:
let
@ -37,7 +41,9 @@ in
```
### Import
modules/module-list.nix:
```nix
[
./services/service-category/my-service.nix
@ -47,7 +53,9 @@ modules/module-list.nix:
## Usage
### Internal
profiles/profile-category/my-profile.nix:
```nix
{ ... }:
{
@ -56,7 +64,9 @@ profiles/profile-category/my-profile.nix:
```
### External
flake.nix:
```nix
{
# inputs omitted

View File

@ -1,4 +1,5 @@
# Overlays
Writing overlays is a common occurence when using a NixOS system. Therefore,
we want to keep the process as simple and straightforward as possible.
@ -9,7 +10,9 @@ exported via `overlays.<channel>/<pkgName>` _as well as_
write it.
## Example
overlays/kakoune.nix:
```nix
final: prev: {
kakoune = prev.kakoune.override {

View File

@ -1,4 +1,5 @@
# Packages
Similar to [modules](./modules.md), the pkgs directory mirrors the upstream
[nixpkgs/pkgs][pkgs], and for the same reason; if you ever want to upstream
your package, it's as simple as dropping it into the nixpkgs/pkgs directory.
@ -13,26 +14,30 @@ the supported systems listed in the package's `meta.platforms` attribute.
And, as usual, every package in the overlay is also available to any NixOS
[host](../concepts/hosts.md).
Another convenient difference is that it is possible to use
[nvfetcher](https://github.com/berberman/nvfetcher) to keep packages up to
Another convenient difference is that it is possible to use
[nvfetcher](https://github.com/berberman/nvfetcher) to keep packages up to
date.
This is best understood by the simple example below.
## Example
It is possible to specify sources separately to keep them up to date semi
It is possible to specify sources separately to keep them up to date semi
automatically.
The basic rules are specified in pkgs/sources.toml:
```toml
# nvfetcher.toml
[libinih]
src.github = "benhoyt/inih"
fetch.github = "benhoyt/inih"
```
After changes to this file as well as to update the packages specified in there run
After changes to this file as well as to update the packages specified in there run
nvfetcher (for more details see [nvfetcher](https://github.com/berberman/nvfetcher)).
The pkgs overlay is managed in
pkgs/default.nix:
```nix
final: prev: {
# keep sources first, this makes sources available to the pkgs
@ -45,6 +50,7 @@ final: prev: {
Lastly the example package is in
pkgs/development/libraries/libinih/default.nix:
```nix
{ stdenv, meson, ninja, lib, sources, ... }:
stdenv.mkDerivation {
@ -59,16 +65,17 @@ stdenv.mkDerivation {
}
```
## Migration from flake based approach
Previous to nvfetcher it was possible to manage sources via a pkgs/flake.nix, the main changes from there are that sources where in the attribute "srcs" (now "sources") and the contents of the sources where slightly different.
In order to switch to the new system, rewrite pkgs/flake.nix to a pkgs/sources.toml file using the documentation of nvfetcher,
add the line that calls the sources at the beginning of pkgs/default.nix, and
add the line that calls the sources at the beginning of pkgs/default.nix, and
accomodate the small changes in the packages as can be seen from the example.
The example package looked like:
pkgs/flake.nix:
```nix
{
description = "Package sources";
@ -81,6 +88,7 @@ pkgs/flake.nix:
```
pkgs/default.nix:
```nix
final: prev: {
# then, call packages with `final.callPackage`
@ -89,6 +97,7 @@ final: prev: {
```
pkgs/development/libraries/libinih/default.nix:
```nix
{ stdenv, meson, ninja, lib, srcs, ... }:
let inherit (srcs) libinih; in

View File

@ -1,9 +1,11 @@
# Secrets
Secrets are managed using [agenix][agenix]
so you can keep your flake in a public repository like GitHub without
exposing your password or other sensitive data.
## Agenix
Currently, there is [no mechanism][secrets-issue] in nix itself to deploy secrets
within the nix store because it is world-readable.
@ -17,6 +19,7 @@ matching ssh private key can read the data. The [age module][age module] will ad
encrypted files to the nix store and decrypt them on activation to `/run/agenix`.
### Setup
All hosts must have openssh enabled, this is done by default in the core profile.
You need to populate your `secrets/secrets.nix` with the proper ssh public keys.
@ -24,6 +27,7 @@ Be extra careful to make sure you only add public keys, you should never share a
private key!!
secrets/secrets.nix:
```nix
let
system = "<system ssh key>";
@ -37,22 +41,25 @@ this file doesn't exist you likely need to enable openssh and rebuild your syste
Your users ssh public key is probably stored in `~/.ssh/id_ed25519.pub` or
`~/.ssh/id_rsa.pub`. If you haven't generated a ssh key yet, be sure do so:
```sh
ssh-keygen -t ed25519
```
> ##### _Note:_
>
> The underlying tool used by agenix, rage, doesn't work well with password protected
> ssh keys. So if you have lots of secrets you might have to type in your password many
> times.
### Secrets
You will need the `agenix` command to create secrets. DevOS conveniently provides that
in the devShell, so just run `nix develop` whenever you want to edit secrets. Make sure
to always run `agenix` while in the `secrets/` folder, so it can pick up your `secrets.nix`.
To create secrets, simply add lines to your `secrets/secrets.nix`:
```
let
...
@ -62,21 +69,26 @@ in
"secret.age".publicKeys = allKeys;
}
```
That would tell agenix to create a `secret.age` file that is encrypted with the `system`
and `user` ssh public key.
Then go into the `secrets` folder and run:
```sh
agenix -e secret.age
```
This will create the `secret.age`, if it doesn't already exist, and allow you to edit it.
If you ever change the `publicKeys` entry of any secret make sure to rekey the secrets:
```sh
agenix --rekey
```
### Usage
Once you have your secret file encrypted and ready to use, you can utilize the [age module][age module]
to ensure that your secrets end up in `/run/secrets`.
@ -89,15 +101,14 @@ In any profile that uses a NixOS module that requires a secret you can enable a
}
```
Then you can just pass the path `/run/agenix/mysecret` to the module.
You can make use of the many options provided by the age module to customize where and how
secrets get decrypted. You can learn about them by looking at the
[age module][age module].
> ##### _Note:_
>
> You can take a look at the [agenix repository][agenix] for more information
> about the tool.

View File

@ -1,18 +1,24 @@
# Quick Start
The only dependency is nix, so make sure you have it [installed][install-nix].
## Get the Template
If you currently don't have flakes setup, you can utilize the digga shell to pull the template:
```sh
nix-shell "https://github.com/divnix/digga/archive/main.tar.gz" \
--run "nix flake init -t github:divnix/digga"
```
If you already have flakes support, you can directly pull the template:
```sh
nix flake init -t github:divnix/digga
```
Then make sure to create the git repository:
```sh
git init
git add .
@ -20,11 +26,14 @@ git commit -m init
```
To drop into a nix-shell, if you don't have flakes setup, use the digga shell to create a `flake.lock`:
```sh
nix-shell "https://github.com/divnix/digga/archive/main.tar.gz" \
--run "nix flake lock"
```
Or if you do have flakes support, just run:
```sh
nix flake lock
```
@ -35,6 +44,7 @@ version required. You can run `menu` to confirm that you are using digga (expect
In addition, the [binary cache](../integrations/cachix.md) is added for faster deployment.
> ##### _Notes:_
>
> - Flakes ignore files that have not been added to git, so be sure to stage new
> files before building the system.
> - You can choose to simply clone the repo with git if you want to follow
@ -46,5 +56,4 @@ In addition, the [binary cache](../integrations/cachix.md) is added for faster d
- [Make installable ISO](./iso.md)
[install-nix]: https://nixos.org/manual/nix/stable/#sect-multi-user-installation

View File

@ -31,6 +31,6 @@ custom-made for your target host will maximise those local cache hits. For hosts
that don't differ too much, a single USB stick might be ok, whereas when there
are bigger differences, a custom-made USB stick will be considerably faster.
[nixos-generators]: https://github.com/nix-community/nixos-generators
[nixos-generators]: https://github.com/nix-community/nixos-generators
[burn]: https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb
[formats]: https://github.com/nix-community/nixos-generators/tree/master/formats

View File

@ -6,12 +6,14 @@ configuration, and, optionally, run them in
[CI](./integrations/hercules.md).
## Unit Tests
Unit tests can be created from regular derivations, and they can do
almost anything you can imagine. By convention, it is best to test your
packages during their [check phase][check]. All packages and their tests will
be built during CI.
## Integration Tests
All your profiles defined in suites can be tested against an individual host.
Simply use digga's pre-baked `digga.lib.allProfilesTest` like so:

View File

@ -1,9 +1,10 @@
# Nix Configuration
This repository is home to the nix code that builds my systems.
## Why Nix?
Nix allows for easy to manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works forever. If someone else shares their configuration, anyone can make use of it.
Nix allows for easy to manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works forever. If someone else shares their configuration, anyone can make use of it.
This flake is configured with the use of [digga][digga].

View File

@ -9,23 +9,28 @@ let
"x86_64-linux"
];
filterSystems = lib.filterAttrs
filterSystems =
lib.filterAttrs
(system: _: lib.elem system ciSystems);
recurseIntoAttrsRecursive = lib.mapAttrs (_: v:
if lib.isAttrs v
then recurseIntoAttrsRecursive (lib.recurseIntoAttrs v)
else v
recurseIntoAttrsRecursive = lib.mapAttrs (
_: v:
if lib.isAttrs v
then recurseIntoAttrsRecursive (lib.recurseIntoAttrs v)
else v
);
systemOutputs = lib.filterAttrs
(name: set: lib.isAttrs set
&& lib.any
(system: set ? ${system} && name != "legacyPackages")
ciSystems
systemOutputs =
lib.filterAttrs
(
name: set:
lib.isAttrs set
&& lib.any
(system: set ? ${system} && name != "legacyPackages")
ciSystems
)
default.outputs;
ciDrvs = lib.mapAttrs (_: system: filterSystems system) systemOutputs;
in
(recurseIntoAttrsRecursive ciDrvs) // { shell = import ./shell.nix; }
(recurseIntoAttrsRecursive ciDrvs) // {shell = import ./shell.nix;}

View File

@ -5,205 +5,212 @@
nixConfig.extra-substituters = "https://nrdxp.cachix.org https://nix-community.cachix.org";
nixConfig.extra-trusted-public-keys = "nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
inputs =
{
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
# Track channels with commits tested and built by hydra
nixos.url = "github:nixos/nixpkgs/nixos-22.05";
latest.url = "github:nixos/nixpkgs/nixos-unstable";
# For darwin hosts: it can be helpful to track this darwin-specific stable
# channel equivalent to the `nixos-*` channels for NixOS. For one, these
# channels are more likely to provide cached binaries for darwin systems.
# But, perhaps even more usefully, it provides a place for adding
# darwin-specific overlays and packages which could otherwise cause build
# failures on Linux systems.
nixpkgs-darwin-stable.url = "github:NixOS/nixpkgs/nixpkgs-22.05-darwin";
digga.url = "github:divnix/digga";
digga.inputs.nixpkgs.follows = "nixos";
digga.inputs.nixlib.follows = "nixos";
digga.inputs.home-manager.follows = "home";
digga.inputs.deploy.follows = "deploy";
home.url = "github:nix-community/home-manager/release-22.05";
home.inputs.nixpkgs.follows = "nixos";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs-darwin-stable";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixos";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixos";
nvfetcher.url = "github:berberman/nvfetcher";
nvfetcher.inputs.nixpkgs.follows = "nixos";
naersk.url = "github:nmattia/naersk";
naersk.inputs.nixpkgs.follows = "nixos";
nixos-hardware.url = "github:nixos/nixos-hardware";
nixos-generators.url = "github:nix-community/nixos-generators";
inputs = {
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
outputs =
{ self
, digga
, nixos
, home
, nixos-hardware
, nur
, agenix
, nvfetcher
, deploy
, nixpkgs
, ...
} @ inputs:
# Track channels with commits tested and built by hydra
nixos.url = "github:nixos/nixpkgs/nixos-22.05";
latest.url = "github:nixos/nixpkgs/nixos-unstable";
# For darwin hosts: it can be helpful to track this darwin-specific stable
# channel equivalent to the `nixos-*` channels for NixOS. For one, these
# channels are more likely to provide cached binaries for darwin systems.
# But, perhaps even more usefully, it provides a place for adding
# darwin-specific overlays and packages which could otherwise cause build
# failures on Linux systems.
nixpkgs-darwin-stable.url = "github:NixOS/nixpkgs/nixpkgs-22.05-darwin";
digga.url = "github:divnix/digga";
digga.inputs.nixpkgs.follows = "nixos";
digga.inputs.nixlib.follows = "nixos";
digga.inputs.home-manager.follows = "home";
digga.inputs.deploy.follows = "deploy";
home.url = "github:nix-community/home-manager/release-22.05";
home.inputs.nixpkgs.follows = "nixos";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs-darwin-stable";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixos";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixos";
nvfetcher.url = "github:berberman/nvfetcher";
nvfetcher.inputs.nixpkgs.follows = "nixos";
naersk.url = "github:nmattia/naersk";
naersk.inputs.nixpkgs.follows = "nixos";
nixos-hardware.url = "github:nixos/nixos-hardware";
nixos-generators.url = "github:nix-community/nixos-generators";
};
outputs = {
self,
digga,
nixos,
home,
nixos-hardware,
nur,
agenix,
nvfetcher,
deploy,
nixpkgs,
...
} @ inputs:
digga.lib.mkFlake
{
inherit self inputs;
{
inherit self inputs;
channelsConfig = { allowUnfree = true; };
channels = {
nixos = {
imports = [ (digga.lib.importOverlays ./overlays) ];
overlays = [ ];
};
nixpkgs-darwin-stable = {
imports = [ (digga.lib.importOverlays ./overlays) ];
overlays = [
# TODO: restructure overlays directory for per-channel overrides
# `importOverlays` will import everything under the path given
(channels: final: prev: {
inherit (channels.latest) mas;
} // prev.lib.optionalAttrs true { })
];
};
latest = { };
};
lib = import ./lib { lib = digga.lib // nixos.lib; };
sharedOverlays = [
(final: prev: {
__dontExport = true;
lib = prev.lib.extend (lfinal: lprev: {
our = self.lib;
});
})
nur.overlay
agenix.overlay
nvfetcher.overlay
(import ./pkgs)
];
channelsConfig = {allowUnfree = true;};
channels = {
nixos = {
hostDefaults = {
system = "x86_64-linux";
channelName = "nixos";
imports = [ (digga.lib.importExportableModules ./modules) ];
modules = [
{ lib.our = self.lib; }
digga.nixosModules.bootstrapIso
digga.nixosModules.nixConfig
home.nixosModules.home-manager
agenix.nixosModules.age
];
};
imports = [(digga.lib.importOverlays ./overlays)];
overlays = [];
};
nixpkgs-darwin-stable = {
imports = [(digga.lib.importOverlays ./overlays)];
overlays = [
# TODO: restructure overlays directory for per-channel overrides
# `importOverlays` will import everything under the path given
(channels: final: prev:
{
inherit (channels.latest) mas;
}
// prev.lib.optionalAttrs true {})
];
};
latest = {};
};
imports = [ (digga.lib.importHosts ./hosts/nixos) ];
hosts = {
/* set host-specific properties here */
NixOS = { };
};
importables = rec {
profiles = digga.lib.rakeLeaves ./profiles // {
lib = import ./lib {lib = digga.lib // nixos.lib;};
sharedOverlays = [
(final: prev: {
__dontExport = true;
lib = prev.lib.extend (lfinal: lprev: {
our = self.lib;
});
})
nur.overlay
agenix.overlay
nvfetcher.overlay
(import ./pkgs)
];
nixos = {
hostDefaults = {
system = "x86_64-linux";
channelName = "nixos";
imports = [(digga.lib.importExportableModules ./modules)];
modules = [
{lib.our = self.lib;}
digga.nixosModules.bootstrapIso
digga.nixosModules.nixConfig
home.nixosModules.home-manager
agenix.nixosModules.age
];
};
imports = [(digga.lib.importHosts ./hosts/nixos)];
hosts = {
/*
set host-specific properties here
*/
NixOS = {};
};
importables = rec {
profiles =
digga.lib.rakeLeaves ./profiles
// {
users = digga.lib.rakeLeaves ./users;
};
suites = with profiles; rec {
base = [ core.nixos users.nixos users.root ];
};
suites = with profiles; rec {
base = [core.nixos users.nixos users.root];
};
};
};
darwin = {
hostDefaults = {
system = "x86_64-darwin";
channelName = "nixpkgs-darwin-stable";
imports = [ (digga.lib.importExportableModules ./modules) ];
modules = [
{ lib.our = self.lib; }
digga.darwinModules.nixConfig
home.darwinModules.home-manager
agenix.nixosModules.age
];
};
darwin = {
hostDefaults = {
system = "x86_64-darwin";
channelName = "nixpkgs-darwin-stable";
imports = [(digga.lib.importExportableModules ./modules)];
modules = [
{lib.our = self.lib;}
digga.darwinModules.nixConfig
home.darwinModules.home-manager
agenix.nixosModules.age
];
};
imports = [ (digga.lib.importHosts ./hosts/darwin) ];
hosts = {
/* set host-specific properties here */
Mac = { };
};
importables = rec {
profiles = digga.lib.rakeLeaves ./profiles // {
imports = [(digga.lib.importHosts ./hosts/darwin)];
hosts = {
/*
set host-specific properties here
*/
Mac = {};
};
importables = rec {
profiles =
digga.lib.rakeLeaves ./profiles
// {
users = digga.lib.rakeLeaves ./users;
};
suites = with profiles; rec {
base = [ core.darwin users.darwin ];
};
suites = with profiles; rec {
base = [core.darwin users.darwin];
};
};
};
home = {
imports = [ (digga.lib.importExportableModules ./users/modules) ];
modules = [ ];
importables = rec {
profiles = digga.lib.rakeLeaves ./users/profiles;
suites = with profiles; rec {
base = [ direnv git ];
};
home = {
imports = [(digga.lib.importExportableModules ./users/modules)];
modules = [];
importables = rec {
profiles = digga.lib.rakeLeaves ./users/profiles;
suites = with profiles; rec {
base = [direnv git];
};
users = {
# TODO: does this naming convention still make sense with darwin support?
#
# - it doesn't make sense to make a 'nixos' user available on
# darwin, and vice versa
#
# - the 'nixos' user might have special significance as the default
# user for fresh systems
#
# - perhaps a system-agnostic home-manager user is more appropriate?
# something like 'primaryuser'?
#
# all that said, these only exist within the `hmUsers` attrset, so
# it could just be left to the developer to determine what's
# appropriate. after all, configuring these hm users is one of the
# first steps in customizing the template.
nixos = { suites, ... }: { imports = suites.base; };
darwin = { suites, ... }: { imports = suites.base; };
}; # digga.lib.importers.rakeLeaves ./users/hm;
};
users = {
# TODO: does this naming convention still make sense with darwin support?
#
# - it doesn't make sense to make a 'nixos' user available on
# darwin, and vice versa
#
# - the 'nixos' user might have special significance as the default
# user for fresh systems
#
# - perhaps a system-agnostic home-manager user is more appropriate?
# something like 'primaryuser'?
#
# all that said, these only exist within the `hmUsers` attrset, so
# it could just be left to the developer to determine what's
# appropriate. after all, configuring these hm users is one of the
# first steps in customizing the template.
nixos = {suites, ...}: {imports = suites.base;};
darwin = {suites, ...}: {imports = suites.base;};
}; # digga.lib.importers.rakeLeaves ./users/hm;
};
devshell = ./shell;
devshell = ./shell;
# TODO: similar to the above note: does it make sense to make all of
# these users available on all systems?
homeConfigurations = digga.lib.mergeAny
(digga.lib.mkHomeConfigurations self.darwinConfigurations)
(digga.lib.mkHomeConfigurations self.nixosConfigurations)
;
# TODO: similar to the above note: does it make sense to make all of
# these users available on all systems?
homeConfigurations =
digga.lib.mergeAny
(digga.lib.mkHomeConfigurations self.darwinConfigurations)
(digga.lib.mkHomeConfigurations self.nixosConfigurations);
deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations { };
}
;
deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations {};
};
}

View File

@ -1,8 +1,10 @@
{ config, pkgs, suites, ... }:
{
imports = with suites;
base;
config,
pkgs,
suites,
...
}: {
imports = with suites; base;
# The `mas` package is included here as a test for platform-specific package
# support in Digga. Feel free to remove it in your config.

View File

@ -1,5 +1,4 @@
{ suites, ... }:
{
{suites, ...}: {
### root password is empty by default ###
imports = suites.base;
@ -8,5 +7,5 @@
networking.networkmanager.enable = true;
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };
fileSystems."/" = {device = "/dev/disk/by-label/nixos";};
}

View File

@ -1,5 +1,4 @@
{ profiles, ... }:
{
{profiles, ...}: {
imports = [
# profiles.networking
profiles.core.nixos
@ -10,5 +9,5 @@
boot.loader.systemd-boot.enable = true;
# Required, but will be overridden in the resulting installer ISO.
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };
fileSystems."/" = {device = "/dev/disk/by-label/nixos";};
}

View File

@ -1,6 +1,10 @@
let
lock = builtins.fromJSON (builtins.readFile builtins.path { path = ../../flake.lock; name = "lockPath"; });
flake = (import
lock = builtins.fromJSON (builtins.readFile builtins.path {
path = ../../flake.lock;
name = "lockPath";
});
flake =
import
(
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
@ -8,7 +12,10 @@ let
}
)
{
src = builtins.path { path = ../../.; name = "projectRoot"; };
});
src = builtins.path {
path = ../../.;
name = "projectRoot";
};
};
in
flake
flake

View File

@ -1,5 +1,4 @@
{ ... }:
let
{...}: let
inherit (default.inputs.nixos) lib;
host = configs.${hostname} or configs.NixOS;
@ -7,4 +6,4 @@ let
default = (import ../.).defaultNix;
hostname = lib.fileContents /etc/hostname;
in
host
host

View File

@ -1,2 +1,2 @@
{ lib }:
lib.makeExtensible (self: { })
{lib}:
lib.makeExtensible (self: {})

View File

@ -1,11 +1,15 @@
{ config, pkgs, ... }: {
{
config,
pkgs,
...
}: {
home-manager.sharedModules = [
{
home.sessionVariables = {
# environment.sessionVariables is not currently available in nix-darwin
NIX_PATH = config.environment.sessionVariables.NIX_PATH
or config.environment.variables.NIX_PATH
;
NIX_PATH =
config.environment.sessionVariables.NIX_PATH
or config.environment.variables.NIX_PATH;
};
xdg.configFile."nix/registry.json".text =
config.environment.etc."nix/registry.json".text;

View File

@ -1,4 +1,8 @@
{ channel, inputs, ... }: {
{
channel,
inputs,
...
}: {
nix.nixPath = [
"nixpkgs=${channel.input}"
"nixos-config=${../lib/compat/nixos}"

View File

@ -1,5 +1,5 @@
final: prev: {
manix = prev.manix.overrideAttrs (o: rec{
manix = prev.manix.overrideAttrs (o: rec {
inherit (prev.sources.manix) pname version src;
});
}

View File

@ -1,8 +1,8 @@
channels: final: prev: {
__dontExport = true; # overrides clutter up actual creations
inherit (channels.latest)
inherit
(channels.latest)
cachix
dhall
discord
@ -15,15 +15,17 @@ channels: final: prev: {
deploy-rs
;
haskellPackages = prev.haskellPackages.override
haskellPackages =
prev.haskellPackages.override
(old: {
overrides = prev.lib.composeExtensions (old.overrides or (_: _: { })) (hfinal: hprev:
let version = prev.lib.replaceChars [ "." ] [ "" ] prev.ghc.version;
in
{
# same for haskell packages, matching ghc versions
inherit (channels.latest.haskell.packages."ghc${version}")
haskell-language-server;
});
overrides = prev.lib.composeExtensions (old.overrides or (_: _: {})) (hfinal: hprev: let
version = prev.lib.replaceChars ["."] [""] prev.ghc.version;
in {
# same for haskell packages, matching ghc versions
inherit
(channels.latest.haskell.packages."ghc${version}")
haskell-language-server
;
});
});
}

View File

@ -1,6 +1,8 @@
# This file was generated by nvfetcher, please do not modify it manually.
{ fetchgit, fetchurl }:
{
fetchgit,
fetchurl,
}: {
manix = {
pname = "manix";
version = "d08e7ca185445b929f097f8bfb1243a8ef3e10e4";

View File

@ -1,5 +1,5 @@
final: prev: {
# keep sources this first
sources = prev.callPackage (import ./_sources/generated.nix) { };
sources = prev.callPackage (import ./_sources/generated.nix) {};
# then, call packages with `final.callPackage`
}

View File

@ -1,11 +1,13 @@
{ pkgs, lib, ... }:
let
{
pkgs,
lib,
...
}: let
folder = ./.;
toImport = name: value: folder + ("/" + name);
filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key && key != "default.nix";
imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder));
in
{
in {
inherit imports;
nix.binaryCaches = [ "https://cache.nixos.org/" ];
nix.binaryCaches = ["https://cache.nixos.org/"];
}

View File

@ -1,16 +1,17 @@
{ self, config, lib, pkgs, ... }:
let
{
self,
config,
lib,
pkgs,
...
}: let
inherit (lib) fileContents;
inherit (pkgs.stdenv.hostPlatform) isDarwin;
in
{
in {
# Sets nrdxp.cachix.org binary cache which just speeds up some builds
imports = [ ../cachix ];
imports = [../cachix];
environment = {
# Selection of sysadmin tools that can come in handy
systemPackages = with pkgs; [
alejandra
@ -42,57 +43,53 @@ in
}
'';
shellAliases =
let
# The `security.sudo.enable` option does not exist on darwin because
# sudo is always available.
ifSudo = lib.mkIf (isDarwin || config.security.sudo.enable);
in
{
# quick cd
".." = "cd ..";
"..." = "cd ../..";
"...." = "cd ../../..";
"....." = "cd ../../../..";
shellAliases = let
# The `security.sudo.enable` option does not exist on darwin because
# sudo is always available.
ifSudo = lib.mkIf (isDarwin || config.security.sudo.enable);
in {
# quick cd
".." = "cd ..";
"..." = "cd ../..";
"...." = "cd ../../..";
"....." = "cd ../../../..";
# git
g = "git";
# git
g = "git";
# grep
grep = "rg";
gi = "grep -i";
# grep
grep = "rg";
gi = "grep -i";
# internet ip
# TODO: explain this hard-coded IP address
myip = "dig +short myip.opendns.com @208.67.222.222 2>&1";
# internet ip
# TODO: explain this hard-coded IP address
myip = "dig +short myip.opendns.com @208.67.222.222 2>&1";
# nix
n = "nix";
np = "n profile";
ni = "np install";
nr = "np remove";
ns = "n search --no-update-lock-file";
nf = "n flake";
nepl = "n repl '<nixpkgs>'";
srch = "ns nixos";
orch = "ns override";
mn = ''
manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | sk --preview="manix '{}'" | xargs manix
'';
top = "btm";
# nix
n = "nix";
np = "n profile";
ni = "np install";
nr = "np remove";
ns = "n search --no-update-lock-file";
nf = "n flake";
nepl = "n repl '<nixpkgs>'";
srch = "ns nixos";
orch = "ns override";
mn = ''
manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | sk --preview="manix '{}'" | xargs manix
'';
top = "btm";
# sudo
s = ifSudo "sudo -E ";
si = ifSudo "sudo -i";
se = ifSudo "sudoedit";
};
# sudo
s = ifSudo "sudo -E ";
si = ifSudo "sudo -i";
se = ifSudo "sudoedit";
};
};
fonts.fonts = with pkgs; [ powerline-fonts dejavu_fonts ];
fonts.fonts = with pkgs; [powerline-fonts dejavu_fonts];
nix = {
# Improve nix store disk usage
gc.automatic = true;
@ -100,7 +97,7 @@ in
useSandbox = true;
# Give root user and wheel group special Nix privileges.
trustedUsers = [ "root" "@wheel" ];
trustedUsers = ["root" "@wheel"];
# Generally useful nix option defaults
extraOptions = ''
@ -109,7 +106,5 @@ in
keep-derivations = true
fallback = true
'';
};
}

View File

@ -1,6 +1,10 @@
{ self, config, lib, pkgs, ... }:
{
self,
config,
lib,
pkgs,
...
}: {
imports = [
./common.nix
];
@ -12,7 +16,6 @@
users.nix.configureBuildUsers = true;
environment = {
systemPackages = with pkgs; [
m-cli
terminal-notifier
@ -23,11 +26,9 @@
shellAliases = {
nrb = "sudo darwin-rebuild switch --flake";
};
};
nix = {
nixPath = [
# TODO: This entry should be added automatically via FUP's
# `nix.linkInputs` and `nix.generateNixPathFromInputs` options, but
@ -42,8 +43,7 @@
];
# Administrative users on Darwin are part of this group.
trustedUsers = [ "@admin" ];
trustedUsers = ["@admin"];
};
programs.bash = {
@ -57,5 +57,4 @@
eval "$(${pkgs.direnv}/bin/direnv hook bash)"
'';
};
}

View File

@ -1,15 +1,18 @@
{ config, lib, pkgs, self, ... }:
{
config,
lib,
pkgs,
self,
...
}: {
imports = [
./common.nix
];
# This is just a representation of the nix default
nix.systemFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
nix.systemFeatures = ["nixos-test" "benchmark" "big-parallel" "kvm"];
environment = {
# Selection of sysadmin tools that can come in handy
systemPackages = with pkgs; [
dosfstools
@ -19,37 +22,37 @@
utillinux
];
shellAliases =
let ifSudo = lib.mkIf config.security.sudo.enable; in
{
# nix
nrb = ifSudo "sudo nixos-rebuild";
shellAliases = let
ifSudo = lib.mkIf config.security.sudo.enable;
in {
# nix
nrb = ifSudo "sudo nixos-rebuild";
# fix nixos-option for flake compat
nixos-option = "nixos-option -I nixpkgs=${self}/lib/compat";
# fix nixos-option for flake compat
nixos-option = "nixos-option -I nixpkgs=${self}/lib/compat";
# systemd
ctl = "systemctl";
stl = ifSudo "s systemctl";
utl = "systemctl --user";
ut = "systemctl --user start";
un = "systemctl --user stop";
up = ifSudo "s systemctl start";
dn = ifSudo "s systemctl stop";
jtl = "journalctl";
};
# systemd
ctl = "systemctl";
stl = ifSudo "s systemctl";
utl = "systemctl --user";
ut = "systemctl --user start";
un = "systemctl --user stop";
up = ifSudo "s systemctl start";
dn = ifSudo "s systemctl stop";
jtl = "journalctl";
};
};
fonts.fontconfig.defaultFonts = {
monospace = [ "DejaVu Sans Mono for Powerline" ];
sansSerif = [ "DejaVu Sans" ];
monospace = ["DejaVu Sans Mono for Powerline"];
sansSerif = ["DejaVu Sans"];
};
nix = {
# Improve nix store disk usage
autoOptimiseStore = true;
optimise.automatic = true;
allowedUsers = [ "@wheel" ];
allowedUsers = ["@wheel"];
};
programs.bash = {
@ -71,5 +74,4 @@
# Service that makes Out of Memory Killer more effective
services.earlyoom.enable = true;
}

View File

@ -2,8 +2,7 @@ let
# set ssh public keys here for your system and user
system = "";
user = "";
allKeys = [ system user ];
in
{
allKeys = [system user];
in {
"secret.age".publicKeys = allKeys;
}

View File

@ -1,8 +1,10 @@
{ self, inputs, ... }:
{
self,
inputs,
...
}: {
modules = with inputs; [];
exportedModules = [
./devos.nix
];
}

View File

@ -1,7 +1,12 @@
{ pkgs, extraModulesPath, inputs, lib, ... }:
let
inherit (pkgs)
{
pkgs,
extraModulesPath,
inputs,
lib,
...
}: let
inherit
(pkgs)
agenix
cachix
editorconfig-checker
@ -13,39 +18,37 @@ let
hooks = import ./hooks;
pkgWithCategory = category: package: { inherit package category; };
pkgWithCategory = category: package: {inherit package category;};
devos = pkgWithCategory "devos";
linter = pkgWithCategory "linter";
docs = pkgWithCategory "docs";
in
{
in {
_file = toString ./.;
imports = [ "${extraModulesPath}/git/hooks.nix" ];
git = { inherit hooks; };
imports = ["${extraModulesPath}/git/hooks.nix"];
git = {inherit hooks;};
commands = [
(devos nixUnstable)
(devos agenix)
commands =
[
(devos nixUnstable)
(devos agenix)
{
category = "devos";
name = nvfetcher-bin.pname;
help = nvfetcher-bin.meta.description;
command = "cd $PRJ_ROOT/pkgs; ${nvfetcher-bin}/bin/nvfetcher -c ./sources.toml $@";
}
(linter treefmt)
(linter editorconfig-checker)
{
category = "devos";
name = nvfetcher-bin.pname;
help = nvfetcher-bin.meta.description;
command = "cd $PRJ_ROOT/pkgs; ${nvfetcher-bin}/bin/nvfetcher -c ./sources.toml $@";
}
(linter treefmt)
(linter editorconfig-checker)
(docs mdbook)
]
++ lib.optionals (!pkgs.stdenv.buildPlatform.isi686) [
(devos cachix)
]
++ lib.optionals (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin) [
(devos inputs.nixos-generators.defaultPackage.${pkgs.system})
(devos inputs.deploy.packages.${pkgs.system}.deploy-rs)
]
;
(docs mdbook)
]
++ lib.optionals (!pkgs.stdenv.buildPlatform.isi686) [
(devos cachix)
]
++ lib.optionals (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin) [
(devos inputs.nixos-generators.defaultPackage.${pkgs.system})
(devos inputs.deploy.packages.${pkgs.system}.deploy-rs)
];
}

View File

@ -1,6 +1,5 @@
{ hmUsers, ... }:
{
home-manager.users = { inherit (hmUsers) darwin; };
{hmUsers, ...}: {
home-manager.users = {inherit (hmUsers) darwin;};
users.users.darwin = {
description = "default";

View File

@ -1,11 +1,10 @@
{ hmUsers, ... }:
{
home-manager.users = { inherit (hmUsers) nixos; };
{hmUsers, ...}: {
home-manager.users = {inherit (hmUsers) nixos;};
users.users.nixos = {
password = "nixos";
description = "default";
isNormalUser = true;
extraGroups = [ "wheel" ];
extraGroups = ["wheel"];
};
}

View File

@ -30,12 +30,9 @@
h1rd = "hard HEAD~1";
# logging
lg =
"log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog =
"log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog =
"log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
rank = "shortlog -sn --no-merges";
# delete merged branches

View File

@ -1,4 +1,4 @@
{ ... }:
{...}:
# recommend using `hashedPassword`
{
users.users.root.password = "";

View File

@ -1,11 +1,16 @@
{ lib, pkgs, config, suites, ... }: {
{
lib,
pkgs,
config,
suites,
...
}: {
# TODO: remove manually-imported suites and profiles once custom test support
# is added for darwin
imports = with suites;
base;
imports = with suites; base;
# On Darwin, admins are added to the `admin` group.
nix.trustedUsers = [ "@admin" "sosumi" ];
nix.trustedUsers = ["@admin" "sosumi"];
# https://daiderd.com/nix-darwin/manual/index.html#opt-system.stateVersion
system.stateVersion = 4;

View File

@ -1,27 +1,27 @@
{ self, inputs, ... }:
let
inherit (inputs.digga.lib) allProfilesTest;
in
{
self,
inputs,
...
}: let
inherit (inputs.digga.lib) allProfilesTest;
in {
hostDefaults = {
channelName = "nixpkgs-darwin-stable";
};
hosts = {
Darwinia = {
modules = [ ./Darwinia.nix ];
modules = [./Darwinia.nix];
# TODO: add custom test support for darwin hosts
# tests = [ allProfilesTest ];
tests = [ ];
tests = [];
};
};
importables = rec {
suites = rec {
base = [ ];
base = [];
};
};
}

View File

@ -1,4 +1,3 @@
{ self, ... }:
{
exportedModules = [ ./python.toml ];
{self, ...}: {
exportedModules = [./python.toml];
}

View File

@ -23,29 +23,27 @@
home.inputs.nixpkgs.follows = "nixos";
};
outputs =
inputs @ { self
, nixos
, nixpkgs
, nixpkgs-darwin-stable
, darwin
, digga
, home
, ...
}:
outputs = inputs @ {
self,
nixos,
nixpkgs,
nixpkgs-darwin-stable,
darwin,
digga,
home,
...
}:
digga.lib.mkFlake {
inherit self inputs;
channels = {
nixos = { };
nixpkgs-darwin-stable = { };
nixos = {};
nixpkgs-darwin-stable = {};
};
nixos = ./nixos;
darwin = ./darwin;
home = ./home;
devshell = ./devshell;
};
}

View File

@ -1,7 +1,5 @@
{ self, ... }:
let
{self, ...}: let
lib = self.inputs.digga.lib;
in
{
imports = [ (lib.importExportableModules ./modules) ];
in {
imports = [(lib.importExportableModules ./modules)];
}

View File

@ -30,12 +30,9 @@
h1rd = "hard HEAD~1";
# logging
lg =
"log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog =
"log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog =
"log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
rank = "shortlog -sn --no-merges";
# delete merged branches

View File

@ -1,6 +1,11 @@
{ lib, pkgs, config, ... }: {
{
lib,
pkgs,
config,
...
}: {
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
fileSystems."/" = { device = "/dev/disk/by-label/One"; };
fileSystems."/" = {device = "/dev/disk/by-label/One";};
users.users.root.password = "";
}

View File

@ -1,24 +1,24 @@
{ self, inputs, ... }:
let
inherit (inputs.digga.lib) allProfilesTest;
in
{
self,
inputs,
...
}: let
inherit (inputs.digga.lib) allProfilesTest;
in {
hostDefaults = {
channelName = "nixos";
};
hosts = {
Morty = {
modules = [ ./Morty.nix ];
tests = [ allProfilesTest ];
modules = [./Morty.nix];
tests = [allProfilesTest];
};
};
importables = rec {
suites = rec {
base = [ ];
base = [];
};
};
}

View File

@ -10,16 +10,19 @@
home.inputs.nixpkgs.follows = "nixos";
};
outputs = inputs @ { self, nixos, digga, home }:
outputs = inputs @ {
self,
nixos,
digga,
home,
}:
digga.lib.mkFlake {
inherit self inputs;
channels.nixos = { };
channels.nixos = {};
nixos.hostDefaults.channelName = "nixos";
home = ./home;
};
}

View File

@ -1,14 +1,16 @@
{ self, inputs, ... }:
let
lib = inputs.digga.lib;
in
{
imports = [ (lib.importExportableModules ./modules) ];
modules = [ ];
self,
inputs,
...
}: let
lib = inputs.digga.lib;
in {
imports = [(lib.importExportableModules ./modules)];
modules = [];
importables = rec {
profiles = lib.rakeLeaves ./profiles;
suites = with profiles; {
shell = with shell; [ direnv ];
shell = with shell; [direnv];
};
};
users = lib.rakeLeaves ./users;

View File

@ -1,12 +1,14 @@
{ pkgs, suites, ... }:
let
{
pkgs,
suites,
...
}: let
name = "Test User";
email = "test@example.com";
in
{
in {
imports = suites.shell;
home.packages = [ pkgs.hello ];
home.packages = [pkgs.hello];
programs.browserpass.enable = true;
programs.starship.enable = true;
@ -15,4 +17,3 @@ in
userEmail = email;
};
}

250
flake.nix
View File

@ -5,151 +5,149 @@
nixConfig.extra-substituters = "https://nrdxp.cachix.org https://nix-community.cachix.org";
nixConfig.extra-trusted-public-keys = "nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
inputs =
{
# Track channels with commits tested and built by hydra
nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
inputs = {
# Track channels with commits tested and built by hydra
nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixlib.url = "github:nix-community/nixpkgs.lib";
nixlib.url = "github:nix-community/nixpkgs.lib";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixpkgs";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager/release-22.05";
home-manager.inputs.nixpkgs.follows = "nixlib";
home-manager.url = "github:nix-community/home-manager/release-22.05";
home-manager.inputs.nixpkgs.follows = "nixlib";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs";
devshell.url = "github:numtide/devshell";
devshell.inputs.nixpkgs.follows = "nixpkgs";
devshell.url = "github:numtide/devshell";
devshell.inputs.nixpkgs.follows = "nixpkgs";
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/?ref=refs/pull/120/head";
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/?ref=refs/pull/120/head";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
};
outputs = {
self,
nixlib,
nixpkgs,
deploy,
devshell,
flake-utils-plus,
darwin,
home-manager,
...
} @ inputs: let
tests = import ./src/tests.nix {inherit (nixlib) lib;};
internal-modules = import ./src/modules.nix {
inherit (nixlib) lib;
};
outputs =
{ self
, nixlib
, nixpkgs
, deploy
, devshell
, flake-utils-plus
, darwin
, home-manager
, ...
}@inputs:
let
importers = import ./src/importers.nix {
inherit (nixlib) lib;
};
tests = import ./src/tests.nix { inherit (nixlib) lib; };
collectors = import ./src/collectors.nix {
inherit (nixlib) lib;
};
internal-modules = import ./src/modules.nix {
generators = import ./src/generators.nix {
inherit (nixlib) lib;
inherit deploy;
};
mkFlake = let
mkFlake' = import ./src/mkFlake {
inherit (nixlib) lib;
inherit (flake-utils-plus.inputs) flake-utils;
inherit
collectors
darwin
deploy
devshell
home-manager
flake-utils-plus
internal-modules
tests
;
};
in {
__functor = _: args: (mkFlake' args).flake;
options = args: (mkFlake' args).options;
};
importers = import ./src/importers.nix {
inherit (nixlib) lib;
};
# Unofficial Flakes Roadmap - Polyfills
# This project is committed to the Unofficial Flakes Roadmap!
# .. see: https://demo.hedgedoc.org/s/_W6Ve03GK#
collectors = import ./src/collectors.nix {
inherit (nixlib) lib;
};
# Super Stupid Flakes (ssf) / System As an Input - Style:
supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin"];
generators = import ./src/generators.nix {
inherit (nixlib) lib;
inherit deploy;
};
mkFlake =
let
mkFlake' = import ./src/mkFlake {
inherit (nixlib) lib;
inherit (flake-utils-plus.inputs) flake-utils;
inherit
collectors
darwin
deploy
devshell
home-manager
flake-utils-plus
internal-modules
tests
;
};
in
{
__functor = _: args: (mkFlake' args).flake;
options = args: (mkFlake' args).options;
};
# Unofficial Flakes Roadmap - Polyfills
# This project is committed to the Unofficial Flakes Roadmap!
# .. see: https://demo.hedgedoc.org/s/_W6Ve03GK#
# Super Stupid Flakes (ssf) / System As an Input - Style:
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];
# Pass this flake(self) as "digga"
polyfillInputs = self.inputs // { digga = self; };
polyfillOutput = loc: nixlib.lib.genAttrs supportedSystems (system:
import loc { inherit system; inputs = polyfillInputs; }
# Pass this flake(self) as "digga"
polyfillInputs = self.inputs // {digga = self;};
polyfillOutput = loc:
nixlib.lib.genAttrs supportedSystems (
system:
import loc {
inherit system;
inputs = polyfillInputs;
}
);
# .. we hope you like this style.
# .. it's adopted by a growing number of projects.
# Please consider adopting it if you want to help to improve flakes.
# .. we hope you like this style.
# .. it's adopted by a growing number of projects.
# Please consider adopting it if you want to help to improve flakes.
# DEPRECATED - will be removed timely
deprecated = import ./deprecated.nix {
inherit (nixlib) lib;
inherit importers;
};
# DEPRECATED - will be removed timely
deprecated = import ./deprecated.nix {
inherit (nixlib) lib;
inherit importers;
};
in {
# what you came for ...
lib = {
inherit (flake-utils-plus.inputs.flake-utils.lib) defaultSystems eachSystem eachDefaultSystem filterPackages;
inherit (flake-utils-plus.lib) exportModules exportOverlays exportPackages mergeAny;
inherit mkFlake;
inherit (tests) mkTest allProfilesTest;
inherit (importers) flattenTree rakeLeaves importOverlays importExportableModules importHosts;
inherit (generators) mkDeployNodes mkHomeConfigurations;
inherit
(collectors)
collectHosts
collectHostsOnSystem
;
in
{
# what you came for ...
lib = {
inherit (flake-utils-plus.inputs.flake-utils.lib) defaultSystems eachSystem eachDefaultSystem filterPackages;
inherit (flake-utils-plus.lib) exportModules exportOverlays exportPackages mergeAny;
inherit mkFlake;
inherit (tests) mkTest allProfilesTest;
inherit (importers) flattenTree rakeLeaves importOverlays importExportableModules importHosts;
inherit (generators) mkDeployNodes mkHomeConfigurations;
inherit (collectors)
collectHosts
collectHostsOnSystem
;
# DEPRECATED - will be removed soon
inherit (deprecated)
# Place any deprecated lib functions here
;
};
# a little extra service ...
overlays = import ./overlays { inherit inputs; };
nixosModules = import ./modules/nixos-modules.nix;
darwinModules = import ./modules/darwin-modules.nix;
defaultTemplate = self.templates.devos;
templates.devos.path = ./examples/devos;
templates.devos.description = ''
an awesome template for NixOS users, with consideration for common tools like home-manager, devshell, and more.
'';
# digga-local use
## This doesn't appear to be used?
formatter = nixlib.lib.genAttrs supportedSystems (s: nixpkgs.legacyPackages.${s}.treefmt);
# system-space and pass sytem and input to each file
jobs = polyfillOutput ./jobs;
checks = polyfillOutput ./checks;
devShell = polyfillOutput ./devShell.nix;
# DEPRECATED - will be removed soon
inherit
(deprecated)
# Place any deprecated lib functions here
;
};
# a little extra service ...
overlays = import ./overlays {inherit inputs;};
nixosModules = import ./modules/nixos-modules.nix;
darwinModules = import ./modules/darwin-modules.nix;
defaultTemplate = self.templates.devos;
templates.devos.path = ./examples/devos;
templates.devos.description = ''
an awesome template for NixOS users, with consideration for common tools like home-manager, devshell, and more.
'';
# digga-local use
## This doesn't appear to be used?
formatter = nixlib.lib.genAttrs supportedSystems (s: nixpkgs.legacyPackages.${s}.treefmt);
# system-space and pass sytem and input to each file
jobs = polyfillOutput ./jobs;
checks = polyfillOutput ./checks;
devShell = polyfillOutput ./devShell.nix;
};
}

View File

@ -1,13 +1,15 @@
{ system ? builtins.currentSystem
, inputs ? (import ../.).inputs
}:
let
{
system ? builtins.currentSystem,
inputs ? (import ../.).inputs,
}: let
inherit (inputs) digga;
pkgs = inputs.nixpkgs.legacyPackages.${system};
docOptions = digga.lib.mkFlake.options { self = { }; inputs = { }; };
evaledOptions = (pkgs.lib.evalModules { modules = [ docOptions ]; }).options;
docOptions = digga.lib.mkFlake.options {
self = {};
inputs = {};
};
evaledOptions = (pkgs.lib.evalModules {modules = [docOptions];}).options;
mkDocPartMd = part: title: intro:
pkgs.writeText "api-reference-${part}.md" ''
@ -15,13 +17,11 @@ let
${intro}
${(
pkgs.nixosOptionsDoc { options = evaledOptions.${part}; }
).optionsMDDoc}
pkgs.nixosOptionsDoc {options = evaledOptions.${part};}
)
.optionsMDDoc}
'';
in
{
in {
mkApiReferenceTopLevel = pkgs.writeText "api-reference.md" ''
# Top Level API
`digga`'s top level API. API Containers are documented in their respective sub-chapter:
@ -32,17 +32,19 @@ in
- [NixOS](./api-reference-nixos.md)
- [Darwin](./api-reference-darwin.md)
${( pkgs.nixosOptionsDoc {
${(pkgs.nixosOptionsDoc {
options = {
inherit (evaledOptions)
inherit
(evaledOptions)
channelsConfig
self
inputs
outputsBuilder
supportedSystems
;
;
};
}).optionsMDDoc}
})
.optionsMDDoc}
'';
mkApiReferenceChannels = mkDocPartMd "channels" "Channels API Container" ''
@ -64,5 +66,4 @@ in
mkApiReferenceDarwin = mkDocPartMd "darwin" "Darwin API Container" ''
Configure your darwin/macOS modules, profiles & suites.
'';
}

View File

@ -1,29 +1,39 @@
let
getFqdn = config:
let
net = config.networking;
fqdn =
if (net ? domain) && (net.domain != null)
then "${net.hostName}.${net.domain}"
else net.hostName;
in
getFqdn = config: let
net = config.networking;
fqdn =
if (net ? domain) && (net.domain != null)
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
protoModule = fullHostConfig: { config, lib, modulesPath, suites, self, inputs, ... }@args: {
imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" ];
protoModule = fullHostConfig: {
config,
lib,
modulesPath,
suites,
self,
inputs,
...
} @ args: {
imports = ["${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"];
isoImage.isoBaseName = "bootstrap-" + (getFqdn config);
isoImage.contents = [{
source = self;
target = "/devos/";
}];
isoImage.storeContents = [
self.devShell.${config.nixpkgs.system}
# include also closures that are "switched off" by the
# above profile filter on the local config attribute
fullHostConfig.system.build.toplevel
] ++ builtins.attrValues inputs;
isoImage.contents = [
{
source = self;
target = "/devos/";
}
];
isoImage.storeContents =
[
self.devShell.${config.nixpkgs.system}
# include also closures that are "switched off" by the
# above profile filter on the local config attribute
fullHostConfig.system.build.toplevel
]
++ builtins.attrValues inputs;
# still pull in tools of deactivated profiles
environment.systemPackages = fullHostConfig.environment.systemPackages;
@ -63,12 +73,16 @@ let
};
};
in
{ config, ... }:
{
system.build = {
bootstrapIso = (config.lib.digga.mkBuild
(protoModule config)
).config.system.build.isoImage;
};
}
{config, ...}: {
system.build = {
bootstrapIso =
(
config.lib.digga.mkBuild
(protoModule config)
)
.config
.system
.build
.isoImage;
};
}

View File

@ -1,6 +1,4 @@
{ lib, ... }:
let
{lib, ...}: let
experimental-features = [
"flakes"
"nix-command"
@ -13,16 +11,14 @@ let
"nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
in
{
in {
# package and option is from fup
nix.generateRegistryFromInputs = lib.mkDefault true;
# missing merge semantics in this option force us to use extra-* for now
nix.extraOptions = ''
extra-experimental-features = ${lib.concatStringsSep " " experimental-features }
extra-substituters = ${lib.concatStringsSep " " substituters }
extra-trusted-public-keys = ${lib.concatStringsSep " " trusted-public-keys }
extra-experimental-features = ${lib.concatStringsSep " " experimental-features}
extra-substituters = ${lib.concatStringsSep " " substituters}
extra-trusted-public-keys = ${lib.concatStringsSep " " trusted-public-keys}
'';
}

View File

@ -1 +1 @@
{ inputs }: { }
{inputs}: {}

View File

@ -1 +1 @@
import ./devShell.nix { }
import ./devShell.nix {}

View File

@ -1,34 +1,38 @@
{ lib }:
let
{lib}: let
collectHosts = nixosConfigurations: darwinConfigurations:
/**
Synopsis: collectHosts _nixosConfigurations_ _darwinConfigurations_
Collect all hosts across NixOS and Darwin configurations, validating for
unique hostnames to prevent collisions.
**/
(nixosConfigurations // lib.mapAttrs
(name: value:
/*
*
Synopsis: collectHosts _nixosConfigurations_ _darwinConfigurations_
Collect all hosts across NixOS and Darwin configurations, validating for
unique hostnames to prevent collisions.
*
*/
(nixosConfigurations
// lib.mapAttrs
(
name: value:
if builtins.hasAttr name nixosConfigurations
then
throw ''
Hostnames must be unique across all platforms! Found a duplicate host config for '${name}'.
''
else value
)
darwinConfigurations);
in
{
)
darwinConfigurations);
in {
inherit collectHosts;
collectHostsOnSystem = hostConfigurations: system:
/**
Synopsis: collectHostsOnSystem _hostConfigurations_ _system_
Filter a set of host configurations to those matching a given system.
**/
let
systemSieve = _: host: host.config.nixpkgs.system == system;
in
/*
*
Synopsis: collectHostsOnSystem _hostConfigurations_ _system_
Filter a set of host configurations to those matching a given system.
*
*/
let
systemSieve = _: host: host.config.nixpkgs.system == system;
in
lib.filterAttrs systemSieve hostConfigurations;
}

View File

@ -1,82 +1,83 @@
{ lib, deploy }:
let
getFqdn = c:
let
net = c.config.networking;
fqdn =
if (net ? domain) && (net.domain != null)
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
in
{
lib,
deploy,
}: let
getFqdn = c: let
net = c.config.networking;
fqdn =
if (net ? domain) && (net.domain != null)
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
in {
mkHomeConfigurations = systemConfigurations:
/**
Synopsis: mkHomeConfigurations _systemConfigurations_
Generate the `homeConfigurations` attribute expected by `home-manager` cli
from _nixosConfigurations_ or _darwinConfigurations_ in the form
_user@hostname_.
**/
let
op = attrs: c:
attrs
//
(
lib.mapAttrs'
(user: v: {
name = "${user}@${getFqdn c}";
value = v.home;
})
c.config.home-manager.users
)
;
mkHmConfigs = lib.foldl op { };
in
/*
*
Synopsis: mkHomeConfigurations _systemConfigurations_
Generate the `homeConfigurations` attribute expected by `home-manager` cli
from _nixosConfigurations_ or _darwinConfigurations_ in the form
_user@hostname_.
*
*/
let
op = attrs: c:
attrs
// (
lib.mapAttrs'
(user: v: {
name = "${user}@${getFqdn c}";
value = v.home;
})
c.config.home-manager.users
);
mkHmConfigs = lib.foldl op {};
in
mkHmConfigs (builtins.attrValues systemConfigurations);
mkDeployNodes = systemConfigurations: extraConfig:
/**
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
Generate the `nodes` attribute expected by deploy-rs
where _systemConfigurations_ are `nodes`.
_systemConfigurations_ should take the form of a flake's
_nixosConfigurations_. Note that deploy-rs does not currently support
deploying to darwin hosts.
_extraConfig_, if specified, will be merged into each of the
nodes' configurations.
Example _systemConfigurations_ input:
```
{
hostname-1 = {
fastConnection = true;
sshOpts = [ "-p" "25" ];
};
hostname-2 = {
sshOpts = [ "-p" "19999" ];
sshUser = "root";
};
}
```
**/
/*
*
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
Generate the `nodes` attribute expected by deploy-rs
where _systemConfigurations_ are `nodes`.
_systemConfigurations_ should take the form of a flake's
_nixosConfigurations_. Note that deploy-rs does not currently support
deploying to darwin hosts.
_extraConfig_, if specified, will be merged into each of the
nodes' configurations.
Example _systemConfigurations_ input:
```
{
hostname-1 = {
fastConnection = true;
sshOpts = [ "-p" "25" ];
};
hostname-2 = {
sshOpts = [ "-p" "19999" ];
sshUser = "root";
};
}
```
*
*/
lib.recursiveUpdate
(lib.mapAttrs
(_: c:
{
hostname = getFqdn c;
profiles.system = {
user = "root";
path = deploy.lib.${c.config.nixpkgs.system}.activate.nixos c;
};
}
)
systemConfigurations)
extraConfig;
(lib.mapAttrs
(
_: c: {
hostname = getFqdn c;
profiles.system = {
user = "root";
path = deploy.lib.${c.config.nixpkgs.system}.activate.nixos c;
};
}
)
systemConfigurations)
extraConfig;
}

View File

@ -1,108 +1,108 @@
{ lib }:
let
{lib}: let
flattenTree =
/**
Synopsis: flattenTree _tree_
Flattens a _tree_ of the shape that is produced by rakeLeaves.
Output Format:
An attrset with names in the spirit of the Reverse DNS Notation form
that fully preserve information about grouping from nesting.
Example input:
```
{
a = {
b = {
c = <path>;
};
};
}
```
Example output:
```
{
"a.b.c" = <path>;
}
```
**/
tree:
let
op = sum: path: val:
let
pathStr = builtins.concatStringsSep "." path; # dot-based reverse DNS notation
in
if builtins.isPath val then
# builtins.trace "${toString val} is a path"
(sum // {
"${pathStr}" = val;
})
else if builtins.isAttrs val then
# builtins.trace "${builtins.toJSON val} is an attrset"
# recurse into that attribute set
/*
*
Synopsis: flattenTree _tree_
Flattens a _tree_ of the shape that is produced by rakeLeaves.
Output Format:
An attrset with names in the spirit of the Reverse DNS Notation form
that fully preserve information about grouping from nesting.
Example input:
```
{
a = {
b = {
c = <path>;
};
};
}
```
Example output:
```
{
"a.b.c" = <path>;
}
```
*
*/
tree: let
op = sum: path: val: let
pathStr = builtins.concatStringsSep "." path; # dot-based reverse DNS notation
in
if builtins.isPath val
then
# builtins.trace "${toString val} is a path"
(sum
// {
"${pathStr}" = val;
})
else if builtins.isAttrs val
then
# builtins.trace "${builtins.toJSON val} is an attrset"
# recurse into that attribute set
(recurse sum path val)
else
# ignore that value
# builtins.trace "${toString path} is something else"
sum
;
# ignore that value
# builtins.trace "${toString path} is something else"
sum;
recurse = sum: path: val:
builtins.foldl'
(sum: key: op sum (path ++ [ key ]) val.${key})
sum
(builtins.attrNames val)
;
(sum: key: op sum (path ++ [key]) val.${key})
sum
(builtins.attrNames val);
in
recurse { } [ ] tree;
recurse {} [] tree;
rakeLeaves =
/**
Synopsis: rakeLeaves _path_
Recursively collect the nix files of _path_ into attrs.
Output Format:
An attribute set where all `.nix` files and directories with `default.nix` in them
are mapped to keys that are either the file with .nix stripped or the folder name.
All other directories are recursed further into nested attribute sets with the same format.
Example file structure:
```
./core/default.nix
./base.nix
./main/dev.nix
./main/os/default.nix
```
Example output:
```
{
core = ./core;
base = base.nix;
main = {
dev = ./main/dev.nix;
os = ./main/os;
};
}
```
**/
dirPath:
let
/*
*
Synopsis: rakeLeaves _path_
Recursively collect the nix files of _path_ into attrs.
Output Format:
An attribute set where all `.nix` files and directories with `default.nix` in them
are mapped to keys that are either the file with .nix stripped or the folder name.
All other directories are recursed further into nested attribute sets with the same format.
Example file structure:
```
./core/default.nix
./base.nix
./main/dev.nix
./main/os/default.nix
```
Example output:
```
{
core = ./core;
base = base.nix;
main = {
dev = ./main/dev.nix;
os = ./main/os;
};
}
```
*
*/
dirPath: let
seive = file: type:
# Only rake `.nix` files or directories
(type == "regular" && lib.hasSuffix ".nix" file) || (type == "directory")
;
# Only rake `.nix` files or directories
(type == "regular" && lib.hasSuffix ".nix" file) || (type == "directory");
collect = file: type: {
name = lib.removeSuffix ".nix" file;
value =
let
path = dirPath + "/${file}";
in
if (type == "regular")
value = let
path = dirPath + "/${file}";
in
if
(type == "regular")
|| (type == "directory" && builtins.pathExists (path + "/default.nix"))
then path
# recurse on directories that don't contain a `default.nix`
@ -111,34 +111,28 @@ let
files = lib.filterAttrs seive (builtins.readDir dirPath);
in
lib.filterAttrs (n: v: v != { }) (lib.mapAttrs' collect files);
in
{
lib.filterAttrs (n: v: v != {}) (lib.mapAttrs' collect files);
in {
inherit rakeLeaves flattenTree;
importOverlays = dir:
{
# Meant to output a module that sets the overlays option
# overlays order matters. mkAfter ensures those in-house
# overlays are loaded later (after external ones), so the latter
# can be modified via internal overlays
overlays = lib.mkAfter (builtins.attrValues (flattenTree (rakeLeaves dir)));
};
importOverlays = dir: {
# Meant to output a module that sets the overlays option
# overlays order matters. mkAfter ensures those in-house
# overlays are loaded later (after external ones), so the latter
# can be modified via internal overlays
overlays = lib.mkAfter (builtins.attrValues (flattenTree (rakeLeaves dir)));
};
importExportableModules = dir:
{
# Meant to output a module that sets the modules option
exportedModules = builtins.attrValues (flattenTree (rakeLeaves dir));
};
importHosts = dir:
{
# Meant to output a module that sets the hosts option (including constructed host names)
hosts = lib.mapAttrs
(n: v: { modules = [ v ]; })
(flattenTree (rakeLeaves dir));
};
importExportableModules = dir: {
# Meant to output a module that sets the modules option
exportedModules = builtins.attrValues (flattenTree (rakeLeaves dir));
};
importHosts = dir: {
# Meant to output a module that sets the hosts option (including constructed host names)
hosts =
lib.mapAttrs
(n: v: {modules = [v];})
(flattenTree (rakeLeaves dir));
};
}

View File

@ -1,38 +1,36 @@
{ lib
, collectors
, darwin
, deploy
, devshell
, home-manager
, flake-utils-plus
, flake-utils
, internal-modules
, tests
} @ injectedDeps:
{ self, inputs, ... } @ args:
let
{
lib,
collectors,
darwin,
deploy,
devshell,
home-manager,
flake-utils-plus,
flake-utils,
internal-modules,
tests,
} @ injectedDeps: {
self,
inputs,
...
} @ args: let
# avoid infinite recursions w.r.t. using self or inputs in imports
injectedDeps' = injectedDeps // { inherit self inputs; };
injectedDeps' = injectedDeps // {inherit self inputs;};
options' = import ./options.nix injectedDeps';
fupAdapter' = import ./fup-adapter.nix injectedDeps';
defaultOutputsBuilder' = import ./outputs-builder.nix injectedDeps';
evaled = lib.evalModules { modules = [ args options' ]; };
evaled = lib.evalModules {modules = [args options'];};
defaultOutputsBuilder = defaultOutputsBuilder' evaled.config;
extraArgs = removeAttrs args (builtins.attrNames evaled.options);
in
{
in {
flake = fupAdapter' {
inherit (evaled) config;
inherit extraArgs defaultOutputsBuilder;
};
options = options';
}

View File

@ -1,17 +1,21 @@
# constructor dependencies
{ lib, self, inputs, darwin, flake-utils-plus, collectors, internal-modules, ... }:
{
lib,
self,
inputs,
darwin,
flake-utils-plus,
collectors,
internal-modules,
...
}: {
# evaluated digga configuration
config
config,
# extra arguments that are passed down to fup
, extraArgs
extraArgs,
# pass a custom default fup outputs builder
, defaultOutputsBuilder
}:
let
defaultOutputsBuilder,
}: let
sharedOverlays = [
(final: prev: {
__dontExport = true;
@ -24,102 +28,122 @@ let
defaultHostModules = [
(internal-modules.hmNixosDefaults {
specialArgs = config.home.importables // { inherit self inputs; };
specialArgs = config.home.importables // {inherit self inputs;};
modules = config.home.modules ++ config.home.exportedModules;
})
(internal-modules.globalDefaults {
hmUsers = config.home.users;
})
({ ... }@args: {
lib.specialArgs = args.specialArgs or (builtins.trace ''
WARNING: specialArgs is not accessibly by the module system which means you
are likely using NixOS 20.09. Profiles testing and custom builds (ex: iso)
are not supported in 20.09 and using them could result in infinite
recursion errors. It is recommended to update to 21.05 to use either feature.
''
{ });
({...} @ args: {
lib.specialArgs =
args.specialArgs
or (builtins.trace ''
WARNING: specialArgs is not accessibly by the module system which means you
are likely using NixOS 20.09. Profiles testing and custom builds (ex: iso)
are not supported in 20.09 and using them could result in infinite
recursion errors. It is recommended to update to 21.05 to use either feature.
''
{});
})
];
unifyOverlays = channels:
let
getChannel = inputs."${channelName}".legacyPackages.x86_64-linux;
channelName = builtins.elemAt (builtins.attrNames channels) 0;
in
map (o: if builtins.isFunction (o getChannel getChannel) then o channels else o);
unifyOverlays = channels: let
getChannel = inputs."${channelName}".legacyPackages.x86_64-linux;
channelName = builtins.elemAt (builtins.attrNames channels) 0;
in
map (o:
if builtins.isFunction (o getChannel getChannel)
then o channels
else o);
stripChannel = channel: removeAttrs channel [
# arguments in our channels api that shouldn't be passed to fup
"overlays"
];
stripChannel = channel:
removeAttrs channel [
# arguments in our channels api that shouldn't be passed to fup
"overlays"
];
# evalArgs sets channelName and system to null by default
# but for proper default handling in fup, null args have to be removed
stripNull = args: (lib.filterAttrs (_: arg: arg != null) args);
stripHost = args: removeAttrs (stripNull args) [
# arguments in our hosts/hostDefaults api that shouldn't be passed to fup
"externalModules" # TODO: remove deprecated option
"exportedModules"
"tests"
];
stripHost = args:
removeAttrs (stripNull args) [
# arguments in our hosts/hostDefaults api that shouldn't be passed to fup
"externalModules" # TODO: remove deprecated option
"exportedModules"
"tests"
];
nixosHostDefaults = flake-utils-plus.lib.mergeAny
nixosHostDefaults =
flake-utils-plus.lib.mergeAny
{
system = "x86_64-linux";
output = "nixosConfigurations";
# add `self` & `inputs` as specialArgs so their libs can be used in imports
specialArgs = config.nixos.importables // { inherit (config) self inputs; };
specialArgs = config.nixos.importables // {inherit (config) self inputs;};
modules = config.nixos.hostDefaults.exportedModules ++ defaultHostModules ++ [
internal-modules.nixosDefaults
];
modules =
config.nixos.hostDefaults.exportedModules
++ defaultHostModules
++ [
internal-modules.nixosDefaults
];
}
(stripNull config.nixos.hostDefaults);
nixosHosts = lib.mapAttrs
nixosHosts =
lib.mapAttrs
(
_: hostConfig:
flake-utils-plus.lib.mergeAny
nixosHostDefaults
(stripNull hostConfig)
nixosHostDefaults
(stripNull hostConfig)
)
config.nixos.hosts;
darwinHostDefaults = flake-utils-plus.lib.mergeAny
darwinHostDefaults =
flake-utils-plus.lib.mergeAny
{
system = "x86_64-darwin";
output = "darwinConfigurations";
builder = darwin.lib.darwinSystem;
# add `self` & `inputs` as specialArgs so their libs can be used in imports
specialArgs = config.darwin.importables // { inherit (config) self inputs; };
specialArgs = config.darwin.importables // {inherit (config) self inputs;};
modules = config.darwin.hostDefaults.exportedModules ++ defaultHostModules;
}
(stripNull config.darwin.hostDefaults);
darwinHosts = lib.mapAttrs
darwinHosts =
lib.mapAttrs
(
_: hostConfig: flake-utils-plus.lib.mergeAny
_: hostConfig:
flake-utils-plus.lib.mergeAny
darwinHostDefaults
(stripNull hostConfig)
)
config.darwin.hosts;
diggaFupArgs = {
inherit (config)
inherit
(config)
channelsConfig
supportedSystems;
supportedSystems
;
inherit self inputs sharedOverlays;
hosts = builtins.mapAttrs (_: stripHost)
hosts =
builtins.mapAttrs (_: stripHost)
(collectors.collectHosts nixosHosts darwinHosts);
channels = builtins.mapAttrs
(name: channel:
stripChannel (channel // {
# pass channels if "overlay" has three arguments
overlaysBuilder = channels: unifyOverlays channels channel.overlays;
})
channels =
builtins.mapAttrs
(
name: channel:
stripChannel (channel
// {
# pass channels if "overlay" has three arguments
overlaysBuilder = channels: unifyOverlays channels channel.overlays;
})
)
config.channels;
@ -141,13 +165,12 @@ let
outputsBuilder = channels:
flake-utils-plus.lib.mergeAny
(defaultOutputsBuilder channels)
(config.outputsBuilder channels);
(defaultOutputsBuilder channels)
(config.outputsBuilder channels);
};
in
flake-utils-plus.lib.mkFlake (
flake-utils-plus.lib.mergeAny
flake-utils-plus.lib.mkFlake (
flake-utils-plus.lib.mergeAny
diggaFupArgs
extraArgs # for overlays list order
)
)

View File

@ -1,466 +1,500 @@
# constructor dependencies
{ lib, devshell, flake-utils, self, inputs, ... }:
with lib;
{ config, ... }:
let
cfg = config;
# #############
# Resolver
# #############
/**
Synopsis: maybeImport <path|string or obj>
Returns an imported path or string or the object otherwise.
Use when you want to allow specifying an object directly or a path to it.
It saves the end user the additional import statement.
**/
maybeImport = obj:
if (builtins.isPath obj || builtins.isString obj) then
import obj
else obj
;
/**
Synopsis: maybeImportDevshellToml <path|string or obj>
Returns an imported path or string if the filename ends in `toml` or the object or path otherwise.
Use only for devshell modules, as an apply function.
**/
maybeImportDevshellToml = obj:
if ((builtins.isPath obj || builtins.isString obj) && lib.hasSuffix ".toml" obj) then
devshell.lib.importTOML obj
else obj
;
/**
Synopsis: pathToOr <type>
Type resolver: types maybeImport's <obj>.
Use in type declarations.
**/
pathToOr = elemType: with types; coercedTo path maybeImport elemType;
/**
Synopsis: coercedListOf <type>
Type resolver & list flattner: flattens a (evtl. arbitrarily nested) list of type <type>.
Use in type declarations.
**/
coercedListOf = elemType: with types;
coercedTo anything (x: flatten (singleton x)) (listOf elemType);
# #############
# Custom Types
# #############
nixosTestType = pathToOr (mkOptionType {
name = "test";
check = x: builtins.isFunction x || builtins.isAttrs x;
description = "valid NixOS test";
});
moduleType = mkOptionType {
name = "module";
inherit (types.submodule { }) check;
description = "valid module";
};
devshellModuleType = with types; coercedTo path maybeImportDevshellToml moduleType;
overlayType = pathToOr (mkOptionType {
name = "overlay";
check = builtins.isFunction;
description = "valid Nixpkgs overlay";
});
systemType = (types.enum config.supportedSystems) // {
description = "system defined in `supportedSystems`";
};
channelType = (types.enum (builtins.attrNames config.channels)) // {
description = "channel defined in `channels`";
};
flakeType = with types; (addCheck attrs lib.isStorePath) // {
description = "nix flake";
};
userType = with types; pathToOr moduleType // {
description = "HM user config";
};
overlaysType = with types; coercedListOf overlayType;
modulesType = with types; coercedListOf moduleType;
nixosTestsType = with types; coercedListOf nixosTestType;
devshellModulesType = with types; coercedListOf devshellModuleType;
legacyProfilesType = with types; listOf path;
legacySuitesType = with types; functionTo attrs;
suitesType = with types; attrsOf (coercedListOf path);
usersType = with types; attrsOf userType;
inputsType = with types; attrsOf flakeType;
# #############
# Options
# #############
systemOpt = {
system = mkOption {
type = with types; nullOr systemType;
default = null;
description = ''
system for this host
'';
};
};
channelNameOpt = required: {
channelName = mkOption
{
description = ''
Channel this host should follow
'';
}
//
(
if required then {
type = with types; channelType;
} else {
type = with types; nullOr channelType;
default = null;
}
);
};
nixosTestOpt = {
tests = mkOption {
type = with types; nixosTestsType;
default = [ ];
description = ''
tests to run
'';
example = literalExample ''
[
{
name = "testname1";
machine = { ... };
testScript = '''
# ...
''';
}
({ corutils, writers, ... }: {
name = "testname2";
machine = { ... };
testScript = '''
# ...
''';
})
./path/to/test.nix
];
'';
};
};
modulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [ ];
description = ''
modules to include
'';
};
};
exportedModulesOpt' = name: {
type = with types; pathToOr modulesType;
default = [ ];
description = ''
modules to include in all hosts and export to ${name}Modules output
'';
};
exportedModulesOpt = name: { exportedModules = mkOption (exportedModulesOpt' name); };
exportedDevshellModulesOpt = {
exportedModules = mkOption (
(exportedModulesOpt' "devshell") // {
type = with types; devshellModulesType;
}
);
};
# This is only needed for hostDefaults
# modules in each host don't get exported
regularModulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [ ];
description = ''
modules to include that won't be exported
meant importing modules from external flakes
'';
};
};
externalModulesDeprecationMessage = ''
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
'';
legacyExternalModulesMod = { config, options, ... }: {
options = {
externalModules = mkOption {
type = with types; modulesType;
default = [ ];
description = externalModulesDeprecationMessage;
};
};
config = mkIf (config.externalModules != [ ]) {
modules = throw ''
ERROR: ${externalModulesDeprecationMessage}
'';
};
};
hostDefaultsOpt = name: {
hostDefaults = mkOption {
type = with types; hostDefaultsType name;
default = { };
description = ''
Defaults for all hosts.
the modules passed under hostDefaults will be exported
to the '${name}Modules' flake output.
They will also be added to all hosts.
'';
};
};
hostsOpt = name: {
hosts = mkOption {
type = with types; hostType;
default = { };
description = ''
configurations to include in the ${name}Configurations output
'';
};
};
inputOpt = name: {
input = mkOption {
type = flakeType;
default = self.inputs.${name};
defaultText = "self.inputs.<name>";
description = ''
nixpkgs flake input to use for this channel
'';
};
};
overlaysOpt = {
overlays = mkOption {
type = with types; pathToOr overlaysType;
default = [ ];
description = escape [ "<" ">" ] ''
overlays to apply to this channel
these will get exported under the 'overlays' flake output
as <channel>/<name> and any overlay pulled from <inputs>
will be filtered out
'';
};
};
patchesOpt = {
patches = mkOption {
type = with types; listOf path;
default = [ ];
description = ''
patches to apply to this channel
'';
};
};
configOpt = {
config = mkOption {
type = with types; pathToOr attrs;
default = { };
apply = lib.recursiveUpdate cfg.channelsConfig;
description = ''
nixpkgs config for this channel
'';
};
};
importablesOpt = {
importables = mkOption {
type = with types; submoduleWith {
modules = [{
freeformType = attrs;
options = {
suites = mkOption {
type = nullOr (pathToOr suitesType);
default = null;
description = ''
collections of profiles
'';
};
};
}];
};
default = { };
description = ''
Packages of paths to be passed to modules as `specialArgs`.
'';
};
};
usersOpt = {
users = mkOption {
type = with types; usersType;
default = { };
description = ''
HM users that can be deployed portably without a host.
'';
};
};
# #############
# Aggreagate types
# #############
hostType = with types; attrsOf (submoduleWith {
modules = [
# per-host modules not exported, no external modules
{ options = systemOpt // (channelNameOpt false) // modulesOpt // nixosTestOpt; }
];
});
hostDefaultsType = name: with types; submoduleWith {
modules = [
{ options = systemOpt // (channelNameOpt true) // regularModulesOpt // (exportedModulesOpt name); }
legacyExternalModulesMod
];
};
nixosType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = (hostsOpt "nixos") // (hostDefaultsOpt "nixos") // importablesOpt; }
];
};
darwinType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = (hostsOpt "darwin") // (hostDefaultsOpt "darwin") // importablesOpt; }
];
};
homeType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = regularModulesOpt // (exportedModulesOpt "home") // importablesOpt // usersOpt; }
legacyExternalModulesMod
];
};
devshellType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = regularModulesOpt // exportedDevshellModulesOpt; }
legacyExternalModulesMod
];
};
channelsType = with types; attrsOf (submoduleWith {
modules = [
({ name, ... }: { options = overlaysOpt // configOpt // (inputOpt name) // patchesOpt; })
];
});
outputsBuilderType = with types; functionTo attrs;
in
{
# this does not get propagated to submodules
# to allow passing flake outputs directly to mkFlake
config._module.check = false;
lib,
devshell,
flake-utils,
self,
inputs,
...
}:
with lib;
{config, ...}: let
cfg = config;
options = with types; {
self = mkOption {
type = flakeType;
readOnly = true;
description = "The flake to create the DevOS outputs for";
# #############
# Resolver
# #############
/*
*
Synopsis: maybeImport <path|string or obj>
Returns an imported path or string or the object otherwise.
Use when you want to allow specifying an object directly or a path to it.
It saves the end user the additional import statement.
*
*/
maybeImport = obj:
if (builtins.isPath obj || builtins.isString obj)
then import obj
else obj;
/*
*
Synopsis: maybeImportDevshellToml <path|string or obj>
Returns an imported path or string if the filename ends in `toml` or the object or path otherwise.
Use only for devshell modules, as an apply function.
*
*/
maybeImportDevshellToml = obj:
if ((builtins.isPath obj || builtins.isString obj) && lib.hasSuffix ".toml" obj)
then devshell.lib.importTOML obj
else obj;
/*
*
Synopsis: pathToOr <type>
Type resolver: types maybeImport's <obj>.
Use in type declarations.
*
*/
pathToOr = elemType: with types; coercedTo path maybeImport elemType;
/*
*
Synopsis: coercedListOf <type>
Type resolver & list flattner: flattens a (evtl. arbitrarily nested) list of type <type>.
Use in type declarations.
*
*/
coercedListOf = elemType:
with types;
coercedTo anything (x: flatten (singleton x)) (listOf elemType);
# #############
# Custom Types
# #############
nixosTestType = pathToOr (mkOptionType {
name = "test";
check = x: builtins.isFunction x || builtins.isAttrs x;
description = "valid NixOS test";
});
moduleType = mkOptionType {
name = "module";
inherit (types.submodule {}) check;
description = "valid module";
};
inputs = mkOption {
type = inputsType;
readOnly = true;
description = "The flake's inputs";
devshellModuleType = with types; coercedTo path maybeImportDevshellToml moduleType;
overlayType = pathToOr (mkOptionType {
name = "overlay";
check = builtins.isFunction;
description = "valid Nixpkgs overlay";
});
systemType =
(types.enum config.supportedSystems)
// {
description = "system defined in `supportedSystems`";
};
channelType =
(types.enum (builtins.attrNames config.channels))
// {
description = "channel defined in `channels`";
};
flakeType = with types;
(addCheck attrs lib.isStorePath)
// {
description = "nix flake";
};
userType = with types;
pathToOr moduleType
// {
description = "HM user config";
};
overlaysType = with types; coercedListOf overlayType;
modulesType = with types; coercedListOf moduleType;
nixosTestsType = with types; coercedListOf nixosTestType;
devshellModulesType = with types; coercedListOf devshellModuleType;
legacyProfilesType = with types; listOf path;
legacySuitesType = with types; functionTo attrs;
suitesType = with types; attrsOf (coercedListOf path);
usersType = with types; attrsOf userType;
inputsType = with types; attrsOf flakeType;
# #############
# Options
# #############
systemOpt = {
system = mkOption {
type = with types; nullOr systemType;
default = null;
description = ''
system for this host
'';
};
};
supportedSystems = mkOption {
type = listOf str;
default = flake-utils.lib.defaultSystems;
channelNameOpt = required: {
channelName =
mkOption
{
description = ''
Channel this host should follow
'';
}
// (
if required
then {
type = with types; channelType;
}
else {
type = with types; nullOr channelType;
default = null;
}
);
};
nixosTestOpt = {
tests = mkOption {
type = with types; nixosTestsType;
default = [];
description = ''
tests to run
'';
example = literalExample ''
[
{
name = "testname1";
machine = { ... };
testScript = '''
# ...
''';
}
({ corutils, writers, ... }: {
name = "testname2";
machine = { ... };
testScript = '''
# ...
''';
})
./path/to/test.nix
];
'';
};
};
modulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [];
description = ''
modules to include
'';
};
};
exportedModulesOpt' = name: {
type = with types; pathToOr modulesType;
default = [];
description = ''
The systems supported by this flake
modules to include in all hosts and export to ${name}Modules output
'';
};
channelsConfig = mkOption {
type = pathToOr attrs;
default = { };
description = ''
nixpkgs config for all channels
'';
exportedModulesOpt = name: {exportedModules = mkOption (exportedModulesOpt' name);};
exportedDevshellModulesOpt = {
exportedModules = mkOption (
(exportedModulesOpt' "devshell")
// {
type = with types; devshellModulesType;
}
);
};
channels = mkOption {
type = pathToOr channelsType;
default = { };
description = ''
nixpkgs channels to create
'';
# This is only needed for hostDefaults
# modules in each host don't get exported
regularModulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [];
description = ''
modules to include that won't be exported
meant importing modules from external flakes
'';
};
};
outputsBuilder = mkOption {
type = pathToOr outputsBuilderType;
default = channels: { };
defaultText = "channels: { }";
description = ''
builder for flake system-spaced outputs
The builder gets passed an attrset of all channels
'';
externalModulesDeprecationMessage = ''
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
'';
legacyExternalModulesMod = {
config,
options,
...
}: {
options = {
externalModules = mkOption {
type = with types; modulesType;
default = [];
description = externalModulesDeprecationMessage;
};
};
config = mkIf (config.externalModules != []) {
modules = throw ''
ERROR: ${externalModulesDeprecationMessage}
'';
};
};
nixos = mkOption {
type = pathToOr nixosType;
default = { };
description = ''
hosts, modules, suites, and profiles for NixOS
'';
hostDefaultsOpt = name: {
hostDefaults = mkOption {
type = with types; hostDefaultsType name;
default = {};
description = ''
Defaults for all hosts.
the modules passed under hostDefaults will be exported
to the '${name}Modules' flake output.
They will also be added to all hosts.
'';
};
};
darwin = mkOption {
type = pathToOr darwinType;
default = { };
description = ''
hosts, modules, suites, and profiles for darwin
'';
hostsOpt = name: {
hosts = mkOption {
type = with types; hostType;
default = {};
description = ''
configurations to include in the ${name}Configurations output
'';
};
};
home = mkOption {
type = pathToOr homeType;
default = { };
description = ''
hosts, modules, suites, and profiles for home-manager
'';
inputOpt = name: {
input = mkOption {
type = flakeType;
default = self.inputs.${name};
defaultText = "self.inputs.<name>";
description = ''
nixpkgs flake input to use for this channel
'';
};
};
devshell = mkOption {
type = pathToOr devshellType;
default = { };
description = ''
Modules to include in your DevOS shell. the `modules` argument
will be exported under the `devshellModules` output
'';
overlaysOpt = {
overlays = mkOption {
type = with types; pathToOr overlaysType;
default = [];
description = escape ["<" ">"] ''
overlays to apply to this channel
these will get exported under the 'overlays' flake output
as <channel>/<name> and any overlay pulled from <inputs>
will be filtered out
'';
};
};
};
}
patchesOpt = {
patches = mkOption {
type = with types; listOf path;
default = [];
description = ''
patches to apply to this channel
'';
};
};
configOpt = {
config = mkOption {
type = with types; pathToOr attrs;
default = {};
apply = lib.recursiveUpdate cfg.channelsConfig;
description = ''
nixpkgs config for this channel
'';
};
};
importablesOpt = {
importables = mkOption {
type = with types;
submoduleWith {
modules = [
{
freeformType = attrs;
options = {
suites = mkOption {
type = nullOr (pathToOr suitesType);
default = null;
description = ''
collections of profiles
'';
};
};
}
];
};
default = {};
description = ''
Packages of paths to be passed to modules as `specialArgs`.
'';
};
};
usersOpt = {
users = mkOption {
type = with types; usersType;
default = {};
description = ''
HM users that can be deployed portably without a host.
'';
};
};
# #############
# Aggreagate types
# #############
hostType = with types;
attrsOf (submoduleWith {
modules = [
# per-host modules not exported, no external modules
{options = systemOpt // (channelNameOpt false) // modulesOpt // nixosTestOpt;}
];
});
hostDefaultsType = name:
with types;
submoduleWith {
modules = [
{options = systemOpt // (channelNameOpt true) // regularModulesOpt // (exportedModulesOpt name);}
legacyExternalModulesMod
];
};
nixosType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = (hostsOpt "nixos") // (hostDefaultsOpt "nixos") // importablesOpt;}
];
};
darwinType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = (hostsOpt "darwin") // (hostDefaultsOpt "darwin") // importablesOpt;}
];
};
homeType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = regularModulesOpt // (exportedModulesOpt "home") // importablesOpt // usersOpt;}
legacyExternalModulesMod
];
};
devshellType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = regularModulesOpt // exportedDevshellModulesOpt;}
legacyExternalModulesMod
];
};
channelsType = with types;
attrsOf (submoduleWith {
modules = [
({name, ...}: {options = overlaysOpt // configOpt // (inputOpt name) // patchesOpt;})
];
});
outputsBuilderType = with types; functionTo attrs;
in {
# this does not get propagated to submodules
# to allow passing flake outputs directly to mkFlake
config._module.check = false;
options = with types; {
self = mkOption {
type = flakeType;
readOnly = true;
description = "The flake to create the DevOS outputs for";
};
inputs = mkOption {
type = inputsType;
readOnly = true;
description = "The flake's inputs";
};
supportedSystems = mkOption {
type = listOf str;
default = flake-utils.lib.defaultSystems;
description = ''
The systems supported by this flake
'';
};
channelsConfig = mkOption {
type = pathToOr attrs;
default = {};
description = ''
nixpkgs config for all channels
'';
};
channels = mkOption {
type = pathToOr channelsType;
default = {};
description = ''
nixpkgs channels to create
'';
};
outputsBuilder = mkOption {
type = pathToOr outputsBuilderType;
default = channels: {};
defaultText = "channels: { }";
description = ''
builder for flake system-spaced outputs
The builder gets passed an attrset of all channels
'';
};
nixos = mkOption {
type = pathToOr nixosType;
default = {};
description = ''
hosts, modules, suites, and profiles for NixOS
'';
};
darwin = mkOption {
type = pathToOr darwinType;
default = {};
description = ''
hosts, modules, suites, and profiles for darwin
'';
};
home = mkOption {
type = pathToOr homeType;
default = {};
description = ''
hosts, modules, suites, and profiles for home-manager
'';
};
devshell = mkOption {
type = pathToOr devshellType;
default = {};
description = ''
Modules to include in your DevOS shell. the `modules` argument
will be exported under the `devshellModules` output
'';
};
};
}

View File

@ -1,144 +1,156 @@
# constructor dependencies
{ lib, self, inputs, collectors, deploy, devshell, home-manager, flake-utils-plus, tests, ... }:
config: channels:
let
{
lib,
self,
inputs,
collectors,
deploy,
devshell,
home-manager,
flake-utils-plus,
tests,
...
}: config: channels: let
pkgs = channels.${config.nixos.hostDefaults.channelName};
system = pkgs.system;
mkPortableHomeManagerConfiguration =
{ username
, configuration
, pkgs
, system ? pkgs.system
}:
let
homeDirectoryPrefix =
if pkgs.stdenv.hostPlatform.isDarwin then "/Users" else "/home";
homeDirectory = "${homeDirectoryPrefix}/${username}";
in
mkPortableHomeManagerConfiguration = {
username,
configuration,
pkgs,
system ? pkgs.system,
}: let
homeDirectoryPrefix =
if pkgs.stdenv.hostPlatform.isDarwin
then "/Users"
else "/home";
homeDirectory = "${homeDirectoryPrefix}/${username}";
in
home-manager.lib.homeManagerConfiguration {
inherit username homeDirectory pkgs system;
extraModules = config.home.modules ++ config.home.exportedModules;
extraSpecialArgs = config.home.importables // { inherit self inputs; };
extraSpecialArgs = config.home.importables // {inherit self inputs;};
configuration = {
imports = [ configuration ];
} // (
if (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin)
then { targets.genericLinux.enable = true; }
else { }
);
configuration =
{
imports = [configuration];
}
// (
if (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin)
then {targets.genericLinux.enable = true;}
else {}
);
};
homeConfigurationsPortable =
builtins.mapAttrs
(n: v: mkPortableHomeManagerConfiguration {
(n: v:
mkPortableHomeManagerConfiguration {
inherit pkgs system;
username = n;
configuration = v;
})
config.home.users;
in
{
config.home.users;
in {
inherit homeConfigurationsPortable;
packages = flake-utils-plus.lib.exportPackages self.overlays channels;
devShell =
let
eval = import "${devshell}/modules" pkgs;
configuration = {
name = lib.mkDefault config.nixos.hostDefaults.channelName;
imports = config.devshell.modules ++ config.devshell.exportedModules;
};
in
devShell = let
eval = import "${devshell}/modules" pkgs;
configuration = {
name = lib.mkDefault config.nixos.hostDefaults.channelName;
imports = config.devshell.modules ++ config.devshell.exportedModules;
};
in
(eval {
inherit configuration;
extraSpecialArgs = { inherit self inputs; };
}).shell;
extraSpecialArgs = {inherit self inputs;};
})
.shell;
checks =
(
# for self.homeConfigurations if present & non empty
if (
(builtins.hasAttr "homeConfigurations" self) &&
(self.homeConfigurations != { })
) then
let
seive = _: v: v.system == system; # only test for the appropriate system
collectActivationPackages = n: v: { name = "user-" + n; value = v.activationPackage; };
in
if
(
(builtins.hasAttr "homeConfigurations" self)
&& (self.homeConfigurations != {})
)
then let
seive = _: v: v.system == system; # only test for the appropriate system
collectActivationPackages = n: v: {
name = "user-" + n;
value = v.activationPackage;
};
in
lib.filterAttrs seive (lib.mapAttrs' collectActivationPackages self.homeConfigurations)
else { }
else {}
)
//
(
// (
# for portableHomeConfigurations if present & non empty
if (
(homeConfigurationsPortable != { })
) then
let
collectActivationPackages = n: v: { name = "user-" + n; value = v.activationPackage; };
in
if (homeConfigurationsPortable != {})
then let
collectActivationPackages = n: v: {
name = "user-" + n;
value = v.activationPackage;
};
in
# N.B. portable home configurations for Linux/NixOS hosts cannot be built on Darwin!
lib.mapAttrs' collectActivationPackages homeConfigurationsPortable
else { }
else {}
)
//
(
// (
# for self.deploy
if (
(builtins.hasAttr "deploy" self) &&
(self.deploy != { }) &&
(!pkgs.stdenv.buildPlatform.isDarwin)
) then
let
deployChecks = deploy.lib.${system}.deployChecks self.deploy;
renameOp = n: v: { name = "deploy-" + n; value = deployChecks.${n}; };
in
if
(
(builtins.hasAttr "deploy" self)
&& (self.deploy != {})
&& (!pkgs.stdenv.buildPlatform.isDarwin)
)
then let
deployChecks = deploy.lib.${system}.deployChecks self.deploy;
renameOp = n: v: {
name = "deploy-" + n;
value = deployChecks.${n};
};
in
lib.mapAttrs' renameOp deployChecks
else { }
else {}
)
//
(
// (
# for self.nixosConfigurations if present & non-empty
if (
(builtins.hasAttr "nixosConfigurations" self) &&
(self.nixosConfigurations != { }) &&
(!pkgs.stdenv.buildPlatform.isDarwin)
) then
let
hostConfigsOnThisSystem = collectors.collectHostsOnSystem self.nixosConfigurations system;
if
(
(builtins.hasAttr "nixosConfigurations" self)
&& (self.nixosConfigurations != {})
&& (!pkgs.stdenv.buildPlatform.isDarwin)
)
then let
hostConfigsOnThisSystem = collectors.collectHostsOnSystem self.nixosConfigurations system;
createCustomTestOp = n: host: test:
lib.warnIf (!(test ? name)) ''
'${n}' has a test without a name. To distinguish tests in the flake output
all tests must have names.
''
{
name = "customTestFor-${n}-${test.name}";
value = tests.mkTest host test;
};
createCustomTestsOp = n: host:
let
op = createCustomTestOp n host;
in
builtins.listToAttrs (map op config.nixos.hosts.${n}.tests);
customTests =
if (hostConfigsOnThisSystem != [ ])
then lib.foldl (a: b: a // b) { } (lib.attrValues (lib.mapAttrs createCustomTestsOp hostConfigsOnThisSystem))
else { };
createCustomTestOp = n: host: test:
lib.warnIf (!(test ? name)) ''
'${n}' has a test without a name. To distinguish tests in the flake output
all tests must have names.
''
{
name = "customTestFor-${n}-${test.name}";
value = tests.mkTest host test;
};
createCustomTestsOp = n: host: let
op = createCustomTestOp n host;
in
customTests
else { }
)
;
builtins.listToAttrs (map op config.nixos.hosts.${n}.tests);
customTests =
if (hostConfigsOnThisSystem != [])
then lib.foldl (a: b: a // b) {} (lib.attrValues (lib.mapAttrs createCustomTestsOp hostConfigsOnThisSystem))
else {};
in
customTests
else {}
);
}

View File

@ -1,40 +1,44 @@
{ lib }:
{
hmNixosDefaults = { specialArgs, modules }:
{ options, ... }: {
config = lib.optionalAttrs (options ? home-manager) {
home-manager = {
# always use the system nixpkgs from the host's channel
useGlobalPkgs = true;
# and use the possible future default (see manual)
useUserPackages = lib.mkDefault true;
{lib}: {
hmNixosDefaults = {
specialArgs,
modules,
}: {options, ...}: {
config = lib.optionalAttrs (options ? home-manager) {
home-manager = {
# always use the system nixpkgs from the host's channel
useGlobalPkgs = true;
# and use the possible future default (see manual)
useUserPackages = lib.mkDefault true;
extraSpecialArgs = specialArgs;
sharedModules = modules;
};
extraSpecialArgs = specialArgs;
sharedModules = modules;
};
};
};
globalDefaults = { hmUsers }:
{ config, pkgs, self, ... }: {
# digga lib can be accessed in modules directly as config.lib.digga
lib = {
inherit (pkgs.lib) digga;
};
_module.args = {
inherit hmUsers;
hosts = throw ''
The `hosts` module argument has been removed, you should instead use
`self.nixosConfigurations`, with the `self` module argument.
'';
};
globalDefaults = {hmUsers}: {
config,
pkgs,
self,
...
}: {
# digga lib can be accessed in modules directly as config.lib.digga
lib = {
inherit (pkgs.lib) digga;
};
nixosDefaults = { self, ... }: {
_module.args = {
inherit hmUsers;
hosts = throw ''
The `hosts` module argument has been removed, you should instead use
`self.nixosConfigurations`, with the `self` module argument.
'';
};
};
nixosDefaults = {self, ...}: {
users.mutableUsers = lib.mkDefault false;
hardware.enableRedistributableFirmware = lib.mkDefault true;
system.configurationRevision = lib.mkIf (self ? rev) self.rev;
};
}

View File

@ -1,42 +1,35 @@
{ lib }:
let
{lib}: let
maybeImport = obj:
if (builtins.isPath obj || builtins.isString obj) then
import obj
else obj
;
if (builtins.isPath obj || builtins.isString obj)
then import obj
else obj;
maybeCallTest = pkgs: obj:
if lib.isFunction obj then
pkgs.callPackage obj { }
else obj
;
if lib.isFunction obj
then pkgs.callPackage obj {}
else obj;
mkTest = host: test:
let
pkgs = host._module.args.pkgs;
nixosTesting =
(import "${toString pkgs.path}/nixos/lib/testing-python.nix" {
inherit pkgs;
inherit (pkgs) system;
inherit (host.config.lib) specialArgs;
extraConfigurations = host._module.args.modules;
});
in
mkTest = host: test: let
pkgs = host._module.args.pkgs;
nixosTesting = import "${toString pkgs.path}/nixos/lib/testing-python.nix" {
inherit pkgs;
inherit (pkgs) system;
inherit (host.config.lib) specialArgs;
extraConfigurations = host._module.args.modules;
};
in
nixosTesting.makeTest (maybeCallTest pkgs (maybeImport test));
allProfilesTest = {
name = "allProfiles";
nodes.machine = { suites ? null, ... }: {
imports =
let
allProfiles = lib.foldl
(lhs: rhs: lhs ++ rhs) [ ]
(builtins.attrValues suites);
in
nodes.machine = {suites ? null, ...}: {
imports = let
allProfiles =
lib.foldl
(lhs: rhs: lhs ++ rhs) []
(builtins.attrValues suites);
in
allProfiles;
};
@ -44,5 +37,4 @@ let
machine.systemctl("is-system-running --wait")
'';
};
in
{ inherit mkTest allProfilesTest; }
in {inherit mkTest allProfilesTest;}