Update user-specific config

Oh no, now I'm content with creating my own framework instead of using
something like digga or flake-utils.
This commit is contained in:
Gabriel Arazas 2021-11-29 13:30:57 +08:00
parent 516f465185
commit db5fc8269e
13 changed files with 237 additions and 303 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "users/config"]
path = users/config
url = https://github.com/foo-dogsquared/dotfiles.git

View File

@ -18,8 +18,9 @@ This primarily uses Nix flakes so you can have a preview of what's available in
nix flake show github:foo-dogsquared/nixos-config
----
It should only export my NixOS configurations of my different hosts (of only one so far excluding VMs and VPSs ;p).
It should export my NixOS configurations of my different hosts (of only one so far excluding VMs and VPSs ;p) among other things.
To install it, run the `nixos-install --flake github:foo-dogsquared/nixos-config#ni`.
(Please see the respective appropriate host README for more information.)
@ -28,24 +29,16 @@ It should only export my NixOS configurations of my different hosts (of only one
In order of priority:
* Create custom modules.
** Create a themes system similar to link:https://github.com/hlissner/dotfiles[this NixOS config].
* Manage secrets with agenix.
* Automate backups with NixOS config.
* Create custom packages and export it to flakes. (Maybe consider making it to upstream)
* Create cluser-wide configs.
* Create host-wide configs.
* Create user-specific configs with home-manager.
* ~Steal~ Get some ideas from link:https://github.com/divnix/devos[this overengineered template].
* Make use of other established utilities such as link:https://github.com/divnix/digga/[digga], link:https://github.com/gytis-ivaskevicius/flake-utils-plus[flake-utils-plus], and link:https://github.com/nix-community/home-manager[home-manager] once I'm familiar to create my own Nix programs.
* [x] Create custom modules.
* [x] Create a themes system similar to link:https://github.com/hlissner/dotfiles[this NixOS config].
* [ ] Manage secrets with agenix.
* [x] Automate backups with NixOS config.
* [ ] Create custom packages and export it to flakes. (Maybe consider making it to upstream)
* [x] Create cluser-wide configs.
* [x] Create host-wide configs.
* [ ] Create user-specific configs with home-manager.
* [ ] ~Steal~ Get some ideas from link:https://github.com/divnix/devos[this overengineered template].
* [ ] Make use of other established utilities such as link:https://github.com/divnix/digga/[digga], link:https://github.com/gytis-ivaskevicius/flake-utils-plus[flake-utils-plus], and link:https://github.com/nix-community/home-manager[home-manager] once I'm familiar to create my own Nix programs.
Out of scope:
@ -55,3 +48,18 @@ They are often updated. I don't want to rebuild it every time I change it.
* Migration of my link:https://github.com/foo-dogsquared/dotfiles[dotfiles].
I still use it on other non-NixOS systems.
== Frequently asked questions (FAQ)
[qanda]
Hello! I'm new to Nix and NixOS, where should I start?::
Oh no, you've seen the multiple configurations from other systems, didn't you?
I hope you're ready for some time understanding because the learning curve is steeper than the link:https://en.wikipedia.org/wiki/Troll_Wall[Troll Wall].
I've written link:https://foo-dogsquared.github.io/blog/posts/moving-into-nixos/[a blog post regarding my experience with Nix] with a bunch of links for getting started.
(Un)Fortunately, it is mostly the same experience now that I've revisited it.
Any requirements for this setup?::
You only need Nix 2.4 installed with the experimental features for Nix command and flakes enabled (i.e., `experimental-features = nix-command flakes`).

279
flake.lock generated
View File

@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1637625975,
"narHash": "sha256-ByDgmhpLykhAVeaFggjqoSRdl2OzTDODnxjPuu97fL4=",
"lastModified": 1637793790,
"narHash": "sha256-oPXavjxETEWGXq8g7kQHyRLKUmLX2yPtGn+t3V0mrTY=",
"owner": "ryantm",
"repo": "agenix",
"rev": "a0e9ca505c82e762d39e9477a428b537a0aab022",
"rev": "f85eea0e29fa9a8924571d0e398215e175f80d55",
"type": "github"
},
"original": {
@ -20,178 +20,18 @@
"type": "github"
}
},
"blank": {
"locked": {
"lastModified": 1625557891,
"narHash": "sha256-O8/MWsPBGhhyPoPLHZAuoZiiHo9q6FLlEeIDEXuj6T4=",
"owner": "divnix",
"repo": "blank",
"rev": "5a5d2684073d9f563072ed07c871d577a6c614a8",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "blank",
"type": "github"
}
},
"deploy": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"digga",
"latest"
],
"utils": [
"digga",
"flake-utils"
]
},
"locked": {
"lastModified": 1632822684,
"narHash": "sha256-lt7eayYmgsD5OQwpb1XYfHpxttn43bWo7G7hIJs+zJw=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "9a02de4373e0ec272d08a417b269a28ac8b961b4",
"type": "github"
},
"original": {
"owner": "serokell",
"repo": "deploy-rs",
"type": "github"
}
},
"devshell": {
"locked": {
"lastModified": 1632436039,
"narHash": "sha256-OtITeVWcKXn1SpVEnImpTGH91FycCskGBPqmlxiykv4=",
"owner": "numtide",
"repo": "devshell",
"rev": "7a7a7aa0adebe5488e5abaec688fd9ae0f8ea9c6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"digga": {
"inputs": {
"blank": "blank",
"deploy": "deploy",
"devshell": "devshell",
"flake-utils": "flake-utils",
"flake-utils-plus": "flake-utils-plus",
"home-manager": "home-manager",
"latest": "latest",
"nix": "nix",
"nixlib": [
"digga",
"nixpkgs"
],
"nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1634161492,
"narHash": "sha256-7OZz7DqAhO+3axY68xsMXAyD+b5gJgVXuKjslTSCM3Y=",
"owner": "divnix",
"repo": "digga",
"rev": "a55450a16d362b6e1c50bb4025aaa604b385d3ba",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "digga",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1627913399,
"narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1623875721,
"narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "f7e004a55b120c02ecb6219596820fcd32ca8772",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils-plus": {
"inputs": {
"flake-utils": [
"digga",
"flake-utils"
]
},
"locked": {
"lastModified": 1630859749,
"narHash": "sha256-qkoU2rIbbP2+T0dfcqXW35GCWNsi0Y1IgN9BELmt4Zo=",
"owner": "divnix",
"repo": "flake-utils-plus",
"rev": "a4e267e3fc87e60c5029c6c3855935ff1ff3018e",
"type": "github"
},
"original": {
"owner": "divnix",
"repo": "flake-utils-plus",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"digga",
"nixlib"
]
},
"locked": {
"lastModified": 1629347633,
"narHash": "sha256-FGZJ7lmTAMIkjdrh6dIPck5HuB4KMT2GgDV5ZjiCWoc=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "bf6b85136b47ab1a76df4a90ea4850871147494a",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1637721183,
"narHash": "sha256-4CAKKxrt9l0Hbl57Uypo7ol93Ko+5Yn+7xWWCMUyHQ8=",
"lastModified": 1638150501,
"narHash": "sha256-aWH3MRmjUtx8ciSGLegBJC5mhymsuroHPs74ZldrNTU=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "df931a59a5864d6ff0c5d83598135816f8593647",
"rev": "9de77227d7780518cfeaee5a917970247f3ecc56",
"type": "github"
},
"original": {
@ -200,109 +40,13 @@
"type": "github"
}
},
"latest": {
"locked": {
"lastModified": 1632660378,
"narHash": "sha256-sjA8eQlnyDjDLyAyq3XlJmN0nqW0ftl/pb7VnMg86L0=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "31ffc50c571e6683e9ecc9dbcbd4a8e9914b4497",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"lowdown-src": {
"flake": false,
"locked": {
"lastModified": 1617481909,
"narHash": "sha256-SqnfOFuLuVRRNeVJr1yeEPJue/qWoCp5N6o5Kr///p4=",
"owner": "kristapsdz",
"repo": "lowdown",
"rev": "148f9b2f586c41b7e36e73009db43ea68c7a1a4d",
"type": "github"
},
"original": {
"owner": "kristapsdz",
"ref": "VERSION_0_8_4",
"repo": "lowdown",
"type": "github"
}
},
"nix": {
"inputs": {
"lowdown-src": "lowdown-src",
"nixpkgs": [
"digga",
"nixpkgs"
]
},
"locked": {
"lastModified": 1630335771,
"narHash": "sha256-eljjEPJdLK3aDskF7qX4YM/6KCq+w9nr+IKhrKW/AIQ=",
"owner": "nixos",
"repo": "nix",
"rev": "50a35860ee9237d341948437c5f70a7f0987d393",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nix",
"type": "github"
}
},
"nixos-generators": {
"inputs": {
"nixlib": [
"digga",
"nixlib"
],
"nixpkgs": [
"digga",
"blank"
]
},
"locked": {
"lastModified": 1624973746,
"narHash": "sha256-11JbJRduNwyf556gndGErR5/12ceyHOHBfEuha5Vws4=",
"owner": "nix-community",
"repo": "nixos-generators",
"rev": "022ef440af8dc237ab1f59fa363cb1e25783ec3e",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-generators",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1628203131,
"narHash": "sha256-jQgXeJ9NQQS0Eobb/qQOvS+RRULkqRikAeXkkFKOPDA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "178da37860823d35e801c7df2f73d7866d3d598a",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "release-21.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1637593665,
"narHash": "sha256-R7jKS7A+0tZS8qD5pBr1UFcMiTdsw5bfoxgXbYsoWhM=",
"lastModified": 1638097282,
"narHash": "sha256-EXCzj9b8X/lqDPJapxZThIOKL5ASbpsJZ+8L1LnY1ig=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "98747f27ecfee70c8c97b195cbb94df80a074dda",
"rev": "78cb77b29d37a9663e05b61abb4fa09465da4b70",
"type": "github"
},
"original": {
@ -315,9 +59,8 @@
"root": {
"inputs": {
"agenix": "agenix",
"digga": "digga",
"home-manager": "home-manager_2",
"nixpkgs": "nixpkgs_2"
"home-manager": "home-manager",
"nixpkgs": "nixpkgs"
}
}
},

View File

@ -8,11 +8,9 @@
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
digga.url = "github:divnix/digga";
};
outputs = inputs@{ self, nixpkgs, ... }:
outputs = inputs@{ self, nixpkgs, home-manager, ... }:
let
libExtended = nixpkgs.lib.extend
(final: prev: (import ./lib { inherit inputs; lib = final; }));
@ -33,10 +31,17 @@
};
# TODO: Remove this after nix-command and flakes has been considered stable.
#
# Since we're using flakes to make this possible, we need it.
# Plus, the UX of Nix CLI is becoming closer to Guix's which is a nice bonus.
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
};
userDefaultConfig = {
system = "x86_64-linux";
};
in {
# Exposes only my library with the custom functions to make it easier to include in other flakes.
lib = import ./lib { inherit inputs; lib = nixpkgs.lib; };
@ -50,5 +55,21 @@
# or not this is a good thing is debatable, I just want to test it.
nixosModules =
libExtended.mapAttrs (_: path: import path) (libExtended.filesToAttr ./modules);
homeConfigurations =
let
excludedModules = [
"config" # The common user-specific configurations.
"modules" # User-specific Nix modules.
];
in
libExtended.mapAttrs (user: path:
home-manager.lib.homeManagerConfiguration {
system = "x86_64-linux";
configuration = import path;
homeDirectory = "/home/${user}";
username = user;
})
(libExtended.filterAttrs (n: v: !libExtended.elem n excludedModules) (libExtended.filesToAttr ./users));
};
}

34
hosts/ni/README.adoc Normal file
View File

@ -0,0 +1,34 @@
= ni, my (only) workstation
:toc:
My laptop.
I was about to have two computers but my desktop is broken ever since.
Whoops!
I try to be minimal with my dependencies unlike last time.
`direnv`, `lorri`, and Flatpak are mostly enough for desktop needs.
(Which is Fedora Silverblue is good at! :))
I know partitioning is not your favorite part so here's one way to prepare the laptop with this config.
[source, shell]
----
# Preparing the partitions.
parted /dev/sda -- mklabel gpt
parted /dev/sda -- mkpart primary 512MiB -4GB
parted /dev/sda -- mkpart primary linux-swap -4GB 100%
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
parted /dev/sda -- set 3 esp on
# Setting up the filesystems.
mkfs.ext4 -L nixos /dev/sda1
mkswap -L swap /dev/sda2
mkfs.fat -F 32 -n boot /dev/sda3
# Mount the partitions before installation.
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
swapon /dev/disk/by-label/swap
----

View File

@ -117,6 +117,24 @@ in rec {
++ (lib.mapAttrsToList (n: v: import v) (filesToAttr ../modules));
};
/* Return an attribute set of valid users from a given list of users.
Signature:
list -> attrset
Where:
- `list` is a list of usernames as strings
- `attrset` is a set of valid users with the name as the key and the path as the value.
Example:
# Assuming only 'foo-dogsquared' is the existing user.
getUsers [ "foo-dogsquared" "archie" "brad" ]
=> { foo-dogsquared = /home/foo-dogsquared/projects/nixos-config/users/foo-dogsquared; }
*/
getUsers = users:
let
userModules = filesToAttr ../users;
validUsers = lib.filter (user: lib.elem user (lib.attrNames userModules)) users;
in lib.filterAttrs (n: _: lib.elem n validUsers) userModules;
/* Create an attribute set from two lists (or a zip).
Examples:

62
modules/README.adoc Normal file
View File

@ -0,0 +1,62 @@
= Modules
:toc:
These are the modules to be used for the system configuration.
For easier modularization, any user-specific configurations such as from link:https://github.com/nix-community/home-manager[home-manager] should be placed in link:../users/[`../users/` directory].
The modules are imported usually through `lib.filesToAttr`, allowing for easier structuring without modifying the index file of each module (i.e., `default.nix`).
(See the implementation for more details.)
For example, take the following module folder structure...
[source, tree]
----
modules/
├── themes/
│   ├── a-happy-gnome/
│   │   ├── default.nix
│   │   └── README.adoc
│   ├── a-sad-gnome/
│   │   ├── default.nix
│   │   └── README.adoc
│   └── default.nix
├── specific/
│   ├── borg.nix
│   └── prometheus.nix
├── agenix.nix
├── archiving.nix
├── desktop.nix
├── dev.nix
├── editors.nix
└── users.nix
----
...should have the following attribute set.
[source, nix]
----
{
agenix = path/to/agenix.nix;
archiving = path/to/archiving.nix;
desktop = path/to/desktop.nix;
dev = path/to/dev.nix;
editors = path/to/editors.nix;
specific = {
borg = path/to/specific/borg.nix
prometheus = path/to/specific/prometheus.nix
};
themes = path/to/themes; # Since it has a 'default.nix' detected, we're using it instead.
users = path/to/users.nix;
}
----
The resulting attribute set can be easily be used for importing.
Here's an example of a NixOS system created with the modules which can used for shared configuration between hosts.
[source, nix]
----
lib.nixosSystem {
system = "x86_64-linux";
modules = lib.mapAttrsToList (name: path: import path) (lib.filesToAttr ./modules);
}
----

View File

@ -4,7 +4,7 @@
let cfg = config.modules.agenix;
in {
options.modules.agenix.enable =
lib.mkEnableOption "Enable agenix on your system";
lib.mkEnableOption "Automate agenix-related config on your system";
imports = [ inputs.agenix.nixosModules.age ];
config = lib.mkIf cfg.enable {

View File

@ -1,3 +1,4 @@
# Your text editor war arsenal.
{ config, options, lib, pkgs, ... }:
let cfg = config.modules.editors;

View File

@ -1,3 +1,4 @@
# This enables home-manager specific configs and an easier modularization for user-specific configurations.
{ inputs, config, options, lib, ... }:
let
@ -6,7 +7,22 @@ let
users = lib.attrNames userModules;
nonexistentUsers = lib.filter (name: !lib.elem name users) cfg.users;
validUsers = lib.filterAttrs (n: v: lib.elem n users) userModules;
mkUser = user: path:
let
defaultConfig = {
home.username = user;
home.homeDirectory = "/home/${user}";
};
in
{
users.users.${user} = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
home-manager.users.${user} = defaultConfig // import path;
};
in
{
options.modules.users = {
@ -17,7 +33,19 @@ in
};
};
imports = [ inputs.home-manager.nixosModules.home-manager ] ++ (lib.attrValues validUsers);
# FIXME: Recursion error when using `lib.getUsers cfg.users`.
# Time to study how Nix modules really work.
# The assertion is basically enough for this case.
imports = [
# home-manager to enable user-specific config.
inputs.home-manager.nixosModules.home-manager
# The global configuration for the home-manager module.
{
home-manager.useUserPackages = true;
home-manager.useGlobalPkgs = true;
}
] ++ (lib.mapAttrsToList mkUser userModules);
config = {
assertions = [{

View File

@ -1,5 +1,21 @@
= Users
= Users configuration
:toc:
This is where user-specific configurations comes in.
Ideally,
Ideally, the configurations are link:https://nix-community.github.io/home-manager/[home-manager config].
The configs should assume to be used as a configuration as `.config/nixpkgs/home.nix` (i.e., `home-manager.lib.homeManagerConfiguration`, `home-manager.users.${user}`, in your ordinary home-manager setup in a foreign distro).
Here's an example of a sample user config placed in `users/hello.nix`.
[source, nix]
----
{ config, options, pkgs, lib, ... }:
{
programs.home-manager.enable = true;
programs.direnv.enable = true;
home.file.".npmrc".source = ./config/npmrc;
}
----
This is to be imported to `homeManagerConfiguration` in the flake outputs and when indicated from `config.modules.users.users` (e.g., `modules.users.users = [ "hello" ];`).

1
users/config Submodule

@ -0,0 +1 @@
Subproject commit 9af98f21d21f5118c241a7c4809ae3d2a390846d

View File

@ -1,12 +1,11 @@
{ config, options, lib, pkgs, ... }:
{
# Define a user account. Don't forget to set a password with passwd.
users.users.foo-dogsquared = {
isNormalUser = true;
extraGroups = [ "wheel" ]; # Enable sudo for the user.
programs.direnv.enable = true;
programs.git = {
enable = true;
lfs.enable = true;
userName = "foo-dogsquared";
userEmail = "foo.dogsquared@gmail.com";
};
home-manager.useUserPackages = true;
home-manager.useGlobalPkgs = true;
}