Use hidden directory based on mount path
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user