diff --git a/provisioning/standalone/vscode/java/Dockerfile b/provisioning/standalone/vscode/java/Dockerfile index 89b401d181..20c01e6ede 100755 --- a/provisioning/standalone/vscode/java/Dockerfile +++ b/provisioning/standalone/vscode/java/Dockerfile @@ -1,33 +1,71 @@ -# syntax = edrevo/dockerfile-plus - -INCLUDE+ ./base/Dockerfile - - -# Setup permissions - -# Install required packages -RUN apt-get update && apt-get install -y openjdk-17-jdk openjdk-17-source maven --no-install-recommends - -# Install VS code extension -RUN code-server --extensions-dir ${VSCODE_SRV_DIR}/extensions --install-extension vscjava.vscode-java-pack - -# Remove apt and useless/dangerous packages -RUN apt-get clean && \ - apt-get remove --autoremove --purge -y apt sudo --allow-remove-essential - -COPY ./java/settings.json ${VSCODE_SRV_DIR}/data/User/settings.json - -RUN chown -R ${USER}:${USER} ${VSCODE_SRV_DIR} - -USER ${USER} - -WORKDIR ${VSCODE_SRV_DIR} - -# Forces Maven to preload dependencies -RUN --mount=type=bind,source=./java/triggerproject/,target=./triggerproject cd ${VSCODE_SRV_DIR}/triggerproject && mvn test && rm -rf /tmp/target - -RUN git config --global credential.helper 'cache --timeout=10800'&&\ - git config --global user.email student@crownlabs.polito.it &&\ - git config --global user.name crownlabs - -ENTRYPOINT [ "/start.sh" ] +# syntax = edrevo/dockerfile-plus + +INCLUDE+ ./base/Dockerfile + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget \ + ca-certificates \ + procps \ + tar \ + && rm -rf /var/lib/apt/lists/* + +RUN wget -q https://corretto.aws/downloads/latest/amazon-corretto-25-x64-linux-jdk.deb && \ + apt-get update && apt-get install -y ./amazon-corretto-25-x64-linux-jdk.deb && \ + rm -f ./amazon-corretto-25-x64-linux-jdk.deb && \ + rm -rf /var/lib/apt/lists/* + +ENV JAVA_HOME=/usr/lib/jvm/java-25-amazon-corretto +ENV PATH=${JAVA_HOME}/bin:${PATH} + +RUN update-alternatives --install /usr/bin/java java ${JAVA_HOME}/bin/java 200 && \ + update-alternatives --install /usr/bin/javac javac ${JAVA_HOME}/bin/javac 200 && \ + update-alternatives --set java ${JAVA_HOME}/bin/java && \ + update-alternatives --set javac ${JAVA_HOME}/bin/javac + +ARG MAVEN_VERSION=3.9.12 +ENV MAVEN_HOME=/opt/maven +ENV PATH=${MAVEN_HOME}/bin:${PATH} + +RUN wget -q -O /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz \ + https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/${MAVEN_VERSION}/apache-maven-${MAVEN_VERSION}-bin.tar.gz && \ + tar -xzf /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt && \ + rm -f /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz && \ + ln -s /opt/apache-maven-${MAVEN_VERSION} ${MAVEN_HOME} + +RUN apt-get update && apt-get purge -y \ + 'openjdk-*' \ + 'default-jre*' \ + 'default-jdk*' \ + && apt-get autoremove -y --purge && \ + rm -rf /var/lib/apt/lists/* + +RUN code-server --extensions-dir ${VSCODE_SRV_DIR}/extensions \ + --install-extension vscjava.vscode-java-pack \ + --install-extension vscode.simple-browser + +RUN apt-get clean && \ + dpkg -l | grep -q '^ii sudo ' && apt-get remove --autoremove --purge -y sudo || true && \ + apt-get remove --autoremove --purge -y apt --allow-remove-essential && \ + rm -rf /var/lib/apt/lists/* + +COPY ./java/settings.json ${VSCODE_SRV_DIR}/data/User/settings.json +COPY ./java/vscode/user-tasks.json ${VSCODE_SRV_DIR}/data/User/tasks.json + +COPY ./java/devtools/h2-console.sh /usr/local/bin/h2-console +RUN chmod +x /usr/local/bin/h2-console + +RUN chown -R ${USER}:${USER} ${VSCODE_SRV_DIR} + +USER ${USER} +WORKDIR ${VSCODE_SRV_DIR} + +RUN --mount=type=bind,source=./java/triggerproject/,target=./triggerproject \ + cd ${VSCODE_SRV_DIR}/triggerproject && mvn clean test && rm -rf /tmp/target + +RUN git config --global credential.helper 'cache --timeout=10800' && \ + git config --global user.email student@crownlabs.polito.it && \ + git config --global user.name crownlabs + +ENTRYPOINT [ "/start.sh" ] diff --git a/provisioning/standalone/vscode/java/devtools/h2-console.sh b/provisioning/standalone/vscode/java/devtools/h2-console.sh new file mode 100644 index 0000000000..c72d4f1f0d --- /dev/null +++ b/provisioning/standalone/vscode/java/devtools/h2-console.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +set -euo pipefail + +H2_VERSION="${H2_VERSION:-2.3.232}" +M2="${HOME}/.m2/repository" +JAR_DIR="${M2}/com/h2database/h2/${H2_VERSION}" +JAR="${JAR_DIR}/h2-${H2_VERSION}.jar" + +PORT="${H2_PORT:-8082}" +PID_FILE="${HOME}/.h2-console.pid" +LOG_FILE="${HOME}/.h2-console.log" + +ensure_jar() { + if [ ! -f "${JAR}" ]; then + mvn -q dependency:get -Dartifact="com.h2database:h2:${H2_VERSION}" -Dtransitive=false >/dev/null + fi +} + +pid_running() { + # true se il PID nel file esiste ed è un processo Java H2 + [ -f "${PID_FILE}" ] || return 1 + local pid; pid="$(cat "${PID_FILE}")" || return 1 + [ -d "/proc/${pid}" ] || return 1 + # controllo grossolano che sia il nostro jar + tr -d '\0' <"/proc/${pid}/cmdline" 2>/dev/null | grep -q "h2-${H2_VERSION}.jar" || return 1 + return 0 +} + +start() { + ensure_jar + + if pid_running; then + echo "H2 Console already running on port ${PORT}" + echo "/proxy/${PORT}/" + exit 0 + fi + + # se la porta è occupata, H2 potrebbe crashare: controlla prima + if ss -lnt 2>/dev/null | awk '{print $4}' | grep -q ":${PORT}$"; then + echo "ERROR: port ${PORT} is already in use." + ss -lnt | (echo "Listening ports:"; cat -) | sed 's/^/ /' + exit 1 + fi + + # avvia e stacca davvero il processo, logga su file + nohup java -jar "${JAR}" \ + -web -webPort "${PORT}" -webAllowOthers \ + >> "${LOG_FILE}" 2>&1 & + + echo $! > "${PID_FILE}" + sleep 1 + + if pid_running; then + echo "H2 Console started on port ${PORT}" + echo "/proxy/${PORT}/" + exit 0 + else + echo "ERROR: H2 did not stay up. Log tail:" + tail -n 50 "${LOG_FILE}" || true + # pulizia + rm -f "${PID_FILE}" || true + exit 1 + fi +} + +stop() { + if ! pid_running; then + echo "H2 Console not running on port ${PORT}" + exit 0 + fi + kill "$(cat "${PID_FILE}")" 2>/dev/null || true + sleep 0.5 + if pid_running; then + kill -9 "$(cat "${PID_FILE}")" 2>/dev/null || true + fi + rm -f "${PID_FILE}" || true + echo "H2 Console stopped on port ${PORT}" +} + +status() { + if pid_running; then + echo "H2 Console is RUNNING on port ${PORT}" + echo "/proxy/${PORT}/" + else + echo "H2 Console is STOPPED" + # Piccolo aiuto: se il log esiste e ha errori recenti, mostra le ultime righe + if [ -f "${LOG_FILE}" ]; then + echo "--- recent log ---" + tail -n 10 "${LOG_FILE}" || true + fi + fi +} + +case "${1:-}" in + start) start ;; + stop) stop ;; + status) status ;; + *) echo "Usage: $0 {start|stop|status}"; exit 1 ;; +esac diff --git a/provisioning/standalone/vscode/java/img/forward.png b/provisioning/standalone/vscode/java/img/forward.png new file mode 100644 index 0000000000..32cb9100e4 Binary files /dev/null and b/provisioning/standalone/vscode/java/img/forward.png differ diff --git a/provisioning/standalone/vscode/java/img/h2.png b/provisioning/standalone/vscode/java/img/h2.png new file mode 100644 index 0000000000..74951aad8a Binary files /dev/null and b/provisioning/standalone/vscode/java/img/h2.png differ diff --git a/provisioning/standalone/vscode/java/img/port.png b/provisioning/standalone/vscode/java/img/port.png new file mode 100644 index 0000000000..1ca1e18258 Binary files /dev/null and b/provisioning/standalone/vscode/java/img/port.png differ diff --git a/provisioning/standalone/vscode/java/img/run.png b/provisioning/standalone/vscode/java/img/run.png new file mode 100644 index 0000000000..db505d55c1 Binary files /dev/null and b/provisioning/standalone/vscode/java/img/run.png differ diff --git a/provisioning/standalone/vscode/java/img/start.png b/provisioning/standalone/vscode/java/img/start.png new file mode 100644 index 0000000000..79701915d0 Binary files /dev/null and b/provisioning/standalone/vscode/java/img/start.png differ diff --git a/provisioning/standalone/vscode/java/prewarmDockerfile b/provisioning/standalone/vscode/java/prewarmDockerfile new file mode 100644 index 0000000000..6716e01081 --- /dev/null +++ b/provisioning/standalone/vscode/java/prewarmDockerfile @@ -0,0 +1,88 @@ +# syntax = edrevo/dockerfile-plus + +INCLUDE+ ./base/Dockerfile + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget \ + ca-certificates \ + procps \ + tar \ + coreutils \ + && rm -rf /var/lib/apt/lists/* + +RUN wget -q https://corretto.aws/downloads/latest/amazon-corretto-25-x64-linux-jdk.deb && \ + apt-get update && apt-get install -y ./amazon-corretto-25-x64-linux-jdk.deb && \ + rm -f ./amazon-corretto-25-x64-linux-jdk.deb && \ + rm -rf /var/lib/apt/lists/* + +ENV JAVA_HOME=/usr/lib/jvm/java-25-amazon-corretto +ENV PATH=${JAVA_HOME}/bin:${PATH} + +RUN update-alternatives --install /usr/bin/java java ${JAVA_HOME}/bin/java 200 && \ + update-alternatives --install /usr/bin/javac javac ${JAVA_HOME}/bin/javac 200 && \ + update-alternatives --set java ${JAVA_HOME}/bin/java && \ + update-alternatives --set javac ${JAVA_HOME}/bin/javac + +ARG MAVEN_VERSION=3.9.12 +ENV MAVEN_HOME=/opt/maven +ENV PATH=${MAVEN_HOME}/bin:${PATH} + +RUN wget -q -O /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz \ + https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/${MAVEN_VERSION}/apache-maven-${MAVEN_VERSION}-bin.tar.gz && \ + tar -xzf /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt && \ + rm -f /tmp/apache-maven-${MAVEN_VERSION}-bin.tar.gz && \ + ln -s /opt/apache-maven-${MAVEN_VERSION} ${MAVEN_HOME} + +RUN apt-get update && apt-get purge -y \ + 'openjdk-*' \ + 'default-jre*' \ + 'default-jdk*' \ + && apt-get autoremove -y --purge && \ + rm -rf /var/lib/apt/lists/* + +RUN code-server --extensions-dir ${VSCODE_SRV_DIR}/extensions \ + --install-extension vscjava.vscode-java-pack \ + --install-extension vscode.simple-browser + +RUN apt-get clean && \ + dpkg -l | grep -q '^ii sudo ' && apt-get remove --autoremove --purge -y sudo || true && \ + apt-get remove --autoremove --purge -y apt --allow-remove-essential && \ + rm -rf /var/lib/apt/lists/* + +COPY ./java/settings.json ${VSCODE_SRV_DIR}/data/User/settings.json +COPY ./java/vscode/user-tasks.json ${VSCODE_SRV_DIR}/data/User/tasks.json + +COPY ./java/devtools/h2-console.sh /usr/local/bin/h2-console +RUN chmod +x /usr/local/bin/h2-console + +RUN chown -R ${USER}:${USER} ${VSCODE_SRV_DIR} + +USER ${USER} +WORKDIR ${VSCODE_SRV_DIR} + +RUN mkdir -p ${VSCODE_SRV_DIR}/workspace/prewarm + +RUN --mount=type=bind,source=./java/triggerproject/,target=./triggerproject \ + cd ${VSCODE_SRV_DIR}/triggerproject && \ + mvn -q -DskipTests package && \ + mvn clean test && \ + rm -rf /tmp/target + +RUN --mount=type=bind,source=./java/triggerproject/,target=${VSCODE_SRV_DIR}/workspace/prewarm/triggerproject \ + timeout 180s code-server \ + --user-data-dir ${VSCODE_SRV_DIR}/data \ + --extensions-dir ${VSCODE_SRV_DIR}/extensions \ + --disable-telemetry \ + --bind-addr 127.0.0.1:0 \ + ${VSCODE_SRV_DIR}/workspace/prewarm/triggerproject \ + || true + +RUN rm -rf ${VSCODE_SRV_DIR}/workspace/prewarm + +RUN git config --global credential.helper 'cache --timeout=10800'&&\ + git config --global user.email student@crownlabs.polito.it &&\ + git config --global user.name crownlabs + +ENTRYPOINT [ "/start.sh" ] diff --git a/provisioning/standalone/vscode/java/readme.md b/provisioning/standalone/vscode/java/readme.md new file mode 100644 index 0000000000..032c3957e7 --- /dev/null +++ b/provisioning/standalone/vscode/java/readme.md @@ -0,0 +1,51 @@ +# H2 Console in VS Code (code-server) + +You can manage the **H2 Console** directly from VS Code using preconfigured tasks. +The **in-memory database** (`jdbc:h2:mem:...`) is **not easily inspectable** via the console. Only **file-based databases** are easily accessible. + +## Available Tasks + +- `h2:start` → starts the H2 Console (web) on port **8082** +- `h2:status` → shows whether the console is running +- `h2:stop` → stops the console + +## How to use the H2 Console + +1. Open the Command Palette (`Ctrl+Shift+P`) and select **Tasks: Run Task**. + ![Command Palette → Run Task](./img/run.png) + +2. From the list of available tasks, choose **h2:start**. + ![Run h2:start](./img/start.png) + +3. When the task runs, VS Code automatically **forwards port 8082**. + ![Port Forwarding](./img/forward.png) + +4. Open the **Ports** tab at the bottom of VS Code. Locate **port 8082** and click the **globe icon**. + ![Ports tab](./img/port.png) + +5. A new browser tab will open with the H2 Console web UI. + ![H2 Console Web UI](./img/h2.png) + +## Connecting from the H2 Console + +- **File-based database** (recommended for inspection): + +``` +JDBC URL: jdbc:h2:file:./data/socialdb +User: sa +Password: (empty) +``` + +Depending on how the project was cloned on the VS Code server, the database URL may need the **path with the project directory**. For example: + +``` +jdbc:h2:file:./lab5-social/data/socialdb +``` + +- **In-memory database** + Not accessible from the console. It is used only for tests. + +## Notes + +- You do not need to download or manage the H2 jar manually: the tasks handle it. +- Port forwarding is automatic when you run `h2:start`. diff --git a/provisioning/standalone/vscode/java/readme_it.md b/provisioning/standalone/vscode/java/readme_it.md new file mode 100644 index 0000000000..2a501afc7f --- /dev/null +++ b/provisioning/standalone/vscode/java/readme_it.md @@ -0,0 +1,51 @@ +# Console H2 in VS Code (code-server) + +Puoi gestire la **H2 Console** direttamente da VS Code con i task già configurati. +Il **database in-memory** (`jdbc:h2:mem:...`) **non è consultabile facilmente** dalla console. Solo i **database su file** sono facilmente accessibili. + +## Task disponibili + +- `h2:start` → avvia la H2 Console (web) sulla porta **8082** +- `h2:status` → mostra se la console è in esecuzione +- `h2:stop` → arresta la console + +## Come usare la Console H2 + +1. Apri la Command Palette (`Ctrl+Shift+P`) e scegli **Tasks: Run Task**. + ![Command Palette → Run Task](./img/run.png) + +2. Dall’elenco dei task disponibili seleziona **h2:start**. + ![Lanciare h2:start](./img/start.png) + +3. Quando il task parte, VS Code esegue automaticamente il **forward della porta 8082**. + ![Port Forwarding](./img/forward.png) + +4. Apri il tab **Ports** in basso in VS Code. Trova la **porta 8082** e clicca sull’**icona del globo**. + ![Tab Ports](./img/port.png) + +5. Si aprirà una nuova scheda del browser con l’interfaccia web della console H2. + ![Console H2 Web](./img/h2.png) + +## Connessione dalla Console H2 + +- **Database su file** (consigliato per l’ispezione): + +``` +JDBC URL: jdbc:h2:file:./data/socialdb +User: sa +Password: (empty) +``` + +In base a come il progetto è stato clonato sul server VS Code, l’URL del database potrebbe richiedere il **percorso contenente la cartella del progetto**. Esempio: + +``` +jdbc:h2:file:./lab5-social/data/socialdb +``` + +- **Database in-memory** + Non è consultabile dalla console. È usato solo nei test. + +## Note + +- Non serve scaricare o gestire manualmente il jar di H2: ci pensano i task. +- Il forward della porta avviene automaticamente quando esegui `h2:start`. diff --git a/provisioning/standalone/vscode/java/settings.json b/provisioning/standalone/vscode/java/settings.json index c1d4557172..50b4ada07e 100755 --- a/provisioning/standalone/vscode/java/settings.json +++ b/provisioning/standalone/vscode/java/settings.json @@ -4,5 +4,16 @@ "workbench.startupEditor": "none", "window.menuBarVisibility": "visible", "java.project.importHint": false, - "redhat.telemetry.enabled": false -} \ No newline at end of file + "redhat.telemetry.enabled": false, + "java.configuration.runtimes": [{ + "name": "JavaSE-25", + "path": "/usr/lib/jvm/java-25-amazon-corretto", + "default": true + }], + "java.jdt.ls.java.home": "/usr/lib/jvm/java-25-amazon-corretto", + "maven.terminal.useJavaHome": true, + "java.import.maven.java.home": "/usr/lib/jvm/java-25-amazon-corretto", + "java.configuration.enablePreview": true, + "extensions.autoCheckUpdates": false, + "extensions.autoUpdate": false +} diff --git a/provisioning/standalone/vscode/java/triggerproject/pom.xml b/provisioning/standalone/vscode/java/triggerproject/pom.xml index 48b0cb82a9..8fe44d1def 100755 --- a/provisioning/standalone/vscode/java/triggerproject/pom.xml +++ b/provisioning/standalone/vscode/java/triggerproject/pom.xml @@ -8,16 +8,35 @@ UTF-8 + 25 + 25 + 25 + + + + + org.junit + junit-bom + 5.11.4 + pom + import + + + - - - junit - junit - 4.13.2 - test - + + org.junit.jupiter + junit-jupiter + test + + + com.h2database + h2 + 2.3.232 + runtime + @@ -35,43 +54,11 @@ - maven-compiler-plugin - 3.8.1 - - 17 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.0 - - - org.apache.maven.surefire - surefire-junit4 - 2.22.0 - - - - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - - prepare-agent - - - - report - test - - report - - - + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + \ No newline at end of file diff --git a/provisioning/standalone/vscode/java/triggerproject/test/MainTest.java b/provisioning/standalone/vscode/java/triggerproject/test/MainTest.java index f530c6b752..a6eba15edf 100755 --- a/provisioning/standalone/vscode/java/triggerproject/test/MainTest.java +++ b/provisioning/standalone/vscode/java/triggerproject/test/MainTest.java @@ -1,6 +1,6 @@ -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class MainTest { @Test diff --git a/provisioning/standalone/vscode/java/vscode/user-tasks.json b/provisioning/standalone/vscode/java/vscode/user-tasks.json new file mode 100644 index 0000000000..8daaa0da9d --- /dev/null +++ b/provisioning/standalone/vscode/java/vscode/user-tasks.json @@ -0,0 +1,8 @@ +{ + "version": "2.0.0", + "tasks": [ + { "label": "h2:start", "type": "shell", "command": "h2-console start", "problemMatcher": [] }, + { "label": "h2:stop", "type": "shell", "command": "h2-console stop", "problemMatcher": [] }, + { "label": "h2:status", "type": "shell", "command": "h2-console status", "problemMatcher": [] } + ] +}