Refactored modules, updated flake, added ci effects, and more.
Settei modules now should be reusable by others. Started migrating legion (home server) over to the new config. Added initial setup for hercules-ci. Updated all flake inputs.
This commit is contained in:
parent
ee7223ca36
commit
ef44ff6943
15 changed files with 466 additions and 169 deletions
5
effects.nix
Normal file
5
effects.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
hercules-ci = {
|
||||||
|
flake-update.enable = true;
|
||||||
|
};
|
||||||
|
}
|
261
flake.lock
generated
261
flake.lock
generated
|
@ -3,7 +3,7 @@
|
||||||
"agenix": {
|
"agenix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"darwin": [
|
"darwin": [
|
||||||
"darwin"
|
"darwin-old-for-agenix"
|
||||||
],
|
],
|
||||||
"home-manager": [
|
"home-manager": [
|
||||||
"home-manager"
|
"home-manager"
|
||||||
|
@ -13,11 +13,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1690228878,
|
"lastModified": 1694793763,
|
||||||
"narHash": "sha256-9Xe7JV0krp4RJC9W9W9WutZVlw6BlHTFMiUP/k48LQY=",
|
"narHash": "sha256-y6gTE1C9mIoSkymRYyzCmv62PFgy+hbZ5j8fuiQK5KI=",
|
||||||
"owner": "ryantm",
|
"owner": "ryantm",
|
||||||
"repo": "agenix",
|
"repo": "agenix",
|
||||||
"rev": "d8c973fd228949736dedf61b7f8cc1ece3236792",
|
"rev": "572baca9b0c592f71982fca0790db4ce311e3c75",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -26,24 +26,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"base16": {
|
|
||||||
"inputs": {
|
|
||||||
"fromYaml": "fromYaml"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1689633990,
|
|
||||||
"narHash": "sha256-iwvQg2Vx0IIDWZaKo8Xmzxlv1YPHg+Kp/QSv8dRv0RY=",
|
|
||||||
"owner": "SenchoPens",
|
|
||||||
"repo": "base16.nix",
|
|
||||||
"rev": "dddf2e1c04845d43c89a8e9e37d574519649a404",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "SenchoPens",
|
|
||||||
"repo": "base16.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"blobs": {
|
"blobs": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
@ -67,11 +49,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1692248770,
|
"lastModified": 1694497842,
|
||||||
"narHash": "sha256-tZeFpETKQGbgnaSIO1AGWD27IyTcBm4D+A9d7ulQ4NM=",
|
"narHash": "sha256-z03v/m0OwcLBok97KcUgMl8ZFw5Xwsi2z+n6nL7JdXY=",
|
||||||
"owner": "lnl7",
|
"owner": "lnl7",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "511177ffe8226c78c9cf6a92a7b5f2df3684956b",
|
"rev": "4496ab26628c5f43d2a5c577a06683c753e32fe2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -80,6 +62,25 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"darwin-old-for-agenix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689065945,
|
||||||
|
"narHash": "sha256-0LICmtzO3nkbeRCYdkzHCnEVjldSFiHMG56uA/W2BAE=",
|
||||||
|
"owner": "lnl7",
|
||||||
|
"repo": "nix-darwin",
|
||||||
|
"rev": "22620845fee1cc16f4ea639509c50fd989ccc1ce",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "lnl7",
|
||||||
|
"repo": "nix-darwin",
|
||||||
|
"rev": "22620845fee1cc16f4ea639509c50fd989ccc1ce",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"deploy-rs": {
|
"deploy-rs": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
|
@ -89,11 +90,11 @@
|
||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1686747123,
|
"lastModified": 1694513707,
|
||||||
"narHash": "sha256-XUQK9kwHpTeilHoad7L4LjMCCyY13Oq383CoFADecRE=",
|
"narHash": "sha256-wE5kHco3+FQjc+MwTPwLVqYz4hM7uno2CgXDXUFMCpc=",
|
||||||
"owner": "serokell",
|
"owner": "serokell",
|
||||||
"repo": "deploy-rs",
|
"repo": "deploy-rs",
|
||||||
"rev": "724463b5a94daa810abfc64a4f87faef4e00f984",
|
"rev": "31c32fb2959103a796e07bbe47e0a5e287c343a8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -109,11 +110,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693189188,
|
"lastModified": 1694763556,
|
||||||
"narHash": "sha256-o6otfsB/ecudboYFwiCeL49BX3/8vRC/XUZTgkaDx54=",
|
"narHash": "sha256-csMoysn8NrVAaPuhAB64nRd4CeH+yXEdFcYf04vFfw0=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "00169fe4a6015a88c3799f0bf89689e06a4d4896",
|
"rev": "8aa6ec5ff220f1d9749d636dbeb46ec929f112dc",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -154,22 +155,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat_3": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1673956053,
|
|
||||||
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
|
@ -177,11 +162,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1690933134,
|
"lastModified": 1693611461,
|
||||||
"narHash": "sha256-ab989mN63fQZBFrkk4Q8bYxQCktuHmBIBqUG1jl6/FQ=",
|
"narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "59cf3f1447cfc75087e7273b04b31e689a8599fb",
|
"rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -190,19 +175,84 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fromYaml": {
|
"flake-parts_2": {
|
||||||
"flake": false,
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"hercules-ci-effects",
|
||||||
|
"hercules-ci-agent",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1689549921,
|
"lastModified": 1688466019,
|
||||||
"narHash": "sha256-iX0pk/uB019TdBGlaJEWvBCfydT6sRq+eDcGPifVsCM=",
|
"narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
|
||||||
"owner": "SenchoPens",
|
"owner": "hercules-ci",
|
||||||
"repo": "fromYaml",
|
"repo": "flake-parts",
|
||||||
"rev": "11fbbbfb32e3289d3c631e0134a23854e7865c84",
|
"rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "SenchoPens",
|
"owner": "hercules-ci",
|
||||||
"repo": "fromYaml",
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"haskell-flake": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1684780604,
|
||||||
|
"narHash": "sha256-2uMZsewmRn7rRtAnnQNw1lj0uZBMh4m6Cs/7dV5YF08=",
|
||||||
|
"owner": "srid",
|
||||||
|
"repo": "haskell-flake",
|
||||||
|
"rev": "74210fa80a49f1b6f67223debdbf1494596ff9f2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "srid",
|
||||||
|
"ref": "0.3.0",
|
||||||
|
"repo": "haskell-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hercules-ci-agent": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts_2",
|
||||||
|
"haskell-flake": "haskell-flake",
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1688568579,
|
||||||
|
"narHash": "sha256-ON0M56wtY/TIIGPkXDlJboAmuYwc73Hi8X9iJGtxOhM=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "hercules-ci-agent",
|
||||||
|
"rev": "367dd8cd649b57009a6502e878005a1e54ad78c5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "hercules-ci-agent",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hercules-ci-effects": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": [
|
||||||
|
"flake-parts"
|
||||||
|
],
|
||||||
|
"hercules-ci-agent": "hercules-ci-agent",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689397210,
|
||||||
|
"narHash": "sha256-fVxZnqxMbsDkB4GzGAs/B41K0wt/e+B/fLxmTFF/S20=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "hercules-ci-effects",
|
||||||
|
"rev": "0a63bfa3f00a3775ea3a6722b247880f1ffe91ce",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "hercules-ci-effects",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -213,11 +263,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693399033,
|
"lastModified": 1694643239,
|
||||||
"narHash": "sha256-yXhiMo8MnE86sGtPIHAKaLHhmhe8v9tqGGotlUgKJvY=",
|
"narHash": "sha256-pv2k/5FvyirDE8g4TNehzwZ0T4UOMMmqWSQnM/luRtE=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "f5c15668f9842dd4d5430787d6aa8a28a07f7c10",
|
"rev": "d9b88b43524db1591fb3d9410a21428198d75d49",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -256,7 +306,7 @@
|
||||||
"flake-parts": [
|
"flake-parts": [
|
||||||
"flake-parts"
|
"flake-parts"
|
||||||
],
|
],
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1690830552,
|
"lastModified": 1690830552,
|
||||||
|
@ -274,18 +324,15 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1690753480,
|
"lastModified": 1687274257,
|
||||||
"narHash": "sha256-GQgPs8fCh/LsyQoYMUZgT2p7jFVWyHu9p+1Nl/dp8GY=",
|
"narHash": "sha256-TutzPriQcZ8FghDhEolnHcYU2oHIG5XWF+/SUBNnAOE=",
|
||||||
"owner": "nixos",
|
"path": "/nix/store/22qgs3skscd9bmrxv9xv4q5d4wwm5ppx-source",
|
||||||
"repo": "nixpkgs",
|
"rev": "2c9ecd1f0400076a4d6b2193ad468ff0a7e7fdc5",
|
||||||
"rev": "9e06dd56947c1dc3dc837c3149bfe02c71a6edd7",
|
"type": "path"
|
||||||
"type": "github"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"id": "nixpkgs",
|
||||||
"ref": "nixpkgs-unstable",
|
"type": "indirect"
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-22_11": {
|
"nixpkgs-22_11": {
|
||||||
|
@ -320,11 +367,43 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1693355128,
|
"lastModified": 1688322751,
|
||||||
"narHash": "sha256-+ZoAny3ZxLcfMaUoLVgL9Ywb/57wP+EtsdNGuXUJrwg=",
|
"narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1690753480,
|
||||||
|
"narHash": "sha256-GQgPs8fCh/LsyQoYMUZgT2p7jFVWyHu9p+1Nl/dp8GY=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a63a64b593dcf2fe05f7c5d666eb395950f36bc9",
|
"rev": "9e06dd56947c1dc3dc837c3149bfe02c71a6edd7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_4": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1694760568,
|
||||||
|
"narHash": "sha256-3G07BiXrp2YQKxdcdms22MUx6spc6A++MSePtatCYuI=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "46688f8eb5cd6f1298d873d4d2b9cf245e09e88e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -358,44 +437,20 @@
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"agenix": "agenix",
|
"agenix": "agenix",
|
||||||
"darwin": "darwin",
|
"darwin": "darwin",
|
||||||
|
"darwin-old-for-agenix": "darwin-old-for-agenix",
|
||||||
"deploy-rs": "deploy-rs",
|
"deploy-rs": "deploy-rs",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
|
"hercules-ci-effects": "hercules-ci-effects",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"mailserver": "mailserver",
|
"mailserver": "mailserver",
|
||||||
"niko-nur": "niko-nur",
|
"niko-nur": "niko-nur",
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs_4",
|
||||||
"racket": "racket",
|
"racket": "racket",
|
||||||
"stylix": "stylix",
|
|
||||||
"wrapper-manager": "wrapper-manager",
|
"wrapper-manager": "wrapper-manager",
|
||||||
"wrapper-manager-hm-compat": "wrapper-manager-hm-compat"
|
"wrapper-manager-hm-compat": "wrapper-manager-hm-compat"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"stylix": {
|
|
||||||
"inputs": {
|
|
||||||
"base16": "base16",
|
|
||||||
"flake-compat": "flake-compat_3",
|
|
||||||
"home-manager": [
|
|
||||||
"home-manager"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1691942466,
|
|
||||||
"narHash": "sha256-bK6FFbsKtyLKJLwgHerWp/EMMoWqE0UJk0KEbgYICbY=",
|
|
||||||
"owner": "danth",
|
|
||||||
"repo": "stylix",
|
|
||||||
"rev": "beb35709c9a769a5f279d3177af778a15dcbda46",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "danth",
|
|
||||||
"repo": "stylix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utils": {
|
"utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667395993,
|
"lastModified": 1667395993,
|
||||||
|
|
31
flake.nix
31
flake.nix
|
@ -8,11 +8,14 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
inputs.hercules-ci-effects.flakeModule
|
||||||
|
|
||||||
./assets
|
./assets
|
||||||
./hosts
|
./hosts
|
||||||
./modules
|
./modules
|
||||||
./wrappers
|
./wrappers
|
||||||
./deploy.nix
|
./deploy.nix
|
||||||
|
./effects.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
perSystem = {
|
perSystem = {
|
||||||
|
@ -21,7 +24,10 @@
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
devShells.default = pkgs.mkShellNoCC {
|
devShells.default = pkgs.mkShellNoCC {
|
||||||
packages = [inputs'.deploy-rs.packages.deploy-rs inputs'.agenix.packages.agenix];
|
packages = [
|
||||||
|
inputs'.deploy-rs.packages.deploy-rs
|
||||||
|
inputs'.agenix.packages.agenix
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
formatter = pkgs.alejandra;
|
formatter = pkgs.alejandra;
|
||||||
|
@ -58,11 +64,13 @@
|
||||||
url = "github:lnl7/nix-darwin";
|
url = "github:lnl7/nix-darwin";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
# agenix checks fail because of https://github.com/LnL7/nix-darwin/pull/687
|
||||||
|
darwin-old-for-agenix.url = "github:lnl7/nix-darwin/22620845fee1cc16f4ea639509c50fd989ccc1ce";
|
||||||
agenix = {
|
agenix = {
|
||||||
url = "github:ryantm/agenix";
|
url = "github:ryantm/agenix";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.follows = "nixpkgs";
|
nixpkgs.follows = "nixpkgs";
|
||||||
darwin.follows = "darwin";
|
darwin.follows = "darwin-old-for-agenix";
|
||||||
home-manager.follows = "home-manager";
|
home-manager.follows = "home-manager";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -81,17 +89,22 @@
|
||||||
home-manager.follows = "home-manager";
|
home-manager.follows = "home-manager";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
stylix = {
|
# stylix = {
|
||||||
url = "github:danth/stylix";
|
# url = "github:danth/stylix";
|
||||||
inputs = {
|
# inputs = {
|
||||||
nixpkgs.follows = "nixpkgs";
|
# nixpkgs.follows = "nixpkgs";
|
||||||
home-manager.follows = "home-manager";
|
# home-manager.follows = "home-manager";
|
||||||
};
|
# };
|
||||||
};
|
# };
|
||||||
racket = {
|
racket = {
|
||||||
url = "github:nrabulinski/racket.nix";
|
url = "github:nrabulinski/racket.nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
hercules-ci-effects = {
|
||||||
|
url = "github:hercules-ci/hercules-ci-effects";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.flake-parts.follows = "flake-parts";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
nixConfig = {
|
nixConfig = {
|
||||||
|
|
|
@ -7,50 +7,53 @@
|
||||||
}: {
|
}: {
|
||||||
builders = {
|
builders = {
|
||||||
nixos = name: module: let
|
nixos = name: module: let
|
||||||
combinedInputs = inputs // {settei = self;};
|
|
||||||
baseOptions = {
|
|
||||||
settei.flake-qol = {
|
|
||||||
enable = true;
|
|
||||||
inputs = combinedInputs;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
base = inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
modules = [
|
|
||||||
inputs.agenix.nixosModules.age
|
|
||||||
inputs.disko.nixosModules.disko
|
|
||||||
inputs.mailserver.nixosModules.default
|
|
||||||
self.nixosModules.settei
|
|
||||||
baseOptions
|
|
||||||
];
|
|
||||||
};
|
|
||||||
defaultOptions = {
|
defaultOptions = {
|
||||||
username,
|
username,
|
||||||
inputs',
|
inputs',
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
_file = ./default.nix;
|
||||||
|
|
||||||
settei = {
|
settei = {
|
||||||
username = lib.mkDefault "niko";
|
username = lib.mkDefault "niko";
|
||||||
sane-defaults.enable = lib.mkDefault true;
|
sane-defaults = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
allSshKeys = config.assets.sshKeys.user;
|
||||||
|
};
|
||||||
|
flake-qol = {
|
||||||
|
enable = true;
|
||||||
|
inputs = inputs // {settei = self;};
|
||||||
|
};
|
||||||
|
user = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
home.packages = lib.attrValues inputs'.settei.packages;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.${username}.packages = lib.attrValues inputs'.settei.packages;
|
time.timeZone = lib.mkDefault "Europe/Warsaw";
|
||||||
|
i18n.defaultLocale = lib.mkDefault "en_US.UTF-8";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
base.extendModules {
|
inputs.nixpkgs.lib.nixosSystem {
|
||||||
modules = [
|
modules = [
|
||||||
|
inputs.agenix.nixosModules.age
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
inputs.mailserver.nixosModules.default
|
||||||
|
inputs.home-manager.nixosModules.home-manager
|
||||||
|
self.nixosModules.settei
|
||||||
defaultOptions
|
defaultOptions
|
||||||
module
|
module
|
||||||
];
|
];
|
||||||
specialArgs = {
|
specialArgs.configurationName = name;
|
||||||
prev = base;
|
|
||||||
configurationName = name;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./kazuki
|
./kazuki
|
||||||
./hijiri-vm
|
./hijiri-vm
|
||||||
|
# ./legion
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,17 @@
|
||||||
username,
|
username,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
_file = ./default.nix;
|
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
"${modulesPath}/profiles/qemu-guest.nix"
|
"${modulesPath}/profiles/qemu-guest.nix"
|
||||||
./disks.nix
|
./disks.nix
|
||||||
];
|
];
|
||||||
boot = {
|
|
||||||
supportedFilesystems = ["btrfs"];
|
|
||||||
loader.systemd-boot.enable = true;
|
|
||||||
loader.systemd-boot.configurationLimit = 1;
|
|
||||||
loader.efi.canTouchEfiVariables = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
nixpkgs.system = "aarch64-linux";
|
nixpkgs.system = "aarch64-linux";
|
||||||
|
|
||||||
users.users.${username} = {
|
boot = {
|
||||||
openssh.authorizedKeys.keys = lib.attrValues config.assets.sshKeys.user;
|
loader.systemd-boot.enable = true;
|
||||||
|
loader.systemd-boot.configurationLimit = 1;
|
||||||
|
loader.efi.canTouchEfiVariables = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.domain = "hijiri";
|
networking.domain = "hijiri";
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
configurations.nixos.kazuki = {
|
configurations.nixos.kazuki = {
|
||||||
modulesPath,
|
modulesPath,
|
||||||
lib,
|
lib,
|
||||||
username,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -20,10 +19,7 @@
|
||||||
|
|
||||||
nixpkgs.system = "aarch64-linux";
|
nixpkgs.system = "aarch64-linux";
|
||||||
|
|
||||||
users.users.${username}.openssh.authorizedKeys.keys = lib.attrValues config.assets.sshKeys.user;
|
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
supportedFilesystems = ["btrfs"];
|
|
||||||
loader.systemd-boot.enable = true;
|
loader.systemd-boot.enable = true;
|
||||||
loader.systemd-boot.configurationLimit = 1;
|
loader.systemd-boot.configurationLimit = 1;
|
||||||
loader.efi.canTouchEfiVariables = true;
|
loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
36
hosts/legion/default.nix
Normal file
36
hosts/legion/default.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{config, ...}: let
|
||||||
|
inherit (config.assets) sshKeys;
|
||||||
|
in {
|
||||||
|
configurations.nixos.legion = {
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
./hardware.nix
|
||||||
|
# ./disks.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
nixpkgs.system = "x86_64-linux";
|
||||||
|
|
||||||
|
specialisation = {
|
||||||
|
nas.configuration = ./nas;
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||||
|
loader.systemd-boot.enable = true;
|
||||||
|
loader.efi.canTouchEfiVariables = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "legion";
|
||||||
|
hostId = builtins.substring 0 8 (builtins.readFile ./machine-id);
|
||||||
|
networkmanager.enable = true;
|
||||||
|
useDHCP = true;
|
||||||
|
firewall.trustedInterfaces = ["tailscale0"];
|
||||||
|
};
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = "performance";
|
||||||
|
};
|
||||||
|
}
|
10
hosts/legion/disks.nix
Normal file
10
hosts/legion/disks.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
args: let
|
||||||
|
bootDevice = args.bootDevice or "/dev/nvme0n1";
|
||||||
|
in {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = false;
|
||||||
|
message = "Disko config TODO";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
58
hosts/legion/hardware.nix
Normal file
58
hosts/legion/hardware.nix
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{...}: {
|
||||||
|
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "uas"];
|
||||||
|
boot.extraModulePackages = with config.boot.kernelPackages; [acpi_call];
|
||||||
|
boot.kernelModules = ["kvm-intel" "i2c-dev" "acpi_call"];
|
||||||
|
boot.blacklistedKernelModules = ["nouveau"];
|
||||||
|
|
||||||
|
hardware = {
|
||||||
|
enableAllFirmware = true;
|
||||||
|
cpu.intel.updateMicrocode = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.smartd.enable = true;
|
||||||
|
|
||||||
|
# TODO: Move to disko only
|
||||||
|
# TODO: Actually set up impermanence
|
||||||
|
boot.supportedFilesystems = ["btrfs"];
|
||||||
|
boot.initrd.luks.devices."enc".device = "/dev/disk/by-label/LUKS";
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-label/LINUX";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = ["subvol=root" "compress=zstd" "noatime"];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/home" = {
|
||||||
|
device = "/dev/disk/by-label/LINUX";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = ["subvol=home" "compress=zstd" "noatime"];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
device = "/dev/disk/by-label/LINUX";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = ["subvol=nix" "compress=zstd" "noatime"];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/persist" = {
|
||||||
|
device = "/dev/disk/by-label/LINUX";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = ["subvol=persist" "compress=zstd" "noatime"];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/log" = {
|
||||||
|
device = "/dev/disk/by-label/LINUX";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = ["subvol=log" "compress=zstd" "noatime"];
|
||||||
|
neededForBoot = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-label/BOOT";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [
|
||||||
|
{device = "/dev/disk/by-label/SWAP";}
|
||||||
|
];
|
||||||
|
}
|
33
hosts/legion/nas/default.nix
Normal file
33
hosts/legion/nas/default.nix
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
username,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [
|
||||||
|
./media.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.supportedFilesystems = ["zfs"];
|
||||||
|
|
||||||
|
boot.zfs.extraPools = ["yottapool"];
|
||||||
|
services.zfs = {
|
||||||
|
autoScrub.enable = true;
|
||||||
|
zed.settings = {
|
||||||
|
ZED_DEBUG_LOG = "/tmp/zed.debug.log";
|
||||||
|
ZED_EMAIL_ADDR = [username];
|
||||||
|
ZED_EMAIL_PROG = "${pkgs.msmtp}/bin/msmtp";
|
||||||
|
ZED_EMAIL_OPTS = "@ADDRESS@";
|
||||||
|
|
||||||
|
ZED_NOTIFY_INTERVAL_SECS = 3600;
|
||||||
|
ZED_NOTIFY_VERBOSE = true;
|
||||||
|
|
||||||
|
ZED_USE_ENCLOSURE_LEDS = true;
|
||||||
|
ZED_SCRUB_AFTER_RESILVER = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix-cache" = {
|
||||||
|
device = "/dev/disk/by-label/CACHE";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
}
|
18
hosts/legion/nas/media.nix
Normal file
18
hosts/legion/nas/media.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
services.jellyfin.enable = true;
|
||||||
|
services.radarr.enable = true;
|
||||||
|
services.sonarr.enable = true;
|
||||||
|
services.prowlarr.enable = true;
|
||||||
|
services.deluge = {
|
||||||
|
enable = true;
|
||||||
|
web.enable = true;
|
||||||
|
config.download_location = "/media/deluge";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = {
|
||||||
|
jellyfin.extraGroups = ["radarr" "sonarr"];
|
||||||
|
radarr.extraGroups = ["deluge"];
|
||||||
|
sonarr.extraGroups = ["deluge"];
|
||||||
|
niko.extraGroups = ["deluge"];
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,9 +3,12 @@
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
_file = ./default.nix;
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./sane-defaults.nix
|
./sane-defaults.nix
|
||||||
(import ./flake-qol.nix {inherit perInput;})
|
(import ./flake-qol.nix {inherit perInput;})
|
||||||
|
./user.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
options.settei = with lib; {
|
options.settei = with lib; {
|
||||||
|
|
|
@ -9,7 +9,7 @@ in {
|
||||||
_file = ./flake-qol.nix;
|
_file = ./flake-qol.nix;
|
||||||
|
|
||||||
options.settei.flake-qol = with lib; {
|
options.settei.flake-qol = with lib; {
|
||||||
enable = lib.mkEnableOption "QoL defaults when using flakes";
|
enable = mkEnableOption "QoL defaults when using flakes";
|
||||||
reexportAsArgs = mkOption {
|
reexportAsArgs = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
@ -27,19 +27,23 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = let
|
||||||
settei.flake-qol = {
|
reexportedArgs = lib.mkIf cfg.reexportAsArgs {
|
||||||
inputs-flakes = lib.filterAttrs (_: input: input ? flake -> input.flake) cfg.inputs;
|
|
||||||
inputs' = lib.mapAttrs (_: perInput pkgs.stdenv.system) cfg.inputs-flakes;
|
|
||||||
};
|
|
||||||
|
|
||||||
_module.args = lib.mkIf cfg.reexportAsArgs {
|
|
||||||
inherit (cfg) inputs inputs-flakes inputs';
|
inherit (cfg) inputs inputs-flakes inputs';
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
|
settei.flake-qol = {
|
||||||
|
inputs-flakes = lib.filterAttrs (_: input: input ? flake -> input.flake) cfg.inputs;
|
||||||
|
inputs' = lib.mapAttrs (_: perInput pkgs.stdenv.system) cfg.inputs-flakes;
|
||||||
|
};
|
||||||
|
|
||||||
nix = {
|
_module.args = reexportedArgs;
|
||||||
registry = lib.mapAttrs (_: flake: {inherit flake;}) cfg.inputs-flakes;
|
settei.user.extraArgs = reexportedArgs;
|
||||||
nixPath = map (name: "${name}=flake:${name}") (lib.attrNames cfg.inputs-flakes);
|
|
||||||
|
nix = {
|
||||||
|
registry = lib.mapAttrs (_: flake: {inherit flake;}) cfg.inputs-flakes;
|
||||||
|
nixPath = map (name: "${name}=flake:${name}") (lib.attrNames cfg.inputs-flakes);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# This module is supposed to be a reusable set of options you probably would want to set anyway
|
||||||
|
#
|
||||||
|
# Other default options which don't necessairly make sense for other people go into hosts/default.nix
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
|
@ -5,18 +8,28 @@
|
||||||
} @ args: {
|
} @ args: {
|
||||||
_file = ./sane-defaults.nix;
|
_file = ./sane-defaults.nix;
|
||||||
|
|
||||||
options.settei.sane-defaults = {
|
options.settei.sane-defaults = with lib; {
|
||||||
enable = lib.mkEnableOption "Personal sane defaults";
|
enable = mkEnableOption "Personal sane defaults (but they should make sense for anyone)";
|
||||||
|
allSshKeys = mkOption {
|
||||||
|
type = types.attrsOf types.singleLineStr;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf config.settei.sane-defaults.enable (let
|
config = lib.mkIf config.settei.sane-defaults.enable (let
|
||||||
cfg = config.settei;
|
cfg = config.settei;
|
||||||
inherit (cfg) username;
|
inherit (cfg) username;
|
||||||
|
configName = optionName:
|
||||||
|
args.configurationName
|
||||||
|
or (throw "pass configurationName to module arguments or set ${optionName} yourself");
|
||||||
in {
|
in {
|
||||||
_module.args = {
|
_module.args = {
|
||||||
username = lib.mkDefault username;
|
username = lib.mkDefault username;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/254807
|
||||||
|
boot.swraid.enable = false;
|
||||||
|
|
||||||
hardware.enableRedistributableFirmware = true;
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
|
@ -30,20 +43,23 @@
|
||||||
home = "/home/${username}";
|
home = "/home/${username}";
|
||||||
group = username;
|
group = username;
|
||||||
extraGroups = ["wheel"];
|
extraGroups = ["wheel"];
|
||||||
|
openssh.authorizedKeys.keys = let
|
||||||
|
filteredKeys = let
|
||||||
|
configName' = configName "users.users.${username}.openssh.authorizedKeys";
|
||||||
|
in
|
||||||
|
lib.filterAttrs (name: _: name != configName') cfg.sane-defaults.allSshKeys;
|
||||||
|
in
|
||||||
|
lib.mkDefault (lib.attrValues filteredKeys);
|
||||||
};
|
};
|
||||||
groups.${username} = {};
|
groups.${username} = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.hostName = lib.mkDefault (
|
networking.hostName = lib.mkDefault (configName "networking.hostName");
|
||||||
args.configurationName
|
|
||||||
or (throw "pass configurationName to module arguments or set networking.hostName yourself")
|
|
||||||
);
|
|
||||||
time.timeZone = lib.mkDefault "Europe/Warsaw";
|
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
settings = {
|
settings = {
|
||||||
experimental-features = ["nix-command" "flakes" "repl-flake" "auto-allocate-uids"];
|
experimental-features = ["nix-command" "flakes" "repl-flake" "auto-allocate-uids"];
|
||||||
trusted-users = [username];
|
trusted-users = lib.optionals (!config.security.sudo.wheelNeedsPassword) [username];
|
||||||
auto-allocate-uids = true;
|
auto-allocate-uids = true;
|
||||||
extra-substituters = [
|
extra-substituters = [
|
||||||
"https://hyprland.cachix.org"
|
"https://hyprland.cachix.org"
|
||||||
|
|
53
modules/nixos/settei/user.nix
Normal file
53
modules/nixos/settei/user.nix
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
options,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
hasHomeManager = options ? home-manager;
|
||||||
|
cfg = config.settei.user;
|
||||||
|
inherit (config.settei) username;
|
||||||
|
in {
|
||||||
|
_file = ./user.nix;
|
||||||
|
|
||||||
|
options.settei.user = with lib; {
|
||||||
|
enable = mkEnableOption "User-specific configuration";
|
||||||
|
config = mkOption {
|
||||||
|
type = types.deferredModule;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
extraArgs = mkOption {
|
||||||
|
type = types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
hmConfig = lib.optionalAttrs hasHomeManager {
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
home-manager.extraSpecialArgs = cfg.extraArgs;
|
||||||
|
|
||||||
|
home-manager.users.${username} = {
|
||||||
|
imports = [cfg.config];
|
||||||
|
|
||||||
|
home = {
|
||||||
|
inherit username;
|
||||||
|
homeDirectory = config.users.users.${username}.home;
|
||||||
|
stateVersion = config.system.stateVersion;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable ({
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = hasHomeManager;
|
||||||
|
message = "Home-manager module has to be imported before enabling settei.user";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// hmConfig);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue