Skip to content

RSDK-14354: Add disk space monitor for viam-agent - #293

Merged
nandini-swami merged 23 commits into
mainfrom
nandiniswami/disk-space-monitor
Sep 15, 2026
Merged

nandini-swami merged 23 commits into
mainfrom
nandiniswami/disk-space-monitor

Conversation

@nandini-swami

@nandini-swami nandini-swami commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

RSDK-14354:

Add a disk-space check before viam-agent downloads.

The agent checks free space before it downloads or copies a binary. This covers viam-server downloads and agent self-updates. Both go through utils.DownloadFile.

The check requires the remaining download size plus a 10 MB floor. It reads the size from the HEAD request that already runs before every download. If a partial download is on disk and the agent can resume it, the check subtracts those bytes, because only the remaining bytes need to fit. If the server does not report a size, the check uses the just the 10 MB floor.

The warning includes the path, the available space, the required space, and the download size.

Adds block_downloads_on_low_disk to advanced_settings config for agent. Unset (the default) is log-only: the warning is logged and the download continues, matching viam-server's default (RSDK-13166, rdk#6075). When set to true, a low-disk result refuses the download and the agent logs the error instead.

Tests cover the sizing math for both paths, unknown content length, a resumable partial, a stale partial that must not be subtracted, and refusal in both branches when blocking is on.

Manually verified on a Raspberry Pi (log-only and blocking) and a Windows 11 VM (log-only).

@nandini-swami nandini-swami changed the title Add disk space monitor for viam-agent RSDK-14354: Add disk space monitor for viam-agent Sep 1, 2026
@nandini-swami

Copy link
Copy Markdown
Contributor Author

Manual tested on raspberry pi and Windows machine

Windows:
RSDK-14354, testing logs windows

Pi:
RSDK-14354, testing logs pi

@cheukt Cheuk (cheukt) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the code looks good! let's just export the rdk function so we aren't duplicating code too much (it does mean you'll have to do an rdk pr as well, but hopefully nothing crazy). that should also hopefully make the tests a little simpler

Comment thread utils/disk_space.go Outdated
// Callers must not pass a file path: on Windows GetDiskFreeSpaceExW rejects one, and
// diskusage.Usage stops walking up at the first path that exists, which is the file itself
// once a partial download is on disk.
func warnIfLowDiskSpace(logger logging.Logger, path, desc string, required uint64, extraFields ...any) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's go ahead and export rdk's robot/packages.checkDiskSpace instead of basically reimplementing it here. maybe with a signature of diskusage.WarnIfLow(logger, path, desc, required, extra...) (low bool, err error)?

@nandini-swami

Copy link
Copy Markdown
Contributor Author

Manual testing on Windows

Windows testing (http) Windows testing (file)

@nandini-swami

Copy link
Copy Markdown
Contributor Author

Manual testing on Pi
Pi testing

@nandini-swami
nandini-swami force-pushed the nandiniswami/disk-space-monitor branch from 051876f to 75295b4 Compare September 9, 2026 19:14
@nandini-swami

Copy link
Copy Markdown
Contributor Author

Manually tested on Pi

Default - warning comes from CheckDiskSpace in rdk, and the download proceeds.
Pi CheckDiskSpace

With block_downloads_on_low_disk: true in advanced_settings: rdk returns the error instead, and the agent logs it and skips the download.
Pi blocking

@nandini-swami

Copy link
Copy Markdown
Contributor Author

Manually tested on Windows
Pi CheckDiskSpace

@nandini-swami
nandini-swami force-pushed the nandiniswami/disk-space-monitor branch from 75295b4 to 48e5692 Compare September 9, 2026 21:41
Comment thread version_control.go
// download and record the sha of the download itself
verData.DlPath, err = utils.DownloadFile(ctx, verData.URL, c.logger)
verData.DlPath, err = utils.DownloadFile(ctx, verData.URL, c.logger, c.blockOnLowDisk)
if err != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if err is diskusage.ErrInsufficientDiskSpace we don't want to set data.brokenTarget = true since the target isn't actually broken, we're just out of space. Otherwise, even if we make more disk space, we won't re-download/install the custom URL version until we changed the URL back and forth.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh good catch, that would've stuck permanently. fixed it, thx!

Comment thread manager.go Outdated
Comment on lines 280 to 283
m.cache.SetBlockOnLowDisk(m.cfg.AdvancedSettings.BlockDownloadsOnLowDisk.Get())

// Agent
needRestart, err := m.cache.UpdateBinary(ctx, SubsystemName)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we maybe just pass m.cfg.AdvancedSettings.BlockDownloadsOnLowDisk.Get() to UpdateBinary instead of having it be a field with a getter on the cache? It was a little hard to follow how it was being used and I think this is clearer.

Also small nit: looks like most (all?) advanced config settings have a getter wrapper instead of doing a raw Get().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that's clearer. fixed nit as well!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice job!

@cheukt Cheuk (cheukt) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! just a small change and then good to approve

Comment thread utils/utils.go
defer res.Body.Close() //nolint:errcheck
// we remove surrounding quotes if present
return strings.Trim(res.Header.Get("ETag"), `"`), nil
return strings.Trim(res.Header.Get("ETag"), `"`), res.ContentLength, nil

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is pre-existing but let's check the status code of the response (that it's a 200) before returning a size

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg!

Comment thread go.sum Outdated
go.viam.com/rdk v1.2.0/go.mod h1:rl0RdP/baQRLFSkkUQHGF3SzbKgTajjUuoAr9K1kN7A=
go.viam.com/api v0.1.579 h1:KQz5abVMsNxLxvs7Xw0dZqjSYhSqZns9xVFT9B+d7ec=
go.viam.com/api v0.1.579/go.mod h1:4wA8A7g955PH03er3PNSJAi32bu3fpj9/kFp6AbrDNY=
go.viam.com/rdk v1.7.1-0.20260909213157-0dc7ed903416 h1:fYqJN2JyEqfCZqoBPwp6ZbtbjYYKiX+td8Bd4Dgi55o=

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's wait until next week to bump rdk to a proper release before merging

@nandini-swami
nandini-swami merged commit d1b34dd into main Sep 15, 2026
7 checks passed
@nandini-swami
nandini-swami deleted the nandiniswami/disk-space-monitor branch September 15, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants