Files
kopia/cli/config.go
Jarek Kowalski a5838ff34c Improvements to UX for mounting directories (both CLI and KopiaUI) (#573)
* cli: simplified mount command

See https://youtu.be/1Nt_HIl-NWQ

It will always use WebDAV on Windows and FUSE on Unix. Removed
confusing options.

New usage:

$ kopia mount [--browse]
    Mounts all snapshots in a temporary filesystem directory
    (both Unix and Windows).

$ kopia mount <object> [--browse]
    Mounts given object in a temporary filesystem directory
    (both Unix and Windows).

$ kopia mount <object> z: [--browse]
    Mounts given object as a given drive letter in Windows (using
    temporary WebDAV mount).

$ kopia mount <object> * [--browse]
    Mounts given object as a random drive letter in Windows.

$ kopia mount <object> /mount/path [--browse]
    Mounts given object in given path in Unix.

<object> can be the ID of a directory 'k<hash>' or 'all'

Optional --browse automatically opens OS-native file browser.

* htmlui: added UI for mounting directories

See https://youtu.be/T-9SshVa1d8 for a quick demo.

Also replaced some UI text with icons.

* lint: windows-specific fix
2020-09-03 17:46:48 -07:00

118 lines
3.1 KiB
Go

package cli
import (
"context"
"fmt"
"os"
"os/signal"
"path/filepath"
"runtime"
"github.com/pkg/errors"
"github.com/kopia/kopia/fs"
"github.com/kopia/kopia/fs/localfs"
"github.com/kopia/kopia/fs/loggingfs"
"github.com/kopia/kopia/internal/ospath"
"github.com/kopia/kopia/repo"
)
var (
traceStorage = app.Flag("trace-storage", "Enables tracing of storage operations.").Default("true").Hidden().Bool()
traceObjectManager = app.Flag("trace-object-manager", "Enables tracing of object manager operations.").Envar("KOPIA_TRACE_OBJECT_MANAGER").Bool()
traceLocalFS = app.Flag("trace-localfs", "Enables tracing of local filesystem operations").Envar("KOPIA_TRACE_FS").Bool()
enableCaching = app.Flag("caching", "Enables caching of objects (disable with --no-caching)").Default("true").Hidden().Bool()
enableListCaching = app.Flag("list-caching", "Enables caching of list results (disable with --no-list-caching)").Default("true").Hidden().Bool()
metricsListenAddr = app.Flag("metrics-listen-addr", "Expose Prometheus metrics on a given host:port").Hidden().String()
configPath = app.Flag("config-file", "Specify the config file to use.").Default(defaultConfigFileName()).Envar("KOPIA_CONFIG_PATH").String()
)
func printStderr(msg string, args ...interface{}) {
fmt.Fprintf(os.Stderr, msg, args...)
}
func printStdout(msg string, args ...interface{}) {
fmt.Fprintf(os.Stdout, msg, args...)
}
func onCtrlC(f func()) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
<-c
f()
}()
}
func openRepository(ctx context.Context, opts *repo.Options, required bool) (repo.Repository, error) {
if _, err := os.Stat(repositoryConfigFileName()); os.IsNotExist(err) && !required {
return nil, nil
}
maybePrintUpdateNotification(ctx)
pass, err := getPasswordFromFlags(ctx, false, true)
if err != nil {
return nil, errors.Wrap(err, "get password")
}
r, err := repo.Open(ctx, repositoryConfigFileName(), pass, applyOptionsFromFlags(ctx, opts))
if os.IsNotExist(err) {
return nil, errors.New("not connected to a repository, use 'kopia connect'")
}
return r, err
}
func applyOptionsFromFlags(ctx context.Context, opts *repo.Options) *repo.Options {
if opts == nil {
opts = &repo.Options{}
}
if *traceStorage {
opts.TraceStorage = log(ctx).Debugf
}
if *traceObjectManager {
opts.ObjectManagerOptions.Trace = log(ctx).Debugf
}
return opts
}
func repositoryConfigFileName() string {
return *configPath
}
func defaultConfigFileName() string {
return filepath.Join(ospath.ConfigDir(), "repository.config")
}
func getLocalFSEntry(ctx context.Context, path0 string) (fs.Entry, error) {
path, err := filepath.EvalSymlinks(path0)
if err != nil {
return nil, errors.Wrap(err, "evaluate symlink")
}
if path != path0 {
log(ctx).Infof("%v resolved to %v", path0, path)
}
e, err := localfs.NewEntry(path)
if err != nil {
return nil, errors.Wrap(err, "can't get local fs entry")
}
if *traceLocalFS {
e = loggingfs.Wrap(e, log(ctx).Debugf, loggingfs.Prefix("[LOCALFS] "))
}
return e, nil
}
func isWindows() bool {
return runtime.GOOS == "windows"
}