first commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
|||||||
|
# Скопируйте в .env: cp .env.example .env
|
||||||
|
# Либо запустите make up — цель создаст .env сама.
|
||||||
|
|
||||||
|
NEBULA_VERSION=v3.8.0
|
||||||
|
# Studio 3.10 — выпуск, который документация NebulaGraph 3.8 ставит рядом с графом 3.8.
|
||||||
|
STUDIO_VERSION=v3.10.0
|
||||||
|
ES_VERSION=7.17.29
|
||||||
|
|
||||||
|
# Пароль встроенного пользователя elastic. Только буквы и цифры:
|
||||||
|
# он подставляется в nGQL SIGN IN TEXT SERVICE.
|
||||||
|
ELASTIC_PASSWORD=NebulaEsLab2026
|
||||||
|
|
||||||
|
# Пароль контейнера PKCS#12 для транспортного TLS Elasticsearch.
|
||||||
|
ES_CERT_PASSWORD=NebulaCertLab2026
|
||||||
|
|
||||||
|
# 512m на узел — запас для Docker Desktop. На сервере можно -Xms1g -Xmx1g.
|
||||||
|
ES_JAVA_OPTS=-Xms512m -Xmx512m
|
||||||
|
|
||||||
|
# true имеет смысл на Linux, где memlock разрешён. На Docker Desktop чаще false.
|
||||||
|
ES_MEMORY_LOCK=false
|
||||||
|
|
||||||
|
# false не даёт Elasticsearch остановить запись, если диск хоста почти полон.
|
||||||
|
# На сервере со свободным местом поставьте true.
|
||||||
|
ES_DISK_THRESHOLD=false
|
||||||
|
|
||||||
|
# Подсеть моста Docker. Если адрес занят, смените подсеть и все IP ниже.
|
||||||
|
DOCKER_SUBNET=172.30.80.0/24
|
||||||
|
METAD0_IP=172.30.80.11
|
||||||
|
METAD1_IP=172.30.80.12
|
||||||
|
METAD2_IP=172.30.80.13
|
||||||
|
STORAGED0_IP=172.30.80.21
|
||||||
|
STORAGED1_IP=172.30.80.22
|
||||||
|
STORAGED2_IP=172.30.80.23
|
||||||
|
GRAPHD_IP=172.30.80.31
|
||||||
|
LISTENER_IP=172.30.80.41
|
||||||
|
ES01_IP=172.30.80.51
|
||||||
|
ES02_IP=172.30.80.52
|
||||||
|
ES03_IP=172.30.80.53
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.env
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# NebulaGraph 3.8 + Elasticsearch 7 + Nebula Studio
|
||||||
|
# Рецепты — однострочные команды docker compose.
|
||||||
|
# На Windows запускайте из WSL или Git Bash. Те же команды есть в README.
|
||||||
|
|
||||||
|
COMPOSE = docker compose
|
||||||
|
|
||||||
|
.PHONY: help env up init verify console ps logs es-health check config down clean
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "make up поднять NebulaGraph, Elasticsearch и Studio"
|
||||||
|
@echo "make init ADD HOSTS и SIGN IN TEXT SERVICE"
|
||||||
|
@echo "make verify init, listener, полнотекстовый индекс и поиск"
|
||||||
|
@echo "make console интерактивная консоль nGQL"
|
||||||
|
@echo "make ps статус контейнеров"
|
||||||
|
@echo "make logs последние логи"
|
||||||
|
@echo "make es-health состояние кластера Elasticsearch"
|
||||||
|
@echo "make check vm.max_map_count внутри Docker"
|
||||||
|
@echo "make down остановить, тома сохранить"
|
||||||
|
@echo "make clean остановить и удалить тома"
|
||||||
|
|
||||||
|
.env:
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
env: .env
|
||||||
|
|
||||||
|
up: .env
|
||||||
|
$(COMPOSE) up -d
|
||||||
|
|
||||||
|
init: up
|
||||||
|
$(COMPOSE) --profile ops run --rm --no-deps -e OPS_COMMAND=init ops
|
||||||
|
|
||||||
|
verify: up
|
||||||
|
$(COMPOSE) --profile ops run --rm --no-deps -e OPS_COMMAND=verify ops
|
||||||
|
|
||||||
|
console: .env
|
||||||
|
$(COMPOSE) --profile ops run --rm --no-deps console
|
||||||
|
|
||||||
|
ps:
|
||||||
|
$(COMPOSE) ps -a
|
||||||
|
|
||||||
|
logs:
|
||||||
|
$(COMPOSE) logs --tail=80
|
||||||
|
|
||||||
|
es-health: .env
|
||||||
|
$(COMPOSE) exec -T es01 sh -c 'curl -fsS -u "elastic:$$ELASTIC_PASSWORD" http://127.0.0.1:9200/_cluster/health?pretty'
|
||||||
|
|
||||||
|
check:
|
||||||
|
docker run --rm alpine sysctl vm.max_map_count
|
||||||
|
|
||||||
|
config: .env
|
||||||
|
$(COMPOSE) config --quiet && echo "compose config ok"
|
||||||
|
|
||||||
|
down:
|
||||||
|
$(COMPOSE) --profile ops down
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(COMPOSE) --profile ops down -v
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
# NebulaGraph 3.8 + Elasticsearch 7 + Studio
|
||||||
|
|
||||||
|
## Быстрый запуск
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make verify
|
||||||
|
make es-health
|
||||||
|
make ps
|
||||||
|
```
|
||||||
|
|
||||||
|
Первый `make verify` сам создаёт `.env` из `.env.example`, поднимает контейнеры и проводит проверку.
|
||||||
|
|
||||||
|
| Команда | Что делает |
|
||||||
|
| --- | --- |
|
||||||
|
| `make verify` | Поднимает стек и проверяет регистрацию storage, вход в Elasticsearch, listener, полнотекстовый индекс и поиск `doc-001`. |
|
||||||
|
| `make es-health` | Показывает состояние кластера Elasticsearch. Ожидается `green` и три узла. |
|
||||||
|
| `make ps` | Печатает статус контейнеров. `es-certs` в `Exited (0)` значит, что сертификат уже создан. |
|
||||||
|
|
||||||
|
Локальный кластер:
|
||||||
|
|
||||||
|
| Сервис | Число | Адрес в сети Docker | Порт |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| metad | 3 | `172.30.80.11`–`.13` | 9559 |
|
||||||
|
| storaged | 3 | `172.30.80.21`–`.23` | 9779 |
|
||||||
|
| graphd | 1 | `172.30.80.31` | 9669 |
|
||||||
|
| storaged-listener | 1 | `172.30.80.41` | 9789 |
|
||||||
|
| Elasticsearch 7.17 | 3 | `172.30.80.51`–`.53` | 9200 |
|
||||||
|
| Nebula Studio 3.10 | 1 | имя `studio` | 7001 |
|
||||||
|
|
||||||
|
С хоста опубликованы только `127.0.0.1:9669` (graphd), `127.0.0.1:9200` (Elasticsearch) и `127.0.0.1:7001` (Studio).
|
||||||
|
|
||||||
|
Адреса заданы в `.env` и совпадают на macOS, Linux и Windows: контейнеры видят одну сеть `nebula-stack-net`, а не localhost хоста.
|
||||||
|
|
||||||
|
## Что нужно
|
||||||
|
|
||||||
|
- Docker Engine или Docker Desktop и Docker Compose v2 (`docker compose`).
|
||||||
|
- Для `make`: macOS, Linux, либо Windows через WSL или Git Bash.
|
||||||
|
- Память Docker: комфортно от 8 ГБ. В `.env` у каждого узла Elasticsearch куча 512 МБ.
|
||||||
|
- Место на диске под образы (около 3–4 ГБ).
|
||||||
|
|
||||||
|
На Linux перед первым запуском ядро должно разрешать Elasticsearch много memory map:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo sysctl -w vm.max_map_count=262144
|
||||||
|
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-elasticsearch.conf
|
||||||
|
sudo sysctl --system
|
||||||
|
```
|
||||||
|
|
||||||
|
На macOS и Windows это настройка виртуальной машины Docker Desktop, обычно уже `262144`. Проверка из любого хоста:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make check
|
||||||
|
```
|
||||||
|
|
||||||
|
Число в ответе должно быть не меньше `262144`.
|
||||||
|
|
||||||
|
## Запуск
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env # make up сделает это сам
|
||||||
|
make up
|
||||||
|
make init # ADD HOSTS и SIGN IN TEXT SERVICE
|
||||||
|
make verify # listener, индекс и поиск по тестовым вершинам
|
||||||
|
```
|
||||||
|
|
||||||
|
`make verify` включает `make init`. Контейнер `es-certs` после успеха в `make ps` будет `Exited (0)`: сертификат транспортного TLS уже записан в том.
|
||||||
|
|
||||||
|
Studio: <http://127.0.0.1:7001>
|
||||||
|
|
||||||
|
| Поле | Значение |
|
||||||
|
| --- | --- |
|
||||||
|
| Graphd IP | `172.30.80.31` |
|
||||||
|
| Port | `9669` |
|
||||||
|
| Username | `root` |
|
||||||
|
| Password | `nebula` |
|
||||||
|
|
||||||
|
Адрес `127.0.0.1` в Studio не подходит: запрос к graphd уходит из контейнера Studio. `172.30.80.31` — адрес graphd в сети Docker. Авторизация NebulaGraph в этом стенде выключена, пароль `nebula` принимает консоль и Studio.
|
||||||
|
|
||||||
|
Интерактивная консоль:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make console
|
||||||
|
```
|
||||||
|
|
||||||
|
Остановить, не удаляя данные: `make down`. Удалить тома: `make clean`.
|
||||||
|
|
||||||
|
### Windows без make
|
||||||
|
|
||||||
|
В PowerShell из каталога проекта:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Copy-Item .env.example .env
|
||||||
|
docker compose up -d
|
||||||
|
docker compose --profile ops run --rm --no-deps -e OPS_COMMAND=init ops
|
||||||
|
docker compose --profile ops run --rm --no-deps -e OPS_COMMAND=verify ops
|
||||||
|
docker compose --profile ops run --rm --no-deps console
|
||||||
|
```
|
||||||
|
|
||||||
|
### Полезные команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make ps
|
||||||
|
make logs
|
||||||
|
make es-health
|
||||||
|
docker compose logs -f storaged-listener
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка Elasticsearch с хоста (пароль из `.env`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -u "elastic:NebulaEsLab2026" "http://127.0.0.1:9200/_cluster/health?pretty"
|
||||||
|
curl -u "elastic:NebulaEsLab2026" "http://127.0.0.1:9200/_cat/indices?v"
|
||||||
|
```
|
||||||
|
|
||||||
|
Если меняли `ELASTIC_PASSWORD` в `.env`, подставьте его.
|
||||||
|
|
||||||
|
## Как подключён listener
|
||||||
|
|
||||||
|
Полнотекстовый индекс NebulaGraph пишет в Elasticsearch не сам storaged, а отдельный процесс Raft Listener. Это тот же бинарник `nebula-storaged`, но со своим портом и каталогом WAL. В compose у `storaged-listener` свой entrypoint: флаги listener не смешиваются с обычным `nebula-storaged.conf`.
|
||||||
|
|
||||||
|
Слушает он `172.30.80.41:9789` (`LISTENER_IP` в `.env`). В кластер хранения через `ADD HOSTS` его не добавляют. Для каждого графового пространства listener регистрируется один раз, все адреса — одним оператором `ADD LISTENER`. Пока `SHOW LISTENER` не покажет `ONLINE` по всем партициям, полнотекстовый индекс не создают.
|
||||||
|
|
||||||
|
Учётные данные Elasticsearch глобальные для кластера, не для пространства: один `SIGN IN TEXT SERVICE` на все space. Повторный вход делается после `SIGN OUT TEXT SERVICE`.
|
||||||
|
|
||||||
|
`make init` и `make verify` выполняют команды ниже сами и повторяют попытку, пока метаданные и listener не станут готовы. Вручную между `CREATE SPACE`, `CREATE TAG` и индексом нужно подождать одно-два сердцебиения meta (около 20 секунд): иначе пространство или тег ещё не видны.
|
||||||
|
|
||||||
|
Пароль в примерах — значение `ELASTIC_PASSWORD` из `.env`. Адреса — значения по умолчанию из `.env.example`.
|
||||||
|
|
||||||
|
### 1. Узлы хранения
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
ADD HOSTS
|
||||||
|
"172.30.80.21":9779,
|
||||||
|
"172.30.80.22":9779,
|
||||||
|
"172.30.80.23":9779;
|
||||||
|
SHOW HOSTS;
|
||||||
|
```
|
||||||
|
|
||||||
|
В `SHOW HOSTS` три строки `ONLINE`. До этой команды контейнеры storaged уже запущены, но метаданные ещё не отдают им партиции. `make ps` может показывать их unhealthy, пока `ADD HOSTS` не пройдёт.
|
||||||
|
|
||||||
|
### 2. Elasticsearch
|
||||||
|
|
||||||
|
Транспорт между `es01`–`es03` зашифрован общим сертификатом, HTTP оставлен без TLS и закрыт basic-авторизацией. NebulaGraph ходит по HTTP, поэтому в `SIGN IN` схема `HTTP`, пользователь `elastic` и пароль из `.env`.
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
SIGN IN TEXT SERVICE
|
||||||
|
(172.30.80.51:9200, HTTP, "elastic", "NebulaEsLab2026"),
|
||||||
|
(172.30.80.52:9200, HTTP, "elastic", "NebulaEsLab2026"),
|
||||||
|
(172.30.80.53:9200, HTTP, "elastic", "NebulaEsLab2026");
|
||||||
|
SHOW TEXT SEARCH CLIENTS;
|
||||||
|
```
|
||||||
|
|
||||||
|
Ожидаются три строки `ELASTICSEARCH`. Клиент один на весь кластер. Сброс: `SIGN OUT TEXT SERVICE;`.
|
||||||
|
|
||||||
|
### 3. Пространство и listener
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
CREATE SPACE IF NOT EXISTS demo (
|
||||||
|
partition_num = 12,
|
||||||
|
replica_factor = 3,
|
||||||
|
vid_type = FIXED_STRING(64)
|
||||||
|
);
|
||||||
|
|
||||||
|
USE demo;
|
||||||
|
ADD LISTENER ELASTICSEARCH "172.30.80.41":9789;
|
||||||
|
SHOW LISTENER;
|
||||||
|
```
|
||||||
|
|
||||||
|
`USE` и `ADD LISTENER` должны быть в одной сессии консоли. `SHOW LISTENER` — тоже после `USE demo`. Для 12 партиций будет 12 строк. Ждите `ONLINE` в каждой. Снять listener с пространства: `REMOVE LISTENER ELASTICSEARCH;`.
|
||||||
|
|
||||||
|
### 4. Схема, индекс и данные
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
USE demo;
|
||||||
|
CREATE TAG IF NOT EXISTS document (
|
||||||
|
title STRING,
|
||||||
|
content STRING
|
||||||
|
);
|
||||||
|
CREATE FULLTEXT TAG INDEX document_search
|
||||||
|
ON document(title, content)
|
||||||
|
ANALYZER = "standard";
|
||||||
|
SHOW FULLTEXT INDEXES;
|
||||||
|
```
|
||||||
|
|
||||||
|
В NebulaGraph 3.8 у `CREATE FULLTEXT TAG INDEX` нет `IF NOT EXISTS`. Повторный запуск отвечает `Existed!`, `make verify` это учитывает.
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
INSERT VERTEX document(title, content) VALUES
|
||||||
|
"doc-001":("Kubernetes", "Container orchestration platform"),
|
||||||
|
"doc-002":("NebulaGraph", "Distributed graph database");
|
||||||
|
```
|
||||||
|
|
||||||
|
Индексация идёт асинхронно через listener. Для уже лежащих в пространстве данных:
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
USE demo;
|
||||||
|
REBUILD FULLTEXT INDEX;
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка со стороны NebulaGraph — запрос в Elasticsearch через индекс:
|
||||||
|
|
||||||
|
```ngql
|
||||||
|
USE demo;
|
||||||
|
LOOKUP ON document
|
||||||
|
WHERE ES_QUERY(document_search, "Kubernetes")
|
||||||
|
YIELD id(vertex);
|
||||||
|
```
|
||||||
|
|
||||||
|
В ответе должен быть `doc-001`. Анализатор `standard` приводит слово к нижнему регистру, поэтому в Elasticsearch документ ищется и по `Kubernetes`.
|
||||||
|
|
||||||
|
Появление индекса снаружи:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -u "elastic:NebulaEsLab2026" "http://127.0.0.1:9200/_cat/indices?v"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Если адреса другие
|
||||||
|
|
||||||
|
Поменяйте подсеть и IP в `.env`, затем `make clean && make up && make verify`. Команды nGQL и поле Graphd IP в Studio берите уже из своего `.env`: listener и `ADD HOSTS` должны указывать те же адреса, что `--local_ip` у контейнеров.
|
||||||
|
|
||||||
|
На сервере со свободным диском в `.env` поставьте `ES_DISK_THRESHOLD=true`. Кучу Elasticsearch увеличивают через `ES_JAVA_OPTS`. `ES_MEMORY_LOCK=true` включайте на Linux, где для контейнера разрешён memlock.
|
||||||
@@ -0,0 +1,442 @@
|
|||||||
|
name: nebula-stack
|
||||||
|
|
||||||
|
x-logging: &logging
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
x-nebula: &nebula
|
||||||
|
restart: unless-stopped
|
||||||
|
cap_add:
|
||||||
|
- SYS_PTRACE
|
||||||
|
logging: *logging
|
||||||
|
|
||||||
|
x-es-env: &es-env
|
||||||
|
cluster.name: nebula-elasticsearch
|
||||||
|
discovery.seed_hosts: ${ES01_IP}:9300,${ES02_IP}:9300,${ES03_IP}:9300
|
||||||
|
cluster.initial_master_nodes: es01,es02,es03
|
||||||
|
bootstrap.memory_lock: "${ES_MEMORY_LOCK}"
|
||||||
|
network.host: "0.0.0.0"
|
||||||
|
xpack.security.enabled: "true"
|
||||||
|
xpack.security.http.ssl.enabled: "false"
|
||||||
|
xpack.security.transport.ssl.enabled: "true"
|
||||||
|
xpack.security.transport.ssl.verification_mode: certificate
|
||||||
|
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
|
||||||
|
xpack.security.transport.ssl.truststore.path: certs/elastic-stack-ca.p12
|
||||||
|
xpack.security.transport.ssl.keystore.password: ${ES_CERT_PASSWORD}
|
||||||
|
xpack.security.transport.ssl.truststore.password: ${ES_CERT_PASSWORD}
|
||||||
|
ELASTIC_PASSWORD: ${ELASTIC_PASSWORD}
|
||||||
|
ES_JAVA_OPTS: ${ES_JAVA_OPTS}
|
||||||
|
TAKE_FILE_OWNERSHIP: "true"
|
||||||
|
cluster.routing.allocation.disk.threshold_enabled: "${ES_DISK_THRESHOLD}"
|
||||||
|
ingest.geoip.downloader.enabled: "false"
|
||||||
|
|
||||||
|
x-es-node: &es-node
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION}
|
||||||
|
user: "0:0"
|
||||||
|
restart: unless-stopped
|
||||||
|
logging: *logging
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
nofile:
|
||||||
|
soft: 65536
|
||||||
|
hard: 65536
|
||||||
|
depends_on:
|
||||||
|
es-certs:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- 'curl -fsS -u "elastic:$$ELASTIC_PASSWORD" http://127.0.0.1:9200/_cluster/health >/dev/null'
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
||||||
|
start_period: 90s
|
||||||
|
|
||||||
|
services:
|
||||||
|
es-certs:
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch:${ES_VERSION}
|
||||||
|
user: "0:0"
|
||||||
|
restart: "no"
|
||||||
|
logging: *logging
|
||||||
|
environment:
|
||||||
|
ES_CERT_PASSWORD: ${ES_CERT_PASSWORD}
|
||||||
|
ES01_IP: ${ES01_IP}
|
||||||
|
ES02_IP: ${ES02_IP}
|
||||||
|
ES03_IP: ${ES03_IP}
|
||||||
|
entrypoint: ["bash", "-ec"]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
if [ -s /certs/elastic-certificates.p12 ] && [ -s /certs/elastic-stack-ca.p12 ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
rm -f /certs/elastic-certificates.p12 /certs/elastic-stack-ca.p12
|
||||||
|
bin/elasticsearch-certutil ca \
|
||||||
|
--silent \
|
||||||
|
--out /certs/elastic-stack-ca.p12 \
|
||||||
|
--pass "$$ES_CERT_PASSWORD"
|
||||||
|
bin/elasticsearch-certutil cert \
|
||||||
|
--silent \
|
||||||
|
--ca /certs/elastic-stack-ca.p12 \
|
||||||
|
--ca-pass "$$ES_CERT_PASSWORD" \
|
||||||
|
--pass "$$ES_CERT_PASSWORD" \
|
||||||
|
--name nebula-es \
|
||||||
|
--dns es01,es02,es03 \
|
||||||
|
--ip "$$ES01_IP,$$ES02_IP,$$ES03_IP,127.0.0.1" \
|
||||||
|
--out /certs/elastic-certificates.p12
|
||||||
|
chown 1000:0 /certs/elastic-certificates.p12 /certs/elastic-stack-ca.p12
|
||||||
|
chmod 600 /certs/elastic-certificates.p12 /certs/elastic-stack-ca.p12
|
||||||
|
volumes:
|
||||||
|
- es_certs:/certs
|
||||||
|
networks:
|
||||||
|
- backend
|
||||||
|
|
||||||
|
es01:
|
||||||
|
<<: *es-node
|
||||||
|
hostname: es01
|
||||||
|
environment:
|
||||||
|
<<: *es-env
|
||||||
|
node.name: es01
|
||||||
|
network.publish_host: ${ES01_IP}
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:9200:9200"
|
||||||
|
volumes: &es-volumes
|
||||||
|
- esdata01:/usr/share/elasticsearch/data
|
||||||
|
- es_certs:/usr/share/elasticsearch/config/certs:ro
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${ES01_IP}
|
||||||
|
|
||||||
|
es02:
|
||||||
|
<<: *es-node
|
||||||
|
hostname: es02
|
||||||
|
environment:
|
||||||
|
<<: *es-env
|
||||||
|
node.name: es02
|
||||||
|
network.publish_host: ${ES02_IP}
|
||||||
|
volumes:
|
||||||
|
- esdata02:/usr/share/elasticsearch/data
|
||||||
|
- es_certs:/usr/share/elasticsearch/config/certs:ro
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${ES02_IP}
|
||||||
|
|
||||||
|
es03:
|
||||||
|
<<: *es-node
|
||||||
|
hostname: es03
|
||||||
|
environment:
|
||||||
|
<<: *es-env
|
||||||
|
node.name: es03
|
||||||
|
network.publish_host: ${ES03_IP}
|
||||||
|
volumes:
|
||||||
|
- esdata03:/usr/share/elasticsearch/data
|
||||||
|
- es_certs:/usr/share/elasticsearch/config/certs:ro
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${ES03_IP}
|
||||||
|
|
||||||
|
metad0:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-metad:${NEBULA_VERSION}
|
||||||
|
hostname: metad0
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command: &meta-cmd
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${METAD0_IP}
|
||||||
|
- --ws_ip=${METAD0_IP}
|
||||||
|
- --port=9559
|
||||||
|
- --ws_http_port=19559
|
||||||
|
- --data_path=/data/meta
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
healthcheck: &meta-health
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${METAD0_IP}/9559'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- meta0:/data/meta
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${METAD0_IP}
|
||||||
|
|
||||||
|
metad1:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-metad:${NEBULA_VERSION}
|
||||||
|
hostname: metad1
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command:
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${METAD1_IP}
|
||||||
|
- --ws_ip=${METAD1_IP}
|
||||||
|
- --port=9559
|
||||||
|
- --ws_http_port=19559
|
||||||
|
- --data_path=/data/meta
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${METAD1_IP}/9559'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- meta1:/data/meta
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${METAD1_IP}
|
||||||
|
|
||||||
|
metad2:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-metad:${NEBULA_VERSION}
|
||||||
|
hostname: metad2
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command:
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${METAD2_IP}
|
||||||
|
- --ws_ip=${METAD2_IP}
|
||||||
|
- --port=9559
|
||||||
|
- --ws_http_port=19559
|
||||||
|
- --data_path=/data/meta
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${METAD2_IP}/9559'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- meta2:/data/meta
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${METAD2_IP}
|
||||||
|
|
||||||
|
storaged0:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-storaged:${NEBULA_VERSION}
|
||||||
|
hostname: storaged0
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command: &storage-cmd
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${STORAGED0_IP}
|
||||||
|
- --ws_ip=${STORAGED0_IP}
|
||||||
|
- --port=9779
|
||||||
|
- --ws_http_port=19779
|
||||||
|
- --data_path=/data/storage
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
depends_on: &meta-ready
|
||||||
|
metad0:
|
||||||
|
condition: service_healthy
|
||||||
|
metad1:
|
||||||
|
condition: service_healthy
|
||||||
|
metad2:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${STORAGED0_IP}/9779'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- storage0:/data/storage
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${STORAGED0_IP}
|
||||||
|
|
||||||
|
storaged1:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-storaged:${NEBULA_VERSION}
|
||||||
|
hostname: storaged1
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command:
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${STORAGED1_IP}
|
||||||
|
- --ws_ip=${STORAGED1_IP}
|
||||||
|
- --port=9779
|
||||||
|
- --ws_http_port=19779
|
||||||
|
- --data_path=/data/storage
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
depends_on: *meta-ready
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${STORAGED1_IP}/9779'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- storage1:/data/storage
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${STORAGED1_IP}
|
||||||
|
|
||||||
|
storaged2:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-storaged:${NEBULA_VERSION}
|
||||||
|
hostname: storaged2
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command:
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${STORAGED2_IP}
|
||||||
|
- --ws_ip=${STORAGED2_IP}
|
||||||
|
- --port=9779
|
||||||
|
- --ws_http_port=19779
|
||||||
|
- --data_path=/data/storage
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
depends_on: *meta-ready
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${STORAGED2_IP}/9779'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- storage2:/data/storage
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${STORAGED2_IP}
|
||||||
|
|
||||||
|
graphd:
|
||||||
|
<<: *nebula
|
||||||
|
image: vesoft/nebula-graphd:${NEBULA_VERSION}
|
||||||
|
hostname: graphd
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
command:
|
||||||
|
- --meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559
|
||||||
|
- --local_ip=${GRAPHD_IP}
|
||||||
|
- --ws_ip=${GRAPHD_IP}
|
||||||
|
- --port=9669
|
||||||
|
- --ws_http_port=19669
|
||||||
|
- --logtostderr=true
|
||||||
|
- --redirect_stdout=false
|
||||||
|
depends_on: *meta-ready
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:9669:9669"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${GRAPHD_IP}/9669'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${GRAPHD_IP}
|
||||||
|
|
||||||
|
storaged-listener:
|
||||||
|
image: vesoft/nebula-storaged:${NEBULA_VERSION}
|
||||||
|
hostname: storaged-listener
|
||||||
|
restart: unless-stopped
|
||||||
|
cap_add:
|
||||||
|
- SYS_PTRACE
|
||||||
|
logging: *logging
|
||||||
|
environment:
|
||||||
|
USER: root
|
||||||
|
entrypoint: ["bash", "-ec"]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
mkdir -p /data/listener /logs
|
||||||
|
exec /usr/local/nebula/bin/nebula-storaged \
|
||||||
|
--daemonize=false \
|
||||||
|
--containerized=true \
|
||||||
|
--meta_server_addrs=${METAD0_IP}:9559,${METAD1_IP}:9559,${METAD2_IP}:9559 \
|
||||||
|
--local_ip=${LISTENER_IP} \
|
||||||
|
--ws_ip=${LISTENER_IP} \
|
||||||
|
--port=9789 \
|
||||||
|
--ws_http_port=19789 \
|
||||||
|
--heartbeat_interval_secs=10 \
|
||||||
|
--listener_path=/data/listener \
|
||||||
|
--data_path=/data \
|
||||||
|
--log_dir=/logs \
|
||||||
|
--logtostderr=true \
|
||||||
|
--redirect_stdout=false
|
||||||
|
depends_on: *meta-ready
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/${LISTENER_IP}/9789'"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 18
|
||||||
|
start_period: 20s
|
||||||
|
volumes:
|
||||||
|
- listener0:/data
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
ipv4_address: ${LISTENER_IP}
|
||||||
|
|
||||||
|
studio:
|
||||||
|
image: vesoft/nebula-graph-studio:${STUDIO_VERSION}
|
||||||
|
hostname: studio
|
||||||
|
restart: unless-stopped
|
||||||
|
logging: *logging
|
||||||
|
depends_on:
|
||||||
|
- graphd
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:7001:7001"
|
||||||
|
networks:
|
||||||
|
- backend
|
||||||
|
|
||||||
|
console:
|
||||||
|
image: vesoft/nebula-console:${NEBULA_VERSION}
|
||||||
|
profiles: ["ops"]
|
||||||
|
entrypoint: ["nebula-console"]
|
||||||
|
command: ["-addr", "graphd", "-port", "9669", "-u", "root", "-p", "nebula"]
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
networks:
|
||||||
|
- backend
|
||||||
|
|
||||||
|
ops:
|
||||||
|
image: vesoft/nebula-console:${NEBULA_VERSION}
|
||||||
|
profiles: ["ops"]
|
||||||
|
entrypoint: ["sh", "-c"]
|
||||||
|
environment:
|
||||||
|
ELASTIC_PASSWORD: ${ELASTIC_PASSWORD}
|
||||||
|
STORAGED0_IP: ${STORAGED0_IP}
|
||||||
|
STORAGED1_IP: ${STORAGED1_IP}
|
||||||
|
STORAGED2_IP: ${STORAGED2_IP}
|
||||||
|
ES01_IP: ${ES01_IP}
|
||||||
|
ES02_IP: ${ES02_IP}
|
||||||
|
ES03_IP: ${ES03_IP}
|
||||||
|
LISTENER_IP: ${LISTENER_IP}
|
||||||
|
OPS_COMMAND: verify
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
sed 's/\r$$//' /scripts/cluster.sh | sh -s "$${OPS_COMMAND:-verify}"
|
||||||
|
volumes:
|
||||||
|
- ./scripts/cluster.sh:/scripts/cluster.sh:ro
|
||||||
|
networks:
|
||||||
|
- backend
|
||||||
|
|
||||||
|
networks:
|
||||||
|
backend:
|
||||||
|
name: nebula-stack-net
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: ${DOCKER_SUBNET}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
es_certs:
|
||||||
|
esdata01:
|
||||||
|
esdata02:
|
||||||
|
esdata03:
|
||||||
|
meta0:
|
||||||
|
meta1:
|
||||||
|
meta2:
|
||||||
|
storage0:
|
||||||
|
storage1:
|
||||||
|
storage2:
|
||||||
|
listener0:
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user