build: close sftp connection when done (#24593)

This commit is contained in:
Martin Holst Swende 2022-03-27 13:21:36 +02:00 committed by GitHub
parent eb3ebceaa1
commit 0fffd3acbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 14 deletions

View File

@ -17,6 +17,7 @@
package build package build
import ( import (
"bufio"
"bytes" "bytes"
"flag" "flag"
"fmt" "fmt"
@ -116,7 +117,6 @@ func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x
// the form sftp://[user@]host[:port]. // the form sftp://[user@]host[:port].
func UploadSFTP(identityFile, host, dir string, files []string) error { func UploadSFTP(identityFile, host, dir string, files []string) error {
sftp := exec.Command("sftp") sftp := exec.Command("sftp")
sftp.Stdout = os.Stdout
sftp.Stderr = os.Stderr sftp.Stderr = os.Stderr
if identityFile != "" { if identityFile != "" {
sftp.Args = append(sftp.Args, "-i", identityFile) sftp.Args = append(sftp.Args, "-i", identityFile)
@ -131,6 +131,10 @@ func UploadSFTP(identityFile, host, dir string, files []string) error {
if err != nil { if err != nil {
return fmt.Errorf("can't create stdin pipe for sftp: %v", err) return fmt.Errorf("can't create stdin pipe for sftp: %v", err)
} }
stdout, err := sftp.StdoutPipe()
if err != nil {
return fmt.Errorf("can't create stdout pipe for sftp: %v", err)
}
if err := sftp.Start(); err != nil { if err := sftp.Start(); err != nil {
return err return err
} }
@ -139,24 +143,34 @@ func UploadSFTP(identityFile, host, dir string, files []string) error {
fmt.Fprintln(in, "put", f, path.Join(dir, filepath.Base(f))) fmt.Fprintln(in, "put", f, path.Join(dir, filepath.Base(f)))
} }
fmt.Fprintln(in, "exit") fmt.Fprintln(in, "exit")
// Avoid travis timout after 10m of inactivity by printing something // Some issue with the PPA sftp server makes it so the server does not
// every 8 minutes. // respond properly to a 'bye', 'exit' or 'quit' from the client.
done := make(chan bool) // To work around that, we check the output, and when we see the client
// exit command, we do a hard exit.
// See
// https://github.com/kolban-google/sftp-gcs/issues/23
// https://github.com/mscdex/ssh2/pull/1111
aborted := false
go func() { go func() {
for { scanner := bufio.NewScanner(stdout)
select { for scanner.Scan() {
case <-time.After(8 * time.Minute): txt := scanner.Text()
fmt.Println("keepalive log") fmt.Println(txt)
continue if txt == "sftp> exit" {
case <-done: // Give it .5 seconds to exit (server might be fixed), then
return // hard kill it from the outside
time.Sleep(500 * time.Millisecond)
aborted = true
sftp.Process.Kill()
} }
} }
}() }()
stdin.Close() stdin.Close()
defer close(done) err = sftp.Wait()
return sftp.Wait() if aborted {
return nil
}
return err
} }
// FindMainPackages finds all 'main' packages in the given directory and returns their // FindMainPackages finds all 'main' packages in the given directory and returns their