github.com/unclejack/drone@v0.2.1-0.20140918182345-831b034aa33b/pkg/plugin/deploy/ssh.go (about)

     1  package deploy
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/drone/drone/pkg/build/buildfile"
     9  )
    10  
    11  // SSH struct holds configuration data for deployment
    12  // via ssh, deployment done by scp-ing file(s) listed
    13  // in artifacts to the target host, and then run cmd
    14  // remotely.
    15  // It is assumed that the target host already
    16  // add this repo public key in the host's `authorized_hosts`
    17  // file. And the private key is already copied to `.ssh/id_rsa`
    18  // inside the build container. No further check will be done.
    19  type SSH struct {
    20  
    21  	// Target is the deployment host in this format
    22  	//   user@hostname:/full/path <PORT>
    23  	//
    24  	// PORT may be omitted if its default to port 22.
    25  	Target string `yaml:"target,omitempty"`
    26  
    27  	// Artifacts is a list of files/dirs to be deployed
    28  	// to the target host. If artifacts list more than one file
    29  	// it will be compressed into a single tar.gz file.
    30  	// if artifacts contain:
    31  	//   - GITARCHIVE
    32  	//
    33  	// other file listed in artifacts will be ignored, instead, we will
    34  	// create git archive from the current revision and deploy that file
    35  	// alone.
    36  	// If you need to deploy the git archive along with some other files,
    37  	// please use build script to create the git archive, and then list
    38  	// the archive name here with the other files.
    39  	Artifacts []string `yaml:"artifacts,omitempty"`
    40  
    41  	// Cmd is a single command executed at target host after the artifacts
    42  	// is deployed.
    43  	Cmd string `yaml:"cmd,omitempty"`
    44  }
    45  
    46  // Write down the buildfile
    47  func (s *SSH) Write(f *buildfile.Buildfile) {
    48  	host := strings.SplitN(s.Target, " ", 2)
    49  	if len(host) == 1 {
    50  		host = append(host, "22")
    51  	}
    52  	if _, err := strconv.Atoi(host[1]); err != nil {
    53  		host[1] = "22"
    54  	}
    55  
    56  	// Is artifact created?
    57  	artifact := false
    58  
    59  	for _, a := range s.Artifacts {
    60  		if a == "GITARCHIVE" {
    61  			artifact = createGitArchive(f)
    62  			break
    63  		}
    64  	}
    65  
    66  	if !artifact {
    67  		if len(s.Artifacts) > 1 {
    68  			artifact = compress(f, s.Artifacts)
    69  		} else if len(s.Artifacts) == 1 {
    70  			f.WriteEnv("ARTIFACT", s.Artifacts[0])
    71  			artifact = true
    72  		}
    73  	}
    74  
    75  	if artifact {
    76  		scpCmd := "scp -o StrictHostKeyChecking=no -P %s -r ${ARTIFACT} %s"
    77  		f.WriteCmd(fmt.Sprintf(scpCmd, host[1], host[0]))
    78  	}
    79  
    80  	if len(s.Cmd) > 0 {
    81  		sshCmd := "ssh -o StrictHostKeyChecking=no -p %s %s %s"
    82  		f.WriteCmd(fmt.Sprintf(sshCmd, host[1], strings.SplitN(host[0], ":", 2)[0], s.Cmd))
    83  	}
    84  }
    85  
    86  func createGitArchive(f *buildfile.Buildfile) bool {
    87  	f.WriteEnv("COMMIT", "$(git rev-parse HEAD)")
    88  	f.WriteEnv("ARTIFACT", "${PWD##*/}-${COMMIT}.tar.gz")
    89  	f.WriteCmdSilent("git archive --format=tar.gz --prefix=${PWD##*/}/ ${COMMIT} > ${ARTIFACT}")
    90  	return true
    91  }
    92  
    93  func compress(f *buildfile.Buildfile, files []string) bool {
    94  	cmd := "tar -cf ${ARTIFACT} %s"
    95  	f.WriteEnv("ARTIFACT", "${PWD##*/}.tar.gz")
    96  	f.WriteCmdSilent(fmt.Sprintf(cmd, strings.Join(files, " ")))
    97  	return true
    98  }