serverwatcher 5.18__tar.gz → 5.20__tar.gz
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.
- {serverwatcher-5.18/src/serverwatcher.egg-info → serverwatcher-5.20}/PKG-INFO +1 -1
- {serverwatcher-5.18 → serverwatcher-5.20}/pyproject.toml +1 -1
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/configclasses/config.py +2 -4
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/configclasses/watcher.py +8 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/defaultconfigs/config.yaml +2 -4
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/defaultconfigs/watcher.yaml +5 -1
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/validator.py +5 -5
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/watcher.py +23 -17
- {serverwatcher-5.18 → serverwatcher-5.20/src/serverwatcher.egg-info}/PKG-INFO +1 -1
- {serverwatcher-5.18 → serverwatcher-5.20}/LICENSE +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/README.md +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/setup.cfg +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/__init__.py +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/__main__.py +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/configclasses/__init__.py +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/configclasses/messages.py +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher/defaultconfigs/messages.yaml +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher.egg-info/SOURCES.txt +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher.egg-info/dependency_links.txt +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher.egg-info/requires.txt +0 -0
- {serverwatcher-5.18 → serverwatcher-5.20}/src/serverwatcher.egg-info/top_level.txt +0 -0
|
@@ -11,8 +11,6 @@ class GlobalConfig:
|
|
|
11
11
|
panel_url: str = 'panel.url'
|
|
12
12
|
panel_api_key: str = 'panel.api_key'
|
|
13
13
|
|
|
14
|
-
origin_server_id: str = 'origin.server_id'
|
|
15
|
-
|
|
16
14
|
server_name: str = 'server.name'
|
|
17
15
|
server_id: str = 'server.server_id'
|
|
18
16
|
server_domain: str = 'server.domain'
|
|
@@ -32,6 +30,7 @@ class GlobalConfig:
|
|
|
32
30
|
error_prefix: str = 'logger.prefixes.error'
|
|
33
31
|
|
|
34
32
|
clear_terminal: bool = 'terminal.enable_clearing'
|
|
33
|
+
handle_keyboard_interrupt: bool = 'terminal.handle_keyboard_interrupt'
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
class fallbacks:
|
|
@@ -41,8 +40,6 @@ class fallbacks:
|
|
|
41
40
|
panel_url = 'https://example.com'
|
|
42
41
|
panel_api_key = 'CHANGE_ME'
|
|
43
42
|
|
|
44
|
-
origin_server_id = 'CHANGE_ME'
|
|
45
|
-
|
|
46
43
|
server_name = 'My SMP'
|
|
47
44
|
server_id = 'CHANGE_ME'
|
|
48
45
|
server_domain = 'mc.example.com'
|
|
@@ -62,3 +59,4 @@ class fallbacks:
|
|
|
62
59
|
error_prefix = '<red>[ERROR]: '
|
|
63
60
|
|
|
64
61
|
clear_terminal = True
|
|
62
|
+
handle_keyboard_interrupt = True
|
|
@@ -14,6 +14,8 @@ class WatcherConfig:
|
|
|
14
14
|
threshold_cpu: int = 'thresholds.cpu'
|
|
15
15
|
threshold_uptime: int = 'thresholds.uptime'
|
|
16
16
|
threshold_tps: float = 'thresholds.tps'
|
|
17
|
+
threshold_min_uptime: int = 'thresholds.min_uptime'
|
|
18
|
+
threshold_low_gap: int = 'thresholds.low_gap'
|
|
17
19
|
|
|
18
20
|
weight_restart_soon: int = 'weights.restart_soon'
|
|
19
21
|
weight_ram: int = 'weights.ram'
|
|
@@ -27,6 +29,8 @@ class WatcherConfig:
|
|
|
27
29
|
low_gap_minutes: int = 'gaps.low_gap_minutes'
|
|
28
30
|
high_gap_minutes: int = 'gaps.high_gap_minutes'
|
|
29
31
|
|
|
32
|
+
snap_minutes: list = 'snap_minutes'
|
|
33
|
+
|
|
30
34
|
restart_wait_seconds: int = 'restart.wait_seconds'
|
|
31
35
|
restart_timeout: int = 'restart.online_timeout'
|
|
32
36
|
restart_online_interval: int = 'restart.online_interval'
|
|
@@ -42,6 +46,8 @@ class fallbacks:
|
|
|
42
46
|
threshold_cpu = 150
|
|
43
47
|
threshold_uptime = 12
|
|
44
48
|
threshold_tps = 19.5
|
|
49
|
+
threshold_min_uptime = 30
|
|
50
|
+
threshold_low_gap = 2
|
|
45
51
|
|
|
46
52
|
weight_restart_soon = 3
|
|
47
53
|
weight_ram = 1
|
|
@@ -55,6 +61,8 @@ class fallbacks:
|
|
|
55
61
|
low_gap_minutes = 120
|
|
56
62
|
high_gap_minutes = 60
|
|
57
63
|
|
|
64
|
+
snap_minutes = [0, 30]
|
|
65
|
+
|
|
58
66
|
restart_wait_seconds = 30
|
|
59
67
|
restart_timeout = 120
|
|
60
68
|
restart_online_interval = 2
|
|
@@ -5,9 +5,6 @@ panel:
|
|
|
5
5
|
url: 'https://example.com'
|
|
6
6
|
api_key: 'CHANGE_ME'
|
|
7
7
|
|
|
8
|
-
origin:
|
|
9
|
-
server_id: 'CHANGE_ME'
|
|
10
|
-
|
|
11
8
|
server:
|
|
12
9
|
name: 'My SMP'
|
|
13
10
|
server_id: 'CHANGE_ME'
|
|
@@ -30,4 +27,5 @@ logger:
|
|
|
30
27
|
error: "<red>[%hh%:%mm%:%ss%] [ERROR]: "
|
|
31
28
|
|
|
32
29
|
terminal:
|
|
33
|
-
enable_clearing: True
|
|
30
|
+
enable_clearing: True
|
|
31
|
+
handle_keyboard_interrupt: True
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
watch_interval: 300
|
|
1
|
+
watch_interval: 300 # in seconds
|
|
2
2
|
|
|
3
3
|
schedule_control:
|
|
4
4
|
enabled: False
|
|
@@ -9,6 +9,8 @@ thresholds:
|
|
|
9
9
|
cpu: 150
|
|
10
10
|
uptime: 12
|
|
11
11
|
tps: 19.5
|
|
12
|
+
min_uptime: 30 # will not restart the server if the total uptime is less than 30 minutes
|
|
13
|
+
low_gap: 2
|
|
12
14
|
|
|
13
15
|
weights:
|
|
14
16
|
restart_soon: 3
|
|
@@ -23,6 +25,8 @@ gaps:
|
|
|
23
25
|
low_gap_minutes: 120
|
|
24
26
|
high_gap_minutes: 60
|
|
25
27
|
|
|
28
|
+
snap_minutes: [0, 30] # will snap the scheduled time to the nearest hour or half hour
|
|
29
|
+
|
|
26
30
|
restart:
|
|
27
31
|
wait_seconds: 30
|
|
28
32
|
online_timeout: 120
|
|
@@ -50,12 +50,15 @@ def validate_global_config(config, errors):
|
|
|
50
50
|
if config.bridge_port <= 0 or config.bridge_port > 65535:
|
|
51
51
|
errors.append(f'bridge_port: must be 1–65535 (got {config.bridge_port})')
|
|
52
52
|
|
|
53
|
+
if len(config.bridge_token) < 8:
|
|
54
|
+
errors.append(f'bridge_token: must be 8 or more characters (got {config.bridge_token}, {len(config.bridge_token)} characters)')
|
|
55
|
+
|
|
53
56
|
def validate_watcher_config(watcherconfig, errors):
|
|
54
57
|
if watcherconfig.restart_wait_seconds < 1:
|
|
55
|
-
errors.append(f'restart_wait_seconds: must be
|
|
58
|
+
errors.append(f'restart_wait_seconds: must be > 0 (got {watcherconfig.restart_wait_seconds})')
|
|
56
59
|
|
|
57
60
|
if watcherconfig.threshold_cpu <= 0:
|
|
58
|
-
errors.append(f'threshold_cpu: must
|
|
61
|
+
errors.append(f'threshold_cpu: must be > 0 (got {watcherconfig.threshold_cpu})')
|
|
59
62
|
|
|
60
63
|
if watcherconfig.threshold_ram <= 0:
|
|
61
64
|
errors.append(f'threshold_ram: must be > 0 (got {watcherconfig.threshold_ram})')
|
|
@@ -80,9 +83,6 @@ def ensure_no_global_defaults(config, defaults):
|
|
|
80
83
|
if config.panel_api_key == fb.panel_api_key:
|
|
81
84
|
defaults.append('panel_api_key')
|
|
82
85
|
|
|
83
|
-
if config.origin_server_id == fb.origin_server_id:
|
|
84
|
-
defaults.append('origin_server_id')
|
|
85
|
-
|
|
86
86
|
if config.server_id == fb.server_id:
|
|
87
87
|
defaults.append('server_id')
|
|
88
88
|
|
|
@@ -93,7 +93,7 @@ class ServerWatcher:
|
|
|
93
93
|
self.router.error(self.messages.server_failed_restart)
|
|
94
94
|
|
|
95
95
|
def schedule_restart(self, minutes):
|
|
96
|
-
info = utils.snapSchedule(minimumMinutes=minutes)
|
|
96
|
+
info = utils.snapSchedule(minimumMinutes=minutes, snapMinutes=tuple(sorted(self.watcherconfig.snap_minutes)))
|
|
97
97
|
scheduled = info["scheduled"]
|
|
98
98
|
|
|
99
99
|
local_time = scheduled.astimezone(self.tz)
|
|
@@ -104,7 +104,8 @@ class ServerWatcher:
|
|
|
104
104
|
minute_callbacks = {
|
|
105
105
|
int(k.split("_")[1]): (
|
|
106
106
|
lambda raw=self.messages.as_map()[k]:
|
|
107
|
-
self.router.broadcast(mapit(raw))
|
|
107
|
+
self.router.broadcast(mapit(raw)),
|
|
108
|
+
self.router.origin(raw)
|
|
108
109
|
)
|
|
109
110
|
for k in self.messages.as_map()
|
|
110
111
|
if k.startswith("minute_")
|
|
@@ -113,17 +114,14 @@ class ServerWatcher:
|
|
|
113
114
|
second_callbacks = {
|
|
114
115
|
int(k.split("_")[1]): (
|
|
115
116
|
lambda raw=self.messages.as_map()[k]:
|
|
116
|
-
self.router.broadcast(mapit(raw))
|
|
117
|
+
self.router.broadcast(mapit(raw)),
|
|
118
|
+
self.router.origin(raw)
|
|
117
119
|
)
|
|
118
120
|
for k in self.messages.as_map()
|
|
119
121
|
if k.startswith("second_")
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
utils.runCountdownEvents(
|
|
123
|
-
target_time=scheduled,
|
|
124
|
-
minute_callbacks=minute_callbacks,
|
|
125
|
-
second_callbacks=second_callbacks,
|
|
126
|
-
)
|
|
124
|
+
utils.runCountdownEvents(target_time=scheduled, minute_callbacks=minute_callbacks, second_callbacks=second_callbacks)
|
|
127
125
|
|
|
128
126
|
def evaluate(self):
|
|
129
127
|
# Lets Pterodactyl know the server is online, then clears terminal and uses user-defined startup key
|
|
@@ -167,7 +165,7 @@ class ServerWatcher:
|
|
|
167
165
|
restart_reasons.append(mapit(self.messages.reason_tps, tps=snap.tps, threshold=self.watcherconfig.threshold_tps))
|
|
168
166
|
pro += self.watcherconfig.weight_tps
|
|
169
167
|
|
|
170
|
-
if snap.uptime // 60 <
|
|
168
|
+
if snap.uptime // 60 < self.watcherconfig.threshold_min_uptime:
|
|
171
169
|
no_restart_reasons.append(mapit(self.messages.reason_low_uptime, uptime=snap.uptime_formatted))
|
|
172
170
|
anti += self.watcherconfig.weight_low_uptime
|
|
173
171
|
|
|
@@ -203,7 +201,7 @@ class ServerWatcher:
|
|
|
203
201
|
|
|
204
202
|
self.router.info(self.messages.scheduled)
|
|
205
203
|
|
|
206
|
-
if gap <=
|
|
204
|
+
if gap <= self.watcherconfig.threshold_low_gap:
|
|
207
205
|
self.router.warn(self.messages.gap_low, gap=gap)
|
|
208
206
|
self.schedule_restart(self.watcherconfig.low_gap_minutes)
|
|
209
207
|
else:
|
|
@@ -213,10 +211,18 @@ class ServerWatcher:
|
|
|
213
211
|
self.restart_and_wait()
|
|
214
212
|
|
|
215
213
|
def run(self):
|
|
216
|
-
if self.config.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
214
|
+
if self.config.handle_keyboard_interrupt:
|
|
215
|
+
try:
|
|
216
|
+
while True:
|
|
217
|
+
if self.config.clear_terminal:
|
|
218
|
+
utils.clearTerminal()
|
|
219
|
+
self.evaluate()
|
|
220
|
+
time.sleep(self.watcherconfig.watch_interval)
|
|
221
|
+
except KeyboardInterrupt:
|
|
222
|
+
self.shutdown()
|
|
223
|
+
else:
|
|
224
|
+
while True:
|
|
225
|
+
if self.config.clear_terminal:
|
|
226
|
+
utils.clearTerminal()
|
|
227
|
+
self.evaluate()
|
|
228
|
+
time.sleep(self.watcherconfig.watch_interval)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|