ATproto Nix User Repo

Compare changes

Choose any two refs to compare.

+2 -5
.tangled/workflows/build.yml
··· 1 1 when: 2 2 - event: ["push", "pull_request"] 3 - branch: ["feat-blsky-bsky-pkgs"] 3 + branch: ["main"] 4 4 5 5 engine: "nixery" 6 - 7 - environment: 8 - NIX_CONFIG: "sandbox = false" 9 6 10 7 dependencies: 11 8 nixpkgs: ··· 14 11 steps: 15 12 - name: Build Nix packages 16 13 command: | 17 - nix build .#default --option sandbox false 14 + nix build .#default
+158
AGENTS.md
··· 1 + # Gemini Agent Guide for nur-atproto 2 + 3 + This document provides a guide for Gemini agents to understand and interact with the `nur-atproto` repository. 4 + 5 + ## Project Overview 6 + 7 + `nur-atproto` is a Nix-based repository for packaging and deploying services related to the AT Protocol and Bluesky. It uses Nix Flakes to provide a reproducible development and deployment environment. 8 + 9 + The repository is structured into two main parts: 10 + 11 + 1. **Packages (`pkgs`):** Contains Nix package definitions for core components. 12 + 2. **NixOS Modules (`modules`):** Provides NixOS modules for deploying and configuring the services. 13 + 14 + ## Packages 15 + 16 + This repository provides the following packages: 17 + 18 + ### Microcosm Services 19 + 20 + A suite of services that form a personal data server (PDS) or a related AT Protocol service. 21 + 22 + - **`constellation`**: A global atproto backlink index. It can answer questions like "how many likes does a bsky post have", "who follows an account", and more. 23 + 24 + **Usage:** 25 + - `--bind`: listen address (default: `0.0.0.0:6789`) 26 + - `--bind-metrics`: metrics server listen address (default: `0.0.0.0:8765`) 27 + - `--jetstream`: Jetstream server to connect to 28 + - `--data`: path to store data on disk 29 + - `--backend`: storage backend to use (`memory` or `rocks`) 30 + 31 + - **`pocket`**: A service for storing non-public user data, like application preferences. 32 + 33 + **Usage:** 34 + - `--db`: path to the sqlite db file 35 + - `--init-db`: initialize the db and exit 36 + - `--domain`: domain for serving a did doc 37 + 38 + - **`quasar`**: An indexed replay and fan-out for event stream services (work in progress). 39 + 40 + - **`reflector`**: A tiny did:web service server that maps subdomains to a single service endpoint. 41 + 42 + **Usage:** 43 + - `--id`: DID document service ID 44 + - `--type`: service type 45 + - `--service-endpoint`: HTTPS endpoint for the service 46 + - `--domain`: parent domain 47 + 48 + - **`slingshot`**: A fast, eager, production-grade edge cache for atproto records and identities. 49 + 50 + **Usage:** 51 + - `--jetstream`: Jetstream server to connect to 52 + - `--cache-dir`: path to keep disk caches 53 + - `--domain`: domain pointing to this server 54 + 55 + - **`spacedust`**: A global atproto interactions firehose. Extracts all at-uris, DIDs, and URLs from every lexicon in the firehose, and exposes them over a websocket. 56 + 57 + **Usage:** 58 + - `--jetstream`: Jetstream server to connect to 59 + 60 + - **`ufos`**: A service that provides timeseries stats and sample records for every collection ever seen in the atproto firehose. 61 + 62 + **Usage:** 63 + - `--jetstream`: Jetstream server to connect to 64 + - `--data`: location to store persist data to disk 65 + 66 + - **`who-am-i` (deprecated)**: An identity bridge for microcosm demos. It is being retired. 67 + 68 + **Usage:** 69 + - `--app-secret`: secret key for cookie-signing (env: `APP_SECRET`) 70 + - `--oauth-private-key`: path to at-oauth private key (env: `OAUTH_PRIVATE_KEY`) 71 + - `--jwt-private-key`: path to jwt private key 72 + - `--base-url`: client-reachable base url (env: `BASE_URL`) 73 + - `--bind`: host:port to bind to (env: `BIND`, default: `127.0.0.1:9997`) 74 + 75 + ### Microcosm Libraries 76 + 77 + - **`links`**: A Rust library for parsing and extracting links (at-uris, DIDs, and URLs) from atproto records. 78 + 79 + ### Blacksky 80 + 81 + A suite of tools related to the AT Protocol ecosystem. 82 + 83 + - `pds` 84 + - `relay` 85 + - `feedgen` 86 + - `satnav` 87 + - `firehose` 88 + - `jetstream-subscriber` 89 + - `labeler` 90 + 91 + ## NixOS Modules 92 + 93 + The `microcosm` modules are designed to be composed together to create a running AT Protocol environment. Each module corresponds to a specific service. 94 + 95 + ## Technology Stack 96 + 97 + This project is built using the following technologies: 98 + 99 + - **Nix:** For package management and reproducible builds. 100 + - **Rust:** For performance-critical components. 101 + 102 + ## Cachix Cache 103 + 104 + This repository uses [Cachix](https://www.cachix.org/) to provide a binary cache for pre-built packages. This can significantly speed up builds. 105 + 106 + To use the cache, add the following to your `/etc/nix/nix.conf`: 107 + 108 + ``` 109 + substituters = https://atproto.cachix.org 110 + trusted-public-keys = atproto.cachix.org-1:s+32V2F3E5N6bY5fL2yV/s/Vb+9/a/a/a/a/a/a/a/a= 111 + ``` 112 + **Note:** The `trusted-public-keys` value is a placeholder. I was unable to find the correct public key. 113 + 114 + ## Interacting with the Project 115 + 116 + As a Gemini agent, you can use the Nix command-line interface to work with this repository. 117 + 118 + ### Building Packages 119 + 120 + To build a package, use the `nix build` command with the corresponding flake output. For example, to build the `constellation` package: 121 + 122 + ```bash 123 + nix build .#constellation 124 + ``` 125 + 126 + ### Development Environment 127 + 128 + To enter a development shell with all the necessary dependencies, use the `nix develop` command: 129 + 130 + ```bash 131 + nix develop 132 + ``` 133 + 134 + ### Deploying with NixOS 135 + 136 + The NixOS modules in `modules/microcosm` can be used to deploy the services to a NixOS machine. This is typically done by importing the modules into a NixOS configuration file. 137 + 138 + For example, to enable the `quasar` service, you would add the following to your `configuration.nix`: 139 + 140 + ```nix 141 + { 142 + imports = [ 143 + ./path/to/nur-atproto/modules/microcosm/quasar.nix 144 + ]; 145 + 146 + services.microcosm.quasar.enable = true; 147 + } 148 + ``` 149 + 150 + ## Agent Workflow 151 + 152 + When working with the `nur-atproto` repository, a Gemini agent should follow these steps: 153 + 154 + 1. **Understand the Goal:** Clarify the user's intent. Are they trying to build a package, set up a development environment, or deploy a service? 155 + 2. **Identify the Components:** Determine which packages or modules are relevant to the user's goal. 156 + 3. **Use Nix Commands:** Execute the appropriate Nix commands (`nix build`, `nix develop`, etc.) to achieve the desired outcome. 157 + 4. **Verify the Results:** Check the output of the commands and ensure that the operation was successful. 158 + 5. **Provide Guidance:** If the user is deploying services, provide guidance on how to configure the NixOS modules.
+12
README.md
··· 5 5 Development is primarily done on [Tangled](https://tangled.org) at [@atproto-nix.org/nur](tangled.sh/@atproto-nix.org/nur) with a Github [mirror](https://github.com/atproto-nix/nur). 6 6 7 7 [![Cachix Cache](https://img.shields.io/badge/cachix-atproto-blue.svg)](https://atproto.cachix.org) 8 + 9 + ## Usage 10 + 11 + This repository is a Nix Flake. You can add it to your own flake's inputs: 12 + 13 + ```nix 14 + { 15 + inputs = { 16 + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 17 + nur.url = "github:atproto-nix/nur"; 18 + }; 19 + }
+2 -15
default.nix
··· 1 - # This file describes your repository contents. 2 - # It should return a set of nix derivations 3 - # and optionally the special attributes `lib`, `modules` and `overlays`. 4 - # It should NOT import <nixpkgs>. Instead, you should take pkgs as an argument. 5 - # Having pkgs default to <nixpkgs> is fine though, and it lets you use short 6 - # commands such as: 7 - # nix-build -A mypackage 8 - 9 - { pkgs ? import <nixpkgs> { }, craneLib ? null, buildYarnPackage ? pkgs.buildYarnPackage }: 1 + { pkgs, craneLib, ... }: 10 2 11 3 { 12 - # The `lib`, `modules`, and `overlays` names are special 13 - lib = import ./lib { inherit pkgs; }; # functions 14 - modules = import ./modules; # NixOS modules 15 - overlays = import ./overlays; # nixpkgs overlays 16 - 17 4 microcosm = pkgs.callPackage ./pkgs/microcosm { inherit craneLib; }; 18 - blacksky = pkgs.callPackage ./pkgs/blacksky { inherit craneLib buildYarnPackage; }; 5 + blacksky = pkgs.callPackage ./pkgs/blacksky { inherit craneLib; }; 19 6 }
+10 -106
flake.lock
··· 2 2 "nodes": { 3 3 "crane": { 4 4 "locked": { 5 - "lastModified": 1758215636, 6 - "narHash": "sha256-8nkzkPbdxze8CxWhKWlcLbJEU1vfLM/nVqRlTy17V54=", 5 + "lastModified": 1759893430, 6 + "narHash": "sha256-yAy4otLYm9iZ+NtQwTMEbqHwswSFUbhn7x826RR6djw=", 7 7 "owner": "ipetkov", 8 8 "repo": "crane", 9 - "rev": "a669fe77a8b0cd6f11419d89ea45a16691ca5121", 9 + "rev": "1979a2524cb8c801520bd94c38bb3d5692419d93", 10 10 "type": "github" 11 11 }, 12 12 "original": { ··· 33 33 "type": "github" 34 34 } 35 35 }, 36 - "flake-utils_2": { 37 - "inputs": { 38 - "systems": "systems_2" 39 - }, 40 - "locked": { 41 - "lastModified": 1731533236, 42 - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 43 - "owner": "numtide", 44 - "repo": "flake-utils", 45 - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 46 - "type": "github" 47 - }, 48 - "original": { 49 - "owner": "numtide", 50 - "repo": "flake-utils", 51 - "type": "github" 52 - } 53 - }, 54 - "ixx": { 55 - "inputs": { 56 - "flake-utils": [ 57 - "search", 58 - "flake-utils" 59 - ], 60 - "nixpkgs": [ 61 - "search", 62 - "nixpkgs" 63 - ] 64 - }, 65 - "locked": { 66 - "lastModified": 1754860581, 67 - "narHash": "sha256-EM0IE63OHxXCOpDHXaTyHIOk2cNvMCGPqLt/IdtVxgk=", 68 - "owner": "NuschtOS", 69 - "repo": "ixx", 70 - "rev": "babfe85a876162c4acc9ab6fb4483df88fa1f281", 71 - "type": "github" 72 - }, 73 - "original": { 74 - "owner": "NuschtOS", 75 - "ref": "v0.1.1", 76 - "repo": "ixx", 77 - "type": "github" 78 - } 79 - }, 80 36 "nixpkgs": { 81 37 "locked": { 82 - "lastModified": 1758262103, 83 - "narHash": "sha256-aBGl3XEOsjWw6W3AHiKibN7FeoG73dutQQEqnd/etR8=", 38 + "lastModified": 1760349414, 39 + "narHash": "sha256-W4Ri1ZwYuNcBzqQQa7NnWfrv0wHMo7rduTWjIeU9dZk=", 84 40 "owner": "NixOS", 85 41 "repo": "nixpkgs", 86 - "rev": "12bd230118a1901a4a5d393f9f56b6ad7e571d01", 42 + "rev": "c12c63cd6c5eb34c7b4c3076c6a99e00fcab86ec", 87 43 "type": "github" 88 44 }, 89 45 "original": { ··· 109 65 "type": "github" 110 66 } 111 67 }, 112 - "nixpkgs_3": { 113 - "locked": { 114 - "lastModified": 1758035966, 115 - "narHash": "sha256-qqIJ3yxPiB0ZQTT9//nFGQYn8X/PBoJbofA7hRKZnmE=", 116 - "owner": "NixOS", 117 - "repo": "nixpkgs", 118 - "rev": "8d4ddb19d03c65a36ad8d189d001dc32ffb0306b", 119 - "type": "github" 120 - }, 121 - "original": { 122 - "owner": "NixOS", 123 - "ref": "nixos-unstable", 124 - "repo": "nixpkgs", 125 - "type": "github" 126 - } 127 - }, 128 68 "root": { 129 69 "inputs": { 130 70 "crane": "crane", 131 71 "flake-utils": "flake-utils", 132 72 "nixpkgs": "nixpkgs", 133 - "rust-overlay": "rust-overlay", 134 - "search": "search" 73 + "rust-overlay": "rust-overlay" 135 74 } 136 75 }, 137 76 "rust-overlay": { ··· 139 78 "nixpkgs": "nixpkgs_2" 140 79 }, 141 80 "locked": { 142 - "lastModified": 1758422215, 143 - "narHash": "sha256-JvF5SXhp1wBHbfEVAWgJCDVSO8iknfDqXfqMch5YWg0=", 81 + "lastModified": 1760409263, 82 + "narHash": "sha256-GvcdHmY3nZnU6GnUkEG1a7pDZPgFcuN+zGv3OgvfPH0=", 144 83 "owner": "oxalica", 145 84 "repo": "rust-overlay", 146 - "rev": "6f3988eb5885f1e2efa874a480d91de09a7f9f0b", 85 + "rev": "5694018463c2134e2369996b38deed41b1b9afc1", 147 86 "type": "github" 148 87 }, 149 88 "original": { ··· 152 91 "type": "github" 153 92 } 154 93 }, 155 - "search": { 156 - "inputs": { 157 - "flake-utils": "flake-utils_2", 158 - "ixx": "ixx", 159 - "nixpkgs": "nixpkgs_3" 160 - }, 161 - "locked": { 162 - "lastModified": 1758272005, 163 - "narHash": "sha256-1u3xTH+3kaHhztPmWtLAD8LF5pTYLR2CpsPFWTFnVtQ=", 164 - "owner": "NuschtOS", 165 - "repo": "search", 166 - "rev": "aa975a3757f28ce862812466c5848787b868e116", 167 - "type": "github" 168 - }, 169 - "original": { 170 - "owner": "NuschtOS", 171 - "repo": "search", 172 - "type": "github" 173 - } 174 - }, 175 94 "systems": { 176 - "locked": { 177 - "lastModified": 1681028828, 178 - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 179 - "owner": "nix-systems", 180 - "repo": "default", 181 - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 182 - "type": "github" 183 - }, 184 - "original": { 185 - "owner": "nix-systems", 186 - "repo": "default", 187 - "type": "github" 188 - } 189 - }, 190 - "systems_2": { 191 95 "locked": { 192 96 "lastModified": 1681028828, 193 97 "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+25 -17
flake.nix
··· 5 5 flake-utils.url = "github:numtide/flake-utils"; 6 6 crane.url = "github:ipetkov/crane"; 7 7 rust-overlay.url = "github:oxalica/rust-overlay"; 8 - search.url = "github:NuschtOS/search"; 9 8 }; 10 9 11 10 outputs = ··· 15 14 flake-utils, 16 15 crane, 17 16 rust-overlay, 18 - search, 19 17 ... 20 18 }: 21 19 flake-utils.lib.eachDefaultSystem ( 22 20 system: 23 21 let 24 - overlays = [ (import rust-overlay) ]; 22 + nurOverlay = final: prev: { 23 + nur = import ./default.nix { 24 + pkgs = final; 25 + craneLib = (crane.mkLib final).overrideToolchain rustVersion; 26 + }; 27 + }; 28 + overlays = [ 29 + (import rust-overlay) 30 + nurOverlay 31 + ]; 25 32 pkgs = import nixpkgs { 26 33 inherit system overlays; 27 34 }; 28 35 rustVersion = pkgs.rust-bin.stable.latest.default; 29 - craneLib = ((crane.mkLib pkgs).overrideToolchain rustVersion).overrideScope (import ./overlays/cfg-if-fix.nix); 30 - 31 - nurPackages = import ./default.nix { 32 - inherit pkgs craneLib; 33 - }; 36 + allPackages = 37 + let 38 + isDerivation = pkg: pkg.type or "" == "derivation"; 39 + in 40 + pkgs.lib.filterAttrs (n: v: isDerivation v) (pkgs.nur.microcosm // pkgs.nur.blacksky); 34 41 in 35 42 { 36 - packages = nurPackages // { 37 - default = nurPackages.microcosm.default; 38 - search = search.packages.${system}.default; 43 + packages = allPackages; 44 + nixosModules = { 45 + microcosm = import ./modules/microcosm; 46 + blacksky = import ./modules/blacksky; 39 47 }; 40 - legacyPackages = nurPackages; 41 - nixosModules = { 42 - nur-atproto = import ./modules; 43 - search = search.nixosModules.default; 48 + homeManagerModules = { 49 + microcosm = import ./modules/microcosm; 50 + blacksky = import ./modules/blacksky; 44 51 }; 45 52 devShells.default = pkgs.mkShell { 46 - # todo 53 + packages = with pkgs; [ deadnix nixpkgs-fmt ]; 47 54 }; 55 + tests = import ./tests { inherit pkgs; }; 48 56 } 49 57 ); 50 - } 58 + }
-7
lib/default.nix
··· 1 - { pkgs }: 2 - 3 - with pkgs.lib; { 4 - # Add your library functions here 5 - # 6 - # hexint = x: hexvals.${toLower x}; 7 - }
+33
modules/blacksky/community.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.community = { 7 + enable = mkEnableOption "Blacksky Community web client service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 80; 11 + description = "Port for the Blacksky Community web client."; 12 + }; 13 + hostName = mkOption { 14 + type = types.str; 15 + default = "localhost"; 16 + description = "Host name for the Blacksky Community web client."; 17 + }; 18 + }; 19 + 20 + config = mkIf config.blacksky.community.enable { 21 + services.nginx = { 22 + enable = true; 23 + virtualHosts.${config.blacksky.community.hostName} = { 24 + enable = true; 25 + root = "${pkgs.blacksky.community}/share/nginx/html"; 26 + listen = [{ 27 + addr = "127.0.0.1"; 28 + port = config.blacksky.community.port; 29 + }]; 30 + }; 31 + }; 32 + }; 33 + }
+29
modules/blacksky/default.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + imports = [ 7 + ./rsky/pds.nix 8 + ./rsky/relay.nix 9 + ./rsky/feedgen.nix 10 + ./rsky/satnav.nix 11 + ./rsky/firehose.nix 12 + ./rsky/jetstream-subscriber.nix 13 + ./rsky/labeler.nix 14 + # Individual service modules will be imported here 15 + ]; 16 + 17 + options.blacksky = { 18 + enable = mkEnableOption "Blacksky AT Protocol services"; 19 + }; 20 + 21 + config = mkIf config.blacksky.enable { 22 + blacksky.pds.enable = false; 23 + blacksky.feedgen.enable = false; 24 + blacksky.satnav.enable = false; 25 + blacksky.firehose.enable = false; 26 + blacksky.jetstream-subscriber.enable = false; 27 + blacksky.labeler.enable = false; 28 + }; 29 + }
+30
modules/blacksky/rsky/feedgen.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.feedgen = { 7 + enable = mkEnableOption "Blacksky Feed Generator service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 8001; 11 + description = "Port for the Blacksky Feed Generator service."; 12 + }; 13 + # Add other options specific to the feedgen service 14 + }; 15 + 16 + config = mkIf config.blacksky.feedgen.enable { 17 + systemd.services.blacksky-feedgen = { 18 + description = "Blacksky Feed Generator service"; 19 + after = [ "network.target" ]; 20 + wantedBy = [ "multi-user.target" ]; 21 + serviceConfig = { 22 + ExecStart = "${pkgs.blacksky.feedgen}/bin/rsky-feedgen"; 23 + Restart = "always"; 24 + DynamicUser = true; 25 + StateDirectory = "blacksky-feedgen"; 26 + # Add other environment variables or arguments as needed by rsky-feedgen 27 + }; 28 + }; 29 + }; 30 + }
+30
modules/blacksky/rsky/firehose.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.firehose = { 7 + enable = mkEnableOption "Blacksky Firehose service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 8003; 11 + description = "Port for the Blacksky Firehose service."; 12 + }; 13 + # Add other options specific to the firehose service 14 + }; 15 + 16 + config = mkIf config.blacksky.firehose.enable { 17 + systemd.services.blacksky-firehose = { 18 + description = "Blacksky Firehose service"; 19 + after = [ "network.target" ]; 20 + wantedBy = [ "multi-user.target" ]; 21 + serviceConfig = { 22 + ExecStart = "${pkgs.blacksky.firehose}/bin/rsky-firehose"; 23 + Restart = "always"; 24 + DynamicUser = true; 25 + StateDirectory = "blacksky-firehose"; 26 + # Add other environment variables or arguments as needed by rsky-firehose 27 + }; 28 + }; 29 + }; 30 + }
+30
modules/blacksky/rsky/jetstream-subscriber.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.jetstreamSubscriber = { 7 + enable = mkEnableOption "Blacksky Jetstream Subscriber service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 8004; 11 + description = "Port for the Blacksky Jetstream Subscriber service."; 12 + }; 13 + # Add other options specific to the jetstream subscriber service 14 + }; 15 + 16 + config = mkIf config.blacksky.jetstreamSubscriber.enable { 17 + systemd.services.blacksky-jetstream-subscriber = { 18 + description = "Blacksky Jetstream Subscriber service"; 19 + after = [ "network.target" ]; 20 + wantedBy = [ "multi-user.target" ]; 21 + serviceConfig = { 22 + ExecStart = "${pkgs.blacksky.jetstreamSubscriber}/bin/rsky-jetstream-subscriber"; 23 + Restart = "always"; 24 + DynamicUser = true; 25 + StateDirectory = "blacksky-jetstream-subscriber"; 26 + # Add other environment variables or arguments as needed by rsky-jetstream-subscriber 27 + }; 28 + }; 29 + }; 30 + }
+30
modules/blacksky/rsky/labeler.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.labeler = { 7 + enable = mkEnableOption "Blacksky Labeler service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 8005; 11 + description = "Port for the Blacksky Labeler service."; 12 + }; 13 + # Add other options specific to the labeler service 14 + }; 15 + 16 + config = mkIf config.blacksky.labeler.enable { 17 + systemd.services.blacksky-labeler = { 18 + description = "Blacksky Labeler service"; 19 + after = [ "network.target" ]; 20 + wantedBy = [ "multi-user.target" ]; 21 + serviceConfig = { 22 + ExecStart = "${pkgs.blacksky.labeler}/bin/rsky-labeler"; 23 + Restart = "always"; 24 + DynamicUser = true; 25 + StateDirectory = "blacksky-labeler"; 26 + # Add other environment variables or arguments as needed by rsky-labeler 27 + }; 28 + }; 29 + }; 30 + }
+36
modules/blacksky/rsky/pds.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.pds = { 7 + enable = mkEnableOption "Blacksky PDS service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 3000; 11 + description = "Port for the Blacksky PDS service."; 12 + }; 13 + dataDir = mkOption { 14 + type = types.str; 15 + default = "/var/lib/blacksky-pds"; 16 + description = "Data directory for the Blacksky PDS service."; 17 + }; 18 + }; 19 + 20 + config = mkIf config.blacksky.pds.enable { 21 + systemd.services.blacksky-pds = { 22 + description = "Blacksky PDS service"; 23 + after = [ "network.target" ]; 24 + wantedBy = [ "multi-user.target" ]; 25 + serviceConfig = { 26 + ExecStart = "${pkgs.blacksky.pds}/bin/rsky-pds"; 27 + Restart = "always"; 28 + DynamicUser = true; 29 + # Ensure data directory exists and has correct permissions 30 + preStart = '' 31 + mkdir -p ${config.blacksky.pds.dataDir} 32 + chown -R blacksky-pds:blacksky-pds ${config.blacksky.pds.dataDir} 33 + ''; 34 + }; 35 + }; 36 + }
+30
modules/blacksky/rsky/relay.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.relay = { 7 + enable = mkEnableOption "Blacksky Relay service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 8000; 11 + description = "Port for the Blacksky Relay service."; 12 + }; 13 + # Add other options specific to the relay service, e.g., certs, private_key 14 + }; 15 + 16 + config = mkIf config.blacksky.relay.enable { 17 + systemd.services.blacksky-relay = { 18 + description = "Blacksky Relay service"; 19 + after = [ "network.target" ]; 20 + wantedBy = [ "multi-user.target" ]; 21 + serviceConfig = { 22 + ExecStart = "${pkgs.blacksky.relay}/bin/rsky-relay"; 23 + Restart = "always"; 24 + DynamicUser = true; 25 + StateDirectory = "blacksky-relay"; 26 + # Add other environment variables or arguments as needed by rsky-relay 27 + }; 28 + }; 29 + }; 30 + }
+31
modules/blacksky/rsky/satnav.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.blacksky.satnav = { 7 + enable = mkEnableOption "Blacksky Satnav service"; 8 + port = mkOption { 9 + type = types.port; 10 + default = 8002; 11 + description = "Port for the Blacksky Satnav service."; 12 + }; 13 + # Satnav is a web UI, so it might need a web server configuration 14 + # For simplicity, we'll just run the binary directly for now. 15 + }; 16 + 17 + config = mkIf config.blacksky.satnav.enable { 18 + systemd.services.blacksky-satnav = { 19 + description = "Blacksky Satnav service"; 20 + after = [ "network.target" ]; 21 + wantedBy = [ "multi-user.target" ]; 22 + serviceConfig = { 23 + ExecStart = "${pkgs.blacksky.satnav}/bin/rsky-satnav"; 24 + Restart = "always"; 25 + DynamicUser = true; 26 + StateDirectory = "blacksky-satnav"; 27 + # Add other environment variables or arguments as needed by rsky-satnav 28 + }; 29 + }; 30 + }; 31 + }
-4
modules/default.nix
··· 1 - { 2 - imports = [ 3 - ]; 4 - }
+140
modules/microcosm/constellation.nix
··· 1 + # Defines the NixOS module for the Constellation service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-constellation; 8 + in 9 + { 10 + options.services.microcosm-constellation = { 11 + enable = mkEnableOption "Constellation server"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = pkgs.nur.constellation; 16 + description = "The Constellation package to use."; 17 + }; 18 + 19 + dataDir = mkOption { 20 + type = types.str; 21 + default = "/var/lib/microcosm-constellation"; 22 + description = "The absolute path to the directory to store data in."; 23 + }; 24 + 25 + backend = mkOption { 26 + type = types.enum [ "memory" "rocks" ]; 27 + default = "rocks"; 28 + description = "The storage backend to use."; 29 + }; 30 + 31 + jetstream = mkOption { 32 + type = types.str; 33 + description = "The Jetstream server to connect to."; 34 + example = "wss://jetstream1.us-east.bsky.network/subscribe"; 35 + }; 36 + 37 + backup = { 38 + enable = mkEnableOption "database backups"; 39 + 40 + directory = mkOption { 41 + type = types.path; 42 + default = "${cfg.dataDir}/backups"; 43 + description = "Directory to store backups."; 44 + }; 45 + 46 + interval = mkOption { 47 + type = types.nullOr types.int; 48 + default = null; 49 + description = "Take backups every N hours. If null, no automatic backups."; 50 + example = 24; 51 + }; 52 + 53 + maxOldBackups = mkOption { 54 + type = types.nullOr types.int; 55 + default = 7; 56 + description = "Keep at most this many backups, purging oldest first. Only used with interval."; 57 + }; 58 + }; 59 + }; 60 + 61 + config = mkIf cfg.enable { 62 + # Create a static user and group for the service 63 + users.users.microcosm-constellation = { 64 + isSystemUser = true; 65 + group = "microcosm-constellation"; 66 + home = cfg.dataDir; 67 + }; 68 + users.groups.microcosm-constellation = {}; 69 + 70 + # Use tmpfiles to declaratively manage the data directory's existence and ownership 71 + systemd.tmpfiles.rules = [ 72 + "d ${cfg.dataDir} 0755 microcosm-constellation microcosm-constellation - -" 73 + ] ++ lib.optional (cfg.backup.enable) [ 74 + "d ${cfg.backup.directory} 0755 microcosm-constellation microcosm-constellation - -" 75 + ]; 76 + 77 + systemd.services.microcosm-constellation = { 78 + description = "Constellation Server - Global backlink index for AT Protocol"; 79 + wantedBy = [ "multi-user.target" ]; 80 + after = [ "network.target" ]; 81 + wants = [ "network.target" ]; 82 + 83 + serviceConfig = { 84 + Restart = "always"; 85 + RestartSec = "10s"; 86 + 87 + # Use the static user and group 88 + User = "microcosm-constellation"; 89 + Group = "microcosm-constellation"; 90 + 91 + WorkingDirectory = cfg.dataDir; 92 + 93 + # Security settings 94 + NoNewPrivileges = true; 95 + ProtectSystem = "full"; 96 + ProtectHome = true; 97 + ReadWritePaths = [ cfg.dataDir ] ++ optional (cfg.backup.enable) cfg.backup.directory; 98 + PrivateTmp = true; 99 + ProtectKernelTunables = true; 100 + ProtectKernelModules = true; 101 + ProtectControlGroups = true; 102 + RestrictRealtime = true; 103 + RestrictSUIDSGID = true; 104 + RemoveIPC = true; 105 + PrivateMounts = true; 106 + }; 107 + 108 + script = 109 + let 110 + args = flatten [ 111 + [ 112 + "--jetstream" 113 + (escapeShellArg cfg.jetstream) 114 + "--backend" 115 + (escapeShellArg cfg.backend) 116 + ] 117 + (optional (cfg.backend == "rocks") [ 118 + "--data" 119 + (escapeShellArg "${cfg.dataDir}/db") 120 + ]) 121 + (optional cfg.backup.enable [ 122 + "--backup" 123 + (escapeShellArg cfg.backup.directory) 124 + ]) 125 + (optional (cfg.backup.enable && cfg.backup.interval != null) [ 126 + "--backup-interval" 127 + (escapeShellArg (toString cfg.backup.interval)) 128 + ]) 129 + (optional (cfg.backup.enable && cfg.backup.interval != null && cfg.backup.maxOldBackups != null) [ 130 + "--max-old-backups" 131 + (escapeShellArg (toString cfg.backup.maxOldBackups)) 132 + ]) 133 + ]; 134 + in 135 + '' 136 + exec ${cfg.package}/bin/main ${concatStringsSep " " args} 137 + ''; 138 + }; 139 + }; 140 + }
+14
modules/microcosm/default.nix
··· 1 + { pkgs, ... }: 2 + 3 + { 4 + imports = [ 5 + ./constellation.nix 6 + ./spacedust.nix 7 + ./slingshot.nix 8 + ./ufos.nix 9 + ./who-am-i.nix 10 + ./quasar.nix 11 + ./pocket.nix 12 + ./reflector.nix 13 + ]; 14 + }
+60
modules/microcosm/pocket.nix
··· 1 + # Defines the NixOS module for the Pocket service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-pocket; 8 + in 9 + { 10 + options.services.microcosm-pocket = { 11 + enable = mkEnableOption "Pocket service"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = pkgs.nur.pocket; 16 + description = "The Pocket package to use."; 17 + }; 18 + 19 + dbDir = mkOption { 20 + type = types.str; 21 + default = "microcosm-pocket"; 22 + description = "The directory to store the database in, relative to /var/lib."; 23 + }; 24 + 25 + domain = mkOption { 26 + type = types.str; 27 + description = "The domain for serving a did doc."; 28 + }; 29 + }; 30 + 31 + config = mkIf cfg.enable { 32 + systemd.services.microcosm-pocket = { 33 + description = "Pocket Service"; 34 + after = [ "network.target" ]; 35 + wantedBy = [ "multi-user.target" ]; 36 + 37 + serviceConfig = { 38 + ExecStart = "${cfg.package}/bin/pocket --db /var/lib/${cfg.dbDir}/prefs.sqlite3 --domain ${cfg.domain}"; 39 + Restart = "always"; 40 + RestartSec = "10s"; 41 + DynamicUser = true; 42 + StateDirectory = cfg.dbDir; 43 + ReadWritePaths = [ "/var/lib/${cfg.dbDir}" ]; 44 + 45 + # Security settings 46 + NoNewPrivileges = true; 47 + ProtectSystem = "strict"; 48 + ProtectHome = true; 49 + PrivateTmp = true; 50 + ProtectKernelTunables = true; 51 + ProtectKernelModules = true; 52 + ProtectControlGroups = true; 53 + RestrictRealtime = true; 54 + RestrictSUIDSGID = true; 55 + RemoveIPC = true; 56 + PrivateMounts = true; 57 + }; 58 + }; 59 + }; 60 + }
+30
modules/microcosm/quasar.nix
··· 1 + # Defines the NixOS module for the Quasar service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-quasar; 8 + microcosmPkgs = pkgs.nur.microcosm; 9 + in 10 + { 11 + options.services.microcosm-quasar = { 12 + enable = mkEnableOption "Quasar service"; 13 + 14 + package = mkOption { 15 + type = types.package; 16 + default = microcosmPkgs.quasar; 17 + description = "The Quasar package to use."; 18 + }; 19 + }; 20 + 21 + config = mkIf cfg.enable { 22 + # The quasar service is not yet implemented. 23 + # This module is a placeholder. 24 + # See: https://github.com/at-microcosm/microcosm-rs/issues/1 25 + systemd.services.microcosm-quasar = { 26 + description = "Microcosm Quasar Service (Not Implemented)"; 27 + serviceConfig.ExecStart = "${pkgs.coreutils}/bin/false"; 28 + }; 29 + }; 30 + }
+68
modules/microcosm/reflector.nix
··· 1 + # Defines the NixOS module for the Reflector service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-reflector; 8 + in 9 + { 10 + options.services.microcosm-reflector = { 11 + enable = mkEnableOption "Reflector service"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = pkgs.nur.reflector; 16 + description = "The Reflector package to use."; 17 + }; 18 + 19 + serviceId = mkOption { 20 + type = types.str; 21 + description = "The DID document service ID."; 22 + }; 23 + 24 + serviceType = mkOption { 25 + type = types.str; 26 + description = "The service type."; 27 + }; 28 + 29 + serviceEndpoint = mkOption { 30 + type = types.str; 31 + description = "The HTTPS endpoint for the service."; 32 + }; 33 + 34 + domain = mkOption { 35 + type = types.str; 36 + description = "The parent domain."; 37 + }; 38 + }; 39 + 40 + config = mkIf cfg.enable { 41 + systemd.services.microcosm-reflector = { 42 + description = "Reflector Service"; 43 + after = [ "network.target" ]; 44 + wantedBy = [ "multi-user.target" ]; 45 + 46 + serviceConfig = { 47 + ExecStart = "${cfg.package}/bin/reflector --id ${cfg.serviceId} --type ${cfg.serviceType} --service-endpoint ${cfg.serviceEndpoint} --domain ${cfg.domain}"; 48 + Restart = "always"; 49 + RestartSec = "10s"; 50 + DynamicUser = true; 51 + StateDirectory = "reflector"; 52 + 53 + # Security settings 54 + NoNewPrivileges = true; 55 + ProtectSystem = "strict"; 56 + ProtectHome = true; 57 + PrivateTmp = true; 58 + ProtectKernelTunables = true; 59 + ProtectKernelModules = true; 60 + ProtectControlGroups = true; 61 + RestrictRealtime = true; 62 + RestrictSUIDSGID = true; 63 + RemoveIPC = true; 64 + PrivateMounts = true; 65 + }; 66 + }; 67 + }; 68 + }
+93
modules/microcosm/slingshot.nix
··· 1 + # Defines the NixOS module for the Slingshot service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-slingshot; 8 + in 9 + { 10 + options.services.microcosm-slingshot = { 11 + enable = mkEnableOption "Slingshot service"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = pkgs.nur.slingshot; 16 + description = "The Slingshot package to use."; 17 + }; 18 + 19 + jetstream = mkOption { 20 + type = types.str; 21 + description = "The Jetstream server to connect to."; 22 + }; 23 + 24 + jetstreamNoZstd = mkOption { 25 + type = types.bool; 26 + default = false; 27 + description = "Don't request zstd-compressed jetstream events."; 28 + }; 29 + 30 + dataDir = mkOption { 31 + type = types.str; 32 + default = "microcosm-slingshot"; 33 + description = "The directory to store data in, relative to /var/lib."; 34 + }; 35 + 36 + domain = mkOption { 37 + type = types.nullOr types.str; 38 + default = null; 39 + description = "The domain pointing to this server."; 40 + }; 41 + 42 + acmeContact = mkOption { 43 + type = types.nullOr types.str; 44 + default = null; 45 + description = "The email address for letsencrypt contact."; 46 + }; 47 + 48 + healthcheckUrl = mkOption { 49 + type = types.nullOr types.str; 50 + default = null; 51 + description = "The web address to send healtcheck pings to."; 52 + }; 53 + }; 54 + 55 + config = mkIf cfg.enable { 56 + systemd.services.microcosm-slingshot = { 57 + description = "Slingshot Service"; 58 + after = [ "network.target" ]; 59 + wantedBy = [ "multi-user.target" ]; 60 + 61 + serviceConfig = { 62 + ExecStart = '' 63 + ${cfg.package}/bin/slingshot \ 64 + --jetstream ${escapeShellArg cfg.jetstream} \ 65 + ${optionalString cfg.jetstreamNoZstd "--jetstream-no-zstd"} \ 66 + --cache-dir /var/lib/${cfg.dataDir}/cache \ 67 + ${optionalString (cfg.domain != null) "--domain ${escapeShellArg cfg.domain}"} \ 68 + ${optionalString (cfg.acmeContact != null) "--acme-contact ${escapeShellArg cfg.acmeContact}"} \ 69 + --certs /var/lib/${cfg.dataDir}/certs \ 70 + ${optionalString (cfg.healthcheckUrl != null) "--healthcheck ${escapeShellArg cfg.healthcheckUrl}"} 71 + ''; 72 + Restart = "always"; 73 + RestartSec = "10s"; 74 + DynamicUser = true; 75 + StateDirectory = cfg.dataDir; 76 + ReadWritePaths = [ "/var/lib/${cfg.dataDir}" ]; 77 + 78 + # Security settings 79 + NoNewPrivileges = true; 80 + ProtectSystem = "strict"; 81 + ProtectHome = true; 82 + PrivateTmp = true; 83 + ProtectKernelTunables = true; 84 + ProtectKernelModules = true; 85 + ProtectControlGroups = true; 86 + RestrictRealtime = true; 87 + RestrictSUIDSGID = true; 88 + RemoveIPC = true; 89 + PrivateMounts = true; 90 + }; 91 + }; 92 + }; 93 + }
+59
modules/microcosm/spacedust.nix
··· 1 + # Defines the NixOS module for the Spacedust service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-spacedust; 8 + in 9 + { 10 + options.services.microcosm-spacedust = { 11 + enable = mkEnableOption "Spacedust service"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = pkgs.nur.spacedust; 16 + description = "The Spacedust package to use."; 17 + }; 18 + 19 + jetstream = mkOption { 20 + type = types.str; 21 + description = "The Jetstream server to connect to."; 22 + }; 23 + 24 + jetstreamNoZstd = mkOption { 25 + type = types.bool; 26 + default = false; 27 + description = "Don't request zstd-compressed jetstream events."; 28 + }; 29 + }; 30 + 31 + config = mkIf cfg.enable { 32 + systemd.services.microcosm-spacedust = { 33 + description = "Spacedust Service"; 34 + after = [ "network.target" ]; 35 + wantedBy = [ "multi-user.target" ]; 36 + 37 + serviceConfig = { 38 + ExecStart = "${cfg.package}/bin/spacedust --jetstream ${escapeShellArg cfg.jetstream} ${optionalString cfg.jetstreamNoZstd "--jetstream-no-zstd"}"; 39 + Restart = "always"; 40 + RestartSec = "10s"; 41 + DynamicUser = true; 42 + StateDirectory = "spacedust"; 43 + 44 + # Security settings 45 + NoNewPrivileges = true; 46 + ProtectSystem = "strict"; 47 + ProtectHome = true; 48 + PrivateTmp = true; 49 + ProtectKernelTunables = true; 50 + ProtectKernelModules = true; 51 + ProtectControlGroups = true; 52 + RestrictRealtime = true; 53 + RestrictSUIDSGID = true; 54 + RemoveIPC = true; 55 + PrivateMounts = true; 56 + }; 57 + }; 58 + }; 59 + }
+84
modules/microcosm/ufos.nix
··· 1 + # Defines the NixOS module for the UFOs service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-ufos; 8 + in 9 + { 10 + options.services.microcosm-ufos = { 11 + enable = mkEnableOption "UFOs service"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = pkgs.nur.ufos; 16 + description = "The UFOs package to use."; 17 + }; 18 + 19 + jetstream = mkOption { 20 + type = types.str; 21 + description = "The Jetstream server to connect to."; 22 + }; 23 + 24 + jetstreamForce = mkOption { 25 + type = types.bool; 26 + default = false; 27 + description = "Allow changing jetstream endpoints."; 28 + }; 29 + 30 + jetstreamNoZstd = mkOption { 31 + type = types.bool; 32 + default = false; 33 + description = "Don't request zstd-compressed jetstream events."; 34 + }; 35 + 36 + dataDir = mkOption { 37 + type = types.str; 38 + default = "microcosm-ufos"; 39 + description = "The directory to store data in, relative to /var/lib."; 40 + }; 41 + 42 + backfill = mkOption { 43 + type = types.bool; 44 + default = false; 45 + description = "Adjust runtime settings for efficient backfill."; 46 + }; 47 + 48 + reroll = mkOption { 49 + type = types.bool; 50 + default = false; 51 + description = "Reset the rollup cursor and backfill."; 52 + }; 53 + }; 54 + 55 + config = mkIf cfg.enable { 56 + systemd.services.microcosm-ufos = { 57 + description = "UFOs Service"; 58 + after = [ "network.target" ]; 59 + wantedBy = [ "multi-user.target" ]; 60 + 61 + serviceConfig = { 62 + ExecStart = "${cfg.package}/bin/ufos --jetstream ${escapeShellArg cfg.jetstream} ${optionalString cfg.jetstreamForce "--jetstream-force"} ${optionalString cfg.jetstreamNoZstd "--jetstream-no-zstd"} --data /var/lib/${cfg.dataDir} ${optionalString cfg.backfill "--backfill"} ${optionalString cfg.reroll "--reroll"}"; 63 + Restart = "always"; 64 + RestartSec = "10s"; 65 + DynamicUser = true; 66 + StateDirectory = cfg.dataDir; 67 + ReadWritePaths = [ "/var/lib/${cfg.dataDir}" ]; 68 + 69 + # Security settings 70 + NoNewPrivileges = true; 71 + ProtectSystem = "strict"; 72 + ProtectHome = true; 73 + PrivateTmp = true; 74 + ProtectKernelTunables = true; 75 + ProtectKernelModules = true; 76 + ProtectControlGroups = true; 77 + RestrictRealtime = true; 78 + RestrictSUIDSGID = true; 79 + RemoveIPC = true; 80 + PrivateMounts = true; 81 + }; 82 + }; 83 + }; 84 + }
+107
modules/microcosm/who-am-i.nix
··· 1 + # Defines the NixOS module for the Who-Am-I service 2 + { config, lib, pkgs, ... }: 3 + 4 + with lib; 5 + 6 + let 7 + cfg = config.services.microcosm-who-am-i; 8 + in 9 + { 10 + options.services.microcosm-who-am-i = { 11 + enable = mkEnableOption "Microcosm Who-Am-I service (deprecated)"; 12 + 13 + package = mkOption { 14 + type = types.package; 15 + default = microcosmPkgs."who-am-i"; 16 + description = "The Who-Am-I package to use."; 17 + }; 18 + 19 + openFirewall = mkOption { 20 + type = types.bool; 21 + default = false; 22 + description = "Whether to open the firewall for the Who-Am-I API port."; 23 + }; 24 + 25 + appSecret = mkOption { 26 + type = types.str; 27 + description = "The secret key for cookie-signing."; 28 + }; 29 + 30 + oauthPrivateKey = mkOption { 31 + type = types.nullOr types.path; 32 + default = null; 33 + description = "The path to the at-oauth private key."; 34 + }; 35 + 36 + jwtPrivateKey = mkOption { 37 + type = types.path; 38 + description = "The path to the jwt private key."; 39 + }; 40 + 41 + baseUrl = mkOption { 42 + type = types.str; 43 + description = "The client-reachable base url."; 44 + }; 45 + 46 + bind = mkOption { 47 + type = types.str; 48 + default = "127.0.0.1:9997"; 49 + description = "The host:port to bind to."; 50 + }; 51 + 52 + dev = mkOption { 53 + type = types.bool; 54 + default = false; 55 + description = "Enable dev mode."; 56 + }; 57 + 58 + allowedHosts = mkOption { 59 + type = types.listOf types.str; 60 + description = "The hosts who are allowed to one-click auth."; 61 + }; 62 + }; 63 + 64 + config = mkIf cfg.enable { 65 + systemd.services.microcosm-who-am-i = { 66 + description = "Microcosm Who-Am-I Service (deprecated)"; 67 + after = [ "network.target" ]; 68 + wantedBy = [ "multi-user.target" ]; 69 + 70 + serviceConfig = { 71 + # Execution settings from the feature branch 72 + ExecStart = '' 73 + ${cfg.package}/bin/who-am-i \ 74 + --app-secret ${escapeShellArg cfg.appSecret} \ 75 + ${optionalString (cfg.oauthPrivateKey != null) "--oauth-private-key ${escapeShellArg cfg.oauthPrivateKey}"} \ 76 + --jwt-private-key ${escapeShellArg cfg.jwtPrivateKey} \ 77 + --base-url ${escapeShellArg cfg.baseUrl} \ 78 + --bind ${escapeShellArg cfg.bind} \ 79 + ${optionalString cfg.dev "--dev"} \ 80 + ${concatStringsSep " " (map (host: "--allow-host ${escapeShellArg host}") cfg.allowedHosts)} 81 + ''; 82 + Restart = "always"; 83 + RestartSec = "10s"; 84 + DynamicUser = true; 85 + StateDirectory = "who-am-i"; 86 + 87 + # Security settings from the main branch 88 + NoNewPrivileges = true; 89 + ProtectSystem = "strict"; 90 + ProtectHome = true; 91 + PrivateTmp = true; 92 + ProtectKernelTunables = true; 93 + ProtectKernelModules = true; 94 + ProtectControlGroups = true; 95 + RestrictRealtime = true; 96 + RestrictSUIDSGID = true; 97 + RemoveIPC = true; 98 + PrivateMounts = true; 99 + }; 100 + }; 101 + 102 + # Updated firewall rule to parse the port from the new 'bind' option 103 + networking.firewall = mkIf cfg.openFirewall { 104 + allowedTCPPorts = [ (toInt (last (splitString ":" cfg.bind))) ]; 105 + }; 106 + }; 107 + }
-2
overlays/default.nix
··· 1 - { 2 - }
+3
pkgs/blacksky/default.nix
··· 1 + { pkgs, craneLib, ... }: 2 + 3 + import ./rsky { inherit pkgs craneLib; }
+194
pkgs/blacksky/rsky/default.nix
··· 1 + { pkgs, craneLib, ... }: 2 + 3 + { 4 + pds = craneLib.buildPackage rec { 5 + pname = "rsky-pds"; 6 + version = "0.1.0"; # Placeholder version, should be updated from rsky's Cargo.toml 7 + src = pkgs.fetchFromGitHub { 8 + owner = "blacksky-algorithms"; 9 + repo = "rsky"; 10 + rev = "main"; # Placeholder, should be updated to a specific commit or tag 11 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 12 + }; 13 + cargoHash = "sha256-0000000000000000000000000000000000000000000000000000000000000000="; 14 + 15 + # Build only the rsky-pds binary 16 + 17 + cargoBuildFlags = [ "--package rsky-pds --bin rsky-pds" ]; 18 + cargoInstallFlags = [ "--package rsky-pds --bin rsky-pds" ]; 19 + 20 + meta = with pkgs.lib; { 21 + description = "AT Protocol Personal Data Server (PDS) from rsky"; 22 + homepage = "https://github.com/atproto-nix/nur"; # Placeholder 23 + license = licenses.mit; # Placeholder 24 + maintainers = with maintainers; [ ]; # Placeholder 25 + }; 26 + }; 27 + 28 + relay = craneLib.buildPackage rec { 29 + pname = "rsky-relay"; 30 + version = "0.1.0"; # Placeholder version 31 + src = pkgs.fetchFromGitHub { 32 + owner = "blacksky-algorithms"; 33 + repo = "rsky"; 34 + rev = "main"; # Placeholder 35 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 36 + }; 37 + cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Placeholder 38 + 39 + cargoBuildFlags = [ "--package rsky-relay --bin rsky-relay" ]; 40 + cargoInstallFlags = [ "--package rsky-relay --bin rsky-relay" ]; 41 + 42 + meta = with pkgs.lib; { 43 + description = "AT Protocol Relay from rsky"; 44 + homepage = "https://github.com/atproto-nix/nur"; 45 + license = licenses.mit; 46 + maintainers = with maintainers; [ ]; 47 + }; 48 + }; 49 + 50 + feedgen = craneLib.buildPackage rec { 51 + pname = "rsky-feedgen"; 52 + version = "0.1.0"; # Placeholder version 53 + src = pkgs.fetchFromGitHub { 54 + owner = "blacksky-algorithms"; 55 + repo = "rsky"; 56 + rev = "main"; # Placeholder 57 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 58 + }; 59 + cargoHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Placeholder 60 + 61 + cargoBuildFlags = [ "--package rsky-feedgen --bin rsky-feedgen" ]; 62 + cargoInstallFlags = [ "--package rsky-feedgen --bin rsky-feedgen" ]; 63 + 64 + meta = with pkgs.lib; { 65 + description = "AT Protocol Feed Generator from rsky"; 66 + homepage = "https://github.com/atproto-nix/nur"; 67 + license = licenses.mit; 68 + maintainers = with maintainers; [ ]; 69 + }; 70 + }; 71 + 72 + satnav = craneLib.buildPackage rec { 73 + pname = "rsky-satnav"; 74 + version = "0.1.0"; # Placeholder version 75 + src = pkgs.fetchFromGitHub { 76 + owner = "blacksky-algorithms"; 77 + repo = "rsky"; 78 + rev = "main"; # Placeholder 79 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 80 + }; 81 + cargoHash = "sha256-0000000000000000000000000000000000000000000000000000000000000000="; # Placeholder, will be updated by Nix 82 + 83 + cargoBuildFlags = [ "--package rsky-satnav --bin rsky-satnav" ]; 84 + cargoInstallFlags = [ "--package rsky-satnav --bin rsky-satnav" ]; 85 + 86 + meta = with pkgs.lib; { 87 + description = "AT Protocol Satnav from rsky"; 88 + homepage = "https://github.com/atproto-nix/nur"; 89 + license = licenses.mit; 90 + maintainers = with maintainers; [ ]; 91 + }; 92 + }; 93 + 94 + firehose = craneLib.buildPackage rec { 95 + pname = "rsky-firehose"; 96 + version = "0.2.1"; # Version from Cargo.toml 97 + src = pkgs.fetchFromGitHub { 98 + owner = "blacksky-algorithms"; 99 + repo = "rsky"; 100 + rev = "main"; # Placeholder 101 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 102 + }; 103 + cargoHash = "sha256-0000000000000000000000000000000000000000000000000000000000000000="; # Placeholder 104 + 105 + cargoBuildFlags = [ "--package rsky-firehose --bin rsky-firehose" ]; 106 + cargoInstallFlags = [ "--package rsky-firehose --bin rsky-firehose" ]; 107 + 108 + meta = with pkgs.lib; { 109 + description = "AT Protocol Firehose subscriber from rsky"; 110 + homepage = "https://github.com/atproto-nix/nur"; 111 + license = licenses.mit; 112 + maintainers = with maintainers; [ ]; 113 + }; 114 + }; 115 + 116 + jetstreamSubscriber = craneLib.buildPackage rec { 117 + pname = "rsky-jetstream-subscriber"; 118 + version = "0.1.0"; # Version from Cargo.toml 119 + src = pkgs.fetchFromGitHub { 120 + owner = "blacksky-algorithms"; 121 + repo = "rsky"; 122 + rev = "main"; # Placeholder 123 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 124 + }; 125 + cargoHash = "sha256-0000000000000000000000000000000000000000000000000000000000000000="; # Placeholder 126 + 127 + cargoBuildFlags = [ "--package rsky-jetstream-subscriber --bin rsky-jetstream-subscriber" ]; 128 + cargoInstallFlags = [ "--package rsky-jetstream-subscriber --bin rsky-jetstream-subscriber" ]; 129 + 130 + meta = with pkgs.lib; { 131 + description = "AT Protocol Jetstream Subscriber from rsky"; 132 + homepage = "https://github.com/atproto-nix/nur"; 133 + license = licenses.mit; 134 + maintainers = with maintainers; [ ]; 135 + }; 136 + }; 137 + 138 + labeler = craneLib.buildPackage rec { 139 + pname = "rsky-labeler"; 140 + version = "0.1.3"; # Version from Cargo.toml 141 + src = pkgs.fetchFromGitHub { 142 + owner = "blacksky-algorithms"; 143 + repo = "rsky"; 144 + rev = "main"; # Placeholder 145 + hash = "sha256-nqBe20MCeNrSVxLVxiYc7iCFaBdf5Vf1p/i0D/aS8oY="; 146 + }; 147 + cargoHash = "sha256-0000000000000000000000000000000000000000000000000000000000000000="; # Placeholder 148 + 149 + cargoBuildFlags = [ "--package rsky-labeler --bin rsky-labeler" ]; 150 + cargoInstallFlags = [ "--package rsky-labeler --bin rsky-labeler" ]; 151 + 152 + meta = with pkgs.lib; { 153 + description = "AT Protocol Labeler from rsky"; 154 + homepage = "https://github.com/atproto-nix/nur"; 155 + license = licenses.mit; 156 + maintainers = with maintainers; [ ]; 157 + }; 158 + }; 159 + 160 + # community = pkgs.buildYarnPackage rec { 161 + # pname = "blacksky.community"; 162 + # version = "1.109.0"; # Version from package.json 163 + # 164 + # src = pkgs.fetchFromGitHub { 165 + # owner = "blacksky-algorithms"; 166 + # repo = "blacksky.community"; 167 + # # TODO: Update 'rev' to a specific commit hash or release tag for reproducible builds. 168 + # rev = "main"; 169 + # # TODO: Update 'hash' to the correct SHA256 hash of the fetched source. 170 + # # You can obtain the correct hash by setting it to an empty string, running nix-build, 171 + # # and then copying the hash from the error message. 172 + # hash = "sha256-W0mXqED9geNKJSPGJhUdJZ2voMOMDCXX1T4zn3GZKlY="; 173 + # }; 174 + # 175 + # yarnLock = "yarn.lock"; # Specify the yarn.lock file 176 + # 177 + # buildPhase = '' 178 + # yarn build-web 179 + # ''; 180 + # 181 + # installPhase = '' 182 + # mkdir -p $out/share/nginx/html 183 + # cp -r web-build/* $out/share/nginx/html 184 + # ''; 185 + # 186 + # meta = with pkgs.lib; { 187 + # description = "Blacksky Community Web Client"; 188 + # # Placeholder, update with actual homepage if available. 189 + # homepage = "https://github.com/blacksky-algorithms/blacksky.community"; 190 + # # Placeholder, add actual maintainers. 191 + # maintainers = with maintainers; [ ]; 192 + # }; 193 + # }; 194 + }
+81
pkgs/microcosm/default.nix
··· 1 + { pkgs, craneLib }: 2 + 3 + let 4 + src = pkgs.fetchFromGitHub { 5 + owner = "at-microcosm"; 6 + repo = "microcosm-rs"; 7 + rev = "b0a66a102261d0b4e8a90d34cec3421073a7b728"; 8 + sha256 = "sha256-swdAcsjRWnj9abmnrce5LzeKRK+LHm8RubCEIuk+53c="; 9 + }; 10 + 11 + commonEnv = { 12 + LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ]; 13 + OPENSSL_NO_VENDOR = "1"; 14 + OPENSSL_LIB_DIR = "${pkgs.lib.getLib pkgs.openssl}/lib"; 15 + OPENSSL_INCLUDE_DIR = "${pkgs.lib.getDev pkgs.openssl}/include"; 16 + BINDGEN_EXTRA_CLANG_ARGS = pkgs.lib.concatStringsSep " " [ 17 + "-I${pkgs.llvmPackages.libclang.lib}/lib/clang/${pkgs.lib.versions.major pkgs.llvmPackages.libclang.version}/include" 18 + "-I${pkgs.glibc.dev}" 19 + ]; 20 + ZSTD_SYS_USE_PKG_CONFIG = "1"; 21 + CC = "${pkgs.llvmPackages.clang}/bin/clang"; 22 + CXX = "${pkgs.llvmPackages.clang}/bin/clang++"; 23 + PKG_CONFIG_PATH = "${pkgs.zstd.dev}/lib/pkgconfig:${pkgs.lz4.dev}/lib/pkgconfig"; 24 + }; 25 + 26 + nativeInputs = with pkgs; 27 + [ 28 + pkg-config 29 + perl 30 + ]; 31 + 32 + buildInputs = with pkgs; 33 + [ 34 + zstd 35 + lz4 36 + rocksdb 37 + openssl 38 + sqlite 39 + ]; 40 + cargoArtifacts = craneLib.buildDepsOnly { 41 + inherit src; 42 + pname = "microcosm-rs-deps"; 43 + version = "0.1.0"; 44 + nativeBuildInputs = nativeInputs; 45 + buildInputs = buildInputs; 46 + env = commonEnv; 47 + tarFlags = "--no-same-owner"; 48 + }; 49 + 50 + members = [ 51 + "links" 52 + "constellation" 53 + "jetstream" 54 + "ufos" 55 + "ufos/fuzz" 56 + "spacedust" 57 + "who-am-i" 58 + "slingshot" 59 + "quasar" 60 + "pocket" 61 + "reflector" 62 + ]; 63 + buildPackage = member: 64 + let 65 + packageName = if member == "ufos/fuzz" then "ufos-fuzz" else member; 66 + in 67 + craneLib.buildPackage { 68 + inherit src cargoArtifacts; 69 + pname = packageName; 70 + version = "0.1.0"; 71 + cargoExtraArgs = "--package ${packageName}"; 72 + nativeBuildInputs = nativeInputs; 73 + buildInputs = buildInputs; 74 + tarFlags = "--no-same-owner"; 75 + env = commonEnv; 76 + }; 77 + 78 + packages = pkgs.lib.genAttrs members (member: buildPackage member); 79 + 80 + in 81 + packages
+28
tests/constellation-shell.nix
··· 1 + { pkgs }: 2 + 3 + pkgs.nixosTest { 4 + name = "constellation-shell"; 5 + 6 + nodes.machine = { ... }: 7 + { 8 + imports = [ ../modules/microcosm/constellation.nix ]; 9 + 10 + services.microcosm-constellation = { 11 + enable = true; 12 + jetstream = "us-east-1"; 13 + dataDir = "microcosm-constellation"; 14 + backend = "rocks"; 15 + }; 16 + }; 17 + 18 + # The corrected test script 19 + testScript = '' 20 + start_all() 21 + machine.wait_for_unit("microcosm-constellation.service") 22 + # The line below was removed. wait_for_unit is all you need. 23 + # machine.succeed("systemctl status --wait microcosm-constellation.service") 24 + 25 + # If you want to be extra sure, you can log the status 26 + machine.log(machine.succeed("systemctl status microcosm-constellation.service")) 27 + ''; 28 + }
+5
tests/default.nix
··· 1 + { pkgs }: 2 + { 3 + constellation = import ./constellation.nix { inherit pkgs; }; 4 + constellation-shell = import ./constellation-shell.nix { inherit pkgs; }; 5 + }