From b6db98b8dc1ec8667924ac6b94aaa6c214afbd6d Mon Sep 17 00:00:00 2001 From: Daniel Kukula Date: Wed, 13 Aug 2025 19:49:06 +0200 Subject: [PATCH] update logic --- ct/livebook.sh | 49 ++--- frontend/public/json/livebook.json | 7 +- install.sh | 298 +++++++++++++++++++++++++++++ install/livebook-install.sh | 81 ++------ misc/build.func | 14 +- misc/install.func | 6 +- 6 files changed, 338 insertions(+), 117 deletions(-) create mode 100755 install.sh diff --git a/ct/livebook.sh b/ct/livebook.sh index 177db87f..2899724d 100755 --- a/ct/livebook.sh +++ b/ct/livebook.sh @@ -5,6 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/head # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/livebook-dev/livebook +echo -e "Loading..." APP="Livebook" var_tags="${var_tags:-development}" var_disk="${var_disk:-4}" @@ -25,7 +26,7 @@ function update_script() { check_container_resources # Check if Livebook is installed - if [[ ! -d /opt/${APP}_version.txt ]]; then + if [[ ! -f /opt/${APP}_version.txt ]]; then msg_error "No ${APP} Installation Found!" exit 1 fi @@ -40,41 +41,24 @@ function update_script() { fi # Check if version file exists and compare versions - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt 2>/dev/null)" ]]; then - msg_info "Updating ${APP} to v${RELEASE}" + if [[ "${RELEASE}" == "$(cat /opt/${APP}_version.txt 2>/dev/null)" ]]; then + #if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt 2>/dev/null)" ]]; then + msg_info "Updating ${APP} LXC" + $STD apt-get update + $STD apt-get -y upgrade + msg_ok "Updated ${APP} LXC" - # Create backup of user data if it exists - if [[ -d /home/livebook ]]; then - msg_info "Creating backup of user data..." - $STD cp -r /home/livebook /home/livebook-backup - fi - - # Perform the update - msg_info "Installing dependencies and updating Livebook..." - if ! sudo -u livebook bash -c ' - export HOME=/home/livebook - cd /home/livebook - mix local.hex --force >/dev/null 2>&1 - mix local.rebar --force >/dev/null 2>&1 - mix escript.install hex livebook --force >/dev/null 2>&1 - '; then - msg_error "Failed to update Livebook" - # Restore from backup if update failed - if [[ -d /home/livebook-backup ]]; then - msg_info "Restoring from backup..." - rm -rf /home/livebook - mv /home/livebook-backup /home/livebook - fi - exit 1 - fi + msg_info "Updating ${APP} to ${RELEASE}" + source /opt/.env + cd /opt || exit 1 + mix escript.install hex livebook --force >/dev/null 2>&1 # Save the new version echo "$RELEASE" | $STD tee /opt/${APP}_version.txt >/dev/null # Cleanup backup if update was successful - if [[ -d /home/livebook-backup ]]; then - msg_info "Cleaning up backup..." - $STD rm -rf /home/livebook-backup + if [[ -d /opt-backup ]]; then + $STD rm -rf /opt-backup fi msg_ok "Successfully updated to v${RELEASE}" @@ -92,7 +76,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" -echo -e "\n${INFO}${YW} To start Livebook, run the following command:${CL}" -echo -e "${TAB}${BGN}sudo -u livebook /root/.mix/escripts/livebook server${CL}" -echo -e "\n${INFO}${YW} To run it as a service, create a systemd service file.${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}" diff --git a/frontend/public/json/livebook.json b/frontend/public/json/livebook.json index 432a0617..f5599d2b 100644 --- a/frontend/public/json/livebook.json +++ b/frontend/public/json/livebook.json @@ -29,14 +29,13 @@ ], "default_credentials": { "username": null, - "password": "Check /data/token.txt" + "password": null }, "notes": [ - "Access token is stored in /data/token.txt", "Default port is 8080", "Working directory is /data", - "Home directory is /home/livebook", + "Home directory is /opt", "Elixir runtime with Mix.install/2 support", - "Service runs as livebook user" + "Service runs as root user" ] } diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..f1647a15 --- /dev/null +++ b/install.sh @@ -0,0 +1,298 @@ +#!/bin/sh +# See latest version at: +# https://github.com/elixir-lang/elixir-lang.github.com/blob/main/install.sh + +set -eu + +otp_version= +elixir_version= +force=false + +usage() { + cat<&2 + exit 1 + ;; + esac + done + + if [ -z "${elixir_version}" ]; then + usage + echo "error: missing elixir@VERSION argument" + exit 1 + fi + + if [ -z "${otp_version}" ]; then + usage + echo "error: missing otp@VERSION argument" + exit 1 + fi + + root_dir="$HOME/.elixir-install" + tmp_dir="$root_dir/tmp" + mkdir -p "$tmp_dir" + + if [ "${otp_version}" = latest ]; then + url=$(curl -fsS --head https://github.com/erlef/otp_builds/releases/latest | grep -i '^location:' | awk '{print $2}' | tr -d '\r\n') + tag=$(basename "$url") + otp_version="${tag#OTP-}" + fi + + if [ "${elixir_version}" = latest ]; then + url=$(curl -fsS --head https://github.com/elixir-lang/elixir/releases/latest | grep -i '^location:' | awk '{print $2}' | tr -d '\r\n') + tag=$(basename "$url") + elixir_version="${tag#v}" + fi + + case "${otp_version}" in + master|maint*) + branch_version=$(curl -fsS https://raw.githubusercontent.com/erlang/otp/refs/heads/${otp_version}/OTP_VERSION | tr -d '\n') + elixir_otp_release="${branch_version%%.*}" + ;; + *) + elixir_otp_release="${otp_version%%.*}" + ;; + esac + + case "$elixir_version" in + 1.14.*) + [ "${elixir_otp_release}" -ge 25 ] && elixir_otp_release=25 + ;; + 1.15.*|1.16.*) + [ "${elixir_otp_release}" -ge 26 ] && elixir_otp_release=26 + ;; + 1.17.*|1.18.*) + [ "${elixir_otp_release}" -ge 27 ] && elixir_otp_release=27 + ;; + 1.19.*) + [ "${elixir_otp_release}" -ge 28 ] && elixir_otp_release=28 + ;; + *) + [ "${elixir_otp_release}" -ge 28 ] && elixir_otp_release=28 + ;; + esac + + otp_dir="$root_dir/installs/otp/$otp_version" + elixir_dir="${root_dir}/installs/elixir/${elixir_version}-otp-${elixir_otp_release}" + + if unzip_available; then + install_otp & + pid_otp=$! + + install_elixir & + pid_elixir=$! + + wait $pid_otp + wait $pid_elixir + else + # if unzip is missing (e.g. official docker ubuntu image), install otp and elixir + # serially because we unzip elixir using OTP zip:extract/2. + install_otp + install_elixir + fi + + printf "checking OTP... " + export PATH="$otp_dir/bin:$PATH" + erl -noshell -eval 'io:put_chars(erlang:system_info(otp_release) ++ " ok\n"), halt().' + + printf "checking Elixir... " + "$elixir_dir/bin/elixir" -e 'IO.puts(System.version() <> " ok")' + + export PATH="$elixir_dir/bin:$PATH" +cat</dev/null 2>&1 +} + +main "$@" diff --git a/install/livebook-install.sh b/install/livebook-install.sh index eacc992b..20ae054e 100644 --- a/install/livebook-install.sh +++ b/install/livebook-install.sh @@ -23,82 +23,29 @@ $STD apt-get install --no-install-recommends -y \ libncurses5-dev msg_ok "Installed Dependencies" -msg_info "Creating Livebook User and Directories" -useradd -r -s /bin/bash -d /opt livebook -mkdir -p /opt /data -chown livebook:livebook /opt /data - -chmod 777 /opt -msg_ok "Created Livebook User and Directories" msg_info "Installing Erlang and Elixir" -# Create a temporary script -cat > /tmp/setup_elixir.sh << 'EOF' -#!/bin/bash +mkdir -p /opt /data export HOME=/opt -cd /opt +touch $HOME/.env +cd /opt || exit 1 curl -fsSO https://elixir-lang.org/install.sh sh install.sh elixir@1.18.4 otp@27.3.4 >/dev/null 2>&1 - -# Create .env if it doesn't exist and set permissions -touch $HOME/.env -chmod 644 $HOME/.env - -# Add exports to .env echo 'export HOME=/opt' >> $HOME/.env -echo 'export PATH="$HOME/.elixir-install/installs/otp/27.3.4/bin:$HOME/.elixir-install/installs/elixir/1.18.4-otp-27/bin:$PATH"' >> $HOME/.env -EOF - -# Make it executable and run as livebook user -chmod +x /tmp/setup_elixir.sh -$STD sudo -u livebook -H /tmp/setup_elixir.sh -rm /tmp/setup_elixir.sh +echo 'export PATH="/opt/.elixir-install/installs/otp/27.3.4/bin:/opt/.elixir-install/installs/elixir/1.18.4-otp-27/bin:$PATH"' >> $HOME/.env msg_ok "Installed Erlang 27.3.4 and Elixir 1.18.4" msg_info "Installing Livebook" - -cat > /tmp/install_livebook.sh << 'EOF' -#!/bin/bash RELEASE=$(curl -fsSL https://api.github.com/repos/livebook-dev/livebook/releases/latest | grep "tag_name" | awk -F'"' '{print $4}') echo "${RELEASE}" >/opt/Livebook_version.txt -set -e # Exit on any error source /opt/.env -cd $HOME - -# Install hex and rebar for Mix.install/2 and Mix runtime (matching Dockerfile) -echo "Installing hex..." -mix local.hex --force -echo "Installing rebar..." -mix local.rebar --force - -# Following official Livebook escript installation instructions -echo "Installing Livebook escript..." -MIX_ENV=prod mix escript.install hex livebook --force - -# Add escripts to PATH +cd /opt || exit 1 +mix local.hex --force >/dev/null 2>&1 +mix local.rebar --force >/dev/null 2>&1 +mix escript.install hex livebook --force >/dev/null 2>&1 echo 'export PATH="$HOME/.mix/escripts:$PATH"' >> ~/.env - -# Verify livebook was installed and make executable -if [ -f ~/.mix/escripts/livebook ]; then - chmod +x ~/.mix/escripts/livebook - echo "Livebook escript installed successfully" - ls -la ~/.mix/escripts/livebook -else - echo "ERROR: Livebook escript not found after installation" - ls -la ~/.mix/escripts/ || echo "No escripts directory found" - # Try to show what went wrong - echo "Mix environment:" - mix --version - echo "Available packages:" - mix hex.info livebook || echo "Could not get livebook info" - exit 1 -fi -EOF - -chmod +x /tmp/install_livebook.sh -$STD sudo -u livebook -H /tmp/install_livebook.sh -rm /tmp/install_livebook.sh +msg_ok "Installed Livebook" msg_info "Creating Livebook Service" cat </etc/systemd/system/livebook.service @@ -108,8 +55,8 @@ After=network.target [Service] Type=exec -User=livebook -Group=livebook +User=root +Group=root WorkingDirectory=/data Environment=MIX_ENV=prod Environment=HOME=/opt @@ -129,6 +76,7 @@ WantedBy=multi-user.target EOF $STD systemctl enable livebook.service +$STD systemctl start livebook.service msg_ok "Created Livebook Service" msg_info "Cleaning Up" @@ -137,11 +85,6 @@ $STD apt-get autoremove -y $STD apt-get autoclean msg_ok "Cleaned Up" -msg_info "Starting Livebook Service" -$STD systemctl start livebook.service -msg_ok "Started Livebook Service" - - motd_ssh customize diff --git a/misc/build.func b/misc/build.func index 49b20b7f..c03764f8 100644 --- a/misc/build.func +++ b/misc/build.func @@ -16,10 +16,10 @@ variables() { CT_TYPE=${var_unprivileged:-$CT_TYPE} } -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) +source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/api.func) if command -v curl >/dev/null 2>&1; then - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) + source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/core.func) load_functions #echo "(build.func) Loaded core.func via curl" elif command -v wget >/dev/null 2>&1; then @@ -988,7 +988,7 @@ install_script() { header_info echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}" METHOD="advanced" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func) + source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/config-file.func) config_file ;; 5) @@ -1061,7 +1061,7 @@ check_container_storage() { } start() { - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then install_script elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then @@ -1127,9 +1127,9 @@ build_container() { TEMP_DIR=$(mktemp -d) pushd "$TEMP_DIR" >/dev/null if [ "$var_os" == "alpine" ]; then - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/alpine-install.func)" else - export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)" + export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/install.func)" fi export DIAGNOSTICS="$DIAGNOSTICS" export RANDOM_UUID="$RANDOM_UUID" @@ -1163,7 +1163,7 @@ build_container() { -unprivileged $CT_TYPE $PW " - bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" || exit + bash -c "$(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/create_lxc.sh)" || exit if [ $? -ne 0 ]; then exit 200 fi diff --git a/misc/install.func b/misc/install.func index 48c196cf..b38ff336 100644 --- a/misc/install.func +++ b/misc/install.func @@ -10,7 +10,7 @@ if ! command -v curl >/dev/null 2>&1; then apt-get update >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1 fi -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) +source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/core.func) load_functions # This function enables IPv6 if it's not disabled and sets verbose mode @@ -148,7 +148,7 @@ EOF $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Container OS" - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func) + source <(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/misc/tools.func) } # This function modifies the message of the day (motd) and SSH settings @@ -196,7 +196,7 @@ EOF systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//') msg_ok "Customized Container" fi - echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update + echo "bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/dkuku/ProxmoxVED/refs/heads/livebook/ct/${app}.sh)\"" >/usr/bin/update chmod +x /usr/bin/update if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then mkdir -p /root/.ssh