Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/swarm-controller/src/forge/meta_repo.rs
atlas 5950363a10 swarm-controller: render, lock and commit internal/meta
A new update_meta node renders internal/meta's flake.nix with
hive-meta-flake, the renderer hive-c0re uses: hyperhive pinned to its
forge main, each custom agent a hive places pinned to its agent-configs
main, all over https, and the swarm-wide values from
SWARM_CONTROLLER_META_FLAKE (set by swarm-controller.nix from
services.hyperhive.swarm.*). The swarm builder locks it, and the
controller commits flake.nix and flake.lock in one commit and gives
every hive's forge account read on the repo. A render equal to the
committed flake.nix sends no lock and commits nothing.

It runs at start, when hyperhive's main moves, before the deploy of a
merged config PR and before the first deploy of a new agent; those
deploys now wait for it. agent_web_port moves into hive-meta-flake so
both callers compute the same port; hive-c0re re-exports it.

On deploy: internal/meta appears on the forge and follows every merge.
No hive builds from it yet.

Refs #4857
2026-10-24 21:13:24 +02:00

77 lines
2.5 KiB
Rust

//! `internal/meta` on the forge: the repo the swarm meta flake is committed to
//! (`crate::meta_flake`), and the read grant each hive's account holds on it.
use anyhow::{Context, Result};
use base64::Engine as _;
use forgejo_api::structs::{
AddCollaboratorOptionPermission, ChangeFileOperation, ChangeFileOperationOperation,
ChangeFilesOptions,
};
use super::objects::SHARED_ORG;
use super::{Client, DefaultBranchFiles};
use crate::meta_flake::{META_REPO, MetaFile, MetaForge};
impl MetaForge for Client {
async fn head_files(
&self,
owner: &str,
repo: &str,
paths: &[&str],
) -> Result<Option<DefaultBranchFiles>> {
self.default_branch_files(owner, repo, paths).await
}
async fn ensure_meta_repo(&self) -> Result<()> {
self.create_shared_repo(SHARED_ORG, META_REPO, true).await
}
async fn grant_meta_read(&self, login: &str) -> Result<()> {
self.add_collaborator_to(
SHARED_ORG,
META_REPO,
login,
AddCollaboratorOptionPermission::Read,
)
.await
}
async fn commit_meta(&self, message: &str, files: Vec<MetaFile>) -> Result<()> {
let ops: Vec<ChangeFileOperation> = files
.into_iter()
.map(|f| ChangeFileOperation {
content: Some(base64::engine::general_purpose::STANDARD.encode(f.bytes)),
from_path: None,
operation: if f.sha.is_some() {
ChangeFileOperationOperation::Update
} else {
ChangeFileOperationOperation::Create
},
path: f.path.to_owned(),
sha: f.sha,
})
.collect();
self.api
.call(|api| {
api.repo_change_files(
SHARED_ORG,
META_REPO,
ChangeFilesOptions {
author: None,
branch: None,
committer: None,
dates: None,
files: ops.clone(),
force_overwrite_new_branch: None,
message: Some(message.to_owned()),
new_branch: None,
signoff: None,
},
)
.into_future()
})
.await
.with_context(|| format!("commit to {SHARED_ORG}/{META_REPO}"))?;
Ok(())
}
}