From 3968485b1b3f46303bc04463ef2222b278b6b970 Mon Sep 17 00:00:00 2001 From: Hector Date: Mon, 19 Jan 2026 11:42:25 +0000 Subject: [PATCH 1/3] Add colima VM diskspace check --- devenv/checks/colimaDiskSpace.py | 57 ++++++++++++++++++++ tests/checks/test_colimaDiskSpace.py | 78 ++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 devenv/checks/colimaDiskSpace.py create mode 100644 tests/checks/test_colimaDiskSpace.py diff --git a/devenv/checks/colimaDiskSpace.py b/devenv/checks/colimaDiskSpace.py new file mode 100644 index 00000000..3f2bd058 --- /dev/null +++ b/devenv/checks/colimaDiskSpace.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from devenv.lib import colima +from devenv.lib import proc +from devenv.lib_check.types import checker +from devenv.lib_check.types import fixer + +tags: set[str] = {"builtin"} +name = "colima VM has sufficient disk space" + + +@checker +def check() -> tuple[bool, str]: + status = colima.check() + if status != colima.ColimaStatus.UP: + return True, "" + + try: + output = proc.run( + ("colima", "exec", "--", "df", "--output=pcent", "/"), stdout=True + ) + except RuntimeError: + return True, "" + + lines = output.strip().split("\n") + if len(lines) >= 2: + percent_str = lines[1].strip().rstrip("%") + try: + used_percent = int(percent_str) + if used_percent > 90: + return ( + False, + f"Colima VM disk is {used_percent}% full (less than 10% free space).\n" + "Consider resizing the disk or cleaning up unused Docker images/containers.", + ) + except ValueError: + pass + + return True, "" + + +@fixer +def fix() -> tuple[bool, str]: + return ( + False, + """To resize the Colima VM disk: + +1. Stop colima: + colima stop + +2. Start with a larger disk (e.g., 200GB): + colima start --disk 200 + +Alternatively, clean up unused Docker resources: + docker system prune -a +""", + ) diff --git a/tests/checks/test_colimaDiskSpace.py b/tests/checks/test_colimaDiskSpace.py new file mode 100644 index 00000000..645a0f6a --- /dev/null +++ b/tests/checks/test_colimaDiskSpace.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from unittest import mock + +from devenv.checks import colimaDiskSpace +from devenv.lib import colima + + +def test_check_skipped_when_colima_down() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.DOWN + ): + assert colimaDiskSpace.check() == (True, "") + + +def test_check_skipped_when_colima_unhealthy() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.UNHEALTHY + ): + assert colimaDiskSpace.check() == (True, "") + + +def test_check_passes_when_disk_has_space() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.UP + ), mock.patch( + "devenv.checks.colimaDiskSpace.proc.run", return_value="Use%\n 50%" + ): + assert colimaDiskSpace.check() == (True, "") + + +def test_check_passes_at_90_percent() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.UP + ), mock.patch( + "devenv.checks.colimaDiskSpace.proc.run", return_value="Use%\n 90%" + ): + assert colimaDiskSpace.check() == (True, "") + + +def test_check_fails_when_disk_full() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.UP + ), mock.patch( + "devenv.checks.colimaDiskSpace.proc.run", return_value="Use%\n 95%" + ): + ok, msg = colimaDiskSpace.check() + assert ok is False + assert "95% full" in msg + assert "less than 10% free" in msg + + +def test_check_fails_at_91_percent() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.UP + ), mock.patch( + "devenv.checks.colimaDiskSpace.proc.run", return_value="Use%\n 91%" + ): + ok, msg = colimaDiskSpace.check() + assert ok is False + + +def test_check_skipped_on_df_error() -> None: + with mock.patch.object( + colima, "check", return_value=colima.ColimaStatus.UP + ), mock.patch( + "devenv.checks.colimaDiskSpace.proc.run", + side_effect=RuntimeError("command failed"), + ): + assert colimaDiskSpace.check() == (True, "") + + +def test_fix_returns_instructions() -> None: + ok, msg = colimaDiskSpace.fix() + assert ok is False + assert "colima stop" in msg + assert "colima start --disk 200" in msg + assert "docker system prune" in msg From 2d356ccc5c8695b2742601dd070be0d8f4cf9121 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Mon, 26 Jan 2026 11:56:55 -0800 Subject: [PATCH 2/3] update message and start with minimum 128gib --- devenv/checks/colimaDiskSpace.py | 14 +++++++++----- devenv/lib/colima.py | 4 ++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/devenv/checks/colimaDiskSpace.py b/devenv/checks/colimaDiskSpace.py index 3f2bd058..de5a1a86 100644 --- a/devenv/checks/colimaDiskSpace.py +++ b/devenv/checks/colimaDiskSpace.py @@ -43,15 +43,19 @@ def check() -> tuple[bool, str]: def fix() -> tuple[bool, str]: return ( False, - """To resize the Colima VM disk: + """ +First you should try to cleanup unused Docker resources: + docker system prune -a + +Failing that, you can resize the Colima VM's disk: 1. Stop colima: colima stop -2. Start with a larger disk (e.g., 200GB): - colima start --disk 200 +2. Install qemu: + brew install qemu -Alternatively, clean up unused Docker resources: - docker system prune -a +2. Restart colima, resizing to a larger disk (e.g., 200GB): + colima start --disk 200 """, ) diff --git a/devenv/lib/colima.py b/devenv/lib/colima.py index f9c9e680..35a8f90c 100644 --- a/devenv/lib/colima.py +++ b/devenv/lib/colima.py @@ -186,6 +186,10 @@ def start(restart: bool = False) -> ColimaStatus: "colima", "start", "--verbose", + # default 60GiB disk is generally not enough over time + # since devs work with a lot of images + "--disk", + "128", # this effectively makes the vm's resolvectl status use: # DNS Servers: 8.8.8.8 1.1.1.1 192.168.5.2 # https://lima-vm.io/docs/config/network/user/ From 68e62b337fc5058c35f3165b6879186f384c97af Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Mon, 26 Jan 2026 12:04:00 -0800 Subject: [PATCH 3/3] [skip ci]