68 lines
2.4 KiB
Go
68 lines
2.4 KiB
Go
// mesh-build-image: the image build module (novox/hq ADR 0487, ADR 0466 §1, ADR 0469; design 47 R4c-9, issue 1703). A
|
|
// tools bundle the node's runtime launches as the module's own account (runs-as). It builds a module's `image`
|
|
// artifact from the Dockerfile in the module's own directory with buildah, rootless, in a user namespace of its
|
|
// account and with no container runtime socket, and pushes a merged trunk commit's image to the registry from its
|
|
// own process once the build has ended. It refuses a step only when buildah cannot be run or the account has no
|
|
// subordinate ranges, and its health is then unhealthy. What it says, it says on stderr; stdout is the MCP channel.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/user"
|
|
"strings"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
// The directories the module's manifest places outside its home (ADR 0466 §1): the workspaces, and buildah's image
|
|
// store, so nothing of the home is in a build.
|
|
const (
|
|
WorkDir = "/var/lib/mesh-build-image-work"
|
|
StoreDir = "/var/lib/mesh-build-image-store"
|
|
)
|
|
|
|
func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, "[mesh-build-image] "+format+"\n", a...) }
|
|
|
|
func main() {
|
|
ctx := context.Background()
|
|
m := &Module{
|
|
Node: strings.TrimSpace(os.Getenv("MESH_NODE")),
|
|
Steps: stdio.State(delivery.StepsState).Put,
|
|
ReadSteps: readOf(stdio.State(delivery.StepsState)),
|
|
Ctx: ctx,
|
|
Say: logf,
|
|
Work: WorkDir,
|
|
Store: StoreDir,
|
|
}
|
|
m.Floor = floorOf(m.Node)
|
|
if u, err := user.Current(); err == nil {
|
|
m.Home, m.Account, m.UID = u.HomeDir, u.Username, u.Uid
|
|
}
|
|
m.RegistryFile = m.Home + "/registry"
|
|
m.Settings = m.Home + "/settings.json"
|
|
m.Run = StepRunner(m.Home)
|
|
// Outside a launch by the runtime — a build, a check — there is no node and no state to write.
|
|
if m.Node != "" {
|
|
go m.Start(ctx)
|
|
}
|
|
go startKeeper(ctx)
|
|
// Every state it keeps, said on the bus before it serves (ADR 0495 §2; issue 1790).
|
|
if err := keepStates(); err != nil {
|
|
logf("announcing the states it keeps: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
steps := m.StepTools()
|
|
puller := m.Puller(steps, nil)
|
|
if m.Node != "" {
|
|
// The seat's asks, pulled once Serve has the runtime's channel; a pull before it is said and tried again.
|
|
go func() { _ = puller.Pull(ctx) }()
|
|
}
|
|
if err := stdio.Serve("", append(m.Tools(steps), m.SeatTools(puller)...)); err != nil {
|
|
logf("%v", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|