This post digs into the bootstrap process of an IntelliJ-based IDE server inside a Gitpod workspace. It’s also a development note during the https://github.com/gitpod-io/gitpod/pull/10175 and helps me understand Gitpod workspace & IntelliJ Platform better.
Some background information:
TOC
Let’s start a Gitpod workspace from the JetBrains Gateway plugin and open up a terminal and check what's running inside the remote workspace:
gitpod /workspace/spring-petclinic (master) $ ps -afx -o pid,ppid,command
PID PPID COMMAND
1 0 supervisor init
36 1 supervisor run
50 36 \\_ /ide-desktop/status 24000 intellij Open in IntelliJ IDEA
1109 50 | \\_ /bin/sh /ide-desktop/backend/bin/remote-dev-server.sh run /workspace/spring-petclinic
1117 1109 | \\_ /bin/sh /ide-desktop/backend/plugins/remote-dev-server/bin/launcher.sh idea.sh IU IDEA idea -Xmx750m run /workspace/spring-petclinic
1236 1117 | \\_ /bin/sh /ide-desktop/backend/bin/idea.sh cwmHostNoLobby /workspace/spring-petclinic
1251 1236 | \\_ /lib64/ld-linux-x86-64.so.2 --library-path /ide-desktop/backend/plugins/remote-dev-server/selfcontained/lib /workspace/.cache (...truncated)
1353 1251 | \\_ /ide-desktop/backend/bin/fsnotifier
1389 1251 | \\_ /bin/bash --rcfile /ide-desktop/backend/plugins/terminal/jediterm-bash.in -i
2144 1251 | \\_ /bin/bash --rcfile /ide-desktop/backend/plugins/terminal/jediterm-bash.in -i
2404 2144 | \\_ gp tasks attach
...
This post covers the Remote part only, the Local part will be covered later
Supervisor
supervisor
is the init process and service manager for Gitpod workspace (similar to systemd
or tini
) and it runs as root
with PID1. supervisor
spawns and runs the ide process defined in a JSON config file (src file):
{
"entrypoint": "/ide-desktop/startup.sh",
"entrypointArgs": [ "{DESKTOPIDEPORT}", "intellij", "Open in IntelliJ IDEA" ],
"readinessProbe": {
"type": "http",
"http": {
"path": "/status"
}
}
}
The notable part is entrypoint
and readinessProbe
, which gives hints on how the IDE process is started and managed.
startup.sh
script (src file):
# kill background jobs when the script exits
trap "jobs -p | xargs -r kill" SIGINT SIGTERM EXIT
unset JAVA_TOOL_OPTIONS
exec /ide-desktop/status "$@"
A child process (/ide-desktop/status
) is spawned by exec
command, and it replaces the current shell. That's the reason why we didn't see start.sh
in the process tree. So let's move forward to /ide-desktop/status
.