sftp: add --sftp-set-env option to set environment variables

Fixes #6094
This commit is contained in:
Nick Craig-Wood 2022-04-11 10:41:17 +01:00
parent 78120d40d9
commit 60d87185e1

View File

@ -302,6 +302,27 @@ cost of using more memory.
`,
Default: 64,
Advanced: true,
}, {
Name: "set_env",
Default: fs.SpaceSepList{},
Help: `Environment variables to pass to sftp and commands
Set environment variables in the form:
VAR=value
to be passed to the sftp client and to any commands run (eg md5sum).
Pass multiple variables space separated, eg
VAR1=value VAR2=value
and pass variables with spaces in in quotes, eg
"VAR3=value with space" "VAR4=value with space" VAR5=nospacehere
`,
Advanced: true,
}},
}
fs.Register(fsi)
@ -336,6 +357,7 @@ type Options struct {
IdleTimeout fs.Duration `config:"idle_timeout"`
ChunkSize fs.SizeSuffix `config:"chunk_size"`
Concurrency int `config:"concurrency"`
SetEnv fs.SpaceSepList `config:"set_env"`
}
// Fs stores the interface to the remote SFTP files
@ -483,6 +505,22 @@ func (f *Fs) sftpConnection(ctx context.Context) (c *conn, err error) {
return c, nil
}
// Set any environment variables on the ssh.Session
func (f *Fs) setEnv(s *ssh.Session) error {
for _, env := range f.opt.SetEnv {
equal := strings.IndexRune(env, '=')
if equal < 0 {
return fmt.Errorf("no = found in env var %q", env)
}
// fs.Debugf(f, "Setting env %q = %q", env[:equal], env[equal+1:])
err := s.Setenv(env[:equal], env[equal+1:])
if err != nil {
return fmt.Errorf("Failed to set env var %q: %w", env[:equal], err)
}
}
return nil
}
// Creates a new SFTP client on conn, using the specified subsystem
// or sftp server, and zero or more option functions
func (f *Fs) newSftpClient(conn *ssh.Client, opts ...sftp.ClientOption) (*sftp.Client, error) {
@ -490,6 +528,10 @@ func (f *Fs) newSftpClient(conn *ssh.Client, opts ...sftp.ClientOption) (*sftp.C
if err != nil {
return nil, err
}
err = f.setEnv(s)
if err != nil {
return nil, err
}
pw, err := s.StdinPipe()
if err != nil {
return nil, err
@ -1243,6 +1285,10 @@ func (f *Fs) run(ctx context.Context, cmd string) ([]byte, error) {
if err != nil {
return nil, fmt.Errorf("run: get SFTP session: %w", err)
}
err = f.setEnv(session)
if err != nil {
return nil, err
}
defer func() {
_ = session.Close()
}()