Compare commits
No commits in common. "3350d19a45ba0b6da2daa3966b72bc33fc1ea15d" and "be1df0d8267c9fb22ae68609b0ecc01d261a91ca" have entirely different histories.
3350d19a45
...
be1df0d826
80 changed files with 543 additions and 464 deletions
62
flake.lock
generated
62
flake.lock
generated
|
|
@ -112,7 +112,7 @@
|
|||
"devshell_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
@ -198,7 +198,7 @@
|
|||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
@ -291,18 +291,18 @@
|
|||
"git-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"flake-compat"
|
||||
],
|
||||
"gitignore": "gitignore_2",
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
@ -346,7 +346,7 @@
|
|||
"gitignore_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"git-hooks",
|
||||
"nixpkgs"
|
||||
|
|
@ -411,7 +411,7 @@
|
|||
"home-manager_3": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
@ -448,7 +448,7 @@
|
|||
"nix-darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
@ -612,26 +612,6 @@
|
|||
}
|
||||
},
|
||||
"nixvim": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nixvim": "nixvim_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1723012155,
|
||||
"narHash": "sha256-7AlUEGsbIOCQmIRc+lH/k2CJ32pdEkFszyMekTOVoJc=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "e3dc3f07d69bcb0c9df5875aefd7dbf3877be794",
|
||||
"revCount": 14,
|
||||
"type": "git",
|
||||
"url": "https://git.sajenim.dev/jasmine/nvim.nix.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.sajenim.dev/jasmine/nvim.nix.git"
|
||||
}
|
||||
},
|
||||
"nixvim_2": {
|
||||
"inputs": {
|
||||
"devshell": "devshell_2",
|
||||
"flake-compat": "flake-compat_3",
|
||||
|
|
@ -657,11 +637,31 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixvim-config": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nixvim": "nixvim"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1723012155,
|
||||
"narHash": "sha256-7AlUEGsbIOCQmIRc+lH/k2CJ32pdEkFszyMekTOVoJc=",
|
||||
"ref": "refs/heads/master",
|
||||
"rev": "e3dc3f07d69bcb0c9df5875aefd7dbf3877be794",
|
||||
"revCount": 14,
|
||||
"type": "git",
|
||||
"url": "https://git.sajenim.dev/jasmine/nvim.nix.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://git.sajenim.dev/jasmine/nvim.nix.git"
|
||||
}
|
||||
},
|
||||
"nuschtosSearch": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_4",
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
@ -718,7 +718,7 @@
|
|||
"nix-minecraft": "nix-minecraft",
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"nixvim": "nixvim"
|
||||
"nixvim-config": "nixvim-config"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
|
@ -814,7 +814,7 @@
|
|||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixvim",
|
||||
"nixvim-config",
|
||||
"nixvim",
|
||||
"nixpkgs"
|
||||
]
|
||||
|
|
|
|||
147
flake.nix
147
flake.nix
|
|
@ -28,87 +28,84 @@
|
|||
|
||||
# Add any other flake you might need.
|
||||
nix-minecraft.url = "github:Infinidoge/nix-minecraft";
|
||||
nixvim.url = "git+https://git.sajenim.dev/jasmine/nvim.nix.git";
|
||||
nixvim-config.url = "git+https://git.sajenim.dev/jasmine/nvim.nix.git";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
home-manager,
|
||||
...
|
||||
} @ inputs: let
|
||||
inherit (self) outputs;
|
||||
# Supported systems for your flake packages, shell, etc.
|
||||
systems = [
|
||||
"aarch64-linux"
|
||||
"i686-linux"
|
||||
"x86_64-linux"
|
||||
"aarch64-darwin"
|
||||
"x86_64-darwin"
|
||||
];
|
||||
# This is a function that generates an attribute by calling a function you
|
||||
# pass to it, with each system as an argument
|
||||
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||
in {
|
||||
# Your custom packages
|
||||
# Acessible through 'nix build', 'nix shell', etc
|
||||
packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});
|
||||
# Formatter for your nix files, available through 'nix fmt'
|
||||
# Other options beside 'alejandra' include 'nixpkgs-fmt'
|
||||
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
outputs = { self, nixpkgs, home-manager, ... }@inputs:
|
||||
let
|
||||
inherit (self) outputs;
|
||||
# Supported systems for your flake packages, shell, etc.
|
||||
systems = [
|
||||
"aarch64-linux"
|
||||
"i686-linux"
|
||||
"x86_64-linux"
|
||||
"aarch64-darwin"
|
||||
"x86_64-darwin"
|
||||
];
|
||||
# This is a function that generates an attribute by calling a function you
|
||||
# pass to it, with each system as an argument
|
||||
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||
in
|
||||
{
|
||||
# Your custom packages
|
||||
# Acessible through 'nix build', 'nix shell', etc
|
||||
packages = forAllSystems (system: import ./pkgs nixpkgs.legacyPackages.${system});
|
||||
# Formatter for your nix files, available through 'nix fmt'
|
||||
# Other options beside 'alejandra' include 'nixpkgs-fmt'
|
||||
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
|
||||
# Your custom packages and modifications, exported as overlays
|
||||
overlays = import ./overlays {inherit inputs;};
|
||||
# Reusable nixos modules you might want to export
|
||||
# These are usually stuff you would upstream into nixpkgs
|
||||
nixosModules = import ./modules/nixos;
|
||||
# Reusable home-manager modules you might want to export
|
||||
# These are usually stuff you would upstream into home-manager
|
||||
homeManagerModules = import ./modules/home-manager;
|
||||
# Your custom packages and modifications, exported as overlays
|
||||
overlays = import ./overlays { inherit inputs; };
|
||||
# Reusable nixos modules you might want to export
|
||||
# These are usually stuff you would upstream into nixpkgs
|
||||
nixosModules = import ./modules/nixos;
|
||||
# Reusable home-manager modules you might want to export
|
||||
# These are usually stuff you would upstream into home-manager
|
||||
homeManagerModules = import ./modules/home-manager;
|
||||
|
||||
# Expose the necessary information in your flake so agenix-rekey
|
||||
# knows where it has too look for secrets and paths.
|
||||
agenix-rekey = inputs.agenix-rekey.configure {
|
||||
userFlake = self;
|
||||
nodes = self.nixosConfigurations;
|
||||
};
|
||||
|
||||
# NixOS configuration entrypoint
|
||||
# Available through 'nixos-rebuild --flake .#your-hostname'
|
||||
nixosConfigurations = {
|
||||
fuchsia = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = {inherit inputs outputs;};
|
||||
modules = [
|
||||
./nixos/fuchsia/configuration.nix
|
||||
];
|
||||
# Expose the necessary information in your flake so agenix-rekey
|
||||
# knows where it has too look for secrets and paths.
|
||||
agenix-rekey = inputs.agenix-rekey.configure {
|
||||
userFlake = self;
|
||||
nodes = self.nixosConfigurations;
|
||||
};
|
||||
|
||||
viridian = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = {inherit inputs outputs;};
|
||||
modules = [
|
||||
./nixos/viridian/configuration.nix
|
||||
];
|
||||
# NixOS configuration entrypoint
|
||||
# Available through 'nixos-rebuild --flake .#your-hostname'
|
||||
nixosConfigurations = {
|
||||
fuchsia = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs outputs; };
|
||||
modules = [
|
||||
./nixos/fuchsia/configuration.nix
|
||||
];
|
||||
};
|
||||
|
||||
viridian = nixpkgs.lib.nixosSystem {
|
||||
specialArgs = { inherit inputs outputs; };
|
||||
modules = [
|
||||
./nixos/viridian/configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Standalone home-manager configuration entrypoint
|
||||
# Available through 'home-manager --flake .#your-username@your-hostname'
|
||||
homeConfigurations = {
|
||||
"sajenim@fuchsia" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
extraSpecialArgs = { inherit inputs outputs; };
|
||||
modules = [
|
||||
./home-manager/sajenim/fuchsia.nix
|
||||
];
|
||||
};
|
||||
|
||||
"sajenim@viridian" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
extraSpecialArgs = { inherit inputs outputs; };
|
||||
modules = [
|
||||
./home-manager/sajenim/viridian.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Standalone home-manager configuration entrypoint
|
||||
# Available through 'home-manager --flake .#your-username@your-hostname'
|
||||
homeConfigurations = {
|
||||
"sajenim@fuchsia" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
extraSpecialArgs = {inherit inputs outputs;};
|
||||
modules = [
|
||||
./home-manager/sajenim/fuchsia.nix
|
||||
];
|
||||
};
|
||||
|
||||
"sajenim@viridian" = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
extraSpecialArgs = {inherit inputs outputs;};
|
||||
modules = [
|
||||
./home-manager/sajenim/viridian.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./git.nix
|
||||
./nvim.nix
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
lazygit
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
{ inputs, ... }:
|
||||
|
||||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
# Install our nixvim configuration for neovim.
|
||||
home.packages = [inputs.nixvim.packages.${pkgs.system}.default];
|
||||
home.packages = [ inputs.nixvim-config.packages.x86_64-linux.default ];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
fzf # command-line fuzzy finder
|
||||
];
|
||||
|
|
@ -22,10 +24,10 @@
|
|||
|
||||
# Aliases
|
||||
shellAliases = {
|
||||
c = "clear";
|
||||
r = "cd ~/.repositories";
|
||||
p = "cd ~/.print";
|
||||
d = "cd ~/.repositories/dotfiles.nix";
|
||||
c = "clear";
|
||||
r = "cd ~/.repositories";
|
||||
p = "cd ~/.print";
|
||||
d = "cd ~/.repositories/dotfiles.nix";
|
||||
la = "ls -a";
|
||||
ll = "ls -l";
|
||||
tt = "wezterm cli set-tab-title ";
|
||||
|
|
@ -64,3 +66,4 @@
|
|||
'';
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{pkgs, ...}: let
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
awesome = pkgs.awesome.overrideAttrs (oa: {
|
||||
version = "ad0290bc1aac3ec2391aa14784146a53ebf9d1f0";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
|
|
@ -8,18 +9,16 @@
|
|||
hash = "sha256-uaskBbnX8NgxrprI4UbPfb5cRqdRsJZv0YXXshfsxFU=";
|
||||
};
|
||||
|
||||
patches = [];
|
||||
patches = [ ];
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs tests/examples/_postprocess.lua
|
||||
'';
|
||||
});
|
||||
in {
|
||||
in
|
||||
{
|
||||
xdg.configFile = {
|
||||
awesome = {
|
||||
source = ./config;
|
||||
recursive = true;
|
||||
};
|
||||
awesome = { source = ./config; recursive = true; };
|
||||
};
|
||||
|
||||
xsession.windowManager.awesome = {
|
||||
|
|
@ -27,3 +26,4 @@ in {
|
|||
package = awesome;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
{ inputs, pkgs, ... }:
|
||||
|
||||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./discord
|
||||
./rofi
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
discord = prev.discord.override {withOpenASAR = true;};
|
||||
discord = prev.discord.override { withOpenASAR = true; };
|
||||
})
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
# protonmail-bridge requires password manager
|
||||
pass
|
||||
|
|
@ -113,3 +115,4 @@
|
|||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
weechat
|
||||
];
|
||||
|
|
@ -14,3 +16,4 @@
|
|||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.mpd = {
|
||||
enable = true;
|
||||
musicDirectory = "nfs://viridian.kanto.dev/srv/multimedia/library/music";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.picom = {
|
||||
enable = true;
|
||||
shadow = true;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.rofi = {
|
||||
enable = true;
|
||||
font = "Fisa Code 10";
|
||||
|
|
@ -14,3 +16,4 @@
|
|||
recursive = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home.packages = with pkgs.unstable; [
|
||||
wezterm
|
||||
];
|
||||
|
||||
xdg.configFile = {
|
||||
wezterm = {
|
||||
source = ./config;
|
||||
recursive = true;
|
||||
};
|
||||
wezterm = { source = ./config; recursive = true; };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./mangohud.nix
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.mangohud = {
|
||||
enable = true;
|
||||
package = pkgs.mangohud;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
home = {
|
||||
packages = with pkgs; [
|
||||
blender
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./global
|
||||
./features/desktop
|
||||
|
|
@ -49,3 +51,4 @@
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
inputs,
|
||||
outputs,
|
||||
...
|
||||
}: {
|
||||
{ inputs, outputs, ... }: {
|
||||
imports = [
|
||||
inputs.impermanence.nixosModules.home-manager.impermanence
|
||||
../features/cli
|
||||
|
|
@ -16,7 +12,7 @@
|
|||
];
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
allowUnfreePredicate = _: true;
|
||||
allowUnfreePredicate = (_: true);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./global
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Add your reusable home-manager modules to this directory, on their own file (https://nixos.wiki/wiki/Module).
|
||||
# These should be stuff you would like to share with others, not your personal configurations.
|
||||
|
||||
{
|
||||
# List your module files here
|
||||
# my-module = import ./my-module.nix;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Add your reusable NixOS modules to this directory, on their own file (https://nixos.wiki/wiki/Module).
|
||||
# These should be stuff you would like to share with others, not your personal configurations.
|
||||
|
||||
{
|
||||
# List your module files here
|
||||
# my-module = import ./my-module.nix;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
{ config, pkgs, inputs, ... }:
|
||||
let
|
||||
hostname = config.networking.hostName;
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
inputs.agenix.nixosModules.default
|
||||
inputs.agenix-rekey.nixosModules.default
|
||||
|
|
@ -23,7 +20,7 @@ in {
|
|||
# Pubkey for rekeying
|
||||
hostPubkey = ../../${hostname}/ssh_host_ed25519_key.pub;
|
||||
# Master identity used for decryption
|
||||
masterIdentities = [../users/sajenim/agenix-rekey.pub];
|
||||
masterIdentities = [ ../users/sajenim/agenix-rekey.pub ];
|
||||
# Where we store the rekeyed secrets
|
||||
storageMode = "local";
|
||||
localStorageDir = ./. + "/secrets/rekeyed/${config.networking.hostName}";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{outputs, ...}: {
|
||||
{ outputs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./age.nix
|
||||
./env.nix
|
||||
|
|
|
|||
|
|
@ -1,33 +1,35 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
environment = {
|
||||
binsh = "${pkgs.bash}/bin/bash";
|
||||
shells = with pkgs; [zsh];
|
||||
shells = with pkgs; [ zsh ];
|
||||
systemPackages = with pkgs; [
|
||||
# Ensure home-manager is on all systems
|
||||
home-manager
|
||||
|
||||
# Useful system utilities
|
||||
tree # directory structure
|
||||
bc # basic calculator
|
||||
vim # editor
|
||||
ranger # console file manager
|
||||
htop # system monitor
|
||||
scrot # screenshot
|
||||
direnv # load environment
|
||||
jq # JSON processor
|
||||
git # version control
|
||||
nmap # network mapper
|
||||
xclip # clipboard
|
||||
tree # directory structure
|
||||
bc # basic calculator
|
||||
vim # editor
|
||||
ranger # console file manager
|
||||
htop # system monitor
|
||||
scrot # screenshot
|
||||
direnv # load environment
|
||||
jq # JSON processor
|
||||
git # version control
|
||||
nmap # network mapper
|
||||
xclip # clipboard
|
||||
ripgrep # searches the current directory for a regex pattern
|
||||
|
||||
# HTTP
|
||||
curl # transfer dato to/from server
|
||||
wget # download files from web
|
||||
curl # transfer dato to/from server
|
||||
wget # download files from web
|
||||
|
||||
# Archive
|
||||
unrar # extract roshal archive
|
||||
unzip # extract zip archive
|
||||
unrar # extract roshal archive
|
||||
unzip # extract zip archive
|
||||
];
|
||||
pathsToLink = ["/share/zsh"];
|
||||
pathsToLink = [ "/share/zsh" ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
{ config, inputs, lib, ... }:
|
||||
|
||||
{
|
||||
config,
|
||||
inputs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
nix = {
|
||||
gc = {
|
||||
# Automatically run the garbage collector an a specified time.
|
||||
|
|
@ -14,7 +11,7 @@
|
|||
|
||||
# This will add each flake input as a registry
|
||||
# To make nix commands consistent with your flake
|
||||
registry = lib.mapAttrs (_: value: {flake = value;}) inputs;
|
||||
registry = lib.mapAttrs (_: value: { flake = value; }) inputs;
|
||||
|
||||
# This will additionally add your inputs to the system's legacy channels
|
||||
# Making legacy nix commands consistent as well, awesome!
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
|
@ -6,7 +8,7 @@
|
|||
PasswordAuthentication = false;
|
||||
LogLevel = "VERBOSE";
|
||||
};
|
||||
ports = [22];
|
||||
ports = [ 22 ];
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
hostname = config.networking.hostName;
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./persist.nix
|
||||
];
|
||||
|
|
@ -38,26 +36,26 @@ in {
|
|||
"/" = {
|
||||
device = "/dev/disk/by-label/${hostname}";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=root" "compress=zstd"];
|
||||
options = [ "subvol=root" "compress=zstd" ];
|
||||
};
|
||||
|
||||
"/nix" = {
|
||||
device = "/dev/disk/by-label/${hostname}";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=nix" "compress=zstd"];
|
||||
options = [ "subvol=nix" "compress=zstd" ];
|
||||
};
|
||||
|
||||
"/persist" = {
|
||||
device = "/dev/disk/by-label/${hostname}";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=persist" "compress=zstd"];
|
||||
options = [ "subvol=persist" "compress=zstd" ];
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
||||
"/swap" = {
|
||||
device = "/dev/disk/by-label/${hostname}";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=swap" "compress=zstd"];
|
||||
options = [ "subvol=swap" "compress=zstd" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
# Enables files to be encrypted to age identities stored on YubiKeys
|
||||
age-plugin-yubikey
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{inputs, ...}: {
|
||||
{ inputs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
{ inputs, outputs, pkgs, config, ... }:
|
||||
|
||||
{
|
||||
inputs,
|
||||
outputs,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
];
|
||||
users.users.sajenim = {
|
||||
isNormalUser = true;
|
||||
extraGroups = ["audio" "docker" "networkmanager" "wheel" "adbusers"];
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keyFiles = [
|
||||
"${inputs.self}/home-manager/sajenim/sajenim_sk.pub"
|
||||
];
|
||||
hashedPassword = "$y$j9T$qIhW5qL9J9w.w6JWa.bGo/$oddG3HJyOZ1mwHzYnYPJ/MzN38oHEBEvPDc0sB3rAf9";
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "audio" "docker" "networkmanager" "wheel" "adbusers" ];
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keyFiles = [
|
||||
"${inputs.self}/home-manager/sajenim/sajenim_sk.pub"
|
||||
];
|
||||
hashedPassword = "$y$j9T$qIhW5qL9J9w.w6JWa.bGo/$oddG3HJyOZ1mwHzYnYPJ/MzN38oHEBEvPDc0sB3rAf9";
|
||||
};
|
||||
users.mutableUsers = false;
|
||||
|
||||
home-manager = {
|
||||
extraSpecialArgs = {inherit inputs outputs;};
|
||||
extraSpecialArgs = { inherit inputs outputs; };
|
||||
users = {
|
||||
sajenim = import "${inputs.self}/home-manager/sajenim/${config.networking.hostName}.nix";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
{ pkgs, config, ... }:
|
||||
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
age.secrets.smb-secrets = {
|
||||
rekeyFile = ./smb-secrets.age;
|
||||
};
|
||||
|
||||
# For mount.cifs, required unless domain name resolution is not needed.
|
||||
environment.systemPackages = [pkgs.cifs-utils];
|
||||
environment.systemPackages = [ pkgs.cifs-utils ];
|
||||
|
||||
fileSystems."/home/sajenim/.backup" = {
|
||||
device = "//192.168.20.4/sajenim";
|
||||
|
|
@ -16,10 +14,12 @@
|
|||
options = let
|
||||
# this line prevents hanging on network split
|
||||
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s,user,users";
|
||||
in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"];
|
||||
|
||||
in ["${automount_opts},credentials=/etc/nixos/smb-secrets,uid=1000,gid=100"];
|
||||
};
|
||||
|
||||
environment.etc = {
|
||||
"nixos/smb-secrets".source = config.age.secrets.smb-secrets.path;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
fileSystems."/home/sajenim/.local/share/Steam" = {
|
||||
device = "/dev/disk/by-label/data";
|
||||
fsType = "btrfs";
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
{ inputs, pkgs, ... }:
|
||||
|
||||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
inputs.home-manager.nixosModules.home-manager
|
||||
];
|
||||
users.users.spectre = {
|
||||
isNormalUser = true;
|
||||
shell = pkgs.zsh;
|
||||
hashedPassword = "$y$j9T$eCJ0MDPsx3tww9LP0LU8..$sE8u5keO7QNKNAR1t2R6GqsDzvGD0Xn9Fi3to14Gf9/";
|
||||
isNormalUser = true;
|
||||
shell = pkgs.zsh;
|
||||
hashedPassword = "$y$j9T$eCJ0MDPsx3tww9LP0LU8..$sE8u5keO7QNKNAR1t2R6GqsDzvGD0Xn9Fi3to14Gf9/";
|
||||
};
|
||||
users.mutableUsers = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../common/global
|
||||
|
||||
|
|
@ -13,18 +15,18 @@
|
|||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
# Boot configuration
|
||||
/* Boot configuration */
|
||||
boot = {
|
||||
kernelPackages = pkgs.linuxPackages_latest;
|
||||
kernelParams = [
|
||||
# Enable amdgpu driver sysfs API that allows fine grain control of GPU
|
||||
"amdgpu.ppfeaturemask=0xffffffff"
|
||||
];
|
||||
kernelModules = ["i2c-dev" "i2c-piix4"];
|
||||
initrd.kernelModules = ["amdgpu"];
|
||||
kernelModules = [ "i2c-dev" "i2c-piix4" ];
|
||||
initrd.kernelModules = [ "amdgpu" ];
|
||||
};
|
||||
|
||||
# Hardware configuration
|
||||
/* Hardware configuration */
|
||||
hardware = {
|
||||
bluetooth = {
|
||||
enable = true;
|
||||
|
|
@ -47,7 +49,7 @@
|
|||
};
|
||||
};
|
||||
|
||||
# Networking configuration
|
||||
/* Networking configuration */
|
||||
networking = {
|
||||
hostName = "fuchsia";
|
||||
networkmanager.enable = true;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
../common/optional/ephemeral-btrfs.nix
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"];
|
||||
kernelModules = ["kvm-amd"];
|
||||
availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
|
||||
kernelModules = [ "kvm-amd" ];
|
||||
};
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
|
|
@ -27,9 +25,8 @@
|
|||
};
|
||||
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/swap/swapfile";
|
||||
size = 16 * 1024;
|
||||
{ device = "/swap/swapfile";
|
||||
size = 16*1024;
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
programs = {
|
||||
zsh.enable = true;
|
||||
# Load and unload environment variables.
|
||||
|
|
@ -7,3 +9,4 @@
|
|||
adb.enable = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
# Our custom power state
|
||||
environment.etc = {
|
||||
"default/amdgpu-custom-states.card0" = {
|
||||
|
|
@ -24,5 +26,6 @@
|
|||
};
|
||||
|
||||
# Install our overclocking script.
|
||||
environment.systemPackages = with pkgs; [amdgpu-clocks];
|
||||
environment.systemPackages = with pkgs; [ amdgpu-clocks ];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./amdgpu-clocks.nix
|
||||
./flatpak.nix
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
# Required to install flatpak
|
||||
xdg.portal = {
|
||||
enable = true;
|
||||
config.common.default = ["gtk"];
|
||||
extraPortals = [pkgs.xdg-desktop-portal-wlr];
|
||||
config.common.default = [ "gtk" ];
|
||||
extraPortals = [ pkgs.xdg-desktop-portal-wlr ];
|
||||
};
|
||||
|
||||
services.flatpak.enable = true;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.libinput = {
|
||||
enable = true;
|
||||
mouse = {accelProfile = "flat";};
|
||||
mouse = { accelProfile = "flat"; };
|
||||
};
|
||||
|
||||
# DBus daemon to configure input devices.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
# Get up and running with large language models locally.
|
||||
services.ollama = {
|
||||
enable = true;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
# Enable necessary udev rules.
|
||||
services.udev.packages = with pkgs; [
|
||||
openrgb
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
# Setup our display server
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
xkb.layout = "au";
|
||||
videoDrivers = ["amdgpu"];
|
||||
videoDrivers = [ "amdgpu" ];
|
||||
displayManager.startx.enable = true;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../common/global
|
||||
../common/users/sajenim
|
||||
|
|
@ -31,24 +33,24 @@
|
|||
enable = true;
|
||||
allowPing = true;
|
||||
allowedTCPPorts = [
|
||||
53 # adguardhome (DNS)
|
||||
80 # traefik (HTTP)
|
||||
443 # traefik (HTTPS)
|
||||
53 # adguardhome (DNS)
|
||||
80 # traefik (HTTP)
|
||||
443 # traefik (HTTPS)
|
||||
32372 # qbittorrent
|
||||
6600 # mpd
|
||||
6600 # mpd
|
||||
];
|
||||
allowedUDPPorts = [
|
||||
53 # adguardhome (DNS)
|
||||
80 # traefik (HTTP)
|
||||
443 # traefik (HTTPS)
|
||||
53 # adguardhome (DNS)
|
||||
80 # traefik (HTTP)
|
||||
443 # traefik (HTTPS)
|
||||
32372 # qbittorrent
|
||||
51820 # Wireguard
|
||||
6600 # mpd
|
||||
6600 # mpd
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
programs = {
|
||||
zsh.enable = true;
|
||||
};
|
||||
|
||||
|
|
@ -63,3 +65,4 @@
|
|||
# https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion
|
||||
system.stateVersion = "24.05";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./jellyfin.nix
|
||||
./jellyseerr.nix
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "8096";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# Volunteer-built media solution that puts you in control of your media
|
||||
jellyfin = {
|
||||
|
|
@ -33,7 +35,7 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.routers = {
|
||||
jellyfin = {
|
||||
rule = "Host(`jellyfin.kanto.dev`)";
|
||||
rule = "Host(`jellyfin.kanto.dev`)";
|
||||
entryPoints = [
|
||||
"websecure"
|
||||
];
|
||||
|
|
@ -46,7 +48,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
jellyfin.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "5055";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# Request management
|
||||
jellyseerr = {
|
||||
|
|
@ -37,7 +39,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
jellyseerr.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "8686";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# # Music collection manager for Usenet and BitTorrent users
|
||||
lidarr = {
|
||||
|
|
@ -40,7 +42,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
lidarr.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "9925";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
mealie = {
|
||||
autoStart = true;
|
||||
|
|
@ -27,7 +29,7 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.routers = {
|
||||
mealie = {
|
||||
rule = "Host(`mealie.kanto.dev`)";
|
||||
rule = "Host(`mealie.kanto.dev`)";
|
||||
entryPoints = [
|
||||
"websecure"
|
||||
];
|
||||
|
|
@ -41,7 +43,9 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
mealie.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
{config, ...}: let
|
||||
{ config, ... }:
|
||||
let
|
||||
port = "8181";
|
||||
in {
|
||||
in
|
||||
{
|
||||
age.secrets.microbin = {
|
||||
# Environment variables for microbin
|
||||
rekeyFile = ./environment.age;
|
||||
owner = "sajenim";
|
||||
group = "users";
|
||||
# Environment variables for microbin
|
||||
rekeyFile = ./environment.age;
|
||||
owner = "sajenim";
|
||||
group = "users";
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers = {
|
||||
|
|
@ -41,7 +43,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
microbin.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "9696";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# Indexer manager/proxy built on the popular arr .net/reactjs base stack to integrate with your various PVR apps.
|
||||
prowlarr = {
|
||||
|
|
@ -37,7 +39,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
prowlarr.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "8487";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# # Open-source software alternative to µTorrent
|
||||
qbittorrent = {
|
||||
autoStart = true;
|
||||
image = "ghcr.io/hotio/qbittorrent:release-4.6.5";
|
||||
ports = [
|
||||
"${port}:8080/tcp" # WebUI
|
||||
"32372:32372/tcp" # Transport protocol
|
||||
"${port}:8080/tcp" # WebUI
|
||||
"32372:32372/tcp" # Transport protocol
|
||||
];
|
||||
volumes = [
|
||||
# Seedbox
|
||||
|
|
@ -40,7 +42,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
qbittorrent.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "7878";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# Movie collection manager for Usenet and BitTorrent users
|
||||
radarr = {
|
||||
|
|
@ -39,7 +41,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
radarr.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# Automatically synchronize recommended settings from the TRaSH guides to your Sonarr/Radarr instances
|
||||
recyclarr = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{...}: let
|
||||
{ ... }:
|
||||
let
|
||||
port = "8989";
|
||||
in {
|
||||
in
|
||||
{
|
||||
virtualisation.oci-containers.containers = {
|
||||
# PVR for Usenet and BitTorrent users
|
||||
sonarr = {
|
||||
|
|
@ -40,7 +42,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
sonarr.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${port}";}
|
||||
{ url = "http://127.0.0.1:${port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
hostname = config.networking.hostName;
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
../common/optional/ephemeral-btrfs.nix
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"];
|
||||
kernelModules = ["kvm-intel"];
|
||||
availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
};
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
|
|
@ -36,31 +34,30 @@ in {
|
|||
fileSystems."/srv/containers" = {
|
||||
device = "/dev/disk/by-label/${hostname}";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=containers" "compress=zstd"];
|
||||
options = [ "subvol=containers" "compress=zstd" ];
|
||||
};
|
||||
|
||||
fileSystems."/srv/services" = {
|
||||
device = "/dev/disk/by-label/${hostname}";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=services" "compress=zstd"];
|
||||
options = [ "subvol=services" "compress=zstd" ];
|
||||
};
|
||||
|
||||
fileSystems."/srv/shares" = {
|
||||
device = "/dev/disk/by-label/data";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=shares" "compress=zstd"];
|
||||
options = [ "subvol=shares" "compress=zstd" ];
|
||||
};
|
||||
|
||||
fileSystems."/srv/backup" = {
|
||||
device = "/dev/disk/by-label/data";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=backup" "compress=zstd"];
|
||||
options = [ "subvol=backup" "compress=zstd" ];
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/swap/swapfile";
|
||||
size = 16 * 1024;
|
||||
{ device = "/swap/swapfile";
|
||||
size = 16*1024;
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.borgbackup.jobs = {
|
||||
containers = {
|
||||
paths = [
|
||||
|
|
@ -31,3 +33,4 @@
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
{
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
{ config, inputs, pkgs, ... }:
|
||||
let
|
||||
port = "8080";
|
||||
in {
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
inputs.crowdsec.nixosModules.crowdsec
|
||||
inputs.crowdsec.nixosModules.crowdsec-firewall-bouncer
|
||||
|
|
@ -89,12 +86,9 @@ in {
|
|||
|
||||
environment.persistence."/persist" = {
|
||||
directories = [
|
||||
{
|
||||
directory = "/var/lib/crowdsec";
|
||||
user = "crowdsec";
|
||||
group = "crowdsec";
|
||||
}
|
||||
{ directory = "/var/lib/crowdsec"; user = "crowdsec"; group = "crowdsec"; }
|
||||
];
|
||||
hideMounts = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./traefik
|
||||
./crowdsec
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{config, ...}: {
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
stateDir = "/srv/services/forgejo";
|
||||
|
|
@ -32,7 +34,8 @@
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
forgejo.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}";}
|
||||
{ url = "http://127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{config, ...}: {
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
# Setup grafana our grafana instance.
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
|
|
@ -22,15 +24,13 @@
|
|||
|
||||
# Setup our database for grafana.
|
||||
services.mysql = {
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "grafana";
|
||||
ensurePermissions = {
|
||||
"grafana.*" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
];
|
||||
ensureDatabases = ["grafana"];
|
||||
ensureUsers = [{
|
||||
name = "grafana";
|
||||
ensurePermissions = {
|
||||
"grafana.*" = "ALL PRIVILEGES";
|
||||
};
|
||||
}];
|
||||
ensureDatabases = [ "grafana" ];
|
||||
};
|
||||
|
||||
# Setup our traefik router.
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
# Setup our traefik service.
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
grafana.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}";}
|
||||
{ url = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{config, ...}: {
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.lighttpd = {
|
||||
enable = true;
|
||||
port = 5624;
|
||||
|
|
@ -21,7 +23,8 @@
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
lighttpd.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${toString config.services.lighttpd.port}";}
|
||||
{ url = "http://127.0.0.1:${toString config.services.lighttpd.port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ inputs, pkgs, lib, config, ... }:
|
||||
let
|
||||
modpack = pkgs.fetchPackwizModpack rec {
|
||||
version = "7091175a49";
|
||||
url = "https://git.sajenim.dev/jasmine/minecraft-modpack/raw/commit/${version}/pack.toml";
|
||||
|
|
@ -12,8 +7,9 @@
|
|||
};
|
||||
mcVersion = modpack.manifest.versions.minecraft;
|
||||
fabricVersion = modpack.manifest.versions.fabric;
|
||||
serverVersion = lib.replaceStrings ["."] ["_"] "fabric-${mcVersion}";
|
||||
in {
|
||||
serverVersion = lib.replaceStrings [ "." ] [ "_" ] "fabric-${mcVersion}";
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
inputs.nix-minecraft.nixosModules.minecraft-servers
|
||||
];
|
||||
|
|
@ -31,7 +27,7 @@ in {
|
|||
kanto = {
|
||||
enable = true;
|
||||
# The minecraft server package to use.
|
||||
package = pkgs.fabricServers.${serverVersion}.override {loaderVersion = fabricVersion;}; # Specific fabric loader version.
|
||||
package = pkgs.fabricServers.${serverVersion}.override { loaderVersion = fabricVersion; }; # Specific fabric loader version.
|
||||
|
||||
# Allowed players
|
||||
whitelist = {
|
||||
|
|
@ -53,7 +49,7 @@ in {
|
|||
|
||||
# Things to symlink into this server's data directory.
|
||||
symlinks = {
|
||||
"mods" = "${modpack}/mods";
|
||||
"mods" = "${modpack}/mods";
|
||||
};
|
||||
|
||||
# Things to copy into this server's data directory.
|
||||
|
|
@ -94,7 +90,8 @@ in {
|
|||
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
minecraft.loadBalancer.servers = [
|
||||
{url = "http://127.0.0.1:${toString config.services.minecraft-servers.servers.kanto.serverProperties.server-port}";}
|
||||
{ url = "http://127.0.0.1:${toString config.services.minecraft-servers.servers.kanto.serverProperties.server-port}"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.mpd = {
|
||||
enable = true;
|
||||
musicDirectory = "/srv/multimedia/library/music";
|
||||
|
|
@ -26,7 +28,7 @@
|
|||
};
|
||||
networking.firewall = {
|
||||
# # for NFSv3; view with `rpcinfo -p`
|
||||
allowedTCPPorts = [111 2049 4000 4001 4002 20048];
|
||||
allowedUDPPorts = [111 2049 4000 4001 4002 20048];
|
||||
allowedTCPPorts = [ 111 2049 4000 4001 4002 20048 ];
|
||||
allowedUDPPorts = [ 111 2049 4000 4001 4002 20048 ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
dataDir = "/srv/services/mysql";
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
{config, ...}: {
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = 9001; # Port to listen on.
|
||||
port = 9001; # Port to listen on.
|
||||
|
||||
# Valid in all configuration contexts, defaults for other configuration sections.
|
||||
globalConfig = {
|
||||
|
|
@ -12,7 +14,7 @@
|
|||
exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
enabledCollectors = ["systemd" "processes"];
|
||||
enabledCollectors = [ "systemd" "processes" ];
|
||||
port = 9100;
|
||||
};
|
||||
};
|
||||
|
|
@ -21,12 +23,11 @@
|
|||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "node";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["127.0.0.1:${toString config.services.prometheus.exporters.node.port}"];
|
||||
}
|
||||
];
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
|
||||
}];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.samba = {
|
||||
enable = true;
|
||||
securityType = "user";
|
||||
|
|
@ -45,5 +47,5 @@
|
|||
openFirewall = true;
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = ["/var/lib/samba"];
|
||||
environment.persistence."/persist".directories = [ "/var/lib/samba" ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
{ inputs, config, pkgs, ... }:
|
||||
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
disabledModules = ["services/web-servers/traefik.nix"];
|
||||
disabledModules = [ "services/web-servers/traefik.nix" ];
|
||||
|
||||
imports = [
|
||||
"${inputs.nixpkgs-unstable}/nixos/modules/services/web-servers/traefik.nix"
|
||||
|
|
@ -89,14 +86,12 @@
|
|||
# List of domains in our network
|
||||
domains = [
|
||||
# Internal services
|
||||
{
|
||||
main = "kanto.dev";
|
||||
sans = ["*.kanto.dev"];
|
||||
{ main = "kanto.dev";
|
||||
sans = [ "*.kanto.dev" ];
|
||||
}
|
||||
# Public services
|
||||
{
|
||||
main = "sajenim.dev";
|
||||
sans = ["*.sajenim.dev"];
|
||||
{ main = "sajenim.dev";
|
||||
sans = [ "*.sajenim.dev" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
@ -111,7 +106,7 @@
|
|||
metrics = {
|
||||
prometheus = {
|
||||
entryPoint = "metrics";
|
||||
buckets = ["0.1" "0.3" "1.2" "5.0"];
|
||||
buckets = [ "0.1" "0.3" "1.2" "5.0" ];
|
||||
addEntryPointsLabels = true;
|
||||
addRoutersLabels = true;
|
||||
addServicesLabels = true;
|
||||
|
|
@ -149,33 +144,20 @@
|
|||
services.prometheus.scrapeConfigs = [
|
||||
{
|
||||
job_name = "traefik";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["127.0.0.1:8082"];
|
||||
}
|
||||
];
|
||||
static_configs = [{
|
||||
targets = [ "127.0.0.1:8082" ];
|
||||
}];
|
||||
}
|
||||
];
|
||||
|
||||
# Persist our traefik data & logs
|
||||
environment.persistence."/persist" = {
|
||||
directories = [
|
||||
{
|
||||
directory = "/var/lib/traefik";
|
||||
user = "traefik";
|
||||
group = "traefik";
|
||||
}
|
||||
{
|
||||
directory = "/var/log/traefik";
|
||||
user = "traefik";
|
||||
group = "traefik";
|
||||
}
|
||||
{
|
||||
directory = "/plugins-storage";
|
||||
user = "traefik";
|
||||
group = "traefik";
|
||||
}
|
||||
{ directory = "/var/lib/traefik"; user = "traefik"; group = "traefik"; }
|
||||
{ directory = "/var/log/traefik"; user = "traefik"; group = "traefik"; }
|
||||
{ directory = "/plugins-storage"; user = "traefik"; group = "traefik"; }
|
||||
];
|
||||
hideMounts = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{config, ...}: {
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
# Crowdsec Local API key for the bouncer.
|
||||
age.secrets.traefik-bouncer-key = {
|
||||
rekeyFile = ../crowdsec/traefik-bouncer-key.age;
|
||||
|
|
@ -10,7 +12,7 @@
|
|||
services.traefik.dynamicConfigOptions.http.middlewares = {
|
||||
# Restrict access to internal networks
|
||||
internal.ipwhitelist.sourcerange = [
|
||||
"127.0.0.1/32" # localhost
|
||||
"127.0.0.1/32" # localhost
|
||||
"192.168.20.1/24" # lan
|
||||
];
|
||||
|
||||
|
|
@ -55,3 +57,4 @@
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.traefik.dynamicConfigOptions.http.routers = {
|
||||
traefik-dashboard = {
|
||||
rule = "Host(`traefik.kanto.dev`)";
|
||||
|
|
@ -23,3 +25,4 @@
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
{...}: {
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
services.traefik.dynamicConfigOptions.http.services = {
|
||||
ender1.loadBalancer.servers = [
|
||||
{url = "http://192.168.1.103:80";}
|
||||
{ url = "http://192.168.1.103:80"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# This file defines overlays
|
||||
{inputs, ...}: {
|
||||
{ inputs, ... }:
|
||||
|
||||
{
|
||||
# This one brings our custom packages from the 'pkgs' directory
|
||||
additions = final: _prev: import ../pkgs final.pkgs;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
{
|
||||
stdenv,
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
bash,
|
||||
subversion,
|
||||
makeWrapper,
|
||||
{ stdenv
|
||||
, lib
|
||||
, fetchFromGitHub
|
||||
, bash
|
||||
, subversion
|
||||
, makeWrapper
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "amdgpu-clocks";
|
||||
version = "973139a";
|
||||
src = fetchFromGitHub {
|
||||
# https://github.com/sibradzic/amdgpu-clocks
|
||||
owner = "sibradzic";
|
||||
repo = "amdgpu-clocks";
|
||||
rev = "973139a5933bd315aa99332b642305ef5ef49a32";
|
||||
sha256 = "sha256-mZV4ECNG9X6SDIWl6P0nHrxa4kGU1h/hFdMcswbEYrk=";
|
||||
};
|
||||
buildInputs = [bash subversion];
|
||||
nativeBuildInputs = [makeWrapper];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp amdgpu-clocks $out/bin/amdgpu-clocks
|
||||
wrapProgram $out/bin/amdgpu-clocks \
|
||||
--prefix PATH : ${lib.makeBinPath [bash subversion]}
|
||||
'';
|
||||
}
|
||||
stdenv.mkDerivation {
|
||||
pname = "amdgpu-clocks";
|
||||
version = "973139a";
|
||||
src = fetchFromGitHub {
|
||||
# https://github.com/sibradzic/amdgpu-clocks
|
||||
owner = "sibradzic";
|
||||
repo = "amdgpu-clocks";
|
||||
rev = "973139a5933bd315aa99332b642305ef5ef49a32";
|
||||
sha256 = "sha256-mZV4ECNG9X6SDIWl6P0nHrxa4kGU1h/hFdMcswbEYrk=";
|
||||
};
|
||||
buildInputs = [ bash subversion ];
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp amdgpu-clocks $out/bin/amdgpu-clocks
|
||||
wrapProgram $out/bin/amdgpu-clocks \
|
||||
--prefix PATH : ${lib.makeBinPath [ bash subversion ]}
|
||||
'';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
# Custom packages, that can be defined similarly to ones from nixpkgs
|
||||
# You can build them using 'nix build .#example'
|
||||
|
||||
pkgs: {
|
||||
xmobar = pkgs.callPackage ./xmobar-config {};
|
||||
xmonad = pkgs.callPackage ./xmonad-config {};
|
||||
amdgpu-clocks = pkgs.callPackage ./amdgpu-clocks {};
|
||||
xmobar = pkgs.callPackage ./xmobar-config { };
|
||||
xmonad = pkgs.callPackage ./xmonad-config { };
|
||||
amdgpu-clocks = pkgs.callPackage ./amdgpu-clocks { };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{pkgs}:
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.haskellPackages.developPackage {
|
||||
root = ./.;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs ? import <nixpkgs> {}}:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [cabal-install ghc];
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [ cabal-install ghc ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
{pkgs}:
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.haskellPackages.developPackage {
|
||||
root = ./.;
|
||||
source-overrides = {
|
||||
xmonad = builtins.fetchTarball {
|
||||
xmonad = (builtins.fetchTarball {
|
||||
url = "https://github.com/xmonad/xmonad/archive/refs/tags/v0.18.0.tar.gz";
|
||||
sha256 = "0jlc60n5jarcxgjxm1vcsgc3s2lwmn3c3n56hialhzx54wfskkbc";
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs ? import <nixpkgs> {}}:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [cabal-install ghc];
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [ cabal-install ghc ];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue