代码拉取完成,页面将自动刷新
package commands
import (
"errors"
"fmt"
"os"
"os/exec"
"strings"
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/log"
"github.com/docker/machine/libmachine/persist"
)
var (
errWrongNumberArguments = errors.New("Improper number of arguments")
// TODO: possibly move this to ssh package
baseSSHArgs = []string{
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts."
}
)
// HostInfo gives the mandatory information to connect to a host.
type HostInfo interface {
GetMachineName() string
GetSSHHostname() (string, error)
GetSSHPort() (int, error)
GetSSHUsername() string
GetSSHKeyPath() string
}
// HostInfoLoader loads host information.
type HostInfoLoader interface {
load(name string) (HostInfo, error)
}
type storeHostInfoLoader struct {
store persist.Store
}
func (s *storeHostInfoLoader) load(name string) (HostInfo, error) {
host, err := s.store.Load(name)
if err != nil {
return nil, fmt.Errorf("Error loading host: %s", err)
}
return host.Driver, nil
}
func cmdScp(c CommandLine, api libmachine.API) error {
args := c.Args()
if len(args) != 2 {
c.ShowHelp()
return errWrongNumberArguments
}
src := args[0]
dest := args[1]
hostInfoLoader := &storeHostInfoLoader{api}
cmd, err := getScpCmd(src, dest, c.Bool("recursive"), c.Bool("delta"), hostInfoLoader)
if err != nil {
return err
}
return runCmdWithStdIo(*cmd)
}
func getScpCmd(src, dest string, recursive bool, delta bool, hostInfoLoader HostInfoLoader) (*exec.Cmd, error) {
var cmdPath string
var err error
if !delta {
cmdPath, err = exec.LookPath("scp")
if err != nil {
return nil, errors.New("You must have a copy of the scp binary locally to use the scp feature")
}
} else {
cmdPath, err = exec.LookPath("rsync")
if err != nil {
return nil, errors.New("You must have a copy of the rsync binary locally to use the --delta option")
}
}
srcHost, srcPath, srcOpts, err := getInfoForScpArg(src, hostInfoLoader)
if err != nil {
return nil, err
}
destHost, destPath, destOpts, err := getInfoForScpArg(dest, hostInfoLoader)
if err != nil {
return nil, err
}
// TODO: Check that "-3" flag is available in user's version of scp.
// It is on every system I've checked, but the manual mentioned it's "newer"
sshArgs := baseSSHArgs
if !delta {
sshArgs = append(sshArgs, "-3")
if recursive {
sshArgs = append(sshArgs, "-r")
}
}
// Don't use ssh-agent if both hosts have explicit ssh keys
if !missesExplicitSSHKey(srcHost) && !missesExplicitSSHKey(destHost) {
sshArgs = append(sshArgs, "-o", "IdentitiesOnly=yes")
}
// Append needed -i / private key flags to command.
sshArgs = append(sshArgs, srcOpts...)
sshArgs = append(sshArgs, destOpts...)
// Append actual arguments for the scp command (i.e. docker@<ip>:/path)
locationArg, err := generateLocationArg(srcHost, srcPath)
if err != nil {
return nil, err
}
if delta {
sshArgs = append([]string{"-e"}, "ssh "+strings.Join(sshArgs, " "))
if recursive {
sshArgs = append(sshArgs, "-r")
}
}
sshArgs = append(sshArgs, locationArg)
locationArg, err = generateLocationArg(destHost, destPath)
if err != nil {
return nil, err
}
sshArgs = append(sshArgs, locationArg)
cmd := exec.Command(cmdPath, sshArgs...)
log.Debug(*cmd)
return cmd, nil
}
func missesExplicitSSHKey(hostInfo HostInfo) bool {
return hostInfo != nil && hostInfo.GetSSHKeyPath() == ""
}
func getInfoForScpArg(hostAndPath string, hostInfoLoader HostInfoLoader) (HostInfo, string, []string, error) {
// Local path. e.g. "/tmp/foo"
if !strings.Contains(hostAndPath, ":") {
return nil, hostAndPath, nil, nil
}
// Path with hostname. e.g. "hostname:/usr/bin/cmatrix"
parts := strings.SplitN(hostAndPath, ":", 2)
hostName := parts[0]
path := parts[1]
if hostName == "localhost" {
return nil, path, nil, nil
}
// Remote path
hostInfo, err := hostInfoLoader.load(hostName)
if err != nil {
return nil, "", nil, fmt.Errorf("Error loading host: %s", err)
}
args := []string{}
port, err := hostInfo.GetSSHPort()
if err == nil && port > 0 {
args = append(args, "-o", fmt.Sprintf("Port=%v", port))
}
if hostInfo.GetSSHKeyPath() != "" {
args = append(args, "-o", fmt.Sprintf("IdentityFile=%s", hostInfo.GetSSHKeyPath()))
}
return hostInfo, path, args, nil
}
func generateLocationArg(hostInfo HostInfo, path string) (string, error) {
if hostInfo == nil {
return path, nil
}
hostname, err := hostInfo.GetSSHHostname()
if err != nil {
return "", err
}
location := fmt.Sprintf("%s@%s:%s", hostInfo.GetSSHUsername(), hostname, path)
return location, nil
}
func runCmdWithStdIo(cmd exec.Cmd) error {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。