mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 00:57:22 +01:00
feat: use nixos-extra-modules
This commit is contained in:
parent
7ef0ebf5e7
commit
0caef3e587
19 changed files with 3397 additions and 1802 deletions
|
|
@ -1,4 +1,4 @@
|
|||
{ self, outputs, ... }:
|
||||
{ self, ... }:
|
||||
{
|
||||
|
||||
imports = [
|
||||
|
|
@ -8,12 +8,6 @@
|
|||
"${self}/modules/nixos/common/meta.nix"
|
||||
];
|
||||
|
||||
nixpkgs = {
|
||||
overlays = [ outputs.overlays.default ];
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.xcape = {
|
||||
enable = true;
|
||||
|
|
|
|||
108
hosts/nixos/summers/default.nix
Normal file
108
hosts/nixos/summers/default.nix
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
{ inputs, lib, config, configName, minimal, nodes, globals, ... }:
|
||||
{
|
||||
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./disk-config.nix
|
||||
];
|
||||
|
||||
boot = {
|
||||
loader.systemd-boot.enable = true;
|
||||
loader.efi.canTouchEfiVariables = true;
|
||||
};
|
||||
|
||||
# globals.hosts.${config.node.name}.ipv4 = config.repo.secrets.local.ipv4;
|
||||
|
||||
networking = {
|
||||
inherit (config.repo.secrets.local) hostId;
|
||||
hostName = configName;
|
||||
firewall.enable = true;
|
||||
enableIPv6 = true;
|
||||
};
|
||||
|
||||
swarselsystems = {
|
||||
info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
|
||||
flakePath = "/root/.dotfiles";
|
||||
isImpermanence = true;
|
||||
isSecureBoot = true;
|
||||
isCrypted = true;
|
||||
isBtrfs = true;
|
||||
isLinux = true;
|
||||
isNixos = true;
|
||||
withMicroVMs = false;
|
||||
};
|
||||
|
||||
} // lib.optionalAttrs (!minimal) {
|
||||
|
||||
swarselprofiles = {
|
||||
server = true;
|
||||
};
|
||||
|
||||
swarselmodules = {
|
||||
optional = {
|
||||
microvmHost = true;
|
||||
};
|
||||
server = {
|
||||
nfs = false;
|
||||
nginx = false;
|
||||
kavita = false;
|
||||
restic = false;
|
||||
jellyfin = false;
|
||||
navidrome = false;
|
||||
spotifyd = false;
|
||||
mpd = false;
|
||||
postgresql = false;
|
||||
matrix = false;
|
||||
nextcloud = false;
|
||||
immich = false;
|
||||
paperless = false;
|
||||
transmission = false;
|
||||
syncthing = false;
|
||||
grafana = false;
|
||||
emacs = false;
|
||||
freshrss = false;
|
||||
jenkins = false;
|
||||
kanidm = false;
|
||||
firefly-iii = false;
|
||||
koillection = false;
|
||||
radicale = false;
|
||||
atuin = false;
|
||||
forgejo = false;
|
||||
ankisync = false;
|
||||
homebox = false;
|
||||
opkssh = false;
|
||||
garage = false;
|
||||
};
|
||||
};
|
||||
|
||||
microvm.vms =
|
||||
let
|
||||
mkMicrovm = guestName: {
|
||||
${guestName} = {
|
||||
backend = "microvm";
|
||||
autostart = true;
|
||||
modules = [
|
||||
./guests/${guestName}.nix
|
||||
{
|
||||
node.secretsDir = ./secrets/${guestName};
|
||||
}
|
||||
];
|
||||
microvm = {
|
||||
system = "x86_64-linux";
|
||||
# baseMac = config.repo.secrets.local.networking.interfaces.lan.mac;
|
||||
# interfaces.vlan-services = { };
|
||||
};
|
||||
specialArgs = {
|
||||
inherit (config) nodes globals;
|
||||
inherit lib;
|
||||
inherit inputs minimal;
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
lib.mkIf (!minimal && config.swarselsystems.withMicroVMs) (
|
||||
{ }
|
||||
// mkMicrovm "guest1"
|
||||
);
|
||||
|
||||
}
|
||||
118
hosts/nixos/summers/disk-config.nix
Normal file
118
hosts/nixos/summers/disk-config.nix
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
type = "btrfs";
|
||||
extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite
|
||||
subvolumes = {
|
||||
"/root" = {
|
||||
mountpoint = "/";
|
||||
mountOptions = [
|
||||
"subvol=root"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/home" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||
mountpoint = "/home";
|
||||
mountOptions = [
|
||||
"subvol=home"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/persist" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||
mountpoint = "/persist";
|
||||
mountOptions = [
|
||||
"subvol=persist"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/log" = lib.mkIf config.swarselsystems.isImpermanence {
|
||||
mountpoint = "/var/log";
|
||||
mountOptions = [
|
||||
"subvol=log"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/nix" = {
|
||||
mountpoint = "/nix";
|
||||
mountOptions = [
|
||||
"subvol=nix"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
];
|
||||
};
|
||||
"/swap" = lib.mkIf config.swarselsystems.isSwap {
|
||||
mountpoint = "/.swapvol";
|
||||
swap.swapfile.size = config.swarselsystems.swapSize;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
disko.devices = {
|
||||
disk = {
|
||||
disk0 = {
|
||||
type = "disk";
|
||||
device = config.swarselsystems.rootDisk;
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
ESP = {
|
||||
priority = 1;
|
||||
name = "ESP";
|
||||
size = "512M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "defaults" ];
|
||||
};
|
||||
};
|
||||
root = lib.mkIf (!config.swarselsystems.isCrypted) {
|
||||
size = "100%";
|
||||
content = {
|
||||
inherit type subvolumes extraArgs;
|
||||
postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
|
||||
MNTPOINT=$(mktemp -d)
|
||||
mount "/dev/disk/by-label/nixos" "$MNTPOINT" -o subvolid=5
|
||||
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
|
||||
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
|
||||
'';
|
||||
};
|
||||
};
|
||||
luks = lib.mkIf config.swarselsystems.isCrypted {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "cryptroot";
|
||||
passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
|
||||
settings = {
|
||||
allowDiscards = true;
|
||||
# https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
|
||||
crypttabExtraOpts = [
|
||||
"fido2-device=auto"
|
||||
"token-timeout=10"
|
||||
];
|
||||
};
|
||||
content = {
|
||||
inherit type subvolumes extraArgs;
|
||||
postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
|
||||
MNTPOINT=$(mktemp -d)
|
||||
mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
|
||||
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
|
||||
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fileSystems."/persist".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
|
||||
fileSystems."/home".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
|
||||
}
|
||||
25
hosts/nixos/summers/guests/guest1/default.nix
Normal file
25
hosts/nixos/summers/guests/guest1/default.nix
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{ lib, minimal, ... }:
|
||||
{
|
||||
|
||||
swarselsystems = {
|
||||
info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
|
||||
};
|
||||
|
||||
} // lib.optionalAttrs (!minimal) {
|
||||
|
||||
swarselprofiles = {
|
||||
server = false;
|
||||
};
|
||||
|
||||
swarselmodules = {
|
||||
optional = {
|
||||
microvmGuest = false;
|
||||
};
|
||||
};
|
||||
|
||||
microvm = {
|
||||
mem = 1024 * 4;
|
||||
vcpu = 2;
|
||||
};
|
||||
|
||||
}
|
||||
28
hosts/nixos/summers/hardware-configuration.nix
Normal file
28
hosts/nixos/summers/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{ config, lib, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot = {
|
||||
initrd.availableKernelModules = [ "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
initrd.kernelModules = [ ];
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
extraModulePackages = [ ];
|
||||
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
zfs.extraPools = [ "Vault" ];
|
||||
};
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
15
hosts/nixos/summers/secrets/guest1/pii.nix.enc
Normal file
15
hosts/nixos/summers/secrets/guest1/pii.nix.enc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"data": "ENC[AES256_GCM,data:pGWiWA==,iv:sVpYJiphhvVPEo2MUMnpjlJmvf58/UJTTVVdU9dpqzM=,tag:2AsQRCyN9Pc/hnqviCo43g==,type:str]",
|
||||
"sops": {
|
||||
"lastmodified": "2025-11-06T12:11:19Z",
|
||||
"mac": "ENC[AES256_GCM,data:NBAgy3MNd+p8Ih6v/JuxuMWgh0k9xj5Trg7mggBE/LrxfCZg+BpbhYcmAw/FW9Du5gq3Pcynnql3dqwKlzHEtkEOcI1MJSnBSWexgLxwEtRwbTJVOqEkCxby6dcQ4HWD1ZZnwa9Q7Cg1vcPD/yZuzVUH15mFHic7s5M5Xzdfu/w=,iv:tv8CFuXJ0iqh/Vho7vSoOpfhcGfCElMLWNvjxoE3fMg=,tag:pGP3CjKFFm0UuVgSCnn4RA==,type:str]",
|
||||
"pgp": [
|
||||
{
|
||||
"created_at": "2025-11-06T12:11:04Z",
|
||||
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAAwZd6dmNcZqOWY7Ro6DXCRAD2LJuzR0AA26cRRzPgTPcw\nOwvV+Nh3hBWcZb5qkjKysZKGlIxzs4f02dKI172vUyIWQ6P5skygOOOpbr9g5171\nY0XTrmemesSKNfoUhsMFMCbFUc4HUxkUK7zadLk1AiBUqZMIFtx/riFMUBS2qTpR\nuLWiebt1Dw+rwcR8rBNxXPbeclm7322YOQDLUk4sHfi0vTvn+3sfGkbJ+OcJckoD\ndjVhWFqGUAbbELoR8yHpb+Ps6RYjKRNFNros9Yx9zQ18512gxOpRSzm0MTkKFyrz\n1UYVcv4Oz4W/e4nh1z2/re5X3l/HFUzwBG6AUTrYVuRo580kkZvWYFxHT6R+goVC\n5dhkqZpowrGpDIE/C7hKLenFIcOl1Nw5wgJ4Y9EmfZzorUnjJqT1Et2b2GU0hxvY\nKny+fiDeCfNdLzJejSNNg1/whoVmHbw3Q2aBJP0NL3nmNvaykO8RSA8WmzvQa+MA\nXweflh5G9lXOdH2vwb6EelOXpxlTjI7K/43Nbw/SXf/e1FKYK5l6TscyGEcHpFux\ns4ufYkCqTgxdKZjKwh0vqbdmbPUOCe/jqBOz6s/L/sR1/+8c2iIs0JVZd1VJSvDu\nIdfDfQh4wmso8L0qpjWimmkf0Y9itLWZo/oyioIqjVQ9+Daj2mvMkbKcSa486b2F\nAgwDC9FRLmchgYQBD/9lVmkHkPz5pbJV5U0nL3h/xx0JSyt6YYtLDacW8fw135GT\nojHijHvJAd1MqbNv391LcsZ1jtnUawNf6GAkr649lRuEH/WhNitXq20Z/06v5lwt\nGDhPMMf5uh+Uwgjxbeg/PFeTKILS2VX0tjJ8yeos2jNMOrmmwIg74V6mJk03E85K\nId06e2qNjzWlESyWOCFkfLQfSOTajQWmGyil8vNglmjuZdzLSE8eL6nA0hePnfJW\nOwewWcXEzHeeJsaevKFBBDpimAqi3XbKasQbZNSSFlkmw0vzAWKw5mzcdTMseae1\nLafjem7uw2epr4HIhwCZ47pCFrKcbweZMuUY557SomIGmv93OvglnZC40AYkJuNU\nIAVwNc8W/pd+jyiHh6tMlXfQ5/n25AcylDcacxxalNcKI0emNC90TsFc6wDpLh5D\n+R6kJ7GK8tI5BwIwtGIQmFsRREKE1x+IYATtKwQskb0Rng/D6eqNEvs8pjD1nGO3\nfNTG9G8PgC07TXSKGcNGytZy/GNSW9mnFgDgoiqh29bgfoJfSTWWvwZlzFXdWm0c\nzOiV5JSDRLewaqzhsQ/etms7qJIccRD7WcvM82x7UF0VYGd92EVsZxsq2aSVlMob\nCsxNXxij3qqNHdFgUuYYDzFym3/zmmi2wltPOZl7qYMhZI9P6wCsvDpxlFv16tJc\nAaBkBf1oOnjDvJm5i62KCEcRUmphKOB6Odr9/VHkAtgjPdWCOyge7ktbcwgsPw8L\ndemiSrNAglDX9RnPST5ggShZWn1Ik2mFfocCapvGBi5Hj9I/4xG/oIKREYc=\n=Ty0h\n-----END PGP MESSAGE-----",
|
||||
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
|
||||
}
|
||||
],
|
||||
"version": "3.11.0"
|
||||
}
|
||||
}
|
||||
26
hosts/nixos/summers/secrets/pii.nix.enc
Normal file
26
hosts/nixos/summers/secrets/pii.nix.enc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"data": "ENC[AES256_GCM,data:XTHUIhn7yVn2/EvZBSg1v+EU154Kj0hgvHbUdpnc2W4U+0UNBlqxRvVxw8XFm8uo1en2hXoS,iv:XeEzWY0UB/QqbxoIQJEOkWlaU5nyETl0Aki7iyRq/Y8=,tag:rcNiCc5a6+wLYAzX1pMxxQ==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBET1RmRTM5OUxJMGNyWUZK\nMXFqUWF2ZHhOZ1pxa0RDbkNzWnVzVFFCbTJrCm1oU25haDl5eFg5T1VzOXByai84\ndTR6TGREVnBHNlV4S254dzh2Z1lvK2sKLS0tIGFLaWJFQ2VwaWtxaURqNDU2ekRQ\na09Hbm4vNnVQaEV1aGtqTTVOUWN2b28KQaoPc/UKaeQ72GdlbtWFdALywHcUkewf\nK5pEz41pzDKOjatypm9X8ZEIEarjOHIZgMpazVM4i1PRUUefSE0phw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeGtTZ0ZSV0trWlQrS2dV\nSFo0dytGYXhRTjl6cDZrUU0wZ1IybDVRaFZrCmZmRmxJNmdwS0xodHdEOGU4bldU\nR1JScHAvZHhlVTBJbWExb0VpR0h2MXMKLS0tIDYwQmZpMjdYRmpBeXFNOXArN0h5\nVGN1THljeCtVV0hXenMyRVJkMjlHNEEKm+yZTT48nYr3H0Bd1OKw/CYk1kwnrBzk\nTgSQHsGXhmOyDag9cSZ4wAOmqtqSjA9bouFBuhl2lSbgpjnarvFaXQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-11-06T11:16:16Z",
|
||||
"mac": "ENC[AES256_GCM,data:rBE1qTiaLme63i23YL16qmDE6rcKaxwWwzzqgsv4SmKCBJonjiyUc4DyRU8JuCbTx6K9+4VtERJzTLlbXhvjXl27LRQtfbNSBXBIyTgdSz0Fo46lDdVUMFSdPDbU97XAx9P3eu425aspkJYxffOJ2lvqinAVuw9U6oBpot5jVaw=,iv:N3mp0DY80UVGa4Vf4ya+5B/9w8iTihAyg/XgStgtHAo=,tag:tKjnbFm0yFddj759OK5Mdw==,type:str]",
|
||||
"pgp": [
|
||||
{
|
||||
"created_at": "2025-08-24T23:36:17Z",
|
||||
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAAwf7TLx0TR1HBhh57CyIQLw8ztc9oblKAW/V7bSlQM/wR\nIwQTcTi3azdI9yewDRO30rIr++FEapdGVdpXoqQ8zcl49VjwDux6wzF3bsmR5Goc\nlTkDd0bmz8RBfsK+6efXiRqo3C0yP2ZTOh3PSOvsXKbYS6wY3TvNBdGnAYrfOvEw\nmBFRhn6uakw3zjVUngB1di07DH3y0wEb/r6+Mzoswzg4DqT1SAdDkfS9dpn9h3MW\n3NBesYlOukLrNA5Toi6x/fmE2lrPHt5QxPdvfvKe5ye4myZ/gBn1mdejB6U9nOsk\nRCJFMosjBH7jIpwokTjUT6Vs+zs8yrF+gbP82H4RVfZymMfdZoU/pTfYe1Mwg6Yi\ntlHyiRBgSPBY8Doa2hM8/yvmfHVMqSQf8uXltz2VC7JUGD6P0QbDLpqY3URmHg/q\nwN3zYJLlSIkU6Z7oivTjfg0dR32Z80lCdZDQf+OQsRtCUi169Fgxr7+HhdxJyj49\nFIb6CR0DHW4vsEj1GPAa0Q4uMfCxLiSZfesY8myoCtlVo7oeqx787KicJB5PryHr\nyZweKd7tXO9g8LNJtECTZ81y2/sCfSZPBia6M4oz56pIFK4jhYCY3iPnWIS77axu\n5MmqZNOP06obp87nt1ea51BmXkaYxmSPoQ5R29CeYU+m9q+kKvizncgsCl/O7U6F\nAgwDC9FRLmchgYQBEADJo2kPzrxLHptsr6aoIxfYNrQ7JJM3FAZ7do5YvAbQsl5t\ny45qZ4+qWIEMRXwji2TvgSg8/ylnZfN2+rTHdtNJkDdJ2sX+RDr8pm7L3VS2Zhjf\nIp1SdPd5cm/3QupegzUR+kcPa+gPM4asGSytIkAnnpev/DCnLsrqiejdosTDj9dn\nFtPKJKSUBzJSNRxBSpM9L+cTU1qyMT024D5Qvq6vBOjFI1YV3LSfVXQe7OZxxxVX\naChkGR1v3UjndQ4Yv9hamJJ81lRLeIcVEOpOPxLHJX76AJUqP3fR/+m2Poah8bFF\n+yIdSp2jyWOoU60We72fvlEwxsTLl8Zani+xX2ckkUCe+wsiGJLch4Df1pepxpef\nb95wZ9L0msRdHY8vRQYapde/ju8CUHgywVX7+YH3EF1bJSnUOBmyOA76v9ir09am\n49g+VomkWUuzPJ2VYQXXH6d/qn/sm9Z9yxy7e1eh5m+9cd42b4sMdW6ZCTMAtGJF\nPX0SiOMR6S0hjKVBcfcyNoT/wo7wqEl4mYDpoCy10K0nYRn+ggJnIZEJzBWibMYH\nDWUDyuQIYLjOBAchFatXyMtbc8qDorYelLX7amPRDSiDhhj6Y5nYMJtUSwfTLwkN\nrI0Q4bjE+fgNACCqPoq/BDFZotcr1b664ZUJqgnTBPKZ5OnmW/iFkOfzu4fF9tJe\nAcekEPwsFbugu2bZ0Hs5Rl/Dh9p4L9gceuMiwJ3oYGA5cwXFCeVZLNqSDLy4upVX\nnXRaMzBNGgWo4geDq5JL10Mh7/1d4GGVxdts8RGdI8zUFTPV3GOaPEHeNyIO+g==\n=2UMI\n-----END PGP MESSAGE-----",
|
||||
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
|
||||
}
|
||||
],
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.11.0"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue