cachefs/cmd/cachefs/main.go

153 lines
3.5 KiB
Go

// Copyright (C) 2022 Marius Schellenberger
package main
import (
"context"
"flag"
"net/http"
//_ "net/http/pprof"
"os"
"os/signal"
"syscall"
"time"
"cachefs/pkg/fs"
"cachefs/pkg/srv"
"github.com/go-logr/logr"
"k8s.io/klog/v2"
"k8s.io/klog/v2/klogr"
)
var (
version string
src string
dst string
metadata string
listenHttp string
listenWebdav string
listenCache string
quota int64
max int
bs int
block bool
log logr.Logger
)
const gib = 1024 * 1024 * 1024
func main() {
klog.InitFlags(nil)
flag.StringVar(&src, "src", "", "url path to source files (example: file:///mnt/nfs)")
flag.StringVar(&dst, "dst", "", "url path to cache files (example: file:///mnt/cache)")
flag.StringVar(&metadata, "data", "", "path to metadata file")
flag.StringVar(&listenHttp, "listen", "127.0.0.1:8080", "listen addr:port")
flag.StringVar(&listenWebdav, "webdav", "", "listen addr:port for webdav")
flag.StringVar(&listenCache, "cache", "", "listen addr:port for cache only")
flag.IntVar(&max, "max", 1, "max parallel preloads")
flag.IntVar(&bs, "bs", -1, "tune preload buffer size in bytes (default: 8192)")
flag.Int64Var(&quota, "quota", 1, "max disk usage quota for the dst cache in GiB")
flag.BoolVar(&block, "block", true, "block until sftp is connected")
flag.Parse()
//go func() {
// http.ListenAndServe("127.0.0.1:7777", nil)
//}()
log = klogr.New().WithName("main")
log.Info("starting cachefs", "version", version)
if fs.SetBufferSize(bs) {
log.V(2).Info("changed preload buffer size", "size", bs)
}
filesystem, err := fs.NewFS(
quota*gib,
max,
src,
os.Getenv("SRC_KEY"),
dst,
os.Getenv("DST_KEY"),
metadata,
block,
klogr.New().WithName("fs"),
)
if err != nil {
klog.Fatalf("init failed: %s", err)
}
slog := klogr.New().WithName("srv")
s := &http.Server{
Addr: listenHttp,
Handler: srv.NewFileServer(
filesystem,
slog,
),
}
go func() {
log.Info("starting main server", "addr", listenHttp)
err := s.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
klog.Fatalf("init failed: %s", err)
}
}()
var (
dav *http.Server
cache *http.Server
)
if listenWebdav != "" {
log.Info("starting webdav server", "addr", listenWebdav)
dav = &http.Server{
Addr: listenWebdav,
Handler: srv.NewWebDavServer(
fs.NewWebDavFS(filesystem),
slog.WithName("webdav"),
),
}
go func() {
err := dav.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
klog.Fatalf("init failed: %s", err)
}
}()
}
if listenCache != "" {
log.Info("starting cache server", "addr", listenCache)
cache = &http.Server{
Addr: listenCache,
Handler: srv.NewCacheServer(
filesystem,
slog.WithName("cache"),
),
}
go func() {
err := cache.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
klog.Fatalf("init failed: %s", err)
}
}()
}
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs
log.Info("cachefs shutdown initiated")
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
s.Shutdown(ctx)
cancel()
if dav != nil {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
dav.Shutdown(ctx)
cancel()
}
if cache != nil {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
cache.Shutdown(ctx)
cancel()
}
filesystem.Close()
<-filesystem.Done()
log.Info("cachefs shutdown completed")
os.Exit(0)
}