Compare commits

..

1 Commits

Author SHA1 Message Date
5152159691 try to add Kaiteki as a package
requires updating dart (flutter), which is causing problems...
2022-06-05 02:28:23 -07:00
100 changed files with 1438 additions and 3023 deletions

View File

@@ -1,33 +0,0 @@
keys:
- &user_desko_colin age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x
- &user_lappy_colin age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g
- &user_servo_colin age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu
- &user_moby_colin age1lt739n2tq7dmpglvntjr9j2r7426md7rat7x9w930gagtx4jyvnqwts2al
- &host_desko age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v
- &host_lappy age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn
- &host_servo age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf
- &host_moby age1t957gf0z865gya0khgc9x59wy76hzps3sgejjqtwcngn2xl273msxsmpe6
creation_rules:
- path_regex: secrets/universal*
key_groups:
- age:
- *user_desko_colin
- *user_lappy_colin
- *user_servo_colin
- *user_moby_colin
- *host_desko
- *host_lappy
- *host_servo
- *host_moby
- path_regex: secrets/servo.yaml$
key_groups:
- age:
- *user_desko_colin
- *user_servo_colin
- *host_servo
- path_regex: secrets/desko.yaml$
key_groups:
- age:
- *user_desko_colin
- *user_lappy_colin
- *host_desko

13
TODO.md
View File

@@ -1,7 +1,10 @@
# features/tweaks
- enable sshfs (deskto/lappy)
- set firefox default search engine
- iron out video drivers
- emoji picker application
- find a Masto/Pleroma app which works on mobile
# cleanup
- remove helpers from outputs section (use `let .. in`)
# speed up cross compiling
@@ -10,3 +13,9 @@
overlays = [{ ... }: {
nixpkgs.crossSystem.system = "aarch64-linux";
}];
# better secrets management? read:
- decrypted at activation time: https://github.com/Mic92/sops-nix
less promising:
- https://christine.website/blog/nixos-encrypted-secrets-2021-01-20
- git-crypt (https://github.com/bobbbay/dotfiles.git)

25
configuration.nix Normal file
View File

@@ -0,0 +1,25 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
# USEFUL COMMANDS:
# nix show-config
# nix eval --raw <expr> => print an expression. e.g. nixpkgs.raspberrypifw prints store path to the package
# nix-option ## query options -- including their SET VALUE; similar to search: https://search.nixos.org/options
# nixos-rebuild switch --upgrade ## pull changes from the nixos channel (e.g. security updates) and rebuild
{ config, pkgs, ... }:
{
# enable flake support.
# the real config root lives in flake.nix
nix = {
#package = pkgs.nixFlakes;
package = pkgs.nixUnstable;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
}

111
flake.lock generated
View File

@@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1656169755,
"narHash": "sha256-Nlnm4jeQWEGjYrE6hxi/7HYHjBSZ/E0RtjCYifnNsWk=",
"lastModified": 1654113405,
"narHash": "sha256-VpK+0QaWG2JRgB00lw77N9TjkE3ec0iMYIX1TzGpxa4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "4a3d01fb53f52ac83194081272795aa4612c2381",
"rev": "ac2287df5a2d6f0a44bbcbd11701dbbf6ec43675",
"type": "github"
},
"original": {
@@ -21,29 +21,14 @@
"type": "github"
}
},
"impermanence": {
"locked": {
"lastModified": 1646131459,
"narHash": "sha256-GPmgxvUFvQ1GmsGfWHy9+rcxWrczeDhS9XnAIPHi9XQ=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "2f39baeb7d039fda5fc8225111bb79474138e6f4",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "impermanence",
"type": "github"
}
},
"mobile-nixos": {
"flake": false,
"locked": {
"lastModified": 1656299939,
"narHash": "sha256-gODt71CCv0gnMNeU4GYdSBJkxsfmBy0uNv8owQC1oPs=",
"lastModified": 1654281294,
"narHash": "sha256-hT2/u0jUOD4TFU6YyYt+5Gt+hjIeerLTyZG7ru79aDU=",
"owner": "nixos",
"repo": "mobile-nixos",
"rev": "de9a88a70f0ae5fc0839ff94bf29e8a30af399f8",
"rev": "d798b0b34240b18a08c22f5c0ee1f59a3ce43c01",
"type": "github"
},
"original": {
@@ -54,11 +39,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1656679828,
"narHash": "sha256-akGA97pR1BAQew1FrVTCME3p8qvYxJXB2X3a13aBphs=",
"lastModified": 1654275867,
"narHash": "sha256-pt14ZE4jVPGvfB2NynGsl34pgXfOqum5YJNpDK4+b9E=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "915f5a5b3cc4f8ba206afd0b70e52ba4c6a2796b",
"rev": "7a20c208aacf4964c19186dcad51f89165dc7ed0",
"type": "github"
},
"original": {
@@ -67,61 +52,13 @@
"type": "indirect"
}
},
"nixpkgs-21_11": {
"locked": {
"lastModified": 1656198488,
"narHash": "sha256-xe81o3Kin6a0jXA3mTxcR+jeA1jLKw3TCar5LUo/B5c=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "46af3303651699dc58cfc251d9b18c0f59d857da",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-21.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-22_05": {
"locked": {
"lastModified": 1656199498,
"narHash": "sha256-/BCpM7j7y1G4het6Z3idlnv9A87/s0O1glVmH7fnWvk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "72a1f167077060a1a7b6e0104863245d0483fa7f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-22.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1656130826,
"narHash": "sha256-g5Wo75ddDQmWnL70rJCMm+JJlvHbzPFUePUpuMNn5qk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "72d1b0d0fac131df1ea254b65413c85609bdd2ee",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nurpkgs": {
"locked": {
"lastModified": 1656786319,
"narHash": "sha256-MpdBL2+csFfnMu+2eUNkkACkrPt7UhUdpvXnhrLim0E=",
"lastModified": 1654367137,
"narHash": "sha256-xufB/+qvk/7rh7qrwZbzru1kTu8nsmNWBNQkYbdS84Q=",
"owner": "nix-community",
"repo": "NUR",
"rev": "433704dc83b1491725e616bbb898ccd17fbe3d0e",
"rev": "86ff2d098bce1d623232f4886027a1d61317b195",
"type": "github"
},
"original": {
@@ -133,31 +70,9 @@
"root": {
"inputs": {
"home-manager": "home-manager",
"impermanence": "impermanence",
"mobile-nixos": "mobile-nixos",
"nixpkgs": "nixpkgs",
"nurpkgs": "nurpkgs",
"sops-nix": "sops-nix"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": "nixpkgs_2",
"nixpkgs-21_11": "nixpkgs-21_11",
"nixpkgs-22_05": "nixpkgs-22_05"
},
"locked": {
"lastModified": 1656399028,
"narHash": "sha256-re66+rVHGR3y+0QsaDAwoAHCfoi3BlGV24t2EqRZsAE=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "d26947f2d6252e2aae5ffddfe9b38b7c4b94e8f9",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
"nurpkgs": "nurpkgs"
}
}
},

149
flake.nix
View File

@@ -15,69 +15,102 @@
inputs.nixpkgs.follows = "nixpkgs";
};
nurpkgs.url = "github:nix-community/NUR";
sops-nix.url = "github:Mic92/sops-nix";
impermanence.url = "github:nix-community/impermanence";
};
outputs = { self, nixpkgs, mobile-nixos, home-manager, nurpkgs, sops-nix, impermanence }:
let
patchedPkgs = system: nixpkgs.legacyPackages.${system}.applyPatches {
name = "nixpkgs-patched-uninsane";
src = nixpkgs;
patches = import ./nixpatches/list.nix nixpkgs.legacyPackages.${system}.fetchpatch;
};
# return something which behaves like `pkgs`, for the provided system
nixpkgsFor = system: import (patchedPkgs system) { inherit system; };
# evaluate ONLY our overlay, for the provided system
customPackagesFor = system: import ./pkgs/overlay.nix (nixpkgsFor system) (nixpkgsFor system);
decl-machine = { name, system }:
let
nixosSystem = import ((patchedPkgs system) + "/nixos/lib/eval-config.nix");
in (nixosSystem {
inherit system;
specialArgs = { inherit nixpkgs mobile-nixos home-manager nurpkgs impermanence; };
modules = [
./modules
./machines/${name}
(import ./helpers/set-hostname.nix name)
sops-nix.nixosModules.sops
{
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [
nurpkgs.overlay
(import "${mobile-nixos}/overlay/overlay.nix")
(import ./pkgs/overlay.nix)
];
}
];
outputs = { self, nixpkgs, mobile-nixos, home-manager, nurpkgs }: {
machines.uninsane = self.decl-bootable-machine { name = "uninsane"; system = "aarch64-linux"; };
machines.desko = self.decl-bootable-machine { name = "desko"; system = "x86_64-linux"; };
machines.lappy = self.decl-bootable-machine { name = "lappy"; system = "x86_64-linux"; };
machines.moby =
let machine = self.decl-machine {
name = "moby";
system = "aarch64-linux";
extraModules = [
(import "${mobile-nixos}/lib/configuration.nix" {
device = "pine64-pinephone";
})
];
};
in {
nixosConfiguration = machine;
img = machine.config.mobile.outputs.u-boot.disk-image;
};
nixosConfigurations = builtins.mapAttrs (name: value: value.nixosConfiguration) self.machines;
imgs = builtins.mapAttrs (name: value: value.img) self.machines;
decl-machine = { name, system, extraModules ? [], basePkgs ? nixpkgs }: let
patchedPkgs = basePkgs.legacyPackages.${system}.applyPatches {
name = "nixpkgs-patched-uninsane";
src = basePkgs;
patches = [
# for mobile: allow phoc to scale to non-integer values
./nixpatches/01-phosh-float-scale.patch
# for raspberry pi: allow building u-boot for rpi 4{,00}
./nixpatches/02-rpi4-uboot.patch
./nixpatches/03-whalebird-4.6.0.patch
./nixpatches/04-dart-2.7.0.patch
];
};
nixosSystem = import (patchedPkgs + "/nixos/lib/eval-config.nix");
in (nixosSystem {
inherit system;
specialArgs = { inherit home-manager; inherit nurpkgs; secrets = import ./secrets/default.nix; };
modules = [
./configuration.nix
./machines/${name}
(import ./helpers/set-hostname.nix name)
(self.overlaysModule system)
] ++ extraModules;
});
decl-bootable-machine = { name, system }: rec {
nixosConfiguration = decl-machine { inherit name system; };
# this produces a EFI-bootable .img file (GPT with a /boot partition and a system (/ or /nix) partition).
# after building this:
# - flash it to a bootable medium (SD card, flash drive, HDD)
# - resize the root partition (use cfdisk)
# - mount the part
# chown root:nixblkd <part>/nix/store
# chmod 775 <part>/nix/store
# chown root:root -R <part>/nix/store/*
# populate any important things (persist/, home/colin/.ssh, etc)
# - boot
# - if fs wasn't resized automatically, then `sudo btrfs filesystem resize max /`
# - checkout this flake into /etc/nixos AND UPDATE THE FS UUIDS.
# - `nixos-rebuild --flake './#<machine>' switch`
img = nixosConfiguration.config.system.build.img;
# this produces a EFI-bootable .img file (GPT with / and /boot).
# after building this, steps are:
# run `btrfs-convert --uuid copy <device>`
# boot, checkout this flake into /etc/nixos AND UPDATE THE UUIDS IT REFERENCES.
# then `nixos-rebuild ...`
decl-img = { name, system, extraModules ? [] }: (
(self.decl-machine { inherit name; inherit system; extraModules = extraModules ++ [./image.nix]; })
.config.system.build.raw
);
decl-bootable-machine = { name, system }: {
nixosConfiguration = self.decl-machine { inherit name; inherit system; };
img = self.decl-img { inherit name; inherit system; };
};
overlaysModule = system: { config, pkgs, ...}: {
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [
#mobile-nixos.overlay
nurpkgs.overlay
(next: prev: {
#### customized packages
# nixos-unstable pleroma is too far out-of-date for our db
pleroma = prev.callPackage ./pkgs/pleroma { };
# jackett doesn't allow customization of the bind address: this will probably always be here.
jackett = next.callPackage ./pkgs/jackett { pkgs = prev; };
# fix abrupt HDD poweroffs as during reboot. patching systemd requires rebuilding nearly every package.
# systemd = import ./pkgs/systemd { pkgs = prev; };
# patch rpi uboot with something that fixes USB HDD boot
ubootRaspberryPi4_64bit = next.callPackage ./pkgs/ubootRaspberryPi4_64bit { pkgs = prev; };
#### TEMPORARY NIXOS-UNSTABLE PACKAGES
# stable telegram doesn't build, so explicitly use the stable one.
# TODO: apply this specifically to the moby build?
# tdesktop = pkgs-telegram.legacyPackages.${system}.tdesktop;
tdesktop = nixpkgs.legacyPackages.${system}.tdesktop;
#### TEMPORARY: PACKAGES WAITING TO BE UPSTREAMED
whalebird = prev.callPackage ./pkgs/whalebird { };
kaiteki = prev.callPackage ./pkgs/kaiteki { };
})
];
};
machines.servo = decl-bootable-machine { name = "servo"; system = "aarch64-linux"; };
machines.desko = decl-bootable-machine { name = "desko"; system = "x86_64-linux"; };
machines.lappy = decl-bootable-machine { name = "lappy"; system = "x86_64-linux"; };
machines.moby = decl-bootable-machine { name = "moby"; system = "aarch64-linux"; };
in {
nixosConfigurations = builtins.mapAttrs (name: value: value.nixosConfiguration) machines;
imgs = builtins.mapAttrs (name: value: value.img) machines;
packages.x86_64-linux = customPackagesFor "x86_64-linux";
packages.aarch64-linux = customPackagesFor "aarch64-linux";
};
}

13
helpers/gui/gnome.nix Normal file
View File

@@ -0,0 +1,13 @@
{ config, pkgs, lib, ... }:
{
# start gnome/gdm on boot
services.xserver.enable = true;
services.xserver.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
# gnome does networking stuff with networkmanager
networking.useDHCP = false;
networking.networkmanager.enable = true;
networking.wireless.enable = lib.mkForce false;
}

16
helpers/gui/i3.nix Normal file
View File

@@ -0,0 +1,16 @@
{ pkgs, ... }:
{
environment.pathsToLink = [ "/libexec" ]; # patch for i3blocks to work
services.xserver.enable = true;
services.xserver.displayManager.defaultSession = "none+i3";
services.xserver.windowManager.i3 = {
enable = true;
extraPackages = with pkgs; [
dmenu
i3status
i3lock
i3blocks
];
};
}

21
helpers/gui/phosh.nix Normal file
View File

@@ -0,0 +1,21 @@
{ ... }:
{
# docs: https://github.com/NixOS/nixpkgs/blob/nixos-22.05/nixos/modules/services/x11/desktop-managers/phosh.nix
services.xserver.desktopManager.phosh = {
enable = true;
user = "colin";
group = "users";
phocConfig = {
xwayland = "true";
# find default outputs by catting /etc/phosh/phoc.ini
outputs.DSI-1 = {
scale = 1.5;
};
};
};
environment.variables = {
# Qt apps won't always start unless this env var is set
QT_QPA_PLATFORM = "wayland";
};
}

View File

@@ -0,0 +1,14 @@
{ config, pkgs, lib, ... }:
{
# start plasma-mobile on boot
services.xserver.enable = true;
services.xserver.desktopManager.plasma5.mobile.enable = true;
services.xserver.desktopManager.plasma5.mobile.installRecommendedSoftware = false; # not all plasma5-mobile packages build for aarch64
services.xserver.displayManager.sddm.enable = true;
# Plasma does networking stuff with networkmanager, but nix configures the defaults itself
# networking.useDHCP = false;
# networking.networkmanager.enable = true;
# networking.wireless.enable = lib.mkForce false;
}

31
helpers/gui/sway.nix Normal file
View File

@@ -0,0 +1,31 @@
{ pkgs, ... }:
# docs: https://nixos.wiki/wiki/Sway
{
programs.sway = {
# we configure sway with home-manager, but this enable gets us e.g. opengl and fonts
enable = true;
};
# TODO: should be able to use SDDM to get interactive login
services.greetd = {
enable = true;
settings = rec {
initial_session = {
command = "${pkgs.sway}/bin/sway";
user = "colin";
};
default_session = initial_session;
};
};
# unlike other DEs, sway configures no audio stack
# administer with pw-cli, pw-mon, pw-top commands
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true; # ??
pulse.enable = true;
};
}

View File

@@ -0,0 +1,65 @@
{ config, pkgs, lib, ... }:
{
boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
"usb_storage" # rpi needed this to boot from usb storage, i think.
# "usbhid" "hid-generic" # hopefully these will fix USB HID auto-sleep ?
];
boot.initrd.kernelModules = [ ];
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
# find more of these with sensors-detect
boot.kernelModules = [
"coretemp"
"kvm-intel"
"kvm-amd" # desktop
"amdgpu" # desktop
];
boot.extraModulePackages = [ ];
boot.kernelParams = [ "boot.shell_on_fail" ];
boot.consoleLogLevel = 7;
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.configurationLimit = 40; # keep this many generations
boot.loader.efi.canTouchEfiVariables = true;
# enable cross compilation
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
# nixpkgs.crossSystem.system = "aarch64-linux";
powerManagement.cpuFreqGovernor = "powersave";
hardware.enableRedistributableFirmware = true;
hardware.cpu.amd.updateMicrocode = true; # desktop
hardware.cpu.intel.updateMicrocode = true; # laptop
services.fwupd.enable = true;
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
powerManagement.powertop.enable = false;
hardware.opengl.extraPackages = [
# laptop
pkgs.intel-compute-runtime
pkgs.intel-media-driver # new
pkgs.libvdpau-va-gl # new
pkgs.vaapiIntel
# desktop
pkgs.rocm-opencl-icd
pkgs.rocm-opencl-runtime
];
hardware.opengl.driSupport = true;
# For 32 bit applications
hardware.opengl.driSupport32Bit = true;
# TODO colin: does this *do* anything?
swapDevices = [ ];
# services.snapper.configs = {
# root = {
# subvolume = "/";
# extraConfig = {
# ALLOW_USERS = "colin";
# };
# };
# };
# services.snapper.snapshotInterval = "daily";
}

View File

@@ -0,0 +1,532 @@
# docs:
# https://rycee.gitlab.io/home-manager/
# https://rycee.gitlab.io/home-manager/options.html
# man home-configuration.nix
#
# system is e.g. x86_64-linux
# gui is "gnome", or null
{ lib, pkgs, system, gui, extraPackages ? [] }: {
home.stateVersion = "21.11";
home.username = "colin";
home.homeDirectory = "/home/colin";
programs.home-manager.enable = true; # this lets home-manager manage dot-files in user dirs, i think
# XDG defines things like ~/Desktop, ~/Downloads, etc.
# these clutter the home, so i mostly don't use them.
xdg.userDirs = {
enable = true;
createDirectories = false; # on headless systems, most xdg dirs are noise
desktop = "$HOME/.xdg/Desktop";
documents = "$HOME/src";
download = "$HOME/tmp";
music = "$HOME/Music";
pictures = "$HOME/Pictures";
publicShare = "$HOME/.xdg/Public";
templates = "$HOME/.xdg/Templates";
videos = "$HOME/Videos";
};
programs.zsh = {
enable = true;
enableSyntaxHighlighting = true;
enableVteIntegration = true;
dotDir = ".config/zsh";
initExtraBeforeCompInit = ''
# p10k instant prompt
# run p10k configure to configure, but it can't write out its file :-(
POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true
'';
# prezto = oh-my-zsh fork; controls prompt, auto-completion, etc.
# see: https://github.com/sorin-ionescu/prezto
prezto = {
enable = true;
pmodules = [
"environment"
"terminal"
"editor"
"history"
"directory"
"spectrum"
"utility"
"completion"
"prompt"
"git"
];
prompt = {
theme = "powerlevel10k";
};
};
};
programs.kitty.enable = true;
programs.git = {
enable = true;
userName = "colin";
userEmail = "colin@uninsane.org";
};
programs.vim = {
enable = true;
extraConfig = ''
" wtf vim project: NOBODY LIKES MOUSE FOR VISUAL MODE
set mouse-=a
" copy/paste to system clipboard
set clipboard=unnamedplus
" <tab> completion menu settings
set wildmenu
set wildmode=longest,list,full
" highlight all matching searches (using / and ?)
set hlsearch
" allow backspace to delete empty lines in insert mode
set backspace=indent,eol,start
" built-in syntax highlighting
syntax enable
" show line/col number in bottom right
set ruler
" highlight trailing space & related syntax errors (does this work?)
let c_space_errors=1
let python_space_errors=1
'';
};
# obtain these by running `dconf dump /` after manually customizing gnome
# TODO: fix "is not of type `GVariant value'"
# dconf.settings = lib.mkIf (gui == "gnome") {
# gnome = {
# # control alt-tab behavior
# "org/gnome/desktop/wm/keybindings" = {
# switch-applications = [ "<Super>Tab" ];
# switch-applications-backward=[];
# switch-windows=["<Alt>Tab"];
# switch-windows-backward=["<Super><Alt>Tab"];
# };
# # idle power savings
# "org/gnome/settings-deamon/plugins/power" = {
# idle-brigthness = 50;
# sleep-inactive-ac-type = "nothing";
# sleep-inactive-battery-timeout = 5400; # seconds
# };
# "org/gnome/shell" = {
# favorite-apps = [
# "org.gnome.Nautilus.desktop"
# "firefox.desktop"
# "kitty.desktop"
# # "org.gnome.Terminal.desktop"
# ];
# };
# "org/gnome/desktop/session" = {
# # how long until considering a session idle (triggers e.g. screen blanking)
# idle-delay = 900;
# };
# "org/gnome/desktop/interface" = {
# text-scaling-factor = 1.25;
# };
# "org/gnome/desktop/media-handling" = {
# # don't auto-mount inserted media
# automount = false;
# automount-open = false;
# };
# };
# };
# home.pointerCursor = {
# package = pkgs.vanilla-dmz;
# name = "Vanilla-DMZ";
# };
# taken from https://github.com/srid/nix-config/blob/705a70c094da53aa50cf560179b973529617eb31/nix/home/i3.nix
xsession.windowManager.i3 = lib.mkIf (gui == "i3") (
let
mod = "Mod4";
in {
enable = true;
config = {
modifier = mod;
fonts = {
names = [ "DejaVu Sans Mono" ];
style = "Bold Semi-Condensed";
size = 11.0;
};
# terminal = "kitty";
# terminal = "${pkgs.kitty}/bin/kitty";
keybindings = {
"${mod}+Return" = "exec ${pkgs.kitty}/bin/kitty";
"${mod}+p" = "exec ${pkgs.dmenu}/bin/dmenu_run";
"${mod}+x" = "exec sh -c '${pkgs.maim}/bin/maim -s | xclip -selection clipboard -t image/png'";
"${mod}+Shift+x" = "exec sh -c '${pkgs.i3lock}/bin/i3lock -c 222222 & sleep 5 && xset dpms force of'";
# Focus
"${mod}+j" = "focus left";
"${mod}+k" = "focus down";
"${mod}+l" = "focus up";
"${mod}+semicolon" = "focus right";
# Move
"${mod}+Shift+j" = "move left";
"${mod}+Shift+k" = "move down";
"${mod}+Shift+l" = "move up";
"${mod}+Shift+semicolon" = "move right";
# multi monitor setup
# "${mod}+m" = "move workspace to output DP-2";
# "${mod}+Shift+m" = "move workspace to output DP-5";
};
# bars = [
# {
# position = "bottom";
# statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ${./i3status-rust.toml}";
# }
# ];
};
});
wayland.windowManager.sway = lib.mkIf (gui == "sway") {
enable = true;
wrapperFeatures.gtk = true;
config = rec {
terminal = "${pkgs.kitty}/bin/kitty";
window.border = 3; # pixel boundary between windows
# defaults; required for keybindings decl.
modifier = "Mod1";
# list of launchers: https://www.reddit.com/r/swaywm/comments/v39hxa/your_favorite_launcher/
# menu = "${pkgs.dmenu}/bin/dmenu_path";
menu = "${pkgs.fuzzel}/bin/fuzzel";
# menu = "${pkgs.albert}/bin/albert";
left = "h";
down = "j";
up = "k";
right = "l";
keybindings = {
"${modifier}+Return" = "exec ${terminal}";
"${modifier}+Shift+q" = "kill";
"${modifier}+d" = "exec ${menu}";
"${modifier}+${left}" = "focus left";
"${modifier}+${down}" = "focus down";
"${modifier}+${up}" = "focus up";
"${modifier}+${right}" = "focus right";
"${modifier}+Left" = "focus left";
"${modifier}+Down" = "focus down";
"${modifier}+Up" = "focus up";
"${modifier}+Right" = "focus right";
"${modifier}+Shift+${left}" = "move left";
"${modifier}+Shift+${down}" = "move down";
"${modifier}+Shift+${up}" = "move up";
"${modifier}+Shift+${right}" = "move right";
"${modifier}+Shift+Left" = "move left";
"${modifier}+Shift+Down" = "move down";
"${modifier}+Shift+Up" = "move up";
"${modifier}+Shift+Right" = "move right";
"${modifier}+b" = "splith";
"${modifier}+v" = "splitv";
"${modifier}+f" = "fullscreen toggle";
"${modifier}+a" = "focus parent";
"${modifier}+s" = "layout stacking";
"${modifier}+w" = "layout tabbed";
"${modifier}+e" = "layout toggle split";
"${modifier}+Shift+space" = "floating toggle";
"${modifier}+space" = "focus mode_toggle";
"${modifier}+1" = "workspace number 1";
"${modifier}+2" = "workspace number 2";
"${modifier}+3" = "workspace number 3";
"${modifier}+4" = "workspace number 4";
"${modifier}+5" = "workspace number 5";
"${modifier}+6" = "workspace number 6";
"${modifier}+7" = "workspace number 7";
"${modifier}+8" = "workspace number 8";
"${modifier}+9" = "workspace number 9";
"${modifier}+Shift+1" =
"move container to workspace number 1";
"${modifier}+Shift+2" =
"move container to workspace number 2";
"${modifier}+Shift+3" =
"move container to workspace number 3";
"${modifier}+Shift+4" =
"move container to workspace number 4";
"${modifier}+Shift+5" =
"move container to workspace number 5";
"${modifier}+Shift+6" =
"move container to workspace number 6";
"${modifier}+Shift+7" =
"move container to workspace number 7";
"${modifier}+Shift+8" =
"move container to workspace number 8";
"${modifier}+Shift+9" =
"move container to workspace number 9";
"${modifier}+Shift+minus" = "move scratchpad";
"${modifier}+minus" = "scratchpad show";
"${modifier}+Shift+c" = "reload";
"${modifier}+Shift+e" =
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
"${modifier}+r" = "mode resize";
} // {
# media keys
XF86MonBrightnessDown = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set 2%-"'';
XF86MonBrightnessUp = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set +2%"'';
XF86AudioRaiseVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
XF86AudioLowerVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
XF86AudioMute = "exec '${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute'";
};
# mostly defaults:
bars = [{
mode = "dock";
hiddenState = "hide";
position = "top";
command = "${pkgs.waybar}/bin/waybar";
workspaceButtons = true;
workspaceNumbers = true;
statusCommand = "${pkgs.i3status}/bin/i3status";
fonts = {
names = [ "monospace" ];
size = 8.0;
};
trayOutput = "primary";
colors = {
background = "#000000";
statusline = "#ffffff";
separator = "#666666";
focusedWorkspace = {
border = "#4c7899";
background = "#285577";
text = "#ffffff";
};
activeWorkspace = {
border = "#333333";
background = "#5f676a";
text = "#ffffff";
};
inactiveWorkspace = {
border = "#333333";
background = "#222222";
text = "#888888";
};
urgentWorkspace = {
border = "#2f343a";
background = "#900000";
text = "#ffffff";
};
bindingMode = {
border = "#2f343a";
background = "#900000";
text = "#ffffff";
};
};
}];
};
};
programs.waybar = lib.mkIf (gui == "sway") {
enable = true;
# docs: https://github.com/Alexays/Waybar/wiki/Configuration
settings = {
mainBar = {
layer = "top";
height = 40;
modules-left = ["sway/workspaces" "sway/mode"];
modules-center = ["sway/window"];
modules-right = ["custom/mediaplayer" "clock" "cpu" "network"];
"sway/window" = {
max-length = 50;
};
# include song artist/title. source: https://www.reddit.com/r/swaywm/comments/ni0vso/waybar_spotify_tracktitle/
"custom/mediaplayer" = {
exec = pkgs.writeShellScript "waybar-mediaplayer" ''
player_status=$(${pkgs.playerctl}/bin/playerctl status 2> /dev/null)
if [ "$player_status" = "Playing" ]; then
echo "$(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
elif [ "$player_status" = "Paused" ]; then
echo " $(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
fi
'';
interval = 2;
format = "{} ";
# return-type = "json";
on-click = "${pkgs.playerctl}/bin/playerctl play-pause";
on-scroll-up = "${pkgs.playerctl}/bin/playerctl next";
on-scroll-down = "${pkgs.playerctl}/bin/playerctl previous";
};
network = {
interval = 1;
format-ethernet = "{ifname}: {ipaddr}/{cidr} up: {bandwidthUpBits} down: {bandwidthDownBits}";
};
cpu = {
format = "{usage}% ";
tooltip = false;
};
clock = {
format-alt = "{:%a, %d. %b %H:%M}";
};
};
};
# style = ''
# * {
# border: none;
# border-radius: 0;
# font-family: Source Code Pro;
# }
# window#waybar {
# background: #16191C;
# color: #AAB2BF;
# }
# #workspaces button {
# padding: 0 5px;
# }
# .custom-spotify {
# padding: 0 10px;
# margin: 0 4px;
# background-color: #1DB954;
# color: black;
# }
# '';
};
programs.firefox = lib.mkIf (gui != null) {
enable = true;
profiles.default = {
bookmarks = {
fed_uninsane.url = "https://fed.uninsane.org/";
delightful.url = "https://delightful.club/";
crowdsupply.url = "https://www.crowdsupply.com/";
linux_phone_apps.url = "https://linuxphoneapps.org/mobile-compatibility/5/";
mempool.url = "https://jochen-hoenicke.de/queue";
};
};
# firefox profile support seems to be broken :shrug:
# profiles.other = {
# id = 2;
# };
# NB: these must be manually enabled in the Firefox settings on first start
# extensions can be found here: https://gitlab.com/rycee/nur-expressions/-/blob/master/pkgs/firefox-addons/addons.json
extensions = [
pkgs.nur.repos.rycee.firefox-addons.bypass-paywalls-clean
pkgs.nur.repos.rycee.firefox-addons.metamask
pkgs.nur.repos.rycee.firefox-addons.i-dont-care-about-cookies
pkgs.nur.repos.rycee.firefox-addons.sidebery
pkgs.nur.repos.rycee.firefox-addons.sponsorblock
pkgs.nur.repos.rycee.firefox-addons.ublock-origin
];
};
home.shellAliases = {
":q" = "exit";
# common typos
"cd.." = "cd ..";
"cd../" = "cd ../";
};
home.packages = [
pkgs.btrfs-progs
pkgs.dig
pkgs.cryptsetup
pkgs.duplicity
pkgs.fatresize
pkgs.fd
pkgs.file
pkgs.gnumake
pkgs.gptfdisk
pkgs.hdparm
pkgs.htop
pkgs.iftop
pkgs.inetutils # for telnet
pkgs.iotop
pkgs.iptables
pkgs.jq
pkgs.killall
pkgs.lm_sensors # for sensors-detect
pkgs.lsof
pkgs.mix2nix
pkgs.netcat
pkgs.nixpkgs-review
pkgs.nixUnstable # TODO: still needed on 22.05?
# pkgs.nixos-generators
# pkgs.nettools
pkgs.nmap
pkgs.obsidian
pkgs.parted
pkgs.pciutils
# pkgs.ponymix
pkgs.powertop
pkgs.pulsemixer
pkgs.python3
pkgs.ripgrep
pkgs.smartmontools
pkgs.snapper
pkgs.socat
pkgs.sudo
pkgs.usbutils
pkgs.wget
pkgs.wireguard-tools
pkgs.youtube-dl
pkgs.zola
]
++ (if gui != null then
[
# GUI only
pkgs.chromium
pkgs.clinfo
pkgs.element-desktop # broken on phosh
pkgs.evince # works on phosh
pkgs.font-manager
pkgs.gimp # broken on phosh
pkgs.gnome.dconf-editor
pkgs.gnome.file-roller
pkgs.gnome.gnome-maps # works on phosh
pkgs.gnome.nautilus
pkgs.gnome-podcasts
pkgs.gnome.gnome-terminal # works on phosh
pkgs.inkscape
pkgs.kaiteki # Pleroma client
pkgs.libreoffice-fresh # XXX colin: maybe don't want this on mobile
pkgs.mesa-demos
pkgs.playerctl
pkgs.tdesktop # broken on phosh
pkgs.vlc # works on phosh
pkgs.whalebird # pleroma client. input is broken on phosh
pkgs.xterm # broken on phosh
] else [])
++ (if gui == "sway" then
[
# TODO: move this to helpers/gui/sway.nix?
pkgs.swaylock
pkgs.swayidle
pkgs.wl-clipboard
pkgs.mako # notification daemon
# pkgs.dmenu # todo: use wofi?
# user stuff
# pkgs.pavucontrol
] else [])
++ (if gui != null && system == "x86_64-linux" then
[
# x86_64 only
pkgs.signal-desktop
pkgs.spotify
pkgs.discord
] else [])
++ extraPackages;
}

View File

@@ -0,0 +1,17 @@
{ ... }:
{
imports = [
./fs.nix
./home-manager.nix
./nix-cache.nix
./users.nix
];
time.timeZone = "America/Los_Angeles";
environment.variables = {
EDITOR = "vim";
};
}

25
helpers/universal/fs.nix Normal file
View File

@@ -0,0 +1,25 @@
{ pkgs, ... }:
{
fileSystems."/mnt/media-uninsane" = {
# device = "sshfs#colin@uninsane.org:/opt/uninsane/media";
device = "colin@uninsane.org:/opt/uninsane/media";
fsType = "fuse.sshfs";
options = [
"x-systemd.automount"
"_netdev"
"user"
"idmap=user"
"transform_symlinks"
"identityfile=/home/colin/.ssh/id_ed25519"
"allow_other"
"default_permissions"
"uid=1000"
"gid=1000"
];
};
environment.systemPackages = [
pkgs.sshfs-fuse
];
}

View File

@@ -0,0 +1,9 @@
{ home-manager, config, pkgs, ... }:
{
imports = [
home-manager.nixosModule
];
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
}

View File

@@ -0,0 +1,16 @@
{ ... }:
{
# use our own binary cache
nix.settings = {
substituters = [
"https://nixcache.uninsane.org"
"https://nix-community.cachix.org"
"https://cache.nixos.org/"
];
trusted-public-keys = [
"nixcache.uninsane.org:r3WILM6+QrkmsLgqVQcEdibFD7Q/4gyzD9dGT33GP70="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
}

View File

@@ -1,4 +1,4 @@
{ pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
{
@@ -29,11 +29,9 @@
# XXX colin: create ssh key for THIS user by logging in and running:
# ssh-keygen -t ed25519
openssh.authorizedKeys.keys = [
# TODO: is this key dead?
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGSDe/y0e9PSeUwYlMPjzhW0UhNsGAGsW3lCG3apxrD5 colin@colin.desktop"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu colin@lappy"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG+MZ/l5d8g5hbxMB9ed1uyvhV85jwNrSVNVxb5ujQjw colin@lappy"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX colin@desko"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX colin@servo"
# TODO: should probably only let this authenticate to my server
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGCLCA9KbjXaXNNMJJvqbPO5KQQ64JCdG8sg88AfdKzi colin@moby"
];
@@ -49,4 +47,7 @@
permitRootLogin = "no";
passwordAuthentication = false;
};
# TODO colin: move this somewhere else!
programs.vim.defaultEditor = true;
}

21
image.nix Normal file
View File

@@ -0,0 +1,21 @@
{ config, lib, pkgs, modulesPath, ... }:
{
fileSystems."/" = {
# boot by label instead of unpredictable uuid
device = "/dev/disk/by-label/nixos-img";
# make-disk-image only supports ext4
fsType = "ext4";
};
# fileSystems."/boot".device = "/dev/vda1";
fileSystems."/boot".device = "/dev/disk/by-label/ESP";
system.build.raw = import "${toString modulesPath}/../lib/make-disk-image.nix" {
inherit lib config pkgs;
partitionTableType = "efi";
label = "nixos-img";
fsType = config.fileSystems."/".fsType;
diskSize = "auto";
format = "raw";
};
}

View File

@@ -1,45 +1,23 @@
{ pkgs, ... }:
{ config, pkgs, lib, ... }:
{
imports = [
./../../helpers/universal
./../../helpers/hardware-x86_64.nix
# ./../../helpers/gui/gnome.nix
#./../../helpers/gui/i3.nix
./../../helpers/gui/sway.nix
./fs.nix
];
colinsane.home-manager.extraPackages = [
pkgs.electrum
];
colinsane.gui.sway.enable = true;
colinsane.services.duplicity.enable = true;
colinsane.impermanence.enable = true;
boot.loader.generic-extlinux-compatible.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
colinsane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
hardware.opengl.extraPackages = with pkgs; [
rocm-opencl-icd
rocm-opencl-runtime
amdvlk
];
# needed to use libimobiledevice/ifuse, for iphone sync
services.usbmuxd.enable = true;
# default config: https://man.archlinux.org/man/snapper-configs.5
# defaults to something like:
# - hourly snapshots
# - auto cleanup; keep the last 10 hourlies, last 10 daylies, last 10 monthlys.
services.snapper.configs.nix = {
# TODO: for the impermanent setup, we'd prefer to just do /nix/persist,
# but that also requires setting up the persist dir as a subvol
subvolume = "/nix";
# TODO: ALLOW_USERS doesn't seem to work. still need `sudo snapper -c nix list`
extraConfig = ''
ALLOW_USERS = "colin";
'';
};
sops.secrets.duplicity_passphrase = {
sopsFile = ../../secrets/desko.yaml;
home-manager.users.colin = import ./../../helpers/home-manager-gen-colin.nix {
inherit pkgs lib;
system = "x86_64-linux";
# gui = "gnome";
# gui = "i3";
gui = "sway";
extraPackages = [
pkgs.electrum
];
};
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion

View File

@@ -1,28 +1,8 @@
{ ... }:
{ config, pkgs, lib, ... }:
{
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
fileSystems."/" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=755"
"size=1G"
"defaults"
];
};
# we need a /tmp of default size (half RAM) for building large nix things
fileSystems."/tmp" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=777"
"defaults"
];
};
fileSystems."/nix" = {
# device = "/dev/disk/by-uuid/985a0a32-da52-4043-9df7-615adec2e4ff";
device = "/dev/disk/by-uuid/0ab0770b-7734-4167-88d9-6e4e20bb2a56";
fileSystems."/" = lib.mkDefault {
device = "/dev/disk/by-uuid/d969ee61-12cf-4490-be07-4440c7be593f";
fsType = "btrfs";
options = [
"compress=zstd"
@@ -31,8 +11,7 @@
};
fileSystems."/boot" = {
# device = "/dev/disk/by-uuid/CAA7-E7D2";
device = "/dev/disk/by-uuid/41B6-BAEF";
device = lib.mkDefault "/dev/disk/by-uuid/F826-6192";
fsType = "vfat";
};
}

View File

@@ -1,35 +1,18 @@
{ pkgs, ... }:
{ config, pkgs, lib, ... }:
{
imports = [
./../../helpers/universal
./../../helpers/hardware-x86_64.nix
./../../helpers/gui/gnome.nix
./fs.nix
];
colinsane.gui.sway.enable = true;
colinsane.impermanence.enable = true;
boot.loader.generic-extlinux-compatible.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
colinsane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
hardware.opengl.extraPackages = with pkgs; [
intel-compute-runtime
intel-media-driver # new
libvdpau-va-gl # new
vaapiIntel
];
# default config: https://man.archlinux.org/man/snapper-configs.5
# defaults to something like:
# - hourly snapshots
# - auto cleanup; keep the last 10 hourlies, last 10 daylies, last 10 monthlys.
services.snapper.configs.nix = {
# TODO: for the impermanent setup, we'd prefer to just do /nix/persist,
# but that also requires setting up the persist dir as a subvol
subvolume = "/nix";
home-manager.users.colin = import ./../../helpers/home-manager-gen-colin.nix {
inherit pkgs lib;
system = "x86_64-linux";
gui = "gnome";
};
# TODO: only here for debugging
# services.ipfs.enable = true;
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
system.stateVersion = "21.05";
}

View File

@@ -1,27 +1,7 @@
{ ... }:
{ config, pkgs, lib, ... }:
{
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
fileSystems."/" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=755"
"size=1G"
"defaults"
];
};
# we need a /tmp of default size (half RAM) for building large nix things
fileSystems."/tmp" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=777"
"defaults"
];
};
fileSystems."/nix" = {
fileSystems."/" = lib.mkDefault {
device = "/dev/disk/by-uuid/75230e56-2c69-4e41-b03e-68475f119980";
fsType = "btrfs";
options = [
@@ -31,27 +11,7 @@
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/BD79-D6BB";
device = lib.mkDefault "/dev/disk/by-uuid/BD79-D6BB";
fsType = "vfat";
};
# fileSystems."/nix" = {
# device = "/dev/disk/by-uuid/5a7fa69c-9394-8144-a74c-6726048b129f";
# fsType = "btrfs";
# };
# fileSystems."/boot" = {
# device = "/dev/disk/by-uuid/4302-1685";
# fsType = "vfat";
# };
# fileSystems."/" = {
# device = "none";
# fsType = "tmpfs";
# options = [
# "mode=755"
# "size=1G"
# "defaults"
# ];
# };
}

View File

@@ -1,42 +1,41 @@
{ pkgs, mobile-nixos, ... }:
{ config, pkgs, lib, ... }:
{
imports = [
(import "${mobile-nixos}/lib/configuration.nix" {
device = "pine64-pinephone";
})
./firmware.nix
./fs.nix
./../../helpers/universal
./../../helpers/gui/phosh.nix
# ./../../helpers/gui/plasma-mobile.nix
# ./../../helpers/gui/gnome.nix
];
# XXX colin: phosh doesn't work well with passwordless login
users.users.colin.initialPassword = "147147";
colinsane.home-manager.extraPackages = [
# for web browsers see: https://forum.pine64.org/showthread.php?tid=13669
pkgs.angelfish # plasma mobile web browser; broken on phosh (poor wayland support)
# pkgs.plasma5Packages.index # file browser
pkgs.plasma5Packages.konsole # terminal
# pkgs.plasma5Packages.pix # picture viewer
pkgs.plasma5Packages.kalk # calculator; broken on phosh
# pkgs.plasma5Packages.buho # (plasma mobile?) note application
pkgs.plasma5Packages.kasts # podcast app; works on phosh after setting QT envar
pkgs.plasma5Packages.koko # image gallery; broken on phosh
pkgs.plasma5Packages.kwave # media player.
# pkgs.plasma5Packages.neochat # matrix client. needs qcoro => no aarch64 support
# pkgs.plasma5Packages.plasma-dialer # phone dialer
# pkgs.plasma5Packages.plasma-mobile # the whole shebang?
# pkgs.plasma5Packages.plasma-settings
pkgs.plasma5Packages.bomber # arcade game; broken on phosh
pkgs.plasma5Packages.kapman # pacman
pkgs.w3m # text-based web browser; works!
pkgs.st # suckless terminal; broken on phosh
# pkgs.alacritty # terminal; crashes phosh
];
colinsane.nixcache.enable = true;
colinsane.gui.phosh.enable = true;
boot.loader.grub.enable = false;
mobile.bootloader.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
home-manager.users.colin = import ./../../helpers/home-manager-gen-colin.nix {
inherit pkgs lib;
system = "aarch64-linux";
gui = "phosh";
extraPackages = [
# for web browsers see: https://forum.pine64.org/showthread.php?tid=13669
pkgs.angelfish # plasma mobile web browser; broken on phosh (poor wayland support)
# pkgs.plasma5Packages.index # file browser
pkgs.plasma5Packages.konsole # terminal
# pkgs.plasma5Packages.pix # picture viewer
pkgs.plasma5Packages.kalk # calculator; broken on phosh
# pkgs.plasma5Packages.buho # (plasma mobile?) note application
pkgs.plasma5Packages.kasts # podcast app; works on phosh after setting QT envar
pkgs.plasma5Packages.koko # image gallery; broken on phosh
pkgs.plasma5Packages.kwave # media player.
# pkgs.plasma5Packages.neochat # matrix client. needs qcoro => no aarch64 support
# pkgs.plasma5Packages.plasma-dialer # phone dialer
# pkgs.plasma5Packages.plasma-mobile # the whole shebang?
# pkgs.plasma5Packages.plasma-settings
pkgs.plasma5Packages.bomber # arcade game; broken on phosh
pkgs.plasma5Packages.kapman # pacman
pkgs.w3m # text-based web browser; works!
pkgs.st # suckless terminal; broken on phosh
# pkgs.alacritty # terminal; crashes phosh
];
};
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions

View File

@@ -1,12 +0,0 @@
{ config, pkgs, ... }:
{
# we need space in the GPT header to place tow-boot.
# only actually need 1 MB, but better to over-allocate than under-allocate
colinsane.image.extraGPTPadding = 16 * 1024 * 1024;
colinsane.image.firstPartGap = 0;
system.build.img = pkgs.runCommandNoCC "nixos_full-disk-image.img" {} ''
cp -v ${config.system.build.img-without-firmware}/nixos.img $out
chmod +w $out
dd if=${pkgs.tow-boot-pinephone}/Tow-Boot.noenv.bin of=$out bs=1024 seek=8 conv=notrunc
'';
}

View File

@@ -1,17 +0,0 @@
{ ... }:
{
fileSystems."/" = {
device = "/dev/disk/by-uuid/1f1271f8-53ce-4081-8a29-60a4a6b5d6f9";
fsType = "btrfs";
options = [
"compress=zstd"
"defaults"
];
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/0299-F1E5";
fsType = "vfat";
};
}

View File

@@ -1,79 +0,0 @@
{ ... }:
{
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
fileSystems."/" = {
device = "none";
fsType = "tmpfs";
options = [
"mode=755"
"size=1G"
"defaults"
];
};
# we need a /tmp for building large nix things
fileSystems."/tmp" = {
device = "none";
fsType = "tmpfs";
options = [
"size=16G"
"mode=777"
"defaults"
];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/aa272cff-0fcc-498e-a4cb-0d95fb60631b";
fsType = "btrfs";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/31D3-40CB";
fsType = "vfat";
};
# fileSystems."/var/lib/pleroma" = {
# device = "/opt/pleroma";
# options = [ "bind" ];
# };
# TODO: does transmission handle symlinks?
fileSystems."/var/lib/transmission/Downloads" = {
device = "/var/lib/uninsane/media";
options = [ "bind" ];
};
fileSystems."/var/lib/transmission/.incomplete" = {
device = "/var/lib/uninsane/media/incomplete";
options = [ "bind" ];
};
# in-memory compressed RAM (seems to be dynamically sized)
zramSwap = {
enable = true;
};
# btrfs doesn't easily support swapfiles
# swapDevices = [
# { device = "/nix/persist/swapfile"; size = 4096; }
# ];
# this can be a partition. create with:
# fdisk <dev>
# n
# <default partno>
# <start>
# <end>
# t
# <partno>
# 19 # set part type to Linux swap
# w # write changes
# mkswap -L swap <part>
swapDevices = [
{
label = "swap";
# TODO: randomEncryption.enable = true;
}
];
}

View File

@@ -1,32 +0,0 @@
{ config, pkgs, ... }:
{
systemd.services.ddns-he = {
description = "update dynamic DNS entries for HurricaneElectric";
serviceConfig = {
EnvironmentFile = config.sops.secrets.ddns_he.path;
# TODO: ProtectSystem = "strict";
# TODO: ProtectHome = "full";
# TODO: PrivateTmp = true;
};
# HE DDNS API is documented: https://dns.he.net/docs.html
script = let
crl = "${pkgs.curl}/bin/curl -4";
in ''
${crl} "https://he.uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=he.uninsane.org"
${crl} "https://native.uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=native.uninsane.org"
${crl} "https://uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=uninsane.org"
'';
};
systemd.timers.ddns-he = {
wantedBy = [ "multi-user.target" ];
timerConfig = {
OnStartupSec = "2min";
OnUnitActiveSec = "10min";
};
};
sops.secrets."ddns_he" = {
sopsFile = ../../../secrets/servo.yaml;
};
}

View File

@@ -1,23 +0,0 @@
{ ... }:
{
services.ipfs.enable = true;
services.ipfs.localDiscovery = true;
services.ipfs.swarmAddress = [
"/dns4/ipfs.uninsane.org/tcp/4001"
"/ip4/0.0.0.0/tcp/4001"
"/dns4/ipfs.uninsane.org/udp/4001/quic"
"/ip4/0.0.0.0/udp/4001/quic"
];
services.ipfs.extraConfig = {
Addresses = {
Announce = [
"/dns4/ipfs.uninsane.org/tcp/4001"
"/dns4/ipfs.uninsane.org/udp/4001/quic"
];
};
Gateway = {
# the gateway can only be used to serve content already replicated on this host
NoFetch = true;
};
};
}

View File

@@ -1,14 +1,15 @@
{ pkgs, ... }:
{ pkgs, lib, ... }:
{
imports = [
./../../helpers/universal
./fs.nix
./hardware.nix
./net.nix
./users.nix
./services/ddns-he.nix
./services/duplicity.nix
./services/gitea.nix
./services/ipfs.nix
./services/jackett.nix
./services/jellyfin.nix
./services/matrix.nix
@@ -20,27 +21,11 @@
./services/transmission.nix
];
colinsane.home-manager.enable = true;
colinsane.home-manager.extraPackages = [
pkgs.matrix-synapse
];
colinsane.impermanence.enable = true;
colinsane.services.duplicity.enable = true;
# TODO: validate this
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
colinsane.image.extraBootFiles = [ pkgs.bootpart-u-boot-rpi-aarch64 ];
sops.secrets.duplicity_passphrase = {
sopsFile = ../../secrets/servo.yaml;
};
# both transmission and ipfs try to set different net defaults.
# we just use the most aggressive of the two here:
boot.kernel.sysctl = {
"net.core.rmem_max" = "4194304"; # 4MB
home-manager.users.colin = import ../../helpers/home-manager-gen-colin.nix {
inherit pkgs lib;
system = "aarch64-linux";
gui = null;
extraPackages = [ pkgs.matrix-synapse ];
};
# This value determines the NixOS release from which the default

37
machines/uninsane/fs.nix Normal file
View File

@@ -0,0 +1,37 @@
{ config, pkgs, lib, ... }:
{
fileSystems."/" = lib.mkDefault {
device = "/dev/disk/by-uuid/2be70d38-79f4-41b6-bee2-bce5a25f8f7b";
fsType = "ext4";
};
fileSystems."/boot" = {
device = lib.mkDefault "/dev/disk/by-uuid/B318-A67E";
fsType = "vfat";
};
fileSystems."/var/lib/pleroma" = {
device = "/opt/pleroma";
options = [ "bind" ];
};
fileSystems."/var/lib/transmission/Downloads" = {
device = "/opt/uninsane/media";
options = [ "bind" ];
};
fileSystems."/var/lib/transmission/.incomplete" = {
device = "/opt/uninsane/media/incomplete";
options = [ "bind" ];
};
# in-memory compressed RAM (seems to be dynamically sized)
zramSwap = {
enable = true;
};
swapDevices = [
{ device = "/swapfile"; size = 4096; }
];
}

View File

@@ -1,6 +1,6 @@
# this file originates from nixos-generate-config
# but has been heavily modified
{ pkgs, ... }:
{ config, lib, pkgs, modulesPath, ... }:
{
# enables non-free firmware
@@ -12,9 +12,15 @@
# see: https://github.com/raspberrypi/linux
boot.kernelPackages = pkgs.linuxPackages_rpi4;
# NixOS defaults to grub: we don't want that.
boot.loader.grub.enable = false;
# raspberryPi boot loader creates extlinux.conf.
# otherwise, enable the generic-extlinux-compatible loader below.
# note: THESE ARE MUTUALLY EXCLUSIVE. generic-extlinux-compatible causes uboot to not be built
# boot.loader.generic-extlinux-compatible.enable = true;
boot.loader.raspberryPi.enable = true;
boot.loader.raspberryPi.uboot.enable = true;
boot.loader.raspberryPi.version = 4;
boot.initrd.availableKernelModules = [
"bcm2711_thermal"

View File

@@ -1,4 +1,4 @@
{ config, pkgs, ... }:
{ config, pkgs, secrets, ... }:
{
networking.domain = "uninsane.org";
@@ -18,15 +18,12 @@
80 # HTTP
143 # IMAP
443 # HTTPS
465 # SMTPS
587 # SMTPS/submission
465 # SMTPS (maybe not required?)
587 # SMTPS/submission (maybe not required?)
993 # IMAPS
4001 # IPFS
];
networking.firewall.allowedUDPPorts = [
1900 7359 # DLNA: https://jellyfin.org/docs/general/networking/index.html
4001 # IPFS
];
# DLNA ports: https://jellyfin.org/docs/general/networking/index.html
networking.firewall.allowedUDPPorts = [ 1900 7359 ];
# we need to use externally-visible nameservers in order for VPNs to be able to resolve hosts.
networking.nameservers = [
@@ -38,7 +35,7 @@
# DOCS: https://nixos.wiki/wiki/WireGuard
networking.wireguard.enable = true;
networking.wireguard.interfaces.wg0 = {
privateKeyFile = config.sops.secrets.wg_ovpns_privkey.path;
privateKey = secrets.wireguard.privateKey;
# wg is active only in this namespace.
# run e.g. ip netns exec ovpns <some command like ping/curl/etc, it'll go through wg>
# sudo ip netns exec ovpns ping www.google.com
@@ -90,10 +87,6 @@
};
};
sops.secrets."wg_ovpns_privkey" = {
sopsFile = ../../secrets/servo.yaml;
};
# HURRICANE ELECTRIC CONFIG:
# networking.sits = {
# hurricane = {

View File

@@ -0,0 +1,20 @@
{ pkgs, secrets, ... }:
{
systemd.services.ddns-he = {
description = "update dynamic DNS entries for HurricaneElectric";
# HE DDNS API is documented: https://dns.he.net/docs.html
script = let
pass = secrets.ddns-he.password;
crl = "${pkgs.curl}/bin/curl -4";
in ''
${crl} "https://he.uninsane.org:${pass}@dyn.dns.he.net/nic/update?hostname=he.uninsane.org"
${crl} "https://native.uninsane.org:${pass}@dyn.dns.he.net/nic/update?hostname=native.uninsane.org"
${crl} "https://uninsane.org:${pass}@dyn.dns.he.net/nic/update?hostname=uninsane.org"
'';
};
systemd.timers.ddns-he.timerConfig = {
OnStartupSec = "2min";
OnUnitActiveSec = "10min";
};
}

View File

@@ -0,0 +1,36 @@
# docs: https://search.nixos.org/options?channel=21.11&query=duplicity
{ config, pkgs, lib, secrets, ... }:
{
services.duplicity.enable = true;
services.duplicity.targetUrl = secrets.duplicity.url;
# format: PASSPHRASE=<cleartext>
# two sisters
services.duplicity.secretFile =
builtins.toFile "duplicity_env" "PASSPHRASE=${secrets.duplicity.passphrase}";
# NB: manually trigger with `systemctl start duplicity`
services.duplicity.frequency = "daily";
services.duplicity.exclude = [
# impermanent/inconsequential data:
"/dev"
"/proc"
"/run"
"/sys"
"/tmp"
# bind mounted (dupes):
"/var/lib/pleroma"
"/var/lib/transmission/Downloads"
"/var/lib/transmission/.incomplete"
# data that's not worth the cost to backup:
"/opt/uninsane/media"
];
services.duplicity.extraFlags = [
# without --allow-source-mismatch, duplicity will abort if you change the hostname between backups
"--allow-source-mismatch"
];
# set this for the FIRST backup, then remove it to enable incremental backups
# (that the first backup *isn't* full i think is a defect)
# services.duplicity.fullIfOlderThan = "always";
}

View File

@@ -1,4 +1,4 @@
{ pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
{
services.gitea.enable = true;

View File

@@ -1,4 +1,4 @@
{ ... }:
{ config, pkgs, lib, ... }:
{
services.jackett.enable = true;

View File

@@ -1,4 +1,4 @@
{ ... }:
{ config, pkgs, lib, ... }:
{
services.jellyfin.enable = true;

View File

@@ -1,6 +1,6 @@
# docs: https://nixos.wiki/wiki/Matrix
# docs: https://nixos.org/manual/nixos/stable/index.html#module-services-matrix-synapse
{ config, ... }:
{ config, pkgs, lib, secrets, ... }:
{
services.matrix-synapse.enable = true;
@@ -29,12 +29,29 @@
}
];
# services.matrix-synapse.extraConfig = ''
# registration_requires_token: true
# admin_contact: "admin.matrix@uninsane.org"
# '';
services.matrix-synapse.settings.admin_contact = "admin.matrix@uninsane.org";
services.matrix-synapse.settings.registrations_require_3pid = [ "email" ];
services.matrix-synapse.extraConfigFiles = [
config.sops.secrets.matrix_synapse_secrets.path
];
services.matrix-synapse.settings.email = {
smtp_host = "mx.uninsane.org";
smtp_port = 587;
smtp_user = "matrix-synapse";
smtp_pass = secrets.matrix-synapse.smtp_pass;
require_transport_security = true;
enable_tls = true;
notif_from = "%(app)s <notify.matrix@uninsane.org>";
app_name = "Uninsane Matrix";
enable_notifs = true;
validation_token_lifetime = "96h";
invite_client_location = "https://web.matrix.uninsane.org";
subjects = {
email_validation = "[%(server_name)s] Validate your email";
};
};
# services.matrix-synapse.extraConfigFiles = [builtins.toFile "matrix-synapse-extra-config" ''
# admin_contact: "admin.matrix@uninsane.org"
@@ -155,9 +172,4 @@
};
};
};
sops.secrets.matrix_synapse_secrets = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.matrix-synapse.name;
};
}

View File

@@ -6,11 +6,8 @@
# web blog/personal site
services.nginx.virtualHosts."uninsane.org" = {
root = "/var/lib/uninsane/root";
# a lot of places hardcode https://uninsane.org,
# and then when we mix http + non-https, we get CORS violations
# and things don't look right. so force SSL.
forceSSL = true;
root = "/opt/uninsane/root";
addSSL = true;
enableACME = true;
# allow matrix users to discover that @user:uninsane.org is reachable via matrix.uninsane.org
@@ -213,23 +210,6 @@
};
};
services.nginx.virtualHosts."ipfs.uninsane.org" = {
# don't default to ssl upgrades, since this may be dnslink'd from a different domain.
# ideally we'd disable ssl entirely, but some places assume it?
addSSL = true;
enableACME = true;
default = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8080";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Ipfs-Gateway-Prefix "";
'';
};
};
# exists only to manage certs for dovecot
services.nginx.virtualHosts."imap.uninsane.org" = {
forceSSL = true;

View File

@@ -1,15 +1,12 @@
# docs: https://nixos.wiki/wiki/Binary_Cache
# to copy something to this machine's nix cache, do:
# nix copy --to ssh://nixcache.uninsane.org PACKAGE
{ config, ... }:
{ secrets, ... }:
{
services.nix-serve = {
enable = true;
secretKeyFile = config.sops.secrets.nix_serve_privkey.path;
};
sops.secrets.nix_serve_privkey = {
sopsFile = ../../../secrets/servo.yaml;
secretKeyFile = builtins.toFile "nix-serve-priv-key.pem" secrets.nix-serve.cache-priv-key;
# "/var/cache-priv-key.pem";
};
}

View File

@@ -1,20 +1,21 @@
# docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/pleroma.nix
#
# to run it in a oci-container: https://github.com/barrucadu/nixfiles/blob/master/services/pleroma.nix
{ config, pkgs, ... }:
{ config, pkgs, lib, secrets, ... }:
{
services.pleroma.enable = true;
services.pleroma.secretConfigFile = config.sops.secrets.pleroma_secrets.path;
# TODO: we should write a config file somewhere outside the store... somehow.
services.pleroma.secretConfigFile = "/dev/null";
services.pleroma.configs = [
''
import Config
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "fed.uninsane.org", scheme: "https", port: 443],
http: [ip: {127, 0, 0, 1}, port: 4000]
# secret_key_base: "{secrets.pleroma.secret_key_base}",
# signing_salt: "{secrets.pleroma.signing_salt}"
http: [ip: {127, 0, 0, 1}, port: 4000],
secret_key_base: "${secrets.pleroma.secret_key_base}",
signing_salt: "${secrets.pleroma.signing_salt}"
config :pleroma, :instance,
name: "Perfectly Sane",
@@ -45,6 +46,7 @@
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
username: "pleroma",
password: "${secrets.pleroma.db_password}",
database: "pleroma",
hostname: "localhost",
pool_size: 10,
@@ -52,15 +54,14 @@
parameters: [
plan_cache_mode: "force_custom_plan"
]
# password: "{secrets.pleroma.db_password}",
# Configure web push notifications
config :web_push_encryption, :vapid_details,
subject: "mailto:notify.pleroma@uninsane.org"
# public_key: "{secrets.pleroma.vapid_public_key}",
# private_key: "{secrets.pleroma.vapid_private_key}"
subject: "mailto:notify.pleroma@uninsane.org",
public_key: "${secrets.pleroma.vapid_public_key}",
private_key: "${secrets.pleroma.vapid_private_key}"
# config :joken, default_signer: "{secrets.pleroma.joken_default_signer}"
config :joken, default_signer: "${secrets.pleroma.joken_default_signer}"
config :pleroma, :database, rum_enabled: false
config :pleroma, :instance, static_dir: "/var/lib/pleroma/instance/static"
@@ -123,9 +124,4 @@
# PrivateTmp = lib.mkForce false;
# CapabilityBoundingSet = lib.mkForce "~";
# };
sops.secrets.pleroma_secrets = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.pleroma.name;
};
}

View File

@@ -1,4 +1,4 @@
{ config, lib, ... }:
{ config, pkgs, lib, secrets, ... }:
let
submissionOptions = {
@@ -82,7 +82,10 @@ in
services.dovecot2.enablePAM = false;
services.dovecot2.extraConfig =
let
passwdFile = config.sops.secrets.dovecot_passwd.path;
passwdFile = builtins.toFile "dovecot-passwd-file" ''
colin:${secrets.dovecot.hashedPasswd.colin}:1000:1000::/var/mail/colin/run/current-system/sw/bin/nologin:
matrix-synapse:${secrets.dovecot.hashedPasswd.matrix-synapse}:224:224::/var/mail/colin:/run/current-system/sw/bin/nologin:
'';
in
''
passdb {
@@ -130,11 +133,4 @@ in
# pattern = "/^Subject:.*activate your account/";
# }
];
sops.secrets.dovecot_passwd = {
sopsFile = ../../../secrets/servo.yaml;
owner = config.users.users.dovecot2.name;
# TODO: debug why mail can't be sent without this being world-readable
mode = "0444";
};
}

View File

@@ -1,8 +1,8 @@
{ ... }:
{ config, pkgs, lib, ... }:
{
services.postgresql.enable = true;
# services.postgresql.dataDir = "/opt/postgresql/13";
services.postgresql.dataDir = "/opt/postgresql/13";
# XXX colin: for a proper deploy, we'd want to include something for Pleroma here too.
# services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
# CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>';

View File

@@ -1,4 +1,4 @@
{ ... }:
{ config, pkgs, lib, ... }:
{
services.transmission.enable = true;
@@ -14,8 +14,6 @@
rpc-whitelist-enabled = false;
# download-dir = "/opt/uninsane/media/";
# hopefully, make the downloads world-readable
umask = 0;
# force peer connections to be encrypted
encryption = 2;
@@ -23,12 +21,9 @@
# units in kBps
speed-limit-down = 3000;
speed-limit-down-enabled = true;
speed-limit-up = 300;
speed-limit-up = 600;
speed-limit-up-enabled = true;
# see: https://git.zknt.org/mirror/transmission/commit/cfce6e2e3a9b9d31a9dafedd0bdc8bf2cdb6e876?lang=bg-BG
anti-brute-force-enabled = false;
};
# transmission will by default not allow the world to read its files.
services.transmission.downloadDirPermissions = "775";

View File

@@ -1,4 +1,4 @@
{ ... }:
{ config, pkgs, lib, ... }:
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
{

View File

@@ -1,13 +0,0 @@
{ ... }:
{
imports = [
./gui
./hardware
./image.nix
./impermanence.nix
./nix.nix
./services/duplicity.nix
./universal
];
}

View File

@@ -1,26 +0,0 @@
{ lib, config, ... }:
with lib;
let
cfg = config.colinsane.gui;
in
{
imports = [
./gnome.nix
./phosh.nix
./plasma-mobile.nix
./sway.nix
];
options = {
# doesn't directly create outputs. consumed by e.g. home-manager.nix module
colinsane.gui.enable = mkOption {
default = false;
type = types.bool;
};
};
config = lib.mkIf cfg.enable {
colinsane.home-manager.enable = true;
};
}

View File

@@ -1,68 +0,0 @@
{ lib, config, ... }:
with lib;
let
cfg = config.colinsane.gui.gnome;
in
{
options = {
colinsane.gui.gnome.enable = mkOption {
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
colinsane.gui.enable = true;
# start gnome/gdm on boot
services.xserver.enable = true;
services.xserver.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
# gnome does networking stuff with networkmanager
networking.useDHCP = false;
networking.networkmanager.enable = true;
networking.wireless.enable = lib.mkForce false;
};
# home-mananger.users.colin extras
# obtain these by running `dconf dump /` after manually customizing gnome
# TODO: fix "is not of type `GVariant value'"
# dconf.settings = lib.mkIf (gui == "gnome") {
# gnome = {
# # control alt-tab behavior
# "org/gnome/desktop/wm/keybindings" = {
# switch-applications = [ "<Super>Tab" ];
# switch-applications-backward=[];
# switch-windows=["<Alt>Tab"];
# switch-windows-backward=["<Super><Alt>Tab"];
# };
# # idle power savings
# "org/gnome/settings-deamon/plugins/power" = {
# idle-brigthness = 50;
# sleep-inactive-ac-type = "nothing";
# sleep-inactive-battery-timeout = 5400; # seconds
# };
# "org/gnome/shell" = {
# favorite-apps = [
# "org.gnome.Nautilus.desktop"
# "firefox.desktop"
# "kitty.desktop"
# # "org.gnome.Terminal.desktop"
# ];
# };
# "org/gnome/desktop/session" = {
# # how long until considering a session idle (triggers e.g. screen blanking)
# idle-delay = 900;
# };
# "org/gnome/desktop/interface" = {
# text-scaling-factor = 1.25;
# };
# "org/gnome/desktop/media-handling" = {
# # don't auto-mount inserted media
# automount = false;
# automount-open = false;
# };
# };
# };
}

View File

@@ -1,43 +0,0 @@
{ lib, config, ... }:
with lib;
let
cfg = config.colinsane.gui.phosh;
in
{
options = {
colinsane.gui.phosh.enable = mkOption {
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
colinsane.gui.enable = true;
# docs: https://github.com/NixOS/nixpkgs/blob/nixos-22.05/nixos/modules/services/x11/desktop-managers/phosh.nix
services.xserver.desktopManager.phosh = {
enable = true;
user = "colin";
group = "users";
phocConfig = {
# xwayland = "true";
# find default outputs by catting /etc/phosh/phoc.ini
outputs.DSI-1 = {
scale = 1.5;
};
};
};
hardware.opengl.enable = true;
hardware.opengl.driSupport = true;
environment.variables = {
# Qt apps won't always start unless this env var is set
QT_QPA_PLATFORM = "wayland";
# electron apps (e.g. Element) should use the wayland backend
# toggle this to have electron apps (e.g. Element) use the wayland backend.
# phocConfig.xwayland should be disabled if you do this
NIXOS_OZONE_WL = "1";
};
};
}

View File

@@ -1,28 +0,0 @@
{ lib, config, ... }:
with lib;
let
cfg = config.colinsane.gui.plasma-mobile;
in
{
options = {
colinsane.gui.plasma-mobile.enable = mkOption {
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
colinsane.gui.enable = true;
# start plasma-mobile on boot
services.xserver.enable = true;
services.xserver.desktopManager.plasma5.mobile.enable = true;
services.xserver.desktopManager.plasma5.mobile.installRecommendedSoftware = false; # not all plasma5-mobile packages build for aarch64
services.xserver.displayManager.sddm.enable = true;
# Plasma does networking stuff with networkmanager, but nix configures the defaults itself
# networking.useDHCP = false;
# networking.networkmanager.enable = true;
# networking.wireless.enable = lib.mkForce false;
};
}

View File

@@ -1,296 +0,0 @@
{ pkgs, lib, config, ... }:
# docs: https://nixos.wiki/wiki/Sway
with lib;
let
cfg = config.colinsane.gui.sway;
in
{
options = {
colinsane.gui.sway.enable = mkOption {
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
colinsane.gui.enable = true;
programs.sway = {
# we configure sway with home-manager, but this enable gets us e.g. opengl and fonts
enable = true;
};
# TODO: should be able to use SDDM to get interactive login
services.greetd = {
enable = true;
settings = rec {
initial_session = {
command = "${pkgs.sway}/bin/sway";
user = "colin";
};
default_session = initial_session;
};
};
# unlike other DEs, sway configures no audio stack
# administer with pw-cli, pw-mon, pw-top commands
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true; # ??
pulse.enable = true;
};
hardware.bluetooth.enable = true;
services.blueman.enable = true;
networking.useDHCP = false;
networking.networkmanager.enable = true;
networking.wireless.enable = lib.mkForce false;
colinsane.home-manager.windowManager.sway = {
enable = true;
wrapperFeatures.gtk = true;
config = rec {
terminal = "${pkgs.kitty}/bin/kitty";
window.border = 3; # pixel boundary between windows
# defaults; required for keybindings decl.
modifier = "Mod1";
# list of launchers: https://www.reddit.com/r/swaywm/comments/v39hxa/your_favorite_launcher/
# menu = "${pkgs.dmenu}/bin/dmenu_path";
menu = "${pkgs.fuzzel}/bin/fuzzel";
# menu = "${pkgs.albert}/bin/albert";
left = "h";
down = "j";
up = "k";
right = "l";
keybindings = {
"${modifier}+Return" = "exec ${terminal}";
"${modifier}+Shift+q" = "kill";
"${modifier}+d" = "exec ${menu}";
"${modifier}+${left}" = "focus left";
"${modifier}+${down}" = "focus down";
"${modifier}+${up}" = "focus up";
"${modifier}+${right}" = "focus right";
"${modifier}+Left" = "focus left";
"${modifier}+Down" = "focus down";
"${modifier}+Up" = "focus up";
"${modifier}+Right" = "focus right";
"${modifier}+Shift+${left}" = "move left";
"${modifier}+Shift+${down}" = "move down";
"${modifier}+Shift+${up}" = "move up";
"${modifier}+Shift+${right}" = "move right";
"${modifier}+Shift+Left" = "move left";
"${modifier}+Shift+Down" = "move down";
"${modifier}+Shift+Up" = "move up";
"${modifier}+Shift+Right" = "move right";
"${modifier}+b" = "splith";
"${modifier}+v" = "splitv";
"${modifier}+f" = "fullscreen toggle";
"${modifier}+a" = "focus parent";
"${modifier}+s" = "layout stacking";
"${modifier}+w" = "layout tabbed";
"${modifier}+e" = "layout toggle split";
"${modifier}+Shift+space" = "floating toggle";
"${modifier}+space" = "focus mode_toggle";
"${modifier}+1" = "workspace number 1";
"${modifier}+2" = "workspace number 2";
"${modifier}+3" = "workspace number 3";
"${modifier}+4" = "workspace number 4";
"${modifier}+5" = "workspace number 5";
"${modifier}+6" = "workspace number 6";
"${modifier}+7" = "workspace number 7";
"${modifier}+8" = "workspace number 8";
"${modifier}+9" = "workspace number 9";
"${modifier}+Shift+1" =
"move container to workspace number 1";
"${modifier}+Shift+2" =
"move container to workspace number 2";
"${modifier}+Shift+3" =
"move container to workspace number 3";
"${modifier}+Shift+4" =
"move container to workspace number 4";
"${modifier}+Shift+5" =
"move container to workspace number 5";
"${modifier}+Shift+6" =
"move container to workspace number 6";
"${modifier}+Shift+7" =
"move container to workspace number 7";
"${modifier}+Shift+8" =
"move container to workspace number 8";
"${modifier}+Shift+9" =
"move container to workspace number 9";
"${modifier}+Shift+minus" = "move scratchpad";
"${modifier}+minus" = "scratchpad show";
"${modifier}+Shift+c" = "reload";
"${modifier}+Shift+e" =
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
"${modifier}+r" = "mode resize";
} // {
# media keys
XF86MonBrightnessDown = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set 2%-"'';
XF86MonBrightnessUp = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set +2%"'';
XF86AudioRaiseVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
XF86AudioLowerVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
XF86AudioMute = "exec '${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute'";
"${modifier}+Print" = "exec '${pkgs.sway-contrib.grimshot}/bin/grimshot copy area'";
};
# mostly defaults:
bars = [{
mode = "dock";
hiddenState = "hide";
position = "top";
command = "${pkgs.waybar}/bin/waybar";
workspaceButtons = true;
workspaceNumbers = true;
statusCommand = "${pkgs.i3status}/bin/i3status";
fonts = {
# names = [ "monospace" "Noto Color Emoji" ];
# size = 8.0;
# names = [ "Font Awesome 6 Free" "DejaVu Sans" "Hack" ];
names = with config.fonts.fontconfig.defaultFonts; (emoji ++ monospace ++ serif ++ sansSerif);
size = 24.0;
};
trayOutput = "primary";
colors = {
background = "#000000";
statusline = "#ffffff";
separator = "#666666";
focusedWorkspace = {
border = "#4c7899";
background = "#285577";
text = "#ffffff";
};
activeWorkspace = {
border = "#333333";
background = "#5f676a";
text = "#ffffff";
};
inactiveWorkspace = {
border = "#333333";
background = "#222222";
text = "#888888";
};
urgentWorkspace = {
border = "#2f343a";
background = "#900000";
text = "#ffffff";
};
bindingMode = {
border = "#2f343a";
background = "#900000";
text = "#ffffff";
};
};
}];
};
};
colinsane.home-manager.programs.waybar = {
enable = true;
# docs: https://github.com/Alexays/Waybar/wiki/Configuration
settings = {
mainBar = {
layer = "top";
height = 40;
modules-left = ["sway/workspaces" "sway/mode"];
modules-center = ["sway/window"];
modules-right = ["custom/mediaplayer" "clock" "battery" "cpu" "network"];
"sway/window" = {
max-length = 50;
};
# include song artist/title. source: https://www.reddit.com/r/swaywm/comments/ni0vso/waybar_spotify_tracktitle/
"custom/mediaplayer" = {
exec = pkgs.writeShellScript "waybar-mediaplayer" ''
player_status=$(${pkgs.playerctl}/bin/playerctl status 2> /dev/null)
if [ "$player_status" = "Playing" ]; then
echo "$(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
elif [ "$player_status" = "Paused" ]; then
echo " $(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
fi
'';
interval = 2;
format = "{} ";
# return-type = "json";
on-click = "${pkgs.playerctl}/bin/playerctl play-pause";
on-scroll-up = "${pkgs.playerctl}/bin/playerctl next";
on-scroll-down = "${pkgs.playerctl}/bin/playerctl previous";
};
network = {
interval = 1;
format-ethernet = "{ifname}: {ipaddr}/{cidr} up: {bandwidthUpBits} down: {bandwidthDownBits}";
};
cpu = {
format = "{usage}% ";
tooltip = false;
};
battery = {
states = {
good = 95;
warning = 30;
critical = 10;
};
format = "{icon} {capacity}%";
format-icons = [
""
""
""
""
""
];
};
clock = {
format-alt = "{:%a, %d. %b %H:%M}";
};
};
};
# style = ''
# * {
# border: none;
# border-radius: 0;
# font-family: Source Code Pro;
# }
# window#waybar {
# background: #16191C;
# color: #AAB2BF;
# }
# #workspaces button {
# padding: 0 5px;
# }
# .custom-spotify {
# padding: 0 10px;
# margin: 0 4px;
# background-color: #1DB954;
# color: black;
# }
# '';
};
colinsane.home-manager.extraPackages = with pkgs; [
swaylock
swayidle
wl-clipboard
mako # notification daemon
xdg-utils # for xdg-open
# user stuff
# pavucontrol
sway-contrib.grimshot
gnome.gnome-bluetooth
];
};
}

View File

@@ -1,7 +0,0 @@
{ ... }:
{
imports = [
./x86_64.nix
];
}

View File

@@ -1,60 +0,0 @@
{ lib, pkgs, config, ... }:
with lib;
{
config = mkIf (pkgs.system == "x86_64-linux") {
boot.initrd.availableKernelModules = [
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
"usb_storage" # rpi needed this to boot from usb storage, i think.
"nvme" # to boot from nvme devices
# efi_pstore evivars
];
boot.initrd.kernelModules = [ ];
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
# useful emergency utils
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.btrfs-progs}/bin/btrfstune
'';
boot.kernelModules = [
"coretemp"
"kvm-intel"
"kvm-amd" # desktop
"amdgpu" # desktop
];
boot.extraModulePackages = [ ];
boot.kernelParams = [ "boot.shell_on_fail" ];
boot.consoleLogLevel = 7;
boot.loader.grub.enable = false;
# boot.loader.generic-extlinux-compatible.enable = true;
# enable cross compilation
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
# nixpkgs.crossSystem.system = "aarch64-linux";
powerManagement.cpuFreqGovernor = "powersave";
hardware.enableRedistributableFirmware = true;
hardware.cpu.amd.updateMicrocode = true; # desktop
hardware.cpu.intel.updateMicrocode = true; # laptop
services.fwupd.enable = true;
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
powerManagement.powertop.enable = false;
hardware.opengl.driSupport = true;
# For 32 bit applications
hardware.opengl.driSupport32Bit = true;
# TODO colin: does this *do* anything?
swapDevices = [ ];
# services.snapper.configs = {
# root = {
# subvolume = "/";
# extraConfig = {
# ALLOW_USERS = "colin";
# };
# };
# };
# services.snapper.snapshotInterval = "daily";
};
}

View File

@@ -1,125 +0,0 @@
{ config, lib, pkgs, mobile-nixos, utils, ... }:
with lib;
let
cfg = config.colinsane.image;
in
{
options = {
colinsane.image.extraBootFiles = mkOption {
default = [];
type = types.listOf types.package;
};
colinsane.image.extraGPTPadding = mkOption {
default = 0;
# NB: rpi doesn't like non-zero values for this.
# at the same time, spinning disks REALLY need partitions to be aligned to 4KiB boundaries.
# maybe there's some imageBuilder.fileSystem type which represents empty space?
# default = 2014 * 512; # standard is to start part0 at sector 2048 (versus 34 if no padding)
type = types.int;
};
colinsane.image.firstPartGap = mkOption {
# align the first part to 16 MiB.
# do this by inserting a gap of 16 MiB - gptHeaderSize
# and then multiply by 1MiB and subtract 1 because mobile-nixos
# has a bug which will divide this by 1 MiB (and round up)
default = (16 * 1024 * 1024 - 34 * 512) * 1024 * 1024 - 1;
type = types.nullOr types.int;
};
colinsane.image.bootPartSize = mkOption {
default = 512 * 1024 * 1024;
type = types.int;
};
};
config = let
# return true if super starts with sub
startsWith = super: sub: (
(builtins.substring 0 (builtins.stringLength sub) super) == sub
);
# return the (string) path to get from `stem` to `path`
relPath = stem: path: (
builtins.head (builtins.match "^${stem}(.+)" path)
);
fileSystems = config.fileSystems;
bootFs = fileSystems."/boot";
nixFs = fileSystems."/nix/store" or fileSystems."/nix" or fileSystems."/";
# resolves to e.g. "nix/store", "/store" or ""
storeRelPath = relPath nixFs.mountPoint "/nix/store";
# return a list of all the `device` values -- one for each fileSystems."$x"
devices = builtins.attrValues (builtins.mapAttrs (mount: entry: entry.device) fileSystems);
# filter the devices to just those which sit under nixFs
subNixMounts = builtins.filter (a: startsWith (builtins.toString a) nixFs.mountPoint) devices;
# e.g. ["/nix/persist/var"] -> ["/persist/var"] if nixFs sits at /nix
subNixRelMounts = builtins.map (m: relPath nixFs.mountPoint m) subNixMounts;
makeSubNixMounts = builtins.toString (builtins.map (m: "mkdir -p ./${m};") subNixRelMounts);
uuidFromFs = fs: builtins.head (builtins.match "/dev/disk/by-uuid/(.+)" fs.device);
vfatUuidFromFs = fs: builtins.replaceStrings ["-"] [""] (uuidFromFs fs);
fsBuilderMapBoot = {
"vfat" = pkgs.imageBuilder.fileSystem.makeESP;
};
fsBuilderMapNix = {
"ext4" = pkgs.imageBuilder.fileSystem.makeExt4;
"btrfs" = pkgs.imageBuilder.fileSystem.makeBtrfs;
};
in {
system.build.img-without-firmware = with pkgs; imageBuilder.diskImage.makeGPT {
name = "nixos";
diskID = vfatUuidFromFs bootFs;
# leave some space for firmware
# TODO: we'd prefer to turn this into a protected firmware partition, rather than reserving space in the GPT header itself
# Tow-Boot manages to do that; not sure how.
headerHole = cfg.extraGPTPadding;
partitions = [
(pkgs.imageBuilder.gap cfg.firstPartGap)
(fsBuilderMapBoot."${bootFs.fsType}" {
# fs properties
name = "ESP";
partitionID = vfatUuidFromFs bootFs;
# partition properties
partitionLabel = "EFI System";
partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}";
size = cfg.bootPartSize;
populateCommands = let
extras = builtins.toString (builtins.map (d: "cp -R ${d}/* ./") cfg.extraBootFiles);
in ''
echo "running installBootLoader"
${config.system.build.installBootLoader} ${config.system.build.toplevel} -d .
echo "ran installBootLoader"
${extras}
echo "copied extraBootFiles"
'';
})
(fsBuilderMapNix."${nixFs.fsType}" {
# fs properties
name = "NIXOS_SYSTEM";
partitionID = uuidFromFs nixFs;
# partition properties
partitionLabel = "Linux filesystem";
partitionUUID = uuidFromFs nixFs;
populateCommands =
let
closureInfo = buildPackages.closureInfo { rootPaths = config.system.build.toplevel; };
in
''
mkdir -p ./${storeRelPath}
# TODO: we should create the dirs required for boot (/var/log?). the rest are populated automatically.
# $(makeSubNixMounts)
echo "Copying system closure..."
while IFS= read -r path; do
echo " Copying $path"
cp -prf "$path" ./${storeRelPath}
done < "${closureInfo}/store-paths"
echo "Done copying system closure..."
cp -v ${closureInfo}/registration ./nix-path-registration
'';
})
];
};
system.build.img = lib.mkDefault config.system.build.img-without-firmware;
};
}

View File

@@ -1,121 +0,0 @@
# borrows from:
# https://xeiaso.net/blog/paranoid-nixos-2021-07-18
# https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/
# https://github.com/nix-community/impermanence
{ lib, config, impermanence, ... }:
with lib;
let
cfg = config.colinsane.impermanence;
in
{
imports = [
# TODO: move to flake.nix?
impermanence.nixosModule
];
options = {
colinsane.impermanence.enable = mkOption {
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
environment.persistence."/nix/persist" = {
directories = [
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/archive"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/dev"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/records"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/ref"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/tmp"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/use"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/Music"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/Pictures"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/Videos"; }
# cache is probably too big to fit on the tmpfs
# TODO: we could bind-mount it to something which gets cleared per boot, though.
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.cache"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.cargo"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.rustup"; }
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.ssh"; }
# intentionally omitted:
# "/home/colin/.config" # managed by home-manager
# "/home/colin/.local" # nothing useful in here
# "/home/colin/.mozilla" # managed by home-manager
# creds. TODO: can i manage this with home-manager?
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.config/spotify"; }
# creds, but also 200 MB of node modules, etc
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.config/discord"; }
# creds/session keys, etc
{ user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/.config/Element"; }
{ user = "root"; group = "root"; mode = "0700"; directory = "/etc/NetworkManager/system-connections"; }
# "/etc/nixos"
{ user = "root"; group = "root"; mode = "0755"; directory = "/etc/ssh"; }
# "/var/lib/AccountsService" # not sure what this is, but it's empty
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/alsa"; } # preserve output levels, default devices
# "/var/lib/blueman" # files aren't human readable
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/bluetooth"; } # preserve bluetooth handshakes
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/colord"; } # preserve color calibrations (?)
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/duplicity"; } # we need this mostly because of the size of duplicity's cache
# "/var/lib/dhclient" # empty on lappy; dunno about desko
# "/var/lib/fwupd" # not sure why this would need persistent state
# "/var/lib/geoclue" # empty on lappy
# "/var/lib/lockdown" # empty on desko; might store secrets after iOS handshake?
# "/var/lib/logrotate.status" # seems redundant with what's in /var/log?
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/machines"; } # maybe not needed, but would be painful to add a VM and forget.
# "/var/lib/misc" # empty on lappy
# "/var/lib/NetworkManager" # looks to be mostly impermanent state?
# "/var/lib/NetworkManager-fortisslvpn" # empty on lappy
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/nixos"; } # has some uid/gid maps; not sure what happens if we lose this.
# "/var/lib/PackageKit" # wtf is this?
# "/var/lib/power-profiles-daemon" # redundant with nixos declarations
# "/var/lib/private" # empty on lappy
# "/var/lib/systemd" # nothing obviously necessary
# "/var/lib/udisks2" # empty on lappy
# "/var/lib/upower" # historic charge data. unnecessary, but maybe used somewhere?
#
# servo additions:
{ user = "998"; group = "996"; mode = "0755"; directory = "/var/lib/acme"; } # TODO: mode?
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
# "/var/lib/dovecot"
# "/var/lib/duplicity"
{ user = "994"; group = "993"; mode = "0755"; directory = "/var/lib/gitea"; } # TODO: mode? could be more granular
{ user = "261"; group = "261"; mode = "0755"; directory = "/var/lib/ipfs"; } # TODO: mode? could be more granular
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/jackett"; } # TODO: mode? we only need this to save Indexer creds ==> migrate to config?
{ user = "996"; group = "994"; mode = "0755"; directory = "/var/lib/jellyfin"; } # TODO: mode? could be more granular
{ user = "993"; group = "992"; mode = "0755"; directory = "/var/lib/matrix-appservice-irc"; } # TODO: mode?
{ user = "224"; group = "224"; mode = "0755"; directory = "/var/lib/matrix-synapse"; } # TODO: mode?
{ user = "221"; group = "221"; mode = "0755"; directory = "/var/lib/opendkim"; } # TODO: mode? move this to the nix config (SOPS)
{ user = "997"; group = "995"; mode = "0755"; directory = "/var/lib/pleroma"; } # TODO: mode? could be more granular
{ user = "71"; group = "71"; mode = "0755"; directory = "/var/lib/postgresql"; } # TODO: mode?
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/lib/postfix"; } # TODO: mode? could be more granular
{ user = "70"; group = "70"; mode = "0755"; directory = "/var/lib/transmission"; } # TODO: mode? we need this specifically for the stats tracking in .config/
{ user = "colin"; group = "users"; mode = "0755"; directory = "/var/lib/uninsane"; }
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/log"; }
{ user = "root"; group = "root"; mode = "0755"; directory = "/var/backup"; } # for e.g. postgres dumps
# TODO: what even GOES in /srv?
{ user = "root"; group = "root"; mode = "0755"; directory = "/srv"; }
];
files = [
"/etc/machine-id"
# "/home/colin/knowledge"
"/home/colin/.zsh_history"
# # XXX these only need persistence because i have mutableUsers = true, i think
# "/etc/group"
# "/etc/passwd"
# "/etc/shadow"
# { file = "/home/test2"; persistentStoragePath = "/nix/persist"; }
];
};
systemd.services.sane-sops = {
description = "sops relies on /etc/ssh being available, so re-run its activation AFTER fs-local";
script = config.system.activationScripts.setupSecrets.text;
after = [ "fs-local.target" ];
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@@ -1,34 +0,0 @@
{ lib, config, ... }:
with lib;
let
cfg = config.colinsane.nixcache;
in
{
options = {
colinsane.nixcache.enable = mkOption {
default = false;
type = types.bool;
};
};
config = {
# use our own binary cache
nix.settings = mkIf cfg.enable {
substituters = [
"https://nixcache.uninsane.org"
"https://nix-community.cachix.org"
"https://cache.nixos.org/"
];
trusted-public-keys = [
"nixcache.uninsane.org:r3WILM6+QrkmsLgqVQcEdibFD7Q/4gyzD9dGT33GP70="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
# allow `nix flake ...` command
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
};
}

View File

@@ -1,70 +0,0 @@
# docs: https://search.nixos.org/options?channel=21.11&query=duplicity
{ config, lib, ... }:
with lib;
let
cfg = config.colinsane.services.duplicity;
in
{
options = {
colinsane.services.duplicity.enable = mkOption {
default = false;
type = types.bool;
};
};
config = mkIf cfg.enable {
services.duplicity.enable = true;
services.duplicity.targetUrl = ''"$DUPLICITY_URL"'';
services.duplicity.escapeUrl = false;
# format: PASSPHRASE=<cleartext> \n DUPLICITY_URL=b2://...
# two sisters
# PASSPHRASE: remote backups will be encrypted using this passphrase (using gpg)
# DUPLICITY_URL: b2://$key_id:$app_key@$bucket
# create key with: backblaze-b2 create-key --bucket uninsane-host-duplicity uninsane-host-duplicity-safe listBuckets,listFiles,readBuckets,readFiles,writeFiles
# ^ run this until you get a key with no forward slashes :upside_down:
# web-created keys are allowed to delete files, which you probably don't want for an incremental backup program
# you need to create a new application key from the web in order to first get a key which can create new keys (use env vars in the above command)
# TODO: s/duplicity_passphrase/duplicity_env/
services.duplicity.secretFile = config.sops.secrets.duplicity_passphrase.path;
# NB: manually trigger with `systemctl start duplicity`
services.duplicity.frequency = "daily";
services.duplicity.exclude = [
# impermanent/inconsequential data:
"/dev"
"/proc"
"/run"
"/sys"
"/tmp"
# bind mounted (dupes):
"/var/lib"
# other mounts
"/mnt"
# data that's not worth the cost to backup:
"/nix/persist/var/lib/uninsane/media"
"/nix/persist/home/colin/tmp"
"/nix/persist/home/colin/Videos"
"/home/colin/tmp"
"/home/colin/Videos"
];
services.duplicity.extraFlags = [
# without --allow-source-mismatch, duplicity will abort if you change the hostname between backups
"--allow-source-mismatch"
];
# set this for the FIRST backup, then remove it to enable incremental backups
# (that the first backup *isn't* full i think is a defect)
# services.duplicity.fullIfOlderThan = "always";
systemd.services.duplicity.serviceConfig = {
# rate-limit the read bandwidth in an effort to thereby prevent net upload saturation
# this could perhaps be done better by adding a duplicity config option to replace the binary with `trickle`
IOReadBandwidthMax = [
"/dev/sda1 5M"
"/dev/nvme0n1 5M"
"/dev/mmc0 5M"
];
};
};
}

View File

@@ -1,33 +0,0 @@
{ pkgs, ... }:
{
imports = [
./fs.nix
./home-manager.nix
./secrets.nix
./users.nix
./vpn.nix
];
time.timeZone = "America/Los_Angeles";
fonts = {
enableDefaultFonts = true;
fonts = with pkgs; [ font-awesome twitter-color-emoji hack-font ];
fontconfig.enable = true;
fontconfig.defaultFonts = {
emoji = [ "Font Awesome 6 Free" "Twitter Color Emoji" ];
monospace = [ "Hack" ];
serif = [ "DejaVu Serif" ];
sansSerif = [ "DejaVu Sans" ];
};
};
# programs.vim.defaultEditor = true;
environment.variables = {
EDITOR = "vim";
# git claims it should use EDITOR, but it doesn't!
GIT_EDITOR = "vim";
};
}

View File

@@ -1,37 +0,0 @@
{ pkgs, ... }:
let sshOpts = {
fsType = "fuse.sshfs";
options = [
"x-systemd.automount"
"_netdev"
"user"
"idmap=user"
"transform_symlinks"
"identityfile=/home/colin/.ssh/id_ed25519"
"allow_other"
"default_permissions"
"uid=1000"
"gid=100"
];
};
in
{
fileSystems."/mnt/servo-media-wan" = {
device = "colin@uninsane.org:/var/lib/uninsane/media";
inherit (sshOpts) fsType options;
};
fileSystems."/mnt/servo-media-lan" = {
device = "colin@servo:/var/lib/uninsane/media";
inherit (sshOpts) fsType options;
};
fileSystems."/mnt/desko-home" = {
device = "colin@desko:/home/colin";
inherit (sshOpts) fsType options;
};
environment.systemPackages = [
pkgs.sshfs-fuse
];
}

View File

@@ -1,365 +0,0 @@
# docs:
# https://rycee.gitlab.io/home-manager/
# https://rycee.gitlab.io/home-manager/options.html
# man home-configuration.nix
#
{ home-manager, lib, config, pkgs, ... }:
with lib;
let
cfg = config.colinsane.home-manager;
in
{
imports = [
home-manager.nixosModule
];
options = {
colinsane.home-manager.enable = mkOption {
default = false;
type = types.bool;
};
colinsane.home-manager.extraPackages = mkOption {
default = [ ];
type = types.listOf types.package;
};
colinsane.home-manager.windowManager = mkOption {
default = {};
type = types.attrs;
};
colinsane.home-manager.programs = mkOption {
default = {};
type = types.attrs;
};
};
config = lib.mkIf cfg.enable {
sops.secrets."aerc_accounts" = {
owner = config.users.users.colin.name;
sopsFile = ../../secrets/universal/aerc_accounts.conf;
format = "binary";
};
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
# XXX this weird rename + closure is to get home-manager's `config.lib.file` to exist.
# see: https://github.com/nix-community/home-manager/issues/589#issuecomment-950474105
home-manager.users.colin = let sysconfig = config; in { config, ... }: {
home.stateVersion = "21.11";
home.username = "colin";
home.homeDirectory = "/home/colin";
# XDG defines things like ~/Desktop, ~/Downloads, etc.
# these clutter the home, so i mostly don't use them.
xdg.userDirs = {
enable = true;
createDirectories = false; # on headless systems, most xdg dirs are noise
desktop = "$HOME/.xdg/Desktop";
documents = "$HOME/dev";
download = "$HOME/tmp";
music = "$HOME/Music";
pictures = "$HOME/Pictures";
publicShare = "$HOME/.xdg/Public";
templates = "$HOME/.xdg/Templates";
videos = "$HOME/Videos";
};
xdg.mimeApps.enable = true;
xdg.mimeApps.defaultApplications = {
"text/html" = [ "librewolf.desktop" ];
"x-scheme-handler/http" = [ "librewolf.desktop" ];
"x-scheme-handler/https" = [ "librewolf.desktop" ];
"x-scheme-handler/about" = [ "librewolf.desktop" ];
"x-scheme-handler/unknown" = [ "librewolf.desktop" ];
};
# convenience
home.file."knowledge".source = config.lib.file.mkOutOfStoreSymlink "/home/colin/dev/knowledge";
home.file."nixos".source = config.lib.file.mkOutOfStoreSymlink "/home/colin/dev/nixos";
xdg.configFile."aerc/accounts.conf".source =
config.lib.file.mkOutOfStoreSymlink sysconfig.sops.secrets.aerc_accounts.path;
programs = {
home-manager.enable = true; # this lets home-manager manage dot-files in user dirs, i think
zsh = {
enable = true;
enableSyntaxHighlighting = true;
enableVteIntegration = true;
dotDir = ".config/zsh";
initExtraBeforeCompInit = ''
# p10k instant prompt
# run p10k configure to configure, but it can't write out its file :-(
POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true
'';
# prezto = oh-my-zsh fork; controls prompt, auto-completion, etc.
# see: https://github.com/sorin-ionescu/prezto
prezto = {
enable = true;
pmodules = [
"environment"
"terminal"
"editor"
"history"
"directory"
"spectrum"
"utility"
"completion"
"prompt"
"git"
];
prompt = {
theme = "powerlevel10k";
};
};
};
kitty = {
enable = true;
settings.enable_audio_bell = false;
};
git = {
enable = true;
userName = "colin";
userEmail = "colin@uninsane.org";
};
vim = {
enable = true;
extraConfig = ''
" wtf vim project: NOBODY LIKES MOUSE FOR VISUAL MODE
set mouse-=a
" copy/paste to system clipboard
set clipboard=unnamedplus
" <tab> completion menu settings
set wildmenu
set wildmode=longest,list,full
" highlight all matching searches (using / and ?)
set hlsearch
" allow backspace to delete empty lines in insert mode
set backspace=indent,eol,start
" built-in syntax highlighting
syntax enable
" show line/col number in bottom right
set ruler
" highlight trailing space & related syntax errors (does this work?)
let c_space_errors=1
let python_space_errors=1
'';
};
firefox = lib.mkIf (sysconfig.colinsane.gui.enable) {
# common settings to toggle (at runtime, in about:config):
# > security.ssl.require_safe_negotiation
enable = true;
# librewolf is a forked firefox which patches firefox to allow more things
# (like default search engines) to be configurable at runtime.
# many of the settings below won't have effect without those patches.
# see: https://gitlab.com/librewolf-community/settings/-/blob/master/distribution/policies.json
package = pkgs.wrapFirefox pkgs.librewolf-unwrapped {
# inherit the default librewolf.cfg
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg
inherit (pkgs.librewolf-unwrapped) extraPrefsFiles;
libName = "librewolf";
extraPolicies = {
NoDefaultBookmarks = true;
SearchEngines = {
Default = "DuckDuckGo";
};
AppUpdateURL = "https://localhost";
DisableAppUpdate = true;
OverrideFirstRunPage = "";
OverridePostUpdatePage = "";
DisableSystemAddonUpdate = true;
DisableFirefoxStudies = true;
DisableTelemetry = true;
DisableFeedbackCommands = true;
DisablePocket = true;
DisableSetDesktopBackground = false;
Extensions = {
Install = [
"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
"https://addons.mozilla.org/firefox/downloads/latest/i-dont-care-about-cookies/latest.xpi"
"https://addons.mozilla.org/firefox/downloads/latest/sponsorblock/latest.xpi"
"https://addons.mozilla.org/firefox/downloads/latest/bypass-paywalls-clean/latest.xpi"
"https://addons.mozilla.org/firefox/downloads/latest/sidebery/latest.xpi"
"https://addons.mozilla.org/firefox/downloads/latest/ether-metamask/latest.xpi"
];
# remove many default search providers
Uninstall = [
"google@search.mozilla.org"
"bing@search.mozilla.org"
"amazondotcom@search.mozilla.org"
"ebay@search.mozilla.org"
"twitter@search.mozilla.org"
];
};
# XXX doesn't seem to have any effect...
# docs: https://github.com/mozilla/policy-templates#homepage
# Homepage = {
# HomepageURL = "https://uninsane.org/";
# StartPage = "homepage";
# };
# NewTabPage = true;
# docs: https://chromeenterprise.google/policies/?policy=ManagedBookmarks
# docs: https://github.com/mozilla/policy-templates#managedbookmarks
ManagedBookmarks = [
{
toplevel_name = "bookmarks";
}
{
name = "Pleroma";
url = "https://fed.uninsane.org/";
}
{
name = "Home Manager Config";
url = "https://nix-community.github.io/home-manager/options.html";
}
{
name = "Delightful Apps";
url = "https://delightful.club/";
}
{
name = "Linux Phone Apps";
url = "https://linuxphoneapps.org/mobile-compatibility/5/";
}
{
name = "Crowdsupply";
url = "https://www.crowdsupply.com/";
}
{
name = "Mempool";
url = "https://jochen-hoenicke.de/queue";
}
];
};
};
};
# "command not found" will cause the command to be searched in nixpkgs
nix-index.enable = true;
} // cfg.programs;
home.shellAliases = {
":q" = "exit";
# common typos
"cd.." = "cd ..";
"cd../" = "cd ../";
};
wayland.windowManager = cfg.windowManager;
# devtools:
# bison
# dtc
# flex
# gcc-arm-embedded
# gcc_multi
# swig
home.packages = with pkgs; [
backblaze-b2
btrfs-progs
cryptsetup
dig
duplicity
efibootmgr
fatresize
fd
file
gcc
gnumake
gptfdisk
hdparm
htop
iftop
ifuse
inetutils # for telnet
iotop
ipfs
iptables
jq
killall
libimobiledevice
lm_sensors # for sensors-detect
lsof
mix2nix
netcat
nethogs
networkmanager
nixpkgs-review
# nixos-generators
# nettools
nmap
oathToolkit # for oathtool
openssl
parted
pciutils
# ponymix
powertop
pulsemixer
python3
ripgrep
rmlint
rustup
sane-scripts
screen
smartmontools
snapper
socat
sops
ssh-to-age
sudo
usbutils
wget
wireguard-tools
youtube-dl
zola
]
++ (if sysconfig.colinsane.gui.enable then
with pkgs;
[
# GUI only
aerc # email client
audacity
chromium
clinfo
element-desktop # broken on phosh
evince # works on phosh
font-manager
gimp # broken on phosh
gnome.dconf-editor
gnome-feeds # RSS reader (with claimed mobile support)
gnome.file-roller
gnome.gnome-maps # works on phosh
gnome.nautilus
gnome-podcasts
gnome.gnome-terminal # works on phosh
inkscape
libreoffice-fresh # XXX colin: maybe don't want this on mobile
mesa-demos
networkmanagerapplet
obsidian
playerctl
tdesktop # broken on phosh
vlc # works on phosh
whalebird # pleroma client. input is broken on phosh
xterm # broken on phosh
] else [])
++ (if sysconfig.colinsane.gui.enable && pkgs.system == "x86_64-linux" then
with pkgs;
[
# x86_64 only
discord
kaiteki # Pleroma client
gnome.zenity # for kaiteki (it will use qarma, kdialog, or zenity)
signal-desktop
spotify
] else [])
++ cfg.extraPackages;
};
};
}

View File

@@ -1,53 +0,0 @@
{ config, ... }:
{
# SOPS configuration:
# docs: https://github.com/Mic92/sops-nix
#
# for each new user you want to edit sops files:
# create a private age key from ssh key:
# $ mkdir -p ~/.config/sops/age; ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/sops/age/keys.txt; chmod 600 ~/.config/sops/age/keys.txt
# if the private key was password protected, then first decrypt it:
# $ cp ~/.ssh/id_ed25519 /tmp/id_ed25519
# $ ssh-keygen -p -N "" -f /tmp/id_ed25519
#
# for each user you want to decrypt secrets:
# $ cat ~/.ssh/id_ed25519.pub | ssh-to-age
# add the result to .sops.yaml
# since we specify ssh pubkeys in the nix config, you can just grep for `ssh-ed25519` here and use those instead
#
# for each machine you want to decrypt secrets:
# $ cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age
# add the result to .sops.yaml
# $ sops updatekeys secrets/example.yaml
#
# to create a new secret:
# $ sops secrets/example.yaml
# control access below (sops.secret.<x>.owner = ...)
#
# to read a secret:
# $ cat /run/secrets/example_key
# sops.age.sshKeyPaths = [ "/home/colin/.ssh/id_ed25519_dec" ];
# This will add secrets.yml to the nix store
# You can avoid this by adding a string to the full path instead, i.e.
# sops.defaultSopsFile = "/root/.sops/secrets/example.yaml";
sops.defaultSopsFile = ./../../secrets/universal.yaml;
# This will automatically import SSH keys as age keys
sops.age.sshKeyPaths = [
"/etc/ssh/ssh_host_ed25519_key"
# "/home/colin/.ssh/id_ed25519_dec"
];
# This is using an age key that is expected to already be in the filesystem
# sops.age.keyFile = "/home/colin/.ssh/age.pub";
# sops.age.keyFile = "/var/lib/sops-nix/key.txt";
# This will generate a new key if the key specified above does not exist
# sops.age.generateKey = true;
# This is the actual specification of the secrets.
# sops.secrets.example_key = {
# owner = config.users.users.colin.name;
# };
# sops.secrets."myservice/my_subdir/my_secret" = {};
}

View File

@@ -1,31 +0,0 @@
{ config, ... }:
{
networking.wg-quick.interfaces.ovpnd = {
address = [
"172.27.237.218/32"
"fd00:0000:1337:cafe:1111:1111:ab00:4c8f/128"
];
dns = [
"46.227.67.134"
"192.165.9.158"
];
peers = [
{
allowedIPs = [
"0.0.0.0/0"
"::/0"
];
endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
}
];
privateKeyFile = config.sops.secrets.wg_ovpnd_privkey.path;
# to start: `systemctl start wg-quick-ovpnd`
autostart = false;
};
sops.secrets."wg_ovpnd_privkey" = {
sopsFile = ../../secrets/universal.yaml;
};
}

View File

@@ -0,0 +1,19 @@
diff --git a/nixos/modules/services/x11/desktop-managers/phosh.nix b/nixos/modules/services/x11/desktop-managers/phosh.nix
index 4bf78fa16e7..13f7b3fbef2 100644
--- a/nixos/modules/services/x11/desktop-managers/phosh.nix
+++ b/nixos/modules/services/x11/desktop-managers/phosh.nix
@@ -78,7 +78,13 @@ let
description = ''
Display scaling factor.
'';
- type = types.nullOr types.ints.unsigned;
+ type = types.nullOr (
+ types.addCheck
+ (types.either types.int types.float)
+ (x : x > 0)
+ ) // {
+ description = "null or positive integer or float";
+ };
default = null;
example = 2;
};

View File

@@ -0,0 +1,18 @@
diff --git a/pkgs/applications/misc/whalebird/default.nix b/pkgs/applications/misc/whalebird/default.nix
index 9b8a7f0a348..0f60f74c91b 100644
--- a/pkgs/applications/misc/whalebird/default.nix
+++ b/pkgs/applications/misc/whalebird/default.nix
@@ -3,11 +3,11 @@
stdenv.mkDerivation rec {
pname = "whalebird";
- version = "4.5.4";
+ version = "4.6.0";
src = fetchurl {
url = "https://github.com/h3poteto/whalebird-desktop/releases/download/${version}/Whalebird-${version}-linux-x64.deb";
- sha256 = "048c2hpnlzjli8r1lcm7hd32qfsq4p9vkimrgc049yw9f15ndjpr";
+ sha256 = "d8042eb21e4320771782a1835a591252894ad657eec46248c807d5a772e1938e";
};
nativeBuildInputs = [

View File

@@ -36,19 +36,19 @@ index 9eba6773448..f51aeb8b624 100644
patches = getPatches ./patches;
};
diff --git a/pkgs/development/compilers/flutter/flutter.nix b/pkgs/development/compilers/flutter/flutter.nix
index 43538ede339..ece25c14b55 100644
index 43538ede339..26f50f731c2 100644
--- a/pkgs/development/compilers/flutter/flutter.nix
+++ b/pkgs/development/compilers/flutter/flutter.nix
@@ -56,12 +56,15 @@ let
export STAMP_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.stamp"
@@ -48,6 +48,7 @@ let
'';
export DART_SDK_PATH="${dart}"
+ export DART="${dart}/bin/dart"
HOME=../.. # required for pub upgrade --offline, ~/.pub-cache
buildPhase = ''
+ set -ex
export FLUTTER_ROOT="$(pwd)"
export FLUTTER_TOOLS_DIR="$FLUTTER_ROOT/packages/flutter_tools"
export SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart"
@@ -61,7 +62,7 @@ let
# path is relative otherwise it's replaced by /build/flutter
+ # mkdir -p "$HOME/.cache"
+ # ln -sf "$FLUTTER_ROOT" "$HOME/.cache/flutter"
pushd "$FLUTTER_TOOLS_DIR"
- ${dart}/bin/pub get --offline
@@ -56,247 +56,3 @@ index 43538ede339..ece25c14b55 100644
popd
local revision="$(cd "$FLUTTER_ROOT"; git rev-parse HEAD)"
diff --git a/pkgs/development/compilers/flutter/patches/git-dir.patch b/pkgs/development/compilers/flutter/patches/git-dir.patch
new file mode 100644
index 00000000000..0c736f945ea
--- /dev/null
+++ b/pkgs/development/compilers/flutter/patches/git-dir.patch
@@ -0,0 +1,102 @@
+diff --git a/dev/bots/prepare_package.dart b/dev/bots/prepare_package.dart
+index 468a91a954..5def6897ce 100644
+--- a/dev/bots/prepare_package.dart
++++ b/dev/bots/prepare_package.dart
+@@ -525,7 +525,7 @@ class ArchiveCreator {
+
+ Future<String> _runGit(List<String> args, {Directory? workingDirectory}) {
+ return _processRunner.runProcess(
+- <String>['git', ...args],
++ <String>['git', '--git-dir', '.git', ...args],
+ workingDirectory: workingDirectory ?? flutterRoot,
+ );
+ }
+diff --git a/packages/flutter_tools/lib/src/commands/downgrade.dart b/packages/flutter_tools/lib/src/commands/downgrade.dart
+index bb0eb428a9..4a2a48bb5e 100644
+--- a/packages/flutter_tools/lib/src/commands/downgrade.dart
++++ b/packages/flutter_tools/lib/src/commands/downgrade.dart
+@@ -118,7 +118,7 @@ class DowngradeCommand extends FlutterCommand {
+ // Detect unknown versions.
+ final ProcessUtils processUtils = _processUtils!;
+ final RunResult parseResult = await processUtils.run(<String>[
+- 'git', 'describe', '--tags', lastFlutterVersion,
++ 'git', '--git-dir', '.git', 'describe', '--tags', lastFlutterVersion,
+ ], workingDirectory: workingDirectory);
+ if (parseResult.exitCode != 0) {
+ throwToolExit('Failed to parse version for downgrade:\n${parseResult.stderr}');
+@@ -191,7 +191,7 @@ class DowngradeCommand extends FlutterCommand {
+ continue;
+ }
+ final RunResult parseResult = await _processUtils!.run(<String>[
+- 'git', 'describe', '--tags', sha,
++ 'git', '--git-dir', '.git', 'describe', '--tags', sha,
+ ], workingDirectory: workingDirectory);
+ if (parseResult.exitCode == 0) {
+ buffer.writeln('Channel "${getNameForChannel(channel)}" was previously on: ${parseResult.stdout}.');
+diff --git a/packages/flutter_tools/lib/src/version.dart b/packages/flutter_tools/lib/src/version.dart
+index f2068a6ca2..99b161689e 100644
+--- a/packages/flutter_tools/lib/src/version.dart
++++ b/packages/flutter_tools/lib/src/version.dart
+@@ -106,7 +106,7 @@ class FlutterVersion {
+ String? channel = _channel;
+ if (channel == null) {
+ final String gitChannel = _runGit(
+- 'git rev-parse --abbrev-ref --symbolic @{u}',
++ 'git --git-dir .git rev-parse --abbrev-ref --symbolic @{u}',
+ globals.processUtils,
+ _workingDirectory,
+ );
+@@ -114,7 +114,7 @@ class FlutterVersion {
+ if (slash != -1) {
+ final String remote = gitChannel.substring(0, slash);
+ _repositoryUrl = _runGit(
+- 'git ls-remote --get-url $remote',
++ 'git --git-dir .git ls-remote --get-url $remote',
+ globals.processUtils,
+ _workingDirectory,
+ );
+@@ -326,7 +326,7 @@ class FlutterVersion {
+ /// the branch name will be returned as `'[user-branch]'`.
+ String getBranchName({ bool redactUnknownBranches = false }) {
+ _branch ??= () {
+- final String branch = _runGit('git rev-parse --abbrev-ref HEAD', globals.processUtils);
++ final String branch = _runGit('git --git-dir .git rev-parse --abbrev-ref HEAD', globals.processUtils);
+ return branch == 'HEAD' ? channel : branch;
+ }();
+ if (redactUnknownBranches || _branch!.isEmpty) {
+@@ -359,7 +359,7 @@ class FlutterVersion {
+ /// wrapper that does that.
+ @visibleForTesting
+ static List<String> gitLog(List<String> args) {
+- return <String>['git', '-c', 'log.showSignature=false', 'log'] + args;
++ return <String>['git', '-c', 'log.showSignature=false', '--git-dir', '.git', 'log'] + args;
+ }
+
+ /// Gets the release date of the latest available Flutter version.
+@@ -730,7 +730,7 @@ class GitTagVersion {
+
+ static GitTagVersion determine(ProcessUtils processUtils, {String? workingDirectory, bool fetchTags = false, String gitRef = 'HEAD'}) {
+ if (fetchTags) {
+- final String channel = _runGit('git rev-parse --abbrev-ref HEAD', processUtils, workingDirectory);
++ final String channel = _runGit('git --git-dir .git rev-parse --abbrev-ref HEAD', processUtils, workingDirectory);
+ if (channel == 'dev' || channel == 'beta' || channel == 'stable') {
+ globals.printTrace('Skipping request to fetchTags - on well known channel $channel.');
+ } else {
+@@ -739,7 +739,7 @@ class GitTagVersion {
+ }
+ // find all tags attached to the given [gitRef]
+ final List<String> tags = _runGit(
+- 'git tag --points-at $gitRef', processUtils, workingDirectory).trim().split('\n');
++ 'git --git-dir .git tag --points-at $gitRef', processUtils, workingDirectory).trim().split('\n');
+
+ // Check first for a stable tag
+ final RegExp stableTagPattern = RegExp(r'^\d+\.\d+\.\d+$');
+@@ -760,7 +760,7 @@ class GitTagVersion {
+ // recent tag and number of commits past.
+ return parse(
+ _runGit(
+- 'git describe --match *.*.* --long --tags $gitRef',
++ 'git --git-dir .git describe --match *.*.* --long --tags $gitRef',
+ processUtils,
+ workingDirectory,
+ )
diff --git a/pkgs/development/compilers/flutter/patches/revert-frontend_server_cache.patch b/pkgs/development/compilers/flutter/patches/revert-frontend_server_cache.patch
new file mode 100644
index 00000000000..f68029eb7a1
--- /dev/null
+++ b/pkgs/development/compilers/flutter/patches/revert-frontend_server_cache.patch
@@ -0,0 +1,130 @@
+diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
+index 2aac9686e8..32c4b98b88 100644
+--- a/packages/flutter_tools/lib/src/artifacts.dart
++++ b/packages/flutter_tools/lib/src/artifacts.dart
+@@ -346,10 +346,10 @@ class CachedArtifacts implements Artifacts {
+ ) {
+ switch (artifact) {
+ case HostArtifact.engineDartSdkPath:
+- final String path = _dartSdkPath(_cache);
++ final String path = _dartSdkPath(_fileSystem);
+ return _fileSystem.directory(path);
+ case HostArtifact.engineDartBinary:
+- final String path = _fileSystem.path.join(_dartSdkPath(_cache), 'bin', _hostArtifactToFileName(artifact, _platform.isWindows));
++ final String path = _fileSystem.path.join(_dartSdkPath(_fileSystem), 'bin', _hostArtifactToFileName(artifact, _platform.isWindows));
+ return _fileSystem.file(path);
+ case HostArtifact.flutterWebSdk:
+ final String path = _getFlutterWebSdkPath();
+@@ -398,7 +398,7 @@ class CachedArtifacts implements Artifacts {
+ case HostArtifact.dart2jsSnapshot:
+ case HostArtifact.dartdevcSnapshot:
+ case HostArtifact.kernelWorkerSnapshot:
+- final String path = _fileSystem.path.join(_dartSdkPath(_cache), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform.isWindows));
++ final String path = _fileSystem.path.join(_dartSdkPath(_fileSystem), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform.isWindows));
+ return _fileSystem.file(path);
+ case HostArtifact.iosDeploy:
+ final String artifactFileName = _hostArtifactToFileName(artifact, _platform.isWindows);
+@@ -461,11 +461,13 @@ class CachedArtifacts implements Artifacts {
+ String _getAndroidArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
+ final String engineDir = _getEngineArtifactsPath(platform, mode)!;
+ switch (artifact) {
++ case Artifact.frontendServerSnapshotForEngineDartSdk:
++ assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
++ return _fileSystem.path.join(engineDir, _artifactToFileName(artifact));
+ case Artifact.genSnapshot:
+ assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
+ final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
+ return _fileSystem.path.join(engineDir, hostPlatform, _artifactToFileName(artifact));
+- case Artifact.frontendServerSnapshotForEngineDartSdk:
+ case Artifact.constFinder:
+ case Artifact.flutterFramework:
+ case Artifact.flutterMacOSFramework:
+@@ -497,13 +499,13 @@ class CachedArtifacts implements Artifacts {
+ switch (artifact) {
+ case Artifact.genSnapshot:
+ case Artifact.flutterXcframework:
++ case Artifact.frontendServerSnapshotForEngineDartSdk:
+ final String artifactFileName = _artifactToFileName(artifact)!;
+ final String engineDir = _getEngineArtifactsPath(platform, mode)!;
+ return _fileSystem.path.join(engineDir, artifactFileName);
+ case Artifact.flutterFramework:
+ final String engineDir = _getEngineArtifactsPath(platform, mode)!;
+ return _getIosEngineArtifactPath(engineDir, environmentType, _fileSystem);
+- case Artifact.frontendServerSnapshotForEngineDartSdk:
+ case Artifact.constFinder:
+ case Artifact.flutterMacOSFramework:
+ case Artifact.flutterMacOSPodspec:
+@@ -594,14 +596,10 @@ class CachedArtifacts implements Artifacts {
+ // For script snapshots any gen_snapshot binary will do. Returning gen_snapshot for
+ // android_arm in profile mode because it is available on all supported host platforms.
+ return _getAndroidArtifactPath(artifact, TargetPlatform.android_arm, BuildMode.profile);
+- case Artifact.frontendServerSnapshotForEngineDartSdk:
+- return _fileSystem.path.join(
+- _dartSdkPath(_cache), 'bin', 'snapshots',
+- _artifactToFileName(artifact),
+- );
+ case Artifact.flutterTester:
+ case Artifact.vmSnapshotData:
+ case Artifact.isolateSnapshotData:
++ case Artifact.frontendServerSnapshotForEngineDartSdk:
+ case Artifact.icuData:
+ final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
+ final String platformDirName = _enginePlatformDirectoryName(platform);
+@@ -797,7 +795,7 @@ class CachedLocalEngineArtifacts implements LocalEngineArtifacts {
+ final String path = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform.isWindows));
+ return _fileSystem.file(path);
+ case HostArtifact.dartdevcSnapshot:
+- final String path = _fileSystem.path.join(_dartSdkPath(_cache), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform.isWindows));
++ final String path = _fileSystem.path.join(_dartSdkPath(_fileSystem), 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform.isWindows));
+ return _fileSystem.file(path);
+ case HostArtifact.kernelWorkerSnapshot:
+ final String path = _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', _hostArtifactToFileName(artifact, _platform.isWindows));
+@@ -922,9 +920,7 @@ class CachedLocalEngineArtifacts implements LocalEngineArtifacts {
+ case Artifact.windowsUwpCppClientWrapper:
+ return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
+ case Artifact.frontendServerSnapshotForEngineDartSdk:
+- return _fileSystem.path.join(
+- _hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName,
+- );
++ return _fileSystem.path.join(_hostEngineOutPath, 'gen', artifactFileName);
+ case Artifact.uwptool:
+ return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
+ }
+@@ -1034,8 +1030,8 @@ class OverrideArtifacts implements Artifacts {
+ }
+
+ /// Locate the Dart SDK.
+-String _dartSdkPath(Cache cache) {
+- return cache.getRoot().childDirectory('dart-sdk').path;
++String _dartSdkPath(FileSystem fileSystem) {
++ return fileSystem.path.join(Cache.flutterRoot!, 'bin', 'cache', 'dart-sdk');
+ }
+
+ class _TestArtifacts implements Artifacts {
+diff --git a/packages/flutter_tools/test/general.shard/artifacts_test.dart b/packages/flutter_tools/test/general.shard/artifacts_test.dart
+index d906511a15..adfdd4bb42 100644
+--- a/packages/flutter_tools/test/general.shard/artifacts_test.dart
++++ b/packages/flutter_tools/test/general.shard/artifacts_test.dart
+@@ -153,10 +153,6 @@ void main() {
+ artifacts.getArtifactPath(Artifact.windowsUwpDesktopPath, platform: TargetPlatform.windows_uwp_x64, mode: BuildMode.release),
+ fileSystem.path.join('root', 'bin', 'cache', 'artifacts', 'engine', 'windows-uwp-x64-release'),
+ );
+- expect(
+- artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
+- fileSystem.path.join('root', 'bin', 'cache', 'dart-sdk', 'bin', 'snapshots', 'frontend_server.dart.snapshot')
+- );
+ });
+
+ testWithoutContext('precompiled web artifact paths are correct', () {
+@@ -322,11 +318,6 @@ void main() {
+ artifacts.getHostArtifact(HostArtifact.engineDartSdkPath).path,
+ fileSystem.path.join('/out', 'host_debug_unopt', 'dart-sdk'),
+ );
+- expect(
+- artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
+- fileSystem.path.join('/out', 'host_debug_unopt', 'dart-sdk', 'bin',
+- 'snapshots', 'frontend_server.dart.snapshot')
+- );
+ });
+
+ testWithoutContext('getEngineType', () {

View File

@@ -1,43 +0,0 @@
diff --git a/nixos/modules/services/backup/duplicity.nix b/nixos/modules/services/backup/duplicity.nix
index 6949fa8b995..33d772ffa37 100644
--- a/nixos/modules/services/backup/duplicity.nix
+++ b/nixos/modules/services/backup/duplicity.nix
@@ -54,6 +54,17 @@ in
'';
};
+ escapeUrl = mkOption {
+ type = types.bool;
+ example = false;
+ default = true;
+ description = ''
+ Whether to escape the targetUrl when passing it to Duplicity as a CLI
+ argument. One might disable this in order to make use of shell
+ expressions such as environment variables.
+ '';
+ };
+
secretFile = mkOption {
type = types.nullOr types.path;
default = null;
@@ -148,7 +159,7 @@ in
script =
let
- target = escapeShellArg cfg.targetUrl;
+ target = if cfg.escapeUrl then (escapeShellArg cfg.targetUrl) else cfg.targetUrl;
extra = escapeShellArgs ([ "--archive-dir" stateDirectory ] ++ cfg.extraFlags);
dup = "${pkgs.duplicity}/bin/duplicity";
in
@@ -158,9 +169,8 @@ in
${lib.optionalString (cfg.cleanup.maxAge != null) "${dup} remove-older-than ${lib.escapeShellArg cfg.cleanup.maxAge} ${target} --force ${extra}"}
${lib.optionalString (cfg.cleanup.maxFull != null) "${dup} remove-all-but-n-full ${toString cfg.cleanup.maxFull} ${target} --force ${extra}"}
${lib.optionalString (cfg.cleanup.maxIncr != null) "${dup} remove-all-inc-of-but-n-full ${toString cfg.cleanup.maxIncr} ${target} --force ${extra}"}
- exec ${dup} ${if cfg.fullIfOlderThan == "always" then "full" else "incr"} ${lib.escapeShellArgs (
- [ cfg.root cfg.targetUrl ]
- ++ concatMap (p: [ "--include" p ]) cfg.include
+ exec ${dup} ${if cfg.fullIfOlderThan == "always" then "full" else "incr"} ${lib.escapeShellArg cfg.root} ${target} ${lib.escapeShellArgs (
+ concatMap (p: [ "--include" p ]) cfg.include
++ concatMap (p: [ "--exclude" p ]) cfg.exclude
++ (lib.optionals (cfg.fullIfOlderThan != "never" && cfg.fullIfOlderThan != "always") [ "--full-if-older-than" cfg.fullIfOlderThan ])
)} ${extra}

View File

@@ -1,19 +0,0 @@
fetchpatch: [
# phosh: allow fractional scaling
(fetchpatch {
url = "https://github.com/NixOS/nixpkgs/pull/175872.diff";
sha256 = "sha256-mEmqhe8DqlyCxkFWQKQZu+2duz69nOkTANh9TcjEOdY=";
})
# for raspberry pi: allow building u-boot for rpi 4{,00}
# TODO: remove after upstreamed: https://github.com/NixOS/nixpkgs/pull/176018
./02-rpi4-uboot.patch
# alternative to https://github.com/NixOS/nixpkgs/pull/173200
./04-dart-2.7.0.patch
# whalebird: suuport aarch64
(fetchpatch {
url = "https://github.com/NixOS/nixpkgs/pull/176476.diff";
sha256 = "sha256-126DljM06hqPZ3fjLZ3LBZR64nFbeTfzSazEu72d4y8=";
})
# TODO: upstream
./07-duplicity-rich-url.patch
]

View File

@@ -1,13 +0,0 @@
[pi3]
kernel=Tow-Boot.noenv.rpi3.bin
[pi4]
kernel=Tow-Boot.noenv.rpi4.bin
enable_gic=1
armstub=armstub8-gic.bin
disable_overscan=1
[all]
arm_64bit=1
enable_uart=1
avoid_warnings=1

View File

@@ -1,37 +0,0 @@
{ stdenv, pkgs }:
stdenv.mkDerivation rec {
pname = "bootpart-tow-boot-rpi-aarch64";
version = "1";
buildInputs = with pkgs; [
tow-boot-rpi4 # for Tow-Boot.*.bin
raspberrypifw # for bootcode.bin, *.dat, *.elf, *.dtb
raspberrypi-armstubs # for armstub*
];
src = ./config.txt;
dontUnpack = true;
installPhase = with pkgs; ''
mkdir "$out"
cp ${tow-boot-rpi4}/Tow-Boot.noenv.*.bin "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dtb "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.bin "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dat "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.img "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.elf "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/overlays "$out"/
cp ${raspberrypi-armstubs}/* "$out"/
cp ${src} "$out"/config.txt
'';
meta = {
description = "unmanaged files to place in /boot on a raspberry pi system";
platforms = [ "aarch64-linux" ];
};
}

View File

@@ -1,10 +0,0 @@
[pi4]
kernel=u-boot.bin
enable_gic=1
armstub=armstub8-gic.bin
disable_overscan=1
[all]
arm_64bit=1
enable_uart=1
avoid_warnings=1

View File

@@ -1,39 +0,0 @@
{ stdenv, pkgs }:
stdenv.mkDerivation rec {
pname = "bootpart-u-boot-rpi-aarch64";
version = "1";
buildInputs = with pkgs; [
ubootRaspberryPi4_64bit
raspberrypifw # for bootcode.bin, *.dat, *.elf, *.dtb
raspberrypi-armstubs # for armstub*
];
src = ./config.txt;
dontUnpack = true;
installPhase = with pkgs; ''
mkdir "$out"
cp ${ubootRaspberryPi4_64bit}/u-boot.bin "$out"/
cp ${ubootRaspberryPi4_64bit}/*.dtb "$out"/
# NB: raspberrypifw dtb's are meant for the kernel, not for u-boot
# cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dtb "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.bin "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dat "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.img "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.elf "$out"/
cp -R ${raspberrypifw}/share/raspberrypi/boot/overlays "$out"/
cp ${raspberrypi-armstubs}/* "$out"/
cp ${src} "$out"/config.txt
'';
meta = {
description = "unmanaged files to place in /boot on a raspberry pi system";
platforms = [ "aarch64-linux" ];
};
}

View File

@@ -1,37 +0,0 @@
{ stdenv, pkgs }:
stdenv.mkDerivation rec {
pname = "bootpart-uefi-x86_64";
version = "1";
buildInputs = [ pkgs.syslinux ];
dontUnpack = true;
installPhase = with pkgs; ''
# populate the EFI directory with syslinux, and configure it to read that extlinux.conf file managed by nixos
mkdir -p "$out/EFI/syslinux" "$out/EFI/BOOT" "$out/syslinux"
cp -R "${syslinux}/share/syslinux/efi64"/* "$out/EFI/syslinux"
echo "DEFAULT trampoline" > "$out/EFI/syslinux/syslinux.cfg"
echo "LABEL trampoline" >> "$out/EFI/syslinux/syslinux.cfg"
echo " SAY trampoline into generic extlinux.conf" >> "$out/EFI/syslinux/syslinux.cfg"
echo " CONFIG ../../syslinux/syslinux.cfg ../../syslinux" >> "$out/EFI/syslinux/syslinux.cfg"
# we create this "trampoline" layer so that we can setup the UI directive
# and enable a menu before loading the real, nixos-managed extlinux.conf
cp "${syslinux}/share/syslinux/efi64/menu.c32" "$out/syslinux/menu.c32"
echo "UI menu.c32" > "$out/syslinux/syslinux.cfg"
echo "INCLUDE ../extlinux/extlinux.conf" >> "$out/syslinux/syslinux.cfg"
# create the EFI/BOOT/BOOTX64.EFI default entry
cp "$out/EFI/syslinux"/* "$out/EFI/BOOT"
mv "$out/EFI/BOOT/syslinux.efi" "$out/EFI/BOOT/BOOTX64.EFI"
'';
meta = {
description = "unmanaged files to place in /boot on a x86-64 extlinux system";
platforms = [ "x86_64-linux" ];
};
}

View File

@@ -1,13 +0,0 @@
diff --git a/browser/components/enterprisepolicies/schemas/policies-schema.json b/browser/components/enterprisepolicies/schemas/policies-schema.json
index d436cf1ca1..ecd6e53b9e 100644
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
@@ -1074,7 +1074,7 @@
},
"SearchEngines": {
- "enterprise_only": true,
+ "enterprise_only": false,
"type": "object",
"properties": {

View File

@@ -1,10 +0,0 @@
{ pkgs }:
(pkgs.firefox-unwrapped.overrideAttrs (upstream: {
# NB: firefox takes about 1hr to build on my 24-thread ryzen desktop
patches = (upstream.patches or []) ++ [
# see https://gitlab.com/librewolf-community/browser/source/-/blob/main/patches/sed-patches/allow-searchengines-non-esr.patch
./allow-searchengines-non-esr.patch
];
}))

View File

@@ -1,15 +1,16 @@
{ lib
, fetchFromGitHub
, flutter
, olm
, imagemagick
, makeDesktopItem
}:
flutter.mkFlutterApp rec {
pname = "kaiteki";
version = "unstable-2022-06-03";
version = "1.1";
# this hash seems unstable -- depends on other nixpkgs, perhaps?
vendorHash = "sha256-IC3FAPFASuMcNOpUuaB+MDcm9nqGCtq/6A2dCxIXHEg=";
vendorHash = "sha256-N7s63e8z4pAFtFV9cFN+CIIg+A/s8lYfiJWrBkMkkd0=";
src = fetchFromGitHub {
owner = "Kaiteki-Fedi";
@@ -18,23 +19,70 @@ flutter.mkFlutterApp rec {
hash = "sha256-ggDIbVwueS162m15TFaC6Tcg+0lpcVGi4x/O691sxR8";
};
desktopItems = [ (makeDesktopItem {
desktopItem = makeDesktopItem {
name = "Kaiteki";
exec = "kaiteki";
exec = "@out@/bin/kaiteki";
icon = "kaiteki";
desktopName = "Kaiteki";
genericName = "Micro-blogging client";
comment = meta.description;
categories = [ "Network" "InstantMessaging" "GTK" ];
}) ];
};
sourceRoot = "source/src/kaiteki";
# postUnpack = ''
# mv assets assets-toplevel
# mv src/kaiteki/* .
# '';
buildInputs = [
olm
];
nativeBuildInputs = [
imagemagick
];
# flutterExtraFetchCommands = ''
# M=$(echo $TMP/.pub-cache/hosted/pub.dartlang.org/matrix-*)
# sed -i $M/scripts/prepare.sh \
# -e "s|/usr/lib/x86_64-linux-gnu/libolm.so.3|/bin/sh|g" \
# -e "s|if which flutter >/dev/null; then|exit; if which flutter >/dev/null; then|g"
# pushd $M
# bash scripts/prepare.sh
# popd
# '';
# replace olm dummy path
# postConfigure = ''
# M=$(echo $depsFolder/.pub-cache/hosted/pub.dartlang.org/matrix-*)
# ln -sf ${olm}/lib/libolm.so.3 $M/ffi/olm/libolm.so
# '';
# postInstall = ''
# FAV=$out/app/data/flutter_assets/assets/favicon.png
# ICO=$out/share/icons
# install -D $FAV $ICO/fluffychat.png
# mkdir $out/share/applications
# cp $desktopItem/share/applications/*.desktop $out/share/applications
# for s in 24 32 42 64 128 256 512; do
# D=$ICO/hicolor/''${s}x''${s}/apps
# mkdir -p $D
# convert $FAV -resize ''${s}x''${s} $D/fluffychat.png
# done
# substituteInPlace $out/share/applications/*.desktop \
# --subst-var out
# '';
meta = with lib; {
description = "The comfy Fediverse client";
homepage = "https://craftplacer.moe/projects/kaiteki/";
license = licenses.agpl3Plus;
# maintainers = with maintainers; [ colinsane ];
# maintainers = with maintainers; [ uninsane ];
platforms = platforms.linux;
};
}

View File

@@ -1,32 +0,0 @@
(next: prev: rec {
#### my own, non-upstreamable packages:
sane-scripts = prev.callPackage ./sane-scripts { };
tow-boot-pinephone = prev.callPackage ./tow-boot-pinephone { };
tow-boot-rpi4 = prev.callPackage ./tow-boot-rpi4 { };
bootpart-uefi-x86_64 = prev.callPackage ./bootpart-uefi-x86_64 { pkgs = prev; };
bootpart-tow-boot-rpi-aarch64 = prev.callPackage ./bootpart-tow-boot-rpi-aarch64 {
# not sure why i can't just do pkgs = next here
pkgs = prev // { inherit tow-boot-rpi4; };
};
bootpart-u-boot-rpi-aarch64 = prev.callPackage ./bootpart-u-boot-rpi-aarch64 {
# not sure why i can't just do pkgs = next here
pkgs = prev // { inherit ubootRaspberryPi4_64bit; };
};
#### customized packages
# nixos-unstable pleroma is too far out-of-date for our db
pleroma = prev.callPackage ./pleroma { };
# jackett doesn't allow customization of the bind address: this will probably always be here.
jackett = prev.callPackage ./jackett { pkgs = prev; };
# mozilla keeps nerfing itself and removing configuration options
firefox-unwrapped = prev.callPackage ./firefox-unwrapped { pkgs = prev; };
# fix abrupt HDD poweroffs as during reboot. patching systemd requires rebuilding nearly every package.
# systemd = import ./pkgs/systemd { pkgs = prev; };
# patch rpi uboot with something that fixes USB HDD boot
ubootRaspberryPi4_64bit = prev.callPackage ./ubootRaspberryPi4_64bit { pkgs = prev; };
#### TEMPORARY: PACKAGES WAITING TO BE UPSTREAMED
kaiteki = prev.callPackage ./kaiteki { };
})

View File

@@ -1,24 +0,0 @@
{ lib
, pkgs
, stdenv
}:
stdenv.mkDerivation {
name = "sane-scripts";
src = ./src;
# See: https://nixos.org/nixpkgs/manual/#ssec-stdenv-dependencies
buildInputs = [ pkgs.rsync ];
installPhase = ''
mkdir -p "$out"
cp -R * "$out"/
'';
meta = {
description = "collection of scripts associated with uninsane systems";
homepage = "https://git.uninsane.org";
platforms = lib.platforms.all;
};
}

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env bash
set -ex
mnt=/mnt/servo-media-wan
# if lan not mounted, then try to mount it
if ! (test -d /mnt/servo-media-lan/Music)
then
sudo mount /mnt/servo-media-lan && mnt=/mnt/servo-media-lan
fi
# if the needed mount isn't mounted, mount it
if ! (test -d $mnt/Music)
then
sudo mount $mnt
fi
# symlink the fastest mount point into place
sudo ln -sf $mnt /mnt/servo-media

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env bash
set -ex
# script to reclaim some hard drive space
sudo nix-collect-garbage
# identify duplicate files in the nix store
rmlint --types="duplicates" --config=sh:handler=clone --output=sh:/tmp/rmlint.sh --progress /nix/store
# link the dupes together (uses ioctl_fideduperange)
# see: https://btrfs.wiki.kernel.org/index.php/Deduplication
# see: https://rmlint.readthedocs.io/en/latest/tutorial.html
sudo mount -o remount,rw /nix/store
/tmp/rmlint.sh -d || true # on failure, we still want to remount ro
# XXX this doesn't work: 'mount point is busy.'
sudo mount -o remount,ro /nix/store
# TODO: instead of using rmlint, could use dduper: https://github.com/Lakshmipathi/dduper
# better perf for btrfs (checksum tests)
# likely also better compression, on account of being block-based instead of whole-file based.
# however, not clearly actively maintained; uses custom btrfs-progs patch; riskier
# might not currently build on nix: https://github.com/NixOS/nixpkgs/issues/175730

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env bash
# use: `sane-dump-secret /path/to/accounts/website.yaml`
# dumps relevant information about the account, include a OTP code if present
secrets=$(sops -d --output-type dotenv $1)
function get_value() {
echo "$secrets" | grep "^$1=" | cut -d '=' -f 2-
}
echo username: $(get_value username)
echo password: $(get_value password)
totp=$(get_value totp-b32)
[[ -z "$totp" ]] || echo totp: $(oathtool -b --totp $totp)

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env bash
# unlocks the SOPS store (i.e. populate a SOPS key from the user's SSH key)
set -ex
mkdir -p ~/.config/sops/age
# unlock the SSH key
cp ~/.ssh/id_ed25519 ~/.config/sops/age/id_ed25519
ssh-keygen -p -N "" -f ~/.config/sops/age/id_ed25519
# convert ssh -> age
ssh-to-age -private-key -i ~/.config/sops/age/id_ed25519 > ~/.config/sops/age/keys.txt
chmod 600 ~/.config/sops/age/keys.txt
# remove the unlocked SSH key
rm ~/.config/sops/age/id_ed25519
# present the pubkey for convenience (e.g. if this sops key is new)
echo pubkey: $(cat ~/.ssh/id_ed25519.pub | ssh-to-age)

View File

@@ -1,7 +0,0 @@
#!/usr/bin/env bash
# after modifying .sops.yaml, run this to re-encode all secrets to the new keys
# pass the base directory (under which *everything* is a secret) as argument
for i in $(find "$1" -print)
do
yes | sops updatekeys "$i"
done

View File

@@ -1,7 +0,0 @@
#!/usr/bin/env bash
sudo systemctl stop pleroma gitea matrix-synapse jellyfin dovecot2 opendkim transmission jackett postfix nginx
sudo systemctl stop postgresql
sudo systemctl stop matrix-appservice-irc
sudo systemctl stop duplicity.timer
sudo systemctl stop duplicity
sudo systemctl stop wg0veth wireguard-wg0

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env zsh
# this really does need zsh because bash `test -e` behaves differently
set -ex
# make sure the mountpoint exists
if ! (test -e /mnt/iphone)
then
sudo mkdir /mnt/iphone
sudo chown colin:users /mnt/iphone
fi
# make sure the device is mounted
if ! (test -d /mnt/iphone/DCIM)
then
umount /mnt/iphone || true
ifuse /mnt/iphone
fi
rsync -arv /mnt/iphone/DCIM/ /home/colin/Pictures/iphone/

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -ex
sane-mount-servo
rsync -arv --delete --progress $mnt/Music/ ~/Music/

View File

@@ -1,2 +0,0 @@
#!/usr/bin/env bash
echo success

View File

@@ -1,4 +0,0 @@
#!/usr/bin/env bash
echo vpn: $(curl https://ipinfo.io/ip)
sudo systemctl stop wg-quick-ovpnd
echo plain: $(curl https://ipinfo.io/ip)

View File

@@ -1,4 +0,0 @@
#!/usr/bin/env bash
echo plain: $(curl https://ipinfo.io/ip)
sudo systemctl start wg-quick-ovpnd
echo vpn: $(curl https://ipinfo.io/ip)

View File

@@ -1,30 +0,0 @@
{ lib, stdenv, fetchurl }:
stdenv.mkDerivation rec {
pname = "tow-boot-pinephone";
version = "2021.10-004";
src = fetchurl {
url = "https://github.com/Tow-Boot/Tow-Boot/releases/download/release-2021.10-004/pine64-pinephoneA64-2021.10-004.tar.xz";
sha256 = "sha256-UZSzzzTp8PQ/wuLUA3RJyTa/vbQ0HdhfagJ8574leoA=";
};
unpackPhase = ''
mkdir -p src
tar -xf ${src} -C src
'';
installPhase = ''
mkdir -p "$out"
cp -R src/pine64-pinephoneA64-2021.10-004/*.img "$out"/
cp -R src/pine64-pinephoneA64-2021.10-004/binaries/* "$out"/
'';
meta = with lib; {
description = "An opinionated distribution of U-Boot";
homepage = "https://tow-boot.org/";
platforms = [ "aarch64-linux" ];
};
}

View File

@@ -1,30 +0,0 @@
{ lib, stdenv, fetchurl }:
stdenv.mkDerivation rec {
pname = "tow-boot-rpi4";
version = "2021.10-004";
src = fetchurl {
url = "https://github.com/Tow-Boot/Tow-Boot/releases/download/release-2021.10-004/raspberryPi-aarch64-2021.10-004.tar.xz";
sha256 = "sha256-dO8dFRF8BpJbmWYHAdeLEHZFwcaYcsqgUnA3gLYb2po=";
};
unpackPhase = ''
mkdir -p src
tar -xf ${src} -C src
'';
installPhase = ''
mkdir -p "$out"
cp -R src/raspberryPi-aarch64-2021.10-004/*.img "$out"/
cp -R src/raspberryPi-aarch64-2021.10-004/binaries/* "$out"/
'';
meta = with lib; {
description = "An opinionated distribution of U-Boot";
homepage = "https://tow-boot.org/";
platforms = [ "aarch64-linux" ];
};
}

View File

@@ -0,0 +1,16 @@
diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig
index eae03bf023..2ded4123ce 100644
--- a/configs/rpi_4_defconfig
+++ b/configs/rpi_4_defconfig
@@ -63,3 +63,11 @@ CONFIG_VIDEO_BCM2835=y
CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_PHYS_TO_BUS=y
CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_CMD_CONFIG=y
+CONFIG_CMD_EFIDEBUG=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_LOG=y
+CONFIG_CMD_READ=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_LOG_MAX_LEVEL=7
+CONFIG_CMD_LSBLK=y

View File

@@ -1,39 +1,12 @@
{ pkgs, fetchurl }:
{ pkgs }:
(pkgs.buildUBoot {
# nixos-22.05 is on 2022.01 at time of writing, which lacks rpi-4 dtb.
# TODO: remove this version/src override once upstream bumps u-boot version.
version = "2022.04";
src = fetchurl {
url = "ftp://ftp.denx.de/pub/u-boot/u-boot-2022.04.tar.bz2";
hash = "sha256-aOBlQTkmd44nbsOr0ouzL6gquqSmiY1XDB9I+9sIvNA=";
};
defconfig = "rpi_4_defconfig";
extraMeta.platforms = [ "aarch64-linux" ];
extraConfig = ''
# TODO: this can be removed in 2022.04
CONFIG_DEFAULT_DEVICE_TREE="bcm2711-rpi-4-b"
# enable some builtin commands to aid in debugging, while we're here
CONFIG_CMD_CONFIG=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_GPT=y
CONFIG_CMD_LOG=y
CONFIG_CMD_READ=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_LOG_MAX_LEVEL=7
CONFIG_CMD_LSBLK=y
'';
extraMakeFlags = [
"u-boot.dtb"
"u-boot.bin"
];
filesToInstall = [ "u-boot.bin" "u-boot.dtb" ];
postInstall = ''
mv $out/u-boot.dtb $out/bcm2711-rpi-4-b.dtb
'';
extraPatches = [
(pkgs.ubootRaspberryPi4_64bit.overrideAttrs (upstream: {
patches = (upstream.patches or []) ++ [
# enable booting from > 2 TiB drives
./01-skip-lba-check.patch
# enable some builtin commands to aid in debugging, while we're here
./02-extra-cmds.patch
# ./03-verbose-log.patch
];
})
}))

View File

@@ -0,0 +1,91 @@
{ lib, stdenv, fetchurl, autoPatchelfHook, makeDesktopItem, makeWrapper, electron
, nodePackages, alsa-lib, gtk3, libdbusmenu, libxshmfence, mesa, nss }:
let
desktopItem = makeDesktopItem {
desktopName = "Whalebird";
genericName = "An Electron based Mastodon client for Windows, Mac and Linux";
categories = [ "Network" ];
exec = "opt/Whalebird/whalebird";
icon = "whalebird";
name = "whalebird";
};
in
stdenv.mkDerivation rec {
pname = "whalebird";
version = "4.6.0";
src = let
downloads = "https://github.com/h3poteto/whalebird-desktop/releases/download/${version}";
in
{
x86_64-linux = fetchurl {
url = downloads + "/Whalebird-${version}-linux-x64.tar.bz2";
sha256 = "02f2f4b7184494926ef58523174acfa23738d5f27b4956d094836a485047c2f8";
};
aarch64-linux = fetchurl {
url = downloads + "/Whalebird-${version}-linux-arm64.tar.bz2";
sha256 = "de0cdf7cbd6f0305100a2440e2559ddce0a5e4ad73a341874d6774e23dc76974";
};
}.${stdenv.system};
nativeBuildInputs = [
autoPatchelfHook
makeWrapper
nodePackages.asar
];
buildInputs = [ alsa-lib gtk3 libdbusmenu libxshmfence mesa nss ];
dontConfigure = true;
unpackPhase = ''
mkdir -p ./opt
tar -xf ${src} -C ./opt
# remove the version/target suffix from the untar'd directory
mv ./opt/Whalebird-* ./opt/Whalebird
'';
buildPhase = ''
runHook preBuild
# Necessary steps to find the tray icon
asar extract opt/Whalebird/resources/app.asar "$TMP/work"
substituteInPlace $TMP/work/dist/electron/main.js \
--replace "jo,\"tray_icon.png\"" "\"$out/opt/Whalebird/resources/build/icons/tray_icon.png\""
asar pack --unpack='{*.node,*.ftz,rect-overlay}' "$TMP/work" opt/Whalebird/resources/app.asar
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir $out
mv opt $out
# install icons
for icon in $out/opt/Whalebird/resources/build/icons/*.png; do
mkdir -p "$out/share/icons/hicolor/$(basename $icon .png)/apps"
ln -s "$icon" "$out/share/icons/hicolor/$(basename $icon .png)/apps/whalebird.png"
done
# install desktop item
mkdir -p "$out/share"
ln -s "${desktopItem}/share/applications" "$out/share/applications"
makeWrapper ${electron}/bin/electron $out/bin/whalebird \
--add-flags $out/opt/Whalebird/resources/app.asar \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"
runHook postInstall
'';
meta = with lib; {
description = "Electron based Mastodon, Pleroma and Misskey client for Windows, Mac and Linux";
homepage = "https://whalebird.social";
license = licenses.mit;
maintainers = with maintainers; [ wolfangaukang ];
platforms = [ "x86_64-linux" "aarch64-linux" ];
};
}

View File

@@ -1,9 +1,11 @@
to deploy:
after checking out, drop secrets into secrets/
to build:
```sh
nixos-rebuild --flake "./#servo" {build,switch}
nixos-rebuild --flake "/etc/nixos/#uninsane" {build,switch}
```
more options (like building packages defined in this repo):
query with:
```sh
nix flake show
```
@@ -11,16 +13,38 @@ nix flake show
# secrets
i use [sops](https://github.com/Mic92/sops-nix) for secrets.
see `modules/universal/secrets.nix` for some tips.
`secrets/default.nix` declares the secrets exposed at evaluation time.
these are defined *outside* git by writing the actual values to `secrets/local.nix`.
*don't* check in the local.nix file. use `git update-index --assume-unchanged secrets/local.nix` to prevent it from ever being added.
but after that you can set them to their real value and run `git update-index --assume-unchanged secrets/*`
## building images
to build a distributable image (GPT-formatted image with rootfs and /boot partition):
```sh
nix build ./#imgs.lappy
nix build .#imgs.lappy
```
this can then be `dd`'d onto a disk and directly booted from a EFI system.
there's some post-processing to do before running a rebuild on the deployed system (deploying ssh keys, optionally changing fs UUIDs, etc).
refer to flake.nix for more details.
there's some post-processing to do before running a rebuild on the deployed system (e.g. change fstab UUIDs)
refer to flake.nix for more details
# admin tips
online: <https://nixos.wiki/wiki/Cheatsheet>
verify ALL nix store contents with:
```sh
sudo nix-store --verify --check-contents # add the --repair flag to auto-repair as well
```
search for a package with:
```sh
nix search nixpkgs <query string>
```
find which package owns some file with:
```sh
nix-locate /bin/vim # or any other package-relative path
```

35
secrets/default.nix Normal file
View File

@@ -0,0 +1,35 @@
{
ddns-he.password = "<REPLACEME>";
# format: b2://$key_id:$app_key@$bucket
# create key with: b2 create-key --bucket uninsane-host-duplicity uninsane-host-duplicity-safe listBuckets,listFiles,readBuckets,readFiles,writeFiles
# ^ run this until you get a key with no forward slashes :upside_down:
# web-created keys are allowed to delete files, which you probably don't want for an incremental backup program
duplicity.url = "b2://<REPLACEME:KEY_ID>:<REPLACEME:APPKEY>:<REPLACEME:BUCKET>";
# remote backups will be encrypted using this (gpg) passphrase
duplicity.passphrase = "<REPLACEME>";
# to generate:
# wg genkey > wg0.private
# wg pubkey < wg0.private > wg0.public
wireguard.privateKey = "<REPLACEME>";
# these would otherwise be found in 'pleroma.secret.exs'
pleroma.secret_key_base = "<REPLACEME>";
pleroma.signing_salt = "<REPLACEME>";
pleroma.db_password = "<REPLACEME>";
pleroma.vapid_public_key = "<REPLACEME>";
pleroma.vapid_private_key = "<REPLACEME>";
pleroma.joken_default_signer = "<REPLACEME>";
# keep this synchronized with the dovecot auth
matrix-synapse.smtp_pass = "<REPLACEME>";
# passwd file looks like /etc/passwd.
# use nix run nixpkgs.apacheHttpd -c htpasswd -nbB "" "my passwd" to generate the password
dovecot.hashedPasswd.colin = "<REPLACEME>";
dovecot.hashedPasswd.matrix-synapse = "<REPLACEME>";
# generate with nix-store --generate-binary-cache-key nixcache.uninsane.org cache-priv-key.pem cache-pub-key.pem
nix-serve.cache-priv-key = "<REPLACEME>";
} // import ./local.nix

View File

@@ -1,39 +0,0 @@
duplicity_passphrase: ENC[AES256_GCM,data:rzUfcxe5YPloOrqgVwdCjsccexWc5RvmFf1i3Xs459iVTfWHlVJeT/IqReY6ZqdAkPJteTtrUZzak2GXyRUkE13+W0kE8isnDjPX/YDQwoK2sa+dwc4xGTekboc0gf6HH3vQpF1aiJDBfb3GtGyDVLH9MVIRPJGXSztZBduUDezA2wAx2wI=,iv:EHJg8kE/07v+ySSFDtW4FA4y1y/+fcGxfNCWoainwBI=,tag:S3ecM4DbDl8jqXLRKipZmQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlWnpQbnFFMWtLODFlbU1M
OGswTzhKRCtDZ0lVVTZWK3hmcnh4SlRRSjJvCjkvYmFTbzBQczl2dXpQdGYvWXFJ
MDllOUlkd1hUTDR3SS9KV0N3VDF5VWMKLS0tIFRQQ1hrMStmK0xqejUra1Q1NHBp
a29tdklGaUd2MHAwNDQxQVZsN1VYcVEKtFynEmTqzFnomLB06VfALag0h9ECvMpv
dWr6x2419QlXOMSkLHYLiIPydh7xJUAV0tMWoIEcpKfmsMKDXFYnJQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1Sm45cGp1akl3elBmUEtU
UUhHOVB1U2VHaTZFdGxSMUNINlc1YzN4RzNVCmtDYnE2NWhHVmU2a0YzMGxybWNQ
VDZ0cm9wcXlsV2FZQzBLK2dkc1JiblEKLS0tIFpDUWFTRkZSNXJoR1dZYlVERnJj
YlVrNE9aVHF0RFZ3WDB3VVMwdEt5ZUUK1d2GIJkS+8vSConO3nN+YCvTmc+B/bNF
+A5N4EmivJarrat4WUUzzfvlyCNcb72chvQSvVYK+IyfCCwVjiYhgA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzTWd1YTVVbm9xbUg2QVZH
QXZseXBIdVJISDd2b01VUG5acVRNNjA4RTMwCklWTVhqbVNPcnZHMGhIQk9EU2xP
aFhIbENNamRjbW56UkdmdjVmdndJSlUKLS0tIHI1Q05zV2ZZd1dZK2lVTTBLU3Jr
Si9kT0ZMUnJJWlhUZ3FFakZFaDlPdEEKXtWfh6wdGPin1h/UUs21cdspddpW1YDq
rCKS2DI2KWdgciih9FnmWGAwGUhB3uhimUr6hgho4z+dZfLrpoP1PA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-06-10T08:41:13Z"
mac: ENC[AES256_GCM,data:51N4a+P+eXVAdPFAI3h4TFKsR6IOGBnyusW4k7ZrMOleH1l4C3khYaUmCoE1nnLlmD2q+kmtdGdU6FWyB7BYiSytjqvQa0WumEhf5PpOtj5k+55c1sljvtK58BxQd7N5Th+R4VmlqZ7LXviwzIb8OkoiCf0yC+jxZRi/2MQiKC4=,iv:Jjrrnp7isbmEP9vAYZ+lVRit2RNbrq2unXzuZD8C/2Q=,tag:HvKUFKdhE3O75o8hX+hIsA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

3
secrets/local.nix Normal file
View File

@@ -0,0 +1,3 @@
{
# populate secrets on a per-machine basis below (and don't push changes to this file to git)
}

View File

@@ -1,53 +0,0 @@
duplicity_passphrase: ENC[AES256_GCM,data:WAQE+xhfRg+4N9Q1P9U8Lt7sVwpcEZFPJzyHIA+FIcCcZZhv+QmvCT/eTRtAOIFvII5l9f0A4GRnSEagalyaZgTgq7t8qOhvvB+s8cIj7prM1psnKstpx3+BxsinGOsZcPqbBxph9gdGuIVP3qH7pYAT+6GMPLnxW21s0r26mZFZM8Mu15VGyuvTz2Pknw==,iv:hu+6w6TWQensA4y5wBz1vPgw8YlBk5TuxEm2rRjV6Ao=,tag:UJ2joJZNxr/+O5y0dx6q9g==,type:str]
ddns_he: ENC[AES256_GCM,data:zAKbEAIMIsENUctG9bNAAjAty6g+w3QW5VM=,iv:ncIjblXnTiU3TQcHJutz9lCl0wBdWs+FybY0sZcnaH0=,tag:7O6EIob2/if1fcVDVEkVzQ==,type:str]
#ENC[AES256_GCM,data:LMfqz2Rih6CR7RcCbA==,iv:MQ7z93Mhus2Z2q7HZMk4BzkkY/apBIR+9hIiZlknolc=,tag:HU5McecdYk12I3AcvVHEBw==,type:comment]
#ENC[AES256_GCM,data:zhL2iNWZ8xPbBneffWcc93ZCW/SDv5FH,iv:P3a8+oucJRM8o7hnHUxAvefHdZEAbKJKhK2Y1+r75GA=,tag:VFvFucE5c780RmspW7p8Qg==,type:comment]
#ENC[AES256_GCM,data:N0wn6NUjQKXFbSULhrKzqDc4bHVbM3JLWJwOu5Zoi00gCKSiMA==,iv:9NhoT+OM+bjz4DwRRm2c4rTBZ3Jr6eMOY7F1l4WeE1k=,tag:inkd6kw8HvT5Tz3UAbIklw==,type:comment]
wg_ovpns_privkey: ENC[AES256_GCM,data:+SdnhsPyg6Vbl0itNLq4fBPONLBknkjFCr/4shTr2HjeGdaD7LxPud1VvfM=,iv:Rf647IlLImPu7l2CHqetjs0y6QkWdqXUO70OKfcII00=,tag:ykvKJ9BeTDbQqR7K5S6Rfw==,type:str]
#ENC[AES256_GCM,data:857w7AqbAbVTOKFLxKcMkcQjJ7EkHZFwBRwtCJFspOk8do2f,iv:bIrXzdrhRYk79ZV+JCdIw4UVxq11/tTZUDL6Bwf+NoE=,tag:igMRz5UPX//JrF9NGCOwHQ==,type:comment]
#ENC[AES256_GCM,data:KzCOrdCiXHrVx+oGj2mz/+zkZ8eRRnFhHadx6FlXj8OXQDMvDkSPi6G2f6j5FE//G2F321mZCiMJ1Mf32tItGb0SxoEhyO9wxTesNn45hmA7M0z5HqTxACU=,iv:ksdz8j2fq1W/xnzu0y1JaIgbKzjiqj2KHCEYhkEKsrM=,tag:dbH/vy4JgL1eUeNpv7afSQ==,type:comment]
dovecot_passwd: ENC[AES256_GCM,data:GsXT6PQjCibzyr5G4W3IOIRL4xBuYqFYHpRJOjS2TvXIlTSwVrHbx5Vw5wLHI0zN14rvYy5sycJvEMiCC1YPVphAYNm7VHdo97sUGLpjZ1BpUaJ2KBx77jErxbPrJUSpAroojQFtXFYA2t2bTpOSjZGH7UeyZoLckZtdDqXmnBDvirwVDPNaPv04RrhnqehGyh8EN+b2b5KAm99U9H1oyxIL6mAMJo6FtduVejiVqJB2sl/myI5fJ+bvwkW1CLRmVi0JdVHs4BlTQpi5Q8Kx2SMOH02TP+QDSHv/O8ROpbZ8m0oTk2YbgAG7U8K0t55j8jjWX/7OD4nMv485PgzAMINdzI46g9l9afzo,iv:8MqpUkRPpGJiuWtrdTJAIDXrKZMI73LcwzOiqVMWR88=,tag:+zXmEPV90loAMJtL/+v3vA==,type:str]
#ENC[AES256_GCM,data:1zQ8X9W4ZGquYEjEsN8YNLhwBt6kaRCKYMjM8GiZbKzsaqwt/cFk+4cC85+QKWF0FNlX38Uba7bI2FvC8fTIO8eoZ5VymJ9Du3NcExE1976FSIze44FhtkSKQkm/vQw5cb2sPNKBGFLSNV/IpdPu,iv:xwv2+Fns0k2STkS760v9p1XZ5s2HAz3wLb8xyIOGTGA=,tag:OGtHxQgyWxGKtg5I9nJAag==,type:comment]
nix_serve_privkey: ENC[AES256_GCM,data:JlLuslwyjKARo3Mo36SeRz6ctVuV+jzDMXACekaGs/UjP+Jm8PoxZsWjMcN+qq0tJB9xGMfi7TKHDi+XnK2k60h+7+yDyeqJQfjID6axMYmgxYUivq4CugutFVB27FmDPljUs2M7CRqe1IHrdjc=,iv:1iQVr9rP80hHCRSVD95KW7bpOWj3oZReJAvqa9TllJ8=,tag:6DDGtHF4suOyy2kcnqSDsQ==,type:str]
#ENC[AES256_GCM,data:cyptbs4VfXY4P4+W5e2LRZOHkpqvWzn2JEpV80w8cIaQ0lTZa/Hg7IwDNQcsYobmBFO2yLrKawHDKlDos2fMy0KgIhUrw4f8WksxdC06oMqS0mDtgA==,iv:StB34bvA8GWR+7nwOOpsiJ3yqGgeSg5frAgRMhff8nw=,tag:b1LYFzII2Ik1nmGXxgMZuw==,type:comment]
pleroma_secrets: ENC[AES256_GCM,data:TSbNUptz/1vybQAl1cBh6h75JR/yYue/zkAOoCrevQtZLuwOioTNGCesSeD/Y2O387N0BD+reVovdmfDA8WqvUnUZ4KpIjXRe+fxAxw4s14/BNChaSohCtADN0919JrvxjiKACizvgMNKmcP7PXsaoXMLmY1jh1VjK/3xL5+OMa1sHH58fndwgVF7f4XO+7VRRgYfUdyDobLPyE5ESKCYLWA2dUIuGPMo7zYQPVe++mgJ3S44Spx1AmJ+XNOf8z+GhQB3Fcc1yITv+drUHeBGC4Y6vVH1gEQA2K1kqSTEaNcPFhKBnN1ITzee24ULozNotdNPDWvv71K/ZdgZ8qx3hRECUGTgTSpqE5IlCk7kDYyyLcH28+yUurto6sNo4k28tiGh64QM5r4mQepfkFpDs2aNXE+EwF4/+wxlzZj69flIAtkN7i5YTj9tKBf93rs5zNuRpNnNCclcD1XukbUp4mMt4t74TdYH3uN35j/bIApEGliiU8TTBxxLXFLsCSxXJPUhNGdIPwuYivp4m9joezID/U/LBT+0qOB4+tuPk+C2Z2vp4i2a8G+VvBFqCKQWpflZS9hO4flyfOTJ3zquuWozbsqFugLjeqj+/4c0BYOL5gWnvitbqTQJtmzf/XncNL9UjmztbQg+IzCx90xb6OHX77G+beiiyz+ASglXkiN++17Wi5+0PJQFSLgY4JKbQ5Au7X5KzRAHFrB5NpekhaoIno1QULcrl8QJ0jiB3NLW5uE9MPLZDv8kwK01mcR5iaUv/sYP3OXDui4uQ==,iv:FmAx/D4u7XBysO53kbpl9ASnGwTD0w9wSi+9hqQOKl8=,tag:5pngKmp07l2KCjMXUgZqhw==,type:str]
#ENC[AES256_GCM,data:RdKGF5jpu91pgr8dkekaBED+3vlA8C/ccWSeS8fNFXZ0JcWaeDq+za6JO2X13+7QHIMQ0doOFJmvVmAlrV7pM6tenCqXxyvYmNL1dfHS/x7s8XJFCzDzubzFbWc=,iv:SisRMWRBHOkBIvdNmbdpaWLQ6Nt3JuPpddGdg+ufwSs=,tag:r+7lgrucNMIc07sG7RVE7Q==,type:comment]
matrix_synapse_secrets: ENC[AES256_GCM,data:fJsbTw9INakO0x4/x6O11dsrwSYcM5x1zWXuqZSWPsH739klYN7fi1Rx5P3yLoZu2NFXwyQRQDMMxiNzrdb91xhVFope+8ZCsd89a3UoDeUk5BOF1HDrIrqhUVUK45mdlULm/afjE4hx3YgnLPJIvS5pCJ3Xr5xfdSaIQeZM5MBQxGMaRwGaUkALNoNa/TSH2a4toUYQvDAsOKFmyoV6O8oc+qatVB02x7OrIkVDqfQEE5AEGpydx1fUJ4+LNXiXIVz3xvxKzJ7IMsSB9GF3FUwPgq2PsjFbtQVnv00/4epwho3fX8ZL+EfFefQ6JLJFhNxmd05RNiaBbEmv6P7FICcngSUKwXuLcLAlKW8di3aI/NbW2JYY+g4gwsax4UDeeElXK+IOqC7709aIN9FuWcM+KDTObTs+1qwBbR6M8/RTdEYEhW6Cw2Ij24kn1Xa/xEtlQJcWfCLoeExMzRRMWG4yZRXnb9nXnx/TqDRoMjy3X6FFSwd6cLDKNPyQEOt1MmGwmWlGRexikzxByJvhthtiOMasYOZT0lxD4rhIfNfwA+UNcBkbsmPMPuqWg7Q9x5Rpm47m2MJgnV4O,iv:fPLfxImLW610TXrhr8tPm91M44PzgEj3uRw54bI4BUQ=,tag:3TttyGEX/7OtRAUSfXZ54g==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyTWJwNXplSnJQTzUxVjBt
TzZ2aUZ4RUkyejVUQnpOdnpKajcxa0l3WWlrCmkwZVJuenhpN0R2OUxFV1pXUkVa
dk8ydnlnU1JvOElvNVovVlBjKzZVYlkKLS0tIHlVbkRRYllJR2J5UWhKeGg5SWJj
VExDaHc3amdTcWdUU3ZRUDNGREtxelEKXHuDfNM3uc3UBiPCAveG/u5b7C8zPzTi
GGCx0R+6swS9yVSAJ//nUvu1zFuFfGgm3mKaSqfqWKfDSMFvAp0Pyg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDY3NCbCtjY2ZHNkE2dWxN
Vk5nQ0Z2M1pQOXUzMVYyS3MxT252T1lhKzFJCm5NZ25DSlpZbnhTV0JMbVBvbm9j
SEtzdDJWS3gxby8rVlpzZ20yY3hRK2MKLS0tIGVqNUFZeGYxRnVSd3E1eitNUGFW
dEszSTFicTZRUzZxbFF5YWF1RmtwSkkKPle5Xw5gyd5YCPIAABaABNdgbpialJTV
hUOVdYCsmqd+spCA0Q9f0D3S5ud59iFq8moBh97BZQuLcc2qUeyJ2g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4UGdCMjRpRUFMdXJRQVgx
aklIY1dkOXRXNmliVjIyNHlUN1B1ZmZZbTB3CnFxQjZLbWkwWHRTN2lycEx4K3RL
UGdFVktETXJCSXhKSWFsbnNyU25tRzgKLS0tIDVsdmdxRDFnQU9XeHpibm00bm1C
U0ZlOUljcE9BL1lhcmIrVVl6eFdTUmMKBHmv96FmkL/oQw9//ATfem6HtORRjcce
xJNwnsdrEqrBS3sG6xDkmJYOjaFrg1pwxYZRG87zeLShgkXkMNvz2A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-06-10T08:38:03Z"
mac: ENC[AES256_GCM,data:DroE9KGyV6hba0aPVYmwxpL8yXDa+AFsjyF5ttImW5bKzE9EM2I76APoGOyvOnnnbBRrOditWXA2HQzhf4M/7hq0CmLLph1J3I8xgEsaiJiExaKZQpQTBS/ZAHeygR/fvRcMmAY9VZRubv1iQ94rDkZ3C3UJ+8SMuwpdmdlaPYc=,iv:KkY0Kmd02QYx0Ds0LUY9tXz+AayKj6Y5p/rUO8sLYCc=,tag:gZDe+GOw2ULJ1yHONlt7bw==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -1,84 +0,0 @@
wg_ovpnd_privkey: ENC[AES256_GCM,data:qmyCOcD5TA7SKqSDCTZOTahkfYVZMJUGuyselmQbqj1uer3e4cBRSMuIiRI=,iv:jnHvGgVu/8HWT8MkI2wtGqlCs6wTu0C8huHpkdDmBYk=,tag:a0r0f/6LTBUuhvLGu+SFug==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmMUNtRnRkSXhlK0tOM0x2
Qlc4cFdFc3FvVERDWXF2ajkzZlhOcGlMclhvCndWL0FYY0plMFllcVJkeHh0UXpa
eGtYZ0VLK0ZRVHZhWFNqSmVTdnpScW8KLS0tIHZkOGIwSEVVQStrSmowM3JlSzdo
WElESWFBZ3U2UEFSdGVpSzZFcFJIZjQKXsem6B+/so57tcfM8itjmisnaMeWI39w
kL53mQMod2eu01XnDdMtLqNTTJM1dw6Sn0ggEUoTYXyUDvEkLjaTzA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSUXdGcC8vb3hiWm0rTFVF
cTR3QlRMZEhoV3FkYy83eDY3WldZQmJyMUNBCjJvTHpqL1loWUdrQUd6TDlUQmZU
MmhlUmE0WjUzK1ZaNzJzUE5DK3FVZlEKLS0tIHRFQ0RIWmovSVdWRWF1cEQxQXkx
TVBoZXhVV2IxVVNRNDY4S1cwNjZlU3cK783VjOQA2vOHDLMa9gfgKBv9rXr28XEA
+0uIeCZMkxpBWsRCt+enFKOHzuqYwYR/bpaaUH85okCTmrPRjPJmyQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1UGR4Zi9ydlEwS2I1TjFt
d2I1cURUemxZTGJ3VE9ZemMyT2RwbVliSWhFCk1XVXp3V1REMTlNWW45ZUg3c2N6
WDkrczZsb3ZGMW5XeW8zWHdtNnl4ajQKLS0tIE8zdm05RXNmWGJsZGVxRXl2bmI3
OEZxTTh0UE9QRXhwYTAyejZWNlFiVG8KYVwqMlwGkOaKh/6ISi+FOz9Tn5eeZR0t
XGU5OoYuJg7OEgxLYkuXxro0eGYrgAQQVIGPP4W8eOHeQDLiUnXoqg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1lt739n2tq7dmpglvntjr9j2r7426md7rat7x9w930gagtx4jyvnqwts2al
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2Zk4vYyswbzNFdDRyaUdS
ckt2eGd4ckhLS0tsOWluOEo3WnN0Y3pWekZNCitDYktFbm1Rd1RnWFZnNnYvbU1Y
ZTh2SFI3MGI1ZDBmTEt4cENHd3JNOEkKLS0tIHozY1dlZFpHam9ERHkzZFZtUndV
aHFFdDF0YXpxczZsQy9KcUx4bjZubzQKVn+jFIqSgUl6unVNdey7l358Sq5v0XyD
OIY2ICPC6Y/jQ6GttvA5eJveCUq5OGmZ3csFSXH6Vk5RUS/p9Qc3Jw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDNkhPKzU4Q0pmWUl0YUNP
WHowVGtHZUdHU0dnNTE5K25pRnh6NXZkLzA4CmV3MTdrNWlINmxaN0RwbDNsaXla
ZzJ0NUpRVVVpNnE4bE84eXp4UHM1aWsKLS0tIGxWVVdGSTdycGVXeTJhZEgwOTZs
cEU3dzZ5c2JLblg0QW5JN0owT0ZISmMK63ZpM6CfYAIo7syEnhOzbRaQ6mBx4D9f
RaGl7KhnSCSHPMWPzlKSrvk76nEUdZUWvgEwE4aGLrqL4hcpoW7fsg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCQllDVUh1NHJ6Slcrcjlo
WWVlTWxMa09TTysydmY5aVdRelEvYlBUWFhNCkNlbmNKUHZodHRsZVdXZGhkanEr
bzhyNEUzWk0xT0xsbHVtUDdEY2Z3V2sKLS0tIHE0dmZUNXQ1YjNIL1FXTDNxbW41
bWQrMzBXV3l3UVJWVVU2V2RQK3VwZUUKdJob/7tk8vPwIlfVU66fIW9ft2Y+7JCr
L9f+AFgy0XD8e+DfQlJGNDeEm5Yu6cW0vWlbJtrRWes4gIF52bq9YA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTOU5sL29KTVQ0VS92QzN2
K2liNmxMdGN4TDdaQWp0ZHlyWjBwQStXQjMwCmNuMUZJMmZncFlRVE9GUFlkV1NT
cHEvcUgyY2F4bG9ITks0OVZZVkFOUGMKLS0tIG5yeS85T0FqeGZrUEg1WlJnMUUz
d1poZjE0TkFqbVNFZDl0cm5sWmJmMzAK/S7ePeCRqeZLJvk49CoatP5J6la4yfEN
C81ivlh7SVDfyW8nJPLw+DIX4SU6e66zva/T+RQO3QnNJSDuw+gHAA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1t957gf0z865gya0khgc9x59wy76hzps3sgejjqtwcngn2xl273msxsmpe6
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXZ25CaGtiY0tDVnIyWkIz
QzFlQXhHMkhUMDlIemxzdUhrVTJtSzhkRTNvCmhDdUdqdml0VWd0TmluSGF5QStG
Rk1leW1ac09LMGZhaHpva2NMS2Z2a00KLS0tIFBwNTRwQm15UFNEdkJNTmh3eTJh
T1ZLaWRwWFJkNE82NC80QTdjZ1l1Zm8K7QhAMCO/65Z0N4coN+sc7WYNVI+BvV01
q5DXWTtePrPRQ8ZCqT7gWdSQc8iS410HEZ2Nya5IA+ktGxMO9h1EXA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-06-21T09:01:02Z"
mac: ENC[AES256_GCM,data:G6crbY/fKKHjiCI7m+uOIRHrW2CJFM6DPD598h/vqRwYI0laIkasr7vUMuV72RyqAW52F90kIYyLY5qhu4uTOBqHK5aJHAxNo55knHrpXYQemMMt5UGC3AwgswLWkqze43EhIj7NrA6LTFF4MX+rD3yhFC+IAQOgZ1HiIk9h0sY=,iv:kDDHyNlaCCq9AVSr5qaF1OYZxNAGgxSGL5bxYL3Q79w=,tag:5FNaXMHjTyjyPScOXgep6Q==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.3

View File

@@ -1,48 +0,0 @@
{
"data": "ENC[AES256_GCM,data:Uh/nvEjCjFKOjwAfmIbJ+PDvwLaPe2kIBES5XzAgxmjvWN2EGUu5f87E6hakmfRSYb8UWf5HlhlGsxj81eucLyzmyw3a3UNzE0UAFW6ozjNRDwDbqXyBj2hQoHKtixLJNzlDjhTdgQMRKZW7GVqly8EThLQDC7s2tDZ0snz+DTEH3JTSUKKAnHfjc+YC6Xp7hQ3g/hmhoIoQyteeYjbWnFAAY7UaIYXde17jvp2N8iNtLaaLM9NNrNHS3OD66L7KXW1otk1+LYNAVRiQOENVwqlF5UGBlFpp2P0Lrv7/EwJjZQxfFD08pOhb+8O5yal60K69+BpAQx4nnQOmpg6NSXeWyaJ0WzD8C6fZFCimWCAKUn2vKtUKjOHJp2bUop696gUkdodEtub9KK/Wa93J8BRp2tYKpNm46+/dv8fiRYJ6HohdoHUyhpJ+uwLFgwpIBcEXIXZGA4YMpo/pskZriuuYrXRWdIE3K2JxtGY3PDM2pufWa+7tp2o6hKAQod8dJKi5Wwe5yNIIV8g/x1gOJQCfPt4JAE8srE73QdLkrXPon3opbYyL4xHEtuA8W7gjpwqZP9A+3KzdsCt/,iv:wUMwP3pfmcuyd5smntbeDmS/c6RYFQl3dhnEIfFIMM8=,tag:k0V/XbERPrpgF9rhxhgMkA==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmQXFUV0NVb0I3UjF6d2lx\nQXlCZURBai9qSERxWlYyQ3k2VGNhVnhPWGxRCk01aVZPbE96NDZ3WVUyRkp1UzFm\ndWNGb1JPNFBWS2hzTEVnTzFsOFRPWFEKLS0tIHVVT2Q0bDkvcmZOYzZqQVZJclVO\nWEpHRS9jUFpuVHZrS2paWHNuRzN4ZzAKOioqqTsqyD4Wa+amWaRNgb/6ZspWDI1K\nKvrIZ8uqunnUjjjNSJJlM8dl1OfyJlrRWEi8QOkqD21FcBTQiljVgg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtT2gwSnJENUgrcUZQS21K\nL05BOW15ajJDVkhGajNzZE1pQTc5WVlwM3hVCjJMVFJDT1laOTlUNk9qM2ppMDZn\ndEdNOXBmMmw4Z1hMMFhIcjlsbFAzNFkKLS0tIFdIS0xzZm5vOGg0S0x5SzJXL1Bt\nWHcyeTVBRkdwS0FzTWU1eTJ6dGhiNkUK6YycEWUOh8M9iYF+2SSnU6cTcxtsFctD\nPcOfrTp+OBX18yXjRraWNLq2+jNj+IQtoRVFBUv2VsZAFFjz7d2oyQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoZGZBN1FSQno0bmcrdmJs\nZFBFb3RRUitZVGFDQkh6S05xSUxGS3l2Z1dFCmNSL3VxZjY1MFNnMlpZbW1MQmUx\nS0FCbnNCREZlSzJiTE1WUDN2U2RQS1UKLS0tICtjeHhzY01XSE4ydFJsLzYrZlND\nOUFURnA4WHhySVBnc0I1cUNwWVlETlkKmvoUt+hvm9QknH12NTEKvilnBUaN8uhx\nYhPEbZkOr1QC8Eakn+b4G8A//COsxzm6cQW10FAiEBOrUybQGopW0g==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1lt739n2tq7dmpglvntjr9j2r7426md7rat7x9w930gagtx4jyvnqwts2al",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsYm5qaVhqb2t6c2ZFUVBr\nYUlSb3FsS3FyTWhOL3prblBSK08zMmRmckdFCmxmK2NabGVmMWZiQnRUNHRDdUhK\nejlwbnZvbm1ndmIvdzIxR0k4U3M5TFkKLS0tIFYyRFhJQXhkdEN5TDN2d1M3Rytq\nc2tZNjQxVGNnUnFvayttbzBPN2dYRjgK2vKIWq3BMn2v+FgZ+F13703FPGMsEGsr\nHYtrnbDnd2fnPz4PTFUwvKldBTOtEymnRd5nfxqAAz9OdZBsahzRxA==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmZlBQR0txRVh2YUFmdjBJ\naG50NU5FVjY2S20rM3I4ZlVrOTVrdHRTZ1NnCklUVGYxUDdza1hmbW5Gc2sxUmw4\nb0hDS3MxbENqclU2QWxic2d4RC9KZVUKLS0tIFhwaURkelNUdlFMWWJlTUN0dUJo\nWWhQaEVmTTJlNE5qS2wvcmtuK2pNSEEKuKeGKXPLLTA9RWoOSacIVEZ2l3/uW96s\nM91c2ezYFOTV6Md23jYAmAnje7dTivTCmFPnPuWdbEGXYbHLzz/O9Q==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFUVN4WEpEcnpjdkFucXlE\nVTRjRlZHM0k2SVVXTkh1V0hLTXl0TVpZSG5rCnl0N2JuR2NsV1BUeXRPZStqRnJl\nR0wzb3l3Ymc2NytlZkw4ZmpoN09kcDAKLS0tIDRVTll5VmdFOWpPV1UwTithNElp\nWnVzU0s2YXR2Y25HcmZ4VUpleFM4TGcKFxi53+wTYdoaIMGvgcy0C6yTPDDPgZps\naWZcXfkberil26xNhRsRV6KwBje61Qd6vwU8hEa7P+hDcbBEavXwhw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuYjZWaXJpdVoyZHpVbkhW\nbEErbUNQa0M4Ty9iakkwblE4TDVBY2ozVFZvCnpiNlRPRTFxbTBQR1E0cGxYdmN2\nUUhSQVFWZ3VyV2VVR2lPNWhpY28rWTQKLS0tIDhLQlFGTncrKzErNnVCTDZZb0NW\nTFZxR2RFR3pBQkY0aVl5bWw2ZDlwOGMKakhqNNF7R4pgXEsXSaO7F5LGCw3yE53d\nItWXIoyCa0c78xk+YdMUNUOlzn39y8itXXpZAH2ZAC1sUrvq0elRew==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1t957gf0z865gya0khgc9x59wy76hzps3sgejjqtwcngn2xl273msxsmpe6",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzdHpmNks0Q3FLV3NiRThx\ncTVTODdYTStiUmdpM0gyaGZCdzNLRUlqalZnClNXbVI2dU9XMGNXTlh1U2trTnFi\ncEkvZllmM09WZDBBKzFTNDVuUjBpTE0KLS0tIDc5ZGJPTHJ6b2ZOaVdWUWl0Tng5\ndm1jRTRrZnltVm5sbW1uVjhTNnRyZGsKq9o7VkxWsf8k9wGi7ICC1M782MMdvQrY\nDDVlH7ITiDpJ1GGRDWAbfxB4izyb3MWoRqkhvcvcHt0WXR51FNa5NA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2022-06-21T07:13:52Z",
"mac": "ENC[AES256_GCM,data:AXFeOZhnpYOytxhU7ISGMikngd7dJbRzYJyu7mEFBPNTW77/1Bl6UwTz6Xy7HtLwX/vlH6eWELScfOUkFMkdxe2Tm8X0/ojB5k0uizpCjD6lQB4LjeMCnUfvA7cRIzTQSycc81VJ9AK0X+Ad+82KzMqQgKJOhFJjlJSColhOfwc=,iv:KXgdQ2547x//u4826q/y339X5TaWFmW4ayAThHTsGTY=,tag:k8N9Bic9d070ed6839mE2g==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"
}
}