// Command zfs-server is the main entry point for the ZFS snapshot backup server. // It initializes the server with S3 or local storage and starts the HTTP API. package main import ( "log" "net/http" "os" "time" "git.ma-al.com/goc_marek/zfs/internal/server" ) func main() { // Load configuration from .env file and environment cfg := server.LoadConfig() // Initialize backends var s3Backend *server.S3Backend var err error if cfg.S3Enabled { s3Backend, err = server.NewS3Backend(cfg.S3Endpoint, cfg.S3AccessKey, cfg.S3SecretKey, cfg.S3BucketName, cfg.S3UseSSL) if err != nil { log.Fatalf("Failed to initialize S3 backend: %v", err) } log.Printf("Initialized S3 backend: %s/%s", cfg.S3Endpoint, cfg.S3BucketName) } else { log.Println("S3 backend disabled, using local ZFS storage only") } localBackend := server.NewLocalBackend(cfg.BaseDataset) // Create metadata directory if needed dir := cfg.MetadataFile if idx := len(dir) - 1; idx > 0 { for i := len(dir) - 1; i >= 0; i-- { if dir[i] == '/' { dir = dir[:i] break } } os.MkdirAll(dir, 0755) } srv := server.New(cfg.ConfigFile, cfg.MetadataFile, s3Backend, localBackend) // Register HTTP routes mux := http.NewServeMux() srv.RegisterRoutes(mux) // Create HTTP server with timeouts for security and reliability httpServer := &http.Server{ Addr: ":" + cfg.Port, Handler: mux, ReadTimeout: 30 * time.Second, // Prevent slowloris attacks WriteTimeout: 30 * time.Minute, // Allow large file uploads IdleTimeout: 120 * time.Second, // Close idle connections } log.Printf("ZFS Snapshot Server starting on port %s", cfg.Port) log.Printf("Config file: %s", cfg.ConfigFile) log.Printf("Metadata file: %s", cfg.MetadataFile) log.Printf("S3 enabled: %v", cfg.S3Enabled) if err := httpServer.ListenAndServe(); err != nil { log.Fatal(err) } }