@ouro.bot/cli 0.1.0-alpha.747 → 0.1.0-alpha.749
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.
package/changelog.json
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.749",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Fix Unraid Butler autostart updates through the root-local Docker manager backend with durable rollback and ghost-entry preservation.",
|
|
8
|
+
"Align the packaged Sanctuary template and bundle runtime metadata with alpha.749."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"version": "0.1.0-alpha.748",
|
|
13
|
+
"changes": [
|
|
14
|
+
"Reject any unexpected running Ouro image or writable Sanctuary-root overlap, including legacy and package-managed layouts, across zero-poller and active-poller deployment handoffs.",
|
|
15
|
+
"Remove the exact legacy Unraid boot hook that rewrites the managed Usenet cron entry after reboot."
|
|
16
|
+
]
|
|
17
|
+
},
|
|
4
18
|
{
|
|
5
19
|
"version": "0.1.0-alpha.747",
|
|
6
20
|
"changes": [
|
package/deploy/unraid/README.txt
CHANGED
|
@@ -52,12 +52,55 @@ Effective-spec audit helper:
|
|
|
52
52
|
trap - EXIT || return $?
|
|
53
53
|
)
|
|
54
54
|
}
|
|
55
|
-
Define these helpers in the same root shell. Each
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
Define these helpers in the same root shell. Each profile change calls Unraid's
|
|
56
|
+
own root-local Docker manager backend, after proving exact durable identities.
|
|
57
|
+
A missing Butler entry is a no-op when disabling; this avoids the backend's
|
|
58
|
+
false-to-index-zero behavior. The helper preserves every non-Butler row byte
|
|
59
|
+
for byte and restores the complete captured file atomically on any failure:
|
|
60
|
+
butler_autostart_counts() {
|
|
61
|
+
(
|
|
62
|
+
AUTOSTART_FILE=/var/lib/docker/unraid-autostart
|
|
63
|
+
test -f "$AUTOSTART_FILE" || return $?
|
|
64
|
+
awk '
|
|
65
|
+
$1 == "ouro-butler" { production++ }
|
|
66
|
+
$1 == "ouro-butler-staging" { staging++ }
|
|
67
|
+
$1 == "ouro-butler-rollback" { rollback++ }
|
|
68
|
+
$1 == "ouro-butler-legacy-evidence" { legacy++ }
|
|
69
|
+
END { printf "%d %d %d %d", production + 0, staging + 0, rollback + 0, legacy + 0 }
|
|
70
|
+
' "$AUTOSTART_FILE"
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
snapshot_nonbutler_autostart() {
|
|
74
|
+
awk '
|
|
75
|
+
$1 != "ouro-butler" && $1 != "ouro-butler-staging" && $1 != "ouro-butler-rollback" && $1 != "ouro-butler-legacy-evidence" { print }
|
|
76
|
+
' /var/lib/docker/unraid-autostart
|
|
77
|
+
}
|
|
78
|
+
run_unraid_autostart_backend() {
|
|
79
|
+
(
|
|
80
|
+
AUTOSTART_ACTION=$1
|
|
81
|
+
AUTOSTART_CONTAINER=$2
|
|
82
|
+
AUTOSTART_VALUE=$3
|
|
83
|
+
case "$AUTOSTART_ACTION:$AUTOSTART_VALUE" in wait:0|autostart:true|autostart:false) ;; *) return 1 ;; esac
|
|
84
|
+
case "$AUTOSTART_CONTAINER" in
|
|
85
|
+
ouro-butler|ouro-butler-staging|ouro-butler-rollback|ouro-butler-legacy-evidence) ;;
|
|
86
|
+
*) return 1 ;;
|
|
87
|
+
esac
|
|
88
|
+
timeout -s KILL 20 /usr/bin/php -r '
|
|
89
|
+
[$action, $container, $value] = array_slice($argv, 1);
|
|
90
|
+
$allowed = ["ouro-butler", "ouro-butler-staging", "ouro-butler-rollback", "ouro-butler-legacy-evidence"];
|
|
91
|
+
if (!in_array($container, $allowed, true)) exit(2);
|
|
92
|
+
if ($action === "wait" && $value === "0") {
|
|
93
|
+
$_POST = ["action" => "wait", "container" => $container, "wait" => "0"];
|
|
94
|
+
} elseif ($action === "autostart" && ($value === "true" || $value === "false")) {
|
|
95
|
+
$_POST = ["action" => "autostart", "container" => $container, "auto" => $value, "wait" => "0"];
|
|
96
|
+
} else exit(2);
|
|
97
|
+
$_SERVER["DOCUMENT_ROOT"] = "/usr/local/emhttp";
|
|
98
|
+
$_SERVER["REQUEST_URI"] = "docker";
|
|
99
|
+
require "/usr/local/emhttp/plugins/dynamix.docker.manager/include/UpdateConfig.php";
|
|
100
|
+
' "$AUTOSTART_ACTION" "$AUTOSTART_CONTAINER" "$AUTOSTART_VALUE"
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
mutate_butler_autostart() {
|
|
61
104
|
(
|
|
62
105
|
AUTOSTART_CONTAINER=$1
|
|
63
106
|
AUTOSTART_ENABLED=$2
|
|
@@ -66,35 +109,102 @@ Effective-spec audit helper:
|
|
|
66
109
|
*) return 1 ;;
|
|
67
110
|
esac
|
|
68
111
|
case "$AUTOSTART_ENABLED" in true|false) ;; *) return 1 ;; esac
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
test
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
112
|
+
AUTOSTART_COUNT=$(awk -v name="$AUTOSTART_CONTAINER" '$1 == name { count++ } END { print count + 0 }' /var/lib/docker/unraid-autostart) || return $?
|
|
113
|
+
case "$AUTOSTART_COUNT" in 0|1) ;; *) return 1 ;; esac
|
|
114
|
+
if test "$AUTOSTART_ENABLED" = false && test "$AUTOSTART_COUNT" -eq 0; then
|
|
115
|
+
return 0
|
|
116
|
+
fi
|
|
117
|
+
if test "$AUTOSTART_COUNT" -eq 1; then
|
|
118
|
+
run_unraid_autostart_backend wait "$AUTOSTART_CONTAINER" 0 || return $?
|
|
119
|
+
fi
|
|
120
|
+
if test "$AUTOSTART_ENABLED" = false; then
|
|
121
|
+
run_unraid_autostart_backend autostart "$AUTOSTART_CONTAINER" false || return $?
|
|
122
|
+
AUTOSTART_EXPECTED_COUNT=0
|
|
123
|
+
else
|
|
124
|
+
if test "$AUTOSTART_COUNT" -eq 0; then
|
|
125
|
+
run_unraid_autostart_backend autostart "$AUTOSTART_CONTAINER" true || return $?
|
|
126
|
+
fi
|
|
127
|
+
AUTOSTART_EXPECTED_COUNT=1
|
|
128
|
+
fi
|
|
129
|
+
AUTOSTART_COUNT=$(awk -v name="$AUTOSTART_CONTAINER" '$1 == name { count++ } END { print count + 0 }' /var/lib/docker/unraid-autostart) || return $?
|
|
130
|
+
test "$AUTOSTART_COUNT" -eq "$AUTOSTART_EXPECTED_COUNT" || return $?
|
|
85
131
|
)
|
|
86
132
|
}
|
|
87
|
-
|
|
133
|
+
set_butler_autostart() {
|
|
88
134
|
(
|
|
135
|
+
AUTOSTART_PROFILE=$1
|
|
136
|
+
case "$AUTOSTART_PROFILE" in disabled|production) ;; *) return 1 ;; esac
|
|
137
|
+
test "$(id -u)" -eq 0 || return $?
|
|
89
138
|
AUTOSTART_FILE=/var/lib/docker/unraid-autostart
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
139
|
+
AUTOSTART_INCLUDE=/usr/local/emhttp/plugins/dynamix.docker.manager/include/UpdateConfig.php
|
|
140
|
+
test -f "$AUTOSTART_FILE" && test ! -L "$AUTOSTART_FILE" || return 1
|
|
141
|
+
test "$(stat -c '%u:%g:%a' "$AUTOSTART_FILE")" = 0:0:644 || return $?
|
|
142
|
+
test -f "$AUTOSTART_INCLUDE" && test ! -L "$AUTOSTART_INCLUDE" || return 1
|
|
143
|
+
test "$(stat -c '%u:%g:%a' "$AUTOSTART_INCLUDE")" = 0:0:644 || return $?
|
|
144
|
+
AUTOSTART_COUNTS=$(butler_autostart_counts) || return $?
|
|
145
|
+
set -- $AUTOSTART_COUNTS
|
|
146
|
+
test "$#" -eq 4 || return $?
|
|
147
|
+
for AUTOSTART_COUNT in "$@"; do case "$AUTOSTART_COUNT" in 0|1) ;; *) return 1 ;; esac; done
|
|
148
|
+
if test "$AUTOSTART_PROFILE" = production; then
|
|
149
|
+
docker container inspect ouro-butler >/dev/null 2>&1 || return $?
|
|
150
|
+
fi
|
|
151
|
+
AUTOSTART_BACKUP=$(mktemp /var/lib/docker/.unraid-autostart.ouro.XXXXXX) || return $?
|
|
152
|
+
AUTOSTART_NONBUTLER_BEFORE=$(mktemp /run/unraid-autostart.nonbutler-before.XXXXXX) || { rm -f -- "$AUTOSTART_BACKUP"; return 1; }
|
|
153
|
+
AUTOSTART_NONBUTLER_AFTER=$(mktemp /run/unraid-autostart.nonbutler-after.XXXXXX) || { rm -f -- "$AUTOSTART_BACKUP" "$AUTOSTART_NONBUTLER_BEFORE"; return 1; }
|
|
154
|
+
AUTOSTART_COMMITTED=no
|
|
155
|
+
AUTOSTART_BACKUP_READY=no
|
|
156
|
+
AUTOSTART_RESTORE_TMP=
|
|
157
|
+
autostart_cleanup() {
|
|
158
|
+
AUTOSTART_STATUS=$?
|
|
159
|
+
trap - EXIT HUP INT TERM
|
|
160
|
+
if test "$AUTOSTART_COMMITTED" = yes; then
|
|
161
|
+
rm -f -- "$AUTOSTART_BACKUP" || AUTOSTART_STATUS=1
|
|
162
|
+
elif test "$AUTOSTART_BACKUP_READY" = yes; then
|
|
163
|
+
AUTOSTART_RESTORE_TMP=$(mktemp /var/lib/docker/.unraid-autostart.restore.XXXXXX) || AUTOSTART_RESTORE_TMP=
|
|
164
|
+
if test -n "$AUTOSTART_RESTORE_TMP" \
|
|
165
|
+
&& cp -p -- "$AUTOSTART_BACKUP" "$AUTOSTART_RESTORE_TMP" \
|
|
166
|
+
&& sync -f "$AUTOSTART_RESTORE_TMP" \
|
|
167
|
+
&& mv -f -- "$AUTOSTART_RESTORE_TMP" "$AUTOSTART_FILE" \
|
|
168
|
+
&& sync -f "$AUTOSTART_FILE" \
|
|
169
|
+
&& sync -f /var/lib/docker; then
|
|
170
|
+
rm -f -- "$AUTOSTART_BACKUP" || AUTOSTART_STATUS=1
|
|
171
|
+
else
|
|
172
|
+
test -z "$AUTOSTART_RESTORE_TMP" || rm -f -- "$AUTOSTART_RESTORE_TMP"
|
|
173
|
+
printf 'CRITICAL: Butler autostart rollback failed; recovery copy preserved at %s\n' "$AUTOSTART_BACKUP" >&2
|
|
174
|
+
AUTOSTART_STATUS=1
|
|
175
|
+
fi
|
|
176
|
+
else
|
|
177
|
+
rm -f -- "$AUTOSTART_BACKUP" || AUTOSTART_STATUS=1
|
|
178
|
+
fi
|
|
179
|
+
rm -f -- "$AUTOSTART_NONBUTLER_BEFORE" "$AUTOSTART_NONBUTLER_AFTER" || AUTOSTART_STATUS=1
|
|
180
|
+
exit "$AUTOSTART_STATUS"
|
|
181
|
+
}
|
|
182
|
+
trap autostart_cleanup EXIT
|
|
183
|
+
trap 'exit 129' HUP
|
|
184
|
+
trap 'exit 130' INT
|
|
185
|
+
trap 'exit 143' TERM
|
|
186
|
+
cp -p -- "$AUTOSTART_FILE" "$AUTOSTART_BACKUP" || return $?
|
|
187
|
+
cmp -s -- "$AUTOSTART_FILE" "$AUTOSTART_BACKUP" || return 1
|
|
188
|
+
sync -f "$AUTOSTART_BACKUP" || return $?
|
|
189
|
+
sync -f /var/lib/docker || return $?
|
|
190
|
+
AUTOSTART_BACKUP_READY=yes
|
|
191
|
+
snapshot_nonbutler_autostart >"$AUTOSTART_NONBUTLER_BEFORE" || return $?
|
|
192
|
+
mutate_butler_autostart ouro-butler-staging false || return $?
|
|
193
|
+
mutate_butler_autostart ouro-butler-rollback false || return $?
|
|
194
|
+
mutate_butler_autostart ouro-butler-legacy-evidence false || return $?
|
|
195
|
+
if test "$AUTOSTART_PROFILE" = production; then
|
|
196
|
+
mutate_butler_autostart ouro-butler true || return $?
|
|
197
|
+
AUTOSTART_EXPECTED_COUNTS="1 0 0 0"
|
|
198
|
+
else
|
|
199
|
+
mutate_butler_autostart ouro-butler false || return $?
|
|
200
|
+
AUTOSTART_EXPECTED_COUNTS="0 0 0 0"
|
|
201
|
+
fi
|
|
202
|
+
verify_butler_autostart "$AUTOSTART_EXPECTED_COUNTS" || return $?
|
|
203
|
+
snapshot_nonbutler_autostart >"$AUTOSTART_NONBUTLER_AFTER" || return $?
|
|
204
|
+
cmp -s -- "$AUTOSTART_NONBUTLER_BEFORE" "$AUTOSTART_NONBUTLER_AFTER" || return 1
|
|
205
|
+
sync -f "$AUTOSTART_FILE" || return $?
|
|
206
|
+
sync -f /var/lib/docker || return $?
|
|
207
|
+
AUTOSTART_COMMITTED=yes
|
|
98
208
|
)
|
|
99
209
|
}
|
|
100
210
|
verify_butler_autostart() {
|
|
@@ -105,17 +215,11 @@ Effective-spec audit helper:
|
|
|
105
215
|
)
|
|
106
216
|
}
|
|
107
217
|
disable_butler_autostart() {
|
|
108
|
-
set_butler_autostart
|
|
109
|
-
set_butler_autostart ouro-butler-rollback false || return $?
|
|
110
|
-
set_butler_autostart ouro-butler-legacy-evidence false || return $?
|
|
111
|
-
set_butler_autostart ouro-butler false || return $?
|
|
218
|
+
set_butler_autostart disabled || return $?
|
|
112
219
|
verify_butler_autostart "0 0 0 0" || return $?
|
|
113
220
|
}
|
|
114
221
|
enable_butler_autostart() {
|
|
115
|
-
set_butler_autostart
|
|
116
|
-
set_butler_autostart ouro-butler-rollback false || return $?
|
|
117
|
-
set_butler_autostart ouro-butler-legacy-evidence false || return $?
|
|
118
|
-
set_butler_autostart ouro-butler true || return $?
|
|
222
|
+
set_butler_autostart production || return $?
|
|
119
223
|
verify_butler_autostart "1 0 0 0" || return $?
|
|
120
224
|
}
|
|
121
225
|
This bounded wait accepts only Docker's healthy state. The image healthcheck
|
|
@@ -141,7 +245,8 @@ Effective-spec audit helper:
|
|
|
141
245
|
return 1
|
|
142
246
|
}
|
|
143
247
|
Define these fail-closed image and topology helpers in the same shell. They use
|
|
144
|
-
exact Docker image IDs and
|
|
248
|
+
exact Docker image IDs and container identity, image provenance, and writable
|
|
249
|
+
root overlap; no mutation is performed:
|
|
145
250
|
validate_exact_image_id() {
|
|
146
251
|
VALIDATE_IMAGE_ID=$1
|
|
147
252
|
case "$VALIDATE_IMAGE_ID" in
|
|
@@ -155,18 +260,43 @@ Effective-spec audit helper:
|
|
|
155
260
|
docker image inspect "$VALIDATE_IMAGE_ID" >/dev/null || return $?
|
|
156
261
|
}
|
|
157
262
|
assert_only_running_butler() {
|
|
263
|
+
(
|
|
158
264
|
EXPECTED_RUNNING_BUTLER=$1
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
265
|
+
case "$EXPECTED_RUNNING_BUTLER" in
|
|
266
|
+
-) EXPECTED_RUNNING_BUTLER_COUNT=0 ;;
|
|
267
|
+
ouro-butler|ouro-butler-staging) EXPECTED_RUNNING_BUTLER_COUNT=1 ;;
|
|
268
|
+
*) return 1 ;;
|
|
269
|
+
esac
|
|
270
|
+
RUNNING_CONTAINER_IDS=$(docker container ls -q) || return $?
|
|
271
|
+
MATCHING_RUNNING_BUTLERS=0
|
|
272
|
+
for RUNNING_CONTAINER_ID in $RUNNING_CONTAINER_IDS; do
|
|
273
|
+
RUNNING_CONTAINER_NAME=$(docker container inspect --format '{{.Name}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
274
|
+
RUNNING_CONTAINER_NAME=${RUNNING_CONTAINER_NAME#/}
|
|
275
|
+
if test "$RUNNING_CONTAINER_NAME" = "$EXPECTED_RUNNING_BUTLER"; then
|
|
276
|
+
MATCHING_RUNNING_BUTLERS=$(( MATCHING_RUNNING_BUTLERS + 1 ))
|
|
277
|
+
continue
|
|
278
|
+
fi
|
|
279
|
+
RUNNING_CONTAINER_IMAGE_ID=$(docker container inspect --format '{{.Image}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
280
|
+
RUNNING_CONTAINER_IMAGE_REF=$(docker container inspect --format '{{.Config.Image}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
281
|
+
RUNNING_CONTAINER_IMAGE_SOURCE=$(docker image inspect --format '{{with .Config.Labels}}{{index . "org.opencontainers.image.source"}}{{end}}' "$RUNNING_CONTAINER_IMAGE_ID") || return $?
|
|
282
|
+
test "$RUNNING_CONTAINER_IMAGE_SOURCE" != https://github.com/ourostack/ouroboros || return 1
|
|
283
|
+
test "$RUNNING_CONTAINER_IMAGE_ID" != sha256:681449ad47a2621705cd339b481e6339236b31dc65e195b1cf5025d0f2191d7d || return 1
|
|
284
|
+
case "$RUNNING_CONTAINER_IMAGE_REF" in
|
|
285
|
+
ouro-butler|ouro-butler:*|ouro-butler@sha256:*|ouroboros-butler|ouroboros-butler:*|ouroboros-butler@sha256:*|ghcr.io/ourostack/ouroboros-butler|ghcr.io/ourostack/ouroboros-butler:*|ghcr.io/ourostack/ouroboros-butler@sha256:*) return 1 ;;
|
|
286
|
+
esac
|
|
287
|
+
RUNNING_WRITABLE_MOUNT_SOURCES=$(docker container inspect --format '{{range .Mounts}}{{if .RW}}{{println .Source}}{{end}}{{end}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
288
|
+
if printf '%s\n' "$RUNNING_WRITABLE_MOUNT_SOURCES" | awk '
|
|
289
|
+
function overlaps(path, root) {
|
|
290
|
+
return length(path) > 0 && (path == root || index(path, root "/") == 1 || index(root, path "/") == 1)
|
|
165
291
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
292
|
+
overlaps($0, "/mnt/user/appdata/ouro-butler/runtime") || overlaps($0, "/mnt/user/appdata/ouro-butler/runtime/.ouro-cli") || overlaps($0, "/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro") || overlaps($0, "/mnt/user/appdata/ouro-butler/AgentBundles") { found = 1 }
|
|
293
|
+
END { exit found ? 0 : 1 }
|
|
294
|
+
'; then
|
|
295
|
+
return 1
|
|
296
|
+
fi
|
|
297
|
+
done
|
|
298
|
+
test "$MATCHING_RUNNING_BUTLERS" -eq "$EXPECTED_RUNNING_BUTLER_COUNT" || return $?
|
|
299
|
+
)
|
|
170
300
|
}
|
|
171
301
|
assert_update_topology() {
|
|
172
302
|
EXPECTED_ROLLBACK_IMAGE_ID=$1
|
|
@@ -786,6 +916,7 @@ Effective-spec audit helper:
|
|
|
786
916
|
&& CURRENT_LEGACY_EVIDENCE_IMAGE_ID=$(docker inspect --format '{{.Image}}' ouro-butler-legacy-evidence) \
|
|
787
917
|
&& test "$CURRENT_LEGACY_EVIDENCE_IMAGE_ID" = "$LEGACY_STAGING_IMAGE_ID" \
|
|
788
918
|
&& test "$(docker inspect --format '{{.State.Running}}' ouro-butler-legacy-evidence)" = false \
|
|
919
|
+
&& assert_only_running_butler - \
|
|
789
920
|
&& docker create --name ouro-butler-staging --network host --restart unless-stopped --user 10001:10001 \
|
|
790
921
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/runtime/.ouro-cli,dst=/home/ouro/.ouro-cli" \
|
|
791
922
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro,dst=/home/ouro/AgentBundles/sanctuary.ouro" \
|
|
@@ -799,6 +930,7 @@ Effective-spec audit helper:
|
|
|
799
930
|
&& docker stop ouro-butler-staging \
|
|
800
931
|
&& test "$(docker inspect --format '{{.Image}}' ouro-butler-staging)" = "$IMAGE_ID" \
|
|
801
932
|
&& docker rm ouro-butler-staging \
|
|
933
|
+
&& assert_only_running_butler - \
|
|
802
934
|
&& docker create --name ouro-butler --network host --restart unless-stopped --user 10001:10001 \
|
|
803
935
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/runtime/.ouro-cli,dst=/home/ouro/.ouro-cli" \
|
|
804
936
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro,dst=/home/ouro/AgentBundles/sanctuary.ouro" \
|
|
@@ -1362,6 +1494,7 @@ Update:
|
|
|
1362
1494
|
cmp -s "$EVENT_SCRIPT_STAGE/install-usenet-guard.sh" /boot/config/custom/ouro-events/install-usenet-guard.sh
|
|
1363
1495
|
test "$(grep -Fxc '/bin/bash /boot/config/custom/ouro-events/install-usenet-guard.sh --boot --install-root /boot/config/custom' /boot/config/go)" = 1
|
|
1364
1496
|
test "$(grep -Fxc '/boot/config/custom/ouro-events/bootstrap-spool.sh --mount' /boot/config/go || true)" = 0
|
|
1497
|
+
test "$(grep -Fxc '(crontab -l 2>/dev/null | grep -v usenet_health; echo "*/15 * * * * /bin/bash /boot/config/custom/usenet_health.sh") | crontab -' /boot/config/go || true)" = 0
|
|
1365
1498
|
INSTALLED_GUARD_CRON=$(crontab -l)
|
|
1366
1499
|
test "$(printf '%s\n' "$INSTALLED_GUARD_CRON" | grep -Fxc '*/15 * * * * /bin/bash /boot/config/custom/usenet_health.sh # ouro:usenet-health')" = 1
|
|
1367
1500
|
INSTALLED_LEGACY_GUARD_COUNT=$(printf '%s\n' "$INSTALLED_GUARD_CRON" | grep -Fxc '*/15 * * * * /bin/bash /boot/config/custom/usenet_health.sh' || true)
|
|
@@ -1511,6 +1644,7 @@ ouro-butler-rollback
|
|
|
1511
1644
|
&& remove_stopped_rollback_if_present "$ROLLBACK_IMAGE_ID" \
|
|
1512
1645
|
&& docker rename ouro-butler ouro-butler-rollback \
|
|
1513
1646
|
&& test "$(docker inspect --format '{{.State.Running}}' ouro-butler-rollback)" = false \
|
|
1647
|
+
&& assert_only_running_butler - \
|
|
1514
1648
|
&& migrate_sanctuary_package_managed_bundle "$IMAGE_ID" migrate "$ROLLBACK_IMAGE_ID"; then
|
|
1515
1649
|
:
|
|
1516
1650
|
else
|
|
@@ -1566,7 +1700,8 @@ ouro-butler-rollback
|
|
|
1566
1700
|
&& assert_only_running_butler ouro-butler-staging \
|
|
1567
1701
|
&& wait_butler_ready ouro-butler-staging \
|
|
1568
1702
|
&& docker stop ouro-butler-staging \
|
|
1569
|
-
&& docker rm ouro-butler-staging
|
|
1703
|
+
&& docker rm ouro-butler-staging \
|
|
1704
|
+
&& assert_only_running_butler -; then
|
|
1570
1705
|
:
|
|
1571
1706
|
else
|
|
1572
1707
|
STAGING_ACTIVATION_STATUS=$?
|
|
@@ -49,6 +49,7 @@ LEGACY_BOOT_HOOK="/boot/config/custom/ouro-events/bootstrap-spool.sh --mount"
|
|
|
49
49
|
LEGACY_BASH_BOOT_HOOK="/bin/bash /boot/config/custom/ouro-events/bootstrap-spool.sh --mount"
|
|
50
50
|
CANONICAL_PREVIOUS_BOOT_HOOK="/bin/bash /boot/config/custom/ouro-events/install-usenet-guard.sh --boot"
|
|
51
51
|
CANONICAL_BOOT_HOOK="$CANONICAL_PREVIOUS_BOOT_HOOK --install-root /boot/config/custom"
|
|
52
|
+
LEGACY_CRON_BOOT_HOOK='(crontab -l 2>/dev/null | grep -v usenet_health; echo "*/15 * * * * /bin/bash /boot/config/custom/usenet_health.sh") | crontab -'
|
|
52
53
|
printf -v HEALTH_SCRIPT_Q '%q' "$INSTALL_ROOT/usenet_health.sh"
|
|
53
54
|
CRON_LINE="*/15 * * * * /bin/bash $HEALTH_SCRIPT_Q # ouro:usenet-health"
|
|
54
55
|
LEGACY_CRON_LINE="*/15 * * * * /bin/bash $HEALTH_SCRIPT_Q"
|
|
@@ -125,7 +126,7 @@ render_inactive_cron() {
|
|
|
125
126
|
|
|
126
127
|
is_canonical_butler_go_hook() {
|
|
127
128
|
case "$1" in
|
|
128
|
-
"$LEGACY_BOOT_HOOK"|"$LEGACY_BASH_BOOT_HOOK"|"$CANONICAL_PREVIOUS_BOOT_HOOK"|"$CANONICAL_BOOT_HOOK") return 0 ;;
|
|
129
|
+
"$LEGACY_BOOT_HOOK"|"$LEGACY_BASH_BOOT_HOOK"|"$CANONICAL_PREVIOUS_BOOT_HOOK"|"$CANONICAL_BOOT_HOOK"|"$PREVIOUS_INSTALLER_BOOT_HOOK"|"$BOOT_HOOK"|"$LEGACY_CRON_BOOT_HOOK") return 0 ;;
|
|
129
130
|
*) return 1 ;;
|
|
130
131
|
esac
|
|
131
132
|
}
|
|
@@ -232,7 +233,7 @@ install_transaction() {
|
|
|
232
233
|
printf '#!/bin/bash\n' > "$stage/go.base"
|
|
233
234
|
fi
|
|
234
235
|
go_candidate="$stage/go.candidate"
|
|
235
|
-
|
|
236
|
+
render_go_without_owned "$stage/go.base" "$stage/go.filtered"
|
|
236
237
|
if [ -s "$stage/go.filtered" ]; then
|
|
237
238
|
awk -v hook="$BOOT_HOOK" 'NR == 1 && /^#!/ { print; print hook; next } NR == 1 { print hook } { print }' "$stage/go.filtered" > "$go_candidate"
|
|
238
239
|
else
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0"?>
|
|
2
2
|
<Container version="2">
|
|
3
3
|
<Name>Mendelow Cloud Butler</Name>
|
|
4
|
-
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.
|
|
4
|
+
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.749</Repository>
|
|
5
5
|
<Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
|
|
6
6
|
<Network>host</Network>
|
|
7
7
|
<Shell>sh</Shell>
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.749",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@ouro.bot/cli",
|
|
9
|
-
"version": "0.1.0-alpha.
|
|
9
|
+
"version": "0.1.0-alpha.749",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|