This commit is contained in:
1 parent
6fa74fead8
commit
c2bb81ec7c
11 files changed
+383
-369
No files matched your search
@@ -15,7 +15,6 @@ with pkgs;
|
|||||||
parallel
|
parallel
|
||||||
pass
|
pass
|
||||||
ripgrep
|
ripgrep
|
||||||
sops
|
|
||||||
tldr
|
tldr
|
||||||
tree
|
tree
|
||||||
wget
|
wget
|
||||||
|
|||||||
@@ -2,61 +2,51 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib',
|
|
||||||
osConfig ? null,
|
|
||||||
inputs ? null,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
sops = lib'.sopsAvailability config osConfig;
|
authReady = config.secrets.templatePath ? "opencode/auth.json";
|
||||||
standalone = osConfig == null;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = lib.mkIf config.ai-tools.opencode.enable (
|
config = lib.mkIf config.ai-tools.opencode.enable {
|
||||||
lib.optionalAttrs standalone {
|
secrets.files.opencode = [ "api-key" ];
|
||||||
sops = {
|
|
||||||
secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null {
|
|
||||||
opencode = [ "api-key" ];
|
|
||||||
};
|
|
||||||
templates."opencode/auth.json" = {
|
|
||||||
path = "${config.home.homeDirectory}/.local/share/opencode/auth.json";
|
|
||||||
content = builtins.toJSON {
|
|
||||||
zai-coding-plan = {
|
|
||||||
type = "api";
|
|
||||||
key = config.sops.placeholder."opencode/api-key";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// {
|
|
||||||
warnings =
|
|
||||||
lib.optional (!sops.available)
|
|
||||||
"opencode is enabled, but sops templates are not available. the opencode API key will not be configured.";
|
|
||||||
|
|
||||||
home.packages = [ pkgs.opencode ];
|
secrets.templates."opencode/auth.json" = {
|
||||||
home.file.".config/opencode/opencode.json".text = builtins.toJSON {
|
path = ".local/share/opencode/auth.json";
|
||||||
"$schema" = "https://opencode.ai/config.json";
|
content = builtins.toJSON {
|
||||||
permission = {
|
zai-coding-plan = {
|
||||||
external_directory = {
|
type = "api";
|
||||||
"/run/secrets/" = "deny";
|
key = config.sops.placeholder."opencode/api-key";
|
||||||
"~/.config/sops/age/keys.txt" = "deny";
|
|
||||||
"~/.ssh/id_rsa" = "deny";
|
|
||||||
"~/.ssh/id_ed25519" = "deny";
|
|
||||||
"~/.ssh/id_ecdsa" = "deny";
|
|
||||||
"~/.ssh/id_dsa" = "deny";
|
|
||||||
"/etc/ssh/ssh_host_rsa_key" = "deny";
|
|
||||||
"/etc/ssh/ssh_host_ed25519_key" = "deny";
|
|
||||||
"/etc/ssh/ssh_host_ecdsa_key" = "deny";
|
|
||||||
"/etc/ssh/ssh_host_dsa_key" = "deny";
|
|
||||||
};
|
|
||||||
command = {
|
|
||||||
sops = "deny";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
plugin = [ "@mohak34/opencode-notifier@latest" ];
|
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
);
|
|
||||||
|
warnings =
|
||||||
|
lib.optional (!authReady)
|
||||||
|
"opencode is enabled but its auth template is unavailable. the opencode API key will not be configured.";
|
||||||
|
|
||||||
|
home.packages = [ pkgs.opencode ];
|
||||||
|
home.file.".config/opencode/opencode.json".text = builtins.toJSON {
|
||||||
|
"$schema" = "https://opencode.ai/config.json";
|
||||||
|
permission = {
|
||||||
|
external_directory = {
|
||||||
|
"/run/secrets/" = "deny";
|
||||||
|
"~/.config/sops/age/keys.txt" = "deny";
|
||||||
|
"~/.ssh/id_rsa" = "deny";
|
||||||
|
"~/.ssh/id_ed25519" = "deny";
|
||||||
|
"~/.ssh/id_ecdsa" = "deny";
|
||||||
|
"~/.ssh/id_dsa" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_rsa_key" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_ed25519_key" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_ecdsa_key" = "deny";
|
||||||
|
"/etc/ssh/ssh_host_dsa_key" = "deny";
|
||||||
|
};
|
||||||
|
command = {
|
||||||
|
sops = "deny";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
plugin = [ "@mohak34/opencode-notifier@latest" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -2,60 +2,51 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib',
|
|
||||||
osConfig ? null,
|
|
||||||
inputs ? null,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.anki;
|
cfg = config.anki;
|
||||||
sops = lib'.sopsAvailability config osConfig;
|
syncReady = config.secrets.path ? "anki/sync-user" && config.secrets.path ? "anki/sync-key";
|
||||||
standalone = osConfig == null;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.anki.enable = lib.mkEnableOption "Anki";
|
options.anki.enable = lib.mkEnableOption "Anki";
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
config = lib.mkIf cfg.enable {
|
||||||
lib.optionalAttrs standalone {
|
secrets.files.anki = [
|
||||||
sops.secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null {
|
"sync-user"
|
||||||
anki = [
|
"sync-key"
|
||||||
"sync-user"
|
];
|
||||||
"sync-key"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// {
|
|
||||||
warnings = lib.optional (
|
|
||||||
!sops.available
|
|
||||||
) "anki is enabled but sops secrets are not available. anki sync will not be configured.";
|
|
||||||
|
|
||||||
programs.anki = {
|
warnings = lib.optional (
|
||||||
enable = true;
|
!syncReady
|
||||||
package = config.nixgl.wrap pkgs.anki;
|
) "anki is enabled but its secrets are unavailable. anki sync will not be configured.";
|
||||||
addons = with pkgs.ankiAddons; [
|
|
||||||
(anki-connect.withConfig {
|
|
||||||
# https://git.sr.ht/~foosoft/anki-connect/tree/master/item/plugin/config.json
|
|
||||||
config = {
|
|
||||||
apiKey = null;
|
|
||||||
apiLogPath = null;
|
|
||||||
webBindAddress = "127.0.0.1";
|
|
||||||
webBindPort = 8765;
|
|
||||||
webCorsOriginList = [ "http://localhost" ];
|
|
||||||
ignoreOriginList = [ ];
|
|
||||||
};
|
|
||||||
})
|
|
||||||
puppy-reinforcement
|
|
||||||
review-heatmap
|
|
||||||
];
|
|
||||||
profiles."User 1".sync = lib.mkIf sops.available {
|
|
||||||
usernameFile = "${sops.secrets."anki/sync-user".path}";
|
|
||||||
keyFile = "${sops.secrets."anki/sync-key".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# allow Anki to write prefs
|
programs.anki = {
|
||||||
home.file."${config.xdg.dataHome}/Anki2/prefs21.db".enable = lib.mkForce false;
|
enable = true;
|
||||||
}
|
package = config.nixgl.wrap pkgs.anki;
|
||||||
);
|
addons = with pkgs.ankiAddons; [
|
||||||
|
(anki-connect.withConfig {
|
||||||
|
# https://git.sr.ht/~foosoft/anki-connect/tree/master/item/plugin/config.json
|
||||||
|
config = {
|
||||||
|
apiKey = null;
|
||||||
|
apiLogPath = null;
|
||||||
|
webBindAddress = "127.0.0.1";
|
||||||
|
webBindPort = 8765;
|
||||||
|
webCorsOriginList = [ "http://localhost" ];
|
||||||
|
ignoreOriginList = [ ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
puppy-reinforcement
|
||||||
|
review-heatmap
|
||||||
|
];
|
||||||
|
profiles."User 1".sync = lib.mkIf syncReady {
|
||||||
|
usernameFile = config.secrets.path."anki/sync-user";
|
||||||
|
keyFile = config.secrets.path."anki/sync-key";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# allow Anki to write prefs
|
||||||
|
home.file."${config.xdg.dataHome}/Anki2/prefs21.db".enable = lib.mkForce false;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
+119
-125
@@ -1,22 +1,24 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
inputs,
|
|
||||||
lib,
|
lib,
|
||||||
lib',
|
|
||||||
osConfig ? null,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.git;
|
cfg = config.git;
|
||||||
sops = lib'.sopsAvailability config osConfig;
|
identities = [
|
||||||
standalone = osConfig == null;
|
"personal"
|
||||||
|
"work"
|
||||||
|
];
|
||||||
|
|
||||||
personalEmail = sops.templates.".gitconfig.email".path;
|
emailTemplate = key: ".gitconfig.${key}.email";
|
||||||
workEmail = sops.templates.".gitconfig.work.email".path;
|
emailInclude =
|
||||||
|
key:
|
||||||
|
lib.optionalAttrs (config.secrets.templatePath ? ${emailTemplate key}) {
|
||||||
|
include.path = config.secrets.templatePath.${emailTemplate key};
|
||||||
|
};
|
||||||
|
|
||||||
workSettings = {
|
workSettings = emailInclude "work" // {
|
||||||
include.path = workEmail;
|
|
||||||
core.longpaths = true;
|
core.longpaths = true;
|
||||||
user = {
|
user = {
|
||||||
name = "Hektor Misplon";
|
name = "Hektor Misplon";
|
||||||
@@ -47,123 +49,116 @@ in
|
|||||||
./gitlab.nix
|
./gitlab.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable (
|
config = lib.mkIf cfg.enable {
|
||||||
lib.optionalAttrs standalone {
|
secrets.files.email = identities;
|
||||||
sops = {
|
|
||||||
secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null {
|
|
||||||
email = [
|
|
||||||
"personal"
|
|
||||||
"work"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
templates = {
|
secrets.templates = lib.genAttrs' identities (
|
||||||
".gitconfig.email".content = ''
|
key:
|
||||||
[user]
|
lib.nameValuePair (emailTemplate key) {
|
||||||
email = ${config.sops.placeholder."email/personal"}
|
content = ''
|
||||||
'';
|
[user]
|
||||||
".gitconfig.work.email".content = ''
|
email = ${config.sops.placeholder."email/${key}"}
|
||||||
[user]
|
'';
|
||||||
email = ${config.sops.placeholder."email/work"}
|
}
|
||||||
'';
|
);
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// {
|
|
||||||
warnings = lib.optional (
|
|
||||||
!config.nvim.enable
|
|
||||||
) "'git.enable' is enabled without 'nvim.enable' (not using 'nvimdiff')";
|
|
||||||
|
|
||||||
xdg.configFile."git/ignore".source = ./global.gitignore;
|
warnings = lib.optional (
|
||||||
|
!config.nvim.enable
|
||||||
|
) "'git.enable' is enabled without 'nvim.enable' (not using 'nvimdiff')";
|
||||||
|
|
||||||
programs.git = {
|
xdg.configFile."git/ignore".source = ./global.gitignore;
|
||||||
enable = true;
|
|
||||||
settings = lib.mkMerge [
|
|
||||||
{
|
|
||||||
user = {
|
|
||||||
name = "Hektor Misplon";
|
|
||||||
username = "hektor";
|
|
||||||
signingKey = "AEB98353B8D72E465C4236435151AF79E723F21C";
|
|
||||||
};
|
|
||||||
alias = {
|
|
||||||
d = "diff";
|
|
||||||
ds = "diff --staged";
|
|
||||||
a = "add";
|
|
||||||
ap = "add -p";
|
|
||||||
c = "commit";
|
|
||||||
cm = "commit -m";
|
|
||||||
cam = "commit --amend";
|
|
||||||
l = ''log --pretty=format:(%an)\ \ %h\ \ %ad\ \ %s --date=short'';
|
|
||||||
s = "status --short";
|
|
||||||
sv = "status --verbose";
|
|
||||||
co = "checkout";
|
|
||||||
cob = "checkout -b";
|
|
||||||
pullr = "pull --rebase --autostash";
|
|
||||||
pushf = "push --force-with-lease";
|
|
||||||
al = "!git config -l | grep alias | cut -c 7-";
|
|
||||||
alf = "!git config -l | grep alias | cut -c 7- | fzf";
|
|
||||||
"al-" =
|
|
||||||
''!git config --local --unset $(git config -l | grep alias | cut --delimiter="=" --fields=1 | fzf)'';
|
|
||||||
rs = "restore --staged";
|
|
||||||
rb = "rebase";
|
|
||||||
rbi = "rebase -i";
|
|
||||||
wt = "worktree";
|
|
||||||
wtc = ''config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"'';
|
|
||||||
};
|
|
||||||
color = {
|
|
||||||
ui = "auto";
|
|
||||||
diff = {
|
|
||||||
meta = "yellow bold";
|
|
||||||
commit = "green bold";
|
|
||||||
frag = "magenta bold";
|
|
||||||
old = "red bold";
|
|
||||||
new = "green bold";
|
|
||||||
whitespace = "red reverse";
|
|
||||||
};
|
|
||||||
"diff-highlight" = {
|
|
||||||
oldNormal = "red bold";
|
|
||||||
oldHighlight = "red bold 52";
|
|
||||||
newNormal = "green bold";
|
|
||||||
newHighlight = "green bold 22";
|
|
||||||
};
|
|
||||||
branch = {
|
|
||||||
current = "normal bold";
|
|
||||||
local = "normal";
|
|
||||||
remote = "normal italic";
|
|
||||||
};
|
|
||||||
status = {
|
|
||||||
added = "green";
|
|
||||||
changed = "yellow";
|
|
||||||
untracked = "normal italic";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
credential.helper = "cache --timeout=3600";
|
|
||||||
init.defaultBranch = "main";
|
|
||||||
log = {
|
|
||||||
date = "relative";
|
|
||||||
abbrevCommit = true;
|
|
||||||
};
|
|
||||||
merge.conflictStyle = "diff3";
|
|
||||||
diff.colorMoved = "zebra";
|
|
||||||
commit.gpgSign = false;
|
|
||||||
interactive.singleKey = true;
|
|
||||||
pull.rebase = true;
|
|
||||||
rerere.enabled = true;
|
|
||||||
}
|
|
||||||
(lib.mkIf config.nvim.enable {
|
|
||||||
core.editor = "nvim";
|
|
||||||
diff.tool = "nvimdiff";
|
|
||||||
merge.tool = "nvimdiff";
|
|
||||||
difftool.prompt = false;
|
|
||||||
mergetool = {
|
|
||||||
prompt = false;
|
|
||||||
keepBackup = false;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
includes = [
|
programs.git = {
|
||||||
{ path = personalEmail; }
|
enable = true;
|
||||||
|
settings = lib.mkMerge [
|
||||||
|
{
|
||||||
|
user = {
|
||||||
|
name = "Hektor Misplon";
|
||||||
|
username = "hektor";
|
||||||
|
signingKey = "AEB98353B8D72E465C4236435151AF79E723F21C";
|
||||||
|
};
|
||||||
|
alias = {
|
||||||
|
d = "diff";
|
||||||
|
ds = "diff --staged";
|
||||||
|
a = "add";
|
||||||
|
ap = "add -p";
|
||||||
|
c = "commit";
|
||||||
|
cm = "commit -m";
|
||||||
|
cam = "commit --amend";
|
||||||
|
l = ''log --pretty=format:(%an)\ \ %h\ \ %ad\ \ %s --date=short'';
|
||||||
|
s = "status --short";
|
||||||
|
sv = "status --verbose";
|
||||||
|
co = "checkout";
|
||||||
|
cob = "checkout -b";
|
||||||
|
pullr = "pull --rebase --autostash";
|
||||||
|
pushf = "push --force-with-lease";
|
||||||
|
al = "!git config -l | grep alias | cut -c 7-";
|
||||||
|
alf = "!git config -l | grep alias | cut -c 7- | fzf";
|
||||||
|
"al-" =
|
||||||
|
''!git config --local --unset $(git config -l | grep alias | cut --delimiter="=" --fields=1 | fzf)'';
|
||||||
|
rs = "restore --staged";
|
||||||
|
rb = "rebase";
|
||||||
|
rbi = "rebase -i";
|
||||||
|
wt = "worktree";
|
||||||
|
wtc = ''config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"'';
|
||||||
|
};
|
||||||
|
color = {
|
||||||
|
ui = "auto";
|
||||||
|
diff = {
|
||||||
|
meta = "yellow bold";
|
||||||
|
commit = "green bold";
|
||||||
|
frag = "magenta bold";
|
||||||
|
old = "red bold";
|
||||||
|
new = "green bold";
|
||||||
|
whitespace = "red reverse";
|
||||||
|
};
|
||||||
|
"diff-highlight" = {
|
||||||
|
oldNormal = "red bold";
|
||||||
|
oldHighlight = "red bold 52";
|
||||||
|
newNormal = "green bold";
|
||||||
|
newHighlight = "green bold 22";
|
||||||
|
};
|
||||||
|
branch = {
|
||||||
|
current = "normal bold";
|
||||||
|
local = "normal";
|
||||||
|
remote = "normal italic";
|
||||||
|
};
|
||||||
|
status = {
|
||||||
|
added = "green";
|
||||||
|
changed = "yellow";
|
||||||
|
untracked = "normal italic";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
credential.helper = "cache --timeout=3600";
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
log = {
|
||||||
|
date = "relative";
|
||||||
|
abbrevCommit = true;
|
||||||
|
};
|
||||||
|
merge.conflictStyle = "diff3";
|
||||||
|
diff.colorMoved = "zebra";
|
||||||
|
commit.gpgSign = false;
|
||||||
|
interactive.singleKey = true;
|
||||||
|
pull.rebase = true;
|
||||||
|
rerere.enabled = true;
|
||||||
|
}
|
||||||
|
(lib.mkIf config.nvim.enable {
|
||||||
|
core.editor = "nvim";
|
||||||
|
diff.tool = "nvimdiff";
|
||||||
|
merge.tool = "nvimdiff";
|
||||||
|
difftool.prompt = false;
|
||||||
|
mergetool = {
|
||||||
|
prompt = false;
|
||||||
|
keepBackup = false;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
includes =
|
||||||
|
lib.optional (config.secrets.templatePath ? ${emailTemplate "personal"}) {
|
||||||
|
path = config.secrets.templatePath.${emailTemplate "personal"};
|
||||||
|
}
|
||||||
|
++ [
|
||||||
{
|
{
|
||||||
condition = "gitdir:~/work/";
|
condition = "gitdir:~/work/";
|
||||||
contents = workSettings;
|
contents = workSettings;
|
||||||
@@ -175,7 +170,6 @@ in
|
|||||||
contentSuffix = "gitconfig-work";
|
contentSuffix = "gitconfig-work";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
);
|
|
||||||
}
|
}
|
||||||
@@ -2,24 +2,94 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
lib',
|
||||||
|
osConfig ? null,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.secrets;
|
||||||
|
sops = lib'.sopsAvailability config osConfig;
|
||||||
|
standalone = !sops.osAvailable;
|
||||||
|
|
||||||
|
sopsDir = "${toString inputs.nix-secrets}/secrets";
|
||||||
|
in
|
||||||
{
|
{
|
||||||
|
imports = [ ./vault.nix ];
|
||||||
|
|
||||||
options.secrets = {
|
options.secrets = {
|
||||||
enable = lib.mkEnableOption "secrets";
|
enable = lib.mkEnableOption "secrets";
|
||||||
|
vault.enable = lib.mkEnableOption "vault CLI";
|
||||||
|
|
||||||
vault = {
|
files = lib.mkOption {
|
||||||
enable = lib.mkEnableOption "vault CLI";
|
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
||||||
|
};
|
||||||
|
|
||||||
|
templates = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
path = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
content = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
path = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
templatePath = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
readOnly = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [ ./vault.nix ];
|
config = lib.mkMerge [
|
||||||
|
{
|
||||||
|
secrets.path = lib.optionalAttrs sops.available (
|
||||||
|
lib.mapAttrs (_: secret: secret.path) sops.secrets
|
||||||
|
);
|
||||||
|
|
||||||
config = lib.mkIf config.secrets.enable {
|
secrets.templatePath = lib.optionalAttrs sops.available (
|
||||||
home.packages = with pkgs; [
|
lib.mapAttrs (_: template: template.path) sops.templates
|
||||||
age
|
);
|
||||||
age-plugin-yubikey
|
}
|
||||||
sops
|
(lib.mkIf cfg.enable (
|
||||||
];
|
lib.optionalAttrs standalone {
|
||||||
};
|
sops = {
|
||||||
|
secrets = lib'.mkSopsSecrets sopsDir null cfg.files;
|
||||||
|
|
||||||
|
templates = lib.mapAttrs (
|
||||||
|
_: t:
|
||||||
|
{
|
||||||
|
inherit (t) content;
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (t.path != null) {
|
||||||
|
path = "${config.home.homeDirectory}/${t.path}";
|
||||||
|
}
|
||||||
|
) cfg.templates;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// {
|
||||||
|
home.packages = [
|
||||||
|
pkgs.age
|
||||||
|
pkgs.age-plugin-yubikey
|
||||||
|
pkgs.sops
|
||||||
|
];
|
||||||
|
|
||||||
|
warnings = lib.optional (
|
||||||
|
!sops.available && (cfg.files != { } || cfg.templates != { })
|
||||||
|
) "secrets declared, but sops unavailable.";
|
||||||
|
}
|
||||||
|
))
|
||||||
|
];
|
||||||
}
|
}
|
||||||
@@ -2,15 +2,11 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib',
|
|
||||||
osConfig ? null,
|
|
||||||
inputs ? null,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
sops = lib'.sopsAvailability config osConfig;
|
syncReady = config.secrets.templatePath ? "taskrc.d/sync";
|
||||||
standalone = osConfig == null;
|
|
||||||
|
|
||||||
syncHook = pkgs.writers.writePython3 "on-exit.sync.py" { flakeIgnore = [ "E501" ]; } ''
|
syncHook = pkgs.writers.writePython3 "on-exit.sync.py" { flakeIgnore = [ "E501" ]; } ''
|
||||||
# Source: <https://gist.github.com/danmou/83079feac22307813178d7f8c456c544>
|
# Source: <https://gist.github.com/danmou/83079feac22307813178d7f8c456c544>
|
||||||
@@ -61,111 +57,102 @@ in
|
|||||||
{
|
{
|
||||||
options.taskwarrior.enable = lib.mkEnableOption "taskwarrior";
|
options.taskwarrior.enable = lib.mkEnableOption "taskwarrior";
|
||||||
|
|
||||||
config = lib.mkIf config.taskwarrior.enable (
|
config = lib.mkIf config.taskwarrior.enable {
|
||||||
lib.optionalAttrs standalone {
|
secrets.files.taskwarrior = [
|
||||||
sops = {
|
"sync-server-url"
|
||||||
secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null {
|
"sync-server-client-id"
|
||||||
taskwarrior = [
|
"sync-encryption-secret"
|
||||||
"sync-server-url"
|
];
|
||||||
"sync-server-client-id"
|
|
||||||
"sync-encryption-secret"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
templates."taskrc.d/sync" = {
|
secrets.templates."taskrc.d/sync".content = ''
|
||||||
content = ''
|
sync.server.url=${config.sops.placeholder."taskwarrior/sync-server-url"}
|
||||||
sync.server.url=${config.sops.placeholder."taskwarrior/sync-server-url"}
|
sync.server.client_id=${config.sops.placeholder."taskwarrior/sync-server-client-id"}
|
||||||
sync.server.client_id=${config.sops.placeholder."taskwarrior/sync-server-client-id"}
|
sync.encryption_secret=${config.sops.placeholder."taskwarrior/sync-encryption-secret"}
|
||||||
sync.encryption_secret=${config.sops.placeholder."taskwarrior/sync-encryption-secret"}
|
'';
|
||||||
'';
|
|
||||||
};
|
warnings =
|
||||||
|
lib.optional (!syncReady)
|
||||||
|
"taskwarrior is enabled but its sync template is unavailable. taskwarrior sync will not be configured.";
|
||||||
|
|
||||||
|
home.file = {
|
||||||
|
".local/share/task/hooks/on-exit.sync.py".source = syncHook;
|
||||||
|
".local/share/task/scripts/sync-and-notify.sh".source = lib.getExe syncAndNotify;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.taskwarrior = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.taskwarrior3;
|
||||||
|
colorTheme = "dark-256";
|
||||||
|
config = {
|
||||||
|
# taskrc.d/aliases
|
||||||
|
"alias.a" = "add";
|
||||||
|
"alias.burndown" = "burndown.daily";
|
||||||
|
"alias.e" = "modify";
|
||||||
|
"alias.rm" = "delete";
|
||||||
|
|
||||||
|
# taskrc.d/colors
|
||||||
|
"color.active" = "bold white on black";
|
||||||
|
"color.alternate" = "";
|
||||||
|
"color.blocked" = "gray15";
|
||||||
|
"color.blocking" = "bold";
|
||||||
|
"color.due" = "";
|
||||||
|
"color.due.today" = "";
|
||||||
|
"color.overdue" = "";
|
||||||
|
"color.scheduled" = "";
|
||||||
|
"color.uda.priority.H" = "bold";
|
||||||
|
"color.uda.priority.L" = "";
|
||||||
|
"color.uda.priority.M" = "";
|
||||||
|
"color.until" = "";
|
||||||
|
|
||||||
|
# taskrc.d/contexts
|
||||||
|
"context.home.read" = "project:home";
|
||||||
|
"context.home.write" = "project:home";
|
||||||
|
"context.studies.read" = "project:studies";
|
||||||
|
"context.studies.write" = "project:studies";
|
||||||
|
"context.work.read" = "tags:work";
|
||||||
|
|
||||||
|
# taskrc.d/reports
|
||||||
|
"report.in.columns" = "id,description";
|
||||||
|
"report.in.description" = "Inbox (untagged)";
|
||||||
|
"report.in.filter" = "status:pending tags.none:";
|
||||||
|
"report.in.labels" = "ID,Description";
|
||||||
|
"report.in.sort" = "entry+";
|
||||||
|
"report.minimal.columns" = "id,description";
|
||||||
|
"report.minimal.labels" = ",";
|
||||||
|
"report.next.columns" =
|
||||||
|
"id,start.age,entry.age,depends,project,tags,scheduled.countdown,due.relative,until.remaining,description";
|
||||||
|
"report.next.filter" = "status:pending -WAITING -BLOCKED limit:page";
|
||||||
|
"report.next.labels" = "ID,Active,Age,Deps,Project,Tag,S,Due,Until,Description";
|
||||||
|
"report.recent.columns" = "id,description,entry";
|
||||||
|
"report.recent.description" = "Recently added";
|
||||||
|
"report.recent.labels" = "ID,Description,Age";
|
||||||
|
"report.recent.sort" = "entry+";
|
||||||
|
|
||||||
|
# taskrc.d/udas
|
||||||
|
"uda.url.label" = "URL";
|
||||||
|
"uda.url.type" = "string";
|
||||||
|
|
||||||
|
# taskrc.d/urgency
|
||||||
|
"urgency.uda.priority.L.coefficient" = "-1.0";
|
||||||
|
"urgency.user.project.admin.coefficient" = "1.0";
|
||||||
|
"urgency.user.project.creative.coefficient" = "0.0";
|
||||||
|
"urgency.user.project.groceries.coefficient" = "0.5";
|
||||||
|
"urgency.user.project.home.coefficient" = "0.2";
|
||||||
|
"urgency.user.project.personal.coefficient" = "0.5";
|
||||||
|
"urgency.user.project.side.coefficient" = "0.0";
|
||||||
|
"urgency.user.project.studies.coefficient" = "1.0";
|
||||||
|
|
||||||
|
# misc
|
||||||
|
"news.version" = "3.5.0";
|
||||||
|
"rc.json.array" = "on";
|
||||||
|
"rc.verbose" = "nothing";
|
||||||
|
"search.case.sensitive" = "no";
|
||||||
|
"recurrence" = "off";
|
||||||
|
"reserved.lines" = "3";
|
||||||
};
|
};
|
||||||
}
|
extraConfig = lib.optionalString syncReady ''
|
||||||
// {
|
include ${config.secrets.templatePath."taskrc.d/sync"}
|
||||||
warnings =
|
'';
|
||||||
lib.optional (!sops.available)
|
};
|
||||||
"taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured.";
|
};
|
||||||
|
|
||||||
home.file = {
|
|
||||||
".local/share/task/hooks/on-exit.sync.py".source = syncHook;
|
|
||||||
".local/share/task/scripts/sync-and-notify.sh".source = lib.getExe syncAndNotify;
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.taskwarrior = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.taskwarrior3;
|
|
||||||
colorTheme = "dark-256";
|
|
||||||
config = {
|
|
||||||
# taskrc.d/aliases
|
|
||||||
"alias.a" = "add";
|
|
||||||
"alias.burndown" = "burndown.daily";
|
|
||||||
"alias.e" = "modify";
|
|
||||||
"alias.rm" = "delete";
|
|
||||||
|
|
||||||
# taskrc.d/colors
|
|
||||||
"color.active" = "bold white on black";
|
|
||||||
"color.alternate" = "";
|
|
||||||
"color.blocked" = "gray15";
|
|
||||||
"color.blocking" = "bold";
|
|
||||||
"color.due" = "";
|
|
||||||
"color.due.today" = "";
|
|
||||||
"color.overdue" = "";
|
|
||||||
"color.scheduled" = "";
|
|
||||||
"color.uda.priority.H" = "bold";
|
|
||||||
"color.uda.priority.L" = "";
|
|
||||||
"color.uda.priority.M" = "";
|
|
||||||
"color.until" = "";
|
|
||||||
|
|
||||||
# taskrc.d/contexts
|
|
||||||
"context.home.read" = "project:home";
|
|
||||||
"context.home.write" = "project:home";
|
|
||||||
"context.studies.read" = "project:studies";
|
|
||||||
"context.studies.write" = "project:studies";
|
|
||||||
"context.work.read" = "tags:work";
|
|
||||||
|
|
||||||
# taskrc.d/reports
|
|
||||||
"report.in.columns" = "id,description";
|
|
||||||
"report.in.description" = "Inbox (untagged)";
|
|
||||||
"report.in.filter" = "status:pending tags.none:";
|
|
||||||
"report.in.labels" = "ID,Description";
|
|
||||||
"report.in.sort" = "entry+";
|
|
||||||
"report.minimal.columns" = "id,description";
|
|
||||||
"report.minimal.labels" = ",";
|
|
||||||
"report.next.columns" =
|
|
||||||
"id,start.age,entry.age,depends,project,tags,scheduled.countdown,due.relative,until.remaining,description";
|
|
||||||
"report.next.filter" = "status:pending -WAITING -BLOCKED limit:page";
|
|
||||||
"report.next.labels" = "ID,Active,Age,Deps,Project,Tag,S,Due,Until,Description";
|
|
||||||
"report.recent.columns" = "id,description,entry";
|
|
||||||
"report.recent.description" = "Recently added";
|
|
||||||
"report.recent.labels" = "ID,Description,Age";
|
|
||||||
"report.recent.sort" = "entry+";
|
|
||||||
|
|
||||||
# taskrc.d/udas
|
|
||||||
"uda.url.label" = "URL";
|
|
||||||
"uda.url.type" = "string";
|
|
||||||
|
|
||||||
# taskrc.d/urgency
|
|
||||||
"urgency.uda.priority.L.coefficient" = "-1.0";
|
|
||||||
"urgency.user.project.admin.coefficient" = "1.0";
|
|
||||||
"urgency.user.project.creative.coefficient" = "0.0";
|
|
||||||
"urgency.user.project.groceries.coefficient" = "0.5";
|
|
||||||
"urgency.user.project.home.coefficient" = "0.2";
|
|
||||||
"urgency.user.project.personal.coefficient" = "0.5";
|
|
||||||
"urgency.user.project.side.coefficient" = "0.0";
|
|
||||||
"urgency.user.project.studies.coefficient" = "1.0";
|
|
||||||
|
|
||||||
# misc
|
|
||||||
"news.version" = "3.5.0";
|
|
||||||
"rc.json.array" = "on";
|
|
||||||
"rc.verbose" = "nothing";
|
|
||||||
"search.case.sensitive" = "no";
|
|
||||||
"recurrence" = "off";
|
|
||||||
"reserved.lines" = "3";
|
|
||||||
};
|
|
||||||
extraConfig = lib.optionalString sops.available ''
|
|
||||||
include ${sops.templates."taskrc.d/sync".path}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ in
|
|||||||
sandboxing.enable = true;
|
sandboxing.enable = true;
|
||||||
secrets = {
|
secrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
nixSigningKey.enable = true;
|
nix = [ "signing-key" ];
|
||||||
};
|
};
|
||||||
ssh.enable = true;
|
ssh.enable = true;
|
||||||
storage.enable = true;
|
storage.enable = true;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ in
|
|||||||
wol.wakes = [ "andromache" ];
|
wol.wakes = [ "andromache" ];
|
||||||
zfs.enable = true;
|
zfs.enable = true;
|
||||||
|
|
||||||
secrets.nixSigningKey.enable = true;
|
secrets.nix = [ "signing-key" ];
|
||||||
restic-backup.enable = true;
|
restic-backup.enable = true;
|
||||||
tailscale.enable = true;
|
tailscale.enable = true;
|
||||||
desktop.ly.enable = true;
|
desktop.ly.enable = true;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
available = osSopsAvailable || hmSopsAvailable;
|
available = osSopsAvailable || hmSopsAvailable;
|
||||||
|
osAvailable = osSopsAvailable;
|
||||||
secrets = if osSopsAvailable then osConfig.sops.secrets else config.sops.secrets;
|
secrets = if osSopsAvailable then osConfig.sops.secrets else config.sops.secrets;
|
||||||
templates = if osSopsAvailable then osConfig.sops.templates else config.sops.templates;
|
templates = if osSopsAvailable then osConfig.sops.templates else config.sops.templates;
|
||||||
};
|
};
|
||||||
|
|||||||
+6
-12
@@ -9,21 +9,15 @@ in
|
|||||||
options.git.enable = lib.mkEnableOption "git";
|
options.git.enable = lib.mkEnableOption "git";
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
sops.templates = {
|
sops.templates = lib.genAttrs' [ "personal" "work" ] (
|
||||||
".gitconfig.email" = {
|
key:
|
||||||
|
lib.nameValuePair ".gitconfig.${key}.email" {
|
||||||
inherit owner;
|
inherit owner;
|
||||||
content = ''
|
content = ''
|
||||||
[user]
|
[user]
|
||||||
email = ${config.sops.placeholder."email/personal"}
|
email = ${config.sops.placeholder."email/${key}"}
|
||||||
'';
|
'';
|
||||||
};
|
}
|
||||||
".gitconfig.work.email" = {
|
);
|
||||||
inherit owner;
|
|
||||||
content = ''
|
|
||||||
[user]
|
|
||||||
email = ${config.sops.placeholder."email/work"}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -10,15 +10,14 @@
|
|||||||
let
|
let
|
||||||
cfg = config.secrets;
|
cfg = config.secrets;
|
||||||
inherit (config.host) username;
|
inherit (config.host) username;
|
||||||
inherit (cfg) sopsDir;
|
sopsDir = "${toString inputs.nix-secrets}/secrets";
|
||||||
owner = config.users.users.${username}.name;
|
owner = username;
|
||||||
|
|
||||||
system = {
|
system = {
|
||||||
email = [
|
email = [
|
||||||
"personal"
|
"personal"
|
||||||
"work"
|
"work"
|
||||||
];
|
];
|
||||||
nix = lib.optional cfg.nixSigningKey.enable "signing-key";
|
|
||||||
}
|
}
|
||||||
// lib.filterAttrs (_: lib.isList) cfg;
|
// lib.filterAttrs (_: lib.isList) cfg;
|
||||||
in
|
in
|
||||||
@@ -33,11 +32,6 @@ in
|
|||||||
options = {
|
options = {
|
||||||
enable = lib.mkEnableOption "secrets management";
|
enable = lib.mkEnableOption "secrets management";
|
||||||
|
|
||||||
sopsDir = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "${toString inputs.nix-secrets}/secrets";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = lib.mkOption {
|
user = lib.mkOption {
|
||||||
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
||||||
default = { };
|
default = { };
|
||||||
@@ -48,10 +42,6 @@ in
|
|||||||
default = owner;
|
default = owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixSigningKey = {
|
|
||||||
enable = lib.mkEnableOption "nix signing key configuration";
|
|
||||||
};
|
|
||||||
|
|
||||||
yubikey = {
|
yubikey = {
|
||||||
enable = lib.mkEnableOption "set up Yubikey";
|
enable = lib.mkEnableOption "set up Yubikey";
|
||||||
};
|
};
|
||||||
@@ -60,11 +50,9 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
sops = {
|
sops.secrets = lib'.mkSopsSecrets sopsDir null system // lib'.mkSopsSecrets sopsDir owner cfg.user;
|
||||||
secrets = lib'.mkSopsSecrets sopsDir null system // lib'.mkSopsSecrets sopsDir owner cfg.user;
|
|
||||||
};
|
|
||||||
|
|
||||||
nix.settings.secret-key-files = lib.mkIf cfg.nixSigningKey.enable [
|
nix.settings.secret-key-files = lib.mkIf (system ? nix) [
|
||||||
config.sops.secrets."nix/signing-key".path
|
config.sops.secrets."nix/signing-key".path
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user