this repo has no description
1{ 2 nixpkgs, 3 system, 4 hostSystem, 5 self, 6}: let 7 envVar = name: let 8 var = builtins.getEnv name; 9 in 10 if var == "" 11 then throw "\$${name} must be defined, see https://docs.tangled.org/hacking-on-tangled.html#hacking-on-tangled for more details" 12 else var; 13 envVarOr = name: default: let 14 var = builtins.getEnv name; 15 in 16 if var != "" 17 then var 18 else default; 19 20 plcUrl = envVarOr "TANGLED_VM_PLC_URL" "https://plc.directory"; 21 jetstream = envVarOr "TANGLED_VM_JETSTREAM_ENDPOINT" "wss://jetstream1.us-west.bsky.network/subscribe"; 22 relayUrl = envVarOr "TANGLED_VM_RELAY_URL" "https://relay1.us-east.bsky.network"; 23in 24 nixpkgs.lib.nixosSystem { 25 inherit system; 26 modules = [ 27 self.nixosModules.knot 28 self.nixosModules.spindle 29 ({ 30 lib, 31 config, 32 pkgs, 33 ... 34 }: { 35 virtualisation.vmVariant.virtualisation = { 36 host.pkgs = import nixpkgs {system = hostSystem;}; 37 38 graphics = false; 39 memorySize = 2048; 40 diskSize = 10 * 1024; 41 cores = 2; 42 forwardPorts = [ 43 # ssh 44 { 45 from = "host"; 46 host.port = 2222; 47 guest.port = 22; 48 } 49 # knot 50 { 51 from = "host"; 52 host.port = 6444; 53 guest.port = 6444; 54 } 55 # spindle 56 { 57 from = "host"; 58 host.port = 6555; 59 guest.port = 6555; 60 } 61 { 62 from = "host"; 63 host.port = 6556; 64 guest.port = 2480; 65 } 66 ]; 67 sharedDirectories = { 68 # We can't use the 9p mounts directly for most of these 69 # as SQLite is incompatible with them. So instead we 70 # mount the shared directories to a different location 71 # and copy the contents around on service start/stop. 72 knotData = { 73 source = "$TANGLED_VM_DATA_DIR/knot"; 74 target = "/mnt/knot-data"; 75 }; 76 spindleData = { 77 source = "$TANGLED_VM_DATA_DIR/spindle"; 78 target = "/mnt/spindle-data"; 79 }; 80 spindleLogs = { 81 source = "$TANGLED_VM_DATA_DIR/spindle-logs"; 82 target = "/var/log/spindle"; 83 }; 84 }; 85 }; 86 # 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 87 networking.firewall.enable = false; 88 time.timeZone = "Europe/London"; 89 services.getty.autologinUser = "root"; 90 environment.systemPackages = with pkgs; [curl vim git sqlite litecli]; 91 services.tangled.knot = { 92 enable = true; 93 motd = "Welcome to the development knot!\n"; 94 server = { 95 owner = envVar "TANGLED_VM_KNOT_OWNER"; 96 hostname = envVarOr "TANGLED_VM_KNOT_HOST" "localhost:6444"; 97 plcUrl = plcUrl; 98 jetstreamEndpoint = jetstream; 99 listenAddr = "0.0.0.0:6444"; 100 }; 101 }; 102 services.tangled.spindle = { 103 enable = true; 104 atpRelayUrl = relayUrl; 105 server = { 106 owner = envVar "TANGLED_VM_SPINDLE_OWNER"; 107 hostname = envVarOr "TANGLED_VM_SPINDLE_HOST" "localhost:6555"; 108 plcUrl = plcUrl; 109 listenAddr = "0.0.0.0:6555"; 110 dev = true; 111 queueSize = 100; 112 maxJobCount = 2; 113 secrets = { 114 provider = "sqlite"; 115 }; 116 }; 117 }; 118 users = { 119 # So we don't have to deal with permission clashing between 120 # blank disk VMs and existing state 121 users.${config.services.tangled.knot.gitUser}.uid = 666; 122 groups.${config.services.tangled.knot.gitUser}.gid = 666; 123 124 # TODO: separate spindle user 125 }; 126 systemd.services = let 127 mkDataSyncScripts = source: target: { 128 enableStrictShellChecks = true; 129 130 preStart = lib.mkBefore '' 131 mkdir -p ${target} 132 ${lib.getExe pkgs.rsync} -a ${source}/ ${target} 133 ''; 134 135 postStop = lib.mkAfter '' 136 ${lib.getExe pkgs.rsync} -a ${target}/ ${source} 137 ''; 138 139 serviceConfig.PermissionsStartOnly = true; 140 }; 141 in { 142 knot = mkDataSyncScripts "/mnt/knot-data" config.services.tangled.knot.stateDir; 143 spindle = mkDataSyncScripts "/mnt/spindle-data" config.services.tangled.spindle.server.stateDir; 144 }; 145 }) 146 ]; 147 }