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
import (
"bufio"
"bytes"
"flag"
"fmt"
@ -116,7 +117,6 @@ func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x
// the form sftp://[user@]host[:port].
func UploadSFTP(identityFile, host, dir string, files []string) error {
sftp := exec.Command("sftp")
sftp.Stdout = os.Stdout
sftp.Stderr = os.Stderr
if identityFile != "" {
sftp.Args = append(sftp.Args, "-i", identityFile)
@ -131,6 +131,10 @@ func UploadSFTP(identityFile, host, dir string, files []string) error {
if err != nil {
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 {
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, "exit")
// Avoid travis timout after 10m of inactivity by printing something
// every 8 minutes.
done := make(chan bool)
// Some issue with the PPA sftp server makes it so the server does not
// respond properly to a 'bye', 'exit' or 'quit' from the client.
// 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() {
for {
select {
case <-time.After(8 * time.Minute):
fmt.Println("keepalive log")
continue
case <-done:
return
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
txt := scanner.Text()
fmt.Println(txt)
if txt == "sftp> exit" {
// Give it .5 seconds to exit (server might be fixed), then
// hard kill it from the outside
time.Sleep(500 * time.Millisecond)
aborted = true
sftp.Process.Kill()
}
}
}()
stdin.Close()
defer close(done)
return sftp.Wait()
err = sftp.Wait()
if aborted {
return nil
}
return err
}
// FindMainPackages finds all 'main' packages in the given directory and returns their