Genesis raises gitea correctly: host network, honest SQL, matched ROOT_URL

Fixes found raising the package registry end-to-end in the lab: seed gitea's DB
with plain psql statements (no \gexec, no $$ DO-blocks that clash with the
shell); run gitea on the host network so it reaches the substrate store and
answers where the builder looks; set gitea ROOT_URL to the machine's loopback so
npm's stored credential matches the tarball host; keep the pivot's passwords so a
re-run is the same run; create the admin without re-enabling must-change-password.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-16 14:11:36 +02:00
parent 1a7c9fdac3
commit 01c7730fb3
2 changed files with 90 additions and 29 deletions
+17 -2
View File
@@ -124,9 +124,12 @@ func (g *giteaAdmin) findTeam(ctx context.Context, org, team string) (int, error
// ensureUser creates a gitea user with the mesh's minted password, or resets that user's password
// when it already exists, so a rotation takes.
func (g *giteaAdmin) ensureUser(ctx context.Context, name, password string) error {
// A dotted domain: gitea's API validates the address, and an @localhost with no dot is refused
// as malformed — which comes back as the same 422 an "already exists" does, so the email is
// chosen to not provoke it and existence is checked directly rather than inferred from a status.
status, body, err := g.do(ctx, http.MethodPost, "/admin/users", map[string]any{
"username": name,
"email": name + "@localhost",
"email": name + "@packages.mesh.local",
"password": password,
"must_change_password": false,
})
@@ -136,7 +139,11 @@ func (g *giteaAdmin) ensureUser(ctx context.Context, name, password string) erro
if status/100 == 2 {
return nil
}
if status == http.StatusUnprocessableEntity || status == http.StatusConflict {
exists, err := g.userExists(ctx, name)
if err != nil {
return err
}
if exists {
// Already there: reset the password so this run's credential is the one that works.
reset, rbody, err := g.do(ctx, http.MethodPatch, "/admin/users/"+name,
map[string]any{"login_name": name, "password": password, "must_change_password": false})
@@ -151,6 +158,14 @@ func (g *giteaAdmin) ensureUser(ctx context.Context, name, password string) erro
return fmt.Errorf("could not create the gitea user %q: %d %s", name, status, body)
}
func (g *giteaAdmin) userExists(ctx context.Context, name string) (bool, error) {
status, _, err := g.do(ctx, http.MethodGet, "/users/"+name, nil)
if err != nil {
return false, err
}
return status == http.StatusOK, nil
}
func (g *giteaAdmin) addToTeam(ctx context.Context, teamID int, user string) error {
status, body, err := g.do(ctx, http.MethodPut, fmt.Sprintf("/teams/%d/members/%s", teamID, user), nil)
if err != nil {