hirochachacha/go-smb2 has no fix for GO-2026-5051, an out-of-bounds read in ReadDir that govulncheck reports as called from walkPath. The cloudsoda fork carries the fix. Dialer.DialConn replaces Dial.
The dashboard was showing 335 packages while the packages page showed 141
because GetStats was counting .mod and .info files as separate packages.
Changes:
- Filter out .mod and .info files in GetStats query
- Now only counts actual packages (.zip files)
- Dashboard and packages page counts will match
This fixes the discrepancy where:
- Dashboard (/api/stats): was 335, now will be ~141
- Packages page (/api/packages): already 141 (deduplicated)
Resolves: "Dashboard showing 335 packages but /packages showing 141"
Go module metadata files (.mod and .info) are not actual packages
and should not be scanned for vulnerabilities. Only .zip files
contain the actual module code.
Changes:
- Added .mod and .info suffix checks to isMetadataEntry filter
- These files are now excluded from database storage
- Scanner won't attempt to scan them during rescan cycles
This fixes OSV scanner 404 errors for metadata files like:
- github.com/mattn/go-isatty/@v/v0.0.20.mod
- github.com/clipperhouse/stringish/@v/v0.1.1.info
Resolves: OSV API errors "The current request is not defined by this API"
for Go module metadata files
Issues fixed:
1. Charts not rendering correctly due to sparse data (missing time buckets)
2. Period "1h" returning empty data when aggregate stats not yet available
Changes:
- Generate continuous time series with 0 values for all time buckets
- Truncate start time to hour/day boundaries for consistent bucketing
- Fallback to package-level stats aggregation when registry totals unavailable
- Add proper time range filtering (since <= time_bucket <= now)
Behavior now:
- All time periods (1h, 1day, 7day, 30day) return complete data sets
- Missing hours/days are filled with value: 0
- Chart libraries can render continuous lines/bars correctly
- No more empty data for "1h" period
Example output (1 hour period):
Before: [{"timestamp":"14:00","value":5}, {"timestamp":"15:00","value":3}]
After: [{"timestamp":"13:00","value":0}, {"timestamp":"14:00","value":5},
{"timestamp":"15:00","value":3}, {"timestamp":"16:00","value":0}]
Resolves: "Chart doesn't generate correctly - it should automatically
fill 0 for the empty periods to render correctly"
Previously, download counts only incremented on cache hits (when package
was served from cache). First-time downloads (cache misses) were not counted.
Changes:
- Add UpdateDownloadCount() call when serving newly cached packages
- This ensures every download through the proxy increments the counter
- Analytics tracking also added for cache misses
Behavior now:
- First download (cache miss): counter = 1
- Second download (cache hit): counter = 2
- Third download (cache hit): counter = 3
- etc.
Updated all relevant tests to expect the additional UpdateDownloadCount call.
Resolves user requirement: "I want the counters to increase whenever
package is downloaded via proxy - regardless of it being new download
or cached download"
Problem:
- Download counts were not incrementing when packages existed in storage
but not in the database (e.g., after database migration/reset)
- UpdateDownloadCount() was failing silently when package didn't exist in DB
- Error was completely ignored despite comment claiming "error logged"
Changes:
1. Log errors when UpdateDownloadCount() fails instead of silently ignoring
2. Auto-save package to database if UpdateDownloadCount() fails
3. Retry download count update after saving package
4. Provide detailed error logging for troubleshooting
This fixes the issue where:
- Database is migrated but storage still has cached packages
- Cache hits occur but download events aren't recorded
- Statistics show zero downloads despite actual usage
Resolves user report: "I cleaned go mod which redownloaded the modules
through the proxy but counters did not increased"
- Rate limits (403) are now accepted as healthy
- Rate limiting is expected without a GitHub token
- Only real errors (network failures, 500s) fail the health check
- Prevents health check failures due to unauthenticated API usage
Related: GHSA scanner health checks
- Scanner failures (e.g., GitHub API rate limits) no longer mark server as unhealthy
- Server can still serve cached packages when scanners are unavailable
- Readiness probes will now pass with degraded scanner status
- Prevents unnecessary pod restarts due to external API issues
Fixes: Readiness probes failing with 503 due to GHSA rate limiting
- OSV API expects clean module paths like 'gorm.io/driver/sqlite'
- Cache keys include Go proxy format like 'gorm.io/driver/sqlite/@v/v1.6.0.zip'
- Added cleanGoModuleName() to extract module path and version
- Strips /@v/ prefix and .zip/.mod/.info suffixes
- Fixes 404 errors when scanning Go modules
Resolves: OSV API returning 404 for Go module scans
- [x] Implement GORM V2 metadata store with SQLite, PostgreSQL, and MySQL support
- [x] Add database migration system using gormigrate for schema versioning
- [x] Create migration CLI tool with support for migrate, rollback, and status commands
- [x] Add Docker support for migration container (Dockerfile.migrate)
- [x] Implement automatic partition management for PostgreSQL time-series tables
- [x] Add background aggregation worker for download statistics
- [x] Support connection pooling configuration (max_open_conns, max_idle_conns, conn_max_lifetime)
- [x] Add blocking mechanism based on vulnerability thresholds in stats and handlers
- [x] Update Helm charts with migration init containers and multi-database configuration
- [x] Replace deprecated SQLite store with optimized GORM implementation
- [x] Add comprehensive integration tests for MySQL and PostgreSQL
- [x] Update frontend to display blocked packages and storage utilization
- [x] Add goreleaser configuration for migrate binary and container image
- [x] Update configuration examples with database backend options and recommendations