mirror of
https://github.com/kittywitch/nixfiles.git
synced 2026-02-10 04:49:19 -08:00
Apparently, depot could be stopped. Who knew?
This commit is contained in:
parent
c3fe9a355e
commit
b383c70492
196 changed files with 21 additions and 21 deletions
17
config/hosts/athame/meta.nix
Normal file
17
config/hosts/athame/meta.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{ config, lib, kw, ... }: with lib; {
|
||||
deploy.targets.infra = {
|
||||
tf = {
|
||||
resources.athame = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = head config.network.nodes.athame.services.openssh.ports;
|
||||
host = config.network.nodes.athame.network.addresses.public.ipv4.address;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
network.nodes.athame = {
|
||||
imports = kw.nodeImport "athame";
|
||||
};
|
||||
}
|
||||
107
config/hosts/athame/nixos.nix
Normal file
107
config/hosts/athame/nixos.nix
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
{ meta, config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
# Imports
|
||||
|
||||
imports = with meta; [
|
||||
profiles.hardware.hcloud-imperative
|
||||
users.kat.server
|
||||
users.kat.services.weechat
|
||||
services.fail2ban
|
||||
services.filehost
|
||||
services.gitea
|
||||
services.grafana
|
||||
services.logrotate
|
||||
services.loki
|
||||
services.mail
|
||||
services.matrix
|
||||
services.murmur
|
||||
services.netdata
|
||||
services.nginx
|
||||
services.node-exporter
|
||||
services.postgres
|
||||
services.prometheus
|
||||
services.promtail
|
||||
services.radicale
|
||||
services.restic
|
||||
services.syncplay
|
||||
services.taskserver
|
||||
services.vaultwarden
|
||||
services.website
|
||||
services.weechat
|
||||
services.xmpp
|
||||
services.znc
|
||||
];
|
||||
|
||||
# File Systems and Swap
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/sda1";
|
||||
fsType = "ext4";
|
||||
};
|
||||
};
|
||||
|
||||
# Bootloader
|
||||
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
version = 2;
|
||||
device = "/dev/sda";
|
||||
};
|
||||
|
||||
|
||||
# Networking
|
||||
|
||||
networking = {
|
||||
hostName = "athame";
|
||||
domain = "kittywit.ch";
|
||||
hostId = "7b0ac74e";
|
||||
useDHCP = false;
|
||||
interfaces = {
|
||||
enp1s0 = {
|
||||
useDHCP = true;
|
||||
ipv6.addresses = [{
|
||||
address = config.network.addresses.public.ipv6.address;
|
||||
prefixLength = 64;
|
||||
}];
|
||||
};
|
||||
};
|
||||
defaultGateway6 = {
|
||||
address = "fe80::1";
|
||||
interface = "enp1s0";
|
||||
};
|
||||
};
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
public = {
|
||||
enable = true;
|
||||
ipv4.address = "168.119.126.111";
|
||||
ipv6.address = "2a01:4f8:c2c:b7a8::1";
|
||||
};
|
||||
};
|
||||
yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "55e3f29c252d16e73ac849a6039824f94df1dee670c030b9e29f90584f935575";
|
||||
listen.enable = true;
|
||||
listen.endpoints = [ "tcp://${config.network.addresses.public.ipv4.address}:52969" "tcp://[${config.network.addresses.public.ipv6.address}]:52969" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
public = {
|
||||
interfaces = singleton "enp1s0";
|
||||
tcp.ports = singleton 52969;
|
||||
};
|
||||
private.interfaces = singleton "yggdrasil";
|
||||
};
|
||||
|
||||
# State
|
||||
system.stateVersion = "20.09";
|
||||
}
|
||||
|
||||
1
config/hosts/beltane/home.nix
Normal file
1
config/hosts/beltane/home.nix
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ ... }: { imports = [ ./home/sway.nix ]; }
|
||||
48
config/hosts/beltane/home/sway.nix
Normal file
48
config/hosts/beltane/home/sway.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
imports = [ ./swayidle.nix ];
|
||||
|
||||
wayland.windowManager.sway = {
|
||||
config =
|
||||
let
|
||||
lockCommand = "swaylock -i VGA-1:${builtins.elemAt config.kw.wallpapers 0} -s fill";
|
||||
cfg = config.wayland.windowManager.sway.config;
|
||||
in
|
||||
{
|
||||
#startup = [{ command = "${pkgs.ckb-next}/bin/ckb-next -b"; }];
|
||||
|
||||
output =
|
||||
let
|
||||
middle = {
|
||||
res = "1280x1024@75Hz";
|
||||
pos = "1920 0";
|
||||
};
|
||||
in
|
||||
{
|
||||
"VGA-1" = middle;
|
||||
};
|
||||
|
||||
keybindings = {
|
||||
"${cfg.modifier}+x" = "exec ${lockCommand}";
|
||||
};
|
||||
|
||||
modes = {
|
||||
"System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown" =
|
||||
{
|
||||
"l" = "exec ${lockCommand}, mode default";
|
||||
"e" = "exec swaymsg exit, mode default";
|
||||
"s" = "exec systemctl suspend, mode default";
|
||||
"h" = "exec systemctl hibernate, mode default";
|
||||
"r" = "exec systemctl reboot, mode default";
|
||||
"Shift+s" = "exec systemctl shutdown, mode default";
|
||||
"Return" = "mode default";
|
||||
"Escape" = "mode default";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
24
config/hosts/beltane/home/swayidle.nix
Normal file
24
config/hosts/beltane/home/swayidle.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
systemd.user.services.swayidle = {
|
||||
Unit = {
|
||||
Description = "swayidle";
|
||||
Documentation = [ "man:swayidle(1)" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = ''
|
||||
${pkgs.swayidle}/bin/swayidle -w \
|
||||
timeout 300 '${pkgs.swaylock}/bin/swaylock -f -i VGA-1:${builtins.elemAt config.kw.wallpapers 0} \
|
||||
timeout 600 'swaymsg "output * dpms off"' \
|
||||
resume 'swaymsg "output * dpms on"' \
|
||||
before-sleep '${pkgs.swaylock}/bin/swaylock -f -i VGA-1:${builtins.elemAt config.kw.wallpapers 0}'
|
||||
'';
|
||||
RestartSec = 3;
|
||||
Restart = "always";
|
||||
};
|
||||
Install = { WantedBy = [ "sway-session.target" ]; };
|
||||
};
|
||||
}
|
||||
20
config/hosts/beltane/meta.nix
Normal file
20
config/hosts/beltane/meta.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{ config, lib, kw, ... }: with lib; {
|
||||
config = {
|
||||
deploy.targets.beltane = {
|
||||
tf = {
|
||||
resources.beltane = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = head config.network.nodes.beltane.services.openssh.ports;
|
||||
host = config.network.nodes.beltane.network.addresses.private.ipv4.address;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
network.nodes.beltane = {
|
||||
imports = kw.nodeImport "beltane";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
129
config/hosts/beltane/nixos.nix
Normal file
129
config/hosts/beltane/nixos.nix
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
{ meta, tf, config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
# Imports
|
||||
|
||||
imports = with meta; [
|
||||
profiles.hardware.rm-310
|
||||
profiles.gui
|
||||
users.kat.guiFull
|
||||
services.fusionpbx
|
||||
services.jellyfin
|
||||
services.kattv-ingest
|
||||
services.promtail
|
||||
services.postgres
|
||||
services.netdata
|
||||
services.nfs
|
||||
services.nginx
|
||||
services.node-exporter
|
||||
services.transmission
|
||||
services.tvheadend
|
||||
services.zfs
|
||||
];
|
||||
|
||||
# File Systems and Swap
|
||||
|
||||
boot.supportedFilesystems = singleton "zfs";
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "zroot/safe/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/nix" = {
|
||||
device = "zroot/local/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/home" = {
|
||||
device = "zroot/safe/home";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/44CC-7137";
|
||||
fsType = "vfat";
|
||||
};
|
||||
"/boot-fallback" = {
|
||||
device = "/dev/disk/by-uuid/4520-4E5F";
|
||||
fsType = "vfat";
|
||||
};
|
||||
"/mnt/zraw" = {
|
||||
device = "zstore/raw";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/mnt/zenc" = {
|
||||
device = "zstore/enc";
|
||||
fsType = "zfs";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{ device = "/dev/disk/by-uuid/682df001-bad8-4d94-a86b-9068ce5eee4c"; }
|
||||
{ device = "/dev/disk/by-uuid/1ee2d322-235c-41de-b272-7ceded4e2624"; }
|
||||
];
|
||||
|
||||
# Bootloader
|
||||
|
||||
boot.loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
grub = {
|
||||
enable = true;
|
||||
efiSupport = true;
|
||||
device = "nodev";
|
||||
mirroredBoots = [
|
||||
{
|
||||
devices = [ "/dev/disk/by-uuid/4520-4E5F" ];
|
||||
path = "/boot-fallback";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Networking
|
||||
|
||||
networking = {
|
||||
hostName = "beltane";
|
||||
hostId = "3ef9a419";
|
||||
useDHCP = false;
|
||||
interfaces.eno1.ipv4.addresses = singleton {
|
||||
inherit (config.network.addresses.private.ipv4) address;
|
||||
prefixLength = 24;
|
||||
};
|
||||
defaultGateway = config.network.privateGateway;
|
||||
};
|
||||
|
||||
network = {
|
||||
extraCerts = {
|
||||
"private_root" = "altar.kittywit.ch";
|
||||
};
|
||||
addresses = {
|
||||
private = {
|
||||
ipv4.address = "192.168.1.2";
|
||||
# TODO ipv6.address
|
||||
};
|
||||
};
|
||||
yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "d3e488574367056d3ae809b678f799c29ebfd5c7151bb1f4051775b3953e5f52";
|
||||
listen.enable = false;
|
||||
listen.endpoints = [ "tcp://0.0.0.0:0" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
private.interfaces = singleton "yggdrasil";
|
||||
public.interfaces = singleton "eno1";
|
||||
};
|
||||
|
||||
# Yggdrasil
|
||||
|
||||
|
||||
# State
|
||||
|
||||
system.stateVersion = "21.05";
|
||||
|
||||
}
|
||||
|
||||
6
config/hosts/dummy/meta.nix
Normal file
6
config/hosts/dummy/meta.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{ config, lib, kw, ... }: with lib; {
|
||||
deploy.targets.dummy.enable = false;
|
||||
network.nodes.dummy = {
|
||||
imports = kw.nodeImport "dummy";
|
||||
};
|
||||
}
|
||||
48
config/hosts/dummy/nixos.nix
Normal file
48
config/hosts/dummy/nixos.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{ config, lib, pkgs, sources, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
hexchen = (import sources.hexchen) { };
|
||||
hexYgg = filterAttrs (_: c: c.enable)
|
||||
(mapAttrs (_: host: host.config.network.yggdrasil) hexchen.hosts);
|
||||
in
|
||||
{
|
||||
# stuff so dummy host is buildable (you probably don't want/need this???)
|
||||
# but idk your config sooooo
|
||||
boot.isContainer = true;
|
||||
networking.useDHCP = false;
|
||||
users.users.root.hashedPassword = "";
|
||||
|
||||
network.yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
listen.enable = true;
|
||||
listen.endpoints = flatten (map (c: c.listen.endpoints) (filter
|
||||
(c:
|
||||
c.listen.enable && (c.pubkey
|
||||
!= "0000000000000000000000000000000000000000000000000000000000000000"))
|
||||
(attrValues hexYgg)));
|
||||
extra.pubkeys = {
|
||||
satorin =
|
||||
"53d99a74a648ff7bd5bc9ba68ef4f472fb4fb8b2e26dfecea33c781f0d5c9525";
|
||||
shanghai =
|
||||
"0cc3c26366cbfddfb1534b25c5655733d8f429edc941bcce674c46566fc87027";
|
||||
grimoire =
|
||||
"2a1567a2848540070328c9e938c58d40f2b1a3f08982c15c7edc5dcabfde3330";
|
||||
boline =
|
||||
"89684441745467da0d1bf7f47dc74ec3ca65e05c72f752298ef3c22a22024d43";
|
||||
} // (mapAttrs (_: c: c.pubkey) hexYgg);
|
||||
};
|
||||
|
||||
# snippet for single host
|
||||
# hexchen.network = {
|
||||
# enable = true;
|
||||
# pubkey = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
# # if server, enable this and set endpoint:
|
||||
# listen.enable = false;
|
||||
# listen.endpoints = [
|
||||
# "tcp://0.0.0.0:0"
|
||||
# ];
|
||||
# };
|
||||
}
|
||||
19
config/hosts/ostara/meta.nix
Normal file
19
config/hosts/ostara/meta.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{ config, lib, kw, ... }: with lib; {
|
||||
config = {
|
||||
deploy.targets.ostara = {
|
||||
tf = {
|
||||
resources.ostara = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = head config.network.nodes.ostara.services.openssh.ports;
|
||||
host = config.network.nodes.ostara.network.addresses.private.ipv4.address;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
network.nodes.ostara = {
|
||||
imports = kw.nodeImport "ostara";
|
||||
};
|
||||
};
|
||||
}
|
||||
69
config/hosts/ostara/nixos.nix
Normal file
69
config/hosts/ostara/nixos.nix
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{ meta, config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
# Imports
|
||||
|
||||
imports = with meta; [
|
||||
profiles.hardware.eeepc-1015pem
|
||||
services.kattv
|
||||
];
|
||||
|
||||
# File Systems and Swap
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/469a684b-eb8f-48a8-8f98-be58528312c4";
|
||||
fsType = "ext4";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [{ device = "/dev/disk/by-uuid/2223e305-79c9-45b3-90d7-560dcc45775a"; }];
|
||||
|
||||
# Bootloader
|
||||
|
||||
boot.loader.grub = {
|
||||
enable = true;
|
||||
version = 2;
|
||||
device = "/dev/sda";
|
||||
};
|
||||
|
||||
# Hardware
|
||||
|
||||
services.logind.lidSwitchExternalPower = "ignore";
|
||||
|
||||
# Networking
|
||||
|
||||
networking = {
|
||||
hostName = "ostara";
|
||||
hostId = "9f89b327";
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0.ipv4.addresses = singleton {
|
||||
inherit (config.network.addresses.private.ipv4) address;
|
||||
prefixLength = 24;
|
||||
};
|
||||
defaultGateway = config.network.privateGateway;
|
||||
};
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
private = {
|
||||
ipv4.address = "192.168.1.32";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
public = {
|
||||
interfaces = singleton "enp1s0";
|
||||
tcp.ports = [ 9981 9982 ];
|
||||
};
|
||||
};
|
||||
|
||||
# State
|
||||
|
||||
system.stateVersion = "20.09";
|
||||
}
|
||||
1
config/hosts/samhain/home.nix
Normal file
1
config/hosts/samhain/home.nix
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ ... }: { imports = [ ./home/sway.nix ]; }
|
||||
83
config/hosts/samhain/home/sway.nix
Normal file
83
config/hosts/samhain/home/sway.nix
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
imports = [ ./swayidle.nix ];
|
||||
|
||||
wayland.windowManager.sway = {
|
||||
config =
|
||||
let
|
||||
lockCommand = "swaylock -i HDMI-A-1:${builtins.elemAt config.kw.wallpapers 0} -i DP-1:${builtins.elemAt config.kw.wallpapers 1} -i DVI-D-1:${builtins.elemAt config.kw.wallpapers 2} -s fill";
|
||||
cfg = config.wayland.windowManager.sway.config;
|
||||
in
|
||||
{
|
||||
#startup = [{ command = "${pkgs.ckb-next}/bin/ckb-next -b"; }];
|
||||
|
||||
output =
|
||||
let
|
||||
left = {
|
||||
res = "1920x1080";
|
||||
pos = "0 0";
|
||||
};
|
||||
middle = {
|
||||
res = "1920x1200";
|
||||
pos = "1920 0";
|
||||
};
|
||||
right = {
|
||||
res = "1920x1080";
|
||||
pos = "3840 0";
|
||||
};
|
||||
in
|
||||
{
|
||||
"DP-1" = right;
|
||||
"DVI-D-1" = middle;
|
||||
"HDMI-A-1" = left;
|
||||
};
|
||||
|
||||
keybindings = {
|
||||
"${cfg.modifier}+x" = "exec ${lockCommand}";
|
||||
};
|
||||
|
||||
modes = {
|
||||
"System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown" =
|
||||
{
|
||||
"l" = "exec ${lockCommand}, mode default";
|
||||
"e" = "exec swaymsg exit, mode default";
|
||||
"s" = "exec systemctl suspend, mode default";
|
||||
"h" = "exec systemctl hibernate, mode default";
|
||||
"r" = "exec systemctl reboot, mode default";
|
||||
"Shift+s" = "exec systemctl shutdown, mode default";
|
||||
"Return" = "mode default";
|
||||
"Escape" = "mode default";
|
||||
};
|
||||
};
|
||||
|
||||
input = {
|
||||
"5426:103:Razer_Razer_Naga_Trinity" = {
|
||||
accel_profile = "adaptive";
|
||||
pointer_accel = "-0.5";
|
||||
};
|
||||
"5824:1503:screenstub-tablet" = { events = "disabled"; };
|
||||
"5824:1503:screenstub-mouse" = { events = "disabled"; };
|
||||
"5824:1503:screenstub-kbd" = { events = "disabled"; };
|
||||
"1386:215:Wacom_BambooPT_2FG_Small_Pen" = {
|
||||
map_to_output = "HDMI-A-1";
|
||||
};
|
||||
"1386:215:Wacom_BambooPT_2FG_Small_Finger" = {
|
||||
natural_scroll = "enabled";
|
||||
middle_emulation = "enabled";
|
||||
tap = "enabled";
|
||||
dwt = "enabled";
|
||||
accel_profile = "flat";
|
||||
pointer_accel = "0.05";
|
||||
};
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
workspace "1" output "DP-1"
|
||||
workspace "11:F1" output "DVI-1"
|
||||
workspace "12:F2" output "HDMI-A-1"
|
||||
'';
|
||||
};
|
||||
}
|
||||
26
config/hosts/samhain/home/swayidle.nix
Normal file
26
config/hosts/samhain/home/swayidle.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
systemd.user.services.swayidle = {
|
||||
Unit = {
|
||||
Description = "swayidle";
|
||||
Documentation = [ "man:swayidle(1)" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = ''
|
||||
${pkgs.swayidle}/bin/swayidle -w \
|
||||
timeout 300 '${pkgs.swaylock}/bin/swaylock -f -i HDMI-A-1:${builtins.elemAt config.kw.wallpapers 0} -i DP-1:${builtins.elemAt config.kw.wallpapers 1} -i DVI-D-1:${builtins.elemAt config.kw.wallpapers 2}' \
|
||||
timeout 600 'swaymsg "output * dpms off"' \
|
||||
resume 'swaymsg "output * dpms on"' \
|
||||
before-sleep '${pkgs.swaylock}/bin/swaylock -f -i HDMI-A-1:${builtins.elemAt config.kw.wallpapers 0} -i DP-1:${builtins.elemAt config.kw.wallpapers 1} -i DVI-D-1:${builtins.elemAt config.kw.wallpapers 2}'
|
||||
'';
|
||||
RestartSec = 3;
|
||||
Restart = "always";
|
||||
};
|
||||
Install = { WantedBy = [ "sway-session.target" ]; };
|
||||
};
|
||||
}
|
||||
19
config/hosts/samhain/meta.nix
Normal file
19
config/hosts/samhain/meta.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{ config, lib, kw, ... }: with lib; {
|
||||
config = {
|
||||
deploy.targets.personal = {
|
||||
tf = {
|
||||
resources.samhain = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = head config.network.nodes.samhain.services.openssh.ports;
|
||||
host = config.network.nodes.samhain.network.addresses.private.ipv4.address;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
network.nodes.samhain = {
|
||||
imports = kw.nodeImport "samhain";
|
||||
};
|
||||
};
|
||||
}
|
||||
153
config/hosts/samhain/nixos.nix
Normal file
153
config/hosts/samhain/nixos.nix
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
{ meta, tf, config, pkgs, lib, sources, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
hexchen = (import sources.hexchen) { };
|
||||
hexYgg = filterAttrs (_: c: c.enable)
|
||||
(mapAttrs (_: host: host.config.network.yggdrasil) hexchen.hosts);
|
||||
in {
|
||||
# Imports
|
||||
|
||||
imports = with meta; [
|
||||
profiles.hardware.ms-7b86
|
||||
profiles.gui
|
||||
profiles.vfio
|
||||
users.kat.guiFull
|
||||
services.netdata
|
||||
services.nginx
|
||||
services.katsplash
|
||||
services.node-exporter
|
||||
services.promtail
|
||||
services.restic
|
||||
services.zfs
|
||||
];
|
||||
|
||||
# File Systems and Swap
|
||||
|
||||
boot.supportedFilesystems = [ "zfs" "xfs" ];
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "rpool/safe/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/nix" = {
|
||||
device = "rpool/local/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/home" = {
|
||||
device = "rpool/safe/home";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/AED6-D0D1";
|
||||
fsType = "vfat";
|
||||
};
|
||||
"/mnt/xstore" = {
|
||||
device = "/dev/disk/by-uuid/64269102-a278-4919-9118-34e37f4afdb0";
|
||||
fsType = "xfs";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{ device = "/dev/disk/by-uuid/89831a0f-93e6-4d30-85e4-09061259f140"; }
|
||||
{ device = "/dev/disk/by-uuid/8f944315-fe1c-4095-90ce-50af03dd5e3f"; }
|
||||
];
|
||||
|
||||
# Bootloader
|
||||
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
# Hardware
|
||||
|
||||
deploy.profile.hardware.acs-override = true;
|
||||
|
||||
hardware.openrazer = {
|
||||
enable = true;
|
||||
};
|
||||
environment.systemPackages = [ pkgs.razergenie ];
|
||||
|
||||
boot.modprobe.modules = {
|
||||
vfio-pci = let
|
||||
vfio-pci-ids = [
|
||||
"1002:67df" "1002:aaf0" # RX 580
|
||||
"1912:0014" # Renesas USB 3
|
||||
"1022:149c" # CPU USB 3
|
||||
];
|
||||
in mkIf (vfio-pci-ids != [ ]) {
|
||||
options.ids = concatStringsSep "," vfio-pci-ids;
|
||||
};
|
||||
};
|
||||
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="1532", ATTRS{idProduct}=="0067", GROUP="vfio"
|
||||
SUBSYSTEM=="block", ACTION=="add", ATTRS{model}=="HFS256G32TNF-N3A", ATTRS{wwid}=="t10.ATA HFS256G32TNF-N3A0A MJ8BN15091150BM1Z ", OWNER="kat"
|
||||
'';
|
||||
|
||||
# TODO: Replace this drive forward with one half of the 1.82TiB drive.
|
||||
# SUBSYSTEM=="block", ACTION=="add", ATTR{partition}=="2", ATTR{size}=="1953503232", ATTRS{wwid}=="naa.5000039fe6e8614e", OWNER="kat"
|
||||
|
||||
# Networking
|
||||
|
||||
networking = {
|
||||
hostName = "samhain";
|
||||
hostId = "617050fc";
|
||||
useDHCP = false;
|
||||
useNetworkd = true;
|
||||
firewall.allowPing = true;
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
networks.enp34s0 = {
|
||||
matchConfig.Name = "enp34s0";
|
||||
bridge = singleton "br";
|
||||
};
|
||||
networks.br = {
|
||||
matchConfig.Name = "br";
|
||||
address = singleton "${config.network.addresses.private.ipv4.address}/24" ;
|
||||
gateway = singleton config.network.privateGateway;
|
||||
};
|
||||
netdevs.br = {
|
||||
netdevConfig = {
|
||||
Name = "br";
|
||||
Kind = "bridge";
|
||||
MACAddress = "00:d8:61:c7:f4:9d";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.avahi.enable = true;
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
private = {
|
||||
ipv4.address = "192.168.1.1";
|
||||
};
|
||||
};
|
||||
dns.dynamic = true;
|
||||
yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "a7110d0a1dc9ec963d6eb37bb6922838b8088b53932eae727a9136482ce45d47";
|
||||
listen.enable = false;
|
||||
listen.endpoints = [ "tcp://0.0.0.0:0" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
public.interfaces = singleton "br";
|
||||
private = {
|
||||
interfaces = singleton "yggdrasil";
|
||||
};
|
||||
};
|
||||
|
||||
# State
|
||||
|
||||
system.stateVersion = "20.09";
|
||||
}
|
||||
|
||||
1
config/hosts/to-do/mabon/home/default.nix
Normal file
1
config/hosts/to-do/mabon/home/default.nix
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ ... }: { }
|
||||
21
config/hosts/to-do/mabon/meta.nix
Normal file
21
config/hosts/to-do/mabon/meta.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{ lib, config, ... }: with lib; {
|
||||
deploy.targets.mabon = {
|
||||
nodeNames = lib.singleton "mabon";
|
||||
tf = {
|
||||
resources.mabon = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = 62954;
|
||||
host = "192.168.1.119";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
network.nodes.mabon = {
|
||||
imports = lib.hostImport "mabon";
|
||||
networking = {
|
||||
hostName = "mabon";
|
||||
};
|
||||
};
|
||||
}
|
||||
29
config/hosts/to-do/mabon/nixos/default.nix
Normal file
29
config/hosts/to-do/mabon/nixos/default.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{ config, users, pkgs, profiles, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hw.nix
|
||||
profiles.gui
|
||||
profiles.fvwm
|
||||
profiles.laptop
|
||||
users.kairi.guiFull
|
||||
];
|
||||
|
||||
networking.wireless.interfaces = [ "wlp3s0" ];
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
boot.kernelPackages = pkgs.linuxPackages;
|
||||
boot.kernelModules = [ "wl" ];
|
||||
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
|
||||
|
||||
networking.hostId = "d199ad70";
|
||||
networking.hostName = "mabon";
|
||||
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces.enp1s0.useDHCP = false;
|
||||
networking.interfaces.wlp2s0.useDHCP = true;
|
||||
|
||||
system.stateVersion = "20.09";
|
||||
}
|
||||
38
config/hosts/to-do/mabon/nixos/hw.nix
Normal file
38
config/hosts/to-do/mabon/nixos/hw.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"uhci_hcd"
|
||||
"ehci_pci"
|
||||
"ahci"
|
||||
"firewire_ohci"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
"sdhci_pci"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" "wl" ];
|
||||
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/236f9363-19ee-46e3-8db4-5dd1e28b742d";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
boot.initrd.luks.devices."cryptroot".device =
|
||||
"/dev/disk/by-uuid/b0435b6c-fd76-44d0-8b63-2c2c059df814";
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/84FB-4F88";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[{ device = "/dev/disk/by-uuid/926c41d6-c06a-4dcc-b55d-f4cfaafe4bac"; }];
|
||||
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
}
|
||||
1
config/hosts/yule/home.nix
Normal file
1
config/hosts/yule/home.nix
Normal file
|
|
@ -0,0 +1 @@
|
|||
{ ... }: { imports = [ ./home/sway.nix ./home/base16.nix ]; }
|
||||
5
config/hosts/yule/home/base16.nix
Normal file
5
config/hosts/yule/home/base16.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
base16.alias.default = "atelier.atelier-cave-light";
|
||||
}
|
||||
51
config/hosts/yule/home/sway.nix
Normal file
51
config/hosts/yule/home/sway.nix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
imports = [ ./swayidle.nix ];
|
||||
|
||||
wayland.windowManager.sway.config =
|
||||
let
|
||||
lockCommand = "swaylock -i eDP-1:${builtins.elemAt config.kw.wallpapers 0} -s fill";
|
||||
cfg = config.wayland.windowManager.sway.config;
|
||||
in
|
||||
{
|
||||
output =
|
||||
let
|
||||
laptop = {
|
||||
res = "1920x1080";
|
||||
pos = "0 0";
|
||||
};
|
||||
in
|
||||
{ "eDP-1" = laptop; };
|
||||
|
||||
keybindings = {
|
||||
"${cfg.modifier}+x" = "exec ${lockCommand}";
|
||||
};
|
||||
|
||||
modes = {
|
||||
"System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown" =
|
||||
{
|
||||
"l" = "exec ${lockCommand}, mode default";
|
||||
"e" = "exec swaymsg exit, mode default";
|
||||
"s" = "exec systemctl suspend, mode default";
|
||||
"h" = "exec systemctl hibernate, mode default";
|
||||
"r" = "exec systemctl reboot, mode default";
|
||||
"Shift+s" = "exec systemctl shutdown, mode default";
|
||||
"Return" = "mode default";
|
||||
"Escape" = "mode default";
|
||||
};
|
||||
};
|
||||
|
||||
input = {
|
||||
"1739:33362:Synaptics_TM3336-002" = {
|
||||
dwt = "enabled";
|
||||
tap = "enabled";
|
||||
natural_scroll = "enabled";
|
||||
middle_emulation = "enabled";
|
||||
click_method = "clickfinger";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
26
config/hosts/yule/home/swayidle.nix
Normal file
26
config/hosts/yule/home/swayidle.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
systemd.user.services.swayidle = {
|
||||
Unit = {
|
||||
Description = "swayidle";
|
||||
Documentation = [ "man:swayidle(1)" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = ''
|
||||
${pkgs.swayidle}/bin/swayidle -w \
|
||||
timeout 300 '${pkgs.swaylock}/bin/swaylock -f -i eDP-1:${builtins.elemAt config.kw.wallpapers 0} \
|
||||
timeout 600 'swaymsg "output * dpms off"' \
|
||||
resume 'swaymsg "output * dpms on"' \
|
||||
before-sleep '${pkgs.swaylock}/bin/swaylock -f -i eDP-1:${builtins.elemAt config.kw.wallpapers 0}'
|
||||
'';
|
||||
RestartSec = 3;
|
||||
Restart = "always";
|
||||
};
|
||||
Install = { WantedBy = [ "sway-session.target" ]; };
|
||||
};
|
||||
}
|
||||
19
config/hosts/yule/meta.nix
Normal file
19
config/hosts/yule/meta.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{ config, lib, kw, ... }: with lib; {
|
||||
config = {
|
||||
deploy.targets.personal = {
|
||||
tf = {
|
||||
resources.yule = {
|
||||
provider = "null";
|
||||
type = "resource";
|
||||
connection = {
|
||||
port = head config.network.nodes.yule.services.openssh.ports;
|
||||
host = config.network.nodes.yule.network.addresses.private.ipv4.address;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
network.nodes.yule = {
|
||||
imports = kw.nodeImport "yule";
|
||||
};
|
||||
};
|
||||
}
|
||||
93
config/hosts/yule/nixos.nix
Normal file
93
config/hosts/yule/nixos.nix
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
{ meta, config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
# Imports
|
||||
|
||||
imports = with meta; [
|
||||
profiles.hardware.v330-14arr
|
||||
profiles.gui
|
||||
users.kat.guiFull
|
||||
services.netdata
|
||||
services.nginx
|
||||
services.node-exporter
|
||||
services.promtail
|
||||
services.restic
|
||||
services.zfs
|
||||
];
|
||||
|
||||
# File Systems and Swap
|
||||
|
||||
boot.supportedFilesystems = singleton "zfs";
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "rpool/safe/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/home" = {
|
||||
device = "rpool/safe/home";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/nix" = {
|
||||
device = "rpool/local/nix";
|
||||
fsType = "zfs";
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/2552-18F2";
|
||||
fsType = "vfat";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [{ device = "/dev/disk/by-uuid/87ff4f68-cc00-494e-8eba-050469c3bf03"; }];
|
||||
|
||||
# Bootloader
|
||||
|
||||
boot.loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
# Networking
|
||||
|
||||
networking = {
|
||||
hostId = "dddbb888";
|
||||
hostName = "yule";
|
||||
useDHCP = false;
|
||||
wireless.interfaces = singleton "wlp2s0";
|
||||
interfaces = {
|
||||
wlp2s0.ipv4.addresses = singleton {
|
||||
inherit (config.network.addresses.private.ipv4) address;
|
||||
prefixLength = 24;
|
||||
};
|
||||
};
|
||||
defaultGateway = config.network.privateGateway;
|
||||
};
|
||||
|
||||
network = {
|
||||
addresses = {
|
||||
private = {
|
||||
ipv4.address = "192.168.1.3";
|
||||
};
|
||||
};
|
||||
yggdrasil = {
|
||||
enable = true;
|
||||
pubkey = "9779fd6b5bdba6b9e0f53c96e141f4b11ce5ef749d1b9e77a759a3fdbd33a653";
|
||||
listen.enable = false;
|
||||
listen.endpoints = [ "tcp://0.0.0.0:0" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall
|
||||
|
||||
network.firewall = {
|
||||
public.interfaces = [ "enp1s0" "wlp2s0" ];
|
||||
private.interfaces = singleton "yggdrasil";
|
||||
};
|
||||
|
||||
# State
|
||||
|
||||
system.stateVersion = "20.09";
|
||||
}
|
||||
|
||||
15
config/modules/home/default.nix
Normal file
15
config/modules/home/default.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ sources, ... }:
|
||||
|
||||
{
|
||||
disabledModules = [ "programs/vim.nix" ];
|
||||
imports = [
|
||||
(import (sources.arcexprs + "/modules")).home-manager
|
||||
(import (sources.katexprs + "/modules")).home
|
||||
./vim.nix
|
||||
./fvwm.nix
|
||||
./deploy.nix
|
||||
./theme.nix
|
||||
./secrets.nix
|
||||
(sources.tf-nix + "/modules/home/secrets.nix")
|
||||
];
|
||||
}
|
||||
39
config/modules/home/deploy.nix
Normal file
39
config/modules/home/deploy.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* Provides in-scope TF config for home-manager.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy.tf;
|
||||
unmergedValues = types.mkOptionType {
|
||||
name = "unmergedValues";
|
||||
merge = loc: defs: map (def: def.value) defs;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
options.deploy.tf = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf unmergedValues;
|
||||
|
||||
options = {
|
||||
attrs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
out.set = mkOption { type = types.unspecified; };
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
config = {
|
||||
deploy.tf = {
|
||||
attrs = [ "out" "attrs" ];
|
||||
out.set = removeAttrs cfg cfg.attrs;
|
||||
};
|
||||
};
|
||||
}
|
||||
9
config/modules/home/fvwm.nix
Normal file
9
config/modules/home/fvwm.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.programs.fvwm = {
|
||||
enable = mkEnableOption "Enable FVWM";
|
||||
};
|
||||
}
|
||||
15
config/modules/home/secrets.nix
Normal file
15
config/modules/home/secrets.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.kw = {
|
||||
secrets = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
config = mkIf (config.kw.secrets != null) {
|
||||
deploy.tf.variables = genAttrs config.kw.secrets (n: { externalSecret = true; });
|
||||
};
|
||||
}
|
||||
32
config/modules/home/theme.nix
Normal file
32
config/modules/home/theme.nix
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* provides a central way to change the font my system uses.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.kw; in {
|
||||
options.kw = {
|
||||
wallpapers = mkOption {
|
||||
type = types.nullOr (types.listOf types.path);
|
||||
default = [ ../../users/kat/sway/wallpapers/left.jpg ../../users/kat/sway/wallpapers/main.png ../../users/kat/sway/wallpapers/right.jpg ];
|
||||
};
|
||||
|
||||
font = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "Cozette";
|
||||
};
|
||||
size = mkOption {
|
||||
type = types.float;
|
||||
default = 9.0;
|
||||
};
|
||||
size_css = mkOption {
|
||||
type = types.str;
|
||||
default = "${toString (cfg.font.size + 3)}px";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
201
config/modules/home/vim.nix
Normal file
201
config/modules/home/vim.nix
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* is from an unmerged PR from home-manager.
|
||||
|
||||
See: https://github.com/nix-community/home-manager/pull/1745
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.programs.vim;
|
||||
defaultPlugins = [ pkgs.vimPlugins.vim-sensible ];
|
||||
|
||||
knownSettings = {
|
||||
background = types.enum [ "dark" "light" ];
|
||||
backupdir = types.listOf types.str;
|
||||
copyindent = types.bool;
|
||||
directory = types.listOf types.str;
|
||||
expandtab = types.bool;
|
||||
hidden = types.bool;
|
||||
history = types.int;
|
||||
ignorecase = types.bool;
|
||||
modeline = types.bool;
|
||||
mouse = types.enum [ "n" "v" "i" "c" "h" "a" "r" ];
|
||||
mousefocus = types.bool;
|
||||
mousehide = types.bool;
|
||||
mousemodel = types.enum [ "extend" "popup" "popup_setpos" ];
|
||||
number = types.bool;
|
||||
relativenumber = types.bool;
|
||||
shiftwidth = types.int;
|
||||
smartcase = types.bool;
|
||||
tabstop = types.int;
|
||||
undodir = types.listOf types.str;
|
||||
undofile = types.bool;
|
||||
};
|
||||
|
||||
vimSettingsType = types.submodule {
|
||||
options =
|
||||
let
|
||||
opt = name: type:
|
||||
mkOption {
|
||||
type = types.nullOr type;
|
||||
default = null;
|
||||
visible = false;
|
||||
};
|
||||
in
|
||||
mapAttrs opt knownSettings;
|
||||
};
|
||||
|
||||
setExpr = name: value:
|
||||
let
|
||||
v =
|
||||
if isBool value then
|
||||
(if value then "" else "no") + name
|
||||
else
|
||||
"${name}=${
|
||||
if isList value then concatStringsSep "," value else toString value
|
||||
}";
|
||||
in
|
||||
optionalString (value != null) ("set " + v);
|
||||
|
||||
plugins =
|
||||
let
|
||||
vpkgs = pkgs.vimPlugins;
|
||||
getPkg = p:
|
||||
if isDerivation p then
|
||||
[ p ]
|
||||
else
|
||||
optional (isString p && hasAttr p vpkgs) vpkgs.${p};
|
||||
in
|
||||
concatMap getPkg cfg.plugins;
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
programs.vim = {
|
||||
enable = mkEnableOption "Vim";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.vim_configurable;
|
||||
defaultText = literalExample "pkgs.vim_configurable";
|
||||
description = "The package to use for the vim binary.";
|
||||
};
|
||||
|
||||
finalPackage = mkOption {
|
||||
type = types.package;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
description = "Resulting customized vim package.";
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
type = with types; listOf (either str package);
|
||||
default = defaultPlugins;
|
||||
example = literalExample "[ pkgs.vimPlugins.YankRing ]";
|
||||
description = ''
|
||||
List of vim plugins to install. To get a list of supported plugins run:
|
||||
<command>nix-env -f '<nixpkgs>' -qaP -A vimPlugins</command>.
|
||||
|
||||
</para><para>
|
||||
|
||||
Note: String values are deprecated, please use actual packages.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = vimSettingsType;
|
||||
default = { };
|
||||
example = literalExample ''
|
||||
{
|
||||
expandtab = true;
|
||||
history = 1000;
|
||||
background = "dark";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
At attribute set of Vim settings. The attribute names and
|
||||
corresponding values must be among the following supported
|
||||
options.
|
||||
|
||||
<informaltable frame="none"><tgroup cols="1"><tbody>
|
||||
${concatStringsSep "\n" (mapAttrsToList (n: v: ''
|
||||
<row>
|
||||
<entry><varname>${n}</varname></entry>
|
||||
<entry>${v.description}</entry>
|
||||
</row>
|
||||
'') knownSettings)}
|
||||
</tbody></tgroup></informaltable>
|
||||
|
||||
See the Vim documentation for detailed descriptions of these
|
||||
options. Note, use <varname>extraConfig</varname> to
|
||||
manually set any options not listed above.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
set nocompatible
|
||||
set nobackup
|
||||
'';
|
||||
description = "Custom .vimrc lines";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = (
|
||||
let
|
||||
customRC = ''
|
||||
${concatStringsSep "\n" (filter (v: v != "") (mapAttrsToList setExpr
|
||||
(builtins.intersectAttrs knownSettings cfg.settings)))}
|
||||
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
vim = cfg.package.customize {
|
||||
name = "vim";
|
||||
vimrcConfig = {
|
||||
inherit customRC;
|
||||
|
||||
packages.home-manager.start = plugins;
|
||||
};
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
assertions =
|
||||
let
|
||||
packagesNotFound =
|
||||
filter (p: isString p && (!hasAttr p pkgs.vimPlugins)) cfg.plugins;
|
||||
in
|
||||
[{
|
||||
assertion = packagesNotFound == [ ];
|
||||
message = "Following VIM plugin not found in pkgs.vimPlugins: ${
|
||||
concatMapStringsSep ", " (p: ''"${p}"'') packagesNotFound
|
||||
}";
|
||||
}];
|
||||
|
||||
warnings =
|
||||
let stringPlugins = filter isString cfg.plugins;
|
||||
in
|
||||
optional (stringPlugins != [ ]) ''
|
||||
Specifying VIM plugins using strings is deprecated, found ${
|
||||
concatMapStringsSep ", " (p: ''"${p}"'') stringPlugins
|
||||
} as strings.
|
||||
'';
|
||||
|
||||
home.packages = [ cfg.finalPackage ];
|
||||
|
||||
programs.vim = {
|
||||
finalPackage = vim;
|
||||
plugins = defaultPlugins;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
9
config/modules/meta/default.nix
Normal file
9
config/modules/meta/default.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./imports.nix
|
||||
./deploy.nix
|
||||
./network.nix
|
||||
];
|
||||
}
|
||||
122
config/modules/meta/deploy.nix
Normal file
122
config/modules/meta/deploy.nix
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
{ sources, config, pkgs, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* makes tf-nix a part of the meta config
|
||||
* handles the trusted import for tf-nix
|
||||
* provides the target interface
|
||||
* imports the per-host TF config for each target
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy;
|
||||
meta = config;
|
||||
tfModule = { lib, ... }: with lib; {
|
||||
config._module.args = {
|
||||
pkgs = mkDefault pkgs;
|
||||
};
|
||||
};
|
||||
tfType = types.submoduleWith {
|
||||
modules = [
|
||||
tfModule
|
||||
"${toString sources.tf-nix}/modules"
|
||||
./secrets.nix
|
||||
];
|
||||
};
|
||||
in {
|
||||
imports = [
|
||||
(toString (sources.tf-nix + "/modules/run.nix"))
|
||||
] ++ (optional (builtins.pathExists ../../trusted/tf/tf.nix) (../../trusted/tf/tf.nix));
|
||||
options = {
|
||||
deploy = {
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
};
|
||||
local = {
|
||||
isRoot = mkOption {
|
||||
type = types.bool;
|
||||
default = builtins.getEnv "HOME_UID" == "0";
|
||||
};
|
||||
hostName = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = let
|
||||
hostName = builtins.getEnv "HOME_HOSTNAME";
|
||||
in if hostName == "" then null else hostName;
|
||||
};
|
||||
};
|
||||
targets = let
|
||||
type = types.submodule ({ config, name, ... }: {
|
||||
options = {
|
||||
enable = mkEnableOption "Enable the target" // { default = true; };
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
};
|
||||
nodeNames = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
tf = mkOption {
|
||||
type = tfType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config.tf = mkMerge (singleton {
|
||||
imports = [
|
||||
../../targets/common
|
||||
];
|
||||
deps = {
|
||||
select.allProviders = true;
|
||||
enable = true;
|
||||
};
|
||||
terraform = {
|
||||
version = "1.0";
|
||||
logPath = cfg.dataDir + "/terraform-${config.name}.log";
|
||||
dataDir = cfg.dataDir + "/tfdata/${config.name}";
|
||||
environment.TF_CLI_ARGS_apply = "-backup=-";
|
||||
environment.TF_CLI_ARGS_taint = "-backup=-";
|
||||
};
|
||||
state = {
|
||||
file = cfg.dataDir + "/terraform-${config.name}.tfstate";
|
||||
};
|
||||
runners = {
|
||||
lazy = {
|
||||
inherit (meta.runners.lazy) file args;
|
||||
attrPrefix = "deploy.targets.${name}.tf.runners.run.";
|
||||
};
|
||||
run = {
|
||||
apply.name = "${name}-apply";
|
||||
terraform.name = "${name}-tf";
|
||||
};
|
||||
};
|
||||
continue.envVar = "TF_NIX_CONTINUE_${replaceStrings [ "-" ] [ "_" ] config.name}";
|
||||
} ++ map (nodeName: mapAttrs (_: mkMerge) meta.network.nodes.${nodeName}.deploy.tf.out.set) config.nodeNames);
|
||||
});
|
||||
in mkOption {
|
||||
type = types.attrsOf type;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
deploy.targets = let
|
||||
nodeNames = attrNames config.network.nodes;
|
||||
targets = config.deploy.targets;
|
||||
explicitlyDefinedHosts = concatLists (mapAttrsToList (targetName: target: remove targetName target.nodeNames) config.deploy.targets);
|
||||
in genAttrs nodeNames ( nodeName: {
|
||||
enable = mkDefault (! elem nodeName explicitlyDefinedHosts);
|
||||
nodeNames = singleton nodeName;
|
||||
});
|
||||
|
||||
runners = {
|
||||
run = mkMerge (mapAttrsToList (targetName: target: mapAttrs' (k: run:
|
||||
nameValuePair run.name run.set
|
||||
) target.tf.runners.run) (filterAttrs (_: v: v.enable) cfg.targets));
|
||||
lazy.run = mkMerge (mapAttrsToList (targetName: target: mapAttrs' (k: run:
|
||||
nameValuePair run.name run.set
|
||||
) target.tf.runners.lazy.run) (filterAttrs (_: v: v.enable) cfg.targets));
|
||||
};
|
||||
};
|
||||
}
|
||||
41
config/modules/meta/imports.nix
Normal file
41
config/modules/meta/imports.nix
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{ config, lib, profiles, root, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
lib = mkOption {
|
||||
type = types.attrsOf (types.attrsOf types.unspecified);
|
||||
};
|
||||
network.importing = {
|
||||
nixosImports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
homeImports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
users = mkOption {
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
network.importing = {
|
||||
nixosImports = mkDefault (map (path: toString path) [
|
||||
(root + "/config/hosts/HN/nixos.nix")
|
||||
(root + "/config/trusted/hosts/HN/nixos.nix")
|
||||
]);
|
||||
homeImports = mkDefault (map (path: toString path) [
|
||||
(root + "/config/hosts/HN/home.nix")
|
||||
(root + "/config/trusted/hosts/HN/home.nix")
|
||||
]);
|
||||
users = mkDefault (singleton "kat");
|
||||
};
|
||||
lib.kw.nodeImport = hostName: lib.nodeImport {
|
||||
inherit (config.network.importing) nixosImports homeImports users;
|
||||
inherit profiles hostName;
|
||||
};
|
||||
|
||||
_module.args = { inherit (config.lib) kw; };
|
||||
};
|
||||
}
|
||||
66
config/modules/meta/network.nix
Normal file
66
config/modules/meta/network.nix
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
{ pkgs, sources, lib, meta, config, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* Makes hosts nixosModules.
|
||||
* Manages module imports and specialArgs.
|
||||
* Builds network.nodes.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.network = {
|
||||
nixos = {
|
||||
extraModules = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
default = [ ];
|
||||
};
|
||||
specialArgs = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = { };
|
||||
};
|
||||
modulesPath = mkOption {
|
||||
type = types.path;
|
||||
default = toString (pkgs.path + "/nixos/modules");
|
||||
};
|
||||
};
|
||||
nodes = let
|
||||
nixosModule = { name, config, meta, modulesPath, lib, ... }: with lib; {
|
||||
config = {
|
||||
nixpkgs = {
|
||||
system = mkDefault pkgs.system;
|
||||
pkgs = mkDefault pkgs;
|
||||
};
|
||||
};
|
||||
};
|
||||
nixosType = let
|
||||
baseModules = import (config.network.nixos.modulesPath + "/module-list.nix");
|
||||
in types.submoduleWith {
|
||||
modules = baseModules
|
||||
++ singleton nixosModule
|
||||
++ config.network.nixos.extraModules;
|
||||
|
||||
specialArgs = {
|
||||
inherit baseModules;
|
||||
inherit (config.network.nixos) modulesPath;
|
||||
} // config.network.nixos.specialArgs;
|
||||
};
|
||||
in mkOption {
|
||||
type = types.attrsOf nixosType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config.network = {
|
||||
nixos = {
|
||||
extraModules = [
|
||||
"${toString sources.home-manager}/nixos"
|
||||
../../modules/nixos
|
||||
];
|
||||
specialArgs = {
|
||||
inherit (config.network) nodes;
|
||||
inherit sources meta;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
30
config/modules/meta/secrets.nix
Normal file
30
config/modules/meta/secrets.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = let tf = config; in {
|
||||
variables = mkOption {
|
||||
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||
options.externalSecret = mkEnableOption "Is ths secret to be templated into a command provided?";
|
||||
config = mkIf config.externalSecret {
|
||||
type = "string";
|
||||
value.shellCommand = "${tf.commandPrefix} ${tf.folderPrefix}${tf.folderDivider}${escapeShellArg name}";
|
||||
sensitive = true;
|
||||
};
|
||||
}));
|
||||
};
|
||||
commandPrefix = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
folderPrefix = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
folderDivider = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
}
|
||||
25
config/modules/nixos/default.nix
Normal file
25
config/modules/nixos/default.nix
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{ meta, sources, lib, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
(import (sources.arcexprs + "/modules")).nixos
|
||||
(import (sources.katexprs + "/modules")).nixos
|
||||
./deploy.nix
|
||||
./dyndns.nix
|
||||
./secrets.nix
|
||||
(sources.tf-nix + "/modules/nixos/secrets.nix")
|
||||
(sources.tf-nix + "/modules/nixos/secrets-users.nix")
|
||||
(sources.hexchen + "/modules/network/yggdrasil")
|
||||
];
|
||||
|
||||
options.hexchen.dns = lib.mkOption { };
|
||||
options.hexchen.deploy = lib.mkOption { };
|
||||
|
||||
/*
|
||||
This maps hosts to network.nodes from the meta config. This is required for hexchen's yggdrasil network module.
|
||||
*/
|
||||
config = {
|
||||
_module.args.hosts = lib.mapAttrs (_: config: { inherit config; } ) meta.network.nodes;
|
||||
};
|
||||
}
|
||||
83
config/modules/nixos/deploy.nix
Normal file
83
config/modules/nixos/deploy.nix
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
{ tf, target, name, meta, config, lib, ... }:
|
||||
|
||||
/*
|
||||
This module:
|
||||
* aliases <hostname>.system.build.toplevel to <hostname>.deploy.system for ease of use.
|
||||
* marries meta config to NixOS configs for each host.
|
||||
* provides in-scope TF config in NixOS and home-manager, instead of only as a part of meta config.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.deploy;
|
||||
unmergedValues = types.mkOptionType {
|
||||
name = "unmergedValues";
|
||||
merge = loc: defs: map (def: def.value) defs;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.deploy = {
|
||||
targetName = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
system = mkOption {
|
||||
type = types.unspecified;
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
options.deploy.tf = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf unmergedValues;
|
||||
|
||||
options = {
|
||||
import = mkOption {
|
||||
type = types.attrsOf types.unspecified;
|
||||
default = [ ];
|
||||
};
|
||||
imports = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "Other targets to depend on";
|
||||
default = [ ];
|
||||
};
|
||||
attrs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
};
|
||||
out.set = mkOption { type = types.unspecified; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
deploy = {
|
||||
system = config.system.build.toplevel;
|
||||
targetName = let targetsList = attrNames ( filterAttrs (_: target: target.enable && elem name target.nodeNames) meta.deploy.targets ); in
|
||||
if (builtins.length targetsList == 0) then null
|
||||
else lib.warnIf (builtins.length targetsList > 1) "The host ${name} is assigned to several targets: ${concatMapStrings (x: "${x},") targetsList}." (head targetsList);
|
||||
};
|
||||
deploy.tf = mkMerge (singleton (lib.mkIf (config.deploy.targetName != null) {
|
||||
attrs = [ "import" "imports" "out" "attrs" ];
|
||||
import = genAttrs cfg.tf.imports (target: meta.deploy.targets.${target}.tf);
|
||||
out.set = removeAttrs cfg.tf cfg.tf.attrs;
|
||||
deploy.systems.${config.networking.hostName} =
|
||||
with tf.resources; {
|
||||
isRemote =
|
||||
(config.networking.hostName != builtins.getEnv "HOME_HOSTNAME");
|
||||
nixosConfig = config;
|
||||
connection = tf.resources.${config.networking.hostName}.connection.set;
|
||||
triggers.copy.${config.networking.hostName} =
|
||||
tf.resources.${config.networking.hostName}.refAttr "id";
|
||||
triggers.secrets.${config.networking.hostName} =
|
||||
tf.resources.${config.networking.hostName}.refAttr "id";
|
||||
};
|
||||
}) ++ mapAttrsToList
|
||||
(_: user:
|
||||
mapAttrs (_: mkMerge) user.deploy.tf.out.set)
|
||||
config.home-manager.users);
|
||||
|
||||
_module.args.target = mapNullable (targetName: meta.deploy.targets.${targetName}) cfg.targetName;
|
||||
_module.args.tf = mapNullable (target: target.tf) target;
|
||||
};
|
||||
}
|
||||
54
config/modules/nixos/dyndns.nix
Normal file
54
config/modules/nixos/dyndns.nix
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
{ config, pkgs, lib, tf, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
network.dns.dynamic = mkEnableOption "Enable Glauca Dynamic DNS Updater";
|
||||
};
|
||||
|
||||
config = mkIf (config.network.dns.dynamic) {
|
||||
kw.secrets = [
|
||||
"hexdns-key"
|
||||
"hexdns-secret"
|
||||
"hexdns-host"
|
||||
];
|
||||
|
||||
secrets.files.kat-glauca-dns = {
|
||||
text = ''
|
||||
user="${tf.variables.hexdns-key.ref}"
|
||||
pass="${tf.variables.hexdns-secret.ref}"
|
||||
hostname="${tf.variables.hexdns-host.ref}"
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.kat-glauca-dns =
|
||||
let updater = pkgs.writeShellScriptBin "glauca-dyndns" ''
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
|
||||
ip4=$(${pkgs.curl}/bin/curl -s --ipv4 https://dns.glauca.digital/checkip)
|
||||
ip6=$(${pkgs.curl}/bin/curl -s --ipv6 https://dns.glauca.digital/checkip)
|
||||
source $passFile
|
||||
echo "$ip4, $ip6"
|
||||
${pkgs.curl}/bin/curl -u ''${user}:''${pass} --data-urlencode "hostname=''${hostname}" --data-urlencode "myip=''${ip4}" "https://dns.glauca.digital/nic/update"
|
||||
echo ""
|
||||
${pkgs.curl}/bin/curl -u ''${user}:''${pass} --data-urlencode "hostname=''${hostname}" --data-urlencode "myip=''${ip6}" "https://dns.glauca.digital/nic/update"
|
||||
''; in {
|
||||
serviceConfig = {
|
||||
ExecStart = "${updater}/bin/glauca-dyndns";
|
||||
};
|
||||
environment = { passFile = config.secrets.files.kat-glauca-dns.path; };
|
||||
wantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
systemd.timers.kat-glauca-dns = {
|
||||
timerConfig = {
|
||||
Unit = "kat-glauca-dns.service";
|
||||
OnBootSec = "5m";
|
||||
OnUnitActiveSec = "1h";
|
||||
};
|
||||
wantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
15
config/modules/nixos/secrets.nix
Normal file
15
config/modules/nixos/secrets.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.kw = {
|
||||
secrets = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
config = mkIf (config.kw.secrets != null) {
|
||||
deploy.tf.variables = genAttrs config.kw.secrets (n: { externalSecret = true; });
|
||||
};
|
||||
}
|
||||
18
config/profiles/base/access.nix
Normal file
18
config/profiles/base/access.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
security.sudo.wheelNeedsPassword = lib.mkForce false;
|
||||
|
||||
users.users.root = {
|
||||
hashedPassword =
|
||||
"$6$i28yOXoo$/WokLdKds5ZHtJHcuyGrH2WaDQQk/2Pj0xRGLgS8UcmY2oMv3fw2j/85PRpsJJwCB2GBRYRK5LlvdTleHd3mB.";
|
||||
openssh.authorizedKeys.keys = with pkgs.lib;
|
||||
concatLists (mapAttrsToList
|
||||
(name: user:
|
||||
if elem "wheel" user.extraGroups then
|
||||
user.openssh.authorizedKeys.keys
|
||||
else
|
||||
[ ])
|
||||
config.users.users);
|
||||
};
|
||||
}
|
||||
10
config/profiles/base/base16.nix
Normal file
10
config/profiles/base/base16.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
base16 = {
|
||||
console = {
|
||||
enable = true;
|
||||
scheme = "rebecca.rebecca";
|
||||
};
|
||||
};
|
||||
}
|
||||
23
config/profiles/base/default.nix
Normal file
23
config/profiles/base/default.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{ config, meta, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = with meta; [
|
||||
users.kat.base
|
||||
# users.kairi.base TODO
|
||||
users.arc
|
||||
users.hexchen
|
||||
./system.nix
|
||||
./dns.nix
|
||||
./home.nix
|
||||
./profiles.nix
|
||||
./shell.nix
|
||||
./base16.nix
|
||||
./net.nix
|
||||
./access.nix
|
||||
./locale.nix
|
||||
./nix.nix
|
||||
./ssh.nix
|
||||
./packages.nix
|
||||
./secrets.nix
|
||||
];
|
||||
}
|
||||
8
config/profiles/base/dns.nix
Normal file
8
config/profiles/base/dns.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
network.dns = {
|
||||
email = "kat@kittywit.ch";
|
||||
tld = "kittywit.ch.";
|
||||
};
|
||||
}
|
||||
23
config/profiles/base/home.nix
Normal file
23
config/profiles/base/home.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{ meta, config, lib, sources, tf, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options.home-manager.users = mkOption {
|
||||
type = types.attrsOf (types.submoduleWith {
|
||||
modules = singleton ../../modules/home;
|
||||
specialArgs = {
|
||||
inherit sources tf meta;
|
||||
superConfig = config;
|
||||
modulesPath = sources.home-manager + "/modules";
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
config = {
|
||||
home-manager = {
|
||||
useUserPackages = true;
|
||||
useGlobalPkgs = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
13
config/profiles/base/locale.nix
Normal file
13
config/profiles/base/locale.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
fonts.fonts = [
|
||||
pkgs.tamzen
|
||||
];
|
||||
i18n.defaultLocale = "en_GB.UTF-8";
|
||||
time.timeZone = "Europe/London";
|
||||
console = {
|
||||
packages = [ pkgs.tamzen ];
|
||||
keyMap = "uk";
|
||||
};
|
||||
}
|
||||
7
config/profiles/base/net.nix
Normal file
7
config/profiles/base/net.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
network.nftables.enable = lib.mkDefault true;
|
||||
network.enable = true;
|
||||
network.dns.enable = true;
|
||||
}
|
||||
31
config/profiles/base/nix.nix
Normal file
31
config/profiles/base/nix.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{ config, lib, pkgs, sources, ... }:
|
||||
|
||||
{
|
||||
boot.loader.grub.configurationLimit = 8;
|
||||
boot.loader.systemd-boot.configurationLimit = 8;
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellScriptBin "nixFlakes" ''
|
||||
exec ${pkgs.nixUnstable}/bin/nix --experimental-features "nix-command flakes" "$@"
|
||||
'')
|
||||
];
|
||||
|
||||
nix = {
|
||||
nixPath = [
|
||||
"nixpkgs=${sources.nixpkgs}"
|
||||
"nur=${sources.nur}"
|
||||
"arc=${sources.arcexprs}"
|
||||
"ci=${sources.ci}"
|
||||
];
|
||||
sandboxPaths = [
|
||||
"/var/run/nscd/socket"
|
||||
];
|
||||
binaryCaches = [ "https://arc.cachix.org" "https://kittywitch.cachix.org" ];
|
||||
binaryCachePublicKeys =
|
||||
[ "arc.cachix.org-1:DZmhclLkB6UO0rc0rBzNpwFbbaeLfyn+fYccuAy7YVY=" "kittywitch.cachix.org-1:KIzX/G5cuPw5WgrXad6UnrRZ8UDr7jhXzRTK/lmqyK0=" ];
|
||||
autoOptimiseStore = true;
|
||||
gc.automatic = lib.mkDefault true;
|
||||
gc.options = lib.mkDefault "--delete-older-than 1w";
|
||||
trustedUsers = [ "root" "@wheel" ];
|
||||
};
|
||||
}
|
||||
12
config/profiles/base/packages.nix
Normal file
12
config/profiles/base/packages.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
smartmontools
|
||||
hddtemp
|
||||
lm_sensors
|
||||
cachix
|
||||
pinentry-curses
|
||||
gnupg
|
||||
];
|
||||
}
|
||||
55
config/profiles/base/profiles.nix
Normal file
55
config/profiles/base/profiles.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
options = {
|
||||
deploy.profile = {
|
||||
gui = mkEnableOption "Graphical System";
|
||||
vfio = mkEnableOption "VFIO";
|
||||
trusted = mkEnableOption "Trusted Submodule";
|
||||
hardware = {
|
||||
acs-override = mkEnableOption "ACS IOMMU Override";
|
||||
amdgpu = mkEnableOption "AMD GPU";
|
||||
hcloud-imperative = mkEnableOption "Imperative Hetzner Cloud Setup";
|
||||
intel = mkEnableOption "Intel CPU";
|
||||
laptop = mkEnableOption "Laptop";
|
||||
wifi = mkEnableOption "WiFi, home network";
|
||||
ryzen = mkEnableOption "AMD Ryzen CPU";
|
||||
ms-7b86 = mkEnableOption "MSI B450-A Pro Max";
|
||||
rm-310 = mkEnableOption "Intel DQ67OW";
|
||||
eeepc-1015pem = mkEnableOption "Asus Eee PC 1015PEM";
|
||||
v330-14arr = mkEnableOption "Lenovo Ideapad v330-14ARR";
|
||||
};
|
||||
};
|
||||
home-manager.users = mkOption {
|
||||
type = types.attrsOf (types.submoduleWith {
|
||||
modules = [
|
||||
({ superConfig, ... }: {
|
||||
options.deploy.profile = {
|
||||
gui = mkEnableOption "Graphical System";
|
||||
vfio = mkEnableOption "VFIO";
|
||||
trusted = mkEnableOption "Trusted Submodule";
|
||||
hardware = {
|
||||
acs-override = mkEnableOption "ACS IOMMU Override";
|
||||
amdgpu = mkEnableOption "AMD GPU";
|
||||
hcloud-imperative = mkEnableOption "Imperative Hetzner Cloud Setup";
|
||||
intel = mkEnableOption "Intel CPU";
|
||||
laptop = mkEnableOption "Laptop";
|
||||
wifi = mkEnableOption "WiFi, home network";
|
||||
ryzen = mkEnableOption "AMD Ryzen CPU";
|
||||
ms-7b86 = mkEnableOption "MSI B450-A Pro Max";
|
||||
rm-310 = mkEnableOption "Intel DQ67OW";
|
||||
eeepc-1015pem = mkEnableOption "Asus Eee PC 1015PEM";
|
||||
v330-14arr = mkEnableOption "Lenovo Ideapad v330-14ARR";
|
||||
};
|
||||
};
|
||||
config = {
|
||||
deploy.profile = superConfig.deploy.profile;
|
||||
};
|
||||
})
|
||||
];
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
9
config/profiles/base/secrets.nix
Normal file
9
config/profiles/base/secrets.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
secrets = {
|
||||
root = "/var/lib/kat/secrets";
|
||||
persistentRoot = "/var/lib/kat/secrets";
|
||||
external = true;
|
||||
};
|
||||
}
|
||||
8
config/profiles/base/shell.nix
Normal file
8
config/profiles/base/shell.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
enableCompletion = true;
|
||||
};
|
||||
}
|
||||
36
config/profiles/base/ssh.nix
Normal file
36
config/profiles/base/ssh.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
network.firewall = {
|
||||
public = {
|
||||
tcp.ports = singleton 62954;
|
||||
udp.ranges = [{
|
||||
from = 60000;
|
||||
to = 61000;
|
||||
}];
|
||||
};
|
||||
private = {
|
||||
tcp.ports = singleton 62954;
|
||||
udp.ranges = [{
|
||||
from = 60000;
|
||||
to = 61000;
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
ports = lib.mkDefault [ 62954 ];
|
||||
passwordAuthentication = false;
|
||||
challengeResponseAuthentication = false;
|
||||
permitRootLogin = lib.mkDefault "prohibit-password";
|
||||
kexAlgorithms = [ "curve25519-sha256@libssh.org" ];
|
||||
extraConfig = ''
|
||||
StreamLocalBindUnlink yes
|
||||
LogLevel VERBOSE
|
||||
'';
|
||||
};
|
||||
programs.mosh.enable = true;
|
||||
}
|
||||
16
config/profiles/base/system.nix
Normal file
16
config/profiles/base/system.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
|
||||
hardware.enableRedistributableFirmware = lib.mkDefault true;
|
||||
boot.tmpOnTmpfs = true;
|
||||
boot.zfs.enableUnstable = true;
|
||||
boot.kernel.sysctl = {
|
||||
"net.core.rmem_max" = "16777216";
|
||||
"net.core.wmem_max" ="16777216";
|
||||
"net.ipv4.tcp_rmem" = "4096 87380 16777216";
|
||||
"net.ipv4.tcp_wmem" = "4096 65536 16777216";
|
||||
};
|
||||
services.journald.extraConfig = "SystemMaxUse=512M";
|
||||
users.mutableUsers = false;
|
||||
}
|
||||
6
config/profiles/gui/adb.nix
Normal file
6
config/profiles/gui/adb.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
programs.adb.enable = true;
|
||||
users.users.kat.extraGroups = [ "adbusers" ];
|
||||
}
|
||||
24
config/profiles/gui/default.nix
Normal file
24
config/profiles/gui/default.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./adb.nix
|
||||
./fonts.nix
|
||||
./sway.nix
|
||||
./fvwm.nix
|
||||
./filesystems.nix
|
||||
./gpg.nix
|
||||
./xdg-portals.nix
|
||||
./dns.nix
|
||||
./nfs.nix
|
||||
./nix-doc.nix
|
||||
./mpd.nix
|
||||
./nixpkgs.nix
|
||||
./mingetty.nix
|
||||
./sound.nix
|
||||
];
|
||||
|
||||
services.tumbler.enable = true;
|
||||
|
||||
deploy.profile.gui = true;
|
||||
}
|
||||
37
config/profiles/gui/dns.nix
Normal file
37
config/profiles/gui/dns.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{ config, lib, pkgs, ... }: {
|
||||
networking = {
|
||||
# networkmanager.enable = true;
|
||||
resolvconf.useLocalResolver = true;
|
||||
networkmanager.dns = "none";
|
||||
};
|
||||
|
||||
services.dnscrypt-proxy2 = {
|
||||
enable = true;
|
||||
settings = {
|
||||
ipv6_servers = true;
|
||||
require_dnssec = true;
|
||||
|
||||
sources.public-resolvers = {
|
||||
urls = [
|
||||
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
|
||||
"https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md"
|
||||
];
|
||||
cache_file = "/var/lib/dnscrypt-proxy2/public-resolvers.md";
|
||||
minisign_key =
|
||||
"RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
|
||||
};
|
||||
|
||||
# You can choose a specific set of servers from https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v2/public-resolvers.md
|
||||
server_names = [
|
||||
"acsacsar-ams-ipv4"
|
||||
"acsacsar-ams-ipv6"
|
||||
"dnscrypt.eu-dk"
|
||||
"dnscrypt.eu-dk-ipv6"
|
||||
"dnscrypt.eu-nl"
|
||||
"dnscrypt.eu-nl-ipv6"
|
||||
"meganerd"
|
||||
"meganerd-ipv6"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
5
config/profiles/gui/filesystems.nix
Normal file
5
config/profiles/gui/filesystems.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
environment.systemPackages = with pkgs; [ ntfs3g exfat-utils ];
|
||||
}
|
||||
27
config/profiles/gui/fonts.nix
Normal file
27
config/profiles/gui/fonts.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
fonts = {
|
||||
enableDefaultFonts = true;
|
||||
fontDir.enable = true;
|
||||
fontconfig = {
|
||||
enable = true;
|
||||
allowBitmaps = true;
|
||||
defaultFonts = {
|
||||
emoji = [
|
||||
"Twitter Color Emoji"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fonts.fonts = with pkgs; [
|
||||
font-awesome
|
||||
nerdfonts
|
||||
vegur
|
||||
creep
|
||||
cozette
|
||||
emacs-all-the-icons-fonts
|
||||
twitter-color-emoji
|
||||
];
|
||||
}
|
||||
14
config/profiles/gui/fvwm.nix
Normal file
14
config/profiles/gui/fvwm.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
config = mkIf (any (user: user.programs.fvwm.enable) (attrValues config.home-manager.users)) {
|
||||
services.xserver.enable = true;
|
||||
services.xserver.displayManager.startx.enable = true;
|
||||
services.xserver.windowManager.fvwm = {
|
||||
enable = true;
|
||||
gestures = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
12
config/profiles/gui/gpg.nix
Normal file
12
config/profiles/gui/gpg.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
services.pcscd.enable = true;
|
||||
services.udev.packages = [ pkgs.yubikey-personalization ];
|
||||
|
||||
programs.gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = true;
|
||||
pinentryFlavor = "gtk2";
|
||||
};
|
||||
}
|
||||
46
config/profiles/gui/mingetty.nix
Normal file
46
config/profiles/gui/mingetty.nix
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
c1 = "\\e[22;34m";
|
||||
c2 = "\\e[1;35m";
|
||||
nixos = [
|
||||
" ${c1} ::::. ${c2}'::::: ::::' "
|
||||
" ${c1} '::::: ${c2}':::::. ::::' "
|
||||
" ${c1} ::::: ${c2}'::::.::::: "
|
||||
" ${c1} .......:::::..... ${c2}:::::::: "
|
||||
" ${c1} ::::::::::::::::::. ${c2}:::::: ${c1}::::. "
|
||||
" ${c1} ::::::::::::::::::::: ${c2}:::::. ${c1}.::::' "
|
||||
" ${c2} ..... ::::' ${c1}:::::' "
|
||||
" ${c2} ::::: '::' ${c1}:::::' "
|
||||
" ${c2} ........::::: ' ${c1}:::::::::::. "
|
||||
" ${c2}::::::::::::: ${c1}::::::::::::: "
|
||||
" ${c2} ::::::::::: ${c1}.. ${c1}::::: "
|
||||
" ${c2} .::::: ${c1}.::: ${c1}::::: "
|
||||
" ${c2} .::::: ${c1}::::: ${c1}''''' ${c2}..... "
|
||||
" ${c2} ::::: ${c1}':::::. ${c2}......:::::::::::::' "
|
||||
" ${c2} ::: ${c1}::::::. ${c2}':::::::::::::::::' "
|
||||
" ${c1} .:::::::: ${c2}':::::::::: "
|
||||
" ${c1} .::::''::::. ${c2}'::::. "
|
||||
" ${c1} .::::' ::::. ${c2}'::::. "
|
||||
" ${c1} .:::: :::: ${c2}'::::. "
|
||||
];
|
||||
in
|
||||
{
|
||||
console = {
|
||||
font = "Tamzen7x14";
|
||||
earlySetup = true;
|
||||
getty = {
|
||||
greetingPrefix =
|
||||
''\e[H\e[2J'' + # topleft
|
||||
''\e[9;10]''; # setterm blank/powersave = 10 minutes
|
||||
greeting =
|
||||
"\n" +
|
||||
lib.concatStringsSep "\n" nixos +
|
||||
"\n\n" +
|
||||
''\e[1;32m>>> NixOS ${config.system.nixos.label} (Linux \r) - \l\e[0m'';
|
||||
};
|
||||
};
|
||||
services.getty = {
|
||||
helpLine = lib.mkForce "";
|
||||
};
|
||||
}
|
||||
10
config/profiles/gui/mpd.nix
Normal file
10
config/profiles/gui/mpd.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
network.firewall = {
|
||||
public.tcp.ports = [ 6600 32101 ];
|
||||
private.tcp.ports = [ 6600 32101 ];
|
||||
};
|
||||
}
|
||||
29
config/profiles/gui/nfs.nix
Normal file
29
config/profiles/gui/nfs.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{ config, lib, meta, ... }:
|
||||
|
||||
{
|
||||
boot.supportedFilesystems = [ "nfs" ];
|
||||
|
||||
fileSystems."/mnt/kat-nas" = lib.mkIf (config.networking.hostName != "beltane") {
|
||||
device = "${meta.network.nodes.beltane.network.addresses.private.domain}:/mnt/zraw/media";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "noauto" "nfsvers=4" "soft" "retrans=2" "timeo=60"];
|
||||
};
|
||||
|
||||
/*
|
||||
fileSystems."/mnt/hex-corn" = {
|
||||
device = "storah.net.lilwit.ch:/data/cornbox";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "noauto" ];
|
||||
};
|
||||
|
||||
fileSystems."/mnt/hex-tor" = {
|
||||
device = "storah.net.lilwit.ch:/data/torrents";
|
||||
fsType = "nfs";
|
||||
options = [ "x-systemd.automount" "noauto" ];
|
||||
};
|
||||
*/
|
||||
|
||||
systemd.services.nfs-mountd = {
|
||||
wants = [ "network-online.target" "yggdrassil.service" ];
|
||||
};
|
||||
}
|
||||
11
config/profiles/gui/nix-doc.nix
Normal file
11
config/profiles/gui/nix-doc.nix
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
nix.extraOptions = ''
|
||||
plugin-files = ${pkgs.nix-doc}/lib/libnix_doc_plugin.so
|
||||
'';
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nix-doc
|
||||
];
|
||||
}
|
||||
8
config/profiles/gui/nixpkgs.nix
Normal file
8
config/profiles/gui/nixpkgs.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
|
||||
{
|
||||
nixpkgs.config = {
|
||||
allowUnfree = true;
|
||||
pulseaudio = true;
|
||||
};
|
||||
}
|
||||
43
config/profiles/gui/sound.nix
Normal file
43
config/profiles/gui/sound.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
sound = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
defaults.pcm.rate_converter "speexrate_best"
|
||||
'';
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [ pulsemixer ];
|
||||
|
||||
security.rtkit.enable = true;
|
||||
|
||||
services.pipewire = {
|
||||
enable = true;
|
||||
config = {
|
||||
pipewire = {
|
||||
"context.properties" = {
|
||||
"log.level" = 2;
|
||||
"default.clock.min-quantum" =
|
||||
32; # default; going lower may cause crackles and distorted audio
|
||||
};
|
||||
pipewire-pulse = {
|
||||
"context.modules" = [{
|
||||
name = "libpipewire-module-protocol-pulse";
|
||||
args = {
|
||||
"pulse.min.quantum" = 32; # controls minimum playback quant
|
||||
"pulse.min.req" = 32; # controls minimum recording quant
|
||||
"pulse.min.frag" = 32; # controls minimum fragment size
|
||||
"server.address" =
|
||||
[ "unix:native" ]; # the default address of the server
|
||||
};
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
pulse.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
jack.enable = true;
|
||||
alsa.enable = true;
|
||||
};
|
||||
}
|
||||
10
config/profiles/gui/sway.nix
Normal file
10
config/profiles/gui/sway.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
programs.sway = {
|
||||
enable = any (user: user.wayland.windowManager.sway.enable) (attrValues config.home-manager.users);
|
||||
extraPackages = with pkgs; mkForce [ xwayland swaylock swayidle ];
|
||||
};
|
||||
}
|
||||
14
config/profiles/gui/xdg-portals.nix
Normal file
14
config/profiles/gui/xdg-portals.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
xdg = {
|
||||
portal = {
|
||||
enable = true;
|
||||
extraPortals = with pkgs; [
|
||||
xdg-desktop-portal-wlr
|
||||
xdg-desktop-portal-gtk
|
||||
];
|
||||
gtkUsePortal = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
10
config/profiles/hardware/amdgpu/default.nix
Normal file
10
config/profiles/hardware/amdgpu/default.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
deploy.profile.hardware.amdgpu = true;
|
||||
|
||||
boot.initrd.availableKernelModules = [ "amdgpu" ];
|
||||
hardware.opengl.extraPackages = with pkgs; [ libvdpau-va-gl vaapiVdpau ];
|
||||
}
|
||||
39
config/profiles/hardware/default.nix
Normal file
39
config/profiles/hardware/default.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
let hardwareProfiles = { lib }:
|
||||
let profiles = with profiles; lib.domainMerge {
|
||||
folder = ""; # not used in this usage
|
||||
folderPaths = [
|
||||
./.
|
||||
../../trusted/profiles/hardware
|
||||
];
|
||||
} // {
|
||||
ms-7b86 = {
|
||||
imports = [
|
||||
ms-7b86-base
|
||||
ryzen
|
||||
amdgpu
|
||||
];
|
||||
};
|
||||
rm-310 = {
|
||||
imports = [
|
||||
rm-310-base
|
||||
intel
|
||||
];
|
||||
};
|
||||
v330-14arr = {
|
||||
imports = [
|
||||
v330-14arr-base
|
||||
ryzen
|
||||
amdgpu
|
||||
laptop
|
||||
wifi
|
||||
];
|
||||
};
|
||||
eeepc-1015pem = {
|
||||
imports = [
|
||||
eeepc-1015pem-base
|
||||
intel
|
||||
laptop
|
||||
];
|
||||
};
|
||||
}; in profiles;
|
||||
in { __functor = self: hardwareProfiles; isModule = false; }
|
||||
19
config/profiles/hardware/eeepc-1015pem-base/default.nix
Normal file
19
config/profiles/hardware/eeepc-1015pem-base/default.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
deploy.profile.hardware.eeepc-1015pem = true;
|
||||
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "sd_mod" ];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
kernelModules = [ ];
|
||||
extraModulePackages = [ ];
|
||||
kernelParams = [
|
||||
"usbcore.autosuspend=-1"
|
||||
"acpi_osi=Linux"
|
||||
"acpi_enforce_resources=lax"
|
||||
];
|
||||
};
|
||||
}
|
||||
14
config/profiles/hardware/hcloud-imperative/default.nix
Normal file
14
config/profiles/hardware/hcloud-imperative/default.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, sources, ... }:
|
||||
|
||||
/*
|
||||
This hardware profile corresponds with the imperatively provisioned hetzner cloud box.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
deploy.profile.hardware.hcloud-imperative = true;
|
||||
|
||||
imports = [ (sources.nixpkgs + "/nixos/modules/profiles/qemu-guest.nix") ];
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "sd_mod" "sr_mod" ];
|
||||
}
|
||||
13
config/profiles/hardware/intel/default.nix
Normal file
13
config/profiles/hardware/intel/default.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ config, ... }:
|
||||
|
||||
/*
|
||||
This hardware profile corresponds to any machine which has an Intel processor.
|
||||
*/
|
||||
|
||||
{
|
||||
deploy.profile.hardware.intel = true;
|
||||
|
||||
boot = {
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
};
|
||||
}
|
||||
9
config/profiles/hardware/laptop/default.nix
Normal file
9
config/profiles/hardware/laptop/default.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
deploy.profile.hardware.laptop = true;
|
||||
|
||||
imports = [
|
||||
./light.nix
|
||||
];
|
||||
}
|
||||
5
config/profiles/hardware/laptop/light.nix
Normal file
5
config/profiles/hardware/laptop/light.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
programs.light.enable = true;
|
||||
}
|
||||
14
config/profiles/hardware/ms-7b86-base/default.nix
Normal file
14
config/profiles/hardware/ms-7b86-base/default.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
/*
|
||||
This hardware profile corresponds to the MSI B450-A PRO MAX system.
|
||||
*/
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
deploy.profile.hardware.ms-7b86 = true;
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "sd_mod" ];
|
||||
boot.kernelModules = [ "nct6775" ];
|
||||
}
|
||||
14
config/profiles/hardware/rm-310-base/default.nix
Normal file
14
config/profiles/hardware/rm-310-base/default.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ config, ... }:
|
||||
|
||||
/*
|
||||
This hardware profile corresponds with the RM DESKTOP 310 system, which is actually just an Intel DQ67OW motherboard.
|
||||
*/
|
||||
|
||||
{
|
||||
deploy.profile.hardware.rm-310 = true;
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_generic" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
}
|
||||
26
config/profiles/hardware/ryzen/default.nix
Normal file
26
config/profiles/hardware/ryzen/default.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
/*
|
||||
This hardware profile corresponds to any machine which has an AMD Ryzen processor.
|
||||
*/
|
||||
|
||||
{
|
||||
deploy.profile.hardware.ryzen = true;
|
||||
|
||||
boot = {
|
||||
kernelModules = [
|
||||
"msr"
|
||||
"ryzen_smu"
|
||||
"kvm-amd"
|
||||
];
|
||||
kernelParams = [ "amd_iommu=on" ];
|
||||
};
|
||||
|
||||
hardware.cpu.amd.updateMicrocode = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
lm_sensors
|
||||
ryzen-smu-monitor_cpu
|
||||
ryzen-monitor
|
||||
];
|
||||
}
|
||||
15
config/profiles/hardware/v330-14arr-base/default.nix
Normal file
15
config/profiles/hardware/v330-14arr-base/default.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ config, ... }:
|
||||
|
||||
/*
|
||||
This hardware profile corresponds to the Lenovo IdeaPad v330-14ARR.
|
||||
*/
|
||||
|
||||
{
|
||||
deploy.profile.hardware.v330-14arr = true;
|
||||
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "xhci_pci" "ahci" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
}
|
||||
6
config/profiles/hardware/wifi/default.nix
Normal file
6
config/profiles/hardware/wifi/default.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{ config, ... }:
|
||||
|
||||
{
|
||||
deploy.profile.hardware.wifi = true;
|
||||
networking.wireless.enable = true;
|
||||
}
|
||||
68
config/profiles/vfio/default.nix
Normal file
68
config/profiles/vfio/default.nix
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
win10-screenstub = pkgs.writeShellScriptBin "win10-screenstub" ''
|
||||
${pkgs.screenstub-kat}/bin/screenstub -c "${./screenstub.yml}" x
|
||||
'';
|
||||
win10-diskmapper = pkgs.writeShellScriptBin "win10-diskmapper" ''
|
||||
sudo ${pkgs.disk-mapper}/bin/disk-mapper /dev/disk/by-id/ata-ST2000DM008-2FR102_WK301C3H-part2
|
||||
'';
|
||||
in {
|
||||
deploy.profile.vfio = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
win10-screenstub
|
||||
win10-vm
|
||||
win10-diskmapper
|
||||
ddcutil
|
||||
];
|
||||
|
||||
|
||||
users.users.kat.extraGroups = [ "vfio" "input" "uinput" ];
|
||||
users.groups = { uinput = { }; vfio = { }; };
|
||||
|
||||
boot = lib.mkMerge [ {
|
||||
initrd.kernelModules = mkBefore ["vfio" "vfio_iommu_type1" "vfio_pci" "vfio_virqfd"];
|
||||
kernelModules = [ "i2c-dev" ]; # i2c-dev is required for DDC/CI for screenstub
|
||||
kernelPatches = with pkgs.kernelPatches; [
|
||||
(mkIf config.deploy.profile.hardware.acs-override acs-override)
|
||||
];
|
||||
} (mkIf (config.deploy.profile.hardware.amdgpu) {
|
||||
kernelParams = [
|
||||
"video=efifb:off"
|
||||
];
|
||||
extraModulePackages = [
|
||||
(pkgs.linuxPackagesFor config.boot.kernelPackages.kernel).vendor-reset
|
||||
];
|
||||
}) ( mkIf (config.deploy.profile.hardware.acs-override) {
|
||||
kernelParams = [
|
||||
"pci=noats"
|
||||
"pcie_acs_override=downstream,multifunction"
|
||||
];
|
||||
}) ];
|
||||
|
||||
environment.etc."qemu/bridge.conf".text = "allow br";
|
||||
|
||||
security.wrappers = {
|
||||
qemu-bridge-helper = {
|
||||
source = "${pkgs.qemu-vfio}/libexec/qemu-bridge-helper";
|
||||
};
|
||||
};
|
||||
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="i2c-dev", GROUP="vfio", MODE="0660"
|
||||
SUBSYSTEM=="misc", KERNEL=="uinput", OPTIONS+="static_node=uinput", MODE="0660", GROUP="uinput"
|
||||
SUBSYSTEM=="vfio", OWNER="root", GROUP="vfio"
|
||||
'';
|
||||
|
||||
security.pam.loginLimits = [{
|
||||
domain = "@vfio";
|
||||
type = "-";
|
||||
item = "memlock";
|
||||
value = "unlimited";
|
||||
}];
|
||||
|
||||
systemd.extraConfig = "DefaultLimitMEMLOCK=infinity";
|
||||
}
|
||||
85
config/profiles/vfio/screenstub.yml
Normal file
85
config/profiles/vfio/screenstub.yml
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
screens:
|
||||
- monitor: # fill in with info from `screenstub detect`
|
||||
manufacturer: BNQ
|
||||
model: BenQ GW2270
|
||||
#serial: "..."
|
||||
guest_source: # Could be automatically detected, but best to fill in if monitor has more than two inputs
|
||||
name: HDMI-1
|
||||
#value: 0x0f # can also specify raw VCP value
|
||||
host_source: # Usually automatically detected
|
||||
name: HDMI-2
|
||||
#value: 0x11
|
||||
ddc:
|
||||
#minimal_delay: 100ms # minimum time to wait between switching inputs again
|
||||
#guest: [] # disable input switching
|
||||
#host: [] # disable input switching
|
||||
guest: # configure how to switch to the guest
|
||||
#- guest_wait # wait until guest agent responds, otherwise might get stranded on other input
|
||||
- ddc # (default) Use ddc-rs
|
||||
#exec: ["ddcutil", "-g", "BNQ", "setvcp", "0x60", "{}"]
|
||||
#- exec: [ddccontrol, -r, "0x60", -w, "{}", /dev/i2c-5]
|
||||
host: # configure how to switch back from the guest
|
||||
- ddc # (default) Controls DDC from the host GPU - requires no guest agent but many monitors won't support this
|
||||
#- exec: ["ddcutil", "-g", "BNQ", "setvcp", "0x60", "{}"]
|
||||
#- guest_exec: ["C:/ddcset.exe", "setvcp", "60", "{:x}"] # or "0x{:x}" for hex input value
|
||||
#- guest_exec: ["C:/ScreenBright.exe", "-set", "0x60", "{}"] # "{}" is for decimal input value
|
||||
#- exec: ["ssh", "user@vm", "ddcutil", "setvcp", "0x60", "{}"] # system commands can also be used
|
||||
|
||||
qemu:
|
||||
#routing: qmp # (default) does not require extra configuration or dependencies
|
||||
#routing: spice # no external requirements # CURRENTLY UNIMPLEMENTED
|
||||
#routing: input-linux # requires uinput
|
||||
routing: virtio-host # requires uinput, recommended for performance, requires vioinput drivers in guest
|
||||
#driver: ps2 # use PS/2 in the guest for all input devices (absolute mouse mode unsupported)
|
||||
#driver: usb # use USB keyboard/mouse/tablet in the guest
|
||||
#driver: virtio # Recommended but vioinput drivers must be installed in guest
|
||||
#keyboard_driver: ps2 # (default) can also be set separately per input type, this should rarely be necessary
|
||||
#relative_driver: usb # (default)
|
||||
#absolute_driver: usb # (default)
|
||||
#driver: virtio
|
||||
#relative_driver: virtio
|
||||
qmp_socket: /tmp/vfio-qmp # path to QMP socket
|
||||
ga_socket: /tmp/vfio-qga # path to Guest Agent socket
|
||||
|
||||
key_remap: # Arbitrary keys can be remapped in the guest
|
||||
# See https://docs.rs/input-linux/*/input_linux/enum.Key.html for a list of key names available (mouse buttons can also be used)
|
||||
LeftMeta: Reserved # disable the windows key
|
||||
RightAlt: LeftMeta # remap right alt to trigger the windows key
|
||||
|
||||
hotkeys: # Trigger various events on key combinations
|
||||
#- toggle_grab:y
|
||||
# xdevice: # CURRENTLY UNIMPLEMENTED
|
||||
# devices: # Only grab specific devices from Xorg
|
||||
# - "..."
|
||||
#- exec: [echo, hi] # Execute an arbitrary system command
|
||||
#- show_host # switch to the host display
|
||||
#- show_guest # switch to the guest display
|
||||
#- toggle_show # switch the current display
|
||||
#- unstick_guest # causes all held keys to be released in the guest
|
||||
#- shutdown # safely shuts the guest system down
|
||||
#- reboot # reboots the guest
|
||||
#- exit # quits screenstub
|
||||
- triggers: [G]
|
||||
modifiers: [LeftMeta]
|
||||
events:
|
||||
- toggle_grab:
|
||||
x:
|
||||
mouse: false # Confine input/mouse to window
|
||||
- toggle_grab:
|
||||
evdev: # evdev grab is useful for playing games that don't work with absolute mouse events
|
||||
exclusive: false # grab exclusive access from the device(s)
|
||||
#new_device_name: "unique-grab-name" # create a new uinput device for this grab
|
||||
xcore_ignore: [absolute] # which events to ignore from the window (key, button, absolute)
|
||||
evdev_ignore: [button] # which events to ignore from the evdev device
|
||||
devices: # List of devices to forward to guest
|
||||
- /dev/input/by-id/usb-Razer_Razer_Naga_Trinity_00000000001A-event-mouse
|
||||
- unstick_host # force-depress all Xorg keys (prevents keys getting stuck)
|
||||
- triggers: [T]
|
||||
modifiers: [LeftMeta]
|
||||
on_release: false
|
||||
events:
|
||||
- toggle_show
|
||||
|
||||
exit_events: # Events to trigger on window close / exit
|
||||
- show_host
|
||||
#- shutdown
|
||||
41
config/services/fail2ban/default.nix
Normal file
41
config/services/fail2ban/default.nix
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.fail2ban = {
|
||||
enable = true;
|
||||
packageFirewall = pkgs.nftables;
|
||||
banaction = "nftables-multiport";
|
||||
banaction-allports = "nftables-allports";
|
||||
jails = {
|
||||
default = ''
|
||||
bantime = 7d
|
||||
blocktype = DROP
|
||||
action = nftables-allports
|
||||
logpath = /var/log/auth.log
|
||||
'';
|
||||
ssh = ''
|
||||
enabled = true
|
||||
filter = sshd
|
||||
maxretry = 4
|
||||
action = nftables-multiport[name=SSH, port=ssh, protocol=tcp]
|
||||
'';
|
||||
sshd-ddos = ''
|
||||
enabled = true
|
||||
filter = sshd-ddos
|
||||
maxretry = 4
|
||||
action = nftables-multiport[name=ssh, port=ssh, protocol=tcp]
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."fail2ban/filter.d/sshd-ddos.conf" = {
|
||||
enable = true;
|
||||
text = ''
|
||||
[Definition]
|
||||
failregex = sshd(?:\[\d+\])?: Did not receive identification string from <HOST>$
|
||||
ignoreregex =
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.fail2ban.serviceConfig.LimitSTACK = 128 * 1024;
|
||||
}
|
||||
17
config/services/filehost/default.nix
Normal file
17
config/services/filehost/default.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.nginx.virtualHosts = {
|
||||
"files.${config.network.dns.domain}" = {
|
||||
root = "/var/www/files";
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
};
|
||||
|
||||
deploy.tf.dns.records.services_filehost = {
|
||||
tld = config.network.dns.tld;
|
||||
domain = "files";
|
||||
cname.target = "${config.networking.hostName}.${config.network.dns.tld}";
|
||||
};
|
||||
}
|
||||
51
config/services/fusionpbx/default.nix
Normal file
51
config/services/fusionpbx/default.nix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
{ config, pkgs, tf, ... }:
|
||||
|
||||
{
|
||||
deploy.tf.dns.records.services_fusionpbx = {
|
||||
tld = config.network.dns.tld;
|
||||
domain = "pbx";
|
||||
cname.target = "${config.network.addresses.private.domain}.";
|
||||
};
|
||||
|
||||
kw.secrets = [
|
||||
"fusionpbx-username"
|
||||
"fusionpbx-password"
|
||||
];
|
||||
|
||||
secrets.files.fusionpbx_env = {
|
||||
text = ''
|
||||
USER_NAME=${tf.variables.fusionpbx-username.ref}
|
||||
USER_PASSWORD=${tf.variables.fusionpbx-password.ref}
|
||||
'';
|
||||
owner = "fusionpbx";
|
||||
group = "fusionpbx";
|
||||
};
|
||||
|
||||
security.acme.certs.services_fusionpbx = {
|
||||
domain = "pbx.${config.network.dns.domain}";
|
||||
group = "fusionpbx";
|
||||
dnsProvider = "rfc2136";
|
||||
credentialsFile = config.secrets.files.dns_creds.path;
|
||||
postRun = "systemctl restart nginx";
|
||||
};
|
||||
|
||||
services.fusionpbx = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
useLocalPostgreSQL = true;
|
||||
environmentFile = config.secrets.files.fusionpbx_env.path;
|
||||
hardphones = true;
|
||||
useACMEHost = "services_fusionpbx";
|
||||
domain = "pbx.${config.network.dns.domain}";
|
||||
package = with pkgs; fusionpbxWithApps [ fusionpbx-apps.sms ];
|
||||
freeSwitchPackage = with pkgs; freeswitch;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."altar.kittywit.ch" = {
|
||||
locations = {
|
||||
"app/sms/hook/" = {
|
||||
proxyPass = "http://pbx.kittywit.ch/app/sms/hook";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
90
config/services/gitea/default.nix
Normal file
90
config/services/gitea/default.nix
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
{ config, lib, pkgs, tf, ... }:
|
||||
|
||||
{
|
||||
kw.secrets = [
|
||||
"gitea-mail-pass"
|
||||
];
|
||||
|
||||
secrets.files.gitea-mail-passfile = {
|
||||
text = ''
|
||||
${tf.variables.gitea-mail-pass.ref};
|
||||
'';
|
||||
owner = "gitea";
|
||||
group = "gitea";
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "gitea" ];
|
||||
ensureUsers = [{
|
||||
name = "gitea";
|
||||
ensurePermissions."DATABASE gitea" = "ALL PRIVILEGES";
|
||||
}];
|
||||
};
|
||||
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
disableRegistration = true;
|
||||
domain = "git.${config.network.dns.domain}";
|
||||
rootUrl = "https://git.${config.network.dns.domain}";
|
||||
httpAddress = "127.0.0.1";
|
||||
appName = "kittywitch git";
|
||||
ssh = { clonePort = 62954; };
|
||||
database = {
|
||||
type = "postgres";
|
||||
name = "gitea";
|
||||
user = "gitea";
|
||||
};
|
||||
mailerPasswordFile = config.secrets.files.gitea-mail-passfile.path;
|
||||
settings = {
|
||||
security = { DISABLE_GIT_HOOKS = false; };
|
||||
api = { ENABLE_SWAGGER = true; };
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
SUBJECT = "%(APP_NAME)s";
|
||||
HOST = "athame.kittywit.ch:465";
|
||||
USER = "gitea@kittywit.ch";
|
||||
#SEND_AS_PLAIN_TEXT = true;
|
||||
USE_SENDMAIL = false;
|
||||
FROM = "\"kittywitch git\" <gitea@${config.network.dns.domain}>";
|
||||
};
|
||||
service = {
|
||||
NO_REPLY_ADDRESS = "kittywit.ch";
|
||||
REGISTER_EMAIL_CONFIRM = true;
|
||||
ENABLE_NOTIFY_MAIL = true;
|
||||
};
|
||||
ui = {
|
||||
THEMES = "pitchblack,gitea,arc-green";
|
||||
DEFAULT_THEME = "pitchblack";
|
||||
THEME_COLOR_META_TAG = "#222222";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.gitea.serviceConfig.ExecStartPre = [
|
||||
"${pkgs.coreutils}/bin/ln -sfT ${pkgs.runCommand "gitea-public" {
|
||||
} ''
|
||||
${pkgs.coreutils}/bin/mkdir -p $out/{css,img}
|
||||
${pkgs.coreutils}/bin/cp ${pkgs.fetchFromGitHub {
|
||||
owner = "iamdoubz";
|
||||
repo = "Gitea-Pitch-Black";
|
||||
rev = "38a10947254e46a0a3c1fb90c617d913d6fe63b9";
|
||||
sha256 = "1zpmjv0h4k9nf52yaj22zyfabhv83n79f6cj6kfm5s685b2s1348";
|
||||
}}/theme-pitchblack.css $out/css
|
||||
${pkgs.coreutils}/bin/cp -r ${./public}/* $out/
|
||||
''} /var/lib/gitea/custom/public"
|
||||
"${pkgs.coreutils}/bin/ln -sfT ${./templates} /var/lib/gitea/custom/templates"
|
||||
];
|
||||
|
||||
services.nginx.virtualHosts."git.${config.network.dns.domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations = { "/".proxyPass = "http://127.0.0.1:3000"; };
|
||||
};
|
||||
|
||||
deploy.tf.dns.records.services_gitea = {
|
||||
tld = config.network.dns.tld;
|
||||
domain = "git";
|
||||
cname.target = "${config.networking.hostName}.${config.network.dns.tld}";
|
||||
};
|
||||
}
|
||||
1
config/services/gitea/public/img/favicon.svg
Normal file
1
config/services/gitea/public/img/favicon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 171.19"><defs><style>.cls-1,.cls-3{stroke:#000;stroke-miterlimit:10;}.cls-2{fill:#ccc;}.cls-3,.cls-4{fill:#f2f2f2;}</style></defs><path class="cls-1" d="M403.84,463.72s13.51-20.52,9.51-44.75c0,0-22.62-2.63-38,12.5C361.41,402.18,345.28,369,369.47,345c0,0,8,5.45,8.47,12.71,2,31.08-1.18,31.53-1.18,31.53,25.3-3.77,32.51-45.12,9.89-59.77-55.53-26.12-63.59-4.21-71.3,42.35-3.2,27.07-3.83,41.66-8.19,62.74-13.46-15.72-38.59-14.19-38-14-3.4,25,7.88,45.73,9.45,46.09-15,4.55-37.67,6.71-73,11.28,75.87,17.66,199,11.15,274.58-4.94C468.23,470.85,414.31,471.71,403.84,463.72Z" transform="translate(-202.9 -317.79)"/><polygon class="cls-2" points="98.68 121.45 90.04 110.5 90.44 120.65 75.53 115.4 83.03 130.62 71.94 130.38 81.58 144.37 98.68 121.45"/><path class="cls-3" d="M305.65,436.85" transform="translate(-202.9 -317.79)"/><path class="cls-4" d="M301.65,439.44l-.07-.2a85.43,85.43,0,0,0-6.65-5.65l0,6.41s-6,1.47-10.83-1.78c0,0,7.18,11.33,1.07,11.54a40.37,40.37,0,0,0-5.48.5l4.78,11.9C299.42,459.81,301.81,444.69,301.65,439.44Z" transform="translate(-202.9 -317.79)"/><polygon class="cls-2" points="179.03 119.28 187.68 108.33 187.28 118.47 202.19 113.22 194.69 128.44 205.78 128.21 196.13 142.19 179.03 119.28"/><path class="cls-4" d="M381.87,437.27l.07-.2a83.13,83.13,0,0,1,6.65-5.66l0,6.41s6,1.47,10.83-1.78c0,0-7.18,11.33-1.07,11.55a38.39,38.39,0,0,1,5.48.5L399,460C384.1,457.63,381.71,442.51,381.87,437.27Z" transform="translate(-202.9 -317.79)"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
BIN
config/services/gitea/public/img/gitea-lg.png
Normal file
BIN
config/services/gitea/public/img/gitea-lg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
config/services/gitea/public/img/gitea-sm.png
Normal file
BIN
config/services/gitea/public/img/gitea-sm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
1
config/services/gitea/public/img/logo.svg
Normal file
1
config/services/gitea/public/img/logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 171.19"><defs><style>.cls-1,.cls-3{stroke:#000;stroke-miterlimit:10;}.cls-2{fill:#ccc;}.cls-3,.cls-4{fill:#f2f2f2;}</style></defs><path class="cls-1" d="M403.84,463.72s13.51-20.52,9.51-44.75c0,0-22.62-2.63-38,12.5C361.41,402.18,345.28,369,369.47,345c0,0,8,5.45,8.47,12.71,2,31.08-1.18,31.53-1.18,31.53,25.3-3.77,32.51-45.12,9.89-59.77-55.53-26.12-63.59-4.21-71.3,42.35-3.2,27.07-3.83,41.66-8.19,62.74-13.46-15.72-38.59-14.19-38-14-3.4,25,7.88,45.73,9.45,46.09-15,4.55-37.67,6.71-73,11.28,75.87,17.66,199,11.15,274.58-4.94C468.23,470.85,414.31,471.71,403.84,463.72Z" transform="translate(-202.9 -317.79)"/><polygon class="cls-2" points="98.68 121.45 90.04 110.5 90.44 120.65 75.53 115.4 83.03 130.62 71.94 130.38 81.58 144.37 98.68 121.45"/><path class="cls-3" d="M305.65,436.85" transform="translate(-202.9 -317.79)"/><path class="cls-4" d="M301.65,439.44l-.07-.2a85.43,85.43,0,0,0-6.65-5.65l0,6.41s-6,1.47-10.83-1.78c0,0,7.18,11.33,1.07,11.54a40.37,40.37,0,0,0-5.48.5l4.78,11.9C299.42,459.81,301.81,444.69,301.65,439.44Z" transform="translate(-202.9 -317.79)"/><polygon class="cls-2" points="179.03 119.28 187.68 108.33 187.28 118.47 202.19 113.22 194.69 128.44 205.78 128.21 196.13 142.19 179.03 119.28"/><path class="cls-4" d="M381.87,437.27l.07-.2a83.13,83.13,0,0,1,6.65-5.66l0,6.41s6,1.47,10.83-1.78c0,0-7.18,11.33-1.07,11.55a38.39,38.39,0,0,1,5.48.5L399,460C384.1,457.63,381.71,442.51,381.87,437.27Z" transform="translate(-202.9 -317.79)"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
29
config/services/gitea/templates/admin/navbar.tmpl
Normal file
29
config/services/gitea/templates/admin/navbar.tmpl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<div class="ui secondary pointing tabular top attached borderless menu stackable new-menu navbar">
|
||||
<a class="item {{if .PageIsAdminDashboard}}acty{{end}}" href="{{AppSubUrl}}/admin">
|
||||
{{.i18n.Tr "admin.dashboard"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminUsers}}acty{{end}}" href="{{AppSubUrl}}/admin/users">
|
||||
{{.i18n.Tr "admin.users"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminOrganizations}}acty{{end}}" href="{{AppSubUrl}}/admin/orgs">
|
||||
{{.i18n.Tr "admin.organizations"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminRepositories}}acty{{end}}" href="{{AppSubUrl}}/admin/repos">
|
||||
{{.i18n.Tr "admin.repositories"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminHooks}}acty{{end}}" href="{{AppSubUrl}}/admin/hooks">
|
||||
{{.i18n.Tr "admin.hooks"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminAuthentications}}acty{{end}}" href="{{AppSubUrl}}/admin/auths">
|
||||
{{.i18n.Tr "admin.authentication"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminConfig}}acty{{end}}" href="{{AppSubUrl}}/admin/config">
|
||||
{{.i18n.Tr "admin.config"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminNotices}}acty{{end}}" href="{{AppSubUrl}}/admin/notices">
|
||||
{{.i18n.Tr "admin.notices"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsAdminMonitor}}acty{{end}}" href="{{AppSubUrl}}/admin/monitor">
|
||||
{{.i18n.Tr "admin.monitor"}}
|
||||
</a>
|
||||
</div>
|
||||
176
config/services/gitea/templates/custom/head.tmpl
Normal file
176
config/services/gitea/templates/custom/head.tmpl
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head data-suburl="{{AppSubUrl}}">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>{{if .Title}}{{.Title}} - {{end}}{{AppName}}</title>
|
||||
<link rel="manifest" href="{{AppSubUrl}}/manifest.json">
|
||||
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('{{AppSubUrl}}/serviceworker.js').then(function(registration) {
|
||||
// Registration was successful
|
||||
console.log('ServiceWorker registration successful with scope: ', registration.scope);
|
||||
}, function(err) {
|
||||
// registration failed :(
|
||||
console.log('ServiceWorker registration failed: ', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<meta name="theme-color" content="{{ThemeColorMetaTag}}">
|
||||
<meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}" />
|
||||
<meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}" />
|
||||
<meta name="keywords" content="{{MetaKeywords}}">
|
||||
<meta name="referrer" content="no-referrer" />
|
||||
<meta name="_csrf" content="{{.CsrfToken}}" />
|
||||
<meta name="_suburl" content="{{AppSubUrl}}" />
|
||||
{{if .IsSigned}}
|
||||
<meta name="_uid" content="{{.SignedUser.ID}}" />
|
||||
{{end}}
|
||||
{{if .ContextUser}}
|
||||
<meta name="_context_uid" content="{{.ContextUser.ID}}" />
|
||||
{{end}}
|
||||
{{if .SearchLimit}}
|
||||
<meta name="_search_limit" content="{{.SearchLimit}}" />
|
||||
{{end}}
|
||||
{{if .GoGetImport}}
|
||||
<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">
|
||||
<meta name="go-source" content="{{.GoGetImport}} _ {{.GoDocDirectory}} {{.GoDocFile}}">
|
||||
{{end}}
|
||||
|
||||
<script>
|
||||
{{SafeJS `/*
|
||||
@licstart The following is the entire license notice for the
|
||||
JavaScript code in this page.
|
||||
|
||||
Copyright (c) 2016 The Gitea Authors
|
||||
Copyright (c) 2015 The Gogs Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
---
|
||||
Licensing information for additional javascript libraries can be found at:
|
||||
{{AppSubUrl}}/vendor/librejs.html
|
||||
|
||||
@licend The above is the entire license notice
|
||||
for the JavaScript code in this page.
|
||||
*/`}}
|
||||
</script>
|
||||
|
||||
<link rel="shortcut icon" href="{{AppSubUrl}}/img/favicon.png" />
|
||||
<link rel="mask-icon" href="{{AppSubUrl}}/img/gitea-safari.svg" color="#609926">
|
||||
<link rel="preload" href="{{AppSubUrl}}/vendor/assets/font-awesome/css/font-awesome.min.css" as="style" onload="this.rel='stylesheet'">
|
||||
<noscript><link rel="stylesheet" href="{{AppSubUrl}}/vendor/assets/font-awesome/css/font-awesome.min.css"></noscript>
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/assets/octicons/octicons.min.css">
|
||||
|
||||
{{if .RequireSimpleMDE}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.css">
|
||||
{{end}}
|
||||
|
||||
{{if .RequireGitGraph}}
|
||||
<!-- graph -->
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/gitgraph/gitgraph.css">
|
||||
{{end}}
|
||||
|
||||
{{if .RequireTribute}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/tribute/tribute.css">
|
||||
{{end}}
|
||||
|
||||
<!-- Stylesheet -->
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.css">
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/index.css?v={{MD5 AppVer}}">
|
||||
<noscript>
|
||||
<style>
|
||||
.dropdown:hover > .menu { display: block; }
|
||||
.ui.secondary.menu .dropdown.item > .menu { margin-top: 0; }
|
||||
</style>
|
||||
</noscript>
|
||||
|
||||
{{if .RequireHighlightJS}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/highlight/github.css">
|
||||
{{end}}
|
||||
{{if .RequireMinicolors}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/jquery.minicolors/jquery.minicolors.css">
|
||||
{{end}}
|
||||
{{if .RequireDatetimepicker}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/jquery.datetimepicker/jquery.datetimepicker.css">
|
||||
{{end}}
|
||||
{{if .RequireDropzone}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/dropzone/dropzone.css">
|
||||
{{end}}
|
||||
{{if .EnableHeatmap}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.css">
|
||||
{{end}}
|
||||
<style class="list-search-style"></style>
|
||||
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/cssrelpreload/loadCSS.min.js"></script>
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js"></script>
|
||||
{{if .PageIsUserProfile}}
|
||||
<meta property="og:title" content="{{.Owner.Name}}" />
|
||||
<meta property="og:type" content="profile" />
|
||||
<meta property="og:image" content="{{.Owner.AvatarLink}}" />
|
||||
<meta property="og:url" content="{{.Owner.HTMLURL}}" />
|
||||
<meta property="og:site_name" content="{{AppName}}" />
|
||||
{{else if .Repository}}
|
||||
<meta property="og:title" content="{{.Repository.Name}}" />
|
||||
<meta property="og:type" content="object" />
|
||||
<meta property="og:image" content="{{.Repository.Owner.AvatarLink}}" />
|
||||
<meta property="og:url" content="{{.Repository.HTMLURL}}" />
|
||||
{{if .Repository.Description}}
|
||||
<meta property="og:description" content="{{.Repository.Description}}" />
|
||||
{{end}}
|
||||
<meta property="og:site_name" content="{{AppName}}" />
|
||||
{{else}}
|
||||
<meta property="og:title" content="{{AppName}}">
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="{{AppSubUrl}}/img/gitea-lg.png" />
|
||||
<meta property="og:url" content="{{AppUrl}}" />
|
||||
<meta property="og:description" content="{{MetaDescription}}">
|
||||
{{end}}
|
||||
{{if .IsSigned }}
|
||||
{{ if ne .SignedUser.Theme "gitea" }}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/theme-{{.SignedUser.Theme}}.css">
|
||||
{{end}}
|
||||
{{else if ne DefaultTheme "gitea"}}
|
||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/theme-{{DefaultTheme}}.css">
|
||||
{{end}}
|
||||
{{template "custom/header" .}}
|
||||
</head>
|
||||
<body>
|
||||
{{template "custom/body_outer_pre" .}}
|
||||
|
||||
<div class="full height">
|
||||
<noscript>{{.i18n.Tr "enable_javascript"}}</noscript>
|
||||
|
||||
{{template "custom/body_inner_pre" .}}
|
||||
|
||||
{{if not .PageIsInstall}}
|
||||
<div class="ui top secondary stackable main menu following bar light">
|
||||
{{template "base/head_navbar" .}}
|
||||
</div><!-- end bar -->
|
||||
{{end}}
|
||||
{{/*
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
*/}}
|
||||
16
config/services/gitea/templates/explore/navbar.tmpl
Normal file
16
config/services/gitea/templates/explore/navbar.tmpl
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<div class="ui secondary pointing tabular top attached borderless stackable menu navbar">
|
||||
<a class="item {{if .PageIsExploreRepositories}}acty{{end}}" href="{{AppSubUrl}}/explore/repos">
|
||||
{{svg "octicon-repo" 16}} {{.i18n.Tr "explore.repos"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsExploreUsers}}acty{{end}}" href="{{AppSubUrl}}/explore/users">
|
||||
{{svg "octicon-person" 16}} {{.i18n.Tr "explore.users"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsExploreOrganizations}}acty{{end}}" href="{{AppSubUrl}}/explore/organizations">
|
||||
{{svg "octicon-organization" 16}} {{.i18n.Tr "explore.organizations"}}
|
||||
</a>
|
||||
{{if .IsRepoIndexerEnabled}}
|
||||
<a class="item {{if .PageIsExploreCode}}acty{{end}}" href="{{AppSubUrl}}/explore/code">
|
||||
{{svg "octicon-code" 16}} {{.i18n.Tr "explore.code"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
18
config/services/gitea/templates/home.tmpl
Normal file
18
config/services/gitea/templates/home.tmpl
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{{template "base/head" .}}
|
||||
<div class="home">
|
||||
<div class="ui stackable middle very relaxed page grid">
|
||||
<div class="sixteen wide center aligned centered column">
|
||||
<div>
|
||||
<img class="logo" src="{{StaticUrlPrefix}}/img/gitea-lg.png" />
|
||||
</div>
|
||||
<div class="hero">
|
||||
<br />
|
||||
<h1 class="ui icon header title">
|
||||
{{AppName}}
|
||||
</h1>
|
||||
<a href="https://kittywit.ch"><h2>back to home</h2></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
143
config/services/gitea/templates/repo/header.tmpl
Normal file
143
config/services/gitea/templates/repo/header.tmpl
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<div class="header-wrapper">
|
||||
{{with .Repository}}
|
||||
<div class="ui container">
|
||||
<div class="repo-header">
|
||||
<div class="ui huge breadcrumb repo-title">
|
||||
{{if .RelAvatarLink}}
|
||||
<img class="ui avatar image" src="{{.RelAvatarLink}}">
|
||||
{{else if .IsTemplate}}
|
||||
{{if .IsPrivate}}
|
||||
{{svg "octicon-repo-template-private" 32}}
|
||||
{{else}}
|
||||
{{svg "octicon-repo-template" 32}}
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{if .IsPrivate}}
|
||||
{{svg "octicon-lock" 32}}
|
||||
{{else if .IsMirror}}
|
||||
{{svg "octicon-repo-clone" 32}}
|
||||
{{else if .IsFork}}
|
||||
{{svg "octicon-repo-fork" 32}}
|
||||
{{else}}
|
||||
{{svg "octicon-repo" 32}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
<a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a>
|
||||
<div class="divider"> / </div>
|
||||
<a href="{{$.RepoLink}}">{{.Name}}</a>
|
||||
{{if .RelAvatarLink}}
|
||||
{{if .IsTemplate}}
|
||||
{{if .IsPrivate}}
|
||||
{{svg "octicon-repo-template-private" 32}}
|
||||
{{else}}
|
||||
{{svg "octicon-repo-template" 32}}
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{if .IsPrivate}}
|
||||
{{svg "octicon-lock" 32}}
|
||||
{{else if .IsMirror}}
|
||||
{{svg "octicon-repo-clone" 32}}
|
||||
{{else if .IsFork}}
|
||||
{{svg "octicon-repo-fork" 32}}
|
||||
{{else}}
|
||||
{{svg "octicon-repo" 32}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if .IsArchived}}<i class="archive icon archived-icon"></i>{{end}}
|
||||
{{if .IsMirror}}<div class="fork-flag">{{$.i18n.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{if .SanitizedOriginalURL}}{{.SanitizedOriginalURL}}{{else}}{{MirrorAddress $.Mirror}}{{end}}">{{if .SanitizedOriginalURL}}{{.SanitizedOriginalURL}}{{else}}{{MirrorAddress $.Mirror}}{{end}}</a></div>{{end}}
|
||||
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{SubStr .BaseRepo.RelLink 1 -1}}</a></div>{{end}}
|
||||
{{if .IsGenerated}}<div class="fork-flag">{{$.i18n.Tr "repo.generated_from"}} <a href="{{.TemplateRepo.Link}}">{{SubStr .TemplateRepo.RelLink 1 -1}}</a></div>{{end}}
|
||||
</div>
|
||||
{{if not .IsBeingCreated}}
|
||||
<div class="repo-buttons">
|
||||
<div class="ui labeled button" tabindex="0">
|
||||
<a class="ui compact basic button" href="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
|
||||
<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}}
|
||||
</a>
|
||||
<a class="ui basic label" href="{{.Link}}/watchers">
|
||||
{{.NumWatches}}
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui labeled button" tabindex="0">
|
||||
<a class="ui compact basic button" href="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
|
||||
<i class="icon star{{if not $.IsStaringRepo}} outline{{end}}"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}}
|
||||
</a>
|
||||
<a class="ui basic label" href="{{.Link}}/stars">
|
||||
{{.NumStars}}
|
||||
</a>
|
||||
</div>
|
||||
{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}}
|
||||
<div class="ui labeled button {{if and ($.IsSigned) (not $.CanSignedUserFork)}}disabled-repo-button{{end}}" tabindex="0">
|
||||
<a class="ui compact basic button {{if or (not $.IsSigned) (not $.CanSignedUserFork)}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else if $.IsSigned}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" {{ else }} data-content="{{$.i18n.Tr "repo.fork_guest_user" }}" rel="nofollow" href="{{AppSubUrl}}/user/login?redirect_to={{AppSubUrl}}/repo/fork/{{.ID}}" {{end}} data-position="top center" data-variation="tiny">
|
||||
{{svg "octicon-repo-forked" 16}}{{$.i18n.Tr "repo.fork"}}
|
||||
</a>
|
||||
<a class="ui basic label" href="{{.Link}}/forks">
|
||||
{{.NumForks}}
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div><!-- end grid -->
|
||||
</div><!-- end container -->
|
||||
{{end}}
|
||||
<div class="ui tabs container">
|
||||
{{if not .Repository.IsBeingCreated}}
|
||||
<div class="ui tabular stackable menu navbar">
|
||||
{{if .Permission.CanRead $.UnitTypeCode}}
|
||||
<a class="item {{if .PageIsViewCode}}acty{{end}}" href="{{.RepoLink}}{{if (ne .BranchName .Repository.DefaultBranch)}}/src/{{.BranchNameSubURL | EscapePound}}{{end}}">
|
||||
{{svg "octicon-code" 16}} {{.i18n.Tr "repo.code"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeIssues}}
|
||||
<a class="item {{if .PageIsIssueList}}acty{{end}}" href="{{.RepoLink}}/issues">
|
||||
{{svg "octicon-issue-opened" 16}} {{.i18n.Tr "repo.issues"}} <span class="ui {{if not .Repository.NumOpenIssues}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenIssues}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if .Permission.CanRead $.UnitTypeExternalTracker}}
|
||||
<a class="item {{if .PageIsIssueList}}acty{{end}}" href="{{.RepoExternalIssuesLink}}" target="_blank" rel="noopener noreferrer">
|
||||
{{svg "octicon-link-external" 16}} {{.i18n.Tr "repo.issues"}} </span>
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and .Repository.CanEnablePulls (.Permission.CanRead $.UnitTypePullRequests)}}
|
||||
<a class="item {{if .PageIsPullList}}acty{{end}}" href="{{.RepoLink}}/pulls">
|
||||
{{svg "octicon-git-pull-request" 16}} {{.i18n.Tr "repo.pulls"}} <span class="ui {{if not .Repository.NumOpenPulls}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenPulls}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and (.Permission.CanRead $.UnitTypeReleases) (not .IsEmptyRepo) }}
|
||||
<a class="item {{if .PageIsReleaseList}}acty{{end}}" href="{{.RepoLink}}/releases">
|
||||
{{svg "octicon-tag" 16}} {{.i18n.Tr "repo.releases"}} <span class="ui {{if not .NumReleases}}gray{{else}}blue{{end}} small label">{{.NumReleases}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if or (.Permission.CanRead $.UnitTypeWiki) (.Permission.CanRead $.UnitTypeExternalWiki)}}
|
||||
<a class="item {{if .PageIsWiki}}acty{{end}}" href="{{.RepoLink}}/wiki" {{if (.Permission.CanRead $.UnitTypeExternalWiki)}} target="_blank" rel="noopener noreferrer" {{end}}>
|
||||
{{svg "octicon-book" 16}} {{.i18n.Tr "repo.wiki"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{if and (.Permission.CanReadAny $.UnitTypePullRequests $.UnitTypeIssues $.UnitTypeReleases) (not .IsEmptyRepo)}}
|
||||
<a class="item {{if .PageIsActivity}}acty{{end}}" href="{{.RepoLink}}/activity">
|
||||
{{svg "octicon-pulse" 16}} {{.i18n.Tr "repo.activity"}}
|
||||
</a>
|
||||
{{end}}
|
||||
|
||||
{{template "custom/extra_tabs" .}}
|
||||
|
||||
{{if .Permission.IsAdmin}}
|
||||
<div class="right menu">
|
||||
<a class="item {{if .PageIsSettings}}acty{{end}}" href="{{.RepoLink}}/settings">
|
||||
{{svg "octicon-tools" 16}} {{.i18n.Tr "repo.settings"}}
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="ui tabs divider"></div>
|
||||
</div>
|
||||
153
config/services/gitea/templates/repo/home.tmpl
Normal file
153
config/services/gitea/templates/repo/home.tmpl
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
{{template "base/head" .}}
|
||||
<div class="repository file list">
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<div class="ui repo-description">
|
||||
<div id="repo-desc">
|
||||
{{if .Repository.DescriptionHTML}}<span class="description has-emoji">{{.Repository.DescriptionHTML}}</span>{{else if .IsRepositoryAdmin}}<span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span>{{end}}
|
||||
<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
|
||||
</div>
|
||||
{{if .RepoSearchEnabled}}
|
||||
<div class="ui repo-search">
|
||||
<form class="ui form ignore-dirty" action="{{.RepoLink}}/search" method="get">
|
||||
<div class="field">
|
||||
<div class="ui action input">
|
||||
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}">
|
||||
<button class="ui icon button" type="submit">
|
||||
<i class="search icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="ui" id="repo-topics">
|
||||
{{range .Topics}}<a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a>{{end}}
|
||||
{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<a id="manage_topic">{{.i18n.Tr "repo.topic.manage_topics"}}</a>{{end}}
|
||||
</div>
|
||||
{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
|
||||
<div class="ui repo-topic-edit grid form segment error" id="topic_edit" style="display:none">
|
||||
<div class="fourteen wide column">
|
||||
<div class="field">
|
||||
<div class="ui fluid multiple search selection dropdown">
|
||||
<input type="hidden" name="topics" value="{{range $i, $v := .Topics}}{{.Name}}{{if lt (Add $i 1) (len $.Topics)}},{{end}}{{end}}">
|
||||
{{range .Topics}}
|
||||
<div class="ui small label topic transition visible" data-value="{{.Name}}" style="display: inline-block !important; cursor: default;">{{.Name}}<i class="delete icon"></i></div>
|
||||
{{end}}
|
||||
<div class="text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="two wide column">
|
||||
<a class="ui button primary" href="javascript:;" id="save_topic"
|
||||
data-link="{{.RepoLink}}/topics">{{.i18n.Tr "repo.topic.done"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="hide" id="validate_prompt">
|
||||
<span id="count_prompt">{{.i18n.Tr "repo.topic.count_prompt"}}</span>
|
||||
<span id="format_prompt">{{.i18n.Tr "repo.topic.format_prompt"}}</span>
|
||||
</div>
|
||||
{{if .Repository.IsArchived}}
|
||||
<div class="ui warning message">
|
||||
{{.i18n.Tr "repo.archive.title"}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{template "repo/sub_menu" .}}
|
||||
<div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins">
|
||||
{{template "repo/branch_dropdown" .}}
|
||||
{{ $n := len .TreeNames}}
|
||||
{{ $l := Subtract $n 1}}
|
||||
<!-- If home page, show new PR. If not, show breadcrumb -->
|
||||
{{if eq $n 0}}
|
||||
{{if and .PullRequestCtx.Allowed .IsViewBranch (not .Repository.IsArchived)}}
|
||||
<div class="fitted item">
|
||||
<a href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}">
|
||||
<button id="new-pull-request" class="ui compact basic button">{{.i18n.Tr "repo.pulls.compare_changes"}}</button>
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section" href="{{.RepoLink}}/src/{{EscapePound .BranchNameSubURL}}" title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span class="divider">/</span>{{if eq $i $l}}<span class="active section" title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}<span class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}" title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div>
|
||||
{{end}}
|
||||
<div class="right fitted item" id="file-buttons">
|
||||
<div class="ui tiny blue buttons">
|
||||
{{if .Repository.CanEnableEditor}}
|
||||
{{if .CanAddFile}}
|
||||
<a href="{{.RepoLink}}/_new/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" class="ui button">
|
||||
{{.i18n.Tr "repo.editor.new_file"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .CanUploadFile}}
|
||||
<a href="{{.RepoLink}}/_upload/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" class="ui button">
|
||||
{{.i18n.Tr "repo.editor.upload_file"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if and (ne $n 0) (not .IsViewFile) (not .IsBlame) }}
|
||||
<a href="{{.RepoLink}}/commits/{{EscapePound .BranchNameSubURL}}/{{EscapePound .TreePath}}" class="ui button">
|
||||
{{.i18n.Tr "repo.file_history"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="fitted item">
|
||||
{{if eq $n 0}}
|
||||
{{if .Repository.IsTemplate}}
|
||||
<div class="ui tiny blue buttons">
|
||||
<a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button">
|
||||
{{.i18n.Tr "repo.use_template"}}
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="fitted item">
|
||||
|
||||
<!-- Only show clone panel in repository home page -->
|
||||
{{if eq $n 0}}
|
||||
<div class="ui action tiny input" id="clone-panel">
|
||||
{{if not $.DisableHTTP}}
|
||||
<button class="ui basic clone button" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}">
|
||||
{{if UseHTTPS}}HTTPS{{else}}HTTP{{end}}
|
||||
</button>
|
||||
{{end}}
|
||||
{{if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}}
|
||||
<button class="ui basic clone button" id="repo-clone-ssh" data-link="{{.CloneLink.SSH}}">
|
||||
SSH
|
||||
</button>
|
||||
{{end}}
|
||||
{{if not $.DisableHTTP}}
|
||||
<input id="repo-clone-url" value="{{$.CloneLink.HTTPS}}" readonly>
|
||||
{{else if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}}
|
||||
<input id="repo-clone-url" value="{{$.CloneLink.SSH}}" readonly>
|
||||
{{end}}
|
||||
{{if or (not $.DisableHTTP) (and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH))}}
|
||||
<button class="ui basic icon button poping up clipboard" id="clipboard-btn" data-original="{{.i18n.Tr "repo.copy_link"}}" data-success="{{.i18n.Tr "repo.copy_link_success"}}" data-error="{{.i18n.Tr "repo.copy_link_error"}}" data-content="{{.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-target="#repo-clone-url">
|
||||
{{svg "octicon-clippy" 16}}
|
||||
</button>
|
||||
{{end}}
|
||||
<div class="ui basic jump dropdown icon button poping up" data-content="{{.i18n.Tr "repo.download_archive"}}" data-variation="tiny inverted" data-position="top right">
|
||||
<i class="download icon"></i>
|
||||
<div class="menu">
|
||||
<a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip">{{svg "octicon-file-zip" 16}} ZIP</a>
|
||||
<a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz">{{svg "octicon-file-zip" 16}} TAR.GZ</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{if .IsViewFile}}
|
||||
{{template "repo/view_file" .}}
|
||||
{{else if .IsBlame}}
|
||||
{{template "repo/blame" .}}
|
||||
{{else}}
|
||||
{{template "repo/view_list" .}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
29
config/services/gitea/templates/repo/settings/navbar.tmpl
Normal file
29
config/services/gitea/templates/repo/settings/navbar.tmpl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<div class="ui secondary pointing tabular top attached borderless menu stackable new-menu navbar">
|
||||
<a class="item {{if .PageIsSettingsOptions}}acty{{end}}" href="{{.RepoLink}}/settings">
|
||||
{{.i18n.Tr "repo.settings.options"}}
|
||||
</a>
|
||||
<a class="item {{if .PageIsSettingsCollaboration}}acty{{end}}" href="{{.RepoLink}}/settings/collaboration">
|
||||
{{.i18n.Tr "repo.settings.collaboration"}}
|
||||
</a>
|
||||
{{if not .Repository.IsEmpty}}
|
||||
<a class="item {{if .PageIsSettingsBranches}}acty{{end}}" href="{{.RepoLink}}/settings/branches">
|
||||
{{.i18n.Tr "repo.settings.branches"}}
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="item {{if .PageIsSettingsHooks}}acty{{end}}" href="{{.RepoLink}}/settings/hooks">
|
||||
{{.i18n.Tr "repo.settings.hooks"}}
|
||||
</a>
|
||||
{{if .SignedUser.CanEditGitHook}}
|
||||
<a class="item {{if .PageIsSettingsGitHooks}}acty{{end}}" href="{{.RepoLink}}/settings/hooks/git">
|
||||
{{.i18n.Tr "repo.settings.githooks"}}
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="item {{if .PageIsSettingsKeys}}acty{{end}}" href="{{.RepoLink}}/settings/keys">
|
||||
{{.i18n.Tr "repo.settings.deploy_keys"}}
|
||||
</a>
|
||||
{{if .LFSStartServer}}
|
||||
<a class="item {{if .PageIsSettingsLFS}}acty{{end}}" href="{{.RepoLink}}/settings/lfs">
|
||||
{{.i18n.Tr "repo.settings.lfs"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
132
config/services/gitea/templates/user/dashboard/dashboard.tmpl
Normal file
132
config/services/gitea/templates/user/dashboard/dashboard.tmpl
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
{{template "base/head" .}}
|
||||
<div class="dashboard feeds">
|
||||
{{template "user/dashboard/navbar" .}}
|
||||
<div class="ui container">
|
||||
{{template "base/alert" .}}
|
||||
<div class="ui mobile reversed stackable grid">
|
||||
<div class="ui container ten wide column">
|
||||
{{if .EnableHeatmap}}
|
||||
<div id="user-heatmap" style="padding-right: 40px">
|
||||
<activity-heatmap :locale="locale" :suburl="suburl" :user="heatmapUser">
|
||||
<div slot="loading">
|
||||
<div class="ui active centered inline indeterminate text loader" id="loading-heatmap">{{.i18n.Tr "user.heatmap.loading"}}</div>
|
||||
</div>
|
||||
</activity-heatmap>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{template "user/dashboard/feeds" .}}
|
||||
</div>
|
||||
<div id="app" class="six wide column">
|
||||
<repo-search
|
||||
:search-limit="searchLimit"
|
||||
:suburl="suburl"
|
||||
:uid="uid"
|
||||
:more-repos-link="'{{.ContextUser.HomeLink}}'"
|
||||
{{if not .ContextUser.IsOrganization}}
|
||||
:organizations="[
|
||||
{{range .ContextUser.Orgs}}
|
||||
{name: '{{.Name}}', num_repos: '{{.NumRepos}}'},
|
||||
{{end}}
|
||||
]"
|
||||
:is-organization="false"
|
||||
:organizations-total-count="{{.ContextUser.GetOrganizationCount}}"
|
||||
:can-create-organization="{{.SignedUser.CanCreateOrganization}}"
|
||||
{{end}}
|
||||
inline-template
|
||||
v-cloak
|
||||
>
|
||||
<div>
|
||||
<div v-if="!isOrganization" class="ui two item tabable menu">
|
||||
<a :class="{item: true, acty: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a>
|
||||
<a :class="{item: true, acty: tab === 'organizations'}" @click="changeTab('organizations')">{{.i18n.Tr "organization"}}</a>
|
||||
</div>
|
||||
<div v-show="tab === 'repos'" class="ui tab active list dashboard-repos">
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "home.my_repos"}} <span class="ui grey label">${reposTotalCount}</span>
|
||||
{{if or (not .ContextUser.IsOrganization) .IsOrganizationOwner}}
|
||||
<div class="ui right">
|
||||
<a class="poping up" :href="suburl + '/repo/create{{if .ContextUser.IsOrganization}}?org={{.ContextUser.ID}}{{end}}'" data-content="{{.i18n.Tr "new_repo"}}" data-variation="tiny inverted" data-position="left center">
|
||||
<i class="plus icon"></i>
|
||||
<span class="sr-only">{{.i18n.Tr "new_repo"}}</span>
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
</h4>
|
||||
<div class="ui attached secondary segment repos-search">
|
||||
<div class="ui fluid icon input" :class="{loading: isLoading}">
|
||||
<input @input="searchRepos(reposFilter)" v-model="searchQuery" ref="search" placeholder="{{.i18n.Tr "home.search_repos"}}">
|
||||
<i class="search icon"></i>
|
||||
</div>
|
||||
<div class="ui secondary tiny pointing borderless menu center aligned grid repos-filter">
|
||||
<a class="item" :class="{acty: reposFilter === 'all'}" @click="changeReposFilter('all')">
|
||||
{{.i18n.Tr "all"}}
|
||||
<div v-show="reposFilter === 'all'" class="ui circular mini grey label">${repoTypeCount}</div>
|
||||
</a>
|
||||
<a class="item" :class="{acty: reposFilter === 'sources'}" @click="changeReposFilter('sources')">
|
||||
{{.i18n.Tr "sources"}}
|
||||
<div v-show="reposFilter === 'sources'" class="ui circular mini grey label">${repoTypeCount}</div>
|
||||
</a>
|
||||
<a class="item" :class="{acty: reposFilter === 'forks'}" @click="changeReposFilter('forks')">
|
||||
{{.i18n.Tr "forks"}}
|
||||
<div v-show="reposFilter === 'forks'" class="ui circular mini grey label">${repoTypeCount}</div>
|
||||
</a>
|
||||
<a class="item" :class="{acty: reposFilter === 'mirrors'}" @click="changeReposFilter('mirrors')">
|
||||
{{.i18n.Tr "mirrors"}}
|
||||
<div v-show="reposFilter === 'mirrors'" class="ui circular mini grey label">${repoTypeCount}</div>
|
||||
</a>
|
||||
<a class="item" :class="{acty: reposFilter === 'collaborative'}" @click="changeReposFilter('collaborative')">
|
||||
{{.i18n.Tr "collaborative"}}
|
||||
<div v-show="reposFilter === 'collaborative'" class="ui circular mini grey label">${repoTypeCount}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui attached table segment">
|
||||
<ul class="repo-owner-name-list">
|
||||
<li v-for="repo in repos" :class="{'private': repo.private}" v-show="showRepo(repo, reposFilter)">
|
||||
<a :href="suburl + '/' + repo.full_name">
|
||||
<svg :class="'svg ' + repoClass(repo)" width="16" height="16" aria-hidden="true"><use :xlink:href="staticPrefix + '/img/svg/icons.svg#' + repoClass(repo)" /></svg>
|
||||
<strong class="text truncate item-name">${repo.full_name}</strong>
|
||||
<i v-if="repo.archived" class="archive icon archived-icon"></i>
|
||||
<span class="ui right text light grey">
|
||||
${repo.stars_count} <span class="rear">{{svg "octicon-star" 16}}</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="showMoreReposLink">
|
||||
<a :href="moreReposLink">{{.i18n.Tr "home.show_more_repos"}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!isOrganization" v-show="tab === 'organizations'" class="ui tab active list">
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "home.my_orgs"}} <span class="ui grey label">${organizationsTotalCount}</span>
|
||||
<div v-if="canCreateOrganization" class="ui right">
|
||||
<a class="poping up" :href="suburl + '/org/create'" data-content="{{.i18n.Tr "new_org"}}" data-variation="tiny inverted" data-position="left center">
|
||||
<i class="plus icon"></i>
|
||||
<span class="sr-only">{{.i18n.Tr "new_org"}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<ul class="repo-owner-name-list">
|
||||
<li v-for="org in organizations">
|
||||
<a :href="suburl + '/' + org.name">
|
||||
{{svg "octicon-organization" 16}}
|
||||
<strong class="text truncate item-name">${org.name}</strong>
|
||||
<span class="ui right text light grey">
|
||||
${org.num_repos} <span class="rear">{{svg "octicon-repo" 16}}</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</repo-search>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue