refactor rustypaste and add alpine-tools

This commit is contained in:
CanbiZ 2026-01-15 10:04:43 +01:00
parent 5e8d2565c4
commit 82053c5b70
6 changed files with 275 additions and 53 deletions

View File

@ -8,7 +8,7 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/
APP="rustypaste"
var_tags="${var_tags:-pastebin;storage}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-20}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
@ -20,38 +20,38 @@ color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
header_info
check_container_storage
check_container_resources
if [[ ! -f "/opt/rustypaste/target/release/rustypaste" ]]; then
msg_error "No rustypaste Installation Found!"
exit
fi
if check_for_gh_release "rustypaste" "orhun/rustypaste"; then
msg_info "Stopping Services"
systemctl stop rustypaste
msg_ok "Stopped Services"
msg_info "Creating Backup"
tar -czf "/opt/rustypaste_backup_$(date +%F).tar.gz" "/opt/rustypaste/upload"
msg_ok "Backup Created"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "tarball" "latest" "/opt/rustypaste"
msg_info "Updating rustypaste"
cd /opt/rustypaste
sed -i 's|^address = ".*"|address = "0.0.0.0:8000"|' config.toml
$STD cargo build --locked --release
msg_ok "Updated rustypaste"
msg_info "Starting Services"
systemctl start rustypaste
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
if [[ ! -f "/opt/rustypaste/target/release/rustypaste" ]]; then
msg_error "No rustypaste Installation Found!"
exit
fi
if check_for_gh_release "rustypaste" "orhun/rustypaste"; then
msg_info "Stopping Services"
systemctl stop rustypaste
msg_ok "Stopped Services"
msg_info "Creating Backup"
tar -czf "/opt/rustypaste_backup_$(date +%F).tar.gz" "/opt/rustypaste/upload"
msg_ok "Backup Created"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "tarball" "latest" "/opt/rustypaste"
msg_info "Updating rustypaste"
cd /opt/rustypaste
sed -i 's|^address = ".*"|address = "0.0.0.0:8000"|' config.toml
$STD cargo build --locked --release
msg_ok "Updated rustypaste"
msg_info "Starting Services"
systemctl start rustypaste
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
exit
}
start

View File

@ -20,7 +20,7 @@
"script": "ct/rustypaste.sh",
"resources": {
"cpu": 1,
"ram": 512,
"ram": 1024,
"hdd": 20,
"os": "Debian",
"version": "13"
@ -32,9 +32,9 @@
"password": null
},
"notes": [
{
"text": "When updating the script it will backup the whole project including all the uploaded files, make sure to extract it to a safe location or remove",
"type": "info"
}
{
"text": "When updating the script it will backup the whole project including all the uploaded files, make sure to extract it to a safe location or remove",
"type": "info"
}
]
}

View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/orhun/rustypaste
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "prebuild" "latest" "/opt/rustypaste" "*x86_64-unknown-linux-musl.tar.gz"
msg_info "Setting up rustypaste"
cd /opt/rustypaste
sed -i 's|^address = ".*"|address = "0.0.0.0:8000"|' config.toml
msg_ok "Set up rustypaste"
msg_info "Creating Service"
cat <<'EOF' >/etc/init.d/rustypaste
#!/sbin/openrc-run
name="rustypaste"
description="rustypaste Service"
directory="/opt/rustypaste"
command="/opt/rustypaste/rustypaste"
command_args=""
pidfile="/run/${RC_SVCNAME}.pid"
command_background="yes"
start_stop_daemon_args="--user root"
depend() {
need net
}
EOF
chmod +x /etc/init.d/rustypaste
rc-update add rustypaste default
rc-service rustypaste start
msg_ok "Created Service"
motd_ssh
customize

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: GoldenSpringness
# Author: GoldenSpringness | MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/orhun/rustypaste
@ -13,17 +13,11 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y build-essential
msg_ok "Dependencies Installed Successfully"
RUST_VERSION="1.92.0" setup_rust
fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "tarball"
fetch_and_deploy_gh_release "rustypaste" "orhun/rustypaste" "prebuild" "latest" "/opt/rustypaste" "*x86_64-unknown-linux-gnu.tar.gz"
msg_info "Setting up rustypaste"
cd /opt/rustypaste
sed -i 's|^address = ".*"|address = "0.0.0.0:8000"|' config.toml
$STD cargo build --locked --release
msg_ok "Set up rustypaste"
msg_info "Creating Service"
@ -34,7 +28,7 @@ After=network.target
[Service]
WorkingDirectory=/opt/rustypaste
ExecStart=/opt/rustypaste/target/release/rustypaste
ExecStart=/opt/rustypaste/rustypaste
Restart=always
[Install]

View File

@ -9,6 +9,145 @@
lower() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]'; }
has() { command -v "$1" >/dev/null 2>&1; }
# tools.func compatibility helpers (Alpine-safe)
cache_installed_version() {
local app="$1" version="$2"
mkdir -p /var/cache/app-versions
echo "$version" >"/var/cache/app-versions/${app}_version.txt"
}
get_cached_version() {
local app="$1"
mkdir -p /var/cache/app-versions
if [ -f "/var/cache/app-versions/${app}_version.txt" ]; then
cat "/var/cache/app-versions/${app}_version.txt"
return 0
fi
return 0
}
version_gt() {
# returns 0 if $1 > $2
# BusyBox-safe version compare
awk -v a="$1" -v b="$2" '
function splitver(v, arr) { n=split(v, arr, /\./); return n }
BEGIN {
na=splitver(a, A); nb=splitver(b, B);
n=(na>nb?na:nb);
for (i=1;i<=n;i++) {
va=(A[i]==""?0:A[i]); vb=(B[i]==""?0:B[i]);
if (va+0 > vb+0) exit 0;
if (va+0 < vb+0) exit 1;
}
exit 1;
}'
}
get_system_arch() {
local arch
arch=$(uname -m 2>/dev/null || echo "")
[ "$arch" = "x86_64" ] && arch="amd64"
[ "$arch" = "aarch64" ] && arch="arm64"
echo "$arch"
}
create_temp_dir() {
mktemp -d
}
get_os_info() {
local field="${1:-all}"
[ -z "${_OS_ID:-}" ] && _OS_ID=$(awk -F= '/^ID=/{gsub(/"/,"",$2); print $2}' /etc/os-release 2>/dev/null)
[ -z "${_OS_CODENAME:-}" ] && _OS_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{gsub(/"/,"",$2); print $2}' /etc/os-release 2>/dev/null)
[ -z "${_OS_VERSION:-}" ] && _OS_VERSION=$(awk -F= '/^VERSION_ID=/{gsub(/"/,"",$2); print $2}' /etc/os-release 2>/dev/null)
case "$field" in
id) echo "$_OS_ID" ;;
codename) echo "$_OS_CODENAME" ;;
version | version_id) echo "$_OS_VERSION" ;;
all) echo "ID=$_OS_ID CODENAME=$_OS_CODENAME VERSION=$_OS_VERSION" ;;
*) echo "$_OS_ID" ;;
esac
}
is_alpine() { [ "$(get_os_info id)" = "alpine" ]; }
get_os_version_major() {
local v
v=$(get_os_info version)
echo "${v%%.*}"
}
ensure_dependencies() {
need_tool "$@"
}
download_file() {
local url="$1" output="$2" max_retries="${3:-3}" show_progress="${4:-false}"
local i=1 curl_opts="-fsSL"
[ "$show_progress" = "true" ] && curl_opts="-fL#"
while [ $i -le "$max_retries" ]; do
if curl $curl_opts -o "$output" "$url"; then
return 0
fi
i=$((i + 1))
[ $i -le "$max_retries" ] && sleep 2
done
msg_error "Failed to download: $url"
return 1
}
github_api_call() {
local url="$1" output_file="${2:-/dev/stdout}"
local max_retries=3 retry_delay=2 attempt=1
local header=""
[ -n "${GITHUB_TOKEN:-}" ] && header="-H Authorization:Bearer\ ${GITHUB_TOKEN}"
while [ $attempt -le $max_retries ]; do
http_code=$(curl -fsSL -w "%{http_code}" -o "$output_file" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
$header "$url" 2>/dev/null || echo 000)
case "$http_code" in
200) return 0 ;;
403) [ $attempt -lt $max_retries ] && sleep "$retry_delay" || {
msg_error "GitHub API rate limit exceeded"
return 1
} ;;
404)
msg_error "GitHub API endpoint not found: $url"
return 1
;;
*) [ $attempt -lt $max_retries ] && sleep "$retry_delay" || {
msg_error "GitHub API call failed with HTTP $http_code"
return 1
} ;;
esac
retry_delay=$((retry_delay * 2))
attempt=$((attempt + 1))
done
return 1
}
extract_version_from_json() {
local json="$1" field="${2:-tag_name}" strip_v="${3:-true}" version
need_tool jq || return 1
version=$(printf '%s' "$json" | jq -r ".${field} // empty")
[ -z "$version" ] && return 1
[ "$strip_v" = "true" ] && printf '%s' "${version#v}" || printf '%s' "$version"
}
get_latest_github_release() {
local repo="$1" strip_v="${2:-true}" tmp
tmp=$(mktemp) || return 1
github_api_call "https://api.github.com/repos/${repo}/releases/latest" "$tmp" || {
rm -f "$tmp"
return 1
}
extract_version_from_json "$(cat "$tmp")" "tag_name" "$strip_v"
rc=$?
rm -f "$tmp"
return $rc
}
need_tool() {
# usage: need_tool curl jq unzip ...
# setup missing tools via apk
@ -78,7 +217,12 @@ check_for_gh_release() {
}
need_tool curl jq || return 1
tag=$(curl -fsSL "https://api.github.com/repos/${source}/releases/latest" | jq -r '.tag_name // empty')
github_api_call "https://api.github.com/repos/${source}/releases/latest" "/tmp/${app_lc}-release.json" || {
msg_error "Unable to fetch latest tag for $app"
return 1
}
tag=$(cat "/tmp/${app_lc}-release.json" | jq -r '.tag_name // empty')
rm -f "/tmp/${app_lc}-release.json"
[ -z "$tag" ] && {
msg_error "Unable to fetch latest tag for $app"
return 1
@ -115,7 +259,7 @@ check_for_gh_release() {
# GitHub: get Release & deployen (Alpine)
# modes: tarball | prebuild | singlefile
# ------------------------------
fetch_and_deploy_gh() {
fetch_and_deploy_gh_release() {
# $1 app, $2 repo, [$3 mode], [$4 version], [$5 target], [$6 asset_pattern
local app="$1" repo="$2" mode="${3:-tarball}" version="${4:-latest}" target="${5:-/opt/$1}" pattern="${6:-}"
local app_lc
@ -133,20 +277,21 @@ fetch_and_deploy_gh() {
tmpd="$(mktemp -d)" || return 1
mkdir -p "$target"
# Release JSON
# Release JSON (with token/rate-limit handling)
if [ "$version" = "latest" ]; then
json="$(curl -fsSL "https://api.github.com/repos/$repo/releases/latest")" || {
github_api_call "https://api.github.com/repos/$repo/releases/latest" "$tmpd/release.json" || {
msg_error "GitHub API failed"
rm -rf "$tmpd"
return 1
}
else
json="$(curl -fsSL "https://api.github.com/repos/$repo/releases/tags/$version")" || {
github_api_call "https://api.github.com/repos/$repo/releases/tags/$version" "$tmpd/release.json" || {
msg_error "GitHub API failed"
rm -rf "$tmpd"
return 1
}
fi
json="$(cat "$tmpd/release.json")"
# correct Version
version="$(printf '%s' "$json" | jq -r '.tag_name // empty')"
@ -173,6 +318,7 @@ fetch_and_deploy_gh() {
return 1
}
unpack="$(find "$tmpd" -mindepth 1 -maxdepth 1 -type d | head -n1)"
[ "${CLEAN_INSTALL:-0}" = "1" ] && rm -rf "${target:?}/"*
# copy content of unpack to target
(cd "$unpack" && tar -cf - .) | (cd "$target" && tar -xf -) || {
msg_error "copy failed"
@ -180,6 +326,34 @@ fetch_and_deploy_gh() {
return 1
}
;;
binary)
[ -n "$pattern" ] || pattern="*.apk"
url="$(printf '%s' "$json" | jq -r '.assets[].browser_download_url' | awk -v p="$pattern" 'BEGIN{IGNORECASE=1} $0 ~ p {print; exit}')"
[ -z "$url" ] && {
msg_error "binary asset not found for pattern: $pattern"
rm -rf "$tmpd"
return 1
}
filename="${url##*/}"
download_with_progress "$url" "$tmpd/$filename" || {
rm -rf "$tmpd"
return 1
}
case "$filename" in
*.apk)
apk add --no-cache --allow-untrusted "$tmpd/$filename" >/dev/null 2>&1 || {
msg_error "apk install failed: $filename"
rm -rf "$tmpd"
return 1
}
;;
*)
msg_error "Unsupported binary asset on Alpine: $filename"
rm -rf "$tmpd"
return 1
;;
esac
;;
prebuild)
[ -n "$pattern" ] || {
msg_error "prebuild requires asset pattern"
@ -220,6 +394,7 @@ fetch_and_deploy_gh() {
return 1
;;
esac
[ "${CLEAN_INSTALL:-0}" = "1" ] && rm -rf "${target:?}/"*
# top-level folder strippen
if [ "$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] && [ -z "$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type f | head -n1)" ]; then
unpack="$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type d)"
@ -252,11 +427,13 @@ fetch_and_deploy_gh() {
return 1
}
filename="${url##*/}"
download_with_progress "$url" "$target/$app" || {
local target_file="$app"
[ "${USE_ORIGINAL_FILENAME:-false}" = "true" ] && target_file="$filename"
download_with_progress "$url" "$target/$target_file" || {
rm -rf "$tmpd"
return 1
}
chmod +x "$target/$app"
chmod +x "$target/$target_file"
;;
*)
msg_error "Unknown mode: $mode"
@ -271,6 +448,11 @@ fetch_and_deploy_gh() {
msg_ok "Deployed $app ($version) → $target"
}
# tools.func compatibility alias
fetch_and_deploy_gh() {
fetch_and_deploy_gh_release "$@"
}
# ------------------------------
# yq (mikefarah) Alpine
# ------------------------------

View File

@ -551,7 +551,7 @@ get_ip() {
# Try hostname -I first (most common)
if command -v hostname &>/dev/null; then
ip=$(hostname -I 2>/dev/null | awk '{print $1}')
ip=$(hostname -I 2>/dev/null | awk '{print $1}' || true)
fi
# Fallback to ip command