forked from canonical/lxd
/
utils.go
72 lines (59 loc) · 1.35 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package main
import (
"fmt"
"github.com/lxc/lxd/client"
"github.com/lxc/lxd/lxd/migration"
)
func transferRootfs(dst lxd.ContainerServer, op lxd.Operation, rootfs string, rsyncArgs string) error {
opAPI := op.Get()
// Connect to the websockets
wsControl, err := op.GetWebsocket(opAPI.Metadata["control"].(string))
if err != nil {
return err
}
wsFs, err := op.GetWebsocket(opAPI.Metadata["fs"].(string))
if err != nil {
return err
}
// Setup control struct
fs := migration.MigrationFSType_RSYNC
rsyncHasFeature := true
header := migration.MigrationHeader{
Fs: &fs,
RsyncFeatures: &migration.RsyncFeatures{
Xattrs: &rsyncHasFeature,
Delete: &rsyncHasFeature,
Compress: &rsyncHasFeature,
},
}
err = migration.ProtoSend(wsControl, &header)
if err != nil {
protoSendError(wsControl, err)
return err
}
err = migration.ProtoRecv(wsControl, &header)
if err != nil {
protoSendError(wsControl, err)
return err
}
// Send the filesystem
abort := func(err error) error {
protoSendError(wsControl, err)
return err
}
err = rsyncSend(wsFs, rootfs, rsyncArgs)
if err != nil {
return abort(err)
}
// Check the result
msg := migration.MigrationControl{}
err = migration.ProtoRecv(wsControl, &msg)
if err != nil {
wsControl.Close()
return err
}
if !*msg.Success {
return fmt.Errorf(*msg.Message)
}
return nil
}