| name | pixels-install |
| description | Guide, execute, and verify a basic Pixels deployment from docs/INSTALL.md using bundled helper scripts. Use when the user asks to install, configure, resume, validate, or troubleshoot a basic Pixels deployment or optional Trino setup. |
pixels-install
Help the user install a basic Pixels deployment according to docs/INSTALL.md.
Treat docs/INSTALL.md as the source of truth for the installation flow. Use the bundled scripts only as helpers for deterministic, repeatable, or easy-to-misconfigure steps. Do not treat this skill as a one-shot unattended installer.
Resource Paths
- Skill directory: use the directory containing this
SKILL.md.
- Helper scripts:
scripts/.
- Shared helper scripts:
shared-scripts/.
- Runtime state:
STATE_DIR when set; otherwise the scripts resolve it to .agents/state/pixels-install for project use or $HOME/.agents/state/pixels-install for global installs.
- Pixels source tree:
REPO_ROOT when set; otherwise scripts try to discover the current Git repository root and fail with a clear message if they cannot.
Helper scripts
Use these helpers when they directly fit the current environment and the user-approved goal:
prepare_deployment.sh: collect and confirm the Pixels deployment topology before any install writes to disk. With no node arguments it prompts for single-node vs. cluster, PIXELS_HOME, the coordinator node, whether the coordinator also runs a worker, and worker nodes; with arguments, use --coordinator <ssh_target,host_ip,host_name,host_user,host_port> plus repeated --worker <...> (legacy --node still works). Writes STATE_DIR/deployment.env and optionally delegates SSH setup to shared-scripts/setup_cluster.sh. In non-interactive mode, set CONFIRM_PIXELS_DEPLOYMENT=true only after the user has reviewed the chosen topology and paths.
check_prerequisites.sh: validate OS, architecture, memory, disk, ports, host resolution, privilege, and optional SSH reachability. Runs every check and exits with a structured === check_prerequisites result === summary (one ok|warn|fail|skip <check>: <detail> line per check, plus a final summary: ok=N warn=N fail=N skip=N status=pass|fail line) instead of stopping at the first failure, so a single run shows every problem at once.
install_jdk.sh: install a Zulu OpenJDK build (default JDK 23) matching the server's CPU architecture (x86_64 or aarch64) under ~/opt, and persist JAVA_HOME only into the current user's shell profile. Looks for a JDK that already satisfies JDK_VERSION first — checking JAVA_HOME if set, otherwise resolving whatever java is on PATH (e.g. an apt-installed JDK that never exported JAVA_HOME) — and if one is found, skips the download entirely and only fixes up the environment variable to point at it. Only downloads/installs a fresh Zulu build when nothing on the system satisfies the version requirement. Falls back to pointing at the manual .deb method in docs/INSTALL.md if the Azul metadata API lookup fails.
install_maven.sh: install or validate Maven 3.8+ (default pinned version 3.9.8; override with MAVEN_VERSION only if the user explicitly asks for a different one) when the current Maven is missing or incompatible with the selected JDK. Same "skip if already satisfied" logic as install_jdk.sh: if an existing mvn (from apt, a prior manual install, etc.) already meets the minimum version, it reuses that installation's home directory instead of downloading anything. Fresh installs go into ~/opt/apache-maven-<version> with a ~/opt/maven symlink, never into /opt.
install_mysql.sh: install MySQL, then interactively confirm the root password and the pixels metadata-DB-user password (default password for both, never applied silently), create the pixels_metadata database/user, and load scripts/sql/metadata_schema.sql from the Pixels source tree. It validates DB/user identifiers, quotes SQL values, avoids putting the root password in command-line arguments, and writes shell-quoted STATE_DIR/deployment.secrets.env (mode 600) so the confirmed credentials flow into configure_pixels.sh automatically.
install_etcd.sh: install and optionally start the bundled etcd 3.3.4 package under ~/opt. Always fixes the shipped conf.yml's hardcoded /home/ubuntu/... data-dir to the real install path. By default (ETCD_ALLOW_REMOTE=false) it keeps etcd localhost-only. For a cluster, set ETCD_ALLOW_REMOTE=true only after confirming private networking/security-group rules; the script then requires CONFIRM_ETCD_REMOTE_ACCESS=true, ASSUME_YES=true, or an interactive confirmation before binding the client/peer listeners for remote access. Can also install and enable a systemd unit so etcd survives reboots and restarts on failure, but only after asking — it never installs this silently. Leave INSTALL_ETCD_SYSTEMD_SERVICE unset to be prompted interactively ([y/N], defaults to no); set it to true/false to answer non-interactively once the user has actually agreed, or ASSUME_YES=true to answer yes to this and other yes/no prompts. Declining (or running non-interactively with no explicit answer) just skips the unit — etcd still starts, as a manually backgrounded process instead. Falls back the same way when systemctl isn't available at all. Restarts/re-enables the installed service automatically when the config actually changed.
build_install_pixels.sh: build and install Pixels into the confirmed PIXELS_HOME from deployment.env, then add the MySQL JDBC connector. It prints the repo, deployment file, and install target before running; in non-interactive mode, set CONFIRM_PIXELS_INSTALL=true only after the user confirms the target. If you must bypass the prepared deployment file, pass USE_DEPLOYMENT_FILE=false PIXELS_HOME=<path> explicitly. AUTO_CONFIRM_INSTALL (default true) auto-answers install.sh's prompts only when that is safe; if PIXELS_HOME/etc/pixels.properties or pixels-cpp.properties already exist, it forces the interactive path instead, because install.sh would otherwise prompt to add/remove config options or overwrite pixels-cpp.properties outright — exactly what Claude agent/SKILL.md say not to do without the user's say-so.
configure_pixels.sh: update PIXELS_HOME/etc/pixels.properties after database, etcd, host, port, topology, and path values are known. Automatically sources deployment.env and deployment.secrets.env (if present), so PIXELS_HOME, coordinator service hosts, worker names, and MySQL credentials stay in sync with what the earlier scripts confirmed. It writes $PIXELS_HOME/etc/workers from PIXELS_WORKERS by default. It fails instead of silently writing the documented default DB password unless METADATA_DB_PASSWORD is explicit or ALLOW_DEFAULT_METADATA_PASSWORD=true is set.
install_shell_helpers.sh: optional convenience step that asks first before writing shell functions. By default it installs only start_pixels/stop_pixels/restart_pixels on the Pixels coordinator recorded in deployment.env; when invoked from another host, it copies a minimal installer over SSH and writes the coordinator user's ~/.pixels-shell-helpers.sh plus shell-profile source line there. These wrap $PIXELS_HOME/sbin/start-pixels.sh and $PIXELS_HOME/sbin/stop-pixels.sh. Set PIXELS_SHELL_HELPERS_TARGET=local only when the user explicitly wants the functions on the current host. Leave INSTALL_PIXELS_SHELL_HELPERS unset to be prompted [y/N]; set true/false to answer non-interactively once the user has actually agreed, or ASSUME_YES=true.
smoke_test.sh: verify the installed layout, configuration, Java (CHECK_JAVA=true), metadata access, etcd health, Pixels topology (deployment.env plus $PIXELS_HOME/etc/workers), core service ports (CHECK_CORE_SERVICES=true), $PIXELS_HOME/logs error patterns (CHECK_PIXELS_LOGS=true), and basic CLI behavior when applicable. It also checks Trino layout/catalog files when CHECK_TRINO=true and trino-deployment.env is present, can separately validate the lightweight Trino-side Pixels client config plus shell-profile PIXELS_HOME/PIXELS_CONFIG exports (CHECK_TRINO_PIXELS_CLIENT=true) without requiring a full Pixels runtime layout (CHECK_PIXELS_LAYOUT=false), can check Trino launcher status across the recorded cluster (CHECK_TRINO_CLUSTER_STATUS=true), checks that Trino logs did not fall back to classpath pixels.properties (CHECK_TRINO_LOGS=true), waits for /v1/info to report starting=false (CHECK_TRINO_READY=true), and can run trino --catalog pixels --execute "SHOW SCHEMAS" (CHECK_TRINO_CLI=true). SHOW SCHEMAS only needs to succeed; an empty Pixels catalog is expected before data is loaded. Same structured-summary behavior as check_prerequisites.sh above.
progress.sh: records which of skill.yaml's phases have actually completed, in STATE_DIR/progress.env. progress.sh mark <phase> [note] after a phase succeeds, progress.sh show to see what's already done, progress.sh is-done <phase> to check one phase, progress.sh reset to start over. Exists so a session interrupted partway through a multi-phase install can resume from the actual state instead of guessing or re-running completed steps.
build_pixels_trino_artifacts.sh: optional Trino-prep step. Builds pixelsdb/pixels-trino once on the local machine where Pixels modules have already been mvn installed, copies pixels-trino-connector-*.zip and pixels-trino-listener-*.zip into STATE_DIR/pixels-trino-artifacts/, and writes STATE_DIR/pixels-trino-artifacts.env for install_trino_cluster.sh. In non-interactive mode, set CONFIRM_PIXELS_TRINO_ARTIFACTS=true only after the user confirms the checkout/artifact paths.
install_trino_cluster.sh: run on the coordinator after prepare_trino_cluster.sh. It prints and confirms the Trino deployment file, version, install parent, home link, data dir, coordinator, coordinator scheduling mode, workers, Trino-side Pixels client home/config source, Pixels service endpoints, and any prebuilt pixels-trino plugin zips before installing; in non-interactive mode, set CONFIRM_TRINO_CLUSTER_INSTALL=true only after the user confirms the fan-out. Installs Trino locally for the coordinator's own role, then dispatches install_trino.sh on every worker in parallel over the coordinator -> worker passwordless SSH that prepare_trino_cluster.sh already set up, instead of requiring the user or skill to copy the same command and run it by hand once per node. Copies the current STATE_DIR/trino-deployment.env to each worker first (workers don't need a shared filesystem). If PIXELS_TRINO_CONNECTOR_ZIP and PIXELS_TRINO_LISTENER_ZIP are provided, or STATE_DIR/pixels-trino-artifacts.env exists from build_pixels_trino_artifacts.sh, it also copies a minimal installer plus those prebuilt plugin zips to each worker, so workers do not need a Pixels checkout or Maven build. It also copies the selected Trino-side Pixels client config (TRINO_PIXELS_CONFIG_SOURCE, defaulting to $PIXELS_HOME/etc/pixels.properties when available) and lets install_trino.sh rewrite service endpoints through TRINO_PIXELS_* variables. Remote Trino nodes receive Trino, the two pixels-trino plugin zips, Trino catalog/listener configs, and a lightweight ~/opt/pixels/etc/pixels.properties client config — not a full Pixels installation. Emits the same structured per-node summary as smoke_test.sh/check_prerequisites.sh, with a log file per node under STATE_DIR/logs/ for diagnosing any failure.
prepare_trino_cluster.sh: collects and confirms the Trino topology and install locations: one coordinator, zero or more workers, whether the coordinator also accepts scheduled work, Trino version, HTTP port, install parent, home symlink/current path, and data directory. With no node arguments it prompts interactively; with arguments, use --coordinator <ssh_target,host_ip,host_name,host_user,host_port> plus repeated --worker <...>. Writes STATE_DIR/trino-deployment.env. Optionally delegates to shared-scripts/setup_cluster.sh (--setup-ssh true) so the coordinator and every worker can passwordlessly SSH into each other, which the cluster shell helpers below depend on. In non-interactive mode, set CONFIRM_TRINO_DEPLOYMENT=true only after the user has reviewed the topology and paths.
install_trino.sh: installs Trino (per the 466 deployment docs) on the current node only — run it once per node in the cluster, it does not SSH anywhere itself (use install_trino_cluster.sh to fan it out across the cluster instead of running it by hand on each node). It reads trino-deployment.env, validates this node's role (coordinator or worker) and the coordinator host, and confirms the role plus install/data paths before writing files; in non-interactive mode, set CONFIRM_TRINO_INSTALL=true only after the user confirms the target. Downloads trino-server-<version>.tar.gz (default 466) from Maven Central into the confirmed install parent with the confirmed home symlink for version-switch-friendly installs. Writes etc/node.properties (node.data-dir under the confirmed data dir, outside the versioned install dir so it survives version switches; node.id generated once and preserved across re-runs), etc/jvm.config (official defaults plus the two --add-opens flags pixels-trino requires), etc/log.properties, and etc/config.properties — discovery.uri always points at the coordinator's real IP from trino-deployment.env, never localhost; this node's coordinator/worker role is read from trino-deployment.env or inferred from this host's own IPs, overridable with TRINO_ROLE. For pixelsdb/pixels-trino, either clones/builds locally (requires Pixels already mvn installed locally and JDK 23) or consumes prebuilt PIXELS_TRINO_CONNECTOR_ZIP and PIXELS_TRINO_LISTENER_ZIP so remote Trino nodes do not need a Pixels checkout or Maven build. Installs both documented plugins by directly unzipping their zips under plugin/ and preserving the zip's versioned top-level directory names, e.g. pixels-trino-connector-0.2.0-SNAPSHOT and pixels-trino-listener-0.2.0-SNAPSHOT; do not rename them to unversioned stable directories. Writes Trino's catalog file etc/catalog/pixels.properties with only catalog properties (connector.name=pixels, cloud.function.switch=off, clean.intermediate.result=true by default). This catalog file is not the same thing as Pixels' client/runtime config file $PIXELS_HOME/etc/pixels.properties; never copy Pixels runtime properties such as metadata.server.host or etcd.hosts into the Trino catalog. Also prepares the Trino-side lightweight Pixels client home (TRINO_PIXELS_HOME, default $HOME/opt/pixels, not $HOME/opt/pixels/etc) with etc/pixels.properties and logs/, then writes export PIXELS_HOME=... and export PIXELS_CONFIG=$PIXELS_HOME/etc/pixels.properties directly into the current user's bash/zsh profile (and mirrors them into STATE_DIR/toolchain.env for later helper-script processes). It does not create ~/.pixels-trino-env.sh. Use TRINO_PIXELS_CONFIG_SOURCE to copy a known-good Pixels config into that client home, and use TRINO_PIXELS_METADATA_SERVER_HOST, TRINO_PIXELS_TRANS_SERVER_HOST, TRINO_PIXELS_QUERY_SCHEDULE_SERVER_HOST, and TRINO_PIXELS_ETCD_HOSTS to rewrite endpoints so Trino nodes do not fall back to localhost. Writes etc/event-listener.properties for the listener and defaults its log directory to a Trino-side path under the install parent unless PIXELS_TRINO_LISTENER_LOG_DIR is set. Best-effort installs trino-cli into bin/trino.
install_trino_shell_helpers.sh: optional, and always asks first, because it bakes a specific list of remote hostnames (from trino-deployment.env) into a shell profile and assumes passwordless SSH between them is already set up. By default it installs only start_trino_cluster/stop_trino_cluster/restart_trino_cluster/trino_cli on the Trino coordinator recorded in trino-deployment.env; when invoked from another host, it copies a minimal installer over SSH and writes the coordinator user's ~/.trino-shell-helpers.sh plus shell-profile source line there. In the generated functions, the coordinator is always operated locally and every worker over SSH. stop_trino_cluster stops workers before the coordinator; restart_trino_cluster runs stop then start. The generated start/stop/restart/client helpers explicitly export PIXELS_HOME and PIXELS_CONFIG before invoking Trino locally or over SSH, without wrapping or replacing Trino's bin/launcher. Set TRINO_SHELL_HELPERS_TARGET=local only when the user explicitly wants the functions on the current host. Leave INSTALL_TRINO_SHELL_HELPERS unset to be prompted [y/N]; set true/false to answer non-interactively once the user has actually agreed, or ASSUME_YES=true.
All of these scripts anchor paths on $HOME (e.g. ~/opt/...) and detect the
current login shell ($SHELL) to pick ~/.bashrc or ~/.zshrc before
persisting any export. Never assume the deployment user is named pixels
or ubuntu, and never write environment variables into a global file such
as /etc/environment — scripts/lib/shell_env.sh
centralizes this logic and is shared by install_jdk.sh, install_maven.sh,
install_etcd.sh, build_install_pixels.sh, configure_pixels.sh,
check_prerequisites.sh, smoke_test.sh, install_trino.sh,
install_trino_cluster.sh, prepare_trino_cluster.sh,
build_pixels_trino_artifacts.sh,
install_trino_shell_helpers.sh, and progress.sh. It also defines the
structured-result (result_record/result_emit_summary) and phase-checkpoint
(mark_phase_done/phase_is_done/print_progress) helpers described above.
Each install_*.sh script runs as its own process, so exporting a variable
in one script does not make it visible to the next one. docs/INSTALL.md's
own walkthrough handles this by running source ~/.bashrc right after
appending to it, but sourcing the user's real rc file from a non-interactive
script is unreliable (Ubuntu's default ~/.bashrc returns immediately for
non-interactive shells, before reaching anything appended at the bottom). So
in addition to persisting into the user's real shell profile,
shell_env.sh also mirrors JAVA_HOME/MAVEN_HOME/ETCD/PIXELS_HOME/PIXELS_CONFIG
into a small STATE_DIR/toolchain.env file with no such guard,
and every script sources it (load_toolchain_env) at startup. This means
running install_jdk.sh then install_maven.sh as two separate tool calls
still works without the skill needing to manually re-source anything in
between — but if you set any of these variables yourself before running a
step, your explicit environment variable still wins.
The skill may run simple commands from docs/INSTALL.md directly when that is clearer than adding another wrapper script.
Workflow
The phase sequence is fixed in skill.yaml's phases list — this section is decision guidance for each phase, not a second copy of that ordering. Before doing anything else, run scripts/progress.sh show to see which phases (if any) already completed in a prior session, and skip straight to the first phase that is not yet marked done instead of re-deriving state from scratch or blindly redoing finished work. After each phase actually succeeds, run scripts/progress.sh mark <phase> (phase names match skill.yaml) so a later session — or this one, after a long gap — can pick up correctly.
- discover_install_target: clarify single node vs. cluster,
PIXELS_HOME, coordinator vs. worker roles, storage/query engine needs, whether to start services now, and whether optional components are in scope. Determine the actual login user (whoami) and home directory ($HOME) instead of assuming pixels or ubuntu; every path this skill writes is anchored on that $HOME. Do not proceed with defaults until the user has confirmed the topology and install locations.
- check_prerequisites: run
check_prerequisites.sh and read its full structured summary before deciding what to install — see "Failure Handling" below for what to do with anything it reports as fail.
- prepare_deployment_config: run for both single-node and cluster deployments so later scripts read the same confirmed
PIXELS_HOME, coordinator service hosts, and worker list from deployment.env. Prefer prepare_deployment.sh with no node arguments for an interactive prompt, or explicit --coordinator ... --worker ... arguments when the user has already provided the topology.
- install_or_verify_jdk:
install_jdk.sh already skips the download when anything on the system (apt-installed JDK, a previous run, etc.) satisfies JDK_VERSION; it only selects and installs a Zulu build under ~/opt when nothing qualifies. JDK 23+ is required for the documented Pixels + Trino 466 path. Ask before installing a downloaded JDK package.
- install_or_verify_maven:
install_maven.sh has the same "skip if already satisfied" behavior for Maven 3.8+ (default pinned 3.9.8, only overridden if the user asks). Ensure mvn -v ends up using the selected JDK.
- install_or_verify_mysql / install_or_verify_etcd: only after the user confirms credentials/ports (see Guardrails — never apply the default MySQL password silently);
install_etcd.sh keeps localhost-only by default, asks before remote etcd access, and asks before installing its systemd auto-start unit.
- build_install_pixels: install Pixels from the repository into the confirmed
PIXELS_HOME from deployment.env and place the MySQL JDBC connector under PIXELS_HOME/lib. In a Pixels cluster, worker nodes need this full installed PIXELS_HOME runtime layout to run $PIXELS_HOME/bin/start-daemon.sh worker, but they do not need to rebuild Pixels locally; build/install once, then distribute the installed PIXELS_HOME to worker nodes (for example with $PIXELS_HOME/sbin/rsync-cluster.sh after etc/workers is correct).
- configure_pixels: update
pixels.properties only once paths, hosts, ports, database, etcd, topology, and cache settings are confirmed; it derives pixels.var.dir from the resolved PIXELS_HOME, writes $PIXELS_HOME/etc/workers from PIXELS_WORKERS, and reuses the MySQL credentials install_mysql.sh already confirmed. If MySQL was configured elsewhere, pass METADATA_DB_PASSWORD explicitly.
- start_pixels_optional: only when the user asks to start services or startup is part of the requested task.
- install_shell_helpers_optional: only if the user wants convenience functions. Install Pixels helpers on the Pixels coordinator and Trino helpers on the Trino coordinator; do not install them on the agent's current host unless that host is the corresponding coordinator or the user explicitly asks for a local helper install. Both helper scripts ask by default before writing to the target user's shell profile.
- smoke_test: run after configuration or startup changes; read the full structured summary (see "Failure Handling" below), don't just check the exit code. For a final deployment check, enable the relevant checks from the actual topology, e.g.
CHECK_PIXELS_LOGS=true CHECK_TRINO=true CHECK_TRINO_CLUSTER_STATUS=true CHECK_TRINO_CLI=true. SHOW SCHEMAS success is enough before data is loaded; do not require returned schemas to be non-empty.
- optional_trino_install: only when the user explicitly asks. Clarify the topology first: coordinator vs. worker(s), how many workers, whether the coordinator also accepts scheduled work (
node-scheduler.include-coordinator; official docs recommend false for a dedicated coordinator, true for a single-node test setup), TRINO_INSTALL_PARENT, TRINO_HOME_LINK, and TRINO_DATA_DIR. Never infer a fixed Trino cluster shape; use the user's topology or prepare_trino_cluster.sh's confirmed output. For a Trino cluster whose remote nodes should not build Pixels, run build_pixels_trino_artifacts.sh once where Pixels has already been mvn installed, or pass PIXELS_TRINO_CONNECTOR_ZIP and PIXELS_TRINO_LISTENER_ZIP explicitly to install_trino_cluster.sh; the remote nodes should only receive Trino plus those two plugins, Trino catalog/listener configs, and the lightweight Trino-side Pixels client config under TRINO_PIXELS_HOME (default ~/opt/pixels). They must not be required to receive the full Pixels install, Maven, or source checkout. Run prepare_trino_cluster.sh --setup-ssh true, then run install_trino_cluster.sh on the coordinator to install Trino on the coordinator and fan out to every worker in parallel over SSH, instead of repeating install_trino.sh by hand once per node. Configure Trino's etc/catalog/pixels.properties as a Trino catalog file only; it is not $PIXELS_HOME/etc/pixels.properties. For the Trino-side Pixels client config, set PIXELS_HOME/TRINO_PIXELS_HOME to the parent directory (e.g. ~/opt/pixels, never ~/opt/pixels/etc) and set/export PIXELS_CONFIG=$PIXELS_HOME/etc/pixels.properties; all Trino nodes need this because the pixels-trino connector initializes on workers as well as the coordinator. install_trino.sh writes those two exports directly to the user's bash/zsh profile. When the skill itself starts, stops, checks, or runs CLI against Trino from a non-interactive SSH command, inline PIXELS_HOME and PIXELS_CONFIG in that command because remote non-interactive shells may not read .bashrc/.zshrc. Ensure metadata.server.host, trans.server.host, query.schedule.server.host, and etcd.hosts are reachable from every Trino node and are not accidental localhost values in a separated topology. Configure presto.pixels.jdbc.url only once the coordinator's endpoint and catalog/schema values are known. Offer install_trino_shell_helpers.sh only after the user agrees (it asks by default anyway).
- optional_hadoop_or_monitoring: out of scope unless the user asks — see Optional Components below.
Failure handling
check_prerequisites.sh and smoke_test.sh never stop at the first failed check — they run every check and print a structured summary block (=== <script> result === … summary: ok=N warn=N fail=N skip=N status=pass|fail … === end <script> result ===). When status=fail:
- Read every
fail line in the block, not just the first — they are independent and often have independent causes (e.g. a port conflict and a missing config property are unrelated problems, both worth knowing about before acting).
- For each
fail, decide whether it is something this skill should fix directly (e.g. an expected service genuinely isn't running yet — wait and re-check), something that needs a user decision (e.g. a port is held by an unrelated process — ask whether to stop it or change Pixels' port), or something informational that the user already knows about (e.g. a deliberately non-Ubuntu host).
- Don't re-run the same script in a loop hoping it passes — fix (or get a decision on) the specific
fail line first, then re-run once to confirm.
warn and skip lines never fail the run by themselves, but still read them — a warn is frequently the first sign of an edge case worth flagging to the user even though it didn't block anything.
The same applies to install_trino_cluster.sh's per-node summary: a fail for one worker doesn't mean the whole cluster install failed — check which specific node(s) failed, read that node's log under STATE_DIR/logs/, and retry only that node rather than re-running the whole fan-out.
Optional components
Do not install these unless the user explicitly asks for the corresponding later stage:
- Trino or another query engine — see the dedicated Trino steps above and the scripts list; this skill can now install Trino itself when asked, instead of only pointing at the external
pixels-trino documentation.
- Hadoop or HDFS configuration.
- AWS credentials.
- Prometheus, Grafana, node exporter, or JMX exporter.
- Pixels Cache, Turbo, Retina, or Amphi.
The basic Pixels install flow may configure presto.pixels.jdbc.url only after the Trino endpoint and catalog/schema values are known.
Trino-side Pixels client config is not a full Pixels installation. A Trino node does not need $PIXELS_HOME/bin, $PIXELS_HOME/sbin, $PIXELS_HOME/lib, pixels-daemon-*-full.jar, pixels-cli-*-full.jar, Maven, or the Pixels source tree just to run the pixels-trino connector. It does need a readable PIXELS_CONFIG/$PIXELS_HOME/etc/pixels.properties with reachable Pixels metadata, transaction, query-schedule, etcd, and storage settings, plus access to the underlying data storage (for example shared local paths, HDFS configs, or S3/MinIO credentials depending on table storage).
Examples
Prepare a three-node Pixels cluster config and SSH (run from this skill directory, or invoke the script by absolute path):
./scripts/prepare_deployment.sh \
--ssh-user root \
--setup-ssh true \
--coordinator-is-worker false \
--pixels-home /home/pixels/opt/pixels \
--coordinator 10.0.0.11,10.0.0.11,pixels-coordinator,root,22 \
--worker 10.0.0.12,10.0.0.12,pixels-worker-1,root,22 \
--worker 10.0.0.13,10.0.0.13,pixels-worker-2,root,22
./scripts/check_prerequisites.sh
Prepare a 1-coordinator/2-worker Trino cluster, SSH, then install Trino on every node in parallel (run on the coordinator):
./scripts/prepare_trino_cluster.sh \
--ssh-user root \
--setup-ssh true \
--coordinator 10.0.0.11,10.0.0.11,trino-coordinator,root,22 \
--worker 10.0.0.12,10.0.0.12,trino-worker-1,root,22 \
--worker 10.0.0.13,10.0.0.13,trino-worker-2,root,22
./scripts/install_trino_cluster.sh
Check (and resume from) the recorded install progress:
./scripts/progress.sh show
./scripts/progress.sh mark check_prerequisites
Guardrails
- Prefer
docs/INSTALL.md plus targeted helper scripts over a fixed all-in-one install command.
- Do not run scripts that install packages, change services, update credentials, or start daemons unless the user is asking to perform that installation stage.
- Do not modify Git state.
- When modifying this skill's source, keep changes limited to
skills/pixels-install/ unless the user explicitly requests more.
- Ask before handling secrets, installing downloaded JDK packages, changing MySQL root authentication, enabling remote database access, installing the etcd
systemd auto-start unit, or installing the Trino cluster shell helpers.
- Ask before installing Pixels shell helpers or Trino shell helpers into the user's shell profile; do not silently add operational functions.
- For management shell helpers, the default target is the relevant coordinator, not the current agent host: Pixels helpers go to
PIXELS_COORDINATOR_SSH_TARGET, and Trino helpers go to TRINO_COORDINATOR_SSH_TARGET. Use PIXELS_SHELL_HELPERS_TARGET=local or TRINO_SHELL_HELPERS_TARGET=local only after the user explicitly asks for local-only helper functions.
- Ask or use the interactive preparation scripts before choosing
PIXELS_HOME, Trino install/data paths, single-node vs. cluster mode, coordinator role, worker list, or whether a coordinator also runs worker tasks. Never let the skill silently accept topology/path defaults on the user's behalf.
- In non-interactive runs, only set
CONFIRM_PIXELS_DEPLOYMENT=true, CONFIRM_PIXELS_INSTALL=true, CONFIRM_TRINO_DEPLOYMENT=true, CONFIRM_TRINO_INSTALL=true, or CONFIRM_TRINO_CLUSTER_INSTALL=true after showing the user the exact topology and paths that will be written or installed.
- Never hardcode
/home/pixels, /home/ubuntu, or any other specific home directory in a command; always resolve paths from $HOME for whichever user is actually running the install.
- Never persist
JAVA_HOME, MAVEN_HOME, ETCD, PIXELS_HOME, or PIXELS_CONFIG into a global file (/etc/environment, /etc/profile.d/*); only append to the current user's shell profile, matching their actual login shell.
- For Trino nodes, never set
PIXELS_HOME to the etc directory. It must be the parent directory (for example $HOME/opt/pixels), with PIXELS_CONFIG=$PIXELS_HOME/etc/pixels.properties.
- Do not wrap or replace Trino's
bin/launcher to smuggle Pixels environment variables, and do not create a separate ~/.pixels-trino-env.sh. Persist PIXELS_HOME and PIXELS_CONFIG directly in the user's bash/zsh profile; generated helpers and skill-run SSH commands must inline-export them before invoking Trino.
- Do not create SSH tunnels for etcd. If Trino/Pixels nodes must access etcd remotely, configure etcd/network access explicitly and restrict the allowed source IP ranges to trusted Pixels and Trino nodes.
- Never accept the documented default MySQL passwords (
password) without an explicit interactive confirmation from the user; install_mysql.sh enforces this by prompting even when a default is acceptable.
- Never run
install_trino.sh (directly or via install_trino_cluster.sh) against a node without first knowing its role (coordinator vs. worker) from trino-deployment.env or an explicit TRINO_ROLE; discovery.uri must point at the coordinator's real IP, never localhost.
- Never put Pixels client/runtime properties such as
metadata.server.host, trans.server.host, query.schedule.server.host, or etcd.hosts into Trino's etc/catalog/pixels.properties. Keep them only in the Trino-side Pixels client config (PIXELS_CONFIG).
- Preserve the versioned plugin directory names produced by unzipping
pixels-trino-connector-*.zip and pixels-trino-listener-*.zip; do not normalize them to unversioned names.
- When a structured result summary reports
status=fail, address (or get a user decision on) every fail line before re-running — see "Failure handling" above. Don't paper over a fail by re-running the script in a loop.
STATE_DIR/deployment.env, STATE_DIR/deployment.secrets.env, STATE_DIR/toolchain.env, STATE_DIR/trino-deployment.env, STATE_DIR/progress.env, and STATE_DIR/logs/ are generated, user-specific, and must never be committed.