Translate user-facing docs and node help to English
README, NODES.md, install scripts, palette help text, and example flows — node .js logic unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,4 +25,4 @@ EOF
|
||||
fi
|
||||
|
||||
tar -cf /dev/null --exclude-from="${DI}" -C "${NODERED_DIR}" . \
|
||||
&& echo "[fix] Build context OK — kör ./install.sh"
|
||||
&& echo "[fix] Build context OK — run ./install.sh"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
# Snabbfix om git "dubious ownership" efter root-kloning
|
||||
# Quick fix if git reports "dubious ownership" after root clone
|
||||
set -euo pipefail
|
||||
DIR="${1:-/home/ncadmin/nextcloud-collabora-nodered}"
|
||||
USER="${2:-ncadmin}"
|
||||
echo "chown ${USER} ${DIR}"
|
||||
chown -R "${USER}:${USER}" "${DIR}"
|
||||
sudo -u "${USER}" git config --global --add safe.directory "${DIR}"
|
||||
echo "Klart. Kör: cd ${DIR} && ./install.sh"
|
||||
echo "Done. Run: cd ${DIR} && ./install.sh"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# integrate-into-nodered.sh — lägg Collabora-noder i BEFINTLIG nextcloud-node-red (:1880)
|
||||
# Anropas av install.sh / bootstrap-install.sh (standardläge).
|
||||
# integrate-into-nodered.sh — add Collabora nodes to EXISTING nextcloud-node-red (:1880)
|
||||
# Called by install.sh / bootstrap-install.sh (default mode).
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@@ -14,8 +14,8 @@ NEXTCLOUD_URL="${NEXTCLOUD_URL:-https://cloud.hannesahlin.se}"
|
||||
MARKER="nextcloud-collabora-nodered"
|
||||
|
||||
log() { printf '[integrate] %s\n' "$*"; }
|
||||
warn() { printf '[integrate] VARNING: %s\n' "$*" >&2; }
|
||||
die() { printf '[integrate] FEL: %s\n' "$*" >&2; exit 1; }
|
||||
warn() { printf '[integrate] WARNING: %s\n' "$*" >&2; }
|
||||
die() { printf '[integrate] ERROR: %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
run_as_root() {
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
@@ -23,7 +23,7 @@ run_as_root() {
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
sudo "$@"
|
||||
else
|
||||
die "sudo/root krävs för: $*"
|
||||
die "sudo/root required for: $*"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -45,12 +45,12 @@ patch_dockerignore() {
|
||||
local snippet="${PKG_SRC}/integrate/dockerignore.snippet"
|
||||
|
||||
if [ ! -f "${di}" ]; then
|
||||
log "Skapar .dockerignore"
|
||||
log "Creating .dockerignore"
|
||||
touch "${di}"
|
||||
fi
|
||||
|
||||
if ! grep -q "${DOCKERIGNORE_MARKER}" "${di}" 2>/dev/null; then
|
||||
log "Patchar .dockerignore (exkluderar oläsbara lokala artefakter)"
|
||||
log "Patching .dockerignore (exclude unreadable local artifacts)"
|
||||
{
|
||||
echo ""
|
||||
echo "# ${DOCKERIGNORE_MARKER}"
|
||||
@@ -72,7 +72,7 @@ patch_dockerignore() {
|
||||
while IFS= read -r relpath; do
|
||||
[ -n "${relpath}" ] || continue
|
||||
if ! grep -qxF "${relpath}" "${di}" 2>/dev/null; then
|
||||
log " + .dockerignore: ${relpath} (oläsbar)"
|
||||
log " + .dockerignore: ${relpath} (unreadable)"
|
||||
echo "${relpath}" >> "${di}"
|
||||
fi
|
||||
done < <(run_as_root find "${NODERED_DIR}/nodes" -type f ! -readable -printf 'nodes/%P\n' 2>/dev/null || true)
|
||||
@@ -87,7 +87,7 @@ fix_nodered_build_permissions() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Fixar ägande och läsrättigheter för ${NODERED_DIR} (innehåll orört)"
|
||||
log "Fixing ownership and read permissions for ${NODERED_DIR} (content unchanged)"
|
||||
run_as_root chown -R "${user}:${group}" "${NODERED_DIR}"
|
||||
run_as_root find "${NODERED_DIR}/nodes" -type d -exec chmod u+rwx,go+rx {} + 2>/dev/null || true
|
||||
run_as_root find "${NODERED_DIR}/nodes" -type f -exec chmod u+rw,go+r {} + 2>/dev/null || true
|
||||
@@ -102,24 +102,24 @@ verify_build_context() {
|
||||
local errfile
|
||||
errfile="$(mktemp)"
|
||||
|
||||
log "Verifierar Docker build context..."
|
||||
log "Verifying Docker build context..."
|
||||
patch_dockerignore
|
||||
|
||||
if ! run_as_root tar -cf /dev/null \
|
||||
--exclude-from="${di}" \
|
||||
-C "${NODERED_DIR}" . 2>"${errfile}"; then
|
||||
warn "Build context-fel:"
|
||||
warn "Build context error:"
|
||||
sed 's/^/[integrate] /' "${errfile}" >&2 || true
|
||||
# Sista utväg: tvinga bort kända problemfil
|
||||
if [ -f "${NODERED_DIR}/nodes/odds-scraper/odds-scraper" ]; then
|
||||
echo "nodes/odds-scraper/odds-scraper" >> "${di}"
|
||||
log "Tvingade nodes/odds-scraper/odds-scraper in i .dockerignore"
|
||||
log "Forced nodes/odds-scraper/odds-scraper into .dockerignore"
|
||||
fi
|
||||
if ! run_as_root tar -cf /dev/null \
|
||||
--exclude-from="${di}" \
|
||||
-C "${NODERED_DIR}" . 2>"${errfile}"; then
|
||||
rm -f "${errfile}"
|
||||
die "Build context oläsbar efter .dockerignore — se ${di}"
|
||||
die "Build context still unreadable after .dockerignore — see ${di}"
|
||||
fi
|
||||
fi
|
||||
rm -f "${errfile}"
|
||||
@@ -155,10 +155,10 @@ detect_code_ip() {
|
||||
return 0
|
||||
fi
|
||||
if [ -n "${COLLABORA_IP}" ]; then
|
||||
warn "Kunde inte läsa bridge-IP — använder COLLABORA_IP=${COLLABORA_IP}"
|
||||
warn "Could not read bridge IP — using COLLABORA_IP=${COLLABORA_IP}"
|
||||
return 0
|
||||
fi
|
||||
die "CODE bridge-IP saknas — sätt COLLABORA_IP eller kontrollera att ${CODE_CONTAINER} kör på Docker bridge"
|
||||
die "CODE bridge IP missing — set COLLABORA_IP or ensure ${CODE_CONTAINER} runs on Docker bridge"
|
||||
}
|
||||
|
||||
detect_nodered_dir() {
|
||||
@@ -170,7 +170,7 @@ detect_nodered_dir() {
|
||||
from_compose="$(docker inspect -f '{{index .Config.Labels "com.docker.compose.project.working_dir"}}' "${NODERED_CONTAINER}" 2>/dev/null || true)"
|
||||
if [ -n "${from_compose}" ] && [ -f "${from_compose}/Dockerfile" ]; then
|
||||
NODERED_DIR="${from_compose}"
|
||||
log "Node-RED-katalog från compose-label: ${NODERED_DIR}"
|
||||
log "Node-RED directory from compose label: ${NODERED_DIR}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -179,12 +179,12 @@ detect_nodered_dir() {
|
||||
"/opt/nextcloud-node-red"; do
|
||||
if [ -f "${candidate}/Dockerfile" ]; then
|
||||
NODERED_DIR="${candidate}"
|
||||
log "Node-RED-katalog hittad: ${NODERED_DIR}"
|
||||
log "Node-RED directory found: ${NODERED_DIR}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
die "NODERED_DIR saknas eller ogiltig — sätt sökväg till befintlig nextcloud-node-red (Dockerfile + entrypoint.sh)"
|
||||
die "NODERED_DIR missing or invalid — set path to existing nextcloud-node-red (Dockerfile + entrypoint.sh)"
|
||||
}
|
||||
|
||||
resolve_paths() {
|
||||
@@ -206,24 +206,24 @@ resolve_paths() {
|
||||
|
||||
stop_sidecar_if_any() {
|
||||
if docker ps -a --format '{{.Names}}' | grep -qx "nextcloud-collabora-nodered"; then
|
||||
warn "Stoppar felaktig sidecar-container nextcloud-collabora-nodered (skulle inte skapas)"
|
||||
warn "Stopping stray sidecar container nextcloud-collabora-nodered (should not exist)"
|
||||
docker stop nextcloud-collabora-nodered 2>/dev/null || true
|
||||
docker rm nextcloud-collabora-nodered 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
preflight() {
|
||||
[ -d "${PKG_SRC}" ] || die "Paketkälla saknas: ${PKG_SRC}"
|
||||
[ -f "${PKG_SRC}/package.json" ] || die "package.json saknas i ${PKG_SRC}"
|
||||
[ -d "${NODERED_DIR}" ] || die "nextcloud-node-red saknas: ${NODERED_DIR}"
|
||||
[ -f "${NODERED_DIR}/Dockerfile" ] || die "Dockerfile saknas i ${NODERED_DIR}"
|
||||
[ -f "${NODERED_DIR}/entrypoint.sh" ] || die "entrypoint.sh saknas i ${NODERED_DIR}"
|
||||
[ -d "${PKG_SRC}" ] || die "Package source missing: ${PKG_SRC}"
|
||||
[ -f "${PKG_SRC}/package.json" ] || die "package.json missing in ${PKG_SRC}"
|
||||
[ -d "${NODERED_DIR}" ] || die "nextcloud-node-red missing: ${NODERED_DIR}"
|
||||
[ -f "${NODERED_DIR}/Dockerfile" ] || die "Dockerfile missing in ${NODERED_DIR}"
|
||||
[ -f "${NODERED_DIR}/entrypoint.sh" ] || die "entrypoint.sh missing in ${NODERED_DIR}"
|
||||
|
||||
if ! docker ps --format '{{.Names}}' | grep -qx "${NODERED_CONTAINER}"; then
|
||||
die "Container '${NODERED_CONTAINER}' körs inte — starta befintlig nextcloud-node-red först"
|
||||
die "Container '${NODERED_CONTAINER}' is not running — start existing nextcloud-node-red first"
|
||||
fi
|
||||
if ! docker ps --format '{{.Names}}' | grep -qx "${CODE_CONTAINER}"; then
|
||||
die "CODE-container '${CODE_CONTAINER}' körs inte"
|
||||
die "CODE container '${CODE_CONTAINER}' is not running"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -232,25 +232,25 @@ assert_package_layout() {
|
||||
local missing=0
|
||||
|
||||
if [ ! -f "${dest}/package.json" ]; then
|
||||
warn "Saknas: ${dest}/package.json"
|
||||
warn "Missing: ${dest}/package.json"
|
||||
missing=1
|
||||
fi
|
||||
if [ ! -d "${dest}/lib" ] || [ -z "$(ls -A "${dest}/lib" 2>/dev/null)" ]; then
|
||||
warn "Saknas eller tom: ${dest}/lib/"
|
||||
warn "Missing or empty: ${dest}/lib/"
|
||||
missing=1
|
||||
fi
|
||||
if [ ! -d "${dest}/nodes" ] || [ -z "$(ls -A "${dest}/nodes" 2>/dev/null)" ]; then
|
||||
warn "Saknas eller tom: ${dest}/nodes/"
|
||||
warn "Missing or empty: ${dest}/nodes/"
|
||||
missing=1
|
||||
fi
|
||||
if [ "${missing}" -ne 0 ]; then
|
||||
die "Paketlayout fel efter kopiering — förväntat package.json + lib/ + nodes/ under ${dest}"
|
||||
die "Wrong package layout after copy — expected package.json + lib/ + nodes/ under ${dest}"
|
||||
fi
|
||||
}
|
||||
|
||||
copy_node_package() {
|
||||
local dest="${NODERED_DIR}/nodes/nextcloud-collabora"
|
||||
log "Kopierar paket → ${dest} (lib/ + nodes/, inte platt)"
|
||||
log "Copying package → ${dest} (lib/ + nodes/, not flat)"
|
||||
|
||||
rm -rf "${dest}"
|
||||
mkdir -p "${dest}/lib" "${dest}/nodes"
|
||||
@@ -265,16 +265,16 @@ copy_node_package() {
|
||||
fi
|
||||
|
||||
assert_package_layout "${dest}"
|
||||
log "Paketlayout OK: ${dest}/{package.json,lib/,nodes/}"
|
||||
log "Package layout OK: ${dest}/{package.json,lib/,nodes/}"
|
||||
}
|
||||
|
||||
patch_dockerfile() {
|
||||
local df="${NODERED_DIR}/Dockerfile"
|
||||
if grep -q "${MARKER}" "${df}"; then
|
||||
log "Dockerfile redan patchad"
|
||||
log "Dockerfile already patched"
|
||||
return 0
|
||||
fi
|
||||
log "Patchar Dockerfile"
|
||||
log "Patching Dockerfile"
|
||||
cat >> "${df}" <<'EOF'
|
||||
|
||||
# nextcloud-collabora-nodered — Collabora/Office-noder (WebDAV + CODE REST)
|
||||
@@ -291,16 +291,16 @@ patch_entrypoint() {
|
||||
|
||||
# Rensa trasig tidigare patch (rå cp-rader utan install_nodes)
|
||||
if grep -q 'cp -a /opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora' "${ep}"; then
|
||||
log "Rensar trasig collabora-patch i entrypoint.sh"
|
||||
log "Removing broken collabora patch from entrypoint.sh"
|
||||
sed -i '/cp -a \/opt\/nextcloud-nodes\/node-red-contrib-nextcloud-collabora/d' "${ep}"
|
||||
fi
|
||||
|
||||
if grep -q 'install_nodes.*Nextcloud Collabora' "${ep}"; then
|
||||
log "entrypoint.sh redan patchad (Collabora install_nodes)"
|
||||
log "entrypoint.sh already patched (Collabora install_nodes)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Patchar entrypoint.sh (install_nodes för Collabora)"
|
||||
log "Patching entrypoint.sh (install_nodes for Collabora)"
|
||||
if grep -q 'install_nodes.*Nextcloud OCS' "${ep}"; then
|
||||
sed -i '/install_nodes.*Nextcloud OCS/a\
|
||||
install_nodes "/opt/nextcloud-nodes/node-red-contrib-nextcloud-collabora" "/data/node_modules/node-red-contrib-nextcloud-collabora" "Nextcloud Collabora"' "${ep}"
|
||||
@@ -317,16 +317,16 @@ EOF
|
||||
}
|
||||
|
||||
connect_code_network() {
|
||||
log "Ansluter ${NODERED_CONTAINER} till Docker bridge (CODE)"
|
||||
log "Connecting ${NODERED_CONTAINER} to Docker bridge (CODE)"
|
||||
if docker network inspect bridge --format '{{range .Containers}}{{.Name}} {{end}}' 2>/dev/null | grep -q "${NODERED_CONTAINER}"; then
|
||||
log "Redan ansluten till bridge"
|
||||
log "Already connected to bridge"
|
||||
else
|
||||
docker network connect bridge "${NODERED_CONTAINER}" 2>/dev/null || warn "Kunde inte ansluta bridge — kontrollera manuellt"
|
||||
docker network connect bridge "${NODERED_CONTAINER}" 2>/dev/null || warn "Could not connect bridge — check manually"
|
||||
fi
|
||||
}
|
||||
|
||||
rebuild_nodered() {
|
||||
log "Bygger om ${NODERED_CONTAINER} (samma instans, port ${NODERED_PORT})..."
|
||||
log "Rebuilding ${NODERED_CONTAINER} (same instance, port ${NODERED_PORT})..."
|
||||
fix_nodered_build_permissions
|
||||
verify_build_context
|
||||
if [ "${FORCE_REBUILD:-0}" = "1" ]; then
|
||||
@@ -338,36 +338,36 @@ rebuild_nodered() {
|
||||
}
|
||||
|
||||
wait_nodered() {
|
||||
log "Väntar på Node-RED :${NODERED_PORT}..."
|
||||
log "Waiting for Node-RED :${NODERED_PORT}..."
|
||||
for i in $(seq 1 30); do
|
||||
if curl -sf "http://127.0.0.1:${NODERED_PORT}" >/dev/null 2>&1; then
|
||||
log "Node-RED svarar på http://127.0.0.1:${NODERED_PORT}"
|
||||
log "Node-RED responding at http://127.0.0.1:${NODERED_PORT}"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
warn "Node-RED svarade inte inom 60 s"
|
||||
warn "Node-RED did not respond within 60 s"
|
||||
}
|
||||
|
||||
verify_code_from_nodered() {
|
||||
local code_ip
|
||||
code_ip="$(code_bridge_ip)"
|
||||
[ -n "${code_ip}" ] || code_ip="${COLLABORA_IP}"
|
||||
# CODE lyssnar på HTTPS internt (HTTP ger tom svar)
|
||||
# CODE listens on HTTPS internally (HTTP returns empty reply)
|
||||
local url="https://${code_ip}:9980/hosting/capabilities"
|
||||
log "Testar CODE från ${NODERED_CONTAINER}: ${url}"
|
||||
log "Testing CODE from ${NODERED_CONTAINER}: ${url}"
|
||||
if docker exec "${NODERED_CONTAINER}" curl -sfk "${url}" >/dev/null 2>&1; then
|
||||
log "OK: CODE nås från befintlig Node-RED-container"
|
||||
log "OK: CODE reachable from Node-RED container"
|
||||
else
|
||||
warn "CODE nås inte — kör: docker network connect bridge ${NODERED_CONTAINER}"
|
||||
warn "CODE not reachable — run: docker network connect bridge ${NODERED_CONTAINER}"
|
||||
warn "nc-collab-config collaboraUrl=https://${code_ip}:9980 (verifyTls=false)"
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
resolve_paths
|
||||
log "Integrerar Collabora-noder i befintlig nextcloud-node-red"
|
||||
log "Paket: ${PKG_SRC}"
|
||||
log "Integrating Collabora nodes into existing nextcloud-node-red"
|
||||
log "Package: ${PKG_SRC}"
|
||||
log "Node-RED: ${NODERED_DIR} (container ${NODERED_CONTAINER})"
|
||||
|
||||
stop_sidecar_if_any
|
||||
@@ -388,18 +388,18 @@ main() {
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Integrering klar — samma Node-RED på port ${NODERED_PORT}
|
||||
Integrating done — same Node-RED on port ${NODERED_PORT}
|
||||
UI: http://${host_ip}:${NODERED_PORT}
|
||||
Noder: palett "nextcloud collabora" (6 st + config)
|
||||
Palette: "nextcloud collabora" (6 nodes + config)
|
||||
|
||||
Skapa config först (kugghjul → nc-collab-config):
|
||||
Create config first (gear → nc-collab-config):
|
||||
Nextcloud: ${nc_url}
|
||||
Collabora: https://${code_ip}:9980 (verifyTls=false)
|
||||
Publik WOPI: ${nc_url}
|
||||
Auth: användarnamn + app-lösenord
|
||||
Public WOPI: ${nc_url}
|
||||
Auth: username + app password
|
||||
|
||||
Testa: collabora-wopi (capabilities) → collabora-bridge (ncFileToPdf)
|
||||
Exempelflöde: flows/example-flows.json
|
||||
Try: collabora-wopi (capabilities) → collabora-bridge (ncFileToPdf)
|
||||
Example flow: flows/example-flows.json
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user