mirror of
https://github.com/zrepl/zrepl.git
synced 2024-12-22 15:11:16 +01:00
pull job: support manual-only invocation
This commit is contained in:
parent
c655622bf7
commit
4ee00091d6
@ -67,7 +67,38 @@ type PushJob struct {
|
|||||||
type PullJob struct {
|
type PullJob struct {
|
||||||
ActiveJob `yaml:",inline"`
|
ActiveJob `yaml:",inline"`
|
||||||
RootFS string `yaml:"root_fs"`
|
RootFS string `yaml:"root_fs"`
|
||||||
Interval time.Duration `yaml:"interval,positive"`
|
Interval PositiveDurationOrManual `yaml:"interval"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PositiveDurationOrManual struct {
|
||||||
|
Interval time.Duration
|
||||||
|
Manual bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ yaml.Unmarshaler = (*PositiveDurationOrManual)(nil)
|
||||||
|
|
||||||
|
func (i *PositiveDurationOrManual) UnmarshalYAML(u func(interface{}, bool) error) (err error) {
|
||||||
|
var s string
|
||||||
|
if err := u(&s, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch s {
|
||||||
|
case "manual":
|
||||||
|
i.Manual = true
|
||||||
|
i.Interval = 0
|
||||||
|
case "":
|
||||||
|
return fmt.Errorf("value must not be empty")
|
||||||
|
default:
|
||||||
|
i.Manual = false
|
||||||
|
i.Interval, err = time.ParseDuration(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if i.Interval <= 0 {
|
||||||
|
return fmt.Errorf("value must be a positive duration, got %q", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SinkJob struct {
|
type SinkJob struct {
|
||||||
|
41
config/config_positiveintervalormanual_test.go
Normal file
41
config/config_positiveintervalormanual_test.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/zrepl/yaml-config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPositiveDurationOrManual(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Comment, Input string
|
||||||
|
Result *PositiveDurationOrManual
|
||||||
|
}{
|
||||||
|
{"empty is error", "", nil},
|
||||||
|
{"negative is error", "-1s", nil},
|
||||||
|
{"zero seconds is error", "0s", nil},
|
||||||
|
{"zero is error", "0", nil},
|
||||||
|
{"non-manual is error", "something", nil},
|
||||||
|
{"positive seconds works", "1s", &PositiveDurationOrManual{Manual: false, Interval: 1 * time.Second}},
|
||||||
|
{"manual works", "manual", &PositiveDurationOrManual{Manual: true, Interval: 0}},
|
||||||
|
}
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Run(tc.Comment, func(t *testing.T) {
|
||||||
|
var out struct {
|
||||||
|
FieldName PositiveDurationOrManual `yaml:"fieldname"`
|
||||||
|
}
|
||||||
|
input := fmt.Sprintf("\nfieldname: %s\n", tc.Input)
|
||||||
|
err := yaml.UnmarshalStrict([]byte(input), &out)
|
||||||
|
if tc.Result == nil {
|
||||||
|
assert.Error(t, err)
|
||||||
|
t.Logf("%#v", out)
|
||||||
|
} else {
|
||||||
|
assert.Equal(t, *tc.Result, out.FieldName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -153,7 +153,7 @@ type modePull struct {
|
|||||||
receiver *endpoint.Receiver
|
receiver *endpoint.Receiver
|
||||||
sender *rpc.Client
|
sender *rpc.Client
|
||||||
rootFS *zfs.DatasetPath
|
rootFS *zfs.DatasetPath
|
||||||
interval time.Duration
|
interval config.PositiveDurationOrManual
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modePull) ConnectEndpoints(loggers rpc.Loggers, connecter transport.Connecter) {
|
func (m *modePull) ConnectEndpoints(loggers rpc.Loggers, connecter transport.Connecter) {
|
||||||
@ -183,7 +183,12 @@ func (m *modePull) SenderReceiver() (logic.Sender, logic.Receiver) {
|
|||||||
func (*modePull) Type() Type { return TypePull }
|
func (*modePull) Type() Type { return TypePull }
|
||||||
|
|
||||||
func (m *modePull) RunPeriodic(ctx context.Context, wakeUpCommon chan<- struct{}) {
|
func (m *modePull) RunPeriodic(ctx context.Context, wakeUpCommon chan<- struct{}) {
|
||||||
t := time.NewTicker(m.interval)
|
if m.interval.Manual {
|
||||||
|
GetLogger(ctx).Info("manual pull configured, periodic pull disabled")
|
||||||
|
// "waiting for wakeups" is printed in common ActiveSide.do
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t := time.NewTicker(m.interval.Interval)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -212,9 +217,6 @@ func (m *modePull) ResetConnectBackoff() {
|
|||||||
|
|
||||||
func modePullFromConfig(g *config.Global, in *config.PullJob) (m *modePull, err error) {
|
func modePullFromConfig(g *config.Global, in *config.PullJob) (m *modePull, err error) {
|
||||||
m = &modePull{}
|
m = &modePull{}
|
||||||
if in.Interval <= 0 {
|
|
||||||
return nil, errors.New("interval must be positive")
|
|
||||||
}
|
|
||||||
m.interval = in.Interval
|
m.interval = in.Interval
|
||||||
|
|
||||||
m.rootFS, err = zfs.NewDatasetPath(in.RootFS)
|
m.rootFS, err = zfs.NewDatasetPath(in.RootFS)
|
||||||
|
@ -225,7 +225,8 @@ Job Type ``pull``
|
|||||||
- ZFS dataset path are received to
|
- ZFS dataset path are received to
|
||||||
``$root_fs/$client_identity``
|
``$root_fs/$client_identity``
|
||||||
* - ``interval``
|
* - ``interval``
|
||||||
- Interval at which to pull from the source job
|
- | Interval at which to pull from the source job (e.g. ``10m``).
|
||||||
|
| ``manual`` disables periodic pulling, replication then only happens on :ref:`wakeup <cli-signal-wakeup>`.
|
||||||
* - ``pruning``
|
* - ``pruning``
|
||||||
- |pruning-spec|
|
- |pruning-spec|
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ CLI Overview
|
|||||||
The zrepl binary is self-documenting:
|
The zrepl binary is self-documenting:
|
||||||
run ``zrepl help`` for an overview of the available subcommands or ``zrepl SUBCOMMAND --help`` for information on available flags, etc.
|
run ``zrepl help`` for an overview of the available subcommands or ``zrepl SUBCOMMAND --help`` for information on available flags, etc.
|
||||||
|
|
||||||
|
.. _cli-signal-wakeup:
|
||||||
|
|
||||||
.. list-table::
|
.. list-table::
|
||||||
:widths: 30 70
|
:widths: 30 70
|
||||||
:header-rows: 1
|
:header-rows: 1
|
||||||
|
Loading…
Reference in New Issue
Block a user