launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/cmd/juju/scp.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "errors" 8 "strings" 9 10 "launchpad.net/juju-core/cmd" 11 "launchpad.net/juju-core/utils/ssh" 12 ) 13 14 // SCPCommand is responsible for launching a scp command to copy files to/from remote machine(s) 15 type SCPCommand struct { 16 SSHCommon 17 } 18 19 const scpDoc = ` 20 Lauch an scp command to copy files. <to> and <from> are either local 21 file paths or remote locations of the form <target>:<path>, where 22 <target> can be either a machine id as listed by "juju status" in the 23 "machines" section or a unit name as listed in the "services" section. 24 25 Examples 26 27 Copy a single file from machine 2 to the local machine: 28 29 juju scp 2:/var/log/syslog . 30 31 Recursively copy the directory /var/log/mongodb/ on the first mongodb 32 server to the local directory remote-logs: 33 34 juju scp -- -r mongodb/0:/var/log/mongodb/ remote-logs/ 35 36 Copy a local file to the second apache unit of the environment "testing": 37 38 juju scp -e testing foo.txt apache2/1: 39 ` 40 41 func (c *SCPCommand) Info() *cmd.Info { 42 return &cmd.Info{ 43 Name: "scp", 44 Args: "[-- scp-option...] <from> <to>", 45 Purpose: "launch a scp command to copy files to/from remote machine(s)", 46 Doc: scpDoc, 47 } 48 } 49 50 func (c *SCPCommand) Init(args []string) error { 51 switch len(args) { 52 case 0, 1: 53 return errors.New("at least two arguments required") 54 default: 55 c.Args = args 56 } 57 return nil 58 } 59 60 // Run resolves c.Target to a machine, or host of a unit and 61 // forks ssh with c.Args, if provided. 62 func (c *SCPCommand) Run(ctx *cmd.Context) error { 63 var err error 64 c.apiClient, err = c.initAPIClient() 65 if err != nil { 66 return err 67 } 68 defer c.apiClient.Close() 69 70 // translate arguments in the form 0:/somepath or service/0:/somepath into 71 // ubuntu@machine:/somepath so they can be presented to scp. 72 for i := range c.Args { 73 // BUG(dfc) This will not work for IPv6 addresses like 2001:db8::1:2:/somepath. 74 if v := strings.SplitN(c.Args[i], ":", 2); len(v) > 1 { 75 host, err := c.hostFromTarget(v[0]) 76 if err != nil { 77 return err 78 } 79 c.Args[i] = "ubuntu@" + host + ":" + v[1] 80 } 81 } 82 return ssh.Copy(c.Args[0], c.Args[1], nil) 83 }