commit
b3a5f36e02
3 changed files with 61 additions and 5 deletions
|
|
@ -64,6 +64,7 @@ For running the builds:
|
||||||
For running the controller (runboat itself):
|
For running the controller (runboat itself):
|
||||||
|
|
||||||
- Python 3.10
|
- Python 3.10
|
||||||
|
- sqlite3 >= 3.25
|
||||||
- `kubectl`
|
- `kubectl`
|
||||||
- A `KUBECONFIG` or an in-cluster service account that provides access to the namespace
|
- A `KUBECONFIG` or an in-cluster service account that provides access to the namespace
|
||||||
where the builds are deployed, with permissions to create and delete Service, Job,
|
where the builds are deployed, with permissions to create and delete Service, Job,
|
||||||
|
|
|
||||||
|
|
@ -187,10 +187,26 @@ class BuildsDb:
|
||||||
return [self._build_from_row(row) for row in rows]
|
return [self._build_from_row(row) for row in rows]
|
||||||
|
|
||||||
def oldest_stopped(self, limit: int) -> list[Build]:
|
def oldest_stopped(self, limit: int) -> list[Build]:
|
||||||
"""Return a list of oldest stopped builds."""
|
"""Return a list of oldest stopped builds.
|
||||||
|
|
||||||
|
Exclude the most recent build of each branch that we want to
|
||||||
|
preserve from eviction.
|
||||||
|
"""
|
||||||
rows = self._con.execute(
|
rows = self._con.execute(
|
||||||
"SELECT * FROM builds WHERE status IN (?, ?, ?) "
|
"""\
|
||||||
"ORDER BY last_scaled LIMIT ?",
|
SELECT * FROM (
|
||||||
|
SELECT
|
||||||
|
ROW_NUMBER () OVER (
|
||||||
|
PARTITION BY repo, target_branch, pr
|
||||||
|
ORDER BY created DESC
|
||||||
|
) AS rownum,
|
||||||
|
*
|
||||||
|
FROM builds
|
||||||
|
)
|
||||||
|
WHERE status IN (?, ?, ?) AND (rownum != 1 OR pr IS NOT NULL)
|
||||||
|
ORDER BY last_scaled
|
||||||
|
LIMIT ?
|
||||||
|
""",
|
||||||
(BuildStatus.stopping, BuildStatus.stopped, BuildStatus.failed, limit),
|
(BuildStatus.stopping, BuildStatus.stopped, BuildStatus.failed, limit),
|
||||||
).fetchall()
|
).fetchall()
|
||||||
return [self._build_from_row(row) for row in rows]
|
return [self._build_from_row(row) for row in rows]
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ def _make_build(
|
||||||
repo: str | None = None,
|
repo: str | None = None,
|
||||||
target_branch: str | None = None,
|
target_branch: str | None = None,
|
||||||
pr: int | None = None,
|
pr: int | None = None,
|
||||||
|
last_scaled: datetime.datetime | None = None,
|
||||||
|
created: datetime.datetime | None = None,
|
||||||
) -> Build:
|
) -> Build:
|
||||||
name = name or "build-a"
|
name = name or "build-a"
|
||||||
return Build(
|
return Build(
|
||||||
|
|
@ -29,8 +31,8 @@ def _make_build(
|
||||||
status=status or BuildStatus.starting,
|
status=status or BuildStatus.starting,
|
||||||
init_status=init_status or BuildInitStatus.todo,
|
init_status=init_status or BuildInitStatus.todo,
|
||||||
desired_replicas=0,
|
desired_replicas=0,
|
||||||
last_scaled=datetime.datetime(2021, 10, 1, 12, 0, 0),
|
last_scaled=last_scaled or datetime.datetime(2021, 10, 1, 12, 0, 0),
|
||||||
created=datetime.datetime(2021, 10, 1, 11, 0, 0),
|
created=created or datetime.datetime(2021, 10, 1, 11, 0, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -158,3 +160,40 @@ def test_repos() -> None:
|
||||||
db.add(_make_build(name="b1", repo="oca/repo1"))
|
db.add(_make_build(name="b1", repo="oca/repo1"))
|
||||||
db.add(_make_build(name="b2", repo="oca/repo2"))
|
db.add(_make_build(name="b2", repo="oca/repo2"))
|
||||||
assert db.repos() == [Repo(name="oca/repo1"), Repo(name="oca/repo2")]
|
assert db.repos() == [Repo(name="oca/repo1"), Repo(name="oca/repo2")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_oldest_stopped() -> None:
|
||||||
|
db = BuildsDb()
|
||||||
|
db.add(
|
||||||
|
_make_build(
|
||||||
|
name="b1",
|
||||||
|
repo="oca/repo1",
|
||||||
|
target_branch="15.0",
|
||||||
|
status=BuildStatus.stopped,
|
||||||
|
last_scaled=datetime.datetime(2021, 10, 11, 12, 0, 0),
|
||||||
|
created=datetime.datetime(2021, 10, 11, 12, 0, 0),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
db.add(
|
||||||
|
_make_build(
|
||||||
|
name="b2",
|
||||||
|
repo="oca/repo1",
|
||||||
|
target_branch="15.0",
|
||||||
|
status=BuildStatus.stopped,
|
||||||
|
last_scaled=datetime.datetime(2021, 10, 11, 12, 0, 2),
|
||||||
|
created=datetime.datetime(2021, 10, 11, 12, 0, 2),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# a PR that is most recent than the latest branch build
|
||||||
|
db.add(
|
||||||
|
_make_build(
|
||||||
|
name="pr1",
|
||||||
|
repo="oca/repo1",
|
||||||
|
target_branch="15.0",
|
||||||
|
pr=1,
|
||||||
|
status=BuildStatus.stopped,
|
||||||
|
last_scaled=datetime.datetime(2021, 10, 11, 12, 0, 4),
|
||||||
|
created=datetime.datetime(2021, 10, 11, 12, 0, 4),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert [b.name for b in db.oldest_stopped(limit=3)] == ["b1", "pr1"]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue