mirror of
https://github.com/offen/docker-volume-backup.git
synced 2025-12-05 17:18:02 +01:00
SSH connections are left dangling after use (#668)
This commit is contained in:
@@ -177,10 +177,20 @@ func (s *script) init() error {
|
|||||||
IdentityPassphrase: s.c.SSHIdentityPassphrase,
|
IdentityPassphrase: s.c.SSHIdentityPassphrase,
|
||||||
RemotePath: s.c.SSHRemotePath,
|
RemotePath: s.c.SSHRemotePath,
|
||||||
}
|
}
|
||||||
sshBackend, err := ssh.NewStorageBackend(sshConfig, logFunc)
|
|
||||||
|
sshBackend, closeSSHConnection, err := ssh.NewStorageBackend(sshConfig, logFunc)
|
||||||
|
|
||||||
|
s.registerHook(hookLevelPlumbing, func(err error) error {
|
||||||
|
if err := closeSSHConnection(); err != nil {
|
||||||
|
return errwrap.Wrap(err, "failed to close ssh connection")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrap(err, "error creating ssh storage backend")
|
return errwrap.Wrap(err, "error creating ssh storage backend")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.storages = append(s.storages, sshBackend)
|
s.storages = append(s.storages, sshBackend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,10 @@ type Config struct {
|
|||||||
RemotePath string
|
RemotePath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var noop = func() error { return nil }
|
||||||
|
|
||||||
// NewStorageBackend creates and initializes a new SSH storage backend.
|
// NewStorageBackend creates and initializes a new SSH storage backend.
|
||||||
func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error) {
|
func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, func() error, error) {
|
||||||
var authMethods []ssh.AuthMethod
|
var authMethods []ssh.AuthMethod
|
||||||
|
|
||||||
if opts.Password != "" {
|
if opts.Password != "" {
|
||||||
@@ -47,20 +49,20 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
|
|||||||
if _, err := os.Stat(opts.IdentityFile); err == nil {
|
if _, err := os.Stat(opts.IdentityFile); err == nil {
|
||||||
key, err := os.ReadFile(opts.IdentityFile)
|
key, err := os.ReadFile(opts.IdentityFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errwrap.Wrap(nil, "error reading the private key")
|
return nil, noop, errwrap.Wrap(nil, "error reading the private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
var signer ssh.Signer
|
var signer ssh.Signer
|
||||||
if opts.IdentityPassphrase != "" {
|
if opts.IdentityPassphrase != "" {
|
||||||
signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(opts.IdentityPassphrase))
|
signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(opts.IdentityPassphrase))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errwrap.Wrap(nil, "error parsing the encrypted private key")
|
return nil, noop, errwrap.Wrap(nil, "error parsing the encrypted private key")
|
||||||
}
|
}
|
||||||
authMethods = append(authMethods, ssh.PublicKeys(signer))
|
authMethods = append(authMethods, ssh.PublicKeys(signer))
|
||||||
} else {
|
} else {
|
||||||
signer, err = ssh.ParsePrivateKey(key)
|
signer, err = ssh.ParsePrivateKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errwrap.Wrap(nil, "error parsing the private key")
|
return nil, noop, errwrap.Wrap(nil, "error parsing the private key")
|
||||||
}
|
}
|
||||||
authMethods = append(authMethods, ssh.PublicKeys(signer))
|
authMethods = append(authMethods, ssh.PublicKeys(signer))
|
||||||
}
|
}
|
||||||
@@ -72,13 +74,12 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
|
|||||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||||
}
|
}
|
||||||
sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", opts.HostName, opts.Port), sshClientConfig)
|
sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", opts.HostName, opts.Port), sshClientConfig)
|
||||||
|
if err != nil || sshClient == nil {
|
||||||
if err != nil {
|
return nil, noop, errwrap.Wrap(err, "error creating ssh client")
|
||||||
return nil, errwrap.Wrap(err, "error creating ssh client")
|
|
||||||
}
|
}
|
||||||
_, _, err = sshClient.SendRequest("keepalive", false, nil)
|
_, _, err = sshClient.SendRequest("keepalive", false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, sshClient.Close, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sftpClient, err := sftp.NewClient(sshClient,
|
sftpClient, err := sftp.NewClient(sshClient,
|
||||||
@@ -87,7 +88,7 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
|
|||||||
sftp.MaxConcurrentRequestsPerFile(64),
|
sftp.MaxConcurrentRequestsPerFile(64),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errwrap.Wrap(err, "error creating sftp client")
|
return nil, sshClient.Close, errwrap.Wrap(err, "error creating sftp client")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &sshStorage{
|
return &sshStorage{
|
||||||
@@ -98,7 +99,7 @@ func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error
|
|||||||
client: sshClient,
|
client: sshClient,
|
||||||
sftpClient: sftpClient,
|
sftpClient: sftpClient,
|
||||||
hostName: opts.HostName,
|
hostName: opts.HostName,
|
||||||
}, nil
|
}, sshClient.Close, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the name of the storage backend
|
// Name returns the name of the storage backend
|
||||||
|
|||||||
Reference in New Issue
Block a user