mesh/delivery superseded: a newer head of the same pull request
mesh/check failed: unit: git.novox.be/novox/mesh-catalog/chec… | b85d65b53f9e on 3bec357968da | judged by the candidate's mesh-build-go at f4ff9305030a
556 lines
16 KiB
JSON
556 lines
16 KiB
JSON
{
|
|
"module": "gitea",
|
|
"version": "1",
|
|
"moved": true,
|
|
"requires": [
|
|
"postgres-database",
|
|
"route",
|
|
"secret"
|
|
],
|
|
"contributes": {
|
|
"postgres-database": {
|
|
"name": "gitea"
|
|
},
|
|
"route": {
|
|
"web": {
|
|
"label": "git",
|
|
"endpoint": "web"
|
|
},
|
|
"internal-api-refused": {
|
|
"label": "git",
|
|
"path": "/api/internal",
|
|
"deny": true,
|
|
"priority": 100000
|
|
}
|
|
}
|
|
},
|
|
"binds": {
|
|
"postgres-database": "${dir:state}/database.json",
|
|
"route": "${dir:state}/route.json"
|
|
},
|
|
"secrets": {
|
|
"postgres-database": "${dir:state}/database.secret",
|
|
"secret": {
|
|
"internal-token": "${dir:state}/internal-token.secret",
|
|
"admin": "${dir:state}/admin.secret"
|
|
}
|
|
},
|
|
"capabilities": [
|
|
"container-runtime"
|
|
],
|
|
"emits": [
|
|
"repo.created",
|
|
"issue.opened",
|
|
"pull.merged",
|
|
"pull.updated",
|
|
"pull.closed",
|
|
"forge.push",
|
|
"forge.create",
|
|
"forge.delete",
|
|
"forge.fork",
|
|
"forge.status",
|
|
"forge.pull-request.opened",
|
|
"forge.pull-request.reopened",
|
|
"forge.pull-request.synchronized",
|
|
"forge.pull-request.edited",
|
|
"forge.pull-request.closed",
|
|
"forge.pull-request.merged",
|
|
"forge.pull-request.labeled",
|
|
"forge.pull-request.unlabeled",
|
|
"forge.pull-request.assigned",
|
|
"forge.pull-request.unassigned",
|
|
"forge.pull-request.reviewed",
|
|
"forge.pull-request.review-requested",
|
|
"forge.pull-request.commented",
|
|
"forge.pull-request.changed",
|
|
"forge.issue-comment.created",
|
|
"forge.issue-comment.edited",
|
|
"forge.issue-comment.deleted",
|
|
"forge.issues.opened",
|
|
"forge.issues.reopened",
|
|
"forge.issues.closed",
|
|
"forge.issues.edited",
|
|
"forge.issues.labeled",
|
|
"forge.issues.unlabeled",
|
|
"forge.issues.assigned",
|
|
"forge.issues.unassigned",
|
|
"forge.issues.changed",
|
|
"forge.release.published",
|
|
"forge.release.updated",
|
|
"forge.release.deleted",
|
|
"forge.release.changed",
|
|
"forge.repository.created",
|
|
"forge.repository.deleted",
|
|
"forge.repository.changed",
|
|
"forge.wiki.changed",
|
|
"forge.other"
|
|
],
|
|
"consumes": [
|
|
"mesh-controller.checked"
|
|
],
|
|
"listens": [
|
|
{
|
|
"name": "web",
|
|
"port": 3000,
|
|
"protocol": "tcp",
|
|
"from": "mesh",
|
|
"why": "the forge, over http"
|
|
},
|
|
{
|
|
"name": "ssh",
|
|
"port": 22,
|
|
"protocol": "tcp",
|
|
"from": "mesh",
|
|
"why": "git over ssh, gitea's own unmodified sshd. Published on the machine's own side at 222, the mesh's fixed public convention — not 22, which the machine's own daemon holds and a module does not take"
|
|
},
|
|
{
|
|
"name": "forge-events",
|
|
"port": 3047,
|
|
"protocol": "tcp",
|
|
"from": "machine",
|
|
"why": "the forge's system webhook, every event signed with a secret the module keeps, from the forge's container on the docker bridge to the module's receiver at the bridge's gateway 172.17.0.1 (novox/hq issue 729)"
|
|
}
|
|
],
|
|
"serves": {
|
|
"npm-package-registry": {
|
|
"scheme": "http",
|
|
"port": 3000,
|
|
"npm-path": "/api/packages/novox/npm/",
|
|
"public-root": "https://${bound:route:name-web}/api/packages/novox/npm/"
|
|
},
|
|
"git": {
|
|
"scheme": "http",
|
|
"port": 3000
|
|
}
|
|
},
|
|
"receives": {
|
|
"npm-package-registry": "${dir:grants}/npm.json"
|
|
},
|
|
"grants": {
|
|
"npm-package-registry": "${dir:grants}"
|
|
},
|
|
"claims": [
|
|
{
|
|
"name": "npm-package-registry",
|
|
"scope": "mesh"
|
|
},
|
|
{
|
|
"name": "git",
|
|
"scope": "mesh"
|
|
}
|
|
],
|
|
"data": {
|
|
"own": [
|
|
{
|
|
"id": "data",
|
|
"path": "${dir:data}",
|
|
"class": "valuable",
|
|
"why": "every repository, its issues and attachments, and the package registry"
|
|
}
|
|
],
|
|
"consumers": {
|
|
"npm-package-registry": {
|
|
"class": "rebuildable",
|
|
"in": "data",
|
|
"why": "a consumer's packages are published again from its source"
|
|
}
|
|
}
|
|
},
|
|
"config": {
|
|
"url": {
|
|
"type": "string",
|
|
"description": "The address the module's tools reach the forge at, as a URL; unset, the code falls back to its environment, else this machine's gitea on its port.",
|
|
"trusted": true,
|
|
"default": ""
|
|
},
|
|
"agent-read-teams": {
|
|
"type": "object",
|
|
"description": "The read teams of the agents' forge accounts (ADR 0365 clause 3): each team by name, {\"<team>\": {\"repos\": [\"<owner>/<repo>\", ...], \"members\": [\"<node>\", ...]}}. The forge gets a team agent-read-<team> that reads only, with exactly those repositories and the accounts agent-<node>; a team taken out of the value is emptied. Nothing else on the forge is touched; an agent account is in no team until it is listed here.",
|
|
"trusted": true,
|
|
"default": {}
|
|
},
|
|
"keep-main-rules": {
|
|
"type": "boolean",
|
|
"description": "Whether the module keeps main's branch protection as the mesh wants it. True: every ten minutes, and at the start, main's rule in every repository of the organisation novox is put to no push and the tools' account alone merging, and each apply of the `repositories` value narrows the main rule of the repositories it lists and swaps mesh/merge-gate for mesh/check in those it does not. False (the default): the module changes no existing repository's branch protection, whoever set it at the forge; a repository listed in `repositories` that does not exist is still made, with its first protection.",
|
|
"trusted": true,
|
|
"default": false
|
|
},
|
|
"repositories": {
|
|
"type": "object",
|
|
"description": "The repositories of the organisation novox the mesh holds (ADR 0428): each by name, {\"<name>\": {\"private\": true, \"description\": \"...\"}}. One that does not exist is made by the module's setup login under its own account, its main protected and given a first commit (a README naming the description), its rule narrowed to no push and the tools' merge requiring mesh/check, and only then moved into the organisation; one that exists only has main's rule put right, mesh/check in place of mesh/merge-gate and mesh/repo-check and its other statuses kept (a main requiring mesh/repo-check alone keeps it). Every other repository whose main requires mesh/merge-gate has the two swapped for mesh/check; nothing else of a repository out of the value is touched.",
|
|
"trusted": true,
|
|
"default": {}
|
|
}
|
|
},
|
|
"facts": {
|
|
"forge-host": {
|
|
"path": "/etc/gitea/forge-host",
|
|
"template": "{{range .Machines}}{{if eq .Name $.Node}}{{.FQDN}}{{end}}{{end}}\n"
|
|
}
|
|
},
|
|
"resources": [
|
|
{
|
|
"id": "mesh-state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"place": "mesh",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "runtime-state",
|
|
"type": "directory",
|
|
"path": "${dir:mesh-state}/state",
|
|
"mode": "0700",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "forge-patches",
|
|
"type": "directory",
|
|
"path": "/var/lib/mesh/forge-patches",
|
|
"mode": "0733",
|
|
"owner": "${machine:account}",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "state",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"place": ".",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "grants",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "server-env",
|
|
"type": "file",
|
|
"path": "${dir:state}/server.env",
|
|
"mode": "0600",
|
|
"template": "files/server.env"
|
|
},
|
|
{
|
|
"id": "data",
|
|
"type": "directory",
|
|
"mode": "0700",
|
|
"owner": "1000:1000",
|
|
"unknown": "program"
|
|
},
|
|
{
|
|
"id": "server",
|
|
"type": "container",
|
|
"health": {
|
|
"kind": "http",
|
|
"endpoint": "web",
|
|
"path": "/api/healthz",
|
|
"status": 200,
|
|
"needs": "postgres-database"
|
|
},
|
|
"name": "gitea",
|
|
"image": "gitea/gitea@sha256:87a67ee09d3ae0d1df5fda5dcda3e2a1f9236a45b0a59025d6e00e46adc43bef",
|
|
"env": {
|
|
"DB_TYPE": "postgres",
|
|
"USER_UID": "1000",
|
|
"USER_GID": "1000"
|
|
},
|
|
"env-file": [
|
|
"${dir:state}/server.env"
|
|
],
|
|
"ports": [
|
|
"3000",
|
|
"222:22"
|
|
],
|
|
"volumes": [
|
|
"${dir:data}:/data"
|
|
],
|
|
"secrets-in-environment": "gitea honours GITEA__database__PASSWD__FILE and GITEA__security__INTERNAL_TOKEN__FILE; convertible, awaiting a bed that proves it",
|
|
"logging": "journald"
|
|
},
|
|
{
|
|
"id": "admin-bootstrap",
|
|
"type": "container",
|
|
"name": "mesh-gitea-admin",
|
|
"image": "gitea/gitea@sha256:87a67ee09d3ae0d1df5fda5dcda3e2a1f9236a45b0a59025d6e00e46adc43bef",
|
|
"run-once": true,
|
|
"env": {
|
|
"USER_UID": "1000",
|
|
"USER_GID": "1000",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin"
|
|
},
|
|
"env-file": [
|
|
"${dir:state}/server.env"
|
|
],
|
|
"volumes": [
|
|
"${dir:data}:/data",
|
|
"${dir:state}/admin.secret:/run/secrets/admin:ro"
|
|
],
|
|
"args": [
|
|
"/bin/sh",
|
|
"-c",
|
|
"su-exec git gitea admin user create --admin --username \"$MESH_GITEA_ADMIN_USER\" --email mesh-admin@localhost --password \"$(cat /run/secrets/admin)\" --must-change-password=false || true"
|
|
],
|
|
"secrets-in-environment": "gitea honours GITEA__database__PASSWD__FILE and GITEA__security__INTERNAL_TOKEN__FILE; convertible, awaiting a bed that proves it"
|
|
},
|
|
{
|
|
"id": "origins",
|
|
"type": "file",
|
|
"path": "${dir:mesh-state}/origins",
|
|
"mode": "0644",
|
|
"template": "files/origins"
|
|
},
|
|
{
|
|
"id": "runtime-config",
|
|
"type": "file",
|
|
"path": "${dir:mesh-state}/config.json",
|
|
"mode": "0600",
|
|
"template": "files/config.json",
|
|
"merge": "json",
|
|
"takes-config": [
|
|
"url",
|
|
"keep-main-rules"
|
|
]
|
|
},
|
|
{
|
|
"id": "agent-teams-file",
|
|
"type": "file",
|
|
"path": "${dir:mesh-state}/agent-teams.json",
|
|
"mode": "0600",
|
|
"template": "files/agent-teams.json",
|
|
"merge": "json",
|
|
"takes-config": [
|
|
"agent-read-teams"
|
|
]
|
|
},
|
|
{
|
|
"id": "repositories-file",
|
|
"type": "file",
|
|
"path": "${dir:mesh-state}/repositories.json",
|
|
"mode": "0600",
|
|
"template": "files/repositories.json"
|
|
},
|
|
{
|
|
"id": "consumers",
|
|
"type": "file",
|
|
"path": "${dir:state}/consumers.json",
|
|
"mode": "0600",
|
|
"template": "files/consumers.json"
|
|
},
|
|
{
|
|
"id": "agent-teams",
|
|
"type": "process",
|
|
"name": "gitea-agent-teams",
|
|
"artifact": "agent-teams",
|
|
"run": [
|
|
"./agent-teams"
|
|
],
|
|
"run-once": true,
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin",
|
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
|
"MESH_AGENT_TEAMS_FILE": "${dir:mesh-state}/agent-teams.json"
|
|
},
|
|
"restart-on": [
|
|
"agent-teams-file"
|
|
]
|
|
},
|
|
{
|
|
"id": "repositories",
|
|
"type": "process",
|
|
"name": "gitea-repositories",
|
|
"artifact": "repositories",
|
|
"run": [
|
|
"./repositories",
|
|
"sync"
|
|
],
|
|
"run-once": true,
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin",
|
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
|
"MESH_GITEA_TOOLS_USER": "mesh-tools",
|
|
"MESH_REPOSITORIES_FILE": "${dir:mesh-state}/repositories.json",
|
|
"MESH_REPOSITORIES_OUTCOME": "${dir:runtime-state}/repositories-outcome.json"
|
|
},
|
|
"restart-on": [
|
|
"repositories-file"
|
|
]
|
|
}
|
|
],
|
|
"provides": [
|
|
{
|
|
"name": "npm-package-registry",
|
|
"scope": "mesh",
|
|
"identity": {
|
|
"max": 40,
|
|
"in": "a Gitea user name"
|
|
}
|
|
},
|
|
{
|
|
"name": "git",
|
|
"scope": "mesh"
|
|
},
|
|
{
|
|
"name": "gitea-read",
|
|
"scope": "mesh",
|
|
"credential": {
|
|
"issued-by": "software",
|
|
"tool": "gitea_agent_token"
|
|
}
|
|
},
|
|
{
|
|
"name": "forge-account",
|
|
"scope": "mesh"
|
|
}
|
|
],
|
|
"build": {
|
|
"artifacts": [
|
|
{
|
|
"name": "code",
|
|
"kind": "bundle",
|
|
"language": "typescript",
|
|
"entrypoints": [
|
|
"index.js",
|
|
"tools/index.js",
|
|
"provisioner/index.js"
|
|
],
|
|
"loads": [
|
|
"index.js",
|
|
"tools/index.js",
|
|
"provisioner/index.js"
|
|
],
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_CONFIG_FILE": "${dir:mesh-state}/config.json",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin",
|
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
|
"MESH_GITEA_TOOLS_USER": "mesh-tools",
|
|
"MESH_GITEA_STATE_DIR": "${dir:runtime-state}",
|
|
"MESH_RECEIVES": "${dir:grants}/npm.json",
|
|
"MESH_GITEA_HOOK_URL": "http://172.17.0.1:3047",
|
|
"MESH_GITEA_HOOK_PORT": "3047",
|
|
"MESH_GITEA_HOOK_HOST": "172.17.0.1"
|
|
}
|
|
},
|
|
{
|
|
"name": "npm-registry",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/npm-registry",
|
|
"binary": "npm-registry",
|
|
"loads": [
|
|
"npm-registry"
|
|
],
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin",
|
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
|
"MESH_NPM_OWNER": "novox"
|
|
}
|
|
},
|
|
{
|
|
"name": "forge",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/forge",
|
|
"binary": "forge",
|
|
"loads": [
|
|
"forge"
|
|
],
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_TOOLS_USER": "mesh-tools",
|
|
"MESH_GITEA_TOKEN_FILE": "${dir:runtime-state}/token",
|
|
"MESH_GITEA_PATCH_DIR": "${dir:forge-patches}"
|
|
}
|
|
},
|
|
{
|
|
"name": "files",
|
|
"kind": "archive",
|
|
"from": "files"
|
|
},
|
|
{
|
|
"name": "agent-token",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/agent-token",
|
|
"binary": "agent-token",
|
|
"loads": [
|
|
"agent-token"
|
|
],
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin",
|
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
|
"MESH_GITEA_ORIGINS_FILE": "${dir:mesh-state}/origins"
|
|
}
|
|
},
|
|
{
|
|
"name": "agent-teams",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/agent-teams",
|
|
"binary": "agent-teams",
|
|
"loads": [
|
|
"agent-teams"
|
|
]
|
|
},
|
|
{
|
|
"name": "repositories",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/repositories",
|
|
"binary": "repositories",
|
|
"loads": [
|
|
"repositories"
|
|
]
|
|
},
|
|
{
|
|
"name": "forge-account-provider",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/forge-account-provider",
|
|
"binary": "forge-account-provider",
|
|
"loads": [
|
|
"forge-account-provider"
|
|
],
|
|
"env": {
|
|
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
|
|
"MESH_GITEA_ADMIN_USER": "mesh-admin",
|
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
|
"MESH_GITEA_ORIGINS_FILE": "${dir:mesh-state}/origins",
|
|
"MESH_GITEA_SSH_PORT": "222",
|
|
"MESH_FORGE_HOST_FILE": "/etc/gitea/forge-host"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"jails": [
|
|
{
|
|
"name": "gitea",
|
|
"failregex": "^.*Failed authentication attempt for .* from <HOST>(?::\\d+)?\\s*$\n ^.*Invalid user .* from <HOST> port \\d+\\s*$\n ^.*User \\S+ from <HOST> not allowed because .*$",
|
|
"jail": "backend = systemd\njournalmatch = CONTAINER_NAME=gitea\nport = http,https,222\nmaxretry = 3\nfindtime = 1d\nbantime = 1d"
|
|
}
|
|
],
|
|
"state": [
|
|
"bound",
|
|
"announced"
|
|
],
|
|
"reads": [
|
|
"mesh-controller.assignments",
|
|
"ssh-client.keys",
|
|
"mesh-build-go.keys",
|
|
"mesh-build-node.keys",
|
|
"mesh-build-image.keys",
|
|
"mesh-delivery-checker.owed"
|
|
]
|
|
}
|