@keepur/hive 0.2.6 → 0.2.7
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/package.json +1 -1
- package/pkg/cli.min.js +122 -122
- package/service/deploy-check.sh +15 -1
- package/service/deploy.sh +129 -72
- package/service/instances.conf +19 -4
package/service/deploy-check.sh
CHANGED
|
@@ -16,7 +16,10 @@ set -euo pipefail
|
|
|
16
16
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
17
17
|
BUILD_DIR="${BUILD_DIR:-$HOME/build/hive}"
|
|
18
18
|
DEPLOY_DIR="${DEPLOY_DIR:-$HOME/services/hive}"
|
|
19
|
-
|
|
19
|
+
# HIVE_INSTANCES_CONF (KPR-70) lets multi-instance dev hosts point at a
|
|
20
|
+
# workspace-level conf outside .hive/, so engine swaps don't wipe their
|
|
21
|
+
# registry. The shipped $SCRIPT_DIR/instances.conf is empty by design.
|
|
22
|
+
INSTANCES_CONF="${HIVE_INSTANCES_CONF:-$SCRIPT_DIR/instances.conf}"
|
|
20
23
|
|
|
21
24
|
cd "$BUILD_DIR"
|
|
22
25
|
[[ "$(git branch --show-current)" == "deploy" ]] || { echo "ERROR: Build dir not on deploy branch"; exit 1; }
|
|
@@ -25,6 +28,11 @@ echo "Checking for updates on deploy branch..."
|
|
|
25
28
|
git fetch origin deploy --quiet
|
|
26
29
|
|
|
27
30
|
# --- Load instances ---
|
|
31
|
+
if [[ ! -f "$INSTANCES_CONF" ]]; then
|
|
32
|
+
echo "ERROR: instances.conf not found at $INSTANCES_CONF"
|
|
33
|
+
echo " Set HIVE_INSTANCES_CONF to a workspace-level conf outside .hive/."
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
28
36
|
declare -a INSTANCES=()
|
|
29
37
|
while IFS='|' read -r id config _agents _label logs_dir ports engine_tag; do
|
|
30
38
|
[[ "$id" =~ ^[[:space:]]*# ]] && continue
|
|
@@ -34,6 +42,12 @@ while IFS='|' read -r id config _agents _label logs_dir ports engine_tag; do
|
|
|
34
42
|
INSTANCES+=("$id|${engine_tag:-latest}")
|
|
35
43
|
done < "$INSTANCES_CONF"
|
|
36
44
|
|
|
45
|
+
if [[ ${#INSTANCES[@]} -eq 0 ]]; then
|
|
46
|
+
echo "No instances registered in $INSTANCES_CONF — nothing to check."
|
|
47
|
+
echo "(The shipped service/instances.conf is empty by design; multi-instance dev hosts must use HIVE_INSTANCES_CONF.)"
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
|
|
37
51
|
UPDATES_NEEDED=()
|
|
38
52
|
for inst in "${INSTANCES[@]}"; do
|
|
39
53
|
IFS='|' read -r id tag <<< "$inst"
|
package/service/deploy.sh
CHANGED
|
@@ -9,7 +9,16 @@ set -euo pipefail
|
|
|
9
9
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
10
10
|
BUILD_DIR="${BUILD_DIR:-$HOME/build/hive}"
|
|
11
11
|
DEPLOY_DIR="${DEPLOY_DIR:-$HOME/services/hive}"
|
|
12
|
-
INSTANCES_CONF="$SCRIPT_DIR/instances.conf"
|
|
12
|
+
INSTANCES_CONF="${HIVE_INSTANCES_CONF:-$SCRIPT_DIR/instances.conf}"
|
|
13
|
+
|
|
14
|
+
# Single-instance mode (KPR-70): when invoked by `hive update` for a customer
|
|
15
|
+
# install, the calling instance passes its own facts via env, and we skip the
|
|
16
|
+
# build-from-source phase + the shipped instances.conf entirely. The instance
|
|
17
|
+
# running the update is the only instance to update — no global registry read.
|
|
18
|
+
SINGLE_INSTANCE_MODE=false
|
|
19
|
+
if [[ "${HIVE_SINGLE_INSTANCE:-}" == "1" ]]; then
|
|
20
|
+
SINGLE_INSTANCE_MODE=true
|
|
21
|
+
fi
|
|
13
22
|
|
|
14
23
|
# --- Flags ---
|
|
15
24
|
DRY_RUN=false
|
|
@@ -30,30 +39,48 @@ for arg in "$@"; do
|
|
|
30
39
|
esac
|
|
31
40
|
done
|
|
32
41
|
|
|
33
|
-
# --- Notification config
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
# --- Notification config ---
|
|
43
|
+
# Source $DEPLOY_DIR/.env if present so SLACK_BOT_TOKEN / DEVOPS_CHANNEL_ID
|
|
44
|
+
# can populate from the dev convention. Customer installs have neither file
|
|
45
|
+
# nor tokens — that's fine; notify() degrades to a silent no-op below.
|
|
46
|
+
if [[ -f "$DEPLOY_DIR/.env" ]]; then
|
|
47
|
+
# shellcheck source=/dev/null
|
|
48
|
+
source "$DEPLOY_DIR/.env"
|
|
49
|
+
fi
|
|
38
50
|
|
|
39
51
|
# --- Load instances ---
|
|
40
52
|
declare -a INSTANCES=()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
if $SINGLE_INSTANCE_MODE; then
|
|
54
|
+
: "${HIVE_SINGLE_ID:?HIVE_SINGLE_ID required in single-instance mode}"
|
|
55
|
+
: "${HIVE_SINGLE_CONFIG:?HIVE_SINGLE_CONFIG required in single-instance mode}"
|
|
56
|
+
: "${HIVE_SINGLE_LOGS:?HIVE_SINGLE_LOGS required in single-instance mode}"
|
|
57
|
+
: "${HIVE_SINGLE_PORTS:?HIVE_SINGLE_PORTS required in single-instance mode}"
|
|
58
|
+
: "${HIVE_SINGLE_ROOT:?HIVE_SINGLE_ROOT required in single-instance mode}"
|
|
59
|
+
INSTANCES+=("$HIVE_SINGLE_ID|$HIVE_SINGLE_CONFIG|com.hive.${HIVE_SINGLE_ID}.agent|$HIVE_SINGLE_LOGS|$HIVE_SINGLE_PORTS|${HIVE_SINGLE_TAG:-}")
|
|
60
|
+
else
|
|
61
|
+
if [[ ! -f "$INSTANCES_CONF" ]]; then
|
|
62
|
+
echo "ERROR: instances.conf not found at $INSTANCES_CONF"
|
|
63
|
+
echo " For single-instance updates, set HIVE_SINGLE_INSTANCE=1 and the HIVE_SINGLE_* env vars."
|
|
64
|
+
echo " For multi-instance dev, point HIVE_INSTANCES_CONF at a workspace-level conf."
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
while IFS='|' read -r id config _agents_path label logs_dir ports engine_tag; do
|
|
68
|
+
[[ "$id" =~ ^[[:space:]]*# ]] && continue # skip comments
|
|
69
|
+
[[ -z "$id" ]] && continue # skip blank lines
|
|
70
|
+
# Trim whitespace
|
|
71
|
+
id=$(echo "$id" | xargs)
|
|
72
|
+
config=$(echo "$config" | xargs)
|
|
73
|
+
label=$(echo "$label" | xargs)
|
|
74
|
+
logs_dir=$(echo "$logs_dir" | xargs)
|
|
75
|
+
ports=$(echo "$ports" | xargs)
|
|
76
|
+
engine_tag=$(echo "${engine_tag:-}" | xargs)
|
|
77
|
+
INSTANCES+=("$id|$config|$label|$logs_dir|$ports|$engine_tag")
|
|
78
|
+
done < "$INSTANCES_CONF"
|
|
79
|
+
|
|
80
|
+
if [[ ${#INSTANCES[@]} -eq 0 ]]; then
|
|
81
|
+
echo "ERROR: No instances found in $INSTANCES_CONF"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
57
84
|
fi
|
|
58
85
|
|
|
59
86
|
echo "=== Hive Deploy (${#INSTANCES[@]} instances) ==="
|
|
@@ -76,6 +103,11 @@ notify() {
|
|
|
76
103
|
echo "[DRY RUN] notify: $message"
|
|
77
104
|
return
|
|
78
105
|
fi
|
|
106
|
+
# Slack notification is opt-in. Customer installs without devops Slack
|
|
107
|
+
# tokens silently skip — never fail-closed on a missing notification config.
|
|
108
|
+
if [[ -z "${SLACK_BOT_TOKEN:-}" || -z "${DEVOPS_CHANNEL_ID:-}" ]]; then
|
|
109
|
+
return
|
|
110
|
+
fi
|
|
79
111
|
local payload
|
|
80
112
|
payload=$(jq -n --arg channel "$DEVOPS_CHANNEL_ID" --arg text "$message" \
|
|
81
113
|
'{channel: $channel, text: $text}')
|
|
@@ -132,12 +164,17 @@ _normalize_tag() {
|
|
|
132
164
|
}
|
|
133
165
|
|
|
134
166
|
# _instance_root <id>
|
|
135
|
-
# Returns the instance root dir
|
|
136
|
-
#
|
|
137
|
-
#
|
|
138
|
-
#
|
|
167
|
+
# Returns the instance root dir. In single-instance mode (KPR-70) the caller
|
|
168
|
+
# tells us via HIVE_SINGLE_ROOT — we don't probe DEPLOY_DIR. Otherwise:
|
|
169
|
+
# $DEPLOY_DIR/<id> if that dir exists (post-Phase-5 per-instance layout), else
|
|
170
|
+
# $DEPLOY_DIR (today's primary-shared-dir layout). Lets deploy.sh be
|
|
171
|
+
# per-instance-dir aware now so Phase 5's migration is a no-op at the script level.
|
|
139
172
|
_instance_root() {
|
|
140
173
|
local id="$1"
|
|
174
|
+
if $SINGLE_INSTANCE_MODE; then
|
|
175
|
+
echo "$HIVE_SINGLE_ROOT"
|
|
176
|
+
return
|
|
177
|
+
fi
|
|
141
178
|
if [[ -d "$DEPLOY_DIR/$id" ]]; then
|
|
142
179
|
echo "$DEPLOY_DIR/$id"
|
|
143
180
|
else
|
|
@@ -330,62 +367,76 @@ fi
|
|
|
330
367
|
# oscillates between versions on every poll. Compares the configured pins
|
|
331
368
|
# (not the effective tag for this run) so even an explicit --tag override
|
|
332
369
|
# can't sneak past a misconfigured pinning state. Fail fast before any work.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
370
|
+
# Skipped in single-instance mode: one row can't conflict with itself.
|
|
371
|
+
if ! $SINGLE_INSTANCE_MODE; then
|
|
372
|
+
declare -a _seen_roots=()
|
|
373
|
+
declare -a _seen_pins=()
|
|
374
|
+
for inst in "${INSTANCES[@]}"; do
|
|
375
|
+
IFS='|' read -r _id _config _label _logs _ports _engine_tag <<< "$inst"
|
|
376
|
+
_root=$(_instance_root "$_id")
|
|
377
|
+
_pin="${_engine_tag:-latest}"
|
|
378
|
+
for i in "${!_seen_roots[@]}"; do
|
|
379
|
+
if [[ "${_seen_roots[$i]}" == "$_root" && "${_seen_pins[$i]}" != "$_pin" ]]; then
|
|
380
|
+
echo "ERROR: instances share root '$_root' but pin different ENGINE_TAGs ('${_seen_pins[$i]}' vs '$_pin')." >&2
|
|
381
|
+
echo " Set the same ENGINE_TAG for all instances under one root, or migrate them to per-instance dirs (Phase 5)." >&2
|
|
382
|
+
exit 2
|
|
383
|
+
fi
|
|
384
|
+
done
|
|
385
|
+
_seen_roots+=("$_root")
|
|
386
|
+
_seen_pins+=("$_pin")
|
|
345
387
|
done
|
|
346
|
-
_seen_roots
|
|
347
|
-
|
|
348
|
-
done
|
|
349
|
-
unset _seen_roots _seen_pins _id _config _label _logs _ports _engine_tag _root _pin i
|
|
388
|
+
unset _seen_roots _seen_pins _id _config _label _logs _ports _engine_tag _root _pin i
|
|
389
|
+
fi
|
|
350
390
|
|
|
351
391
|
# =============================================================================
|
|
352
392
|
# Phase 1: Build (once, in $BUILD_DIR)
|
|
353
393
|
# =============================================================================
|
|
394
|
+
# Skipped in single-instance mode (KPR-70): customer installs consume the
|
|
395
|
+
# published @keepur/hive npm tarball via fetch_engine in Phase 2 — there is no
|
|
396
|
+
# $BUILD_DIR, no `deploy` branch, nothing to rebuild from source.
|
|
354
397
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
398
|
+
DEPLOY_SHA=""
|
|
399
|
+
DEPLOY_MSG=""
|
|
400
|
+
|
|
401
|
+
if $SINGLE_INSTANCE_MODE; then
|
|
402
|
+
echo ""
|
|
403
|
+
echo "--- Phase 1: Build (skipped in single-instance mode) ---"
|
|
404
|
+
else
|
|
405
|
+
echo ""
|
|
406
|
+
echo "--- Phase 1: Build ---"
|
|
407
|
+
# Per-instance current versions are reported in Phase 2 after each health check.
|
|
358
408
|
|
|
359
|
-
echo "Pulling latest in build dir..."
|
|
360
|
-
cd "$BUILD_DIR"
|
|
361
|
-
[[ "$(git branch --show-current)" == "deploy" ]] || { echo "ERROR: Build dir not on deploy branch"; exit 1; }
|
|
362
|
-
run_cmd git pull --ff-only
|
|
409
|
+
echo "Pulling latest in build dir..."
|
|
410
|
+
cd "$BUILD_DIR"
|
|
411
|
+
[[ "$(git branch --show-current)" == "deploy" ]] || { echo "ERROR: Build dir not on deploy branch"; exit 1; }
|
|
412
|
+
run_cmd git pull --ff-only
|
|
363
413
|
|
|
364
|
-
DEPLOY_SHA=$(git rev-parse --short HEAD)
|
|
365
|
-
DEPLOY_MSG=$(git log -1 --pretty=%s)
|
|
414
|
+
DEPLOY_SHA=$(git rev-parse --short HEAD)
|
|
415
|
+
DEPLOY_MSG=$(git log -1 --pretty=%s)
|
|
366
416
|
|
|
367
|
-
echo "Installing dependencies..."
|
|
368
|
-
if ! run_cmd npm install; then
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
fi
|
|
417
|
+
echo "Installing dependencies..."
|
|
418
|
+
if ! run_cmd npm install; then
|
|
419
|
+
notify "Deploy aborted. \`npm install\` failed. Commit: \`$DEPLOY_SHA\`."
|
|
420
|
+
exit 1
|
|
421
|
+
fi
|
|
372
422
|
|
|
373
|
-
echo "Running checks..."
|
|
374
|
-
if ! run_cmd npm run check; then
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
fi
|
|
423
|
+
echo "Running checks..."
|
|
424
|
+
if ! run_cmd npm run check; then
|
|
425
|
+
notify "Deploy aborted. \`npm run check\` failed. Commit: \`$DEPLOY_SHA\`."
|
|
426
|
+
exit 1
|
|
427
|
+
fi
|
|
378
428
|
|
|
379
|
-
echo "Building..."
|
|
380
|
-
if ! run_cmd npm run build; then
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
fi
|
|
429
|
+
echo "Building..."
|
|
430
|
+
if ! run_cmd npm run build; then
|
|
431
|
+
notify "Deploy aborted. Build failed. Commit: \`$DEPLOY_SHA\`."
|
|
432
|
+
exit 1
|
|
433
|
+
fi
|
|
384
434
|
|
|
385
|
-
echo "Bundling..."
|
|
386
|
-
if ! run_cmd npm run bundle; then
|
|
387
|
-
|
|
388
|
-
|
|
435
|
+
echo "Bundling..."
|
|
436
|
+
if ! run_cmd npm run bundle; then
|
|
437
|
+
notify "Deploy aborted. Bundle failed. Commit: \`$DEPLOY_SHA\`."
|
|
438
|
+
exit 1
|
|
439
|
+
fi
|
|
389
440
|
fi
|
|
390
441
|
|
|
391
442
|
# =============================================================================
|
|
@@ -467,16 +518,22 @@ done
|
|
|
467
518
|
echo ""
|
|
468
519
|
echo "--- Phase 3: Report ---"
|
|
469
520
|
|
|
521
|
+
# Build-commit clause appears only in multi-instance mode (Phase 1 ran).
|
|
522
|
+
build_clause=""
|
|
523
|
+
if [[ -n "$DEPLOY_SHA" ]]; then
|
|
524
|
+
build_clause=" Build commit \`$DEPLOY_SHA\`: $DEPLOY_MSG."
|
|
525
|
+
fi
|
|
526
|
+
|
|
470
527
|
if [[ ${#FAILED_INSTANCES[@]} -gt 0 ]]; then
|
|
471
528
|
failed_list=$(printf ", %s" "${FAILED_INSTANCES[@]}")
|
|
472
529
|
failed_list=${failed_list:2}
|
|
473
|
-
notify "Deploy partial
|
|
530
|
+
notify "Deploy partial.${build_clause} Failed instances: $failed_list."
|
|
474
531
|
echo "Deploy completed with failures: $failed_list"
|
|
475
532
|
exit 1
|
|
476
533
|
else
|
|
477
534
|
# Count actual deploy targets (respecting --instance filter)
|
|
478
535
|
deployed=${#INSTANCES[@]}
|
|
479
536
|
[[ -n "$FILTER_INSTANCE" ]] && deployed=1
|
|
480
|
-
notify "Deploy succeeded ($deployed instance(s))
|
|
537
|
+
notify "Deploy succeeded ($deployed instance(s)).${build_clause}"
|
|
481
538
|
echo "Deploy complete. $deployed instance(s) running."
|
|
482
539
|
fi
|
package/service/instances.conf
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
# Hive instance definitions —
|
|
1
|
+
# Hive instance definitions — multi-instance dev deploy registry
|
|
2
|
+
#
|
|
3
|
+
# THIS FILE SHIPS EMPTY in the @keepur/hive npm bundle.
|
|
4
|
+
#
|
|
5
|
+
# Customer installs do NOT use this file: `hive update` uses the
|
|
6
|
+
# single-instance code path (HIVE_SINGLE_INSTANCE=1) and discovers the calling
|
|
7
|
+
# instance from cwd / hive.yaml / HIVE_HOME — no registry read.
|
|
8
|
+
#
|
|
9
|
+
# Multi-instance dev hosts (one machine running several Hive instances) point
|
|
10
|
+
# the cron-driven deploy-check.sh at a workspace-level conf instead, via:
|
|
11
|
+
#
|
|
12
|
+
# HIVE_INSTANCES_CONF=/path/to/instances.conf
|
|
13
|
+
#
|
|
14
|
+
# That conf lives outside .hive/ so engine swaps don't wipe it.
|
|
15
|
+
#
|
|
16
|
+
# --- Format (when this file IS used) ---
|
|
2
17
|
# Fields: INSTANCE_ID | HIVE_CONFIG | (unused) | (unused label — advisory) | LOGS_DIR | PORTS (space-separated) | ENGINE_TAG
|
|
3
18
|
#
|
|
4
19
|
# HIVE_CONFIG is relative to DEPLOY_DIR
|
|
@@ -10,6 +25,6 @@
|
|
|
10
25
|
# The fourth column was historically the LaunchAgent label but is now ignored by
|
|
11
26
|
# deploy.sh — the label is always derived as com.hive.<INSTANCE_ID>.agent to match
|
|
12
27
|
# what service/install.sh produces. The column is retained for format stability.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
28
|
+
#
|
|
29
|
+
# Example row (commented — do not enable in the shipped bundle):
|
|
30
|
+
# example|hive.yaml|-|com.hive.example.agent|logs|3100 3200|latest
|