2017-07-06 13:03:44 +02:00
|
|
|
package cmd
|
2017-04-26 20:21:18 +02:00
|
|
|
|
|
|
|
import (
|
2017-05-16 16:57:24 +02:00
|
|
|
"fmt"
|
2017-04-26 20:21:18 +02:00
|
|
|
"github.com/zrepl/zrepl/rpc"
|
2017-04-26 20:25:53 +02:00
|
|
|
"github.com/zrepl/zrepl/zfs"
|
|
|
|
"io"
|
2017-04-26 20:21:18 +02:00
|
|
|
)
|
2017-04-26 20:25:53 +02:00
|
|
|
|
2017-05-03 17:38:11 +02:00
|
|
|
type Handler struct {
|
2017-05-20 17:39:39 +02:00
|
|
|
Logger Logger
|
|
|
|
PullACL zfs.DatasetMapping
|
2017-05-16 16:57:24 +02:00
|
|
|
SinkMappingFunc func(clientIdentity string) (mapping zfs.DatasetMapping, err error)
|
2017-05-03 17:38:11 +02:00
|
|
|
}
|
2017-04-26 20:21:18 +02:00
|
|
|
|
2017-05-03 17:26:45 +02:00
|
|
|
func (h Handler) HandleFilesystemRequest(r rpc.FilesystemRequest) (roots []zfs.DatasetPath, err error) {
|
2017-05-07 12:28:03 +02:00
|
|
|
|
|
|
|
h.Logger.Printf("handling fsr: %#v", r)
|
|
|
|
|
2017-05-16 16:57:24 +02:00
|
|
|
h.Logger.Printf("using PullACL: %#v", h.PullACL)
|
|
|
|
|
2017-05-20 17:39:39 +02:00
|
|
|
if roots, err = zfs.ZFSListMapping(h.PullACL); err != nil {
|
2017-05-07 12:28:03 +02:00
|
|
|
h.Logger.Printf("handle fsr err: %v\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-05-16 16:57:24 +02:00
|
|
|
h.Logger.Printf("returning: %#v", roots)
|
2017-05-07 12:28:03 +02:00
|
|
|
|
2017-04-26 20:21:18 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-05-03 17:12:15 +02:00
|
|
|
func (h Handler) HandleFilesystemVersionsRequest(r rpc.FilesystemVersionsRequest) (versions []zfs.FilesystemVersion, err error) {
|
2017-05-07 12:28:03 +02:00
|
|
|
|
|
|
|
// allowed to request that?
|
2017-05-20 17:39:39 +02:00
|
|
|
if _, err = h.PullACL.Map(r.Filesystem); err != nil {
|
2017-05-07 12:28:03 +02:00
|
|
|
h.Logger.Printf("filesystem: %#v\n", r.Filesystem)
|
2017-05-20 17:39:39 +02:00
|
|
|
h.Logger.Printf("pull mapping: %#v\n", h.PullACL)
|
2017-05-07 12:28:03 +02:00
|
|
|
h.Logger.Printf("allowed error: %#v\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
h.Logger.Printf("allowed: %#v\n", r.Filesystem)
|
|
|
|
|
|
|
|
// find our versions
|
2017-06-22 21:49:14 +02:00
|
|
|
if versions, err = zfs.ZFSListFilesystemVersions(r.Filesystem, nil); err != nil {
|
2017-05-07 12:28:03 +02:00
|
|
|
h.Logger.Printf("our versions error: %#v\n", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("our versions: %#v\n", versions)
|
2017-05-03 17:26:45 +02:00
|
|
|
return
|
2017-05-07 12:28:03 +02:00
|
|
|
|
2017-05-03 17:12:15 +02:00
|
|
|
}
|
|
|
|
|
2017-05-07 12:04:16 +02:00
|
|
|
func (h Handler) HandleInitialTransferRequest(r rpc.InitialTransferRequest) (stream io.Reader, err error) {
|
2017-05-07 12:28:03 +02:00
|
|
|
|
|
|
|
h.Logger.Printf("handling initial transfer request: %#v", r)
|
|
|
|
// allowed to request that?
|
2017-05-20 17:39:39 +02:00
|
|
|
if _, err = h.PullACL.Map(r.Filesystem); err != nil {
|
2017-05-07 12:28:03 +02:00
|
|
|
h.Logger.Printf("initial transfer request acl errror: %#v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("invoking zfs send")
|
|
|
|
|
|
|
|
if stream, err = zfs.ZFSSend(r.Filesystem, &r.FilesystemVersion, nil); err != nil {
|
|
|
|
h.Logger.Printf("error sending filesystem: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("finished zfs send")
|
|
|
|
|
2017-05-07 12:04:16 +02:00
|
|
|
return
|
2017-05-07 12:28:03 +02:00
|
|
|
|
2017-04-26 20:21:18 +02:00
|
|
|
}
|
|
|
|
|
2017-05-07 12:04:16 +02:00
|
|
|
func (h Handler) HandleIncrementalTransferRequest(r rpc.IncrementalTransferRequest) (stream io.Reader, err error) {
|
2017-05-07 12:28:03 +02:00
|
|
|
|
|
|
|
h.Logger.Printf("handling incremental transfer request: %#v", r)
|
|
|
|
// allowed to request that?
|
2017-05-20 17:39:39 +02:00
|
|
|
if _, err = h.PullACL.Map(r.Filesystem); err != nil {
|
2017-05-07 12:28:03 +02:00
|
|
|
h.Logger.Printf("incremental transfer request acl errror: %#v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("invoking zfs send")
|
|
|
|
|
|
|
|
if stream, err = zfs.ZFSSend(r.Filesystem, &r.From, &r.To); err != nil {
|
|
|
|
h.Logger.Printf("error sending filesystem: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("finished zfs send")
|
|
|
|
|
2017-05-07 12:04:16 +02:00
|
|
|
return
|
2017-05-07 12:28:03 +02:00
|
|
|
|
2017-04-26 20:21:18 +02:00
|
|
|
}
|
2017-05-16 16:57:24 +02:00
|
|
|
|
|
|
|
func (h Handler) HandlePullMeRequest(r rpc.PullMeRequest, clientIdentity string, client rpc.RPCRequester) (err error) {
|
|
|
|
|
|
|
|
// Check if we have a sink for this request
|
|
|
|
// Use that mapping to do what happens in doPull
|
|
|
|
|
|
|
|
h.Logger.Printf("handling PullMeRequest: %#v", r)
|
|
|
|
|
|
|
|
var sinkMapping zfs.DatasetMapping
|
|
|
|
sinkMapping, err = h.SinkMappingFunc(clientIdentity)
|
|
|
|
if err != nil {
|
|
|
|
h.Logger.Printf("no sink mapping for client identity '%s', denying PullMeRequest", clientIdentity)
|
|
|
|
err = fmt.Errorf("no sink for client identity '%s'", clientIdentity)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("doing pull...")
|
|
|
|
|
|
|
|
err = doPull(PullContext{
|
|
|
|
Remote: client,
|
|
|
|
Log: h.Logger,
|
|
|
|
Mapping: sinkMapping,
|
|
|
|
InitialReplPolicy: r.InitialReplPolicy,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
h.Logger.Printf("PullMeRequest failed with error: %s", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.Logger.Printf("finished handling PullMeRequest: %#v", r)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|