Fix noinlineerr findings: internal/vaultik (refs #61)

This commit is contained in:
2026-08-07 16:59:56 +00:00
parent 919229f224
commit e7b49d58ab
10 changed files with 123 additions and 56 deletions

View File

@@ -32,11 +32,13 @@ func TestFetchAndDecryptBlobVerifiesHash(t *testing.T) {
t.Fatalf("creating blobgen writer: %v", err)
}
if _, err := writer.Write(plaintext); err != nil {
_, err = writer.Write(plaintext)
if err != nil {
t.Fatalf("writing plaintext: %v", err)
}
if err := writer.Close(); err != nil {
err = writer.Close()
if err != nil {
t.Fatalf("closing writer: %v", err)
}
@@ -75,7 +77,8 @@ func TestFetchAndDecryptBlobVerifiesHash(t *testing.T) {
t.Fatalf("reading stream: %v", err)
}
if err := rc.Close(); err != nil {
err = rc.Close()
if err != nil {
t.Fatalf("close (hash verification) failed: %v", err)
}

View File

@@ -275,7 +275,9 @@ func (c *blobDiskCache) ReadAt(key string, offset, length int64) ([]byte, error)
defer func() { _ = f.Close() }()
buf := make([]byte, length)
if _, err := f.ReadAt(buf, offset); err != nil {
_, err = f.ReadAt(buf, offset)
if err != nil {
return nil, err
}

View File

@@ -15,7 +15,9 @@ func TestBlobDiskCache_BasicGetPut(t *testing.T) {
defer func() { _ = cache.Close() }()
data := []byte("hello world")
if err := cache.Put("key1", data); err != nil {
err = cache.Put("key1", data)
if err != nil {
t.Fatal(err)
}
@@ -74,7 +76,9 @@ func TestBlobDiskCache_OversizedEntryRejected(t *testing.T) {
defer func() { _ = cache.Close() }()
data := make([]byte, 200)
if err := cache.Put("big", data); err != nil {
err = cache.Put("big", data)
if err != nil {
t.Fatal(err)
}
@@ -90,11 +94,13 @@ func TestBlobDiskCache_UpdateInPlace(t *testing.T) {
}
defer func() { _ = cache.Close() }()
if err := cache.Put("key1", []byte("v1")); err != nil {
err = cache.Put("key1", []byte("v1"))
if err != nil {
t.Fatal(err)
}
if err := cache.Put("key1", []byte("version2")); err != nil {
err = cache.Put("key1", []byte("version2"))
if err != nil {
t.Fatal(err)
}
@@ -124,11 +130,14 @@ func TestBlobDiskCache_ReadAt(t *testing.T) {
defer func() { _ = cache.Close() }()
data := make([]byte, 1024)
if _, err := rand.Read(data); err != nil {
_, err = rand.Read(data)
if err != nil {
t.Fatal(err)
}
if err := cache.Put("blob1", data); err != nil {
err = cache.Put("blob1", data)
if err != nil {
t.Fatal(err)
}
@@ -158,11 +167,13 @@ func TestBlobDiskCache_Close(t *testing.T) {
t.Fatal(err)
}
if err := cache.Put("key1", []byte("data")); err != nil {
err = cache.Put("key1", []byte("data"))
if err != nil {
t.Fatal(err)
}
if err := cache.Close(); err != nil {
err = cache.Close()
if err != nil {
t.Fatal(err)
}
}
@@ -175,11 +186,14 @@ func TestBlobDiskCache_LRUOrder(t *testing.T) {
defer func() { _ = cache.Close() }()
d := make([]byte, 100)
if err := cache.Put("a", d); err != nil {
err = cache.Put("a", d)
if err != nil {
t.Fatal(err)
}
if err := cache.Put("b", d); err != nil {
err = cache.Put("b", d)
if err != nil {
t.Fatal(err)
}
@@ -187,7 +201,8 @@ func TestBlobDiskCache_LRUOrder(t *testing.T) {
cache.Get("a")
// Adding "c" should evict "b" (LRU), not "a"
if err := cache.Put("c", d); err != nil {
err = cache.Put("c", d)
if err != nil {
t.Fatal(err)
}

View File

@@ -79,7 +79,8 @@ func parseSnapshotName(snapshotID string) string {
// d/day/days, w/week/weeks, mo/month/months, y/year/years, plus standard Go
// duration units (h, m, s).
func parseDuration(s string) (time.Duration, error) {
if d, err := time.ParseDuration(s); err == nil {
d, err := time.ParseDuration(s)
if err == nil {
return d, nil
}

View File

@@ -97,7 +97,8 @@ func (v *Vaultik) ShowInfo() error {
v.printfStdout("Index Path: %s\n", v.Config.IndexPath)
// Check if index file exists and get its size
if info, err := v.Fs.Stat(v.Config.IndexPath); err == nil {
info, err := v.Fs.Stat(v.Config.IndexPath)
if err == nil {
v.printfStdout("Index Size: %s\n", humanize.Bytes(uint64(info.Size())))
// Get snapshot count from database
@@ -201,7 +202,8 @@ func (v *Vaultik) RemoteInfo(jsonOutput bool) error {
v.populateRemoteInfoResult(result, snapshotMetadata, snapshotIDs, referencedBlobs)
if err := v.scanRemoteBlobStorage(result, referencedBlobs, jsonOutput); err != nil {
err = v.scanRemoteBlobStorage(result, referencedBlobs, jsonOutput)
if err != nil {
return err
}

View File

@@ -29,13 +29,14 @@ func (v *Vaultik) NukeRemote(force bool) error {
v.UI.Begin("Removing all snapshot metadata from backup destination store.")
if _, err := v.RemoveAllSnapshots(&RemoveOptions{Force: true}); err != nil {
_, err := v.RemoveAllSnapshots(&RemoveOptions{Force: true})
if err != nil {
return fmt.Errorf("removing all snapshots: %w", err)
}
v.UI.Begin("Removing any blobs still present in backup destination store.")
err := v.PruneBlobs(&PruneOptions{Force: true})
err = v.PruneBlobs(&PruneOptions{Force: true})
if err != nil {
return fmt.Errorf("pruning blobs: %w", err)
}
@@ -74,7 +75,8 @@ func (v *Vaultik) Prune(opts *PruneOptions) error {
return fmt.Errorf("reconciling local snapshots with remote: %w", err)
}
if _, err := v.PruneDatabase(); err != nil {
_, err = v.PruneDatabase()
if err != nil {
return fmt.Errorf("pruning local database: %w", err)
}
@@ -121,7 +123,9 @@ func (v *Vaultik) PruneBlobs(opts *PruneOptions) error {
v.printfStdout("\nDelete %d unreferenced blob(s)? [y/N] ", len(unreferencedBlobs))
var confirm string
if _, err := v.scanStdin(&confirm); err != nil {
_, err = v.scanStdin(&confirm)
if err != nil {
v.printlnStdout("Cancelled")
return nil

View File

@@ -483,14 +483,16 @@ func (v *Vaultik) downloadSnapshotDB(snapshotID string, identity age.Identity) (
tempPath := tempFile.Name()
// Write the binary SQLite database directly
if _, err := tempFile.Write(dbData); err != nil {
_, err = tempFile.Write(dbData)
if err != nil {
_ = tempFile.Close()
_ = v.Fs.Remove(tempPath)
return nil, fmt.Errorf("writing database file: %w", err)
}
if err := tempFile.Close(); err != nil {
err = tempFile.Close()
if err != nil {
_ = v.Fs.Remove(tempPath)
return nil, fmt.Errorf("closing temp file: %w", err)
@@ -559,7 +561,9 @@ func (v *Vaultik) buildChunkToBlobMap(ctx context.Context, repos *database.Repos
bc database.BlobChunk
blobIDStr, chunkHashStr string
)
if err := rows.Scan(&blobIDStr, &chunkHashStr, &bc.Offset, &bc.Length); err != nil {
err = rows.Scan(&blobIDStr, &chunkHashStr, &bc.Offset, &bc.Length)
if err != nil {
return nil, fmt.Errorf("scanning blob_chunk: %w", err)
}
@@ -762,11 +766,13 @@ func (s *restoreSession) restoreRegularFile(file *database.File, targetPath stri
"ms_sweeper", sweeperDur.Milliseconds(),
)
if err := outFile.Close(); err != nil {
err = outFile.Close()
if err != nil {
return fmt.Errorf("closing output file: %w", err)
}
if err := s.v.Fs.Chmod(targetPath, os.FileMode(file.Mode)); err != nil {
err = s.v.Fs.Chmod(targetPath, os.FileMode(file.Mode))
if err != nil {
log.Debug("Failed to set file permissions", "path", targetPath, "error", err)
}
@@ -779,7 +785,8 @@ func (s *restoreSession) restoreRegularFile(file *database.File, targetPath stri
}
}
if err := s.v.Fs.Chtimes(targetPath, file.MTime, file.MTime); err != nil {
err = s.v.Fs.Chtimes(targetPath, file.MTime, file.MTime)
if err != nil {
log.Debug("Failed to set file mtime", "path", targetPath, "error", err)
}

View File

@@ -119,7 +119,8 @@ func (s *restoreSweeper) blobStillNeeded(blobHash string) (bool, error) {
}
}
if err := rows.Err(); err != nil {
err = rows.Err()
if err != nil {
return true, err
}

View File

@@ -56,7 +56,8 @@ func (v *Vaultik) CreateSnapshot(opts *SnapshotCreateOptions) error {
// Prune the database before starting: delete incomplete snapshots and orphaned data.
// This ensures the database is consistent before we start a new snapshot.
// Since we use locking, only one vaultik instance accesses the DB at a time.
if _, err := v.PruneDatabase(); err != nil {
_, err = v.PruneDatabase()
if err != nil {
return fmt.Errorf("prune database: %w", err)
}
@@ -195,7 +196,8 @@ func (v *Vaultik) createNamedSnapshot(opts *SnapshotCreateOptions, hostname, sna
v.collectUploadStats(scanner, stats)
if err := v.finalizeSnapshotMetadata(snapshotID, stats); err != nil {
err = v.finalizeSnapshotMetadata(snapshotID, stats)
if err != nil {
return err
}
@@ -395,7 +397,8 @@ func (v *Vaultik) getSnapshotBlobSizes(snapshotID string) (compressed int64, unc
}
for _, hash := range blobHashes {
if blob, err := v.Repositories.Blobs.GetByHash(v.ctx, hash); err == nil && blob != nil {
blob, err := v.Repositories.Blobs.GetByHash(v.ctx, hash)
if err == nil && blob != nil {
compressed += blob.CompressedSize
uncompressed += blob.UncompressedSize
}
@@ -453,7 +456,8 @@ func (v *Vaultik) ListSnapshots(jsonOutput bool) error {
return encoder.Encode(snapshots)
}
if err := v.printSnapshotTable(snapshots); err != nil {
err = v.printSnapshotTable(snapshots)
if err != nil {
return err
}
@@ -552,15 +556,18 @@ func (v *Vaultik) snapshotInfoFromLocal(ls *database.Snapshot) SnapshotInfo {
func (v *Vaultik) printSnapshotTable(snapshots []SnapshotInfo) error {
w := tabwriter.NewWriter(v.Stdout, 0, 0, 3, ' ', 0)
if _, err := fmt.Fprintln(w, "CONFIGURED SNAPSHOTS:"); err != nil {
_, err := fmt.Fprintln(w, "CONFIGURED SNAPSHOTS:")
if err != nil {
return err
}
if _, err := fmt.Fprintln(w, "NAME\tPATHS"); err != nil {
_, err = fmt.Fprintln(w, "NAME\tPATHS")
if err != nil {
return err
}
if _, err := fmt.Fprintln(w, "────\t─────"); err != nil {
_, err = fmt.Fprintln(w, "────\t─────")
if err != nil {
return err
}
@@ -568,16 +575,20 @@ func (v *Vaultik) printSnapshotTable(snapshots []SnapshotInfo) error {
snap := v.Config.Snapshots[name]
paths := strings.Join(snap.Paths, ", ")
if _, err := fmt.Fprintf(w, "%s\t%s\n", name, paths); err != nil {
_, err = fmt.Fprintf(w, "%s\t%s\n", name, paths)
if err != nil {
return err
}
}
if _, err := fmt.Fprintln(w); err != nil {
_, err = fmt.Fprintln(w)
if err != nil {
return err
}
if _, err := fmt.Fprintln(w, "REMOTE SNAPSHOTS:"); err != nil {
_, err = fmt.Fprintln(w, "REMOTE SNAPSHOTS:")
if err != nil {
return err
}
@@ -599,12 +610,13 @@ func (v *Vaultik) printSnapshotTable(snapshots []SnapshotInfo) error {
newChunks = formatBytes(snap.NewChunkSize)
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
_, err = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
snap.ID,
snap.Timestamp.Format("2006-01-02 15:04:05"),
formatBytes(snap.CompressedSize),
uncompressed,
newChunks); err != nil {
newChunks)
if err != nil {
return err
}
}
@@ -626,11 +638,13 @@ type SnapshotPurgeOptions struct {
// snapshot name, not the latest globally. This prevents `home` and `system`
// snapshots from cannibalizing each other.
func (v *Vaultik) PurgeSnapshotsWithOptions(opts *SnapshotPurgeOptions) error {
if err := v.EnsureStorageBinding(); err != nil {
err := v.EnsureStorageBinding()
if err != nil {
return err
}
// Sync with remote first
if err := v.syncWithRemote(); err != nil {
err = v.syncWithRemote()
if err != nil {
return fmt.Errorf("syncing with remote: %w", err)
}
@@ -731,7 +745,9 @@ func (v *Vaultik) confirmAndExecutePurge(toDelete []SnapshotInfo, force, quiet b
v.printfStdout("\nDelete %d snapshot(s)? [y/N] ", len(toDelete))
var confirm string
if _, err := v.scanStdin(&confirm); err != nil {
_, err := v.scanStdin(&confirm)
if err != nil {
// Treat EOF or error as "no"
v.printlnStdout("Cancelled")
@@ -829,7 +845,8 @@ func (v *Vaultik) VerifySnapshotWithOptions(snapshotID string, opts *VerifyOptio
v.printfStdout(" Total size: %s\n", humanize.Bytes(uint64(manifest.TotalCompressedSize)))
if manifest.Timestamp != "" {
if t, err := time.Parse(time.RFC3339, manifest.Timestamp); err == nil {
t, err := time.Parse(time.RFC3339, manifest.Timestamp)
if err == nil {
v.printfStdout(" Created: %s\n", t.Format("2006-01-02 15:04:05 MST"))
}
}
@@ -849,7 +866,9 @@ func (v *Vaultik) VerifySnapshotWithOptions(snapshotID string, opts *VerifyOptio
// Snapshot ID format: hostname[_name]_<RFC3339>
func (v *Vaultik) printVerifyHeader(snapshotID string, opts *VerifyOptions) {
var snapshotTime time.Time
if t, err := parseSnapshotTimestamp(snapshotID); err == nil {
t, err := parseSnapshotTimestamp(snapshotID)
if err == nil {
snapshotTime = t
}
@@ -945,7 +964,8 @@ func (v *Vaultik) outputVerifyJSON(result *VerifyResult) error {
// human ID is hashed via RemoteSnapshotKey and compared against the
// remote listing.
func (v *Vaultik) CleanupLocalSnapshots() error {
if err := v.EnsureStorageBinding(); err != nil {
err := v.EnsureStorageBinding()
if err != nil {
return err
}
@@ -1137,7 +1157,9 @@ func (v *Vaultik) RemoveSnapshot(snapshotID string, opts *RemoveOptions) (*Remov
}
var confirm string
if _, err := v.scanStdin(&confirm); err != nil {
_, err = v.scanStdin(&confirm)
if err != nil {
v.printlnStdout("Cancelled")
return result, nil
@@ -1205,7 +1227,8 @@ func (v *Vaultik) RemoveSnapshot(snapshotID string, opts *RemoveOptions) (*Remov
// "remove --all" leaves nothing behind, even when the local DB and
// remote storage have diverged.
func (v *Vaultik) RemoveAllSnapshots(opts *RemoveOptions) (*RemoveResult, error) {
if err := v.EnsureStorageBinding(); err != nil {
err := v.EnsureStorageBinding()
if err != nil {
return nil, err
}
@@ -1563,7 +1586,8 @@ func (v *Vaultik) PruneDatabase() (*PruneResult, error) {
blobCountBefore, _ := v.getTableCount("blobs")
// Run the cleanup
if err := v.SnapshotManager.CleanupOrphanedData(v.ctx); err != nil {
err = v.SnapshotManager.CleanupOrphanedData(v.ctx)
if err != nil {
return nil, fmt.Errorf("cleanup orphaned data: %w", err)
}

View File

@@ -90,7 +90,8 @@ func (v *Vaultik) RunDeepVerify(snapshotID string, opts *VerifyOptions) error {
result.TotalSize = totalSize
if err := v.runVerificationSteps(manifest, dbBlobs, tempDB, opts, result, totalSize); err != nil {
err = v.runVerificationSteps(manifest, dbBlobs, tempDB, opts, result, totalSize)
if err != nil {
return err
}
@@ -337,7 +338,8 @@ func (v *Vaultik) verifyBlob(blobInfo snapshot.BlobInfo, db *sql.DB) error {
return err
}
if err := v.verifyBlobFinalIntegrity(decompressor, blobHasher, blobInfo.Hash); err != nil {
err = v.verifyBlobFinalIntegrity(decompressor, blobHasher, blobInfo.Hash)
if err != nil {
return err
}
@@ -396,7 +398,9 @@ func (v *Vaultik) verifyBlobChunks(db *sql.DB, blobHash string, decompressor io.
if offset > totalRead {
// Skip to the correct offset
skipBytes := offset - totalRead
if _, err := io.CopyN(io.Discard, decompressor, skipBytes); err != nil {
_, err = io.CopyN(io.Discard, decompressor, skipBytes)
if err != nil {
return 0, fmt.Errorf("failed to skip to offset %d: %w", offset, err)
}
@@ -405,7 +409,9 @@ func (v *Vaultik) verifyBlobChunks(db *sql.DB, blobHash string, decompressor io.
// Read chunk data
chunkData := make([]byte, length)
if _, err := io.ReadFull(decompressor, chunkData); err != nil {
_, err = io.ReadFull(decompressor, chunkData)
if err != nil {
return 0, fmt.Errorf("failed to read chunk at offset %d: %w", offset, err)
}
@@ -424,7 +430,8 @@ func (v *Vaultik) verifyBlobChunks(db *sql.DB, blobHash string, decompressor io.
chunkCount++
}
if err := rows.Err(); err != nil {
err = rows.Err()
if err != nil {
return 0, fmt.Errorf("error iterating blob chunks: %w", err)
}
@@ -490,7 +497,8 @@ func (v *Vaultik) getBlobsFromDatabase(snapshotID string, db *sql.DB) ([]snapsho
})
}
if err := rows.Err(); err != nil {
err = rows.Err()
if err != nil {
return nil, fmt.Errorf("error iterating blobs: %w", err)
}