+2
-5
.tangled/workflows/build.yml
+2
-5
.tangled/workflows/build.yml
···
1
1
when:
2
2
- event: ["push", "pull_request"]
3
-
branch: ["feat-blsky-bsky-pkgs"]
3
+
branch: ["main"]
4
4
5
5
engine: "nixery"
6
-
7
-
environment:
8
-
9
6
10
7
dependencies:
11
8
nixpkgs:
···
14
11
steps:
15
12
- name: Build Nix packages
16
13
command: |
17
-
nix build .#default
14
+
nix build .#default
+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.
+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
+
}
+4
-19
default.nix
+4
-19
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
-
bluesky = pkgs.callPackage ./pkgs/bluesky {
18
-
buildGoModule = pkgs.buildGoModule;
19
-
fetchFromGitHub = pkgs.fetchFromGitHub;
20
-
};
21
-
}
4
+
microcosm = pkgs.callPackage ./pkgs/microcosm { inherit craneLib; };
5
+
blacksky = pkgs.callPackage ./pkgs/blacksky { inherit craneLib; };
6
+
}
+10
-106
flake.lock
+10
-106
flake.lock
···
2
2
"nodes": {
3
3
"crane": {
4
4
"locked": {
5
-
"lastModified": 1758758545,
6
-
"narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=",
5
+
"lastModified": 1759893430,
6
+
"narHash": "sha256-yAy4otLYm9iZ+NtQwTMEbqHwswSFUbhn7x826RR6djw=",
7
7
"owner": "ipetkov",
8
8
"repo": "crane",
9
-
"rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364",
9
+
"rev": "1979a2524cb8c801520bd94c38bb3d5692419d93",
10
10
"type": "github"
11
11
},
12
12
"original": {
···
33
33
"type": "github"
34
34
}
35
35
},
36
-
"flake-utils_2": {
37
-
"inputs": {
38
-
"systems": "systems_2"
39
-
},
40
-
"locked": {
41
-
"lastModified": 1731533236,
42
-
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
43
-
"owner": "numtide",
44
-
"repo": "flake-utils",
45
-
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
46
-
"type": "github"
47
-
},
48
-
"original": {
49
-
"owner": "numtide",
50
-
"repo": "flake-utils",
51
-
"type": "github"
52
-
}
53
-
},
54
-
"ixx": {
55
-
"inputs": {
56
-
"flake-utils": [
57
-
"search",
58
-
"flake-utils"
59
-
],
60
-
"nixpkgs": [
61
-
"search",
62
-
"nixpkgs"
63
-
]
64
-
},
65
-
"locked": {
66
-
"lastModified": 1754860581,
67
-
"narHash": "sha256-EM0IE63OHxXCOpDHXaTyHIOk2cNvMCGPqLt/IdtVxgk=",
68
-
"owner": "NuschtOS",
69
-
"repo": "ixx",
70
-
"rev": "babfe85a876162c4acc9ab6fb4483df88fa1f281",
71
-
"type": "github"
72
-
},
73
-
"original": {
74
-
"owner": "NuschtOS",
75
-
"ref": "v0.1.1",
76
-
"repo": "ixx",
77
-
"type": "github"
78
-
}
79
-
},
80
36
"nixpkgs": {
81
37
"locked": {
82
-
"lastModified": 1758446476,
83
-
"narHash": "sha256-5rdAi7CTvM/kSs6fHe1bREIva5W3TbImsto+dxG4mBo=",
38
+
"lastModified": 1760349414,
39
+
"narHash": "sha256-W4Ri1ZwYuNcBzqQQa7NnWfrv0wHMo7rduTWjIeU9dZk=",
84
40
"owner": "NixOS",
85
41
"repo": "nixpkgs",
86
-
"rev": "a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0",
42
+
"rev": "c12c63cd6c5eb34c7b4c3076c6a99e00fcab86ec",
87
43
"type": "github"
88
44
},
89
45
"original": {
···
109
65
"type": "github"
110
66
}
111
67
},
112
-
"nixpkgs_3": {
113
-
"locked": {
114
-
"lastModified": 1758035966,
115
-
"narHash": "sha256-qqIJ3yxPiB0ZQTT9//nFGQYn8X/PBoJbofA7hRKZnmE=",
116
-
"owner": "NixOS",
117
-
"repo": "nixpkgs",
118
-
"rev": "8d4ddb19d03c65a36ad8d189d001dc32ffb0306b",
119
-
"type": "github"
120
-
},
121
-
"original": {
122
-
"owner": "NixOS",
123
-
"ref": "nixos-unstable",
124
-
"repo": "nixpkgs",
125
-
"type": "github"
126
-
}
127
-
},
128
68
"root": {
129
69
"inputs": {
130
70
"crane": "crane",
131
71
"flake-utils": "flake-utils",
132
72
"nixpkgs": "nixpkgs",
133
-
"rust-overlay": "rust-overlay",
134
-
"search": "search"
73
+
"rust-overlay": "rust-overlay"
135
74
}
136
75
},
137
76
"rust-overlay": {
···
139
78
"nixpkgs": "nixpkgs_2"
140
79
},
141
80
"locked": {
142
-
"lastModified": 1758767687,
143
-
"narHash": "sha256-znUulOqcL/Kkdr7CkyIi8Z1pTGXpi54Xg2FmlyJmv4A=",
81
+
"lastModified": 1760409263,
82
+
"narHash": "sha256-GvcdHmY3nZnU6GnUkEG1a7pDZPgFcuN+zGv3OgvfPH0=",
144
83
"owner": "oxalica",
145
84
"repo": "rust-overlay",
146
-
"rev": "b8bcc09d4f627f4e325408f6e7a85c3ac31f0eeb",
85
+
"rev": "5694018463c2134e2369996b38deed41b1b9afc1",
147
86
"type": "github"
148
87
},
149
88
"original": {
···
152
91
"type": "github"
153
92
}
154
93
},
155
-
"search": {
156
-
"inputs": {
157
-
"flake-utils": "flake-utils_2",
158
-
"ixx": "ixx",
159
-
"nixpkgs": "nixpkgs_3"
160
-
},
161
-
"locked": {
162
-
"lastModified": 1758662783,
163
-
"narHash": "sha256-igrxT+/MnmcftPOHEb+XDwAMq3Xg1Xy7kVYQaHhPlAg=",
164
-
"owner": "NuschtOS",
165
-
"repo": "search",
166
-
"rev": "7d4c0fc4ffe3bd64e5630417162e9e04e64b27a4",
167
-
"type": "github"
168
-
},
169
-
"original": {
170
-
"owner": "NuschtOS",
171
-
"repo": "search",
172
-
"type": "github"
173
-
}
174
-
},
175
94
"systems": {
176
-
"locked": {
177
-
"lastModified": 1681028828,
178
-
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
179
-
"owner": "nix-systems",
180
-
"repo": "default",
181
-
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
182
-
"type": "github"
183
-
},
184
-
"original": {
185
-
"owner": "nix-systems",
186
-
"repo": "default",
187
-
"type": "github"
188
-
}
189
-
},
190
-
"systems_2": {
191
95
"locked": {
192
96
"lastModified": 1681028828,
193
97
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+24
-17
flake.nix
+24
-17
flake.nix
···
5
5
flake-utils.url = "github:numtide/flake-utils";
6
6
crane.url = "github:ipetkov/crane";
7
7
rust-overlay.url = "github:oxalica/rust-overlay";
8
-
search.url = "github:NuschtOS/search";
9
8
};
10
9
11
10
outputs =
···
15
14
flake-utils,
16
15
crane,
17
16
rust-overlay,
18
-
search,
19
17
...
20
18
}:
21
19
flake-utils.lib.eachDefaultSystem (
22
20
system:
23
21
let
24
-
overlays = [ (import rust-overlay) ];
22
+
nurOverlay = final: prev: {
23
+
nur = import ./default.nix {
24
+
pkgs = final;
25
+
craneLib = (crane.mkLib final).overrideToolchain rustVersion;
26
+
};
27
+
};
28
+
overlays = [
29
+
(import rust-overlay)
30
+
nurOverlay
31
+
];
25
32
pkgs = import nixpkgs {
26
33
inherit system overlays;
27
34
};
28
35
rustVersion = pkgs.rust-bin.stable.latest.default;
29
-
craneLib = (crane.mkLib pkgs).overrideToolchain rustVersion;
30
-
31
-
nurPackages = import ./default.nix {
32
-
inherit pkgs craneLib;
33
-
};
34
-
packages = pkgs.lib.filterAttrs (n: v: pkgs.lib.isDerivation v) nurPackages;
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);
35
41
in
36
42
{
37
-
packages = packages // {
38
-
default = packages.bluesky;
39
-
search = search.packages.${system}.default;
40
-
};
41
-
legacyPackages = packages;
43
+
packages = allPackages;
42
44
nixosModules = {
43
-
nur-atproto = import ./modules;
44
-
search = search.nixosModules.default;
45
+
microcosm = import ./modules/microcosm;
46
+
blacksky = import ./modules/blacksky;
47
+
};
48
+
homeManagerModules = {
49
+
microcosm = import ./modules/microcosm;
50
+
blacksky = import ./modules/blacksky;
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
-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
+
}
-45
modules/bluesky/beemo.nix
-45
modules/bluesky/beemo.nix
···
1
-
{ lib, config, pkgs, ... }:
2
-
3
-
with lib;
4
-
5
-
let
6
-
cfg = config.services.beemo;
7
-
in
8
-
{
9
-
options.services.beemo = {
10
-
enable = mkEnableOption "beemo";
11
-
12
-
package = mkOption {
13
-
type = types.package;
14
-
default = pkgs.bluesky;
15
-
description = "The beemo package to use.";
16
-
};
17
-
18
-
slackWebhookUrl = mkOption {
19
-
type = types.str;
20
-
description = "Slack webhook URL.";
21
-
};
22
-
};
23
-
24
-
config = mkIf cfg.enable {
25
-
systemd.services.beemo-notify-reports = {
26
-
description = "beemo notify-reports service";
27
-
after = [ "network.target" ];
28
-
wantedBy = [ "multi-user.target" ];
29
-
serviceConfig = {
30
-
ExecStart = "${cfg.package}/bin/beemo notify-reports --slack-webhook-url ${cfg.slackWebhookUrl}";
31
-
Restart = "on-failure";
32
-
};
33
-
};
34
-
35
-
systemd.services.beemo-notify-mentions = {
36
-
description = "beemo notify-mentions service";
37
-
after = [ "network.target" ];
38
-
wantedBy = [ "multi-user.target" ];
39
-
serviceConfig = {
40
-
ExecStart = "${cfg.package}/bin/beemo notify-mentions --slack-webhook-url ${cfg.slackWebhookUrl}";
41
-
Restart = "on-failure";
42
-
};
43
-
};
44
-
};
45
-
}
-30
modules/bluesky/bigsky.nix
-30
modules/bluesky/bigsky.nix
···
1
-
{ lib, config, pkgs, ... }:
2
-
3
-
with lib;
4
-
5
-
let
6
-
cfg = config.services.bigsky;
7
-
in
8
-
{
9
-
options.services.bigsky = {
10
-
enable = mkEnableOption "bigsky";
11
-
12
-
package = mkOption {
13
-
type = types.package;
14
-
default = pkgs.bluesky;
15
-
description = "The bigsky package to use.";
16
-
};
17
-
};
18
-
19
-
config = mkIf cfg.enable {
20
-
systemd.services.bigsky = {
21
-
description = "bigsky service";
22
-
after = [ "network.target" ];
23
-
wantedBy = [ "multi-user.target" ];
24
-
serviceConfig = {
25
-
ExecStart = "${cfg.package}/bin/bigsky";
26
-
Restart = "on-failure";
27
-
};
28
-
};
29
-
};
30
-
}
-12
modules/bluesky/default.nix
-12
modules/bluesky/default.nix
-95
modules/bluesky/hepa.nix
-95
modules/bluesky/hepa.nix
···
1
-
{ lib, config, pkgs, ... }:
2
-
3
-
with lib;
4
-
5
-
let
6
-
cfg = config.services.hepa;
7
-
in
8
-
{
9
-
options.services.hepa = {
10
-
enable = mkEnableOption "hepa";
11
-
12
-
package = mkOption {
13
-
type = types.package;
14
-
default = pkgs.bluesky;
15
-
description = "The hepa package to use.";
16
-
};
17
-
18
-
atpRelayHost = mkOption {
19
-
type = types.str;
20
-
default = "wss://bsky.network";
21
-
description = "ATP relay host.";
22
-
};
23
-
24
-
atpPlcHost = mkOption {
25
-
type = types.str;
26
-
default = "https://plc.directory";
27
-
description = "ATP PLC host.";
28
-
};
29
-
30
-
atpBskyHost = mkOption {
31
-
type = types.str;
32
-
default = "https://public.api.bsky.app";
33
-
description = "ATP bsky host.";
34
-
};
35
-
36
-
atpOzoneHost = mkOption {
37
-
type = types.str;
38
-
default = "https://mod.bsky.app";
39
-
description = "ATP ozone host.";
40
-
};
41
-
42
-
ozoneDid = mkOption {
43
-
type = types.str;
44
-
description = "Ozone DID.";
45
-
};
46
-
47
-
ozoneAdminToken = mkOption {
48
-
type = types.str;
49
-
description = "Ozone admin token.";
50
-
};
51
-
52
-
atpPdsHost = mkOption {
53
-
type = types.str;
54
-
default = "https://bsky.social";
55
-
description = "ATP PDS host.";
56
-
};
57
-
58
-
pdsAdminToken = mkOption {
59
-
type = types.str;
60
-
description = "PDS admin token.";
61
-
};
62
-
63
-
redisUrl = mkOption {
64
-
type = types.str;
65
-
description = "Redis URL.";
66
-
};
67
-
68
-
hiveaiApiToken = mkOption {
69
-
type = types.str;
70
-
description = "Hive AI API token.";
71
-
};
72
-
73
-
abyssHost = mkOption {
74
-
type = types.str;
75
-
description = "Abyss host.";
76
-
};
77
-
78
-
abyssPassword = mkOption {
79
-
type = types.str;
80
-
description = "Abyss password.";
81
-
};
82
-
};
83
-
84
-
config = mkIf cfg.enable {
85
-
systemd.services.hepa = {
86
-
description = "hepa service";
87
-
after = [ "network.target" ];
88
-
wantedBy = [ "multi-user.target" ];
89
-
serviceConfig = {
90
-
ExecStart = "${cfg.package}/bin/hepa run --atp-relay-host ${cfg.atpRelayHost} --atp-plc-host ${cfg.atpPlcHost} --atp-bsky-host ${cfg.atpBskyHost} --atp-ozone-host ${cfg.atpOzoneHost} --ozone-did ${cfg.ozoneDid} --ozone-admin-token ${cfg.ozoneAdminToken} --atp-pds-host ${cfg.atpPdsHost} --pds-admin-token ${cfg.pdsAdminToken} --redis-url ${cfg.redisUrl} --hiveai-api-token ${cfg.hiveaiApiToken} --abyss-host ${cfg.abyssHost} --abyss-password ${cfg.abyssPassword}";
91
-
Restart = "on-failure";
92
-
};
93
-
};
94
-
};
95
-
}
-83
modules/bluesky/palomar.nix
-83
modules/bluesky/palomar.nix
···
1
-
{ lib, config, pkgs, ... }:
2
-
3
-
with lib;
4
-
5
-
let
6
-
cfg = config.services.palomar;
7
-
in
8
-
{
9
-
options.services.palomar = {
10
-
enable = mkEnableOption "palomar";
11
-
12
-
package = mkOption {
13
-
type = types.package;
14
-
default = pkgs.bluesky;
15
-
description = "The palomar package to use.";
16
-
};
17
-
18
-
elasticCertFile = mkOption {
19
-
type = types.str;
20
-
description = "Elasticsearch cert file.";
21
-
};
22
-
23
-
elasticInsecureSsl = mkOption {
24
-
type = types.bool;
25
-
default = false;
26
-
description = "Elasticsearch insecure SSL.";
27
-
};
28
-
29
-
elasticUsername = mkOption {
30
-
type = types.str;
31
-
default = "admin";
32
-
description = "Elasticsearch username.";
33
-
};
34
-
35
-
elasticPassword = mkOption {
36
-
type = types.str;
37
-
default = "0penSearch-Pal0mar";
38
-
description = "Elasticsearch password.";
39
-
};
40
-
41
-
elasticHosts = mkOption {
42
-
type = types.str;
43
-
default = "http://localhost:9200";
44
-
description = "Elasticsearch hosts.";
45
-
};
46
-
47
-
esPostIndex = mkOption {
48
-
type = types.str;
49
-
default = "palomar_post";
50
-
description = "Elasticsearch post index.";
51
-
};
52
-
53
-
esProfileIndex = mkOption {
54
-
type = types.str;
55
-
default = "palomar_profile";
56
-
description = "Elasticsearch profile index.";
57
-
};
58
-
59
-
atpRelayHost = mkOption {
60
-
type = types.str;
61
-
default = "wss://bsky.network";
62
-
description = "ATP relay host.";
63
-
};
64
-
65
-
atpPlcHost = mkOption {
66
-
type = types.str;
67
-
default = "https://plc.directory";
68
-
description = "ATP PLC host.";
69
-
};
70
-
};
71
-
72
-
config = mkIf cfg.enable {
73
-
systemd.services.palomar = {
74
-
description = "palomar service";
75
-
after = [ "network.target" ];
76
-
wantedBy = [ "multi-user.target" ];
77
-
serviceConfig = {
78
-
ExecStart = "${cfg.package}/bin/palomar run --elastic-cert-file ${cfg.elasticCertFile} --elastic-insecure-ssl ${toString cfg.elasticInsecureSsl} --elastic-username ${cfg.elasticUsername} --elastic-password ${cfg.elasticPassword} --elastic-hosts ${cfg.elasticHosts} --es-post-index ${cfg.esPostIndex} --es-profile-index ${cfg.esProfileIndex} --atp-relay-host ${cfg.atpRelayHost} --atp-plc-host ${cfg.atpPlcHost}";
79
-
Restart = "on-failure";
80
-
};
81
-
};
82
-
};
83
-
}
-41
modules/bluesky/relay.nix
-41
modules/bluesky/relay.nix
···
1
-
{ lib, config, pkgs, ... }:
2
-
3
-
with lib;
4
-
5
-
let
6
-
cfg = config.services.relay;
7
-
in
8
-
{
9
-
options.services.relay = {
10
-
enable = mkEnableOption "relay";
11
-
12
-
package = mkOption {
13
-
type = types.package;
14
-
default = pkgs.bluesky;
15
-
description = "The relay package to use.";
16
-
};
17
-
18
-
adminPassword = mkOption {
19
-
type = types.str;
20
-
description = "Admin password for the relay.";
21
-
};
22
-
23
-
plcHost = mkOption {
24
-
type = types.str;
25
-
default = "https://plc.directory";
26
-
description = "PLC host for the relay.";
27
-
};
28
-
};
29
-
30
-
config = mkIf cfg.enable {
31
-
systemd.services.relay = {
32
-
description = "relay service";
33
-
after = [ "network.target" ];
34
-
wantedBy = [ "multi-user.target" ];
35
-
serviceConfig = {
36
-
ExecStart = "${cfg.package}/bin/relay serve --admin-password ${cfg.adminPassword} --plc-host ${cfg.plcHost}";
37
-
Restart = "on-failure";
38
-
};
39
-
};
40
-
};
41
-
}
-61
modules/bluesky/sonar.nix
-61
modules/bluesky/sonar.nix
···
1
-
{ lib, config, pkgs, ... }:
2
-
3
-
with lib;
4
-
5
-
let
6
-
cfg = config.services.sonar;
7
-
in
8
-
{
9
-
options.services.sonar = {
10
-
enable = mkEnableOption "sonar";
11
-
12
-
package = mkOption {
13
-
type = types.package;
14
-
default = pkgs.bluesky;
15
-
description = "The sonar package to use.";
16
-
};
17
-
18
-
wsUrl = mkOption {
19
-
type = types.str;
20
-
default = "wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos";
21
-
description = "Websocket URL.";
22
-
};
23
-
24
-
logLevel = mkOption {
25
-
type = types.str;
26
-
default = "info";
27
-
description = "Log level.";
28
-
};
29
-
30
-
port = mkOption {
31
-
type = types.port;
32
-
default = 8345;
33
-
description = "Metrics server port.";
34
-
};
35
-
36
-
maxQueueSize = mkOption {
37
-
type = types.int;
38
-
default = 10;
39
-
description = "Max queue size.";
40
-
};
41
-
42
-
cursorFile = mkOption {
43
-
type = types.str;
44
-
default = "/var/lib/sonar/cursor.json";
45
-
description = "Cursor file.";
46
-
};
47
-
};
48
-
49
-
config = mkIf cfg.enable {
50
-
systemd.services.sonar = {
51
-
description = "sonar service";
52
-
after = [ "network.target" ];
53
-
wantedBy = [ "multi-user.target" ];
54
-
serviceConfig = {
55
-
ExecStart = "${cfg.package}/bin/sonar --ws-url ${cfg.wsUrl} --log-level ${cfg.logLevel} --port ${toString cfg.port} --max-queue-size ${toString cfg.maxQueueSize} --cursor-file ${cfg.cursorFile}";
56
-
Restart = "on-failure";
57
-
StateDirectory = "sonar";
58
-
};
59
-
};
60
-
};
61
-
}
+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
+
}
+3
pkgs/blacksky/default.nix
+3
pkgs/blacksky/default.nix
+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
+
}
+7
-41
pkgs/bluesky/default.nix
+7
-41
pkgs/bluesky/default.nix
···
1
-
{ lib, buildGoModule, fetchFromGitHub }:
2
-
3
-
buildGoModule rec {
4
-
pname = "indigo";
5
-
version = "unstable-2023-09-24";
6
-
7
-
src = fetchFromGitHub {
8
-
owner = "bluesky-social";
9
-
repo = "indigo";
10
-
rev = "b4dd6383c76ffe205afe5407a027bb90a7461b12";
11
-
sha256 = "sha256-e0Y/k1RBnFg8Z9VT7rxuZeyvJo2MZIOHQJbo9prTaoQ=";
12
-
};
13
-
14
-
vendorHash = "sha256-7mYvgvR0tZdEnUgUYzKv6d2QyeXXnrFgVwY8/4UM3oU=";
15
-
16
-
subPackages = [
17
-
"cmd/goat"
18
-
"cmd/gosky"
19
-
"cmd/bigsky"
20
-
"cmd/relay"
21
-
"cmd/beemo"
22
-
"cmd/lexgen"
23
-
"cmd/stress"
24
-
"cmd/fakermaker"
25
-
"cmd/hepa"
26
-
"cmd/supercollider"
27
-
"cmd/sonar"
28
-
"cmd/palomar"
29
-
];
30
-
31
-
buildFlags = [ "-mod=vendor" ];
32
-
33
-
preBuild = ''
34
-
export HOME=$TMPDIR
35
-
'';
1
+
{ stdenv }:
36
2
37
-
meta = with lib; {
38
-
description = "Go source code for Bluesky's atproto services";
39
-
homepage = "https://github.com/bluesky-social/indigo";
40
-
license = licenses.mit;
41
-
maintainers = with maintainers; [ ];
42
-
};
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";
43
9
}
+81
pkgs/microcosm/default.nix
+81
pkgs/microcosm/default.nix
···
1
+
{ pkgs, craneLib }:
2
+
3
+
let
4
+
src = pkgs.fetchFromGitHub {
5
+
owner = "at-microcosm";
6
+
repo = "microcosm-rs";
7
+
rev = "b0a66a102261d0b4e8a90d34cec3421073a7b728";
8
+
sha256 = "sha256-swdAcsjRWnj9abmnrce5LzeKRK+LHm8RubCEIuk+53c=";
9
+
};
10
+
11
+
commonEnv = {
12
+
LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
13
+
OPENSSL_NO_VENDOR = "1";
14
+
OPENSSL_LIB_DIR = "${pkgs.lib.getLib pkgs.openssl}/lib";
15
+
OPENSSL_INCLUDE_DIR = "${pkgs.lib.getDev pkgs.openssl}/include";
16
+
BINDGEN_EXTRA_CLANG_ARGS = pkgs.lib.concatStringsSep " " [
17
+
"-I${pkgs.llvmPackages.libclang.lib}/lib/clang/${pkgs.lib.versions.major pkgs.llvmPackages.libclang.version}/include"
18
+
"-I${pkgs.glibc.dev}"
19
+
];
20
+
ZSTD_SYS_USE_PKG_CONFIG = "1";
21
+
CC = "${pkgs.llvmPackages.clang}/bin/clang";
22
+
CXX = "${pkgs.llvmPackages.clang}/bin/clang++";
23
+
PKG_CONFIG_PATH = "${pkgs.zstd.dev}/lib/pkgconfig:${pkgs.lz4.dev}/lib/pkgconfig";
24
+
};
25
+
26
+
nativeInputs = with pkgs;
27
+
[
28
+
pkg-config
29
+
perl
30
+
];
31
+
32
+
buildInputs = with pkgs;
33
+
[
34
+
zstd
35
+
lz4
36
+
rocksdb
37
+
openssl
38
+
sqlite
39
+
];
40
+
cargoArtifacts = craneLib.buildDepsOnly {
41
+
inherit src;
42
+
pname = "microcosm-rs-deps";
43
+
version = "0.1.0";
44
+
nativeBuildInputs = nativeInputs;
45
+
buildInputs = buildInputs;
46
+
env = commonEnv;
47
+
tarFlags = "--no-same-owner";
48
+
};
49
+
50
+
members = [
51
+
"links"
52
+
"constellation"
53
+
"jetstream"
54
+
"ufos"
55
+
"ufos/fuzz"
56
+
"spacedust"
57
+
"who-am-i"
58
+
"slingshot"
59
+
"quasar"
60
+
"pocket"
61
+
"reflector"
62
+
];
63
+
buildPackage = member:
64
+
let
65
+
packageName = if member == "ufos/fuzz" then "ufos-fuzz" else member;
66
+
in
67
+
craneLib.buildPackage {
68
+
inherit src cargoArtifacts;
69
+
pname = packageName;
70
+
version = "0.1.0";
71
+
cargoExtraArgs = "--package ${packageName}";
72
+
nativeBuildInputs = nativeInputs;
73
+
buildInputs = buildInputs;
74
+
tarFlags = "--no-same-owner";
75
+
env = commonEnv;
76
+
};
77
+
78
+
packages = pkgs.lib.genAttrs members (member: buildPackage member);
79
+
80
+
in
81
+
packages
+28
tests/constellation-shell.nix
+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
+
}