internal/store/cisecrets.go

v1.13.2
gitbay/internal/store/cisecrets.go history · blame · raw

141 lines · 3922 bytes

  1package store
  2
  3// SetBuildSecret stores or replaces one secret. The value never leaves the
  4// server except inside a claimed build's environment.
  5func (s *Store) SetBuildSecret(repoID int64, name, value string) error {
  6	_, err := s.DB.Exec(`
  7		INSERT INTO build_secrets (repo_id, name, value) VALUES (?, ?, ?)
  8		ON CONFLICT (repo_id, name) DO UPDATE SET value = excluded.value`,
  9		repoID, name, value)
 10	return err
 11}
 12
 13func (s *Store) RemoveBuildSecret(repoID int64, name string) error {
 14	res, err := s.DB.Exec("DELETE FROM build_secrets WHERE repo_id = ? AND name = ?", repoID, name)
 15	if err != nil {
 16		return err
 17	}
 18	if n, _ := res.RowsAffected(); n == 0 {
 19		return ErrNotFound
 20	}
 21	return nil
 22}
 23
 24// ListBuildSecretNames returns names only; values are for builds.
 25func (s *Store) ListBuildSecretNames(repoID int64) ([]string, error) {
 26	rows, err := s.DB.Query("SELECT name FROM build_secrets WHERE repo_id = ? ORDER BY name", repoID)
 27	if err != nil {
 28		return nil, err
 29	}
 30	defer rows.Close()
 31	var out []string
 32	for rows.Next() {
 33		var n string
 34		if err := rows.Scan(&n); err != nil {
 35			return nil, err
 36		}
 37		out = append(out, n)
 38	}
 39	return out, rows.Err()
 40}
 41
 42// BuildSecrets returns the values, for injection into a claimed build.
 43func (s *Store) BuildSecrets(repoID int64) (map[string]string, error) {
 44	rows, err := s.DB.Query("SELECT name, value FROM build_secrets WHERE repo_id = ?", repoID)
 45	if err != nil {
 46		return nil, err
 47	}
 48	defer rows.Close()
 49	out := map[string]string{}
 50	for rows.Next() {
 51		var n, v string
 52		if err := rows.Scan(&n, &v); err != nil {
 53			return nil, err
 54		}
 55		out[n] = v
 56	}
 57	return out, rows.Err()
 58}
 59
 60// Schedule is one repo job's cron entry.
 61type Schedule struct {
 62	RepoID  int64
 63	Job     string
 64	Cron    string
 65	NextRun string
 66}
 67
 68// SyncSchedules replaces a repo's schedule set with the given entries,
 69// preserving next_run for entries whose cron is unchanged.
 70func (s *Store) SyncSchedules(repoID int64, entries []Schedule) error {
 71	tx, err := s.DB.Begin()
 72	if err != nil {
 73		return err
 74	}
 75	defer tx.Rollback()
 76	keep := map[string]bool{}
 77	for _, e := range entries {
 78		keep[e.Job] = true
 79		if _, err := tx.Exec(`
 80			INSERT INTO build_schedules (repo_id, job, cron, next_run) VALUES (?, ?, ?, ?)
 81			ON CONFLICT (repo_id, job) DO UPDATE SET
 82				next_run = CASE WHEN cron = excluded.cron THEN next_run ELSE excluded.next_run END,
 83				cron = excluded.cron`,
 84			repoID, e.Job, e.Cron, e.NextRun); err != nil {
 85			return err
 86		}
 87	}
 88	rows, err := tx.Query("SELECT job FROM build_schedules WHERE repo_id = ?", repoID)
 89	if err != nil {
 90		return err
 91	}
 92	var stale []string
 93	for rows.Next() {
 94		var j string
 95		if err := rows.Scan(&j); err != nil {
 96			rows.Close()
 97			return err
 98		}
 99		if !keep[j] {
100			stale = append(stale, j)
101		}
102	}
103	rows.Close()
104	for _, j := range stale {
105		if _, err := tx.Exec("DELETE FROM build_schedules WHERE repo_id = ? AND job = ?", repoID, j); err != nil {
106			return err
107		}
108	}
109	return tx.Commit()
110}
111
112// DueSchedules returns entries whose next_run is at or before now.
113func (s *Store) DueSchedules(nowISO string) ([]Schedule, error) {
114	rows, err := s.DB.Query(
115		"SELECT repo_id, job, cron, next_run FROM build_schedules WHERE next_run <= ? ORDER BY next_run", nowISO)
116	if err != nil {
117		return nil, err
118	}
119	defer rows.Close()
120	var out []Schedule
121	for rows.Next() {
122		var e Schedule
123		if err := rows.Scan(&e.RepoID, &e.Job, &e.Cron, &e.NextRun); err != nil {
124			return nil, err
125		}
126		out = append(out, e)
127	}
128	return out, rows.Err()
129}
130
131// SetScheduleNext advances one entry's next firing time.
132func (s *Store) SetScheduleNext(repoID int64, job, nextRun string) error {
133	_, err := s.DB.Exec(
134		"UPDATE build_schedules SET next_run = ? WHERE repo_id = ? AND job = ?", nextRun, repoID, job)
135	return err
136}
137
138func (s *Store) RemoveSchedule(repoID int64, job string) error {
139	_, err := s.DB.Exec("DELETE FROM build_schedules WHERE repo_id = ? AND job = ?", repoID, job)
140	return err
141}