WIP: move garage from operator ancilliary to hosting-provider (multi-tenant) #911

Closed
kiara wants to merge 1 commit from feat/garage-to-hosting-provider into main
Owner

Summary

  • Moves garage S3 storage from operator-level ancilliary to the hosting-provider layer, so all operators share one garage cluster
  • Operator app bucket/key names are transparently prefixed with the operator group name at the policy apply boundary (e.g. mastodon -> operator-mastodon)
  • Cross-group bucket/key requests are aggregated at eval time in hosts-common.nix and injected into the hosting-provider garage module via _module.args.aggregatedGarageRequests
  • Tests that bundle a local garage (mastodon/peertube/pixelfed service tests) are unaffected via the ancilliaryHosts ? garage guard
  • CI workflows regenerated: adds cd-hosting-provider-garage.yaml, nixosConfigurations-hosting-provider-garage.yaml; removes nixosConfigurations-operator-garage.yaml

Test plan

  • nix build --impure .#nixosConfigurations.hosting-provider-garage.config.system.build.toplevel -L builds clean
  • nix eval --impure .#nixosConfigurations.operator-mastodon.config.systemd.services.mastodon-web.environment.S3_BUCKET == "operator-mastodon"
  • nix build .#checks.x86_64-linux.test-mastodon-service -L passes
  • nix build .#checks.x86_64-linux.test-peertube-service -L passes
  • nix build .#checks.x86_64-linux.test-pixelfed-service -L passes
  • nix build .#checks.x86_64-linux.pre-commit -L passes

Disclaimer: I used a coding agent in the creation of this patch.

## Summary - Moves garage S3 storage from operator-level ancilliary to the hosting-provider layer, so all operators share one garage cluster - Operator app bucket/key names are transparently prefixed with the operator group name at the policy `apply` boundary (e.g. `mastodon` -> `operator-mastodon`) - Cross-group bucket/key requests are aggregated at eval time in `hosts-common.nix` and injected into the hosting-provider garage module via `_module.args.aggregatedGarageRequests` - Tests that bundle a local garage (mastodon/peertube/pixelfed service tests) are unaffected via the `ancilliaryHosts ? garage` guard - CI workflows regenerated: adds `cd-hosting-provider-garage.yaml`, `nixosConfigurations-hosting-provider-garage.yaml`; removes `nixosConfigurations-operator-garage.yaml` ## Test plan - [ ] `nix build --impure .#nixosConfigurations.hosting-provider-garage.config.system.build.toplevel -L` builds clean - [ ] `nix eval --impure .#nixosConfigurations.operator-mastodon.config.systemd.services.mastodon-web.environment.S3_BUCKET` == `"operator-mastodon"` - [ ] `nix build .#checks.x86_64-linux.test-mastodon-service -L` passes - [ ] `nix build .#checks.x86_64-linux.test-peertube-service -L` passes - [ ] `nix build .#checks.x86_64-linux.test-pixelfed-service -L` passes - [ ] `nix build .#checks.x86_64-linux.pre-commit -L` passes Disclaimer: I used a coding agent in the creation of this patch.
move garage from operator ancilliary to hosting-provider (multi-tenant)
All checks were successful
Nix flake completeness check / _complete (pull_request) Successful in 9s
checks-deployment-nixos-hosts / deployment-nixos-hosts (pull_request) Successful in 11s
checks-deployment-ssh-hosts / deployment-ssh-hosts (pull_request) Successful in 1m34s
checks-pre-commit / pre-commit (pull_request) Successful in 5s
checks-test-mastodon-service / test-mastodon-service (pull_request) Successful in 8s
checks-test-peertube-service / test-peertube-service (pull_request) Successful in 10s
checks-test-pixelfed-service / test-pixelfed-service (pull_request) Successful in 10s
devShells-default / default (pull_request) Successful in 6s
checks-deployment-tf-hosts / deployment-tf-hosts (pull_request) Successful in 2m31s
nix-unit-effects-common-lib / effects-common-lib (pull_request) Successful in 8s
nix-unit-effects-tf-common-conversion / effects-tf-common-conversion (pull_request) Successful in 8s
flake-show / apps-ssh (pull_request) Successful in 32s
nix-unit-lib-data-model / lib-data-model (pull_request) Successful in 7s
nix-unit-lib-function / lib-function (pull_request) Successful in 7s
nixosConfigurations-dev-combined / dev-combined (pull_request) Successful in 2s
nix-unit-lib-lib / lib-lib (pull_request) Successful in 7s
nixosConfigurations-dev-forgejo-actions-runner / dev-forgejo-actions-runner (pull_request) Successful in 2s
nixosConfigurations-dev-forgejo / dev-forgejo (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-combined / hosting-provider-combined (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-garage / hosting-provider-garage (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-incus / hosting-provider-incus (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-netbox / hosting-provider-netbox (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-openbao / hosting-provider-openbao (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-panel / hosting-provider-panel (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-terraform-backend / hosting-provider-terraform-backend (pull_request) Successful in 2s
nixosConfigurations-operator-authelia / operator-authelia (pull_request) Successful in 2s
nixosConfigurations-operator-combined / operator-combined (pull_request) Successful in 2s
nixosConfigurations-operator-mastodon / operator-mastodon (pull_request) Successful in 2s
nixosConfigurations-operator-peertube / operator-peertube (pull_request) Successful in 2s
nixosConfigurations-operator-pixelfed / operator-pixelfed (pull_request) Successful in 2s
checks-deployment-tf-incus-hosts / deployment-tf-incus-hosts (pull_request) Successful in 9m53s
checks-apps-tf / apps-tf (pull_request) Successful in 10m18s
checks-apps-tf-incus / apps-tf-incus (pull_request) Successful in 12m17s
checks-apps-panel / apps-panel (pull_request) Successful in 25m29s
6f9285659c
- `garage` is now a `hosting-provider` application at `garage.abundos.eu`;
  bucket/key names are transparently prefixed `<operator>-<name>` at
  policy `apply` time so multiple operator groups share one cluster
  without namespace collisions
- `resources/garage/default.nix`: add `tenant` option; rewrite bucket/key
  names in `rawRequests` and `applicationSide` via `prefixName`; add
  `rawRequests` field to the resource-type submodule; keep `mainConfig`
  intact for tests that bundle a local garage
- new `src/applications/hosting-provider/garage.nix`: NixOS module that
  hosts the garage server and an `ensure-garage` oneshot provisioning
  all operator buckets/keys from `aggregatedGarageRequests`
- `hosts-common.nix`: cross-group evaluation collects every operator
  app's `ancilliaryRequests.garageRequests` into `aggregatedGarageRequests`
  and injects it as `_module.args` into the hosting-provider's garage node;
  guarded by `!(ancilliaryHosts ? garage)` so test groups that bundle a
  local garage still take the existing code path unchanged
- operator app modules (mastodon, peertube, pixelfed) call
  `garage.bucketName` to obtain the physically-prefixed bucket name for
  environment variables
- `groups/hosting-provider.nix`: add `garage` machine entry; auto-import
  loop picks up the new application module automatically
- `groups/operator.nix`: remove `ancilliary.garage`; `machines.ancilliary`
  now contains only `authelia`
- CI workflows regenerated: add `cd-hosting-provider-garage.yaml` and
  `nixosConfigurations-hosting-provider-garage.yaml`; remove
  `nixosConfigurations-operator-garage.yaml`; add `garage.nix` to the
  `hosting-provider-combined` path filter

Assisted-by: Claude:claude-opus-4-7
Author
Owner

while this was intended as a PoC for setup interaction between machines between the operator vs hosting provider groups (on top of... it is actually supposed to be shared), it has instead mostly demonstrated conceptual challenges: whereas in the current setup operators' machines were presumed to rebuild in conjunction as requirements evolve, with ancilliary machines (so far garage) gathering requests from applications to assemble their NixOS configuration (src/resources/garage/default.nix's garageSide), the elephant in the room here is that machines part of the hosting provider group may not really be expected to rebuild with info gathered from operator-side machines - i.e. where the current PR intended to move garage.

for garage, that had been used in the current set-up to for applications' various requests invoke:

  • garage bucket create (#187)
  • garage bucket allow
  • garage bucket deny
  • garage bucket alias
  • garage bucket website --import
  • garage key import
  • aws put-bucket-cors

now, lacking the ability to handle these thru nixos config, that would leave approaches like:

  • LDAP (potentially relevant for authorization-related logic): not so far supported by garage, tho it is supported by ceph, which additionally is distributed unlike garage
  • terraform (providers with various support for different resources available for garage and ceph - in case of garage further being split by garage version)
  • otherwise ensuring the CLI commands are run on the shared machine
while this was intended as a PoC for setup interaction between machines between the operator vs hosting provider groups (on top of... it is actually supposed to be shared), it has instead mostly demonstrated conceptual challenges: whereas in the current setup operators' machines were presumed to rebuild in conjunction as requirements evolve, with ancilliary machines (so far garage) gathering requests from applications to assemble their NixOS configuration (`src/resources/garage/default.nix`'s `garageSide`), the elephant in the room here is that machines part of the hosting provider group may not really be expected to rebuild with info gathered from operator-side machines - i.e. where the current PR intended to move `garage`. for garage, that had been used in the current set-up to for applications' various requests invoke: - [ ] `garage bucket create` (#187) - [ ] `garage bucket allow` - [ ] `garage bucket deny` - [ ] `garage bucket alias` - [ ] `garage bucket website --import` - [ ] `garage key import` - [ ] `aws put-bucket-cors` now, lacking the ability to handle these thru nixos config, that would leave approaches like: - LDAP (potentially relevant for authorization-related logic): not so far supported by garage, tho it is supported by [ceph](https://docs.ceph.com/en/latest/radosgw/ldap-auth/), which additionally is distributed unlike garage - terraform (providers with various support for different resources available for [garage](https://registry.terraform.io/search/providers?q=garage) and [ceph](https://registry.terraform.io/search/providers?q=ceph) - in case of garage further being split by garage version) - otherwise ensuring the CLI commands are run on the shared machine
Member

LDAP would decouple creation of buckets from deploying of services IIUC? It would basically store "Application X needs buckets Y and Z," the Garage host would then make sure it creates the required buckets (how is this triggered, polling?).

Terraform would be run as part of a deployment, ensuring the buckets are deployed before the Application comes online, right?

How about the removal of buckets if an Operator decides to stop using an Application or migrates?

LDAP would decouple creation of buckets from deploying of services IIUC? It would basically store "Application X needs buckets Y and Z," the Garage host would then make sure it creates the required buckets (how is this triggered, polling?). Terraform would be run as part of a deployment, ensuring the buckets are deployed before the Application comes online, right? How about the removal of buckets if an Operator decides to stop using an Application or migrates?
Author
Owner

Terraform would be run as part of a deployment, ensuring the buckets are deployed before the Application comes online, right?

right.

How about the removal of buckets if an Operator decides to stop using an Application or migrates?

so, CRUD is what TF is about, for what it's worth, so should know how to clean up after itself, tho with migration i'm not positive yet if that's the way to do it.

if they stop using an application, another factor is user preference on what to do with the data, see #186.

LDAP would decouple creation of buckets from deploying of services IIUC? It would basically store "Application X needs buckets Y and Z," the Garage host would then make sure it creates the required buckets (how is this triggered, polling?).

i'd have imagined the CRUD things to be closer to terraform's thing than to LDAP's, which i would expect more like to handle the authorization bits

> Terraform would be run as part of a deployment, ensuring the buckets are deployed before the Application comes online, right? right. > How about the removal of buckets if an Operator decides to stop using an Application or migrates? so, CRUD is what TF is about, for what it's worth, so should know how to clean up after itself, tho with migration i'm not positive yet if that's the way to do it. if they stop using an application, another factor is user preference on what to do with the data, see #186. > LDAP would decouple creation of buckets from deploying of services IIUC? It would basically store "Application X needs buckets Y and Z," the Garage host would then make sure it creates the required buckets (how is this triggered, polling?). i'd have imagined the CRUD things to be closer to terraform's thing than to LDAP's, which i would expect more like to handle the authorization bits
Author
Owner

superseded by #1124.

superseded by #1124.
kiara closed this pull request 2026-06-25 22:11:39 +02:00
All checks were successful
Nix flake completeness check / _complete (pull_request) Successful in 9s
checks-deployment-nixos-hosts / deployment-nixos-hosts (pull_request) Successful in 11s
checks-deployment-ssh-hosts / deployment-ssh-hosts (pull_request) Successful in 1m34s
checks-pre-commit / pre-commit (pull_request) Successful in 5s
checks-test-mastodon-service / test-mastodon-service (pull_request) Successful in 8s
checks-test-peertube-service / test-peertube-service (pull_request) Successful in 10s
checks-test-pixelfed-service / test-pixelfed-service (pull_request) Successful in 10s
devShells-default / default (pull_request) Successful in 6s
checks-deployment-tf-hosts / deployment-tf-hosts (pull_request) Successful in 2m31s
nix-unit-effects-common-lib / effects-common-lib (pull_request) Successful in 8s
nix-unit-effects-tf-common-conversion / effects-tf-common-conversion (pull_request) Successful in 8s
flake-show / apps-ssh (pull_request) Successful in 32s
nix-unit-lib-data-model / lib-data-model (pull_request) Successful in 7s
nix-unit-lib-function / lib-function (pull_request) Successful in 7s
nixosConfigurations-dev-combined / dev-combined (pull_request) Successful in 2s
nix-unit-lib-lib / lib-lib (pull_request) Successful in 7s
nixosConfigurations-dev-forgejo-actions-runner / dev-forgejo-actions-runner (pull_request) Successful in 2s
nixosConfigurations-dev-forgejo / dev-forgejo (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-combined / hosting-provider-combined (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-garage / hosting-provider-garage (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-incus / hosting-provider-incus (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-netbox / hosting-provider-netbox (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-openbao / hosting-provider-openbao (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-panel / hosting-provider-panel (pull_request) Successful in 2s
nixosConfigurations-hosting-provider-terraform-backend / hosting-provider-terraform-backend (pull_request) Successful in 2s
nixosConfigurations-operator-authelia / operator-authelia (pull_request) Successful in 2s
nixosConfigurations-operator-combined / operator-combined (pull_request) Successful in 2s
nixosConfigurations-operator-mastodon / operator-mastodon (pull_request) Successful in 2s
nixosConfigurations-operator-peertube / operator-peertube (pull_request) Successful in 2s
nixosConfigurations-operator-pixelfed / operator-pixelfed (pull_request) Successful in 2s
checks-deployment-tf-incus-hosts / deployment-tf-incus-hosts (pull_request) Successful in 9m53s
checks-apps-tf / apps-tf (pull_request) Successful in 10m18s
checks-apps-tf-incus / apps-tf-incus (pull_request) Successful in 12m17s
checks-apps-panel / apps-panel (pull_request) Successful in 25m29s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
fediversity/fediversity!911
No description provided.