Remove obsolete gRPC client/server implementations and migrate to remote package

This commit is contained in:
2025-07-13 23:12:39 +03:00
parent efa2bec38b
commit aaf227f25a
12 changed files with 647 additions and 1352 deletions

View File

@ -2,6 +2,7 @@ package agate
import (
"archive/zip"
"bytes"
"context"
"errors"
"fmt"
@ -31,6 +32,11 @@ func CreateSnapshotManager(metadataStore store.MetadataStore, blobStore store.Bl
return nil, errors.New("parameters can't be nil")
}
// Ensure logger is never nil.
if logger == nil {
logger = log.New(io.Discard, "", 0)
}
return &SnapshotManagerData{
metadataStore: metadataStore,
blobStore: blobStore,
@ -183,31 +189,24 @@ func (data *SnapshotManagerData) DeleteSnapshot(ctx context.Context, snapshotID
return errors.New("snapshot ID cannot be empty")
}
// First check if the snapshot exists and get its details
snapshot, err := data.metadataStore.GetSnapshotMetadata(ctx, snapshotID)
if err != nil {
if errors.Is(err, ErrNotFound) {
// If snapshot doesn't exist, return success (idempotent operation)
if errors.Is(err, store.ErrNotFound) {
return nil
}
return fmt.Errorf("failed to check if snapshot exists: %w", err)
}
// Get the parent ID of the snapshot being deleted
parentID := snapshot.ParentID
// Find all snapshots that have the deleted snapshot as their parent
// We need to update their parent ID to maintain the chain
opts := store.ListOptions{}
allSnapshots, err := data.metadataStore.ListSnapshotsMetadata(ctx, opts)
if err != nil {
return fmt.Errorf("failed to list snapshots: %w", err)
}
// Update parent references for any snapshots that have this one as a parent
for _, info := range allSnapshots {
if info.ParentID == snapshotID {
// Используем новый, более надежный метод для обновления только parent_id
if err := data.metadataStore.UpdateSnapshotParentID(ctx, info.ID, parentID); err != nil {
data.logger.Printf("WARNING: failed to update parent reference for snapshot %s: %v", info.ID, err)
} else {
@ -216,16 +215,11 @@ func (data *SnapshotManagerData) DeleteSnapshot(ctx context.Context, snapshotID
}
}
// Delete the metadata first
if err := data.metadataStore.DeleteSnapshotMetadata(ctx, snapshotID); err != nil {
return fmt.Errorf("failed to delete snapshot metadata: %w", err)
}
// Then delete the blob
if err := data.blobStore.DeleteBlob(ctx, snapshotID); err != nil {
// Note: We don't return here because we've already deleted the metadata
// and the blob store should handle the case where the blob doesn't exist
// Log the error instead
data.logger.Printf("WARNING: failed to delete snapshot blob: %v", err)
}
@ -392,22 +386,130 @@ func (data *SnapshotManagerData) UpdateSnapshotMetadata(ctx context.Context, sna
return errors.New("new name cannot be empty")
}
// Get the current snapshot metadata
snapshot, err := data.metadataStore.GetSnapshotMetadata(ctx, snapshotID)
if err != nil {
if errors.Is(err, ErrNotFound) {
if errors.Is(err, store.ErrNotFound) {
return ErrNotFound
}
return fmt.Errorf("failed to get snapshot metadata: %w", err)
}
// Update the name
snapshot.Name = newName
// Save the updated metadata
if err := data.metadataStore.SaveSnapshotMetadata(ctx, *snapshot); err != nil {
return fmt.Errorf("failed to update snapshot metadata: %w", err)
}
return nil
}
// diffArchiveReader is a wrapper around an *os.File that handles cleanup of temporary files.
type diffArchiveReader struct {
*os.File
tempArchive string
tempStaging string
}
// Close closes the file and removes the temporary archive and staging directory.
func (r *diffArchiveReader) Close() error {
err := r.File.Close()
os.Remove(r.tempArchive)
os.RemoveAll(r.tempStaging)
return err
}
func (data *SnapshotManagerData) StreamSnapshotDiff(ctx context.Context, snapshotID, parentID string, offset int64) (io.ReadCloser, error) {
targetSnap, err := data.metadataStore.GetSnapshotMetadata(ctx, snapshotID)
if err != nil {
return nil, fmt.Errorf("failed to get target snapshot metadata: %w", err)
}
parentFiles := make(map[string]string)
if parentID != "" {
parentSnap, err := data.metadataStore.GetSnapshotMetadata(ctx, parentID)
if err == nil {
for _, file := range parentSnap.Files {
if !file.IsDir {
parentFiles[file.Path] = file.SHA256
}
}
} else {
data.logger.Printf("Warning: failed to get parent snapshot %s, creating full diff: %v", parentID, err)
}
}
var filesToInclude []string
for _, file := range targetSnap.Files {
if file.IsDir {
continue
}
if parentHash, ok := parentFiles[file.Path]; !ok || parentHash != file.SHA256 {
filesToInclude = append(filesToInclude, file.Path)
}
}
if len(filesToInclude) == 0 {
return io.NopCloser(bytes.NewReader(nil)), nil
}
tempStagingDir, err := os.MkdirTemp(data.blobStore.GetBaseDir(), "diff-staging-*")
if err != nil {
return nil, fmt.Errorf("failed to create temp staging directory: %w", err)
}
targetBlobPath, err := data.blobStore.GetBlobPath(ctx, snapshotID)
if err != nil {
os.RemoveAll(tempStagingDir)
return nil, err
}
for _, filePath := range filesToInclude {
destPath := filepath.Join(tempStagingDir, filePath)
if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
os.RemoveAll(tempStagingDir)
return nil, fmt.Errorf("failed to create dir for diff file: %w", err)
}
fileWriter, err := os.Create(destPath)
if err != nil {
os.RemoveAll(tempStagingDir)
return nil, err
}
err = archive.ExtractFileFromArchive(targetBlobPath, filePath, fileWriter)
fileWriter.Close()
if err != nil {
os.RemoveAll(tempStagingDir)
return nil, fmt.Errorf("failed to extract file %s for diff: %w", filePath, err)
}
}
tempArchivePath := filepath.Join(data.blobStore.GetBaseDir(), "diff-"+snapshotID+".zip")
if err := archive.CreateArchive(tempStagingDir, tempArchivePath); err != nil {
os.RemoveAll(tempStagingDir)
os.Remove(tempArchivePath)
return nil, fmt.Errorf("failed to create diff archive: %w", err)
}
archiveFile, err := os.Open(tempArchivePath)
if err != nil {
os.RemoveAll(tempStagingDir)
os.Remove(tempArchivePath)
return nil, err
}
if offset > 0 {
if _, err := archiveFile.Seek(offset, io.SeekStart); err != nil {
archiveFile.Close()
os.RemoveAll(tempStagingDir)
os.Remove(tempArchivePath)
return nil, fmt.Errorf("failed to seek in diff archive: %w", err)
}
}
return &diffArchiveReader{
File: archiveFile,
tempArchive: tempArchivePath,
tempStaging: tempStagingDir,
}, nil
}