first commit

This commit is contained in:
Sergey Antropoff
2026-10-09 07:08:09 +03:00
commit 4381350286
7 changed files with 973 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
#!/bin/sh
# Регистрация NebulaGraph и проверка полнотекстового индекса.
# Запускается внутри контейнера ops, поэтому одинаково работает на macOS, Linux и Windows.
set -eu
: "${ELASTIC_PASSWORD:?ELASTIC_PASSWORD is required}"
: "${STORAGED0_IP:?}"
: "${STORAGED1_IP:?}"
: "${STORAGED2_IP:?}"
: "${ES01_IP:?}"
: "${ES02_IP:?}"
: "${ES03_IP:?}"
: "${LISTENER_IP:?}"
if ! command -v nebula-console >/dev/null 2>&1; then
if [ -x /usr/local/bin/nebula-console ]; then
PATH="/usr/local/bin:${PATH}"
else
found=$(find / -name nebula-console -type f 2>/dev/null | head -n 1 || true)
if [ -z "$found" ]; then
echo "nebula-console binary not found"
exit 1
fi
PATH="$(dirname "$found"):${PATH}"
fi
fi
NGQL_OUT=
run_ngql() {
echo ""
echo "+ $1"
set +e
NGQL_OUT=$(nebula-console -addr graphd -port 9669 -u root -p nebula -e "$1" 2>&1)
NGQL_RC=$?
set -e
printf '%s\n' "$NGQL_OUT"
if [ "$NGQL_RC" -eq 0 ] && ! printf '%s\n' "$NGQL_OUT" | grep -q '\[ERROR'; then
return 0
fi
return 1
}
already_exists() {
printf '%s\n' "$NGQL_OUT" | grep -Eqi 'exist'
}
wait_until() {
attempts=$1
shift
n=0
while [ "$n" -lt "$attempts" ]; do
n=$((n + 1))
if "$@"; then
return 0
fi
echo "retry ${n}/${attempts}"
sleep 5
done
return 1
}
console_up() {
run_ngql "SHOW HOSTS;"
}
hosts_online() {
run_ngql "SHOW HOSTS;" || return 1
on=$(printf '%s\n' "$NGQL_OUT" | grep -c ONLINE || true)
off=$(printf '%s\n' "$NGQL_OUT" | grep -c OFFLINE || true)
[ "$on" -ge 3 ] && [ "$off" -eq 0 ]
}
listener_online() {
run_ngql "USE demo; SHOW LISTENER;" || return 1
on=$(printf '%s\n' "$NGQL_OUT" | grep -c ONLINE || true)
off=$(printf '%s\n' "$NGQL_OUT" | grep -c OFFLINE || true)
[ "$on" -ge 12 ] && [ "$off" -eq 0 ]
}
add_hosts() {
stmt="ADD HOSTS \"${STORAGED0_IP}\":9779, \"${STORAGED1_IP}\":9779, \"${STORAGED2_IP}\":9779;"
if run_ngql "$stmt"; then
return 0
fi
already_exists
}
sign_in() {
stmt="SIGN IN TEXT SERVICE (${ES01_IP}:9200, HTTP, \"elastic\", \"${ELASTIC_PASSWORD}\"), (${ES02_IP}:9200, HTTP, \"elastic\", \"${ELASTIC_PASSWORD}\"), (${ES03_IP}:9200, HTTP, \"elastic\", \"${ELASTIC_PASSWORD}\");"
if run_ngql "$stmt"; then
return 0
fi
if already_exists; then
return 0
fi
run_ngql "SHOW TEXT SEARCH CLIENTS;" || return 1
clients=$(printf '%s\n' "$NGQL_OUT" | grep -c ELASTICSEARCH || true)
[ "$clients" -ge 3 ]
}
do_init() {
echo "=== wait for graphd ==="
wait_until 40 console_up
echo "=== ADD HOSTS ==="
wait_until 12 add_hosts
echo "=== wait until storage is ONLINE ==="
wait_until 36 hosts_online
echo "=== SIGN IN TEXT SERVICE ==="
wait_until 24 sign_in
run_ngql "SHOW TEXT SEARCH CLIENTS;"
}
create_space() {
run_ngql "CREATE SPACE IF NOT EXISTS demo (partition_num = 12, replica_factor = 3, vid_type = FIXED_STRING(64));"
}
create_tag() {
run_ngql "USE demo; CREATE TAG IF NOT EXISTS document (title STRING, content STRING);"
}
add_listener() {
if run_ngql "USE demo; ADD LISTENER ELASTICSEARCH \"${LISTENER_IP}\":9789;"; then
return 0
fi
already_exists
}
create_index() {
if run_ngql "USE demo; CREATE FULLTEXT TAG INDEX document_search ON document(title, content) ANALYZER = \"standard\";"; then
return 0
fi
if printf '%s\n' "$NGQL_OUT" | grep -q 'SyntaxError'; then
echo "fatal nGQL syntax error"
exit 1
fi
already_exists
}
insert_docs() {
if run_ngql "USE demo; INSERT VERTEX document(title, content) VALUES \"doc-001\":(\"Kubernetes\", \"Container orchestration platform\"), \"doc-002\":(\"NebulaGraph\", \"Distributed graph database\");"; then
return 0
fi
already_exists
}
lookup_doc() {
run_ngql "USE demo; LOOKUP ON document WHERE ES_QUERY(document_search, \"Kubernetes\") YIELD id(vertex);" || return 1
printf '%s\n' "$NGQL_OUT" | grep -q 'doc-001'
}
es_has_kubernetes() {
if ! command -v bash >/dev/null 2>&1 || ! command -v base64 >/dev/null 2>&1; then
echo "bash/base64 are not in the console image; LOOKUP already queried Elasticsearch"
return 0
fi
ES01_IP="$ES01_IP" ELASTIC_PASSWORD="$ELASTIC_PASSWORD" bash -c '
auth=$(printf "%s" "elastic:${ELASTIC_PASSWORD}" | base64 | tr -d "\n\r")
exec 3<>"/dev/tcp/${ES01_IP}/9200"
printf "GET /_search?q=Kubernetes HTTP/1.0\r\nHost: elasticsearch\r\nAuthorization: Basic %s\r\nConnection: close\r\n\r\n" "$auth" >&3
resp=$(cat <&3 || true)
printf "%s\n" "$resp"
printf "%s\n" "$resp" | grep -q Kubernetes
'
}
do_verify() {
echo "=== CREATE SPACE demo ==="
wait_until 24 create_space
echo "=== CREATE TAG document ==="
wait_until 24 create_tag
echo "=== ADD LISTENER ELASTICSEARCH ==="
wait_until 12 add_listener
echo "=== wait until listener is ONLINE ==="
wait_until 36 listener_online
echo "=== CREATE FULLTEXT TAG INDEX ==="
wait_until 24 create_index
run_ngql "USE demo; SHOW FULLTEXT INDEXES;"
echo "=== INSERT VERTEX ==="
wait_until 12 insert_docs
run_ngql "USE demo; REBUILD FULLTEXT INDEX;" || true
echo "=== LOOKUP via Elasticsearch ==="
wait_until 24 lookup_doc
echo "=== direct Elasticsearch search ==="
wait_until 12 es_has_kubernetes
echo ""
echo "VERIFY OK"
}
mode="${1:-verify}"
case "$mode" in
init)
do_init
;;
verify)
do_init
do_verify
;;
*)
echo "usage: sh cluster.sh init|verify"
exit 2
;;
esac