| 1 | -- Mirroring: a repository's links to copies of it on other hosts, and the |
| 2 | -- health of those hosts. See src/remotes.rs and crates/contracts |
| 3 | -- src/mirrors.rs. Every timestamp is RFC 3339 UTC; *_ms are milliseconds |
| 4 | -- since the epoch. |
| 5 | |
| 6 | -- One link. role leader: the remote leads and the repository is its |
| 7 | -- mirror (at most one per repository). role follower: g1t leads and the |
| 8 | -- remote is kept in step. |
| 9 | -- |
| 10 | -- provider: github | g1t | git. |
| 11 | -- name: for people, `github.com/acme/web`. url: its web address. |
| 12 | -- clone_url: its https git address. |
| 13 | -- external_id: the provider's id for it (GitHub's numeric repository id, |
| 14 | -- which survives renames). connection_id: GitHub's installation id. |
| 15 | -- username, credential: for g1t and git, the user and token sent by basic |
| 16 | -- authentication; the token sealed under INTEGRATIONS_KEY. |
| 17 | -- state: standby | ci | takeover | handing_back (leaders), following | |
| 18 | -- stuck (followers). state_by: a username, or g1t. |
| 19 | -- settings: JSON `MirrorSettings`. |
| 20 | -- recorded: 0 until the repos service has this state (set_mirror); the |
| 21 | -- cron retries until it has. |
| 22 | -- polled_ms: the last poll of a remote with no webhook. |
| 23 | CREATE TABLE remotes ( |
| 24 | id TEXT PRIMARY KEY, |
| 25 | repo_id TEXT NOT NULL, |
| 26 | workspace TEXT NOT NULL, |
| 27 | repo TEXT NOT NULL, |
| 28 | provider TEXT NOT NULL, |
| 29 | role TEXT NOT NULL, |
| 30 | name TEXT NOT NULL, |
| 31 | url TEXT NOT NULL, |
| 32 | clone_url TEXT NOT NULL, |
| 33 | external_id TEXT, |
| 34 | connection_id TEXT, |
| 35 | username TEXT, |
| 36 | credential TEXT, |
| 37 | state TEXT NOT NULL, |
| 38 | state_since TEXT NOT NULL, |
| 39 | state_by TEXT, |
| 40 | settings TEXT NOT NULL DEFAULT '{}', |
| 41 | recorded INTEGER NOT NULL DEFAULT 0, |
| 42 | polled_ms INTEGER NOT NULL DEFAULT 0, |
| 43 | synced_at TEXT, |
| 44 | last_error TEXT, |
| 45 | created_by TEXT NOT NULL, |
| 46 | created_at TEXT NOT NULL |
| 47 | ); |
| 48 | CREATE UNIQUE INDEX remotes_one_leader ON remotes (repo_id) WHERE role = 'leader'; |
| 49 | CREATE INDEX remotes_by_repo ON remotes (repo_id); |
| 50 | CREATE INDEX remotes_by_external ON remotes (provider, external_id); |
| 51 | CREATE INDEX remotes_unrecorded ON remotes (recorded) WHERE recorded = 0; |
| 52 | |
| 53 | -- During a takeover: each ref's commit when it began (base), what both |
| 54 | -- sides agreed on, and what someone decided for one that diverged. |
| 55 | CREATE TABLE remote_refs ( |
| 56 | remote_id TEXT NOT NULL, |
| 57 | ref TEXT NOT NULL, |
| 58 | base TEXT, |
| 59 | decision TEXT, |
| 60 | PRIMARY KEY (remote_id, ref) |
| 61 | ); |
| 62 | |
| 63 | -- Whether a host answers. It is unreachable after three failed checks |
| 64 | -- over at least two minutes, and reachable again after three good ones |
| 65 | -- over at least five. |
| 66 | -- |
| 67 | -- failures, successes: in a row. streak_ms: when the current run began. |
| 68 | -- unreachable_since: set while unreachable. |
| 69 | CREATE TABLE remote_hosts ( |
| 70 | host TEXT PRIMARY KEY, |
| 71 | failures INTEGER NOT NULL DEFAULT 0, |
| 72 | successes INTEGER NOT NULL DEFAULT 0, |
| 73 | streak_ms INTEGER NOT NULL DEFAULT 0, |
| 74 | unreachable_since TEXT, |
| 75 | checked_ms INTEGER NOT NULL DEFAULT 0, |
| 76 | last_problem TEXT |
| 77 | ); |
| 78 | |
| 79 | -- The GitHub links that kept g1t in step (mirror) or GitHub in step |
| 80 | -- (push) become remotes. A mirror becomes a standby mirror: read-only on |
| 81 | -- g1t until someone takes over, which is what it always was in effect |
| 82 | -- (anything pushed to it was overwritten at the next sync). |
| 83 | INSERT INTO remotes |
| 84 | (id, repo_id, workspace, repo, provider, role, name, url, clone_url, external_id, connection_id, |
| 85 | state, state_since, settings, synced_at, last_error, created_by, created_at) |
| 86 | SELECT |
| 87 | 'rmt_' || lower(hex(randomblob(10))), repo_id, workspace, repo, 'github', |
| 88 | CASE mode WHEN 'mirror' THEN 'leader' ELSE 'follower' END, |
| 89 | 'github.com/' || full_name, 'https://github.com/' || full_name, 'https://github.com/' || full_name || '.git', |
| 90 | CAST(github_repo_id AS TEXT), CAST(installation_id AS TEXT), |
| 91 | CASE mode WHEN 'mirror' THEN 'standby' ELSE 'following' END, |
| 92 | COALESCE(synced_at, created_at), '{}', synced_at, last_error, created_by, created_at |
| 93 | FROM github_repos |
| 94 | WHERE mode IN ('mirror', 'push'); |