Files
kopia/cli/config.go
Shikhar Mall 26e6f59b2b feat(cli): New Upgrade CLI / Switch to Format Version 3 (upgrade coordination) (#1818)
* kopia format upgrade lock

* Update cli/command_repository_set_parameters_test.go

Co-authored-by: Ali Dowair <adowair@umich.edu>

* Update cli/command_repository_upgrade.go

Co-authored-by: Ali Dowair <adowair@umich.edu>

* Update cli/command_repository_upgrade.go

Co-authored-by: Ali Dowair <adowair@umich.edu>

* pr feedback

* pr feedback

* add a min drain time check

* env var for io-drain-timeout

* fix: add more doctext around upgrade phases

* build: wrap with EnvName

* add experimental warning

* protect upgrade cli behind env varible

* fix conflicts after relocating the upgrade lock

* generalize the command args

* drop certain features as per feedback

* sub-divide the upgrade command into begin and rollback

* Update cli/command_repository_upgrade.go

Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>

* Update cli/command_repository_upgrade.go

Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>

* missing return

* rename force flag to allow-unsafe-upgrade

Co-authored-by: Shikhar Mall <shikhar@kasten.io>
Co-authored-by: Ali Dowair <adowair@umich.edu>
Co-authored-by: Shikhar Mall <small@kopia.io>
Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>
2022-07-27 16:23:45 -07:00

124 lines
2.7 KiB
Go

package cli
import (
"context"
"fmt"
"io"
"os"
"os/signal"
"path/filepath"
"runtime"
"github.com/alecthomas/kingpin"
"github.com/pkg/errors"
"github.com/kopia/kopia/fs"
"github.com/kopia/kopia/fs/localfs"
"github.com/kopia/kopia/internal/ospath"
"github.com/kopia/kopia/repo"
)
func deprecatedFlag(w io.Writer, help string) func(_ *kingpin.ParseContext) error {
return func(_ *kingpin.ParseContext) error {
fmt.Fprintf(w, "DEPRECATED: %v\n", help)
return nil
}
}
func (c *App) onCtrlC(f func()) {
s := make(chan os.Signal, 1)
signal.Notify(s, os.Interrupt)
go func() {
// invoke the function when either real or simulated Ctrl-C signal is delivered
select {
case v := <-c.simulatedCtrlC:
if !v {
return
}
case <-s:
}
f()
}()
}
func (c *App) openRepository(ctx context.Context, required bool) (repo.Repository, error) {
if _, err := os.Stat(c.repositoryConfigFileName()); os.IsNotExist(err) {
if !required {
return nil, nil
}
return nil, errors.Errorf("repository is not connected. See https://kopia.io/docs/repositories/")
}
c.maybePrintUpdateNotification(ctx)
pass, err := c.getPasswordFromFlags(ctx, false, true)
if err != nil {
return nil, errors.Wrap(err, "get password")
}
r, err := repo.Open(ctx, c.repositoryConfigFileName(), pass, c.optionsFromFlags(ctx))
if os.IsNotExist(err) {
return nil, errors.New("not connected to a repository, use 'kopia connect'")
}
return r, errors.Wrap(err, "unable to open repository")
}
func (c *App) optionsFromFlags(ctx context.Context) *repo.Options {
return &repo.Options{
TraceStorage: c.traceStorage,
DisableInternalLog: c.disableInternalLog,
UpgradeOwnerID: c.upgradeOwnerID,
DoNotWaitForUpgrade: c.doNotWaitForUpgrade,
}
}
func (c *App) repositoryConfigFileName() string {
if filepath.Base(c.configPath) != c.configPath {
return c.configPath
}
// bare filename specified without any directory (absolute or relative)
// resolve against OS-specific directory.
return filepath.Join(ospath.ConfigDir(), c.configPath)
}
func resolveSymlink(path string) (string, error) {
st, err := os.Lstat(path)
if err != nil {
return "", errors.Wrap(err, "stat")
}
if (st.Mode() & os.ModeSymlink) == 0 {
return path, nil
}
// nolint:wrapcheck
return filepath.EvalSymlinks(path)
}
func getLocalFSEntry(ctx context.Context, path0 string) (fs.Entry, error) {
path, err := resolveSymlink(path0)
if err != nil {
return nil, errors.Wrap(err, "resolveSymlink")
}
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")
}
return e, nil
}
func isWindows() bool {
return runtime.GOOS == "windows"
}