Go to file
2025-05-28 15:38:18 +03:00
archive Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
examples Updated package name 2025-05-08 11:32:21 +03:00
grpc Updated package name 2025-05-08 11:32:21 +03:00
hash Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
interfaces Updated package name 2025-05-08 11:32:21 +03:00
remote Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
store Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
stores Updated package name 2025-05-08 11:32:21 +03:00
.gitignore Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
api_test.go Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
api.go Quick 2025-05-28 15:38:18 +03:00
errors.go Add initial implementation of Agate snapshot library 2025-04-24 02:44:16 +03:00
functional_test.go Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
go.mod Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
go.sum Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
grpc_test.go Add gRPC server-client integration test for snapshot handling 2025-05-11 01:24:41 +03:00
Makefile Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
manager_test.go Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
manager.go Fixed error on snapshot creating 2025-05-25 03:26:37 +03:00
performance_test.go Add comprehensive test coverage for core functionalities 2025-05-10 20:13:29 +03:00
README.md Add active directory management for snapshot operations 2025-05-10 00:57:34 +03:00
snapshot.go Updated package name 2025-05-08 11:32:21 +03:00

Agate

Agate is a Go library for creating, managing, and sharing snapshots of directories. It provides functionality for creating incremental snapshots, storing them efficiently, and sharing them over a network using gRPC.

Installation

go get gitea.unprism.ru/KRBL/Agate

Features

  • Create snapshots of directories
  • Incremental snapshots (only store changes)
  • Restore snapshots
  • List and manage snapshots
  • Share snapshots over a network using gRPC
  • Connect to remote snapshot repositories

Basic Usage

Creating a Snapshot Repository

To create a snapshot repository, you need to initialize the Agate library with the appropriate options:

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"path/filepath"

	"gitea.unprism.ru/KRBL/Agate"
	"gitea.unprism.ru/KRBL/Agate/stores"
)

func main() {
	// Create directories for your repository
	workDir := "/path/to/your/repository"
	if err := os.MkdirAll(workDir, 0755); err != nil {
		log.Fatalf("Failed to create work directory: %v", err)
	}

	// Initialize the default stores
	metadataStore, blobStore, err := stores.InitDefaultStores(workDir)
	if err != nil {
		log.Fatalf("Failed to initialize stores: %v", err)
	}
	defer metadataStore.Close()

	// Initialize Agate
	agateOptions := agate.AgateOptions{
		WorkDir:       workDir,
		MetadataStore: metadataStore,
		BlobStore:     blobStore,
	}

	ag, err := agate.New(agateOptions)
	if err != nil {
		log.Fatalf("Failed to initialize Agate: %v", err)
	}
	defer ag.Close()

	// Create a snapshot
	ctx := context.Background()
	snapshotID, err := ag.SaveSnapshot(ctx, "My First Snapshot", "")
	if err != nil {
		log.Fatalf("Failed to create snapshot: %v", err)
	}
	fmt.Printf("Created snapshot with ID: %s\n", snapshotID)

	// List snapshots
	snapshots, err := ag.ListSnapshots(ctx)
	if err != nil {
		log.Fatalf("Failed to list snapshots: %v", err)
	}
	fmt.Printf("Found %d snapshots:\n", len(snapshots))
	for _, s := range snapshots {
		fmt.Printf("  - %s: %s (created at %s)\n", s.ID, s.Name, s.CreationTime.Format("2006-01-02 15:04:05"))
	}
}

Hosting a Snapshot Repository

To host a snapshot repository and make it available over the network, you can use the StartServer method:

package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"syscall"

	"gitea.unprism.ru/KRBL/Agate"
	"gitea.unprism.ru/KRBL/Agate/stores"
)

func main() {
	// Create directories for your repository
	workDir := "/path/to/your/repository"
	if err := os.MkdirAll(workDir, 0755); err != nil {
		log.Fatalf("Failed to create work directory: %v", err)
	}

	// Initialize the default stores
	metadataStore, blobStore, err := stores.InitDefaultStores(workDir)
	if err != nil {
		log.Fatalf("Failed to initialize stores: %v", err)
	}
	defer metadataStore.Close()

	// Initialize Agate
	agateOptions := agate.AgateOptions{
		WorkDir:       workDir,
		MetadataStore: metadataStore,
		BlobStore:     blobStore,
	}

	ag, err := agate.New(agateOptions)
	if err != nil {
		log.Fatalf("Failed to initialize Agate: %v", err)
	}
	defer ag.Close()

	// Start the gRPC server
	ctx := context.Background()
	address := "0.0.0.0:50051" // Listen on all interfaces, port 50051
	if err := ag.StartServer(ctx, address); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}

	log.Printf("Server started on %s", address)

	// Wait for termination signal
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	log.Println("Shutting down...")
}

Connecting to a Hosted Snapshot Repository

To connect to a hosted snapshot repository and retrieve snapshots:

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"gitea.unprism.ru/KRBL/Agate"
	"gitea.unprism.ru/KRBL/Agate/stores"
)

func main() {
	// Create directories for your local repository
	workDir := "/path/to/your/local/repository"
	if err := os.MkdirAll(workDir, 0755); err != nil {
		log.Fatalf("Failed to create work directory: %v", err)
	}

	// Initialize the default stores
	metadataStore, blobStore, err := stores.InitDefaultStores(workDir)
	if err != nil {
		log.Fatalf("Failed to initialize stores: %v", err)
	}
	defer metadataStore.Close()

	// Initialize Agate
	agateOptions := agate.AgateOptions{
		WorkDir:       workDir,
		MetadataStore: metadataStore,
		BlobStore:     blobStore,
	}

	ag, err := agate.New(agateOptions)
	if err != nil {
		log.Fatalf("Failed to initialize Agate: %v", err)
	}
	defer ag.Close()

	// Connect to a remote server
	ctx := context.Background()
	remoteAddress := "remote-server:50051"

	// List snapshots from the remote server
	snapshots, err := ag.GetRemoteSnapshotList(ctx, remoteAddress)
	if err != nil {
		log.Fatalf("Failed to list remote snapshots: %v", err)
	}

	fmt.Printf("Found %d remote snapshots:\n", len(snapshots))
	for _, s := range snapshots {
		fmt.Printf("  - %s: %s (created at %s)\n", s.ID, s.Name, s.CreationTime.Format("2006-01-02 15:04:05"))
	}

	// Download a specific snapshot
	if len(snapshots) > 0 {
		snapshotID := snapshots[0].ID
		fmt.Printf("Downloading snapshot %s...\n", snapshotID)

		// Download the snapshot (pass empty string as localParentID if this is the first download)
		if err := ag.GetRemoteSnapshot(ctx, remoteAddress, snapshotID, ""); err != nil {
			log.Fatalf("Failed to download snapshot: %v", err)
		}

		fmt.Printf("Successfully downloaded snapshot %s\n", snapshotID)
	}
}

Advanced Usage

Creating Incremental Snapshots

You can create incremental snapshots by specifying a parent snapshot ID:

// Create a first snapshot
snapshotID1, err := ag.SaveSnapshot(ctx, "First Snapshot", "")
if err != nil {
    log.Fatalf("Failed to create first snapshot: %v", err)
}

// Make some changes to your files...

// Create a second snapshot with the first one as parent
snapshotID2, err := ag.SaveSnapshot(ctx, "Second Snapshot", snapshotID1)
if err != nil {
    log.Fatalf("Failed to create second snapshot: %v", err)
}

Restoring a Snapshot

To restore a snapshot:

if err := ag.RestoreSnapshot(ctx, snapshotID); err != nil {
    log.Fatalf("Failed to restore snapshot: %v", err)
}

Getting Snapshot Details

To get detailed information about a snapshot:

snapshot, err := ag.GetSnapshotDetails(ctx, snapshotID)
if err != nil {
    log.Fatalf("Failed to get snapshot details: %v", err)
}

fmt.Printf("Snapshot: %s\n", snapshot.Name)
fmt.Printf("Created: %s\n", snapshot.CreationTime.Format("2006-01-02 15:04:05"))
fmt.Printf("Files: %d\n", len(snapshot.Files))

Deleting a Snapshot

To delete a snapshot:

if err := ag.DeleteSnapshot(ctx, snapshotID); err != nil {
    log.Fatalf("Failed to delete snapshot: %v", err)
}

API Reference

Agate

The main entry point for the library.

  • New(options AgateOptions) (*Agate, error) - Create a new Agate instance
  • SaveSnapshot(ctx context.Context, name string, parentID string) (string, error) - Create a new snapshot
  • RestoreSnapshot(ctx context.Context, snapshotID string) error - Restore a snapshot
  • ListSnapshots(ctx context.Context) ([]store.SnapshotInfo, error) - List all snapshots
  • GetSnapshotDetails(ctx context.Context, snapshotID string) (*store.Snapshot, error) - Get details of a snapshot
  • DeleteSnapshot(ctx context.Context, snapshotID string) error - Delete a snapshot
  • StartServer(ctx context.Context, address string) error - Start a gRPC server to share snapshots
  • ConnectRemote(address string) (*grpc.SnapshotClient, error) - Connect to a remote server
  • GetRemoteSnapshotList(ctx context.Context, address string) ([]store.SnapshotInfo, error) - List snapshots from a remote server
  • GetRemoteSnapshot(ctx context.Context, address string, snapshotID string, localParentID string) error - Download a snapshot from a remote server

AgateOptions

Configuration options for the Agate library.

  • WorkDir string - Directory where snapshots will be stored and managed
  • OpenFunc func(dir string) error - Called after a snapshot is restored
  • CloseFunc func() error - Called before a snapshot is created or restored
  • MetadataStore store.MetadataStore - Implementation of the metadata store
  • BlobStore store.BlobStore - Implementation of the blob store

License

[Add your license information here]