ATproto Nix User Repo

refactor: Update Nix Flake, modules, and documentation

This commit refactors the repository, addressing the Nix Flake structure,
NixOS modules for Microcosm services, and documentation.

Key changes include:

- **Nix Flake and Packaging:**
- Modified `flake.nix` and `default.nix`.
- Removed `flake.lock` and `search` input.
- Added a `nurOverlay` for package integration.
- **NixOS Microcosm Modules:**
- Updated `constellation`, `pocket`, `reflector`, `slingshot`,
`spacedust`, `ufos`, and `who-am-i` modules with additional options,
systemd service configurations, user/group management,
tmpfiles, and security settings.
- Removed the `jetstream` module.
- Modified `quasar` to indicate its "Not Implemented" status.
- **Documentation:**
- Updated `AGENTS.md` with a structured project overview,
service usage details, and a Cachix cache section.
- Removed "Overlays" and "Reference Repositories" sections.
- **Project Structure:**
- Deleted `lib/default.nix` and `overlays/default.nix`.
- Removed `reference/` submodules (`blacksky.community`, `rsky`,
`tektite-cc-migration-service`).
- **Testing:**
- Added new test files (`tests/constellation-shell.nix`,
`tests/default.nix`) for the `constellation` service.

These changes modify the development and deployment of AT Protocol
services using Nix, adjust security configurations, and update documentation.

+77 -32
AGENTS.md
··· 6 6 7 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 8 9 - The repository is structured into three main parts: 9 + The repository is structured into two main parts: 10 10 11 11 1. **Packages (`pkgs`):** Contains Nix package definitions for core components. 12 12 2. **NixOS Modules (`modules`):** Provides NixOS modules for deploying and configuring the services. 13 - 3. **Overlays (`overlays`):** Offers Nix overlays for customizing packages. 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 14 65 15 - ## Core Components 66 + - **`who-am-i` (deprecated)**: An identity bridge for microcosm demos. It is being retired. 16 67 17 - ### Packages (`pkgs`) 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`) 18 74 19 - - **`pkgs/blacksky`:** A custom application or tool related to the AT Protocol ecosystem. 20 - - **`pkgs/bluesky`:** The official Bluesky application or a related utility. 21 - - **`pkgs/microcosm`:** A suite of services that form a personal data server (PDS) or a related AT Protocol service. 75 + ### Microcosm Libraries 22 76 23 - ### NixOS Modules (`modules/microcosm`) 77 + - **`links`**: A Rust library for parsing and extracting links (at-uris, DIDs, and URLs) from atproto records. 24 78 25 - The `microcosm` modules are designed to be composed together to create a running AT Protocol environment. Each module corresponds to a specific service: 79 + ### Blacksky 26 80 27 - - **`constellation`:** Service discovery and orchestration. 28 - - **`jetstream`:** Data streaming and processing. 29 - - **`pocket`:** Storage service. 30 - - **`quasar`:** Public API gateway. 31 - - **`reflector`:** Data mirroring and reflection. 32 - - **`slingshot`:** Deployment and release management. 33 - - **`spacedust`:** Maintenance and cleanup tasks. 34 - - **`ufos`:** Handling of unknown or unidentified requests. 35 - - **`who-am-i`:** Identity and authentication service. 81 + A suite of tools related to the AT Protocol ecosystem. 36 82 37 - ## Reference Repositories 83 + - `pds` 84 + - `relay` 85 + - `feedgen` 86 + - `satnav` 87 + - `firehose` 88 + - `jetstream-subscriber` 89 + - `labeler` 38 90 39 - The `reference/` directory contains source code for several key projects in the AT Protocol ecosystem. These are not directly part of the `nur-atproto` repository, but they provide important context. 91 + ## NixOS Modules 40 92 41 - - **`rsky`:** Blacksky's in-house Rust implementation of the atproto service stack. It includes the following services: 42 - - `relay`: An AT Protocol relay. 43 - - `pds`: An AT Protocol Personal Data Server. 44 - - `feedgen`: A feed generator, used with SAFEskies for moderation. 45 - - `pds-admin`: An administration tool for the PDS. 46 - - `satnav`: A tool for visually exploring AT Protocol repositories (work in progress). 47 - - **`tektite-cc-migration-service` (tektite):** A fully in-browser PDS account migration tool with blob management. It is used in production for migrating users to Blacksky's PDS. 48 - - **`blacksky.community`:** The web client for Blacksky. It is a fork of the official Bluesky social app with Blacksky-specific features and theming. 49 - - **`SAFEskies`:** A BlueSky feed management interface that enables secure moderation of custom feeds. 93 + The `microcosm` modules are designed to be composed together to create a running AT Protocol environment. Each module corresponds to a specific service. 50 94 51 95 ## Technology Stack 52 96 ··· 65 109 substituters = https://atproto.cachix.org 66 110 trusted-public-keys = atproto.cachix.org-1:s+32V2F3E5N6bY5fL2yV/s/Vb+9/a/a/a/a/a/a/a/a= 67 111 ``` 112 + **Note:** The `trusted-public-keys` value is a placeholder. I was unable to find the correct public key. 68 113 69 114 ## Interacting with the Project 70 115 ··· 72 117 73 118 ### Building Packages 74 119 75 - To build a package, use the `nix build` command with the corresponding flake output. For example, to build the `blacksky` package: 120 + To build a package, use the `nix build` command with the corresponding flake output. For example, to build the `constellation` package: 76 121 77 122 ```bash 78 - nix build .#blacksky 123 + nix build .#constellation 79 124 ``` 80 125 81 126 ### Development Environment ··· 110 155 2. **Identify the Components:** Determine which packages or modules are relevant to the user's goal. 111 156 3. **Use Nix Commands:** Execute the appropriate Nix commands (`nix build`, `nix develop`, etc.) to achieve the desired outcome. 112 157 4. **Verify the Results:** Check the output of the commands and ensure that the operation was successful. 113 - 5. **Provide Guidance:** If the user is deploying services, provide guidance on how to configure the NixOS modules. 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 }
-208
flake.lock
··· 1 - { 2 - "nodes": { 3 - "crane": { 4 - "locked": { 5 - "lastModified": 1758215636, 6 - "narHash": "sha256-8nkzkPbdxze8CxWhKWlcLbJEU1vfLM/nVqRlTy17V54=", 7 - "owner": "ipetkov", 8 - "repo": "crane", 9 - "rev": "a669fe77a8b0cd6f11419d89ea45a16691ca5121", 10 - "type": "github" 11 - }, 12 - "original": { 13 - "owner": "ipetkov", 14 - "repo": "crane", 15 - "type": "github" 16 - } 17 - }, 18 - "flake-utils": { 19 - "inputs": { 20 - "systems": "systems" 21 - }, 22 - "locked": { 23 - "lastModified": 1731533236, 24 - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 25 - "owner": "numtide", 26 - "repo": "flake-utils", 27 - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 28 - "type": "github" 29 - }, 30 - "original": { 31 - "owner": "numtide", 32 - "repo": "flake-utils", 33 - "type": "github" 34 - } 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 - "nixpkgs": { 81 - "locked": { 82 - "lastModified": 1758262103, 83 - "narHash": "sha256-aBGl3XEOsjWw6W3AHiKibN7FeoG73dutQQEqnd/etR8=", 84 - "owner": "NixOS", 85 - "repo": "nixpkgs", 86 - "rev": "12bd230118a1901a4a5d393f9f56b6ad7e571d01", 87 - "type": "github" 88 - }, 89 - "original": { 90 - "owner": "NixOS", 91 - "ref": "nixpkgs-unstable", 92 - "repo": "nixpkgs", 93 - "type": "github" 94 - } 95 - }, 96 - "nixpkgs_2": { 97 - "locked": { 98 - "lastModified": 1744536153, 99 - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", 100 - "owner": "NixOS", 101 - "repo": "nixpkgs", 102 - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", 103 - "type": "github" 104 - }, 105 - "original": { 106 - "owner": "NixOS", 107 - "ref": "nixpkgs-unstable", 108 - "repo": "nixpkgs", 109 - "type": "github" 110 - } 111 - }, 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 - "root": { 129 - "inputs": { 130 - "crane": "crane", 131 - "flake-utils": "flake-utils", 132 - "nixpkgs": "nixpkgs", 133 - "rust-overlay": "rust-overlay", 134 - "search": "search" 135 - } 136 - }, 137 - "rust-overlay": { 138 - "inputs": { 139 - "nixpkgs": "nixpkgs_2" 140 - }, 141 - "locked": { 142 - "lastModified": 1758422215, 143 - "narHash": "sha256-JvF5SXhp1wBHbfEVAWgJCDVSO8iknfDqXfqMch5YWg0=", 144 - "owner": "oxalica", 145 - "repo": "rust-overlay", 146 - "rev": "6f3988eb5885f1e2efa874a480d91de09a7f9f0b", 147 - "type": "github" 148 - }, 149 - "original": { 150 - "owner": "oxalica", 151 - "repo": "rust-overlay", 152 - "type": "github" 153 - } 154 - }, 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 - "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 - "locked": { 192 - "lastModified": 1681028828, 193 - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 194 - "owner": "nix-systems", 195 - "repo": "default", 196 - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 197 - "type": "github" 198 - }, 199 - "original": { 200 - "owner": "nix-systems", 201 - "repo": "default", 202 - "type": "github" 203 - } 204 - } 205 - }, 206 - "root": "root", 207 - "version": 7 208 - }
+23 -16
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; 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 = { 48 + homeManagerModules = { 42 49 microcosm = import ./modules/microcosm; 43 50 blacksky = import ./modules/blacksky; 44 - search = search.nixosModules.default; 45 51 }; 46 52 devShells.default = pkgs.mkShell { 47 - # todo? 53 + packages = with pkgs; [ deadnix nixpkgs-fmt ]; 48 54 }; 55 + tests = import ./tests { inherit pkgs; }; 49 56 } 50 57 ); 51 - } 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 - }
-1
modules/default.nix
··· 1 - {}
+115 -22
modules/microcosm/constellation.nix
··· 1 + # Defines the NixOS module for the Constellation service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-constellation; 7 - microcosmPkgs = pkgs.microcosm; # Access the packages we built 8 8 in 9 9 { 10 10 options.services.microcosm-constellation = { 11 - enable = mkEnableOption "Microcosm Constellation service"; 11 + enable = mkEnableOption "Constellation server"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 - default = microcosmPkgs.constellation; 15 - description = "The Microcosm Constellation package to use."; 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"; 16 35 }; 17 - port = mkOption { 18 - type = types.port; 19 - default = 8080; # Example default port 20 - description = "The port on which the Constellation service listens."; 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 + }; 21 58 }; 22 - # Add other service-specific options here (e.g., databaseUrl, logLevel) 23 59 }; 24 60 25 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 + 26 77 systemd.services.microcosm-constellation = { 27 - description = "Microcosm Constellation Service"; 78 + description = "Constellation Server - Global backlink index for AT Protocol"; 79 + wantedBy = [ "multi-user.target" ]; 28 80 after = [ "network.target" ]; 29 - wantedBy = [ "multi-user.target" ]; 81 + wants = [ "network.target" ]; 82 + 30 83 serviceConfig = { 31 - ExecStart = "${cfg.package}/bin/constellation --port ${toString cfg.port}"; # Example command 32 84 Restart = "always"; 33 - User = "microcosm-constellation"; # Create a dedicated user 85 + RestartSec = "10s"; 86 + 87 + # Use the static user and group 88 + User = "microcosm-constellation"; 34 89 Group = "microcosm-constellation"; 35 - # Add other systemd options as needed (e.g., working directory, environment variables) 36 - }; 37 - # Create user and group 38 - users.users.microcosm-constellation = { 39 - isSystem = true; 40 - group = "microcosm-constellation"; 41 - }; 42 - users.groups.microcosm-constellation = { 43 - isSystem = true; 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; 44 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 + ''; 45 138 }; 46 139 }; 47 140 }
+1 -2
modules/microcosm/default.nix
··· 6 6 ./spacedust.nix 7 7 ./slingshot.nix 8 8 ./ufos.nix 9 - ./jetstream.nix 10 9 ./who-am-i.nix 11 10 ./quasar.nix 12 11 ./pocket.nix 13 12 ./reflector.nix 14 13 ]; 15 - } 14 + }
-40
modules/microcosm/jetstream.nix
··· 1 - { config, lib, pkgs, ... }: 2 - 3 - with lib; 4 - 5 - let 6 - cfg = config.services.microcosm-jetstream; 7 - microcosmPkgs = pkgs.microcosm; 8 - in 9 - { 10 - options.services.microcosm-jetstream = { 11 - enable = mkEnableOption "Microcosm Jetstream service"; 12 - package = mkOption { 13 - type = types.package; 14 - default = microcosmPkgs.jetstream; 15 - description = "The Microcosm Jetstream package to use."; 16 - }; 17 - # Add other service-specific options here 18 - }; 19 - 20 - config = mkIf cfg.enable { 21 - systemd.services.microcosm-jetstream = { 22 - description = "Microcosm Jetstream Service"; 23 - after = [ "network.target" ]; 24 - wantedBy = [ "multi-user.target" ]; 25 - serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/jetstream"; # This command likely needs adjustment 27 - Restart = "always"; 28 - User = "microcosm-jetstream"; 29 - Group = "microcosm-jetstream"; 30 - }; 31 - users.users.microcosm-jetstream = { 32 - isSystem = true; 33 - group = "microcosm-jetstream"; 34 - }; 35 - users.groups.microcosm-jetstream = { 36 - isSystem = true; 37 - }; 38 - }; 39 - }; 40 - }
+36 -16
modules/microcosm/pocket.nix
··· 1 + # Defines the NixOS module for the Pocket service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-pocket; 7 - microcosmPkgs = pkgs.microcosm; 8 8 in 9 9 { 10 10 options.services.microcosm-pocket = { 11 - enable = mkEnableOption "Microcosm Pocket service"; 11 + enable = mkEnableOption "Pocket service"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 - default = microcosmPkgs.pocket; 15 - description = "The Microcosm Pocket package to use."; 15 + default = pkgs.nur.pocket; 16 + description = "The Pocket package to use."; 16 17 }; 17 - # Add other service-specific options here 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 + }; 18 29 }; 19 30 20 31 config = mkIf cfg.enable { 21 32 systemd.services.microcosm-pocket = { 22 - description = "Microcosm Pocket Service"; 33 + description = "Pocket Service"; 23 34 after = [ "network.target" ]; 24 35 wantedBy = [ "multi-user.target" ]; 36 + 25 37 serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/pocket"; # This command likely needs adjustment 38 + ExecStart = "${cfg.package}/bin/pocket --db /var/lib/${cfg.dbDir}/prefs.sqlite3 --domain ${cfg.domain}"; 27 39 Restart = "always"; 28 - User = "microcosm-pocket"; 29 - Group = "microcosm-pocket"; 30 - }; 31 - users.users.microcosm-pocket = { 32 - isSystem = true; 33 - group = "microcosm-pocket"; 34 - }; 35 - users.groups.microcosm-pocket = { 36 - isSystem = true; 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; 37 57 }; 38 58 }; 39 59 };
+10 -20
modules/microcosm/quasar.nix
··· 1 + # Defines the NixOS module for the Quasar service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-quasar; 7 - microcosmPkgs = pkgs.microcosm; 8 + microcosmPkgs = pkgs.nur.microcosm; 8 9 in 9 10 { 10 11 options.services.microcosm-quasar = { 11 - enable = mkEnableOption "Microcosm Quasar service"; 12 + enable = mkEnableOption "Quasar service"; 13 + 12 14 package = mkOption { 13 15 type = types.package; 14 16 default = microcosmPkgs.quasar; 15 - description = "The Microcosm Quasar package to use."; 17 + description = "The Quasar package to use."; 16 18 }; 17 - # Add other service-specific options here 18 19 }; 19 20 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 21 25 systemd.services.microcosm-quasar = { 22 - description = "Microcosm Quasar Service"; 23 - after = [ "network.target" ]; 24 - wantedBy = [ "multi-user.target" ]; 25 - serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/quasar"; # This command likely needs adjustment 27 - Restart = "always"; 28 - User = "microcosm-quasar"; 29 - Group = "microcosm-quasar"; 30 - }; 31 - users.users.microcosm-quasar = { 32 - isSystem = true; 33 - group = "microcosm-quasar"; 34 - }; 35 - users.groups.microcosm-quasar = { 36 - isSystem = true; 37 - }; 26 + description = "Microcosm Quasar Service (Not Implemented)"; 27 + serviceConfig.ExecStart = "${pkgs.coreutils}/bin/false"; 38 28 }; 39 29 }; 40 30 }
+44 -16
modules/microcosm/reflector.nix
··· 1 + # Defines the NixOS module for the Reflector service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-reflector; 7 - microcosmPkgs = pkgs.microcosm; 8 8 in 9 9 { 10 10 options.services.microcosm-reflector = { 11 - enable = mkEnableOption "Microcosm Reflector service"; 11 + enable = mkEnableOption "Reflector service"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 - default = microcosmPkgs.reflector; 15 - description = "The Microcosm Reflector package to use."; 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."; 16 22 }; 17 - # Add other service-specific options here 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 + }; 18 38 }; 19 39 20 40 config = mkIf cfg.enable { 21 41 systemd.services.microcosm-reflector = { 22 - description = "Microcosm Reflector Service"; 42 + description = "Reflector Service"; 23 43 after = [ "network.target" ]; 24 44 wantedBy = [ "multi-user.target" ]; 45 + 25 46 serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/reflector"; # This command likely needs adjustment 47 + ExecStart = "${cfg.package}/bin/reflector --id ${cfg.serviceId} --type ${cfg.serviceType} --service-endpoint ${cfg.serviceEndpoint} --domain ${cfg.domain}"; 27 48 Restart = "always"; 28 - User = "microcosm-reflector"; 29 - Group = "microcosm-reflector"; 30 - }; 31 - users.users.microcosm-reflector = { 32 - isSystem = true; 33 - group = "microcosm-reflector"; 34 - }; 35 - users.groups.microcosm-reflector = { 36 - isSystem = true; 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; 37 65 }; 38 66 }; 39 67 };
+69 -16
modules/microcosm/slingshot.nix
··· 1 + # Defines the NixOS module for the Slingshot service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-slingshot; 7 - microcosmPkgs = pkgs.microcosm; 8 8 in 9 9 { 10 10 options.services.microcosm-slingshot = { 11 - enable = mkEnableOption "Microcosm Slingshot service"; 11 + enable = mkEnableOption "Slingshot service"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 - default = microcosmPkgs.slingshot; 15 - description = "The Microcosm Slingshot package to use."; 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."; 16 52 }; 17 - # Add other service-specific options here 18 53 }; 19 54 20 55 config = mkIf cfg.enable { 21 56 systemd.services.microcosm-slingshot = { 22 - description = "Microcosm Slingshot Service"; 57 + description = "Slingshot Service"; 23 58 after = [ "network.target" ]; 24 59 wantedBy = [ "multi-user.target" ]; 60 + 25 61 serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/slingshot"; # This command likely needs adjustment 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 + ''; 27 72 Restart = "always"; 28 - User = "microcosm-slingshot"; 29 - Group = "microcosm-slingshot"; 30 - }; 31 - users.users.microcosm-slingshot = { 32 - isSystem = true; 33 - group = "microcosm-slingshot"; 34 - }; 35 - users.groups.microcosm-slingshot = { 36 - isSystem = true; 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; 37 90 }; 38 91 }; 39 92 };
+35 -16
modules/microcosm/spacedust.nix
··· 1 + # Defines the NixOS module for the Spacedust service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-spacedust; 7 - microcosmPkgs = pkgs.microcosm; 8 8 in 9 9 { 10 10 options.services.microcosm-spacedust = { 11 - enable = mkEnableOption "Microcosm Spacedust service"; 11 + enable = mkEnableOption "Spacedust service"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 - default = microcosmPkgs.spacedust; 15 - description = "The Microcosm Spacedust package to use."; 15 + default = pkgs.nur.spacedust; 16 + description = "The Spacedust package to use."; 16 17 }; 17 - # Add other service-specific options here 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 + }; 18 29 }; 19 30 20 31 config = mkIf cfg.enable { 21 32 systemd.services.microcosm-spacedust = { 22 - description = "Microcosm Spacedust Service"; 33 + description = "Spacedust Service"; 23 34 after = [ "network.target" ]; 24 35 wantedBy = [ "multi-user.target" ]; 36 + 25 37 serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/spacedust"; # This command likely needs adjustment 38 + ExecStart = "${cfg.package}/bin/spacedust --jetstream ${escapeShellArg cfg.jetstream} ${optionalString cfg.jetstreamNoZstd "--jetstream-no-zstd"}"; 27 39 Restart = "always"; 28 - User = "microcosm-spacedust"; 29 - Group = "microcosm-spacedust"; 30 - }; 31 - users.users.microcosm-spacedust = { 32 - isSystem = true; 33 - group = "microcosm-spacedust"; 34 - }; 35 - users.groups.microcosm-spacedust = { 36 - isSystem = true; 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; 37 56 }; 38 57 }; 39 58 };
+60 -16
modules/microcosm/ufos.nix
··· 1 + # Defines the NixOS module for the UFOs service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-ufos; 7 - microcosmPkgs = pkgs.microcosm; 8 8 in 9 9 { 10 10 options.services.microcosm-ufos = { 11 - enable = mkEnableOption "Microcosm UFOs service"; 11 + enable = mkEnableOption "UFOs service"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 - default = microcosmPkgs.ufos; 15 - description = "The Microcosm UFOs package to use."; 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."; 16 22 }; 17 - # Add other service-specific options here 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 + }; 18 53 }; 19 54 20 55 config = mkIf cfg.enable { 21 56 systemd.services.microcosm-ufos = { 22 - description = "Microcosm UFOs Service"; 57 + description = "UFOs Service"; 23 58 after = [ "network.target" ]; 24 59 wantedBy = [ "multi-user.target" ]; 60 + 25 61 serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/ufos"; # This command likely needs adjustment 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"}"; 27 63 Restart = "always"; 28 - User = "microcosm-ufos"; 29 - Group = "microcosm-ufos"; 30 - }; 31 - users.users.microcosm-ufos = { 32 - isSystem = true; 33 - group = "microcosm-ufos"; 34 - }; 35 - users.groups.microcosm-ufos = { 36 - isSystem = true; 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; 37 81 }; 38 82 }; 39 83 };
+82 -15
modules/microcosm/who-am-i.nix
··· 1 + # Defines the NixOS module for the Who-Am-I service 1 2 { config, lib, pkgs, ... }: 2 3 3 4 with lib; 4 5 5 6 let 6 7 cfg = config.services.microcosm-who-am-i; 7 - microcosmPkgs = pkgs.microcosm; 8 8 in 9 9 { 10 10 options.services.microcosm-who-am-i = { 11 - enable = mkEnableOption "Microcosm Who-Am-I service"; 11 + enable = mkEnableOption "Microcosm Who-Am-I service (deprecated)"; 12 + 12 13 package = mkOption { 13 14 type = types.package; 14 15 default = microcosmPkgs."who-am-i"; 15 - description = "The Microcosm Who-Am-I package to use."; 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."; 16 61 }; 17 - # Add other service-specific options here 18 62 }; 19 63 20 64 config = mkIf cfg.enable { 21 65 systemd.services.microcosm-who-am-i = { 22 - description = "Microcosm Who-Am-I Service"; 66 + description = "Microcosm Who-Am-I Service (deprecated)"; 23 67 after = [ "network.target" ]; 24 68 wantedBy = [ "multi-user.target" ]; 69 + 25 70 serviceConfig = { 26 - ExecStart = "${cfg.package}/bin/who-am-i"; # This command likely needs adjustment 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 + ''; 27 82 Restart = "always"; 28 - User = "microcosm-who-am-i"; 29 - Group = "microcosm-who-am-i"; 30 - }; 31 - users.users.microcosm-who-am-i = { 32 - isSystem = true; 33 - group = "microcosm-who-am-i"; 34 - }; 35 - users.groups.microcosm-who-am-i = { 36 - isSystem = true; 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; 37 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))) ]; 38 105 }; 39 106 }; 40 107 }
-5
overlays/default.nix
··· 1 - { 2 - # Add your overlays here 3 - # 4 - # my-overlay = import ./my-overlay; 5 - }
+2 -2
pkgs/blacksky/default.nix
··· 1 - { pkgs, craneLib, buildYarnPackage, ... }: 1 + { pkgs, craneLib, ... }: 2 2 3 - pkgs.callPackage ./rsky { inherit craneLib buildYarnPackage; } 3 + import ./rsky { inherit pkgs craneLib; }
+36 -38
pkgs/blacksky/rsky/default.nix
··· 1 - { pkgs, craneLib, buildYarnPackage }: 1 + { pkgs, craneLib, ... }: 2 2 3 3 { 4 4 pds = craneLib.buildPackage rec { ··· 157 157 }; 158 158 }; 159 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, update with actual license if available. Assuming MIT for now. 191 - license = licenses.mit; 192 - # Placeholder, add actual maintainers. 193 - maintainers = with maintainers; [ ]; 194 - }; 195 - }; 196 - } 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 + }
+1 -8
pkgs/microcosm/default.nix
··· 76 76 packages = pkgs.lib.genAttrs members (member: buildPackage member); 77 77 78 78 in 79 - packages // { 80 - default = pkgs.linkFarm "microcosm-rs" (pkgs.lib.mapAttrsToList (name: value: 81 - let 82 - linkName = if name == "ufos/fuzz" then "ufos-fuzz" else name; 83 - in 84 - { name = linkName; path = value; } 85 - ) packages); 86 - } 79 + 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 + }