mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-08-03 19:43:05 +02:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42a1a57587 | |||
| 16d2e3717b | |||
| 18fb43be11 |
@@ -0,0 +1,6 @@
|
||||
____ __ _ ___ __ _ _____
|
||||
/ __ \/ /_ _____(_)___/ (_)___ _____ / / (_) _____ / ___/__ ______ _____
|
||||
/ / / / __ \/ ___/ / __ / / __ `/ __ \______/ / / / | / / _ \\__ \/ / / / __ \/ ___/
|
||||
/ /_/ / /_/ (__ ) / /_/ / / /_/ / / / /_____/ /___/ /| |/ / __/__/ / /_/ / / / / /__
|
||||
\____/_.___/____/_/\__,_/_/\__,_/_/ /_/ /_____/_/ |___/\___/____/\__, /_/ /_/\___/
|
||||
/____/
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/vrtmrz/obsidian-livesync | https://couchdb.apache.org/
|
||||
|
||||
APP="Obsidian-LiveSync"
|
||||
var_tags="${var_tags:-documents;notes}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -f /opt/couchdb/etc/local.d/obsidian-livesync.ini ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Stopping CouchDB"
|
||||
systemctl stop couchdb
|
||||
msg_ok "Stopped CouchDB"
|
||||
|
||||
create_backup /var/lib/couchdb /opt/couchdb/etc/local.d/obsidian-livesync.ini /opt/obsidian-livesync/.env
|
||||
|
||||
msg_info "Updating Container OS"
|
||||
$STD apt update
|
||||
$STD apt upgrade -y
|
||||
msg_ok "Updated Container OS"
|
||||
|
||||
systemctl stop couchdb
|
||||
restore_backup
|
||||
|
||||
msg_info "Starting CouchDB"
|
||||
systemctl start couchdb
|
||||
msg_ok "Started CouchDB"
|
||||
msg_ok "Updated successfully!"
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW}Configure the Self-hosted LiveSync plugin with the credentials in /opt/obsidian-livesync/.env${CL}"
|
||||
echo -e "${GATEWAY}${BGN}http://${IP}:5984/_utils/${CL}"
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/vrtmrz/obsidian-livesync | https://couchdb.apache.org/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
setup_deb822_repo \
|
||||
"couchdb" \
|
||||
"https://couchdb.apache.org/repo/keys.asc" \
|
||||
"https://apache.jfrog.io/artifactory/couchdb-deb/" \
|
||||
"$(get_os_info codename)" \
|
||||
"main"
|
||||
|
||||
msg_info "Installing CouchDB"
|
||||
COUCHDB_ADMIN_USER="admin"
|
||||
COUCHDB_PASSWORD="$(openssl rand -hex 24)"
|
||||
COUCHDB_COOKIE="$(openssl rand -hex 16)"
|
||||
|
||||
cat <<EOF | debconf-set-selections
|
||||
couchdb couchdb/mode select standalone
|
||||
couchdb couchdb/mode seen true
|
||||
couchdb couchdb/bindaddress string 0.0.0.0
|
||||
couchdb couchdb/bindaddress seen true
|
||||
couchdb couchdb/cookie string ${COUCHDB_COOKIE}
|
||||
couchdb couchdb/cookie seen true
|
||||
couchdb couchdb/adminpass password ${COUCHDB_PASSWORD}
|
||||
couchdb couchdb/adminpass seen true
|
||||
couchdb couchdb/adminpass_again password ${COUCHDB_PASSWORD}
|
||||
couchdb couchdb/adminpass_again seen true
|
||||
EOF
|
||||
DEBIAN_FRONTEND=noninteractive $STD apt-get install -y couchdb
|
||||
|
||||
cat <<EOF >/root/.couchdb.credentials
|
||||
COUCHDB_ADMIN_USER="${COUCHDB_ADMIN_USER}"
|
||||
COUCHDB_ADMIN_PASSWORD="${COUCHDB_PASSWORD}"
|
||||
COUCHDB_COOKIE="${COUCHDB_COOKIE}"
|
||||
EOF
|
||||
msg_ok "Installed CouchDB"
|
||||
|
||||
msg_info "Configuring CouchDB"
|
||||
mkdir -p /opt/couchdb/etc/local.d /opt/obsidian-livesync
|
||||
cat <<EOF >/opt/couchdb/etc/local.d/obsidian-livesync.ini
|
||||
[couchdb]
|
||||
single_node = true
|
||||
max_document_size = 50000000
|
||||
|
||||
[admins]
|
||||
admin = ${COUCHDB_PASSWORD}
|
||||
|
||||
[chttpd]
|
||||
bind_address = 0.0.0.0
|
||||
port = 5984
|
||||
max_http_request_size = 4294967296
|
||||
|
||||
[chttpd_auth]
|
||||
require_valid_user = true
|
||||
|
||||
[httpd]
|
||||
enable_cors = true
|
||||
WWW-Authenticate = Basic realm="couchdb"
|
||||
|
||||
[cors]
|
||||
credentials = true
|
||||
origins = app://obsidian.md,capacitor://localhost,http://localhost
|
||||
headers = accept, authorization, content-type, origin, referer
|
||||
methods = GET, PUT, POST, HEAD, DELETE
|
||||
max_age = 3600
|
||||
EOF
|
||||
cat <<EOF >/opt/obsidian-livesync/.env
|
||||
COUCHDB_URL=http://${LOCAL_IP}:5984
|
||||
COUCHDB_USER=admin
|
||||
COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
|
||||
COUCHDB_DATABASE=obsidiannotes
|
||||
EOF
|
||||
chmod 600 /opt/obsidian-livesync/.env
|
||||
msg_ok "Configured CouchDB"
|
||||
|
||||
msg_info "Creating LiveSync Database"
|
||||
systemctl enable -q couchdb
|
||||
systemctl restart couchdb
|
||||
for _ in {1..30}; do
|
||||
curl -fsS -u "admin:${COUCHDB_PASSWORD}" -X PUT http://127.0.0.1:5984/obsidiannotes >/dev/null 2>&1 && break
|
||||
sleep 1
|
||||
done
|
||||
msg_ok "Created LiveSync Database"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -126,7 +126,7 @@ network_check() {
|
||||
fi
|
||||
|
||||
if [[ $ipv4_connected == false ]]; then
|
||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
|
||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
|
||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
|
||||
+1
-2
@@ -3917,7 +3917,7 @@ run_addon_updates() {
|
||||
name="${a##*/update_}"
|
||||
printf 'Do you also want to update addon "%s"? (y/N) [60s]: ' "$name"
|
||||
ans=""
|
||||
if read -r -t 60 ans </dev/tty; then :; else echo; fi
|
||||
if read -r -t 60 ans; then :; else echo; fi
|
||||
case "${ans,,}" in
|
||||
y | yes)
|
||||
bash "$a" || msg_warn "Addon update for $name failed (rc=$?)"
|
||||
@@ -5729,7 +5729,6 @@ EOF
|
||||
# read itself failed (e.g. broken/closed stdin, I/O error) rather than
|
||||
# timing out - don't guess and destroy the container on a read we
|
||||
# couldn't actually capture; keep it since that's the reversible choice.
|
||||
while read -r -t 0.1 -n 1 _ </dev/tty 2>/dev/null; do :; done
|
||||
echo ""
|
||||
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
|
||||
msg_error "Remove it manually if not needed: pct destroy ${CTID}"
|
||||
|
||||
+7
-7
@@ -754,7 +754,7 @@ msg_info() {
|
||||
# Pause mode: Wait for Enter after each step
|
||||
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
|
||||
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
|
||||
read -r </dev/tty
|
||||
read -r
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@@ -769,7 +769,7 @@ msg_info() {
|
||||
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
|
||||
stop_spinner
|
||||
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
|
||||
read -r </dev/tty
|
||||
read -r
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1217,7 +1217,7 @@ prompt_confirm() {
|
||||
# Interactive prompt with timeout
|
||||
echo -en "${YW}${message} ${hint} (auto-${default} in ${timeout}s): ${CL}"
|
||||
|
||||
if read -t "$timeout" -r response </dev/tty; then
|
||||
if read -t "$timeout" -r response; then
|
||||
# User provided input
|
||||
response="${response,,}" # lowercase
|
||||
case "$response" in
|
||||
@@ -1310,7 +1310,7 @@ prompt_input() {
|
||||
# Interactive prompt with timeout
|
||||
echo -en "${YW}${message}${hint} (auto-default in ${timeout}s): ${CL}" >&2
|
||||
|
||||
if read -t "$timeout" -r response </dev/tty; then
|
||||
if read -t "$timeout" -r response; then
|
||||
# User provided input (or pressed Enter for empty)
|
||||
if [[ -n "$response" ]]; then
|
||||
echo "$response"
|
||||
@@ -1412,7 +1412,7 @@ prompt_input_required() {
|
||||
|
||||
echo -en "${YW}${message} (required, timeout ${timeout}s): ${CL}" >&2
|
||||
|
||||
if read -t "$timeout" -r response </dev/tty; then
|
||||
if read -t "$timeout" -r response; then
|
||||
if [[ -z "$response" ]]; then
|
||||
echo -e "${YW}This field is required. Please enter a value. (attempt ${attempts}/3)${CL}" >&2
|
||||
fi
|
||||
@@ -1507,7 +1507,7 @@ prompt_select() {
|
||||
echo -en "${YW}Select [1-${num_options}] (auto-select ${default} in ${timeout}s): ${CL}" >&2
|
||||
|
||||
local response
|
||||
if read -t "$timeout" -r response </dev/tty; then
|
||||
if read -t "$timeout" -r response; then
|
||||
if [[ -z "$response" ]]; then
|
||||
# Empty response, use default
|
||||
echo "${options[$((default - 1))]}"
|
||||
@@ -1590,7 +1590,7 @@ prompt_password() {
|
||||
# Interactive prompt with timeout (silent input)
|
||||
echo -en "${YW}${message}${hint} (timeout ${timeout}s): ${CL}" >&2
|
||||
|
||||
if read -t "$timeout" -rs response </dev/tty; then
|
||||
if read -t "$timeout" -rs response; then
|
||||
echo "" >&2 # Newline after hidden input
|
||||
if [[ -n "$response" ]]; then
|
||||
# Validate minimum length
|
||||
|
||||
@@ -499,7 +499,7 @@ error_handler() {
|
||||
|
||||
local response=""
|
||||
local read_rc
|
||||
read -t 60 -r response </dev/tty
|
||||
read -t 60 -r response
|
||||
read_rc=$?
|
||||
if [[ $read_rc -eq 0 ]]; then
|
||||
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||
@@ -543,7 +543,6 @@ error_handler() {
|
||||
# read itself failed (e.g. broken/closed stdin, I/O error) rather than
|
||||
# timing out - don't guess and destroy the container on a read we
|
||||
# couldn't actually capture; keep it since that's the reversible choice.
|
||||
while read -r -t 0.1 -n 1 _ </dev/tty 2>/dev/null; do :; done
|
||||
echo ""
|
||||
if declare -f msg_error >/dev/null 2>&1; then
|
||||
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
|
||||
|
||||
+1
-1
@@ -201,7 +201,7 @@ network_check() {
|
||||
|
||||
# If both IPv4 and IPv6 checks fail, prompt the user
|
||||
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
|
||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
|
||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
|
||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
|
||||
+8
-8
@@ -1466,7 +1466,7 @@ prompt_for_github_token() {
|
||||
fi
|
||||
|
||||
local reply
|
||||
read -rp "${TAB}Would you like to enter a GitHub Personal Access Token (PAT)? [y/N]: " reply </dev/tty
|
||||
read -rp "${TAB}Would you like to enter a GitHub Personal Access Token (PAT)? [y/N]: " reply
|
||||
reply="${reply:-n}"
|
||||
|
||||
if [[ ! "${reply,,}" =~ ^(y|yes)$ ]]; then
|
||||
@@ -1475,7 +1475,7 @@ prompt_for_github_token() {
|
||||
|
||||
local token
|
||||
while true; do
|
||||
read -rp "${TAB}Enter your GitHub PAT: " token </dev/tty
|
||||
read -rp "${TAB}Enter your GitHub PAT: " token
|
||||
# Trim leading/trailing whitespace
|
||||
token="$(echo "$token" | xargs)"
|
||||
if [[ -z "$token" ]]; then
|
||||
@@ -3973,7 +3973,7 @@ _gh_scan_older_releases() {
|
||||
local use_fallback="y"
|
||||
if [[ -t 0 ]]; then
|
||||
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
|
||||
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback </dev/tty || use_fallback="y"
|
||||
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y"
|
||||
use_fallback="${use_fallback:-y}"
|
||||
fi
|
||||
|
||||
@@ -4796,7 +4796,7 @@ EOF
|
||||
for entry in "${compose_updates[@]}"; do
|
||||
IFS='|' read -r name image compose_workdir compose_service <<<"$entry"
|
||||
reply=""
|
||||
if read -r -t 60 -p "${TAB3}Update ${name} (${image}) via Compose? <y/N> (auto-no in 60s): " reply </dev/tty; then
|
||||
if read -r -t 60 -p "${TAB3}Update ${name} (${image}) via Compose? <y/N> (auto-no in 60s): " reply; then
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
@@ -4814,7 +4814,7 @@ EOF
|
||||
for entry in "${standalone_updates[@]}"; do
|
||||
IFS='|' read -r name image <<<"$entry"
|
||||
reply=""
|
||||
if read -r -t 60 -p "${TAB3}Pull new image for ${name} (${image})? <y/N> (auto-no in 60s): " reply </dev/tty; then
|
||||
if read -r -t 60 -p "${TAB3}Pull new image for ${name} (${image})? <y/N> (auto-no in 60s): " reply; then
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
@@ -5409,7 +5409,7 @@ setup_hwaccel() {
|
||||
# Read with 60 second timeout
|
||||
local selection=""
|
||||
echo -n "Select GPU(s) to configure (1-${gpu_count}, A=all) [timeout 60s, default=all]: "
|
||||
if read -r -t 60 selection </dev/tty; then
|
||||
if read -r -t 60 selection; then
|
||||
selection="${selection^^}" # uppercase
|
||||
else
|
||||
echo ""
|
||||
@@ -5457,7 +5457,7 @@ setup_hwaccel() {
|
||||
echo ""
|
||||
msg_custom "🎮" "${GN}" "NVIDIA GPU passthrough detected"
|
||||
local nvidia_reply=""
|
||||
read -r -t 60 -p "${TAB3}⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply </dev/tty || nvidia_reply=""
|
||||
read -r -t 60 -p "${TAB3}⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply || nvidia_reply=""
|
||||
case "${nvidia_reply,,}" in
|
||||
n | no) install_nvidia_drivers="no" ;;
|
||||
*) install_nvidia_drivers="yes" ;;
|
||||
@@ -9755,7 +9755,7 @@ _gl_scan_older_releases() {
|
||||
local use_fallback="y"
|
||||
if [[ -t 0 ]]; then
|
||||
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
|
||||
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback </dev/tty || use_fallback="y"
|
||||
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y"
|
||||
use_fallback="${use_fallback:-y}"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user