mirror of https://github.com/restic/restic.git
sftp: Rework Open/Create
This commit is contained in:
parent
ae290ab374
commit
27ce6a85e9
|
@ -118,13 +118,17 @@ func (r *SFTP) clientError() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// open opens an sftp backend. When the command is started via
|
// Open opens an sftp backend as described by the config by running
|
||||||
// exec.Command, it is expected to speak sftp on stdin/stdout. The backend
|
// "ssh" with the appropriate arguments (or cfg.Command, if set).
|
||||||
// is expected at the given path. `dir` must be delimited by forward slashes
|
func Open(cfg Config) (*SFTP, error) {
|
||||||
// ("/"), which is required by sftp.
|
debug.Log("open backend with config %#v", cfg)
|
||||||
func open(dir string, program string, args ...string) (*SFTP, error) {
|
|
||||||
debug.Log("open backend with program %v, %v at %v", program, args, dir)
|
cmd, args, err := buildSSHCommand(cfg)
|
||||||
sftp, err := startClient(program, args...)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sftp, err := startClient(cmd, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("unable to start program: %v", err)
|
debug.Log("unable to start program: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -136,19 +140,36 @@ func open(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if all necessary dirs and files are there
|
// test if all necessary dirs and files are there
|
||||||
for _, d := range paths(dir) {
|
for _, d := range paths(cfg.Path) {
|
||||||
if _, err := sftp.c.Lstat(d); err != nil {
|
if _, err := sftp.c.Lstat(d); err != nil {
|
||||||
return nil, errors.Errorf("%s does not exist", d)
|
return nil, errors.Errorf("%s does not exist", d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp.p = dir
|
sftp.Config = cfg
|
||||||
|
sftp.p = cfg.Path
|
||||||
return sftp, nil
|
return sftp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildSSHCommand(cfg Config) []string {
|
// Join combines path components with slashes (according to the sftp spec).
|
||||||
|
func (r *SFTP) Join(p ...string) string {
|
||||||
|
return path.Join(p...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadDir returns the entries for a directory.
|
||||||
|
func (r *SFTP) ReadDir(dir string) ([]os.FileInfo, error) {
|
||||||
|
return r.c.ReadDir(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSSHCommand(cfg Config) (cmd string, args []string, err error) {
|
||||||
|
if cfg.Command != "" {
|
||||||
|
return SplitShellArgs(cfg.Command)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = "ssh"
|
||||||
|
|
||||||
hostport := strings.Split(cfg.Host, ":")
|
hostport := strings.Split(cfg.Host, ":")
|
||||||
args := []string{hostport[0]}
|
args = []string{hostport[0]}
|
||||||
if len(hostport) > 1 {
|
if len(hostport) > 1 {
|
||||||
args = append(args, "-p", hostport[1])
|
args = append(args, "-p", hostport[1])
|
||||||
}
|
}
|
||||||
|
@ -158,44 +179,36 @@ func buildSSHCommand(cfg Config) []string {
|
||||||
}
|
}
|
||||||
args = append(args, "-s")
|
args = append(args, "-s")
|
||||||
args = append(args, "sftp")
|
args = append(args, "sftp")
|
||||||
return args
|
return cmd, args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens an sftp backend as described by the config by running
|
// Create creates an sftp backend as described by the config by running
|
||||||
// "ssh" with the appropriate arguments.
|
// "ssh" with the appropriate arguments (or cfg.Command, if set).
|
||||||
func Open(cfg Config) (*SFTP, error) {
|
func create(cfg Config) (*SFTP, error) {
|
||||||
debug.Log("config %#v", cfg)
|
cmd, args, err := buildSSHCommand(cfg)
|
||||||
|
|
||||||
if cfg.Command == "" {
|
|
||||||
return open(cfg.Dir, "ssh", buildSSHCommand(cfg)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd, args, err := SplitShellArgs(cfg.Command)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return open(cfg.Dir, cmd, args...)
|
sftp, err := startClient(cmd, args...)
|
||||||
}
|
if err != nil {
|
||||||
|
debug.Log("unable to start program: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// create creates all the necessary files and directories for a new sftp
|
l, err := backend.ParseLayout(sftp, cfg.Layout, defaultLayout, cfg.Path)
|
||||||
// backend at dir. `dir` must be delimited by forward slashes ("/"), which is
|
|
||||||
// required by sftp.
|
|
||||||
func create(dir string, program string, args ...string) (*SFTP, error) {
|
|
||||||
debug.Log("create() %v %v", program, args)
|
|
||||||
sftp, err := startClient(program, args...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if config file already exists
|
// test if config file already exists
|
||||||
_, err = sftp.c.Lstat(Join(dir, backend.Paths.Config))
|
_, err = sftp.c.Lstat(Join(cfg.Path, backend.Paths.Config))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, errors.New("config file already exists")
|
return nil, errors.New("config file already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
// create paths for data, refs and temp blobs
|
// create paths for data, refs and temp blobs
|
||||||
for _, d := range paths(dir) {
|
for _, d := range paths(cfg.Path) {
|
||||||
err = sftp.mkdirAll(d, backend.Modes.Dir)
|
err = sftp.mkdirAll(d, backend.Modes.Dir)
|
||||||
debug.Log("mkdirAll %v -> %v", d, err)
|
debug.Log("mkdirAll %v -> %v", d, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -209,23 +222,7 @@ func create(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// open backend
|
// open backend
|
||||||
return open(dir, program, args...)
|
return Open(cfg)
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates an sftp backend as described by the config by running
|
|
||||||
// "ssh" with the appropriate arguments.
|
|
||||||
func Create(cfg Config) (*SFTP, error) {
|
|
||||||
debug.Log("config %#v", cfg)
|
|
||||||
if cfg.Command == "" {
|
|
||||||
return create(cfg.Dir, "ssh", buildSSHCommand(cfg)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd, args, err := SplitShellArgs(cfg.Command)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return create(cfg.Dir, cmd, args...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Location returns this backend's location (the directory name).
|
// Location returns this backend's location (the directory name).
|
||||||
|
|
Loading…
Reference in New Issue