Procházet zdrojové kódy

build: avoid dput and upload with sftp directly (#19067)

Felix Lange před 6 roky
rodič
revize
a8ddf7ad83
3 změnil soubory, kde provedl 53 přidání a 27 odebrání
  1. 22 19
      build/ci.go
  2. 0 8
      build/dput-launchpad.cf
  3. 31 0
      internal/build/util.go

+ 22 - 19
build/ci.go

@@ -511,41 +511,44 @@ func doDebianSource(cmdline []string) {
 			debuild.Dir = pkgdir
 			build.MustRun(debuild)
 
-			changes := fmt.Sprintf("%s_%s_source.changes", meta.Name(), meta.VersionString())
-			changes = filepath.Join(*workdir, changes)
+			var (
+				basename = fmt.Sprintf("%s_%s", meta.Name(), meta.VersionString())
+				source   = filepath.Join(*workdir, basename+".tar.xz")
+				dsc      = filepath.Join(*workdir, basename+".dsc")
+				changes  = filepath.Join(*workdir, basename+"_source.changes")
+			)
 			if *signer != "" {
 				build.MustRunCommand("debsign", changes)
 			}
 			if *upload != "" {
-				uploadDebianSource(*workdir, *upload, *sshUser, changes)
+				ppaUpload(*workdir, *upload, *sshUser, []string{source, dsc, changes})
 			}
 		}
 	}
 }
 
-func uploadDebianSource(workdir, ppa, sshUser, changes string) {
-	// Create the dput config file.
-	dputConfig := filepath.Join(workdir, "dput.cf")
+func ppaUpload(workdir, ppa, sshUser string, files []string) {
 	p := strings.Split(ppa, "/")
 	if len(p) != 2 {
 		log.Fatal("-upload PPA name must contain single /")
 	}
-	templateData := map[string]string{
-		"LaunchpadUser": p[0],
-		"LaunchpadPPA":  p[1],
-		"LaunchpadSSH":  sshUser,
+	if sshUser == "" {
+		sshUser = p[0]
 	}
+	incomingDir := fmt.Sprintf("~%s/ubuntu/%s", p[0], p[1])
+	// Create the SSH identity file if it doesn't exist.
+	var idfile string
 	if sshkey := getenvBase64("PPA_SSH_KEY"); len(sshkey) > 0 {
-		idfile := filepath.Join(workdir, "sshkey")
-		ioutil.WriteFile(idfile, sshkey, 0600)
-		templateData["IdentityFile"] = idfile
+		idfile = filepath.Join(workdir, "sshkey")
+		if _, err := os.Stat(idfile); os.IsNotExist(err) {
+			ioutil.WriteFile(idfile, sshkey, 0600)
+		}
+	}
+	// Upload
+	dest := sshUser + "@ppa.launchpad.net"
+	if err := build.UploadSFTP(idfile, dest, incomingDir, files); err != nil {
+		log.Fatal(err)
 	}
-	build.Render("build/dput-launchpad.cf", dputConfig, 0644, templateData)
-
-	// Run dput to do the upload.
-	dput := exec.Command("dput", "-c", dputConfig, "--no-upload-log", ppa, changes)
-	dput.Stdin = strings.NewReader("Yes\n") // accept SSH host key
-	build.MustRun(dput)
 }
 
 func getenvBase64(variable string) []byte {

+ 0 - 8
build/dput-launchpad.cf

@@ -1,8 +0,0 @@
-[{{.LaunchpadUser}}/{{.LaunchpadPPA}}]
-fqdn = ppa.launchpad.net
-method = sftp
-incoming = ~{{.LaunchpadUser}}/ubuntu/{{.LaunchpadPPA}}/
-login = {{.LaunchpadSSH}}
-{{ if .IdentityFile }}
-  ssh_options = IdentityFile {{.IdentityFile}}
-{{ end }}

+ 31 - 0
internal/build/util.go

@@ -177,3 +177,34 @@ func ExpandPackagesNoVendor(patterns []string) []string {
 	}
 	return patterns
 }
+
+// UploadSFTP uploads files to a remote host using the sftp command line tool.
+// The destination host may be specified either as [user@]host[: or as a URI in
+// the form sftp://[user@]host[:port].
+func UploadSFTP(identityFile, host, dir string, files []string) error {
+	sftp := exec.Command("sftp")
+	sftp.Stdout = nil
+	sftp.Stderr = os.Stderr
+	if identityFile != "" {
+		sftp.Args = append(sftp.Args, "-i", identityFile)
+	}
+	sftp.Args = append(sftp.Args, host)
+	fmt.Println(">>>", strings.Join(sftp.Args, " "))
+	if *DryRunFlag {
+		return nil
+	}
+
+	stdin, err := sftp.StdinPipe()
+	if err != nil {
+		return fmt.Errorf("can't create stdin pipe for sftp: %v", err)
+	}
+	if err := sftp.Start(); err != nil {
+		return err
+	}
+	in := io.MultiWriter(stdin, os.Stdout)
+	for _, f := range files {
+		fmt.Fprintln(in, "put", f, path.Join(dir, filepath.Base(f)))
+	}
+	stdin.Close()
+	return sftp.Wait()
+}