@ouro.bot/cli 0.1.0-alpha.746 → 0.1.0-alpha.748
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.748",
|
|
6
|
+
"changes": [
|
|
7
|
+
"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.",
|
|
8
|
+
"Remove the exact legacy Unraid boot hook that rewrites the managed Usenet cron entry after reboot."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"version": "0.1.0-alpha.747",
|
|
13
|
+
"changes": [
|
|
14
|
+
"Create every nested host-backup directory as root-private before provenance verification.",
|
|
15
|
+
"Accept a missing OCI source label only on Sanctuary's exact historical alpha.742 image while retaining strict source provenance for every other image."
|
|
16
|
+
]
|
|
17
|
+
},
|
|
4
18
|
{
|
|
5
19
|
"version": "0.1.0-alpha.746",
|
|
6
20
|
"changes": [
|
package/deploy/unraid/README.txt
CHANGED
|
@@ -141,7 +141,8 @@ Effective-spec audit helper:
|
|
|
141
141
|
return 1
|
|
142
142
|
}
|
|
143
143
|
Define these fail-closed image and topology helpers in the same shell. They use
|
|
144
|
-
exact Docker image IDs and
|
|
144
|
+
exact Docker image IDs and container identity, image provenance, and writable
|
|
145
|
+
root overlap; no mutation is performed:
|
|
145
146
|
validate_exact_image_id() {
|
|
146
147
|
VALIDATE_IMAGE_ID=$1
|
|
147
148
|
case "$VALIDATE_IMAGE_ID" in
|
|
@@ -155,18 +156,43 @@ Effective-spec audit helper:
|
|
|
155
156
|
docker image inspect "$VALIDATE_IMAGE_ID" >/dev/null || return $?
|
|
156
157
|
}
|
|
157
158
|
assert_only_running_butler() {
|
|
159
|
+
(
|
|
158
160
|
EXPECTED_RUNNING_BUTLER=$1
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
case "$EXPECTED_RUNNING_BUTLER" in
|
|
162
|
+
-) EXPECTED_RUNNING_BUTLER_COUNT=0 ;;
|
|
163
|
+
ouro-butler|ouro-butler-staging) EXPECTED_RUNNING_BUTLER_COUNT=1 ;;
|
|
164
|
+
*) return 1 ;;
|
|
165
|
+
esac
|
|
166
|
+
RUNNING_CONTAINER_IDS=$(docker container ls -q) || return $?
|
|
167
|
+
MATCHING_RUNNING_BUTLERS=0
|
|
168
|
+
for RUNNING_CONTAINER_ID in $RUNNING_CONTAINER_IDS; do
|
|
169
|
+
RUNNING_CONTAINER_NAME=$(docker container inspect --format '{{.Name}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
170
|
+
RUNNING_CONTAINER_NAME=${RUNNING_CONTAINER_NAME#/}
|
|
171
|
+
if test "$RUNNING_CONTAINER_NAME" = "$EXPECTED_RUNNING_BUTLER"; then
|
|
172
|
+
MATCHING_RUNNING_BUTLERS=$(( MATCHING_RUNNING_BUTLERS + 1 ))
|
|
173
|
+
continue
|
|
174
|
+
fi
|
|
175
|
+
RUNNING_CONTAINER_IMAGE_ID=$(docker container inspect --format '{{.Image}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
176
|
+
RUNNING_CONTAINER_IMAGE_REF=$(docker container inspect --format '{{.Config.Image}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
177
|
+
RUNNING_CONTAINER_IMAGE_SOURCE=$(docker image inspect --format '{{with .Config.Labels}}{{index . "org.opencontainers.image.source"}}{{end}}' "$RUNNING_CONTAINER_IMAGE_ID") || return $?
|
|
178
|
+
test "$RUNNING_CONTAINER_IMAGE_SOURCE" != https://github.com/ourostack/ouroboros || return 1
|
|
179
|
+
test "$RUNNING_CONTAINER_IMAGE_ID" != sha256:681449ad47a2621705cd339b481e6339236b31dc65e195b1cf5025d0f2191d7d || return 1
|
|
180
|
+
case "$RUNNING_CONTAINER_IMAGE_REF" in
|
|
181
|
+
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 ;;
|
|
182
|
+
esac
|
|
183
|
+
RUNNING_WRITABLE_MOUNT_SOURCES=$(docker container inspect --format '{{range .Mounts}}{{if .RW}}{{println .Source}}{{end}}{{end}}' "$RUNNING_CONTAINER_ID") || return $?
|
|
184
|
+
if printf '%s\n' "$RUNNING_WRITABLE_MOUNT_SOURCES" | awk '
|
|
185
|
+
function overlaps(path, root) {
|
|
186
|
+
return length(path) > 0 && (path == root || index(path, root "/") == 1 || index(root, path "/") == 1)
|
|
165
187
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
188
|
+
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 }
|
|
189
|
+
END { exit found ? 0 : 1 }
|
|
190
|
+
'; then
|
|
191
|
+
return 1
|
|
192
|
+
fi
|
|
193
|
+
done
|
|
194
|
+
test "$MATCHING_RUNNING_BUTLERS" -eq "$EXPECTED_RUNNING_BUTLER_COUNT" || return $?
|
|
195
|
+
)
|
|
170
196
|
}
|
|
171
197
|
assert_update_topology() {
|
|
172
198
|
EXPECTED_ROLLBACK_IMAGE_ID=$1
|
|
@@ -311,7 +337,9 @@ Effective-spec audit helper:
|
|
|
311
337
|
const image = JSON.parse(fs.readFileSync(imagePath, "utf8"));
|
|
312
338
|
if (!Array.isArray(container) || container.length !== 1 || !container[0] || container[0].Image !== imageId) process.exit(1);
|
|
313
339
|
if (!Array.isArray(image) || image.length !== 1 || !image[0] || image[0].Id !== imageId) process.exit(1);
|
|
314
|
-
|
|
340
|
+
const source = image[0].Config?.Labels?.["org.opencontainers.image.source"];
|
|
341
|
+
const legacyAlpha742 = "sha256:681449ad47a2621705cd339b481e6339236b31dc65e195b1cf5025d0f2191d7d";
|
|
342
|
+
if (source !== "https://github.com/ourostack/ouroboros" && !(source === undefined && imageId === legacyAlpha742)) process.exit(1);
|
|
315
343
|
const expected = ["custom/usenet_health.sh", "custom/ouro-events/bootstrap-spool.sh", "custom/ouro-events/emit-event.mjs", "custom/ouro-events/emit-usenet-event.sh", "custom/ouro-events/install-usenet-guard.sh", "go.butler-lines", "crontab.butler-lines", "global-state"];
|
|
316
344
|
const expectedUid = 0;
|
|
317
345
|
const expectedGid = 0;
|
|
@@ -784,6 +812,7 @@ Effective-spec audit helper:
|
|
|
784
812
|
&& CURRENT_LEGACY_EVIDENCE_IMAGE_ID=$(docker inspect --format '{{.Image}}' ouro-butler-legacy-evidence) \
|
|
785
813
|
&& test "$CURRENT_LEGACY_EVIDENCE_IMAGE_ID" = "$LEGACY_STAGING_IMAGE_ID" \
|
|
786
814
|
&& test "$(docker inspect --format '{{.State.Running}}' ouro-butler-legacy-evidence)" = false \
|
|
815
|
+
&& assert_only_running_butler - \
|
|
787
816
|
&& docker create --name ouro-butler-staging --network host --restart unless-stopped --user 10001:10001 \
|
|
788
817
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/runtime/.ouro-cli,dst=/home/ouro/.ouro-cli" \
|
|
789
818
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro,dst=/home/ouro/AgentBundles/sanctuary.ouro" \
|
|
@@ -797,6 +826,7 @@ Effective-spec audit helper:
|
|
|
797
826
|
&& docker stop ouro-butler-staging \
|
|
798
827
|
&& test "$(docker inspect --format '{{.Image}}' ouro-butler-staging)" = "$IMAGE_ID" \
|
|
799
828
|
&& docker rm ouro-butler-staging \
|
|
829
|
+
&& assert_only_running_butler - \
|
|
800
830
|
&& docker create --name ouro-butler --network host --restart unless-stopped --user 10001:10001 \
|
|
801
831
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/runtime/.ouro-cli,dst=/home/ouro/.ouro-cli" \
|
|
802
832
|
--mount "type=bind,src=/mnt/user/appdata/ouro-butler/agent/sanctuary.ouro,dst=/home/ouro/AgentBundles/sanctuary.ouro" \
|
|
@@ -1360,6 +1390,7 @@ Update:
|
|
|
1360
1390
|
cmp -s "$EVENT_SCRIPT_STAGE/install-usenet-guard.sh" /boot/config/custom/ouro-events/install-usenet-guard.sh
|
|
1361
1391
|
test "$(grep -Fxc '/bin/bash /boot/config/custom/ouro-events/install-usenet-guard.sh --boot --install-root /boot/config/custom' /boot/config/go)" = 1
|
|
1362
1392
|
test "$(grep -Fxc '/boot/config/custom/ouro-events/bootstrap-spool.sh --mount' /boot/config/go || true)" = 0
|
|
1393
|
+
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
|
|
1363
1394
|
INSTALLED_GUARD_CRON=$(crontab -l)
|
|
1364
1395
|
test "$(printf '%s\n' "$INSTALLED_GUARD_CRON" | grep -Fxc '*/15 * * * * /bin/bash /boot/config/custom/usenet_health.sh # ouro:usenet-health')" = 1
|
|
1365
1396
|
INSTALLED_LEGACY_GUARD_COUNT=$(printf '%s\n' "$INSTALLED_GUARD_CRON" | grep -Fxc '*/15 * * * * /bin/bash /boot/config/custom/usenet_health.sh' || true)
|
|
@@ -1509,6 +1540,7 @@ ouro-butler-rollback
|
|
|
1509
1540
|
&& remove_stopped_rollback_if_present "$ROLLBACK_IMAGE_ID" \
|
|
1510
1541
|
&& docker rename ouro-butler ouro-butler-rollback \
|
|
1511
1542
|
&& test "$(docker inspect --format '{{.State.Running}}' ouro-butler-rollback)" = false \
|
|
1543
|
+
&& assert_only_running_butler - \
|
|
1512
1544
|
&& migrate_sanctuary_package_managed_bundle "$IMAGE_ID" migrate "$ROLLBACK_IMAGE_ID"; then
|
|
1513
1545
|
:
|
|
1514
1546
|
else
|
|
@@ -1564,7 +1596,8 @@ ouro-butler-rollback
|
|
|
1564
1596
|
&& assert_only_running_butler ouro-butler-staging \
|
|
1565
1597
|
&& wait_butler_ready ouro-butler-staging \
|
|
1566
1598
|
&& docker stop ouro-butler-staging \
|
|
1567
|
-
&& docker rm ouro-butler-staging
|
|
1599
|
+
&& docker rm ouro-butler-staging \
|
|
1600
|
+
&& assert_only_running_butler -; then
|
|
1568
1601
|
:
|
|
1569
1602
|
else
|
|
1570
1603
|
STAGING_ACTIVATION_STATUS=$?
|
|
@@ -1786,7 +1819,7 @@ Backup:
|
|
|
1786
1819
|
if docker stop ouro-butler \
|
|
1787
1820
|
&& test "$(docker inspect --format '{{.State.Running}}' ouro-butler)" = false \
|
|
1788
1821
|
&& install -d -m 0700 -o 0 -g 0 "$BACKUP_TMP" "$BACKUP_TMP/runtime" "$BACKUP_TMP/agent" "$BACKUP_TMP/host" "$BACKUP_TMP/provenance" \
|
|
1789
|
-
&& install -d -m 0700 -o 0 -g 0 "$BACKUP_TMP/host/custom/ouro-events" \
|
|
1822
|
+
&& install -d -m 0700 -o 0 -g 0 "$BACKUP_TMP/host/custom" "$BACKUP_TMP/host/custom/ouro-events" \
|
|
1790
1823
|
&& install -m 0600 -o 0 -g 0 /dev/null "$BACKUP_TMP/host/inventory" \
|
|
1791
1824
|
&& backup_host_file /boot/config/custom/usenet_health.sh custom/usenet_health.sh \
|
|
1792
1825
|
&& backup_host_file /boot/config/custom/ouro-events/bootstrap-spool.sh custom/ouro-events/bootstrap-spool.sh \
|
|
@@ -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.748</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.748",
|
|
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.748",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|