Problem
When running bb repo list, the Size column only shows values for repos on the current host. Repos registered on other machines display "Unknown" for their size.
Current Implementation
The size data comes from the metadata field on BorgBoiRepo, which holds a RepoInfo obtained by running borg info against the local repo path.
When converting DynamoDB items to BorgBoiRepo objects (src/borgboi/clients/dynamodb.py:96-104), metadata is only populated for local repos:
metadata = None
if validator.repo_is_local(item):
passphrase = resolve_passphrase(...)
metadata = borg.info(item.repo_path, passphrase=passphrase)
repo_is_local (src/borgboi/validator.py:28-29) compares the repo's stored hostname against socket.gethostname(). If they don't match, metadata stays None and the size column renders as "Unknown".
The rendering logic in output_repos_table (src/borgboi/rich_utils.py:98-103) then falls through:
if repo.metadata is None:
size = "Unknown"
Why It Works This Way
borg info requires the repo directory to exist on the local filesystem. For repos registered on a different host, the path doesn't exist locally, so calling borg info would fail. The code correctly avoids this.
Potential Solutions
1. Persist metadata/size in the storage backend at backup time
When a backup runs on the originating host (where the repo is local), persist the RepoInfo (or at minimum the cache stats like unique_csize_gb) to DynamoDB alongside the other repo fields. Then list_repos can display the last-known size for all repos without needing to call borg info at read time.
Pros: Simple, no new infrastructure, works with existing DynamoDB table (just add attributes).
Cons: Size data is only as fresh as the last backup from the originating host.
2. Hybrid approach — live local data, cached remote data
For local repos, continue calling borg info at list time to get live data. For remote repos, fall back to the cached size from the storage backend (populated per solution 1).
Pros: Best of both worlds — live data when available, stale-but-useful data otherwise.
Cons: Slightly more complex rendering logic; could indicate staleness in the UI (e.g., show the date the size was last updated).
3. Query S3 object sizes as a proxy
Use the existing S3 client to sum object sizes for the repo's S3 prefix. This gives an approximation of the deduplicated/compressed repo size.
Pros: Works for any repo that has been synced to S3, no changes to DynamoDB schema needed.
Cons: S3 size may differ from the actual borg repo size; requires S3 access; doesn't work in offline mode; listing objects can be slow for large repos.
Recommendation
Solution 2 (hybrid) is likely the best path forward. It provides live accuracy for local repos while giving useful stale data for remote repos. The implementation would involve:
- Saving
RepoInfo (or a size subset) to DynamoDB/SQLite during daily_backup or backup operations
- Loading cached metadata during
_convert_table_item_to_repo when repo_is_local() is false
- Optionally annotating the size in the table output to indicate when data is cached (e.g., showing the cache date)
Problem
When running
bb repo list, the Size column only shows values for repos on the current host. Repos registered on other machines display "Unknown" for their size.Current Implementation
The size data comes from the
metadatafield onBorgBoiRepo, which holds aRepoInfoobtained by runningborg infoagainst the local repo path.When converting DynamoDB items to
BorgBoiRepoobjects (src/borgboi/clients/dynamodb.py:96-104), metadata is only populated for local repos:repo_is_local(src/borgboi/validator.py:28-29) compares the repo's stored hostname againstsocket.gethostname(). If they don't match,metadatastaysNoneand the size column renders as "Unknown".The rendering logic in
output_repos_table(src/borgboi/rich_utils.py:98-103) then falls through:Why It Works This Way
borg inforequires the repo directory to exist on the local filesystem. For repos registered on a different host, the path doesn't exist locally, so callingborg infowould fail. The code correctly avoids this.Potential Solutions
1. Persist metadata/size in the storage backend at backup time
When a backup runs on the originating host (where the repo is local), persist the
RepoInfo(or at minimum the cache stats likeunique_csize_gb) to DynamoDB alongside the other repo fields. Thenlist_reposcan display the last-known size for all repos without needing to callborg infoat read time.Pros: Simple, no new infrastructure, works with existing DynamoDB table (just add attributes).
Cons: Size data is only as fresh as the last backup from the originating host.
2. Hybrid approach — live local data, cached remote data
For local repos, continue calling
borg infoat list time to get live data. For remote repos, fall back to the cached size from the storage backend (populated per solution 1).Pros: Best of both worlds — live data when available, stale-but-useful data otherwise.
Cons: Slightly more complex rendering logic; could indicate staleness in the UI (e.g., show the date the size was last updated).
3. Query S3 object sizes as a proxy
Use the existing S3 client to sum object sizes for the repo's S3 prefix. This gives an approximation of the deduplicated/compressed repo size.
Pros: Works for any repo that has been synced to S3, no changes to DynamoDB schema needed.
Cons: S3 size may differ from the actual borg repo size; requires S3 access; doesn't work in offline mode; listing objects can be slow for large repos.
Recommendation
Solution 2 (hybrid) is likely the best path forward. It provides live accuracy for local repos while giving useful stale data for remote repos. The implementation would involve:
RepoInfo(or a size subset) to DynamoDB/SQLite duringdaily_backuporbackupoperations_convert_table_item_to_repowhenrepo_is_local()is false