internal/store/runners.go

v1.10.0
gitbay/internal/store/runners.go history · blame · raw

59 lines · 2321 bytes

 1package store
 2
 3// Runner is one runner account as the instance admin sees it.
 4type Runner struct {
 5	Username string `json:"username"`
 6	LastSeen string `json:"last_seen"`
 7	Scope    string `json:"scope,omitempty"` // comma-joined owner/name, "" for any
 8	// The build it holds, if any.
 9	BuildRepo   string `json:"build_repo,omitempty"`
10	BuildNumber int64  `json:"build_number,omitempty"`
11	BuildJob    string `json:"build_job,omitempty"`
12	StartedAt   string `json:"started_at,omitempty"`
13}
14
15// TouchRunner records a poll: the time, the scope the runner asked for,
16// and the build it just claimed (0 for none).
17func (s *Store) TouchRunner(userID int64, scope string, buildID int64) error {
18	_, err := s.DB.Exec(`INSERT INTO runner_seen (user_id, last_seen, scope, build_id)
19		VALUES (?1, strftime('%Y-%m-%dT%H:%M:%fZ','now'), ?2, NULLIF(?3, 0))
20		ON CONFLICT (user_id) DO UPDATE SET
21			last_seen = excluded.last_seen, scope = excluded.scope,
22			build_id = COALESCE(excluded.build_id, runner_seen.build_id)`,
23		userID, scope, buildID)
24	return err
25}
26
27// RunnerDone records that the runner reported and holds nothing now.
28func (s *Store) RunnerDone(userID int64) error {
29	_, err := s.DB.Exec(`UPDATE runner_seen SET last_seen = strftime('%Y-%m-%dT%H:%M:%fZ','now'),
30		build_id = NULL WHERE user_id = ?`, userID)
31	return err
32}
33
34// ListRunners lists every account that has ever polled as a runner,
35// most recently seen first.
36func (s *Store) ListRunners() ([]Runner, error) {
37	rows, err := s.DB.Query(`SELECT u.username, r.last_seen, r.scope,
38		COALESCE(COALESCE(bu.username, bo.name) || '/' || br.name, ''),
39		COALESCE(b.number, 0), COALESCE(b.job, ''), COALESCE(b.started_at, '')
40		FROM runner_seen r JOIN users u ON u.id = r.user_id
41		LEFT JOIN builds b ON b.id = r.build_id AND b.status = 'running'
42		LEFT JOIN repos br ON br.id = b.repo_id
43		LEFT JOIN users bu ON br.owner_kind = 'user' AND bu.id = br.owner_id
44		LEFT JOIN orgs bo ON br.owner_kind = 'org' AND bo.id = br.owner_id
45		ORDER BY r.last_seen DESC`)
46	if err != nil {
47		return nil, err
48	}
49	defer rows.Close()
50	var out []Runner
51	for rows.Next() {
52		var r Runner
53		if err := rows.Scan(&r.Username, &r.LastSeen, &r.Scope, &r.BuildRepo, &r.BuildNumber, &r.BuildJob, &r.StartedAt); err != nil {
54			return nil, err
55		}
56		out = append(out, r)
57	}
58	return out, rows.Err()
59}