{ "module": "gitea", "version": "1", "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", "node-build-agent.started" ], "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" } } }, "settings": { "ready-authors": { "kind": "preference", "default": "mesh-admin jschoubben", "why": "the forge accounts whose comment \"ready at \" marks a pull request ready for mesh-delivery to merge, separated by spaces: the mesh's own forge account and the operator's (novox/hq issue 722). A comment by any other account is ignored and said in the forge's log. Trusted: who may have a change merged is the operator's word" } }, "resources": [ { "id": "mesh-state", "type": "directory", "mode": "0700", "place": "mesh" }, { "id": "runtime-state", "type": "directory", "path": "${dir:mesh-state}/state", "mode": "0700" }, { "id": "ready-authors", "type": "file", "path": "${dir:mesh-state}/ready-authors", "mode": "0600", "trusted": true, "content": "# The accounts whose \"ready at \" comment marks a pull request ready (novox/hq issue 722), from the setting\n# ready-authors, written by the mesh. Replaced on every push; change the setting, never this file.\nauthors=${setting:ready-authors}\n" }, { "id": "state", "type": "directory", "mode": "0700", "place": "." }, { "id": "grants", "type": "directory", "mode": "0700" }, { "id": "server-env", "type": "file", "path": "${dir:state}/server.env", "mode": "0600", "content": "GITEA__security__INTERNAL_TOKEN=${secret:internal-token}\nGITEA__database__DB_TYPE=postgres\nGITEA__database__HOST=${bound:postgres-database:at}:${bound:postgres-database:port}\nGITEA__database__NAME=${bound:postgres-database:as}\nGITEA__database__USER=${bound:postgres-database:as}\nGITEA__database__PASSWD=${secret:postgres-database}\nGITEA__webhook__ALLOWED_HOST_LIST=172.17.0.1\n" }, { "id": "data", "type": "directory", "mode": "0700", "owner": "1000:1000" }, { "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": "runtime-config", "type": "file", "path": "${dir:mesh-state}/config.json", "mode": "0600", "content": "{}\n", "merge": "json", "takes-settings": [] } ], "provides": [ { "name": "npm-package-registry", "scope": "mesh", "identity": { "max": 40, "in": "a Gitea user name" } }, { "name": "git", "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_STATE_DIR": "${dir:runtime-state}", "MESH_RECEIVES": "${dir:grants}/npm.json", "MESH_GITEA_READY_AUTHORS_FILE": "${dir:mesh-state}/ready-authors", "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_ADMIN_USER": "mesh-admin", "MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret" } } ] }, "jails": [ { "name": "gitea", "failregex": "^.*Failed authentication attempt for .* from (?::\\d+)?\\s*$\n ^.*Invalid user .* from port \\d+\\s*$\n ^.*User \\S+ from not allowed because .*$", "jail": "backend = systemd\njournalmatch = CONTAINER_NAME=gitea\nport = http,https,222\nmaxretry = 3\nfindtime = 1d\nbantime = 1d" } ] }