Merge pull request #27 from sbidoul/gurneyalex-fix_10

Fix issue 10
This commit is contained in:
Stéphane Bidoul 2021-11-26 18:18:10 +01:00 committed by GitHub
commit b3a5f36e02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 5 deletions

View file

@ -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,

View file

@ -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]

View file

@ -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"]