moat-kv 0.70.24__py3-none-any.whl → 0.71.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- build/lib/moat/kv/_cfg.yaml +2 -6
- build/lib/moat/kv/backend/mqtt.py +0 -3
- ci/rtd-requirements.txt +4 -0
- ci/test-requirements.txt +7 -0
- ci/travis.sh +96 -0
- debian/.gitignore +7 -0
- debian/changelog +1435 -0
- debian/control +43 -0
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml +2 -6
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py +0 -3
- debian/moat-kv.postinst +3 -0
- debian/rules +20 -0
- debian/source/format +1 -0
- debian/watch +4 -0
- docs/Makefile +20 -0
- docs/make.bat +36 -0
- docs/source/TODO.rst +61 -0
- docs/source/_static/.gitkeep +0 -0
- docs/source/acls.rst +80 -0
- docs/source/auth.rst +84 -0
- docs/source/client_protocol.rst +456 -0
- docs/source/code.rst +341 -0
- docs/source/command_line.rst +1187 -0
- docs/source/common_protocol.rst +47 -0
- docs/source/debugging.rst +70 -0
- docs/source/extend.rst +37 -0
- docs/source/history.rst +36 -0
- docs/source/index.rst +75 -0
- docs/source/model.rst +54 -0
- docs/source/overview.rst +83 -0
- docs/source/related.rst +89 -0
- docs/source/server_protocol.rst +450 -0
- docs/source/startup.rst +31 -0
- docs/source/translator.rst +244 -0
- docs/source/tutorial.rst +711 -0
- docs/source/v3.rst +168 -0
- examples/code/transform.scale.yml +21 -0
- examples/code/transform.switch.yml +82 -0
- examples/code/transform.timeslot.yml +63 -0
- moat/kv/_cfg.yaml +2 -6
- moat/kv/backend/mqtt.py +0 -3
- {moat_kv-0.70.24.dist-info → moat_kv-0.71.0.dist-info}/METADATA +2 -5
- {moat_kv-0.70.24.dist-info → moat_kv-0.71.0.dist-info}/RECORD +68 -17
- scripts/current +15 -0
- scripts/env +8 -0
- scripts/init +39 -0
- scripts/recover +17 -0
- scripts/rotate +33 -0
- scripts/run +29 -0
- scripts/run-all +10 -0
- scripts/run-any +10 -0
- scripts/run-single +15 -0
- scripts/success +4 -0
- systemd/moat-kv-recover.service +21 -0
- systemd/moat-kv-rotate.service +20 -0
- systemd/moat-kv-rotate.timer +10 -0
- systemd/moat-kv-run-all.service +26 -0
- systemd/moat-kv-run-all@.service +25 -0
- systemd/moat-kv-run-any.service +26 -0
- systemd/moat-kv-run-any@.service +25 -0
- systemd/moat-kv-run-single.service +26 -0
- systemd/moat-kv-run-single@.service +25 -0
- systemd/moat-kv.service +27 -0
- systemd/postinst +7 -0
- systemd/sysusers +3 -0
- build/lib/moat/kv/backend/serf.py +0 -45
- build/lib/moat/kv/mock/serf.py +0 -250
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/serf.py +0 -45
- debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/serf.py +0 -250
- moat/kv/backend/serf.py +0 -45
- moat/kv/mock/serf.py +0 -250
- {moat_kv-0.70.24.dist-info → moat_kv-0.71.0.dist-info}/WHEEL +0 -0
- {moat_kv-0.70.24.dist-info → moat_kv-0.71.0.dist-info}/licenses/LICENSE.txt +0 -0
- {moat_kv-0.70.24.dist-info → moat_kv-0.71.0.dist-info}/top_level.txt +0 -0
docs/source/v3.rst
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
=================
|
2
|
+
MoaT-KV Version 3
|
3
|
+
=================
|
4
|
+
|
5
|
+
+++++++++
|
6
|
+
Rationale
|
7
|
+
+++++++++
|
8
|
+
|
9
|
+
The V2 servers worked, for the most part, but they had a couple of problems.
|
10
|
+
|
11
|
+
* sometimes there are strange deadlocks
|
12
|
+
|
13
|
+
* msgpack isn't that widely supported compared to CBOR
|
14
|
+
|
15
|
+
* the initial client/server negotiation isn't versioned
|
16
|
+
|
17
|
+
* the sync protocol is somewhat overengineered
|
18
|
+
|
19
|
+
* speed of updates is limited by the client>server>MQTT>server>client
|
20
|
+
chain; two possibly-high-load servers in between cause too much delay
|
21
|
+
|
22
|
+
* Messages tended to be more verbose than necessary
|
23
|
+
|
24
|
+
++++++++++++++++++
|
25
|
+
V3 design overview
|
26
|
+
++++++++++++++++++
|
27
|
+
|
28
|
+
Server start
|
29
|
+
++++++++++++
|
30
|
+
|
31
|
+
* connect to MQTT, listen to all MoaT messages,
|
32
|
+
update internal state as messages come in
|
33
|
+
|
34
|
+
* ask for a server link on the Join/Actor topic
|
35
|
+
|
36
|
+
* load the local backup if present
|
37
|
+
|
38
|
+
* fetch full tree from designated server is replied
|
39
|
+
|
40
|
+
* merge data
|
41
|
+
|
42
|
+
* Join actor topic
|
43
|
+
|
44
|
+
|
45
|
+
Client connection setup A
|
46
|
+
+++++++++++++++++++++++++
|
47
|
+
|
48
|
+
* Client connects to MQTT and sends Query message
|
49
|
+
* Designated server replies with connection data
|
50
|
+
* Client connects to server
|
51
|
+
|
52
|
+
* Server greets client
|
53
|
+
* Client authenticates
|
54
|
+
* Server sends MQTT connection information
|
55
|
+
* Client connects to MQTT and sends Birth message
|
56
|
+
* Server sees the client's message and sends ACK to the client
|
57
|
+
|
58
|
+
Client connection setup B
|
59
|
+
+++++++++++++++++++++++++
|
60
|
+
|
61
|
+
This method is slower; it can be used when the configured server doesn't work.
|
62
|
+
|
63
|
+
* Client connects to MQTT and sends Query message
|
64
|
+
* Designated server sends connection data
|
65
|
+
|
66
|
+
Reading initial data
|
67
|
+
++++++++++++++++++++
|
68
|
+
|
69
|
+
* Client subscribes to MQTT topic
|
70
|
+
* Client requests initial data from server
|
71
|
+
* Server sends data, advises client that no data exist, or tells the client
|
72
|
+
that MQTT uses retaining (if so, which codec to use)
|
73
|
+
|
74
|
+
Updates
|
75
|
+
+++++++
|
76
|
+
|
77
|
+
The most notable pain point of the old design is the speed of updates.
|
78
|
+
Thus in V3 all updates will be MQTT messages.
|
79
|
+
|
80
|
+
This section does not apply if the MQTT server retains the data.
|
81
|
+
|
82
|
+
MoaT update messages are CBOR maps. Keys are small integers for message brevity and
|
83
|
+
decode speed.
|
84
|
+
|
85
|
+
* 0: tock
|
86
|
+
|
87
|
+
The system-wide update counter. May be missing.
|
88
|
+
|
89
|
+
* 1: value
|
90
|
+
|
91
|
+
Contents: Whatever is CBOR-encodeable. A missing value means that the
|
92
|
+
object shall be deleted.
|
93
|
+
|
94
|
+
* 2: tick.
|
95
|
+
|
96
|
+
Update tracker. This is a ``((name, seq, counter), …)`` list of tuples.
|
97
|
+
|
98
|
+
* name
|
99
|
+
The server's name
|
100
|
+
|
101
|
+
* seq
|
102
|
+
Client connection. Zero is reserved for server-generated content.
|
103
|
+
|
104
|
+
* counter
|
105
|
+
A per-client update counter, managed by the client. Must start at 1 and
|
106
|
+
increment in steps of 1, in order to detect skipped updates.
|
107
|
+
|
108
|
+
|
109
|
+
The server sees the update and sends an ACK message to the client, assuming
|
110
|
+
that there was no conflict.
|
111
|
+
|
112
|
+
|
113
|
+
Skipped updates
|
114
|
+
+++++++++++++++
|
115
|
+
|
116
|
+
Servers listen to all messages. If there's a gap in a client's sequence
|
117
|
+
numbers, the server will ask it to repeat the message.
|
118
|
+
|
119
|
+
|
120
|
+
Update conflict resolution
|
121
|
+
++++++++++++++++++++++++++
|
122
|
+
|
123
|
+
If a client sends a message which the server determines
|
124
|
+
|
125
|
+
|
126
|
+
MQTT topics
|
127
|
+
+++++++++++
|
128
|
+
|
129
|
+
All are under a common configured prefix, the default is "moat/main".
|
130
|
+
|
131
|
+
svc/act
|
132
|
+
-------
|
133
|
+
|
134
|
+
The Actor topic for server identification.
|
135
|
+
|
136
|
+
The transmitted value contains the server's name, host and port.
|
137
|
+
|
138
|
+
|
139
|
+
svc/query
|
140
|
+
---------
|
141
|
+
|
142
|
+
Connect requests from clients.
|
143
|
+
|
144
|
+
svc/server
|
145
|
+
----------
|
146
|
+
|
147
|
+
Reply queue for messages to ``svc/query``. Contains the server value as
|
148
|
+
above.
|
149
|
+
|
150
|
+
|
151
|
+
d/*
|
152
|
+
---
|
153
|
+
|
154
|
+
Update messages.
|
155
|
+
|
156
|
+
Topic translation
|
157
|
+
+++++++++++++++++
|
158
|
+
|
159
|
+
Topics are encoded like MoaT paths, except for these differences:
|
160
|
+
|
161
|
+
* The path separator is ``/`` instead of ``.``
|
162
|
+
* Slashes are escaped as ``:_``.
|
163
|
+
* Spaces in paths are never escaped: that would collide with the previous rule
|
164
|
+
* Dots are not escaped, obviously.
|
165
|
+
* `None` is encoded as "$NULL" when it's a top-level element.
|
166
|
+
* The sequence ``:.`` is used to shield both wildcards and strings with a
|
167
|
+
leading ``$`` character. It translates back to an empty string, not a
|
168
|
+
dot, and may be treated as an illegal sequence otherwise.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
code: |
|
2
|
+
await _self.watch(src, fetch=False)
|
3
|
+
async for msg in _info:
|
4
|
+
if isinstance(msg, _cls.ChangeMsg):
|
5
|
+
try:
|
6
|
+
val = msg.value * factor + offset
|
7
|
+
except AttributeError:
|
8
|
+
continue
|
9
|
+
await _client.set(dst, value=val, idem=False)
|
10
|
+
info: Apply factor+offset
|
11
|
+
is_async: true
|
12
|
+
vars:
|
13
|
+
- src
|
14
|
+
- dst
|
15
|
+
- factor
|
16
|
+
- offset
|
17
|
+
|
18
|
+
# Whenever the value at 'src', changes, this code multiplies it by
|
19
|
+
# 'factor', adds 'offset', and writes it to 'dst'.
|
20
|
+
#
|
21
|
+
# This takes ~0.025 seconds, end-to-end, on a Raspberry Pi 3.
|
@@ -0,0 +1,82 @@
|
|
1
|
+
code: |
|
2
|
+
await _self.watch(src, fetch=False)
|
3
|
+
inv = high < low
|
4
|
+
if inv:
|
5
|
+
high,low = low,high
|
6
|
+
res = await _client.get(flip)
|
7
|
+
if "value" in res:
|
8
|
+
is_high = res.value != inv
|
9
|
+
else:
|
10
|
+
await _client.set(flip, value=inv)
|
11
|
+
is_high = False
|
12
|
+
|
13
|
+
async for msg in _info:
|
14
|
+
if isinstance(msg, _cls.ChangeMsg):
|
15
|
+
try:
|
16
|
+
val = msg.value
|
17
|
+
except AttributeError:
|
18
|
+
continue
|
19
|
+
if is_high and val < low:
|
20
|
+
is_high = False
|
21
|
+
await _client.set(flip, value=inv)
|
22
|
+
elif not is_high and val > high:
|
23
|
+
is_high = True
|
24
|
+
await _client.set(flip, value=not inv)
|
25
|
+
else:
|
26
|
+
if is_high:
|
27
|
+
val += high-low
|
28
|
+
await _client.set(dst, value=val)
|
29
|
+
info: Switch input between triggers
|
30
|
+
is_async: true
|
31
|
+
vars:
|
32
|
+
- src
|
33
|
+
- dst
|
34
|
+
- flip
|
35
|
+
- high
|
36
|
+
- low
|
37
|
+
|
38
|
+
# Consider this simple hook-up of a photoresistor:
|
39
|
+
#
|
40
|
+
# +5V --- PHOTO --+-- R1 --+-- R2 --- GND
|
41
|
+
# | |
|
42
|
+
# sensor port
|
43
|
+
#
|
44
|
+
# The port is a pull-down output: thus, this setup switches resistance
|
45
|
+
# between R1 and R1+R2, which allows us to measure the wide range of
|
46
|
+
# resistance which a typical photoresistor has, without requiring more
|
47
|
+
# fancy circuitry.
|
48
|
+
# ‹low› and ‹high› need to be calculated so that
|
49
|
+
#
|
50
|
+
# * when the photoresistor's resistance is such that the voltage at the
|
51
|
+
# sensor is at ‹high›, switching on the port will set the voltage to
|
52
|
+
# ‹low›, so you don't get a break in the brightness curve
|
53
|
+
# * the rate of change is roughly equal, so you don't get a kink in that
|
54
|
+
# curve.
|
55
|
+
#
|
56
|
+
# These conditions are satisfied when R(photo) = √(R1*(R1+R2)).
|
57
|
+
# So if R1=100Ω and R2=10kΩ, R(photo) at the switching point would be 1005Ω,
|
58
|
+
# thus you can calculate V(high) as 4.55 Volt and V(low) as 0.45 Volt.
|
59
|
+
#
|
60
|
+
# The actual choice of resistors is up to you and depends on the
|
61
|
+
# photoresistor's behavior in "interesting" lighting conditions. In general
|
62
|
+
# you'd want a high-resolution capture of the values at both ends of the
|
63
|
+
# range. Thus the above resistor values are sensible if the photoresistor
|
64
|
+
# is at 5kΩ when the light gets bright enough to read the newspaper (you
|
65
|
+
# want to capture as many nuances of the dark phase as possible), and at
|
66
|
+
# 50Ω on a bright summer day just as a cloud has obscured the sun.
|
67
|
+
# Or something like that.
|
68
|
+
#
|
69
|
+
# 'src' is the path which the sensor value is written to. Presumably it's
|
70
|
+
# polled periodically.
|
71
|
+
#
|
72
|
+
# 'dst' is the entry which receives the adjusted value.
|
73
|
+
#
|
74
|
+
# 'flip' is the entry which corresponds to the port. It receives a `bool`
|
75
|
+
# value (`False` on startup).
|
76
|
+
#
|
77
|
+
# 'low' and 'high' are the threshold values. If 'low' is greater than
|
78
|
+
# 'high', the port is inverted (i.e. it's set to `True` on startup).
|
79
|
+
#
|
80
|
+
# When a ‹src› update causes the port to be inverted, writing to ‹dst› is
|
81
|
+
# skipped: if the new value is close to the threshold, the delay doesn't
|
82
|
+
# matter much, and if it's not the value would be too inaccurate.
|
@@ -0,0 +1,63 @@
|
|
1
|
+
code: |
|
2
|
+
last_val = None
|
3
|
+
this_val = None
|
4
|
+
timer = None
|
5
|
+
await _client.set(dst, value=0, idem=True)
|
6
|
+
await _self.watch(src, fetch=True)
|
7
|
+
|
8
|
+
async for msg in _info:
|
9
|
+
if isinstance(msg, _cls.ChangeMsg):
|
10
|
+
try:
|
11
|
+
val = msg.value
|
12
|
+
except AttributeError:
|
13
|
+
continue
|
14
|
+
if last_val is None:
|
15
|
+
last_val = val
|
16
|
+
this_val = val
|
17
|
+
continue
|
18
|
+
this_val = val
|
19
|
+
delta = this_val - last_val
|
20
|
+
if delta > 0 and timer is None:
|
21
|
+
# fire an immediate update at first change
|
22
|
+
await _client.set(dst, value=delta*factor, idem=(delta == 0))
|
23
|
+
timer = await _self.timer(seconds)
|
24
|
+
elif delta < 0:
|
25
|
+
# wraparound or whatever
|
26
|
+
last_val = this_val
|
27
|
+
if timer is not None:
|
28
|
+
await timer.cancel()
|
29
|
+
timer = None
|
30
|
+
elif isinstance(msg, _cls.TimerMsg):
|
31
|
+
delta = this_val - last_val
|
32
|
+
if delta >= 0:
|
33
|
+
await _client.set(dst, value=delta*factor, idem=(delta == 0))
|
34
|
+
if delta > 0:
|
35
|
+
await timer.run(seconds)
|
36
|
+
else:
|
37
|
+
timer = None
|
38
|
+
last_val = this_val
|
39
|
+
info: generate timeslots for counter deltas
|
40
|
+
is_async: true
|
41
|
+
vars:
|
42
|
+
- src
|
43
|
+
- dst
|
44
|
+
- seconds
|
45
|
+
- factor
|
46
|
+
|
47
|
+
# This code converts a randomly-updating counter into one that carries a
|
48
|
+
# defined meaning.
|
49
|
+
#
|
50
|
+
# Consider a rain meter. The counter triggers whenever the meter's counter
|
51
|
+
# triggers possibly aggregated so that you don't get more than one update
|
52
|
+
# every ten seconds even if it's raining buckets.
|
53
|
+
#
|
54
|
+
# However, in your display you want the rate of rain over, say, the last
|
55
|
+
# minute, so you can show some approximation of "how much rain is there
|
56
|
+
# right now".
|
57
|
+
#
|
58
|
+
# This code sends an initial update immediately so that receiving code sees
|
59
|
+
# some value > 0 ASAP, then another update every ‹seconds›.
|
60
|
+
#
|
61
|
+
# Updates are scaled by ‹factor› so you can translate the counter's output
|
62
|
+
# to something understandable like "how many mm of water would there be on
|
63
|
+
# the ground if this amount of rain continued for an hour".
|
moat/kv/_cfg.yaml
CHANGED
@@ -26,7 +26,6 @@ runner: # for moat.kv.runner.RunnerRoot
|
|
26
26
|
state: !P :.moat.kv.state"
|
27
27
|
|
28
28
|
name: "run"
|
29
|
-
# Serf event name, suffixed by subpath
|
30
29
|
|
31
30
|
start_delay: 1
|
32
31
|
# time to wait between job starts. Not optional.
|
@@ -56,9 +55,6 @@ server:
|
|
56
55
|
# default
|
57
56
|
mqtt:
|
58
57
|
uri: "mqtt://localhost:1883"
|
59
|
-
serf:
|
60
|
-
host: "localhost"
|
61
|
-
port: 7373
|
62
58
|
|
63
59
|
# event message path/topic prefix
|
64
60
|
root: !P moat.kv
|
@@ -79,10 +75,10 @@ server:
|
|
79
75
|
ping:
|
80
76
|
cycle: 10
|
81
77
|
gap: 2
|
82
|
-
#
|
78
|
+
# asyncactor config timing for server sync
|
83
79
|
# ping also controls minimum server startup time
|
84
80
|
delete:
|
85
|
-
#
|
81
|
+
# asyncactor config timing for deletion
|
86
82
|
cycle: 100
|
87
83
|
gap: 10
|
88
84
|
version: 1
|
moat/kv/backend/mqtt.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: moat-kv
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.71.0
|
4
4
|
Summary: A distributed no-master key-value store
|
5
5
|
Author-email: Matthias Urlichs <matthias@urlichs.de>
|
6
6
|
Project-URL: homepage, https://m-o-a-t.org
|
@@ -25,7 +25,6 @@ Requires-Dist: trio>=0.22
|
|
25
25
|
Requires-Dist: anyio>=4
|
26
26
|
Requires-Dist: range_set>=0.2
|
27
27
|
Requires-Dist: attrs>=22
|
28
|
-
Requires-Dist: asyncserf>=0.16
|
29
28
|
Requires-Dist: asyncactor>=0.24
|
30
29
|
Requires-Dist: asyncscope>=0.10.4
|
31
30
|
Requires-Dist: jsonschema>=2.5
|
@@ -34,11 +33,9 @@ Requires-Dist: PyNaCl>=1.3
|
|
34
33
|
Requires-Dist: moat-lib-diffiehellman~=0.13.4
|
35
34
|
Requires-Dist: psutil
|
36
35
|
Requires-Dist: simpleeval>=0.9.10
|
37
|
-
Requires-Dist: moat-mqtt~=0.42.
|
36
|
+
Requires-Dist: moat-mqtt~=0.42.4
|
38
37
|
Requires-Dist: moat-util~=0.56.4
|
39
38
|
Requires-Dist: exceptiongroup; python_version < "3.11"
|
40
|
-
Provides-Extra: dev
|
41
|
-
Requires-Dist: moat-src>=0.5.0; extra == "dev"
|
42
39
|
Dynamic: license-file
|
43
40
|
|
44
41
|
=======
|
@@ -1,7 +1,7 @@
|
|
1
1
|
build/lib/docs/source/conf.py,sha256=v4cO_xK-WpfHeOCQ4RaeHFk8vwBM7Gg3sw6DgGLmpCc,6072
|
2
2
|
build/lib/examples/pathify.py,sha256=cq2j7Nqhl3jmoNZ6l8wMj4j7DkHMxyB7-oTOrCZA0xQ,1128
|
3
3
|
build/lib/moat/kv/__init__.py,sha256=TO2TyH5Focv78vDDqtiN1vZVLsVihrOqvHBAlLIgVRA,508
|
4
|
-
build/lib/moat/kv/_cfg.yaml,sha256=
|
4
|
+
build/lib/moat/kv/_cfg.yaml,sha256=HMyyiInthAOme_j9ydpfMzSvWVn_wgpNFAFyhpOCsuo,2153
|
5
5
|
build/lib/moat/kv/_main.py,sha256=SgI4ef8AQDOC4N4pLRiyaiSiFIzN-J337WIcuC7DPOY,2234
|
6
6
|
build/lib/moat/kv/client.py,sha256=c8YV0sjpO2XYpNE-fep7fDO2kgsNdShZxgCjohy23CY,34549
|
7
7
|
build/lib/moat/kv/code.py,sha256=gM7WNsjCfukr7h2fKm1U3zMHN5Wj-_hgy5U817LP9qE,6427
|
@@ -21,8 +21,7 @@ build/lib/moat/kv/auth/_test.py,sha256=ZaMpMf2CTJ6sdGyENUhdWAY5TLC-kBtszM3dFQbyu
|
|
21
21
|
build/lib/moat/kv/auth/password.py,sha256=DQG2BnNEoQ0H-znkHJx0G9-bcdWwg3IgqojcAHhKIsQ,6307
|
22
22
|
build/lib/moat/kv/auth/root.py,sha256=lW-_hgQp3ZIzAAe4iBl0rdMU-pFuHIC6ObA3rdFXxkk,1303
|
23
23
|
build/lib/moat/kv/backend/__init__.py,sha256=f5nIOWD2zml2YiaBNXtEOzC7SEGgwDFJMB8YzRISJ0A,1689
|
24
|
-
build/lib/moat/kv/backend/mqtt.py,sha256=
|
25
|
-
build/lib/moat/kv/backend/serf.py,sha256=i4u7V6h8SPO3XmP76DiARnFLC4M67xnQEX5-9SgbwtU,1295
|
24
|
+
build/lib/moat/kv/backend/mqtt.py,sha256=XUwMR8RPzq6EPLub0cy7YzXTS1CkfBZFtZ4W9GTcQBo,2007
|
26
25
|
build/lib/moat/kv/command/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8
|
27
26
|
build/lib/moat/kv/command/acl.py,sha256=wSdlzKBjWIFX3IxCdLcG3ZqjvtX8KPtqe38ibyU2VDo,4665
|
28
27
|
build/lib/moat/kv/command/auth.py,sha256=vP22ZIBMjRdUxN4_ELKiDgIE5ZqdMxs1ky1WDVUx50M,7149
|
@@ -38,14 +37,22 @@ build/lib/moat/kv/command/type.py,sha256=JN0_Abb5wR4UJH5zHnVZgT93NJRYY6qpRD_ZQT1
|
|
38
37
|
build/lib/moat/kv/command/dump/__init__.py,sha256=L05R6W9eDzUDAr7UhfEo1lZR-UB0qYUUf-5dRHC-p-0,4000
|
39
38
|
build/lib/moat/kv/mock/__init__.py,sha256=HW6YAwo_OBVRmTeRCc-ZoUHB7-D78cEONlcb5vACdIE,2760
|
40
39
|
build/lib/moat/kv/mock/mqtt.py,sha256=b9pzbwQBmTX2eSiSgNO7nh2-7l8-0TT8n2GxinQ-1l0,5213
|
41
|
-
build/lib/moat/kv/mock/serf.py,sha256=cuNT3jEXg3eq7Gs2R6734_gdWeyzZryZoT78MtemDH4,7611
|
42
40
|
build/lib/moat/kv/mock/tracer.py,sha256=qLEIn9gdlYUypyRYD8O8SbM8ye8XR4xtBl3otP6uNLs,2058
|
43
41
|
build/lib/moat/kv/obj/__init__.py,sha256=yeiZ6bWM8XhK28ruqX7RmpPhytYXlOJPRw_hsWbvExk,19800
|
44
42
|
build/lib/moat/kv/obj/command.py,sha256=QQiOhPtlGV07kuutV0KowmC2HiXhmIFUktofqlRg1GA,7446
|
43
|
+
ci/rtd-requirements.txt,sha256=q_4dVDUIuXYxY3nN9_NCKYUiBpktQFouyqfmCANc1W4,123
|
44
|
+
ci/test-requirements.txt,sha256=ABIHUDbtJ3hpVgItYyHuFbh9UKuRMYmkILROxc1ygmk,74
|
45
|
+
ci/travis.sh,sha256=CZiQZUebAmYYH3DUOArik0ktJCG8Q0DE7lb0D-porDo,3335
|
46
|
+
debian/.gitignore,sha256=hecgAHAGCwd3DkI44GQT08cmd8DaCcz-zOQuINQ7ZKs,97
|
47
|
+
debian/changelog,sha256=lcGqGWXCsqfuc6LC02cFdiK7c9RD4p9tNMSqOttB81s,32353
|
48
|
+
debian/control,sha256=a5aeNf2U0O9kAZjh28-g0-HuJsYksxPWTgVNZ5kW2VY,1441
|
49
|
+
debian/moat-kv.postinst,sha256=2z322zcHXXTX0lXcOUn9DBnVPNO4f_d8nsfxuhNpfHY,33
|
50
|
+
debian/rules,sha256=bOC4tJvuLUgFaQmBu_zxcjtJGn01HkZKhctnDoqT6WY,461
|
51
|
+
debian/watch,sha256=O8zhQHur_qoHyzVIewbea-dfUSkJmCmV7P6PzZFPkR4,191
|
45
52
|
debian/moat-kv/usr/lib/python3/dist-packages/docs/source/conf.py,sha256=v4cO_xK-WpfHeOCQ4RaeHFk8vwBM7Gg3sw6DgGLmpCc,6072
|
46
53
|
debian/moat-kv/usr/lib/python3/dist-packages/examples/pathify.py,sha256=cq2j7Nqhl3jmoNZ6l8wMj4j7DkHMxyB7-oTOrCZA0xQ,1128
|
47
54
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/__init__.py,sha256=TO2TyH5Focv78vDDqtiN1vZVLsVihrOqvHBAlLIgVRA,508
|
48
|
-
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml,sha256=
|
55
|
+
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml,sha256=HMyyiInthAOme_j9ydpfMzSvWVn_wgpNFAFyhpOCsuo,2153
|
49
56
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_main.py,sha256=SgI4ef8AQDOC4N4pLRiyaiSiFIzN-J337WIcuC7DPOY,2234
|
50
57
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/client.py,sha256=c8YV0sjpO2XYpNE-fep7fDO2kgsNdShZxgCjohy23CY,34549
|
51
58
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/code.py,sha256=gM7WNsjCfukr7h2fKm1U3zMHN5Wj-_hgy5U817LP9qE,6427
|
@@ -65,8 +72,7 @@ debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/_test.py,sha256=ZaMpMf
|
|
65
72
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/password.py,sha256=DQG2BnNEoQ0H-znkHJx0G9-bcdWwg3IgqojcAHhKIsQ,6307
|
66
73
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/root.py,sha256=lW-_hgQp3ZIzAAe4iBl0rdMU-pFuHIC6ObA3rdFXxkk,1303
|
67
74
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/__init__.py,sha256=f5nIOWD2zml2YiaBNXtEOzC7SEGgwDFJMB8YzRISJ0A,1689
|
68
|
-
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py,sha256=
|
69
|
-
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/serf.py,sha256=i4u7V6h8SPO3XmP76DiARnFLC4M67xnQEX5-9SgbwtU,1295
|
75
|
+
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py,sha256=XUwMR8RPzq6EPLub0cy7YzXTS1CkfBZFtZ4W9GTcQBo,2007
|
70
76
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8
|
71
77
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/acl.py,sha256=wSdlzKBjWIFX3IxCdLcG3ZqjvtX8KPtqe38ibyU2VDo,4665
|
72
78
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/auth.py,sha256=vP22ZIBMjRdUxN4_ELKiDgIE5ZqdMxs1ky1WDVUx50M,7149
|
@@ -82,14 +88,39 @@ debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/type.py,sha256=JN0_
|
|
82
88
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/dump/__init__.py,sha256=L05R6W9eDzUDAr7UhfEo1lZR-UB0qYUUf-5dRHC-p-0,4000
|
83
89
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/__init__.py,sha256=HW6YAwo_OBVRmTeRCc-ZoUHB7-D78cEONlcb5vACdIE,2760
|
84
90
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/mqtt.py,sha256=b9pzbwQBmTX2eSiSgNO7nh2-7l8-0TT8n2GxinQ-1l0,5213
|
85
|
-
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/serf.py,sha256=cuNT3jEXg3eq7Gs2R6734_gdWeyzZryZoT78MtemDH4,7611
|
86
91
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/tracer.py,sha256=qLEIn9gdlYUypyRYD8O8SbM8ye8XR4xtBl3otP6uNLs,2058
|
87
92
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/__init__.py,sha256=yeiZ6bWM8XhK28ruqX7RmpPhytYXlOJPRw_hsWbvExk,19800
|
88
93
|
debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/command.py,sha256=QQiOhPtlGV07kuutV0KowmC2HiXhmIFUktofqlRg1GA,7446
|
94
|
+
debian/source/format,sha256=G-cIDXLmtWbfPiNs4sVe_fu7j6HJctgl5bZy_4dzvho,12
|
95
|
+
docs/Makefile,sha256=g6jq_WYItszUyPzdvzs04ZgPOGXE_THsm2zAbvVUMnU,609
|
96
|
+
docs/make.bat,sha256=tZwnc3a-ozijIP3JTHDoSdNFMwXwrELNhOCFMBxB7K0,779
|
97
|
+
docs/source/TODO.rst,sha256=87ZE4VAEzSgYXr2BvUCnMFYa1TSNAr3nPiZNt0b6B5Y,1921
|
98
|
+
docs/source/acls.rst,sha256=qAG7SrTnBJv2IIS36FC74ubt0FJQ5rZBwd8yXuYQZd0,2018
|
99
|
+
docs/source/auth.rst,sha256=9-4se2vH-kbB86BiUMfafTXNtmHrPHH9nZDujRxw0ww,2603
|
100
|
+
docs/source/client_protocol.rst,sha256=X_EMTbWRXBotwAPDRCDeZUEBaK2OXul8t_PV0BiC1Gs,14094
|
101
|
+
docs/source/code.rst,sha256=ihHRtzpeEWGhioCUssakSrbkB7V2heA0Qca4RKcAv00,10371
|
102
|
+
docs/source/command_line.rst,sha256=jBK1-5Kc_ySTiIhVNK7W2Ffdf21MszCLFo3Z_aC04Kw,29241
|
103
|
+
docs/source/common_protocol.rst,sha256=8TT3OMZc0nX8wRSMg6gQk88OwQ2TekWTjcJVK4ymdfc,1281
|
89
104
|
docs/source/conf.py,sha256=v4cO_xK-WpfHeOCQ4RaeHFk8vwBM7Gg3sw6DgGLmpCc,6072
|
105
|
+
docs/source/debugging.rst,sha256=1wZIQGsHjMoLCKAK0TPlvAtxqMU4UyvHa6tUhXN4_eE,2188
|
106
|
+
docs/source/extend.rst,sha256=UjLPvKaod14mEbi20r2Qtx2ROZmsu2cWRAENMfFhlD4,1402
|
107
|
+
docs/source/history.rst,sha256=ba0qchAJyGI0exigWDrhYT26KfxjIYEnf8hFcr_XKJ8,868
|
108
|
+
docs/source/index.rst,sha256=8-oMWmXV6aXzUT6JK-ghYZMphDu98srReAVkj4IV3jU,1866
|
109
|
+
docs/source/model.rst,sha256=8yZfsmoOikxDw-0d82ArPg3MP-XzLWou0lfw8Ry8C0Q,1622
|
110
|
+
docs/source/overview.rst,sha256=-PdRj09LBJP-in5zWMO66OXTCu04tZvuReyeOlHP64c,3409
|
111
|
+
docs/source/related.rst,sha256=CvlTLgsnnha3646NMhH7Kg9KW1WZr0xQistU903C9Gc,2749
|
112
|
+
docs/source/server_protocol.rst,sha256=l9uG0yKOSmr9X7JuokWYbOauGUyp-FZYnbP73UTHNgk,16180
|
113
|
+
docs/source/startup.rst,sha256=vx2_zvNrKHiRaYK5GIfzzJ1SmtMtVJ8yXJHfRhfxWuI,1085
|
114
|
+
docs/source/translator.rst,sha256=b1x0H_8E9abPEA-dBk656wWQpnioGpNmJKfbZz1XnnU,7513
|
115
|
+
docs/source/tutorial.rst,sha256=uoAZR44f6734Y7N9TYLai6-SEF0iPZRfJ8iXHn0yeKA,22429
|
116
|
+
docs/source/v3.rst,sha256=EQf1i4LJe7cSyWCgi_gLYAJjBmeF1KJ5yaKRzpB5psc,3960
|
117
|
+
docs/source/_static/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
90
118
|
examples/pathify.py,sha256=cq2j7Nqhl3jmoNZ6l8wMj4j7DkHMxyB7-oTOrCZA0xQ,1128
|
119
|
+
examples/code/transform.scale.yml,sha256=aim0aTXvbrGfkNsZ6WM5JUHTXfZdGCvKPGhq-8O9IQo,550
|
120
|
+
examples/code/transform.switch.yml,sha256=NUoO3241TtL-L-orMR0a3i2I0ZJLpgbz_TVXT07NocE,3033
|
121
|
+
examples/code/transform.timeslot.yml,sha256=9SSOEE77rT2iveH0UZLrmv9VeUJkAgb5k5bGV5C8WAk,2142
|
91
122
|
moat/kv/__init__.py,sha256=TO2TyH5Focv78vDDqtiN1vZVLsVihrOqvHBAlLIgVRA,508
|
92
|
-
moat/kv/_cfg.yaml,sha256=
|
123
|
+
moat/kv/_cfg.yaml,sha256=HMyyiInthAOme_j9ydpfMzSvWVn_wgpNFAFyhpOCsuo,2153
|
93
124
|
moat/kv/_main.py,sha256=SgI4ef8AQDOC4N4pLRiyaiSiFIzN-J337WIcuC7DPOY,2234
|
94
125
|
moat/kv/client.py,sha256=c8YV0sjpO2XYpNE-fep7fDO2kgsNdShZxgCjohy23CY,34549
|
95
126
|
moat/kv/code.py,sha256=gM7WNsjCfukr7h2fKm1U3zMHN5Wj-_hgy5U817LP9qE,6427
|
@@ -109,8 +140,7 @@ moat/kv/auth/_test.py,sha256=ZaMpMf2CTJ6sdGyENUhdWAY5TLC-kBtszM3dFQbyuWA,4342
|
|
109
140
|
moat/kv/auth/password.py,sha256=DQG2BnNEoQ0H-znkHJx0G9-bcdWwg3IgqojcAHhKIsQ,6307
|
110
141
|
moat/kv/auth/root.py,sha256=lW-_hgQp3ZIzAAe4iBl0rdMU-pFuHIC6ObA3rdFXxkk,1303
|
111
142
|
moat/kv/backend/__init__.py,sha256=f5nIOWD2zml2YiaBNXtEOzC7SEGgwDFJMB8YzRISJ0A,1689
|
112
|
-
moat/kv/backend/mqtt.py,sha256=
|
113
|
-
moat/kv/backend/serf.py,sha256=i4u7V6h8SPO3XmP76DiARnFLC4M67xnQEX5-9SgbwtU,1295
|
143
|
+
moat/kv/backend/mqtt.py,sha256=XUwMR8RPzq6EPLub0cy7YzXTS1CkfBZFtZ4W9GTcQBo,2007
|
114
144
|
moat/kv/command/__init__.py,sha256=9_8wL9Scv8_Cs8HJyJHGvx1vwXErsuvlsAqNZLcJQR0,8
|
115
145
|
moat/kv/command/acl.py,sha256=wSdlzKBjWIFX3IxCdLcG3ZqjvtX8KPtqe38ibyU2VDo,4665
|
116
146
|
moat/kv/command/auth.py,sha256=vP22ZIBMjRdUxN4_ELKiDgIE5ZqdMxs1ky1WDVUx50M,7149
|
@@ -126,12 +156,33 @@ moat/kv/command/type.py,sha256=JN0_Abb5wR4UJH5zHnVZgT93NJRYY6qpRD_ZQT13u4k,6226
|
|
126
156
|
moat/kv/command/dump/__init__.py,sha256=L05R6W9eDzUDAr7UhfEo1lZR-UB0qYUUf-5dRHC-p-0,4000
|
127
157
|
moat/kv/mock/__init__.py,sha256=HW6YAwo_OBVRmTeRCc-ZoUHB7-D78cEONlcb5vACdIE,2760
|
128
158
|
moat/kv/mock/mqtt.py,sha256=b9pzbwQBmTX2eSiSgNO7nh2-7l8-0TT8n2GxinQ-1l0,5213
|
129
|
-
moat/kv/mock/serf.py,sha256=cuNT3jEXg3eq7Gs2R6734_gdWeyzZryZoT78MtemDH4,7611
|
130
159
|
moat/kv/mock/tracer.py,sha256=qLEIn9gdlYUypyRYD8O8SbM8ye8XR4xtBl3otP6uNLs,2058
|
131
160
|
moat/kv/obj/__init__.py,sha256=yeiZ6bWM8XhK28ruqX7RmpPhytYXlOJPRw_hsWbvExk,19800
|
132
161
|
moat/kv/obj/command.py,sha256=QQiOhPtlGV07kuutV0KowmC2HiXhmIFUktofqlRg1GA,7446
|
133
|
-
moat_kv-0.
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
162
|
+
moat_kv-0.71.0.dist-info/licenses/LICENSE.txt,sha256=L5vKJLVOg5t0CEEPpW9-O_0vzbP0PEjEF06tLvnIDuk,541
|
163
|
+
scripts/current,sha256=91NXrtN9AWtOdwGZs-yTaAgU_EKF4xXPo9Dvr9E3BkA,374
|
164
|
+
scripts/env,sha256=Le76hZQSvDrNiFfhCzK0PDe4STLOdIpMcsQTYgk74Qs,113
|
165
|
+
scripts/init,sha256=gvezyZaPG-6RJ5nLC9Wc0kR_tZaiJAjLpJfRVnyfFik,1071
|
166
|
+
scripts/recover,sha256=dBuIN9v6yJ_dffVAsax8AfnD9oRfQHi0U8kk5w1ReH4,332
|
167
|
+
scripts/rotate,sha256=zoBI7A5hN54TNgC0FYIMGusHmqe1LcICNyhkukL7eYs,837
|
168
|
+
scripts/run,sha256=Zbh5Qa5oYmn-fMpg_qUaPVbJrpDx4ht0rjKSm0eQt7E,795
|
169
|
+
scripts/run-all,sha256=GlheLEcCxQejv0cPmPPHSpXvK0ZcGQ_XDbt7W-ouPTM,220
|
170
|
+
scripts/run-any,sha256=y0y1Lk7ppUnOtiYrcAWHBetsW77nZEmlx-S2A7mhxYg,210
|
171
|
+
scripts/run-single,sha256=GmGi5Nu0uUmcs5PJiEBaEbz3O7k1-669nUoAX-Bj2KQ,316
|
172
|
+
scripts/success,sha256=KCkdAPsgiEiUBcEgluKJFcB5fGk6VEv0Uo8FP9frKLA,33
|
173
|
+
systemd/moat-kv-recover.service,sha256=zqqDEBW21iQ8O2tBdiAMEUoGdgt1ZLLzmhToIAq76Ew,355
|
174
|
+
systemd/moat-kv-rotate.service,sha256=BFhLT6FIwk0w0q9AH_mfKS9S1T0wcjr-8oH01bn2LPI,355
|
175
|
+
systemd/moat-kv-rotate.timer,sha256=vQ6oVU4KhvD9q-90y8GUil1ewIv0ld4jULrLelHJ-2I,161
|
176
|
+
systemd/moat-kv-run-all.service,sha256=D34_d8o3qmNAGEtlqpdx4oaU2jUd7h3qypkjQMcGgHE,428
|
177
|
+
systemd/moat-kv-run-all@.service,sha256=-00TrYu3-3k01spmb0_FfbZFBkzguOMcp3LUyjiesfI,397
|
178
|
+
systemd/moat-kv-run-any.service,sha256=kINPhW7CIQCIuMsuKnXTkzOw9dTZ-ujxpJWWQPcC-Ic,428
|
179
|
+
systemd/moat-kv-run-any@.service,sha256=EQXBp1P-MgAzGD1wr2RXgBDkz_zx1MGcz6FMf09GCwU,397
|
180
|
+
systemd/moat-kv-run-single.service,sha256=ASLd9fH-tY8ZnAsuPmNxiuKaVfGzLC56EJU39UtlEgk,436
|
181
|
+
systemd/moat-kv-run-single@.service,sha256=uhy3Pl9ojm4vJhYVP1CxYdM_e-vtIq0q6b-oWjrdABQ,402
|
182
|
+
systemd/moat-kv.service,sha256=g9BtStXpKDQ0o3Ivgw5t9s5KintzXabJIR6FvL-nJnQ,502
|
183
|
+
systemd/postinst,sha256=INv8dSI8KT5VKX9Fr8uN0l6IbAO3Bi28aTQTgfQArL8,198
|
184
|
+
systemd/sysusers,sha256=swfLW1o9tZ8i1d8KL5JP75R1p7DVMekLX0r-YTNPZlY,78
|
185
|
+
moat_kv-0.71.0.dist-info/METADATA,sha256=sRDrUCQS6Kf6Z6xmDdcXPzbNFv3wougCrsWIRcrqu2c,3271
|
186
|
+
moat_kv-0.71.0.dist-info/WHEEL,sha256=xcaH6rP_nCxh1LBIPM7Q0uOnzSGjsIye-Q44j_zbzw8,104
|
187
|
+
moat_kv-0.71.0.dist-info/top_level.txt,sha256=LyFVSz3-SU-7B8r2qZ3ODVF_QvXqE08qepkD1rfQLk4,56
|
188
|
+
moat_kv-0.71.0.dist-info/RECORD,,
|
scripts/current
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -ex
|
3
|
+
|
4
|
+
# This script takes the most-current state files and writes them to the
|
5
|
+
# named file.
|
6
|
+
|
7
|
+
test -n "$1"
|
8
|
+
F="$(python3 -c "import sys; from os.path import abspath; print(abspath(sys.argv[1]))" "$1")"
|
9
|
+
|
10
|
+
mkdir -p "$DEST"
|
11
|
+
cd "$DEST"
|
12
|
+
d=$(find . -name 0.dkv -size +1c -print | sort -r | head -1)
|
13
|
+
cd $(dirname "$d")
|
14
|
+
|
15
|
+
ls | grep '\.dkv$' | sort -n | xargs cat > "$TEMP"
|
scripts/env
ADDED
scripts/init
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -ex
|
3
|
+
|
4
|
+
# This script sets up an initial MoaT-KV master.
|
5
|
+
systemd-sysusers --no-pager /usr/lib/sysusers.d/moat-kv.conf
|
6
|
+
|
7
|
+
. /usr/lib/moat/kv/env
|
8
|
+
|
9
|
+
mkdir -p /etc/moat
|
10
|
+
test -f /etc/moat/kv.env || touch /etc/moat/kv.env
|
11
|
+
grep -qs '^MODE=' /etc/moat/kv.env || echo MODE=hybrid >>/etc/moat/kv.env
|
12
|
+
grep -qs '^NAME=' /etc/moat/kv.env || echo NAME=$(hostname) >>/etc/moat/kv.env
|
13
|
+
grep -qs '^LOCAL=' /etc/moat/kv.env || echo LOCAL=no >>/etc/moat/kv.env
|
14
|
+
|
15
|
+
. /etc/moat/kv.env
|
16
|
+
|
17
|
+
if test "$MODE" != "slave" ; then
|
18
|
+
mkdir -p "$DEST"
|
19
|
+
cd "$DEST"
|
20
|
+
d="$(find . -name 0.dkv -size +1c | sort | head -1)"
|
21
|
+
if test -n "$d" ; then
|
22
|
+
d="$(dirname "$d")"
|
23
|
+
else
|
24
|
+
d="$(date -d 2019-01-01 +"$DATE")"
|
25
|
+
mkdir -p "$d"
|
26
|
+
fi
|
27
|
+
cd $d
|
28
|
+
|
29
|
+
if test ! -s "0.dkv" ; then
|
30
|
+
moat kv dump init $NAME 0.dkv
|
31
|
+
chown -R MoaT-KV:MoaT "$DEST"
|
32
|
+
fi
|
33
|
+
fi
|
34
|
+
|
35
|
+
if test "$(moat util cfg kv.conn.host)" = "127.0.0.1" ; then
|
36
|
+
systemctl enable moat-kv.service
|
37
|
+
systemctl enable moat-kv-rotate.timer || true # may be masked
|
38
|
+
systemctl restart moat-kv.service &
|
39
|
+
fi
|
scripts/recover
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -ex
|
3
|
+
|
4
|
+
# This script tries to recover from hybrid mode start failure
|
5
|
+
# by re-starting in master mode.
|
6
|
+
|
7
|
+
if ! test "$MODE" = hybrid ; then
|
8
|
+
echo "Not hybrid mode. Not restarting." >&2
|
9
|
+
exit 1
|
10
|
+
fi
|
11
|
+
|
12
|
+
if test -f "$TEMP" ; then
|
13
|
+
echo "$TEMP exists, not restarting" >&2
|
14
|
+
exit 1
|
15
|
+
fi
|
16
|
+
/usr/lib/moat/kv/current "$TEMP"
|
17
|
+
|
scripts/rotate
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -ex
|
3
|
+
|
4
|
+
# This script tells MoaT-KV to continue with the next log file.
|
5
|
+
# By default it writes a full dump daily.
|
6
|
+
|
7
|
+
cd "$DEST"
|
8
|
+
D=$(date +"$DATE")
|
9
|
+
test -d $D || mkdir -p $D
|
10
|
+
cd $D
|
11
|
+
|
12
|
+
x=$(ls|sort -rn|head -1)
|
13
|
+
if test -n "$x" ; then
|
14
|
+
x=$(expr $(basename $x .dkv) + 1)
|
15
|
+
I="-i"
|
16
|
+
else
|
17
|
+
x=0
|
18
|
+
I=""
|
19
|
+
fi
|
20
|
+
|
21
|
+
export PYTHONPATH
|
22
|
+
moat -c /etc/moat/moat.cfg kv client log dest $I "$DEST/$D/$x.dkv"
|
23
|
+
if test $x -eq 0 ; then
|
24
|
+
# Now, delete some old backups
|
25
|
+
cd "$DEST"
|
26
|
+
|
27
|
+
# delete hourly after ten days but keep the day's first backup
|
28
|
+
find . -maxdepth 1 ! -name \*-00 -mtime +10 -print0|xargs -0r rm -rf
|
29
|
+
# delete daily after 45 days but keep the month's first backup
|
30
|
+
find . -maxdepth 1 ! -name \*01-00 -mtime +45 -print0|xargs -0r rm -rf
|
31
|
+
# delete monthly (i.e. the rest) after a year or so
|
32
|
+
find . -maxdepth 1 -mtime +400 -print0|xargs -0r rm -rf
|
33
|
+
fi
|