orenccl commented on code in PR #103:
URL: 
https://github.com/apache/gravitino-playground/pull/103#discussion_r1835736352


##########
playground.sh:
##########
@@ -64,140 +127,277 @@ checkHelm() {
   if [ $isExist ]; then
     true # Placeholder, do nothing
   else
-    echo "ERROR: Helm command not found, Please install helm v3."
+    echo "[ERROR] Helm check failed: Helm command not found, Please install 
helm v3."
     exit
   fi
   # check version
   # version will be like:
   # Version:"v3.15.2"
   regex="Version:\"(v[0-9]\.[0-9]+\.[0-9])\""
   version=$(helm version)
-  echo "$version"
   if [[ $version =~ $regex ]]; then
     major_version="${BASH_REMATCH[1]}"
-    echo "$major_version"
+    echo "[INFO] Helm version: ${major_version}"
     if [[ $major_version =~ "v3" ]]; then
-      echo "INFO: helm check PASS."
+      echo "[INFO] Helm check passed."
       return
     else
-      echo "ERROR: Please install helm v3"
+      echo "[ERROR] Please install helm v3."
       exit
     fi
   fi
 }
 
-checkPortInUse() {
-  local port=$1
-  if [[ "$(uname)" == "Darwin" ]]; then
-    openPort=$(lsof -i :$port -sTCP:LISTEN)
-  elif [[ "$(uname)" == "Linux" ]]; then
-    openPort=$(sudo lsof -i :$port -sTCP:LISTEN)
+checkK8sDisk() {
+  local nodeName=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
+  local availableStorage=$(kubectl get node ${nodeName} -o 
jsonpath='{.status.allocatable.ephemeral-storage}')
+
+  # Check if the available storage value was retrieved
+  if [ -z "${availableStorage}" ]; then
+    echo "[ERROR] K8s disk check failed: Could not determine available 
ephemeral storage on node ${nodeName}."
+    exit 1
   fi
-  if [ -z "${openPort}" ]; then
-    echo "INFO: Port $port is ok."
+
+  # Convert storage from bytes to GB
+  local availableSpaceGB=$((${availableStorage} / 1024 / 1024 / 1024))
+
+  if [ "${availableSpaceGB}" -ge "${requiredDiskSpaceGB}" ]; then
+    echo "[INFO] K8s disk check passed: ${availableSpaceGB} GB available on 
node ${nodeName}."
   else
-    echo "ERROR: Port $port is in use. Please check it."
+    echo "[ERROR] K8s disk check failed: Only ${availableSpaceGB} GB available 
on node ${nodeName}, ${requiredDiskSpaceGB} GB or more required."
+    exit 1
+  fi
+}
+
+checkK8sRam() {
+  local nodeName=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
+  local totalRamKi=$(kubectl get node ${nodeName} -o 
jsonpath='{.status.allocatable.memory}' | sed 's/Ki//')
+  local totalRamGB=$((${totalRamKi} / 1024 / 1024))
+
+  if [ "${totalRamGB}" -ge "${requiredRamGB}" ]; then
+    echo "[INFO] K8s RAM check passed: ${totalRamGB} GB available on node 
${nodeName}."
+  else
+    echo "[ERROR] K8s RAM check failed: Only ${totalRamGB} GB available on 
node ${nodeName}, ${requiredRamGB} GB or more required."
+    exit 1
+  fi
+}
+
+checkK8sCpu() {
+  local nodeName=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
+  local cpuCores=$(kubectl get node ${nodeName} -o 
jsonpath='{.status.allocatable.cpu}' | sed 's/m//')
+
+  if [ "${cpuCores}" -ge "${requiredCpuCores}" ]; then
+    echo "[INFO] K8s CPU check passed: ${cpuCores} cores available on node 
${nodeName}."
+  else
+    echo "[ERROR] K8s CPU check failed: Only ${cpuCores} cores available on 
node ${nodeName}, ${requiredCpuCores} cores or more required."
+    exit 1
+  fi
+}
+
+checkPortsInUse() {
+  local usedPorts=()
+  local availablePorts=()
+
+  for port in "${requiredPorts[@]}"; do
+    if [[ "$(uname)" == "Darwin" ]]; then
+      openPort=$(lsof -i :${port} -sTCP:LISTEN)
+    # Use sudo only when necessary
+    elif [[ "$(uname)" == "Linux" ]]; then
+      openPort=$(sudo lsof -i :${port} -sTCP:LISTEN)
+    fi
+
+    if [ -z "${openPort}" ]; then
+      availablePorts+=("${port}")
+    else
+      usedPorts+=("${port}")
+    fi
+  done
+
+  echo "[INFO] Port status check results:"
+
+  if [ ${#availablePorts[@]} -gt 0 ]; then
+    echo "[INFO] Available ports: ${availablePorts[*]}"
+  fi
+
+  if [ ${#usedPorts[@]} -gt 0 ]; then
+    echo "[ERROR] Ports in use: ${usedPorts[*]}"
+    echo "[ERROR] Please check the ports."
+    exit 1
+  fi
+}
+
+checkRuntime() {
+  runtime=""
+
+  echo "[INFO] Checking runtime: ${runtime}"
+  # Check if Docker is available
+  local dockerAvailable=false
+  if command -v docker >/dev/null 2>&1; then
+    dockerAvailable=true
+  fi
+
+  # Check if kubectl is available
+  local k8sAvailable=false
+  if command -v kubectl >/dev/null 2>&1; then
+    k8sAvailable=true
+  fi
+
+  # If no runtime is available
+  if [ "${dockerAvailable}" = false ] && [ "${k8sAvailable}" = false ]; then
+    echo "[ERROR] No runtime found. Please install Docker or Kubernetes."
     exit 1
   fi
+
+  # If both are available, let user choose
+  if [ "${dockerAvailable}" = true ] && [ "${k8sAvailable}" = true ]; then
+    read -p "Both Docker and K8s are available. Which runtime would you like 
to use? [docker/k8s] (default: docker): " choice
+
+    case "$choice" in
+    k8s)
+      echo "[INFO] Using K8s runtime."
+      runtime="k8s"
+      ;;
+    docker | "") # Empty input defaults to docker
+      echo "[INFO] Using Docker runtime."
+      runtime="docker"
+      ;;
+    *)
+      echo "[ERROR] Invalid choice. Using default: docker."
+      runtime="docker"
+      ;;
+    esac
+    return
+  fi
+
+  # If only Docker is available
+  if [ "${dockerAvailable}" = true ]; then
+    runtime="docker"
+    return
+  fi
+
+  # If only K8s is available
+  if [ "${k8sAvailable}" = true ]; then
+    runtime="k8s"
+    return
+  fi
+}
+
+checkCurrentRuntime() {
+  runtime=""
+
+  # Check if gravitino-playground is running in Docker
+  if command -v docker >/dev/null 2>&1; then
+    if docker compose ls | grep -q "${playgroundRuntimeName}"; then
+      echo "[INFO] gravitino-playground is running in Docker."
+      runtime="docker"
+      return
+    fi
+  fi
+
+  # Check if gravitino-playground is running in K8s
+  if command -v kubectl >/dev/null 2>&1; then
+    if kubectl get namespace "${playgroundRuntimeName}" >/dev/null 2>&1; then
+      if kubectl -n "${playgroundRuntimeName}" get pods | grep -q "Running"; 
then
+        echo "[INFO] gravitino-playground is running in Kubernetes."
+        runtime="k8s"
+        return
+      fi
+    fi
+  fi
 }
 
 start() {
-  echo "INFO: Starting the playground..."
+  echo "[INFO] Starting the playground..."
+  echo "[INFO] The playground requires ${requiredCpuCores} CPU cores, 
${requiredRamGB} GB of RAM, and ${requiredDiskSpaceGB} GB of disk storage to 
operate efficiently."
 
-  case "$runtime" in
+  checkCurrentRuntime
+  if [ -n "${runtime}" ]; then
+    echo "[ERROR] Playground is already running in ${runtime}. Please stop it 
first."
+    exit 1
+  fi
+
+  checkRuntime
+  checkPortsInUse
+
+  case "${runtime}" in
   k8s)
     testK8s
     checkHelm
+    checkK8sDisk
+    checkK8sRam
+    checkK8sCpu
     ;;
   docker)
     testDocker
-    checkCompose
-    ports=(8090 9001 3307 19000 19083 60070 13306 15342 18080 18888 19090 
13000)
-    for port in "${ports[@]}"; do
-      checkPortInUse ${port}
-    done
+    checkDockerCompose
+    checkDockerDisk
+    checkDockerRam
+    checkDockerCpu
     ;;
   esac
 
-  cd ${playground_dir}
-  echo "Preparing packages..."
+  cd ${playground_dir} || exit 1
+  echo "[INFO] Preparing packages..."
   ./init/spark/spark-dependency.sh
   ./init/gravitino/gravitino-dependency.sh
   ./init/jupyter/jupyter-dependency.sh
 
-  case "$runtime" in
+  case "${runtime}" in
   k8s)
-    helm upgrade --install gravitino-playground ./helm-chart/ \
-      --create-namespace --namespace gravitino-playground \
+    helm upgrade --install ${playgroundRuntimeName} ./helm-chart/ \
+      --create-namespace --namespace ${playgroundRuntimeName} \
       --set projectRoot=$(pwd)
     ;;
   docker)
-    logSuffix=$(date +%Y%m%d%H%m%s)
-    docker-compose up --detach

Review Comment:
   It's not about the OS; it's about the Docker version. Newer versions of 
Docker have a built-in `docker compose` command, whereas older versions do not. 
For older versions, you need to use `docker-compose`, which is no longer being 
actively updated.
   
   I added a function to automatically detect the appropriate Docker Compose 
command.
   
   **Reference**:
   [Docker Compose Migration 
Guide](https://docs.docker.com/compose/releases/migrate/)
   
   



-- 
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]

Reply via email to