Skip to content
This repository was archived by the owner on May 28, 2023. It is now read-only.

Commit a17f971

Browse files
author
Matthias Kadenbach
committed
allow to talk to rsync endpoint directly
1 parent 631938e commit a17f971

4 files changed

Lines changed: 87 additions & 47 deletions

File tree

README.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,47 @@
11
# docker-rsync
22

33
docker-rsync recursively watches directories for changes and copies
4-
changes to a docker-machine. It is a drop in replacement for the
4+
changes via rsync. It is a drop in replacement for the
55
existing boot2docker vboxsf feature.
66

7-
Please note though that syncing happens only in one direction,
8-
from your local machine to the boot2docker machine. If you want to sync
9-
from a Docker container back to your local machine, docker-rsync is not
10-
the tool you're looking for.
7+
Please note though that syncing happens only in one direction.
8+
If you want to sync back from a Docker container to your local machine,
9+
docker-rsync is not the tool you're looking for.
1110

1211
__Is it fast?__ Yes! While the initial sync might take some seconds
1312
(depending on the number of files you want to sync), following syncs are
1413
super fast (compared to vboxsf & NFS). A one file sync usually takes less than 100ms.
1514

1615
docker-sync relies on [FSEvents API](https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/),
17-
so this tool will only work under Mac OSX. You also need [docker-machine](https://github.com/docker/machine) installed.
16+
so this tool will only work under Mac OSX.
1817

1918

2019
## Installation
2120

2221
```bash
23-
brew install docker-machine
24-
2522
brew tap synack/docker
2623
brew install docker-rsync
2724
```
2825

29-
## Usage
26+
27+
## Usage with docker-machine
3028

3129
```bash
30+
brew install docker-machine
3231
docker-machine create my-machine123 -d virtualbox
3332

3433
cd sync-this-directory
34+
echo "git" >> .rsyncignore
35+
3536
docker-rsync my-machine123
37+
```
38+
39+
40+
## Talk to rsync directly
3641

42+
```bash
43+
cd sync-this-directory
3744
echo "git" >> .rsyncignore
45+
46+
docker-rsync rsync://<IP:PORT>/<MODULE>
3847
```

main.go

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,53 +5,76 @@ import (
55
"fmt"
66
"os"
77
pathpkg "path"
8+
"strings"
89
)
910

1011
func main() {
12+
pwd, err := os.Getwd()
13+
if err != nil {
14+
fmt.Println("error: unable to get current directory:", err)
15+
os.Exit(1)
16+
}
17+
1118
flag.Usage = func() {
12-
fmt.Fprintf(os.Stderr, "usage: %v [-version|-initial] <machine-name>\n", os.Args[0])
19+
fmt.Fprintf(os.Stderr, "usage: %v [options] DOCKER-MACHINE-NAME\n", os.Args[0])
20+
fmt.Fprintf(os.Stderr, "or : %v [options] rsync://IP:PORT/MODULE\n", os.Args[0])
21+
fmt.Print("\nOptions:\n")
1322
flag.PrintDefaults()
1423
}
1524

1625
var version = flag.Bool("version", false, "Print version")
1726
var onetime = flag.Bool("1", false, "Sync only once")
27+
var path = flag.String("path", pwd, "Sync this directory")
1828
flag.Parse()
1929

2030
if *version {
2131
fmt.Println(Version)
2232
os.Exit(0)
2333
}
2434

25-
path, err := os.Getwd()
26-
if err != nil {
27-
fmt.Println("error: unable to get current directory:", err)
28-
os.Exit(1)
29-
}
30-
3135
if len(flag.Args()) != 1 {
32-
fmt.Printf("usage: %v [-version|-initial] <machine-name>\n", os.Args[0])
36+
flag.Usage()
3337
os.Exit(1)
3438
}
3539

36-
machineName := flag.Args()[0]
40+
via := flag.Args()[0]
3741

38-
port, err := GetSSHPort(machineName)
39-
if err != nil {
40-
fmt.Printf("error: unable to get port for machine '%v': %v\n", machineName, err)
41-
os.Exit(1)
42-
}
42+
rpath := *path
43+
rpathDir := pathpkg.Dir(*path)
44+
45+
// TODO: refactor the following part...
4346

44-
Provision(machineName)
47+
if strings.HasPrefix(via, "rsync://") {
48+
// use rsync protocol directly
49+
rsyncEndpoint := via
4550

46-
rpath := path
47-
rpathDir := pathpkg.Dir(path)
51+
Sync(rsyncEndpoint, 0, rpath, rpathDir) // initial sync
4852

49-
PrepareSync(machineName, port, rpath, rpathDir)
50-
Sync(machineName, port, path, pathpkg.Dir(path)) // initial sync
53+
if !*onetime {
54+
Watch(rpath, func(id uint64, path string, flags []string) {
55+
Sync(rsyncEndpoint, 0, rpath, rpathDir)
56+
})
57+
}
5158

52-
if !*onetime {
53-
Watch(path, func(id uint64, path string, flags []string) {
54-
Sync(machineName, port, rpath, rpathDir)
55-
})
59+
} else {
60+
// use rsync via ssh
61+
machineName := via
62+
63+
port, err := GetSSHPort(machineName)
64+
if err != nil {
65+
fmt.Printf("error: unable to get port for machine '%v': %v\n", machineName, err)
66+
os.Exit(1)
67+
}
68+
69+
Provision(machineName)
70+
RunSSHCommand(machineName, "sudo mkdir -p "+rpathDir)
71+
Sync(machineName, port, rpath, rpathDir) // initial sync
72+
73+
if !*onetime {
74+
Watch(rpath, func(id uint64, path string, flags []string) {
75+
Sync(machineName, port, rpath, rpathDir)
76+
})
77+
}
5678
}
79+
5780
}

rsync.go

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,38 @@ import (
88
"strings"
99
)
1010

11-
func PrepareSync(machineName string, port uint, src, dst string) {
12-
RunSSHCommand(machineName, "sudo mkdir -p "+dst)
13-
}
14-
15-
func Sync(machineName string, port uint, src, dst string) {
16-
homePath := os.Getenv("HOME")
17-
ripath := getRsyncIgnorePath()
11+
var lastSyncError = ""
1812

13+
func Sync(via string, port uint, src, dst string) {
1914
args := []string{
15+
// "--verbose",
16+
// "--stats",
2017
"--recursive",
2118
"--links",
2219
"--times",
2320
"--inplace",
24-
// "--verbose",
25-
// "--stats",
2621
"--itemize-changes",
2722
"--delete",
2823
"--force",
2924
"--executability",
3025
"--compress",
31-
"--force",
32-
fmt.Sprintf(`-e 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -i "%s" -p %v'`, filepath.Join(homePath, "/.docker/machine/machines", machineName, "id_rsa"), port),
33-
"--rsync-path='sudo rsync'",
3426
}
27+
28+
ripath := getRsyncIgnorePath()
3529
if ripath != "" {
3630
args = append(args, `--exclude-from='`+ripath+`'`)
3731
}
38-
args = append(args, src, "docker@localhost:"+dst)
32+
33+
if strings.HasPrefix(via, "rsync://") {
34+
args = append(args, filepath.Join(src)+"/.")
35+
args = append(args, via)
36+
} else {
37+
machineName := via
38+
homePath := os.Getenv("HOME")
39+
args = append(args, fmt.Sprintf(`-e 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -i "%s" -p %v'`, filepath.Join(homePath, "/.docker/machine/machines", machineName, "id_rsa"), port))
40+
args = append(args, "--rsync-path='sudo rsync'")
41+
args = append(args, src, "docker@localhost:"+dst)
42+
}
3943

4044
command := "rsync " + strings.Join(args, " ")
4145

@@ -46,7 +50,11 @@ func Sync(machineName string, port uint, src, dst string) {
4650
cmd.Stderr = os.Stderr
4751

4852
if err := cmd.Run(); err != nil {
49-
fmt.Printf("error: %v\n", err)
53+
// don't show duplicate errors
54+
if lastSyncError != err.Error() {
55+
fmt.Printf("error: %v\n", err)
56+
}
57+
lastSyncError = err.Error()
5058
}
5159
}
5260

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package main
22

3-
const Version = "0.0.3"
3+
const Version = "0.0.4"

0 commit comments

Comments
 (0)