Use hidden directory based on mount path

This commit is contained in:
Ben Johnson
2020-11-03 12:21:13 -07:00
parent 42f9ba9d1c
commit bcc6963db6
3 changed files with 53 additions and 16 deletions

View File

@@ -8,6 +8,7 @@ import (
"io/ioutil"
"log"
"os"
"path/filepath"
"bazil.org/fuse"
"bazil.org/fuse/fs"
@@ -27,8 +28,8 @@ func main() {
type Main struct {
logger *log.Logger
SourcePath string
MountPath string
TargetPath string
Path string
}
func NewMain() *Main {
@@ -39,19 +40,36 @@ func NewMain() *Main {
func (m *Main) Run(args []string) (err error) {
flagSet := flag.NewFlagSet("litestream", flag.ContinueOnError)
flagSet.StringVar(&m.TargetPath, "target", "", "target directory")
verbose := flagSet.Bool("v", false, "verbose")
flagSet.Usage = m.usage
if err := flagSet.Parse(args); err != nil {
return err
}
// Ensure src & mount paths are specified.
if m.SourcePath = flagSet.Arg(0); m.SourcePath == "" {
return errors.New("source path required")
} else if m.MountPath = flagSet.Arg(1); m.MountPath == "" {
// Ensure mount path is specified.
if flagSet.NArg() > 1 {
return errors.New("too many arguments, only specify mount path")
} else if m.Path = flagSet.Arg(0); m.Path == "" {
return errors.New("mount path required")
}
// Ensure mount path exists & is a directory.
if fi, err := os.Stat(m.Path); err != nil {
return err
} else if !fi.IsDir() {
return fmt.Errorf("mount path must be a directory")
}
// If no target is specified, default to a hidden directory based on the mount path.
if m.TargetPath == "" {
m.TargetPath = filepath.Join(filepath.Dir(m.Path), "."+filepath.Base(m.Path))
if err := m.ensureTargetPath(); err != nil {
return err
}
}
// Setup logging, if verbose specified.
var config fs.Config
if *verbose {
@@ -60,29 +78,48 @@ func (m *Main) Run(args []string) (err error) {
}
// Mount FUSE filesystem.
conn, err := fuse.Mount(m.MountPath, fuse.FSName("litestream"), fuse.Subtype("litestreamfs"))
conn, err := fuse.Mount(m.Path, fuse.FSName("litestream"), fuse.Subtype("litestreamfs"))
if err != nil {
return err
}
defer fuse.Unmount(m.MountPath)
defer fuse.Unmount(m.Path)
defer conn.Close()
m.logger.Printf("mounted")
m.logger.Printf("mounted %s; target=%s", m.Path, m.TargetPath)
s := fs.New(conn, &config)
return s.Serve(&litestream.FileSystem{SourcePath: m.SourcePath})
return s.Serve(&litestream.FileSystem{TargetPath: m.TargetPath})
}
func (m *Main) ensureTargetPath() error {
// Check if target path exists, exit if it does.
if _, err := os.Stat(m.TargetPath); err == nil {
return nil
} else if err != nil && !os.IsNotExist(err) {
return err
}
// Create target path with the same permissions as the mount path.
fi, err := os.Stat(m.Path)
if err != nil {
return err
}
return os.Mkdir(m.TargetPath, fi.Mode())
}
func (m *Main) usage() {
fmt.Println(`
Litestream is a FUSE file system that automatically replicates SQLite databases.
Litestream is a FUSE file system that replicates SQLite databases.
Usage:
litestream [arguments] source_dir mount_dir
litestream [arguments] PATH
Arguments:
-target PATH
Specifies the directory to store data.
Defaults to a hidden directory next to PATH.
-v
Enable verbose logging.