lxd-p2c/transfer.go
func rsyncSendSetup(path string, rsyncArgs string) (*exec.Cmd, net.Conn, io.ReadCloser, error) {
	auds := fmt.Sprintf("@lxd-p2c/%s", uuid.NewRandom().String())
	if len(auds) > shared.ABSTRACT_UNIX_SOCK_LEN-1 {
		auds = auds[:shared.ABSTRACT_UNIX_SOCK_LEN-1]
	}

	l, err := net.Listen("unix", auds)
	if err != nil {
		return nil, nil, nil, err
	}

	execPath, err := os.Readlink("/proc/self/exe")
	if err != nil {
		return nil, nil, nil, err
	}

	if !shared.PathExists(execPath) {
		execPath = os.Args[0]
	}

	rsyncCmd := fmt.Sprintf("sh -c \"%s netcat %s\"", execPath, auds)

	args := []string{
		"-ar",
		"--devices",
		"--numeric-ids",
		"--partial",
		"--sparse",
		"--xattrs",
		"--delete",
		"--compress",
		"--compress-level=2",
	}

	// Ignore deletions (requires 3.1 or higher)
	rsyncCheckVersion := func(min string) bool {
		out, err := shared.RunCommand("rsync", "--version")
		if err != nil {
			return false
		}

		fields := strings.Split(out, " ")
		curVer, err := version.Parse(fields[3])
		if err != nil {
			return false
		}

		minVer, err := version.Parse(min)
		if err != nil {
			return false
		}

		return curVer.Compare(minVer) >= 0
	}

	if rsyncCheckVersion("3.1.0") {
		args = append(args, "--ignore-missing-args")
	}

	if rsyncArgs != "" {
		args = append(args, strings.Split(rsyncArgs, " ")...)
	}

	args = append(args, []string{path, "localhost:/tmp/foo"}...)
	args = append(args, []string{"-e", rsyncCmd}...)

	cmd := exec.Command("rsync", args...)
	cmd.Stdout = os.Stderr

	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, nil, nil, err
	}

	if err := cmd.Start(); err != nil {
		return nil, nil, nil, err
	}

	conn, err := l.Accept()
	if err != nil {
		cmd.Process.Kill()
		cmd.Wait()
		return nil, nil, nil, err
	}
	l.Close()

	return cmd, conn, stderr, nil
}
func rsyncSendSetup(path string, rsyncArgs string) (*exec.Cmd, net.Conn, io.ReadCloser, error) {
	auds := fmt.Sprintf("@lxd-p2c/%s", uuid.NewRandom().String())
	if len(auds) > shared.ABSTRACT_UNIX_SOCK_LEN-1 {
		auds = auds[:shared.ABSTRACT_UNIX_SOCK_LEN-1]
	}

	l, err := net.Listen("unix", auds)
	if err != nil {
		return nil, nil, nil, err
	}

	execPath, err := os.Readlink("/proc/self/exe")
	if err != nil {
		return nil, nil, nil, err
	}

	if !shared.PathExists(execPath) {
		execPath = os.Args[0]
	}

	rsyncCmd := fmt.Sprintf("sh -c \"%s netcat %s\"", execPath, auds)

	args := []string{
		"-ar",
		"--devices",
		"--numeric-ids",
		"--partial",
		"--sparse",
		"--xattrs",
		"--delete",
		"--compress",
		"--compress-level=2",
	}

	// Ignore deletions (requires 3.1 or higher)
	rsyncCheckVersion := func(min string) bool {
		out, err := shared.RunCommand("rsync", "--version")
		if err != nil {
			return false
		}

		fields := strings.Split(out, " ")
		curVer, err := version.Parse(fields[3])
		if err != nil {
			return false
		}

		minVer, err := version.Parse(min)
		if err != nil {
			return false
		}

		return curVer.Compare(minVer) >= 0
	}

	if rsyncCheckVersion("3.1.0") {
		args = append(args, "--ignore-missing-args")
	}

	if rsyncArgs != "" {
		args = append(args, strings.Split(rsyncArgs, " ")...)
	}

	args = append(args, []string{path, "localhost:/tmp/foo"}...)
	args = append(args, []string{"-e", rsyncCmd}...)

	cmd := exec.Command("rsync", args...)
	cmd.Stdout = os.Stderr

	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, nil, nil, err
	}

	if err := cmd.Start(); err != nil {
		return nil, nil, nil, err
	}

	conn, err := l.Accept()
	if err != nil {
		cmd.Process.Kill()
		cmd.Wait()
		return nil, nil, nil, err
	}
	l.Close()

	return cmd, conn, stderr, nil
}
func rsyncSendSetup ( path string , rsyncArgs string ) ( * exec . Cmd , net . Conn , io . ReadCloser , error ) { auds := fmt . Sprintf ( " " , uuid . NewRandom ( ) . String ( ) ) if len ( auds ) > shared . ABSTRACT_UNIX_SOCK_LEN - 1 { auds = auds [ : shared . ABSTRACT_UNIX_SOCK_LEN - 1 ] } l , err := net . Listen ( " " , auds ) if err != nil { return nil , nil , nil , err } execPath , err := os . Readlink ( " " ) if err != nil { return nil , nil , nil , err } if ! shared . PathExists ( execPath ) { execPath = os . Args [ 0 ] } rsyncCmd := fmt . Sprintf ( " \" \" " , execPath , auds ) args := [ ] string { " " , " " , " " , " " , " " , " " , " " , " " , " " , } // Ignore deletions (requires 3.1 or higher) rsyncCheckVersion := func ( min string ) bool { out , err := shared . RunCommand ( " " , " " ) if err != nil { return false } fields := strings . Split ( out , " " ) curVer , err := version . Parse ( fields [ 3 ] ) if err != nil { return false } minVer , err := version . Parse ( min ) if err != nil { return false } return curVer . Compare ( minVer ) >= 0 } if rsyncCheckVersion ( " " ) { args = append ( args , " " ) } if rsyncArgs != " " { args = append ( args , strings . Split ( rsyncArgs , " " ) ... ) } args = append ( args , [ ] string { path , " " } ... ) args = append ( args , [ ] string { " " , rsyncCmd } ... ) cmd := exec . Command ( " " , args ... ) cmd . Stdout = os . Stderr stderr , err := cmd . StderrPipe ( ) if err != nil { return nil , nil , nil , err } if err := cmd . Start ( ) ; err != nil { return nil , nil , nil , err } conn , err := l . Accept ( ) if err != nil { cmd . Process . Kill ( ) cmd . Wait ( ) return nil , nil , nil , err } l . Close ( ) return cmd , conn , stderr , nil }
// Spawn the rsync process
Spawn the rsync process