+14
.tangled/workflows/build.yml
+14
.tangled/workflows/build.yml
+158
AGENTS.md
+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.
+1
-2
LICENSE
+1
-2
LICENSE
···
1
1
MIT License
2
2
3
-
Copyright (c) 2018 Francesco Gazzetta
3
+
Copyright (c) 2025 atproto-nix.org
4
4
5
5
Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
of this software and associated documentation files (the "Software"), to deal
···
19
19
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
SOFTWARE.
22
-
+12
README.md
+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
[](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
+
}
+3
-17
default.nix
+3
-17
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> { } }:
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
-
example-package = pkgs.callPackage ./pkgs/example-package { };
18
-
# some-qt5-package = pkgs.libsForQt5.callPackage ./pkgs/some-qt5-package { };
19
-
# ...
4
+
microcosm = pkgs.callPackage ./pkgs/microcosm { inherit craneLib; };
5
+
blacksky = pkgs.callPackage ./pkgs/blacksky { inherit craneLib; };
20
6
}
+89
-4
flake.lock
+89
-4
flake.lock
···
1
1
{
2
2
"nodes": {
3
+
"crane": {
4
+
"locked": {
5
+
"lastModified": 1759893430,
6
+
"narHash": "sha256-yAy4otLYm9iZ+NtQwTMEbqHwswSFUbhn7x826RR6djw=",
7
+
"owner": "ipetkov",
8
+
"repo": "crane",
9
+
"rev": "1979a2524cb8c801520bd94c38bb3d5692419d93",
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
+
},
3
36
"nixpkgs": {
4
37
"locked": {
5
-
"lastModified": 1712449641,
6
-
"narHash": "sha256-U9DDWMexN6o5Td2DznEgguh8TRIUnIl9levmit43GcI=",
38
+
"lastModified": 1760349414,
39
+
"narHash": "sha256-W4Ri1ZwYuNcBzqQQa7NnWfrv0wHMo7rduTWjIeU9dZk=",
40
+
"owner": "NixOS",
41
+
"repo": "nixpkgs",
42
+
"rev": "c12c63cd6c5eb34c7b4c3076c6a99e00fcab86ec",
43
+
"type": "github"
44
+
},
45
+
"original": {
46
+
"owner": "NixOS",
47
+
"ref": "nixpkgs-unstable",
48
+
"repo": "nixpkgs",
49
+
"type": "github"
50
+
}
51
+
},
52
+
"nixpkgs_2": {
53
+
"locked": {
54
+
"lastModified": 1744536153,
55
+
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
7
56
"owner": "NixOS",
8
57
"repo": "nixpkgs",
9
-
"rev": "600b15aea1b36eeb43833a50b0e96579147099ff",
58
+
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
10
59
"type": "github"
11
60
},
12
61
"original": {
···
18
67
},
19
68
"root": {
20
69
"inputs": {
21
-
"nixpkgs": "nixpkgs"
70
+
"crane": "crane",
71
+
"flake-utils": "flake-utils",
72
+
"nixpkgs": "nixpkgs",
73
+
"rust-overlay": "rust-overlay"
74
+
}
75
+
},
76
+
"rust-overlay": {
77
+
"inputs": {
78
+
"nixpkgs": "nixpkgs_2"
79
+
},
80
+
"locked": {
81
+
"lastModified": 1760409263,
82
+
"narHash": "sha256-GvcdHmY3nZnU6GnUkEG1a7pDZPgFcuN+zGv3OgvfPH0=",
83
+
"owner": "oxalica",
84
+
"repo": "rust-overlay",
85
+
"rev": "5694018463c2134e2369996b38deed41b1b9afc1",
86
+
"type": "github"
87
+
},
88
+
"original": {
89
+
"owner": "oxalica",
90
+
"repo": "rust-overlay",
91
+
"type": "github"
92
+
}
93
+
},
94
+
"systems": {
95
+
"locked": {
96
+
"lastModified": 1681028828,
97
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
98
+
"owner": "nix-systems",
99
+
"repo": "default",
100
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
101
+
"type": "github"
102
+
},
103
+
"original": {
104
+
"owner": "nix-systems",
105
+
"repo": "default",
106
+
"type": "github"
22
107
}
23
108
}
24
109
},
+56
-12
flake.nix
+56
-12
flake.nix
···
1
1
{
2
-
description = "My personal NUR repository";
3
-
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
4
-
outputs = { self, nixpkgs }:
5
-
let
6
-
forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed;
7
-
in
2
+
description = "ATproto NUR repository";
3
+
inputs = {
4
+
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
5
+
flake-utils.url = "github:numtide/flake-utils";
6
+
crane.url = "github:ipetkov/crane";
7
+
rust-overlay.url = "github:oxalica/rust-overlay";
8
+
};
9
+
10
+
outputs =
8
11
{
9
-
legacyPackages = forAllSystems (system: import ./default.nix {
10
-
pkgs = import nixpkgs { inherit system; };
11
-
});
12
-
packages = forAllSystems (system: nixpkgs.lib.filterAttrs (_: v: nixpkgs.lib.isDerivation v) self.legacyPackages.${system});
13
-
};
14
-
}
12
+
self,
13
+
nixpkgs,
14
+
flake-utils,
15
+
crane,
16
+
rust-overlay,
17
+
...
18
+
}:
19
+
flake-utils.lib.eachDefaultSystem (
20
+
system:
21
+
let
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
+
];
32
+
pkgs = import nixpkgs {
33
+
inherit system overlays;
34
+
};
35
+
rustVersion = pkgs.rust-bin.stable.latest.default;
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);
41
+
in
42
+
{
43
+
packages = allPackages;
44
+
nixosModules = {
45
+
microcosm = import ./modules/microcosm;
46
+
blacksky = import ./modules/blacksky;
47
+
};
48
+
homeManagerModules = {
49
+
microcosm = import ./modules/microcosm;
50
+
blacksky = import ./modules/blacksky;
51
+
};
52
+
devShells.default = pkgs.mkShell {
53
+
packages = with pkgs; [ deadnix nixpkgs-fmt ];
54
+
};
55
+
tests = import ./tests { inherit pkgs; };
56
+
}
57
+
);
58
+
}
-7
lib/default.nix
-7
lib/default.nix
+33
modules/blacksky/community.nix
+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
+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
+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
+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
+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
+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
+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
+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
+
}
-5
modules/default.nix
-5
modules/default.nix
+140
modules/microcosm/constellation.nix
+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
+14
modules/microcosm/default.nix
+60
modules/microcosm/pocket.nix
+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
+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
+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
+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
+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
+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
+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
+
}
-5
overlays/default.nix
-5
overlays/default.nix
+2
-8
pkgs/blacksky/default.nix
+2
-8
pkgs/blacksky/default.nix
···
1
-
{ stdenv }:
1
+
{ pkgs, craneLib, ... }:
2
2
3
-
stdenv.mkDerivation rec {
4
-
name = "example-package-${version}";
5
-
version = "1.0";
6
-
src = ./.;
7
-
buildPhase = "echo echo Hello World > example";
8
-
installPhase = "install -Dm755 example $out";
9
-
}
3
+
import ./rsky { inherit pkgs craneLib; }
+194
pkgs/blacksky/rsky/default.nix
+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
+
}
+80
-8
pkgs/microcosm/default.nix
+80
-8
pkgs/microcosm/default.nix
···
1
-
{ stdenv }:
1
+
{ pkgs, craneLib }:
2
2
3
-
stdenv.mkDerivation rec {
4
-
name = "example-package-${version}";
5
-
version = "1.0";
6
-
src = ./.;
7
-
buildPhase = "echo echo Hello World > example";
8
-
installPhase = "install -Dm755 example $out";
9
-
}
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
+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
+
}