22package etcd
33
44import (
5- "bufio"
5+ // "bufio"
66 "fmt"
77 "io"
88 "strings"
@@ -20,7 +20,7 @@ import (
2020var _ interfaces.Snapshot = & Etcd {}
2121
2222const (
23- etcdctlCmd = " /opt/bin/etcdctl snapshot %s %s > /dev/null;"
23+ etcdctlCmd = ` /opt/bin/etcdctl snapshot %s %s`
2424)
2525
2626var (
@@ -30,13 +30,13 @@ var (
3030 {"store" : "overlay" , "file" : "overlay" , "port" : "2359" },
3131 }
3232
33- envCmd = [] string {
34- " ETCDCTL_CERT=/etc/etcd/ssl/etcd-{{file}}.pem" ,
35- " ETCDCTL_KEY=/etc/etcd/ssl/etcd-{{file}}-key.pem" ,
36- " ETCDCTL_CACERT=/etc/etcd/ssl/etcd-{{file}}-ca.pem" ,
37- " ETCDCTL_API=3" ,
38- " ETCDCTL_ENDPOINTS=https://127.0.0.1:{{port}}" ,
39- }
33+ envCmd = `
34+ export ETCDCTL_CERT=/etc/etcd/ssl/etcd-{{file}}.pem;
35+ export ETCDCTL_KEY=/etc/etcd/ssl/etcd-{{file}}-key.pem;
36+ export ETCDCTL_CACERT=/etc/etcd/ssl/etcd-{{file}}-ca.pem;
37+ export ETCDCTL_API=3;
38+ export ETCDCTL_ENDPOINTS=https://127.0.0.1:{{port}}
39+ `
4040)
4141
4242type Etcd struct {
@@ -75,23 +75,12 @@ func (e *Etcd) Save() error {
7575 saveFunc := func (store map [string ]string ) {
7676 defer wg .Done ()
7777
78- targetPath := fmt .Sprintf ("%s%s.db" , e .path , store ["store" ])
79-
80- reader , writer := io .Pipe ()
81- go snapshot .ReadTarFromStream (targetPath , reader , result , errLock )
82-
8378 hostPath := fmt .Sprintf ("/tmp/etcd-snapshot-%s-%s.db" ,
8479 store ["store" ], time .Now ().Format (snapshot .TimeLayout ))
85- cmdArgs := append (e .template (envCmd , store ),
86- strings .Split (fmt .Sprintf (etcdctlCmd , "save" , hostPath ), " " )... )
87- cmdArgs = append (cmdArgs ,
88- strings .Split (fmt .Sprintf (snapshot .GZipCCmd , hostPath ), " " )... )
89-
90- err = e .sshCmd (
91- aliases [0 ],
92- cmdArgs ,
93- writer ,
94- )
80+
81+ cmdArgs := fmt .Sprintf (`sudo /bin/bash -c "%s; %s"` , e .template (envCmd , store ),
82+ fmt .Sprintf (etcdctlCmd , "save" , hostPath ))
83+ err = snapshot .SSHCmd (e , aliases [0 ], cmdArgs , nil , nil , nil )
9584 if err != nil {
9685
9786 errLock .Lock ()
@@ -101,6 +90,22 @@ func (e *Etcd) Save() error {
10190 return
10291 }
10392
93+ targetPath := fmt .Sprintf ("%s%s.db" , e .path , store ["store" ])
94+ reader , writer := io .Pipe ()
95+ err = snapshot .TarFromStream (func () error {
96+ err := snapshot .SSHCmd (e , aliases [0 ], fmt .Sprintf (snapshot .GZipCCmd , hostPath ),
97+ nil , writer , nil )
98+ writer .Close ()
99+ return err
100+ }, reader , targetPath )
101+ if err != nil {
102+ errLock .Lock ()
103+ result = multierror .Append (result , err )
104+ errLock .Unlock ()
105+
106+ return
107+ }
108+
104109 e .log .Infof ("etcd %s snapshot saved to %s" , store ["store" ], targetPath )
105110
106111 select {
@@ -111,7 +116,6 @@ func (e *Etcd) Save() error {
111116 }
112117
113118 wg .Add (len (stores ))
114-
115119 for _ , store := range stores {
116120 go saveFunc (store )
117121 }
@@ -137,31 +141,18 @@ func (e *Etcd) Restore() error {
137141 return nil
138142}
139143
140- func (e * Etcd ) sshCmd (host string , args []string , stdout io.Writer ) error {
141- readerE , writerE := io .Pipe ()
142- scannerE := bufio .NewScanner (readerE )
143-
144- go func () {
145- for scannerE .Scan () {
146- e .log .WithField ("std" , "err" ).Warn (scannerE .Text ())
147- }
148- }()
149-
150- args = append ([]string {"sudo" }, args ... )
151- ret , err := e .ssh .ExecuteWithPipe (host , args [0 ], args [1 :], nil , stdout , writerE )
152- if ret != 0 {
153- return fmt .Errorf ("command [%s] returned non-zero: %d" , strings .Join (args , " " ), ret )
144+ func (e * Etcd ) template (args string , vars map [string ]string ) string {
145+ for k , v := range vars {
146+ args = strings .Replace (args , fmt .Sprintf ("{{%s}}" , k ), v , - 1 )
154147 }
155148
156- return err
149+ return args
157150}
158151
159- func (e * Etcd ) template (args []string , vars map [string ]string ) []string {
160- for i := range args {
161- for k , v := range vars {
162- args [i ] = strings .Replace (args [i ], fmt .Sprintf ("{{%s}}" , k ), v , - 1 )
163- }
164- }
152+ func (e * Etcd ) Log () * logrus.Entry {
153+ return e .log
154+ }
165155
166- return args
156+ func (e * Etcd ) SSH () interfaces.SSH {
157+ return e .ssh
167158}
0 commit comments