Copilot commented on code in PR #2952:
URL: https://github.com/apache/hugegraph/pull/2952#discussion_r2877117943
##########
hugegraph-store/hg-store-dist/docker/docker-entrypoint.sh:
##########
@@ -15,8 +15,72 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# start hugegraph store
-./bin/start-hugegraph-store.sh -j "$JAVA_OPTS"
+log() { echo "[hugegraph-store-entrypoint] $*"; }
+require_env() {
+ local name="$1"
+ if [[ -z "${!name:-}" ]]; then
+ echo "ERROR: missing required env '${name}'" >&2; exit 2
+ fi
+}
+
+json_escape() {
+ local s="$1"
+ s=${s//\\/\\\\}; s=${s//\"/\\\"}; s=${s//$'\n'/}
+ printf "%s" "$s"
+}
+
+# ── Guard deprecated vars ─────────────────────────────────────────────
+migrate_env() {
+ local old_name="$1" new_name="$2"
+
+ if [[ -n "${!old_name:-}" && -z "${!new_name:-}" ]]; then
+ log "WARN: deprecated env '${old_name}' detected; mapping to
'${new_name}'"
+ export "${new_name}=${!old_name}"
+ fi
+}
+
+migrate_env "PD_ADDRESS" "HG_STORE_PD_ADDRESS"
+migrate_env "GRPC_HOST" "HG_STORE_GRPC_HOST"
+migrate_env "RAFT_ADDRESS" "HG_STORE_RAFT_ADDRESS"
+# ── Required vars ─────────────────────────────────────────────────────
+require_env "HG_STORE_PD_ADDRESS"
+require_env "HG_STORE_GRPC_HOST"
+require_env "HG_STORE_RAFT_ADDRESS"
+
+# ── Defaults ──────────────────────────────────────────────────────────
+: "${HG_STORE_GRPC_PORT:=8500}"
+: "${HG_STORE_REST_PORT:=8520}"
+: "${HG_STORE_DATA_PATH:=/hugegraph-store/storage}"
+
+# ── Build SPRING_APPLICATION_JSON ─────────────────────────────────────
+SPRING_APPLICATION_JSON="$(cat <<JSON
+{
+ "pdserver": { "address": "$(json_escape "${HG_STORE_PD_ADDRESS}")" },
+ "grpc": { "host": "$(json_escape "${HG_STORE_GRPC_HOST}")",
+ "port": "$(json_escape "${HG_STORE_GRPC_PORT}")" },
+ "raft": { "address": "$(json_escape "${HG_STORE_RAFT_ADDRESS}")" },
+ "server": { "port": "$(json_escape "${HG_STORE_REST_PORT}")" },
+ "app": { "data-path": "$(json_escape "${HG_STORE_DATA_PATH}")" }
+}
+JSON
+)"
+export SPRING_APPLICATION_JSON
+
+log "effective config:"
+log " pdserver.address=${HG_STORE_PD_ADDRESS}"
+log " grpc.host=${HG_STORE_GRPC_HOST}"
+log " grpc.port=${HG_STORE_GRPC_PORT}"
+log " raft.address=${HG_STORE_RAFT_ADDRESS}"
+log " server.port=${HG_STORE_REST_PORT}"
+log " app.data-path=${HG_STORE_DATA_PATH}"
+
+log "Patching conf/application.yml with cluster settings..."
+sed -i "s|address: localhost:8686|address: ${HG_STORE_PD_ADDRESS}|"
conf/application.yml
+sed -i "s|host: 127.0.0.1|host: ${HG_STORE_GRPC_HOST}|"
conf/application.yml
+sed -i "s|address: 127.0.0.1:8510|address: ${HG_STORE_RAFT_ADDRESS}|"
conf/application.yml
+
Review Comment:
The entrypoint always runs `sed -i` against `conf/application.yml` with `set
-euo pipefail`. If `/hugegraph-store/conf` is bind-mounted (common in `docker
run`), this will modify host config and can fail when the mount is read-only,
aborting startup. Since `SPRING_APPLICATION_JSON` already provides the same
settings, consider removing the in-place patching or making it
conditional/opt-in.
##########
docker/docker-compose-3pd-3store-3server.yml:
##########
@@ -15,166 +15,218 @@
# limitations under the License.
#
-# TODO: reuse the configs for same type containers
-# User could modify the node nums and the port by themselves
-version: "3"
+name: hugegraph-3x3
+
+networks:
+ hg-net:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/24
+
+volumes:
+ hg-pd0-data:
+ hg-pd1-data:
+ hg-pd2-data:
+ hg-store0-data:
+ hg-store1-data:
+ hg-store2-data:
+
+# ── Shared service templates ──────────────────────────────────────────
+
+x-pd-common: &pd-common
+ image: hugegraph/pd:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ restart: unless-stopped
+ entrypoint: ["/hugegraph-pd/docker-entrypoint.sh"]
+ healthcheck:
Review Comment:
Same concern as the single-node compose: setting `entrypoint:` overrides the
Dockerfile `ENTRYPOINT` (`dumb-init`) and can degrade shutdown/reaping behavior
for these Java processes. Prefer keeping the image entrypoint (remove
`entrypoint:`) or explicitly invoke dumb-init in the compose entrypoint.
##########
docker/docker-compose.yml:
##########
@@ -15,44 +15,118 @@
# limitations under the License.
#
-version: "3"
+name: hugegraph-single
+
+networks:
+ hg-net:
+ driver: bridge
+
+volumes:
+ hg-pd-data:
+ hg-store-data:
services:
+
pd:
- image: hugegraph/pd
- container_name: pd
+ image: hugegraph/pd:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ container_name: hg-pd
hostname: pd
- network_mode: host
+ restart: unless-stopped
+ networks: [hg-net]
+
+ entrypoint: ["/hugegraph-pd/docker-entrypoint.sh"]
+
+ environment:
+ HG_PD_GRPC_HOST: pd
+ HG_PD_GRPC_PORT: "8686"
+ HG_PD_REST_PORT: "8620"
+ HG_PD_RAFT_ADDRESS: pd:8610
+ HG_PD_RAFT_PEERS_LIST: pd:8610
+ HG_PD_INITIAL_STORE_LIST: store:8500
+ HG_PD_DATA_PATH: /hugegraph-pd/pd_data
+
+ ports:
+ - "8620:8620"
+
+ volumes:
+ - hg-pd-data:/hugegraph-pd/pd_data
+ -
../hugegraph-pd/hg-pd-dist/docker/docker-entrypoint.sh:/hugegraph-pd/docker-entrypoint.sh
+
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8620"]
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8620/ >/dev/null || exit
1"]
interval: 10s
timeout: 5s
- retries: 3
+ retries: 12
+ start_period: 30s
+
store:
- image: hugegraph/store
- container_name: store
+ image: hugegraph/store:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ container_name: hg-store
hostname: store
- network_mode: host
+ restart: unless-stopped
+ networks: [hg-net]
+
+ entrypoint: ["/hugegraph-store/docker-entrypoint.sh"]
+
depends_on:
pd:
condition: service_healthy
+
+ environment:
+ HG_STORE_PD_ADDRESS: pd:8686
+ HG_STORE_GRPC_HOST: store
+ HG_STORE_GRPC_PORT: "8500"
+ HG_STORE_REST_PORT: "8520"
+ HG_STORE_RAFT_ADDRESS: store:8510
+ HG_STORE_DATA_PATH: /hugegraph-store/storage
+
+ ports:
+ - "8520:8520"
+
+ volumes:
+ - hg-store-data:/hugegraph-store/storage
+ -
../hugegraph-store/hg-store-dist/docker/docker-entrypoint.sh:/hugegraph-store/docker-entrypoint.sh
+
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8520"]
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8520/v1/health
>/dev/null || exit 1"]
interval: 10s
- timeout: 5s
- retries: 3
+ timeout: 10s
+ retries: 30
+ start_period: 60s
+
server:
- image: hugegraph/server
- container_name: server
+ image: hugegraph/server:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ container_name: hg-server
hostname: server
- network_mode: host
+ restart: unless-stopped
+ networks: [hg-net]
+
+ entrypoint: ["/hugegraph-server/docker-entrypoint.sh"]
+
Review Comment:
`entrypoint:` here overrides the image `ENTRYPOINT` (`dumb-init`), which can
prevent proper signal forwarding and leave the HugeGraph server JVM running
after `docker compose stop`. Prefer relying on the image entrypoint (remove
this) or use `/usr/bin/dumb-init -- /hugegraph-server/docker-entrypoint.sh`.
##########
docker/docker-compose.yml:
##########
@@ -15,44 +15,118 @@
# limitations under the License.
#
-version: "3"
+name: hugegraph-single
+
+networks:
+ hg-net:
+ driver: bridge
+
+volumes:
+ hg-pd-data:
+ hg-store-data:
services:
+
pd:
- image: hugegraph/pd
- container_name: pd
+ image: hugegraph/pd:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ container_name: hg-pd
hostname: pd
- network_mode: host
+ restart: unless-stopped
+ networks: [hg-net]
+
+ entrypoint: ["/hugegraph-pd/docker-entrypoint.sh"]
+
Review Comment:
`entrypoint:` here overrides the image’s Dockerfile `ENTRYPOINT`
(`dumb-init`). That removes signal forwarding/zombie reaping and can make
`docker compose stop` behave poorly. Since the image already runs
`./docker-entrypoint.sh`, consider removing `entrypoint:` entirely (and just
bind-mount the script to the same path) or wrap it with dumb-init (e.g.,
`/usr/bin/dumb-init -- ...`).
##########
hugegraph-pd/hg-pd-dist/docker/docker-entrypoint.sh:
##########
@@ -15,8 +15,79 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# start hugegraph pd
-./bin/start-hugegraph-pd.sh -j "$JAVA_OPTS"
+log() { echo "[hugegraph-pd-entrypoint] $*"; }
+require_env() {
+ local name="$1"
+ if [[ -z "${!name:-}" ]]; then
+ echo "ERROR: missing required env '${name}'" >&2; exit 2
+ fi
+}
+
+json_escape() {
+ local s="$1"
+ s=${s//\\/\\\\}; s=${s//\"/\\\"}; s=${s//$'\n'/}
+ printf "%s" "$s"
+}
+
+migrate_env() {
+ local old_name="$1" new_name="$2"
+
+ if [[ -n "${!old_name:-}" && -z "${!new_name:-}" ]]; then
+ log "WARN: deprecated env '${old_name}' detected; mapping to
'${new_name}'"
+ export "${new_name}=${!old_name}"
+ fi
+}
+
+migrate_env "GRPC_HOST" "HG_PD_GRPC_HOST"
+migrate_env "RAFT_ADDRESS" "HG_PD_RAFT_ADDRESS"
+migrate_env "RAFT_PEERS" "HG_PD_RAFT_PEERS_LIST"
+migrate_env "PD_INITIAL_STORE_LIST" "HG_PD_INITIAL_STORE_LIST"
+
+# ── Required vars ─────────────────────────────────────────────────────
+require_env "HG_PD_GRPC_HOST"
+require_env "HG_PD_RAFT_ADDRESS"
+require_env "HG_PD_RAFT_PEERS_LIST"
+require_env "HG_PD_INITIAL_STORE_LIST"
+
+: "${HG_PD_GRPC_PORT:=8686}"
+: "${HG_PD_REST_PORT:=8620}"
+: "${HG_PD_DATA_PATH:=/hugegraph-pd/pd_data}"
+: "${HG_PD_INITIAL_STORE_COUNT:=1}"
+
+SPRING_APPLICATION_JSON="$(cat <<JSON
+{
+ "grpc": { "host": "$(json_escape "${HG_PD_GRPC_HOST}")",
+ "port": "$(json_escape "${HG_PD_GRPC_PORT}")" },
+ "server": { "port": "$(json_escape "${HG_PD_REST_PORT}")" },
+ "raft": { "address": "$(json_escape "${HG_PD_RAFT_ADDRESS}")",
+ "peers-list": "$(json_escape "${HG_PD_RAFT_PEERS_LIST}")" },
+ "pd": { "data-path": "$(json_escape "${HG_PD_DATA_PATH}")",
+ "initial-store-list": "$(json_escape
"${HG_PD_INITIAL_STORE_LIST}")" ,
+ "initial-store-count": ${HG_PD_INITIAL_STORE_COUNT} }
+}
+JSON
+)"
+export SPRING_APPLICATION_JSON
+
+log "effective config:"
+log " grpc.host=${HG_PD_GRPC_HOST}"
+log " grpc.port=${HG_PD_GRPC_PORT}"
+log " server.port=${HG_PD_REST_PORT}"
+log " raft.address=${HG_PD_RAFT_ADDRESS}"
+log " raft.peers-list=${HG_PD_RAFT_PEERS_LIST}"
+log " pd.initial-store-list=${HG_PD_INITIAL_STORE_LIST}"
+log " pd.initial-store-count=${HG_PD_INITIAL_STORE_COUNT}"
+log " pd.data-path=${HG_PD_DATA_PATH}"
+
+log "Patching conf/application.yml with cluster settings..."
+sed -i "s|address: 127.0.0.1:8610|address: ${HG_PD_RAFT_ADDRESS}|"
conf/application.yml
+sed -i "s|peers-list: 127.0.0.1:8610|peers-list: ${HG_PD_RAFT_PEERS_LIST}|"
conf/application.yml
+sed -i "s|initial-store-list: 127.0.0.1:8500|initial-store-list:
${HG_PD_INITIAL_STORE_LIST}|" conf/application.yml
+sed -i "s|initial-store-count: 1|initial-store-count:
${HG_PD_INITIAL_STORE_COUNT}|" conf/application.yml
+sed -i "s|host: 127.0.0.1|host: ${HG_PD_GRPC_HOST}|"
conf/application.yml
Review Comment:
This entrypoint unconditionally patches `conf/application.yml` in-place
under `set -euo pipefail`. If users mount `/hugegraph-pd/conf` from the host
(as shown in the module README), this will mutate host config and can fail on
read-only mounts/permissions, causing the container to exit. Since
`SPRING_APPLICATION_JSON` already supplies the overrides, consider removing the
`sed -i` patching or guarding it behind an opt-in flag.
```suggestion
if [[ "${HG_PD_PATCH_APPLICATION_YML:-false}" == "true" ]]; then
log "Patching conf/application.yml with cluster settings
(HG_PD_PATCH_APPLICATION_YML=true)..."
sed -i "s|address: 127.0.0.1:8610|address: ${HG_PD_RAFT_ADDRESS}|"
conf/application.yml
sed -i "s|peers-list: 127.0.0.1:8610|peers-list:
${HG_PD_RAFT_PEERS_LIST}|" conf/application.yml
sed -i "s|initial-store-list: 127.0.0.1:8500|initial-store-list:
${HG_PD_INITIAL_STORE_LIST}|" conf/application.yml
sed -i "s|initial-store-count: 1|initial-store-count:
${HG_PD_INITIAL_STORE_COUNT}|" conf/application.yml
sed -i "s|host: 127.0.0.1|host: ${HG_PD_GRPC_HOST}|"
conf/application.yml
else
log "Skipping conf/application.yml patching (HG_PD_PATCH_APPLICATION_YML
not 'true'); relying on SPRING_APPLICATION_JSON."
fi
```
##########
hugegraph-server/hugegraph-dist/docker/docker-entrypoint.sh:
##########
@@ -15,32 +15,78 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# create a folder to save the docker-related file
-DOCKER_FOLDER='./docker'
-mkdir -p $DOCKER_FOLDER
-
+DOCKER_FOLDER="./docker"
INIT_FLAG_FILE="init_complete"
+GRAPH_CONF="./conf/graphs/hugegraph.properties"
+
+mkdir -p "${DOCKER_FOLDER}"
+
+log() { echo "[hugegraph-server-entrypoint] $*"; }
+
+set_prop() {
+ local key="$1" val="$2" file="$3"
+ local esc_key esc_val
+
+ esc_key=$(printf '%s' "$key" | sed -e 's/[][(){}.^$*+?|\\/]/\\&/g')
+ esc_val=$(printf '%s' "$val" | sed -e 's/[&|\\]/\\&/g')
-if [ ! -f "${DOCKER_FOLDER}/${INIT_FLAG_FILE}" ]; then
- # wait for storage backend
- ./bin/wait-storage.sh
- if [ -z "$PASSWORD" ]; then
- echo "init hugegraph with non-auth mode"
+ if grep -qE "^[[:space:]]*${esc_key}[[:space:]]*=" "${file}"; then
+ sed -ri "s|^([[:space:]]*${esc_key}[[:space:]]*=).*|\\1${esc_val}|"
"${file}"
+ else
Review Comment:
The `set_prop` helper interpolates the untrusted `val` argument (for example
from `HG_SERVER_BACKEND` or `HG_SERVER_PD_PEERS`) directly into a double-quoted
`sed -ri` expression. If an attacker can control one of these environment
variables, they can inject `$(command)` or backticks so that arbitrary shell
commands run when `sed` is invoked. Refactor this to ensure the replacement
value is treated as literal datavalidate or whitelist accepted formats and
avoid embedding it directly into a `sed` program that the shell parses.
##########
docker/docker-compose-3pd-3store-3server.yml:
##########
@@ -15,166 +15,218 @@
# limitations under the License.
#
-# TODO: reuse the configs for same type containers
-# User could modify the node nums and the port by themselves
-version: "3"
+name: hugegraph-3x3
+
+networks:
+ hg-net:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/24
+
+volumes:
+ hg-pd0-data:
+ hg-pd1-data:
+ hg-pd2-data:
+ hg-store0-data:
+ hg-store1-data:
+ hg-store2-data:
+
+# ── Shared service templates ──────────────────────────────────────────
+
+x-pd-common: &pd-common
+ image: hugegraph/pd:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ restart: unless-stopped
+ entrypoint: ["/hugegraph-pd/docker-entrypoint.sh"]
+ healthcheck:
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8620/v1/health >/dev/null
|| exit 1"]
+ interval: 15s
+ timeout: 10s
+ retries: 30
+ start_period: 120s
+
+x-store-common: &store-common
+ image: hugegraph/store:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ restart: unless-stopped
+ networks: [hg-net]
+ depends_on:
+ pd0: { condition: service_healthy }
+ pd1: { condition: service_healthy }
+ pd2: { condition: service_healthy }
+ entrypoint: ["/hugegraph-store/docker-entrypoint.sh"]
+ healthcheck:
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8520/v1/health >/dev/null
|| exit 1"]
+ interval: 15s
+ timeout: 15s
+ retries: 40
+ start_period: 120s
+
+x-server-common: &server-common
+ image: hugegraph/server:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ restart: unless-stopped
+ networks: [hg-net]
+ depends_on:
+ store0: { condition: service_healthy }
+ store1: { condition: service_healthy }
+ store2: { condition: service_healthy }
+ entrypoint: ["/hugegraph-server/docker-entrypoint.sh"]
Review Comment:
`x-server-common` sets `entrypoint:` which overrides the Dockerfile
`ENTRYPOINT` (`dumb-init`). For the server JVM this can cause slow/unclean
stops and poor signal propagation. Prefer relying on the image entrypoint
(remove `entrypoint:`) or call dumb-init explicitly in the compose entrypoint.
```suggestion
```
##########
hugegraph-store/hg-store-dist/docker/docker-entrypoint.sh:
##########
@@ -15,8 +15,72 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# start hugegraph store
-./bin/start-hugegraph-store.sh -j "$JAVA_OPTS"
+log() { echo "[hugegraph-store-entrypoint] $*"; }
+require_env() {
+ local name="$1"
+ if [[ -z "${!name:-}" ]]; then
+ echo "ERROR: missing required env '${name}'" >&2; exit 2
+ fi
+}
+
+json_escape() {
+ local s="$1"
+ s=${s//\\/\\\\}; s=${s//\"/\\\"}; s=${s//$'\n'/}
+ printf "%s" "$s"
+}
+
+# ── Guard deprecated vars ─────────────────────────────────────────────
+migrate_env() {
+ local old_name="$1" new_name="$2"
+
+ if [[ -n "${!old_name:-}" && -z "${!new_name:-}" ]]; then
+ log "WARN: deprecated env '${old_name}' detected; mapping to
'${new_name}'"
+ export "${new_name}=${!old_name}"
+ fi
+}
+
+migrate_env "PD_ADDRESS" "HG_STORE_PD_ADDRESS"
+migrate_env "GRPC_HOST" "HG_STORE_GRPC_HOST"
+migrate_env "RAFT_ADDRESS" "HG_STORE_RAFT_ADDRESS"
+# ── Required vars ─────────────────────────────────────────────────────
+require_env "HG_STORE_PD_ADDRESS"
+require_env "HG_STORE_GRPC_HOST"
+require_env "HG_STORE_RAFT_ADDRESS"
Review Comment:
This entrypoint now hard-requires `HG_STORE_GRPC_HOST` and
`HG_STORE_RAFT_ADDRESS` (in addition to PD address). The documented `docker
run` example in `hugegraph-store/README.md` only sets `PD_ADDRESS` + mounts
`conf/`, so it will now fail immediately. Consider defaulting these values to
what’s in `conf/application.yml` and only requiring/overriding them when env
vars are provided.
##########
docker/docker-compose.yml:
##########
@@ -15,44 +15,118 @@
# limitations under the License.
#
-version: "3"
+name: hugegraph-single
+
+networks:
+ hg-net:
+ driver: bridge
+
+volumes:
+ hg-pd-data:
+ hg-store-data:
services:
+
pd:
- image: hugegraph/pd
- container_name: pd
+ image: hugegraph/pd:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ container_name: hg-pd
hostname: pd
- network_mode: host
+ restart: unless-stopped
+ networks: [hg-net]
+
+ entrypoint: ["/hugegraph-pd/docker-entrypoint.sh"]
+
+ environment:
+ HG_PD_GRPC_HOST: pd
+ HG_PD_GRPC_PORT: "8686"
+ HG_PD_REST_PORT: "8620"
+ HG_PD_RAFT_ADDRESS: pd:8610
+ HG_PD_RAFT_PEERS_LIST: pd:8610
+ HG_PD_INITIAL_STORE_LIST: store:8500
+ HG_PD_DATA_PATH: /hugegraph-pd/pd_data
+
+ ports:
+ - "8620:8620"
+
+ volumes:
+ - hg-pd-data:/hugegraph-pd/pd_data
+ -
../hugegraph-pd/hg-pd-dist/docker/docker-entrypoint.sh:/hugegraph-pd/docker-entrypoint.sh
+
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8620"]
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8620/ >/dev/null || exit
1"]
interval: 10s
timeout: 5s
- retries: 3
+ retries: 12
+ start_period: 30s
+
store:
- image: hugegraph/store
- container_name: store
+ image: hugegraph/store:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ container_name: hg-store
hostname: store
- network_mode: host
+ restart: unless-stopped
+ networks: [hg-net]
+
+ entrypoint: ["/hugegraph-store/docker-entrypoint.sh"]
+
Review Comment:
`entrypoint:` overrides the image’s Dockerfile `ENTRYPOINT` (`dumb-init`),
which can hurt signal handling/shutdown behavior for the Store JVM. Prefer
removing this `entrypoint:` (the image already runs `./docker-entrypoint.sh`)
or wrap it with dumb-init explicitly.
```suggestion
```
##########
hugegraph-pd/hg-pd-dist/docker/docker-entrypoint.sh:
##########
@@ -15,8 +15,79 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# start hugegraph pd
-./bin/start-hugegraph-pd.sh -j "$JAVA_OPTS"
+log() { echo "[hugegraph-pd-entrypoint] $*"; }
+require_env() {
+ local name="$1"
+ if [[ -z "${!name:-}" ]]; then
+ echo "ERROR: missing required env '${name}'" >&2; exit 2
+ fi
+}
+
+json_escape() {
+ local s="$1"
+ s=${s//\\/\\\\}; s=${s//\"/\\\"}; s=${s//$'\n'/}
+ printf "%s" "$s"
+}
+
+migrate_env() {
+ local old_name="$1" new_name="$2"
+
+ if [[ -n "${!old_name:-}" && -z "${!new_name:-}" ]]; then
+ log "WARN: deprecated env '${old_name}' detected; mapping to
'${new_name}'"
+ export "${new_name}=${!old_name}"
+ fi
+}
+
+migrate_env "GRPC_HOST" "HG_PD_GRPC_HOST"
+migrate_env "RAFT_ADDRESS" "HG_PD_RAFT_ADDRESS"
+migrate_env "RAFT_PEERS" "HG_PD_RAFT_PEERS_LIST"
+migrate_env "PD_INITIAL_STORE_LIST" "HG_PD_INITIAL_STORE_LIST"
+
+# ── Required vars ─────────────────────────────────────────────────────
+require_env "HG_PD_GRPC_HOST"
+require_env "HG_PD_RAFT_ADDRESS"
+require_env "HG_PD_RAFT_PEERS_LIST"
+require_env "HG_PD_INITIAL_STORE_LIST"
Review Comment:
This entrypoint now requires `HG_PD_*` env vars and will exit if they’re not
set. That breaks the documented `docker run hugegraph-pd:latest ...` flow in
`hugegraph-pd/README.md` (which relies on mounted `conf/application.yml`
defaults and doesn’t set these envs). Consider providing sane defaults (from
current `conf/application.yml` values) and only overriding when env vars are
present, rather than hard-failing.
```suggestion
# ── Defaults (overridable via env) ────────────────────────────────────
: "${HG_PD_GRPC_HOST:=127.0.0.1}"
: "${HG_PD_RAFT_ADDRESS:=127.0.0.1:8610}"
: "${HG_PD_RAFT_PEERS_LIST:=127.0.0.1:8610}"
: "${HG_PD_INITIAL_STORE_LIST:=127.0.0.1:8500}"
```
##########
docker/docker-compose-3pd-3store-3server.yml:
##########
@@ -15,166 +15,218 @@
# limitations under the License.
#
-# TODO: reuse the configs for same type containers
-# User could modify the node nums and the port by themselves
-version: "3"
+name: hugegraph-3x3
+
+networks:
+ hg-net:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.20.0.0/24
+
+volumes:
+ hg-pd0-data:
+ hg-pd1-data:
+ hg-pd2-data:
+ hg-store0-data:
+ hg-store1-data:
+ hg-store2-data:
+
+# ── Shared service templates ──────────────────────────────────────────
+
+x-pd-common: &pd-common
+ image: hugegraph/pd:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ restart: unless-stopped
+ entrypoint: ["/hugegraph-pd/docker-entrypoint.sh"]
+ healthcheck:
+ test: ["CMD-SHELL", "curl -fsS http://localhost:8620/v1/health >/dev/null
|| exit 1"]
+ interval: 15s
+ timeout: 10s
+ retries: 30
+ start_period: 120s
+
+x-store-common: &store-common
+ image: hugegraph/store:${HUGEGRAPH_VERSION:-latest}
+ pull_policy: always
+ restart: unless-stopped
+ networks: [hg-net]
+ depends_on:
+ pd0: { condition: service_healthy }
+ pd1: { condition: service_healthy }
+ pd2: { condition: service_healthy }
+ entrypoint: ["/hugegraph-store/docker-entrypoint.sh"]
Review Comment:
`x-store-common` sets `entrypoint:` which overrides the image’s `ENTRYPOINT`
(`dumb-init`). That can interfere with signal handling and leave orphaned
JVMs/zombies. Prefer removing the compose `entrypoint:` (let the image’s
entrypoint run) or explicitly wrap the script with dumb-init.
```suggestion
```
##########
hugegraph-store/hg-store-dist/docker/docker-entrypoint.sh:
##########
@@ -15,8 +15,72 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# start hugegraph store
-./bin/start-hugegraph-store.sh -j "$JAVA_OPTS"
+log() { echo "[hugegraph-store-entrypoint] $*"; }
+require_env() {
+ local name="$1"
+ if [[ -z "${!name:-}" ]]; then
+ echo "ERROR: missing required env '${name}'" >&2; exit 2
+ fi
+}
+
+json_escape() {
+ local s="$1"
+ s=${s//\\/\\\\}; s=${s//\"/\\\"}; s=${s//$'\n'/}
+ printf "%s" "$s"
+}
+
+# ── Guard deprecated vars ─────────────────────────────────────────────
+migrate_env() {
+ local old_name="$1" new_name="$2"
+
+ if [[ -n "${!old_name:-}" && -z "${!new_name:-}" ]]; then
+ log "WARN: deprecated env '${old_name}' detected; mapping to
'${new_name}'"
+ export "${new_name}=${!old_name}"
+ fi
+}
+
+migrate_env "PD_ADDRESS" "HG_STORE_PD_ADDRESS"
+migrate_env "GRPC_HOST" "HG_STORE_GRPC_HOST"
+migrate_env "RAFT_ADDRESS" "HG_STORE_RAFT_ADDRESS"
+# ── Required vars ─────────────────────────────────────────────────────
+require_env "HG_STORE_PD_ADDRESS"
+require_env "HG_STORE_GRPC_HOST"
+require_env "HG_STORE_RAFT_ADDRESS"
+
+# ── Defaults ──────────────────────────────────────────────────────────
+: "${HG_STORE_GRPC_PORT:=8500}"
+: "${HG_STORE_REST_PORT:=8520}"
+: "${HG_STORE_DATA_PATH:=/hugegraph-store/storage}"
+
+# ── Build SPRING_APPLICATION_JSON ─────────────────────────────────────
+SPRING_APPLICATION_JSON="$(cat <<JSON
+{
+ "pdserver": { "address": "$(json_escape "${HG_STORE_PD_ADDRESS}")" },
+ "grpc": { "host": "$(json_escape "${HG_STORE_GRPC_HOST}")",
+ "port": "$(json_escape "${HG_STORE_GRPC_PORT}")" },
+ "raft": { "address": "$(json_escape "${HG_STORE_RAFT_ADDRESS}")" },
+ "server": { "port": "$(json_escape "${HG_STORE_REST_PORT}")" },
+ "app": { "data-path": "$(json_escape "${HG_STORE_DATA_PATH}")" }
+}
+JSON
+)"
+export SPRING_APPLICATION_JSON
+
+log "effective config:"
+log " pdserver.address=${HG_STORE_PD_ADDRESS}"
+log " grpc.host=${HG_STORE_GRPC_HOST}"
+log " grpc.port=${HG_STORE_GRPC_PORT}"
+log " raft.address=${HG_STORE_RAFT_ADDRESS}"
+log " server.port=${HG_STORE_REST_PORT}"
+log " app.data-path=${HG_STORE_DATA_PATH}"
+
+log "Patching conf/application.yml with cluster settings..."
+sed -i "s|address: localhost:8686|address: ${HG_STORE_PD_ADDRESS}|"
conf/application.yml
+sed -i "s|host: 127.0.0.1|host: ${HG_STORE_GRPC_HOST}|"
conf/application.yml
+sed -i "s|address: 127.0.0.1:8510|address: ${HG_STORE_RAFT_ADDRESS}|"
conf/application.yml
Review Comment:
The environment-derived values `HG_STORE_PD_ADDRESS`, `HG_STORE_GRPC_HOST`,
and `HG_STORE_RAFT_ADDRESS` are expanded inside double-quoted `sed` commands.
If an attacker can influence these environment variables, they can include
shell syntax like `$(command)` or backticks that the shell will execute when
constructing the `sed` arguments, resulting in arbitrary command execution.
Treat these values as data by escaping them appropriately or updating the
configuration file using a safer mechanism that does not embed untrusted input
into shell-evaluated code.
##########
hugegraph-pd/hg-pd-dist/docker/docker-entrypoint.sh:
##########
@@ -15,8 +15,79 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+set -euo pipefail
-# start hugegraph pd
-./bin/start-hugegraph-pd.sh -j "$JAVA_OPTS"
+log() { echo "[hugegraph-pd-entrypoint] $*"; }
+require_env() {
+ local name="$1"
+ if [[ -z "${!name:-}" ]]; then
+ echo "ERROR: missing required env '${name}'" >&2; exit 2
+ fi
+}
+
+json_escape() {
+ local s="$1"
+ s=${s//\\/\\\\}; s=${s//\"/\\\"}; s=${s//$'\n'/}
+ printf "%s" "$s"
+}
+
+migrate_env() {
+ local old_name="$1" new_name="$2"
+
+ if [[ -n "${!old_name:-}" && -z "${!new_name:-}" ]]; then
+ log "WARN: deprecated env '${old_name}' detected; mapping to
'${new_name}'"
+ export "${new_name}=${!old_name}"
+ fi
+}
+
+migrate_env "GRPC_HOST" "HG_PD_GRPC_HOST"
+migrate_env "RAFT_ADDRESS" "HG_PD_RAFT_ADDRESS"
+migrate_env "RAFT_PEERS" "HG_PD_RAFT_PEERS_LIST"
+migrate_env "PD_INITIAL_STORE_LIST" "HG_PD_INITIAL_STORE_LIST"
+
+# ── Required vars ─────────────────────────────────────────────────────
+require_env "HG_PD_GRPC_HOST"
+require_env "HG_PD_RAFT_ADDRESS"
+require_env "HG_PD_RAFT_PEERS_LIST"
+require_env "HG_PD_INITIAL_STORE_LIST"
+
+: "${HG_PD_GRPC_PORT:=8686}"
+: "${HG_PD_REST_PORT:=8620}"
+: "${HG_PD_DATA_PATH:=/hugegraph-pd/pd_data}"
+: "${HG_PD_INITIAL_STORE_COUNT:=1}"
+
+SPRING_APPLICATION_JSON="$(cat <<JSON
+{
+ "grpc": { "host": "$(json_escape "${HG_PD_GRPC_HOST}")",
+ "port": "$(json_escape "${HG_PD_GRPC_PORT}")" },
+ "server": { "port": "$(json_escape "${HG_PD_REST_PORT}")" },
+ "raft": { "address": "$(json_escape "${HG_PD_RAFT_ADDRESS}")",
+ "peers-list": "$(json_escape "${HG_PD_RAFT_PEERS_LIST}")" },
+ "pd": { "data-path": "$(json_escape "${HG_PD_DATA_PATH}")",
+ "initial-store-list": "$(json_escape
"${HG_PD_INITIAL_STORE_LIST}")" ,
+ "initial-store-count": ${HG_PD_INITIAL_STORE_COUNT} }
+}
+JSON
+)"
+export SPRING_APPLICATION_JSON
+
+log "effective config:"
+log " grpc.host=${HG_PD_GRPC_HOST}"
+log " grpc.port=${HG_PD_GRPC_PORT}"
+log " server.port=${HG_PD_REST_PORT}"
+log " raft.address=${HG_PD_RAFT_ADDRESS}"
+log " raft.peers-list=${HG_PD_RAFT_PEERS_LIST}"
+log " pd.initial-store-list=${HG_PD_INITIAL_STORE_LIST}"
+log " pd.initial-store-count=${HG_PD_INITIAL_STORE_COUNT}"
+log " pd.data-path=${HG_PD_DATA_PATH}"
+
+log "Patching conf/application.yml with cluster settings..."
+sed -i "s|address: 127.0.0.1:8610|address: ${HG_PD_RAFT_ADDRESS}|"
conf/application.yml
+sed -i "s|peers-list: 127.0.0.1:8610|peers-list: ${HG_PD_RAFT_PEERS_LIST}|"
conf/application.yml
+sed -i "s|initial-store-list: 127.0.0.1:8500|initial-store-list:
${HG_PD_INITIAL_STORE_LIST}|" conf/application.yml
+sed -i "s|initial-store-count: 1|initial-store-count:
${HG_PD_INITIAL_STORE_COUNT}|" conf/application.yml
+sed -i "s|host: 127.0.0.1|host: ${HG_PD_GRPC_HOST}|"
conf/application.yml
Review Comment:
The PD cluster configuration values (`HG_PD_RAFT_ADDRESS`,
`HG_PD_RAFT_PEERS_LIST`, `HG_PD_INITIAL_STORE_LIST`,
`HG_PD_INITIAL_STORE_COUNT`, `HG_PD_GRPC_HOST`) are interpolated into
double-quoted `sed -i` commands. An attacker who can set any of these
environment variables could include `$(command)` or backticks so that the shell
executes arbitrary commands when expanding the `sed` arguments. To prevent
command injection, treat these values as pure data by escaping them or
modifying the configuration file with tooling that does not embed untrusted
input into shell code.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]