Monorepo for Tangled tangled.org
4

Configure Feed

Select the types of activity you want to include in your feed.

1{ 2 nixpkgs, 3 system, 4 hostSystem, 5 self, 6}: let 7 lib = nixpkgs.lib; 8 9 envVar = name: let 10 var = builtins.getEnv name; 11 in 12 if var == "" 13 then throw "\$${name} must be defined, see https://docs.tangled.org/hacking-on-tangled.html#hacking-on-tangled for more details" 14 else var; 15 envVarOr = name: default: let 16 var = builtins.getEnv name; 17 in 18 if var != "" 19 then var 20 else default; 21 22 plcUrl = envVarOr "TANGLED_VM_PLC_URL" "https://plc.directory"; 23 jetstream = envVarOr "TANGLED_VM_JETSTREAM_ENDPOINT" "wss://jetstream1.us-west.bsky.network/subscribe"; 24 25 checkFile = value: path: 26 if builtins.pathExists path 27 then lib.hasPrefix value (builtins.readFile path) 28 else false; 29 _nestedVirt = 30 (checkFile "1" /sys/module/kvm_amd/parameters/nested) 31 || (checkFile "Y" /sys/module/kvm_intel/parameters/nested); 32 nestedVirtWarning = '' 33 KVM nested virtualisation is not enabled on this host. 34 You should enable it if you can for better performance when testing the QEMU spindle engine! 35 ''; 36 nestedVirt = lib.warnIf (!_nestedVirt) nestedVirtWarning _nestedVirt; 37in 38 lib.nixosSystem { 39 inherit system; 40 modules = [ 41 self.nixosModules.knot 42 self.nixosModules.spindle 43 self.nixosModules.knotmirror 44 ({ 45 lib, 46 config, 47 pkgs, 48 ... 49 }: { 50 virtualisation.vmVariant.virtualisation = { 51 host.pkgs = import nixpkgs {system = hostSystem;}; 52 53 graphics = false; 54 memorySize = 3072; 55 diskSize = 20 * 1024; 56 cores = 2; 57 qemu.options = lib.optionals nestedVirt ["-enable-kvm" "-cpu host"]; 58 59 forwardPorts = [ 60 # ssh 61 { 62 from = "host"; 63 host.port = 2222; 64 guest.port = 22; 65 } 66 # knot 67 { 68 from = "host"; 69 host.port = 6444; 70 guest.port = 6444; 71 } 72 # spindle 73 { 74 from = "host"; 75 host.port = 6555; 76 guest.port = 6555; 77 } 78 # knotmirror 79 { 80 from = "host"; 81 host.port = 7007; # 7000 is deserved in macos for Airplay 82 guest.port = 7000; 83 } 84 # knotmirror-tap 85 { 86 from = "host"; 87 host.port = 7480; 88 guest.port = 7480; 89 } 90 # knotmirror-admin 91 { 92 from = "host"; 93 host.port = 7200; 94 guest.port = 7200; 95 } 96 { 97 from = "host"; 98 host.port = 7100; 99 guest.port = 7100; 100 } 101 ]; 102 sharedDirectories = { 103 # We can't use the 9p mounts directly for most of these 104 # as SQLite is incompatible with them. So instead we 105 # mount the shared directories to a different location 106 # and copy the contents around on service start/stop. 107 knotData = { 108 source = "$TANGLED_VM_DATA_DIR/knot"; 109 target = "/mnt/knot-data"; 110 }; 111 spindleData = { 112 source = "$TANGLED_VM_DATA_DIR/spindle"; 113 target = "/mnt/spindle-data"; 114 }; 115 spindleLogs = { 116 source = "$TANGLED_VM_DATA_DIR/spindle-logs"; 117 target = "/var/log/spindle"; 118 }; 119 }; 120 }; 121 systemd.tmpfiles.rules = [ 122 "L+ /var/lib/spindle/images/nixos-x86_64 - - - - ${self.packages.${system}.spindle-nixos-image}" 123 "L+ /var/lib/spindle/images/nixos - - - - /var/lib/spindle/images/nixos-x86_64" 124 "L+ /var/lib/spindle/images/alpine-x86_64 - - - - ${self.packages.${system}.spindle-alpine-image}" 125 "L+ /var/lib/spindle/images/alpine - - - - /var/lib/spindle/images/alpine-x86_64" 126 ]; 127 # This is fine because any and all ports that are forwarded to host are explicitly marked above, we don't need a separate guest firewall 128 networking.firewall.enable = false; 129 services.timesyncd.enable = lib.mkForce true; 130 time.timeZone = "Europe/London"; 131 services.getty.autologinUser = "root"; 132 environment.systemPackages = with pkgs; [curl vim git sqlite litecli postgresql_14]; 133 services.tangled.knot = { 134 enable = true; 135 motd = "Welcome to the development knot!\n"; 136 server = { 137 secureMode = false; 138 owner = envVar "TANGLED_VM_KNOT_OWNER"; 139 hostname = envVarOr "TANGLED_VM_KNOT_HOST" "localhost:6444"; 140 plcUrl = plcUrl; 141 jetstreamEndpoint = jetstream; 142 listenAddr = "0.0.0.0:6444"; 143 dev = true; 144 }; 145 knotmirrors = [ 146 "http://localhost:7000" 147 ]; 148 }; 149 services.tangled.spindle = { 150 enable = true; 151 server = { 152 owner = envVar "TANGLED_VM_SPINDLE_OWNER"; 153 hostname = envVarOr "TANGLED_VM_SPINDLE_HOST" "localhost:6555"; 154 plcUrl = plcUrl; 155 jetstreamEndpoint = jetstream; 156 listenAddr = "0.0.0.0:6555"; 157 dev = true; 158 queueSize = 100; 159 maxJobCount = 2; 160 secrets = { 161 provider = "sqlite"; 162 }; 163 }; 164 165 pipelines = { 166 logBucket = envVarOr "SPINDLE_S3_LOG_BUCKET" ""; 167 microvm.enableKVM = nestedVirt; 168 nixCache = { 169 readUrls = ["http://127.0.0.1:8501"]; 170 trustedPublicKeys = ["cache.local:F7YqpMzuBdILYd/v+wMZN2YKxCzliXQyFmeezOxw7rU="]; 171 uploadUrl = "http://127.0.0.1:8501/upload"; 172 }; 173 }; 174 }; 175 services.ncps = { 176 enable = true; 177 cache = { 178 allowPutVerb = true; 179 allowDeleteVerb = true; 180 hostName = "cache.local"; 181 secretKeyPath = pkgs.writeText "ncps-secret-key" "cache.local:hay0+jvBNguou2tNt19FvrBCogHwHc+mqQe3bww5ZX4XtiqkzO4F0gth3+/7Axk3ZgrELOWJdDIWZ57M7HDutQ=="; 182 upstream = { 183 urls = ["https://cache.nixos.org"]; 184 publicKeys = ["cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="]; 185 }; 186 }; 187 server.addr = "127.0.0.1:8501"; 188 }; 189 services.postgresql = { 190 enable = true; 191 package = pkgs.postgresql_14; 192 ensureDatabases = ["mirror" "tap"]; 193 ensureUsers = [ 194 {name = "tnglr";} 195 ]; 196 authentication = '' 197 local all tnglr trust 198 host all tnglr 127.0.0.1/32 trust 199 ''; 200 }; 201 services.tangled.knotmirror = { 202 enable = true; 203 knotSSRF = false; 204 listenAddr = "0.0.0.0:7000"; 205 metricsListenAddr = "0.0.0.0:7100"; 206 adminListenAddr = "0.0.0.0:7200"; 207 hostname = "localhost:7000"; 208 dbUrl = "postgresql://tnglr@127.0.0.1:5432/mirror"; 209 fullNetwork = false; 210 tap.dbUrl = "postgresql://tnglr@127.0.0.1:5432/tap"; 211 }; 212 users = { 213 # So we don't have to deal with permission clashing between 214 # blank disk VMs and existing state 215 users.${config.services.tangled.knot.gitUser}.uid = 666; 216 groups.${config.services.tangled.knot.gitUser}.gid = 666; 217 218 # TODO: separate spindle user 219 }; 220 systemd.services = let 221 mkDataSyncScripts = source: target: { 222 enableStrictShellChecks = true; 223 224 preStart = lib.mkBefore '' 225 mkdir -p ${target} 226 ${lib.getExe pkgs.rsync} -a ${source}/ ${target} 227 ''; 228 229 postStop = lib.mkAfter '' 230 ${lib.getExe pkgs.rsync} -a ${target}/ ${source} 231 ''; 232 233 serviceConfig.PermissionsStartOnly = true; 234 }; 235 in { 236 knot = mkDataSyncScripts "/mnt/knot-data" config.services.tangled.knot.stateDir; 237 spindle = mkDataSyncScripts "/mnt/spindle-data" (dirOf config.services.tangled.spindle.server.dbPath); 238 knotmirror.after = ["postgresql.target"]; 239 tap-knotmirror.after = ["postgresql.target"]; 240 }; 241 }) 242 ]; 243 }