WIP rewrite the daemon

cmd subdir does not build on purpose, it's only left in tree to grab old
code and move it to github.com/zrepl/zrepl/daemon
This commit is contained in:
Christian Schwarz
2018-08-27 22:21:45 +02:00
parent df6e1bc64d
commit c69ebd3806
55 changed files with 1133 additions and 84 deletions
+26
View File
@@ -0,0 +1,26 @@
package serve
import (
"github.com/pkg/errors"
"github.com/zrepl/zrepl/config"
"net"
)
type ListenerFactory interface {
Listen() (net.Listener, error)
}
func FromConfig(g config.Global, in config.ServeEnum) (ListenerFactory, error) {
switch v := in.Ret.(type) {
case *config.TCPServe:
return TCPListenerFactoryFromConfig(g, v)
case *config.TLSServe:
return TLSListenerFactoryFromConfig(g, v)
case *config.StdinserverServer:
return StdinserverListenerFactoryFromConfig(g, v)
default:
return nil, errors.Errorf("internal error: unknown serve type %T", v)
}
}
+79
View File
@@ -0,0 +1,79 @@
package serve
import (
"github.com/problame/go-netssh"
"github.com/zrepl/zrepl/config"
"github.com/zrepl/zrepl/daemon/nethelpers"
"io"
"net"
"path"
"time"
)
type StdinserverListenerFactory struct {
ClientIdentity string
sockpath string
}
func StdinserverListenerFactoryFromConfig(g config.Global, in *config.StdinserverServer) (f *StdinserverListenerFactory, err error) {
f = &StdinserverListenerFactory{
ClientIdentity: in.ClientIdentity,
}
f.sockpath = path.Join(g.Serve.StdinServer.SockDir, f.ClientIdentity)
return
}
func (f *StdinserverListenerFactory) Listen() (net.Listener, error) {
if err := nethelpers.PreparePrivateSockpath(f.sockpath); err != nil {
return nil, err
}
l, err := netssh.Listen(f.sockpath)
if err != nil {
return nil, err
}
return StdinserverListener{l}, nil
}
type StdinserverListener struct {
l *netssh.Listener
}
func (l StdinserverListener) Addr() net.Addr {
return netsshAddr{}
}
func (l StdinserverListener) Accept() (net.Conn, error) {
c, err := l.l.Accept()
if err != nil {
return nil, err
}
return netsshConnToNetConnAdatper{c}, nil
}
func (l StdinserverListener) Close() (err error) {
return l.l.Close()
}
type netsshAddr struct{}
func (netsshAddr) Network() string { return "netssh" }
func (netsshAddr) String() string { return "???" }
type netsshConnToNetConnAdatper struct {
io.ReadWriteCloser // works for both netssh.SSHConn and netssh.ServeConn
}
func (netsshConnToNetConnAdatper) LocalAddr() net.Addr { return netsshAddr{} }
func (netsshConnToNetConnAdatper) RemoteAddr() net.Addr { return netsshAddr{} }
func (netsshConnToNetConnAdatper) SetDeadline(t time.Time) error { return nil }
func (netsshConnToNetConnAdatper) SetReadDeadline(t time.Time) error { return nil }
func (netsshConnToNetConnAdatper) SetWriteDeadline(t time.Time) error { return nil }
+21
View File
@@ -0,0 +1,21 @@
package serve
import (
"github.com/zrepl/zrepl/config"
"net"
)
type TCPListenerFactory struct {
Address string
}
func TCPListenerFactoryFromConfig(c config.Global, in *config.TCPServe) (*TCPListenerFactory, error) {
lf := &TCPListenerFactory{
Address: in.Listen,
}
return lf, nil
}
func (f *TCPListenerFactory) Listen() (net.Listener, error) {
return net.Listen("tcp", f.Address)
}
+52
View File
@@ -0,0 +1,52 @@
package serve
import (
"crypto/tls"
"crypto/x509"
"github.com/pkg/errors"
"github.com/zrepl/zrepl/config"
"github.com/zrepl/zrepl/tlsconf"
"net"
"time"
)
type TLSListenerFactory struct {
address string
clientCA *x509.CertPool
serverCert tls.Certificate
clientCommonName string
handshakeTimeout time.Duration
}
func TLSListenerFactoryFromConfig(c config.Global, in *config.TLSServe) (lf *TLSListenerFactory, err error) {
lf = &TLSListenerFactory{
address: in.Listen,
}
if in.Ca == "" || in.Cert == "" || in.Key == "" || in.ClientCN == "" {
return nil, errors.New("fields 'ca', 'cert', 'key' and 'client_cn' must be specified")
}
lf.clientCommonName = in.ClientCN
lf.clientCA, err = tlsconf.ParseCAFile(in.Ca)
if err != nil {
return nil, errors.Wrap(err, "cannot parse ca file")
}
lf.serverCert, err = tls.LoadX509KeyPair(in.Cert, in.Key)
if err != nil {
return nil, errors.Wrap(err, "cannot parse cer/key pair")
}
return lf, nil
}
func (f *TLSListenerFactory) Listen() (net.Listener, error) {
l, err := net.Listen("tcp", f.address)
if err != nil {
return nil, err
}
tl := tlsconf.NewClientAuthListener(l, f.clientCA, f.serverCert, f.clientCommonName, f.handshakeTimeout)
return tl, nil
}