Put every tmpfs path in one place both layers can read
This commit is contained in:
@@ -122,6 +122,44 @@
|
|||||||
STATE_DIR="/boot/config/plugins/varaverk/State_Files"
|
STATE_DIR="/boot/config/plugins/varaverk/State_Files"
|
||||||
PERSISTENT_CONF_CACHE="/boot/config/plugins/varaverk/.cache/vv/d"
|
PERSISTENT_CONF_CACHE="/boot/config/plugins/varaverk/.cache/vv/d"
|
||||||
|
|
||||||
|
# ── Cache Roots ──
|
||||||
|
# Everything Varaverk keeps in RAM, under one root, defined once.
|
||||||
|
#
|
||||||
|
# These used to be four literals in load_config.sh and three more in the PHP layer, spread over
|
||||||
|
# /tmp/vv_cache, /tmp/arr_cache, /tmp/.cache/vv/d, /tmp/.cache/vv/ai and /tmp/varaverk_ai_jobs —
|
||||||
|
# five naming schemes, and no single place that could tell you what Varaverk had in tmpfs. PHP
|
||||||
|
# could not read load_config.sh, so it restated the paths it needed and the two layers were kept
|
||||||
|
# in agreement by hand. They live here because master.conf is the one file both layers actually
|
||||||
|
# read: bash sources it, and the PHP conf parser resolves ${VAR} against it the same way.
|
||||||
|
#
|
||||||
|
# ONE ROOT, NOT ONE DIRECTORY. The subdirectories are deliberately separate and must stay that
|
||||||
|
# way — they have genuinely different rules:
|
||||||
|
#
|
||||||
|
# conf/ holds partner credentials, is chmod 700, and IS snapshotted to PERSISTENT_CONF_CACHE
|
||||||
|
# so it survives a reboot.
|
||||||
|
# ai/ holds non-secret token counters that are worthless when stale and must NOT be
|
||||||
|
# preserved across a reboot — losing them means "not collected here" until the next
|
||||||
|
# sync, which is the honest answer.
|
||||||
|
# jobs/ holds in-flight work handed off to a detached worker — an AI answer being generated,
|
||||||
|
# a container action being applied. chmod 700: each is readable by anyone who can guess
|
||||||
|
# its token, which is why the tokens are random_bytes and not sequential.
|
||||||
|
# arr/ is the large one (100s of MB) and is restored from a DATA_DIR backup on demand.
|
||||||
|
# api/ is the WebGUI payload cache, and is the only one safe to delete at any moment.
|
||||||
|
#
|
||||||
|
# Collapsing those into a single directory would give the credentials the token cache's
|
||||||
|
# persistence rules, or the reverse. The win here is one definition, not one folder.
|
||||||
|
#
|
||||||
|
# Point VV_CACHE_ROOT somewhere else and everything follows. It must be on a filesystem that is
|
||||||
|
# cleared or safe to clear on boot — every consumer treats a missing cache as a cold start, and
|
||||||
|
# nothing here is a source of truth for anything.
|
||||||
|
VV_CACHE_ROOT="/tmp/varaverk"
|
||||||
|
VV_CACHE_DIR="${VV_CACHE_ROOT}/api" # WebGUI payload cache — monitor, arrs, ai
|
||||||
|
CONF_RAM_CACHE_DIR="${VV_CACHE_ROOT}/conf" # partner host*.conf — chmod 700, snapshotted
|
||||||
|
ARR_CACHE_DIR="${VV_CACHE_ROOT}/arr" # arr payloads — restored from DATA_DIR on demand
|
||||||
|
AI_TOKEN_CACHE_DIR="${VV_CACHE_ROOT}/ai" # partner token ledgers — never preserved
|
||||||
|
AI_JOB_DIR="${VV_CACHE_ROOT}/jobs/ai" # in-flight AI answers — chmod 700
|
||||||
|
DOCKER_JOB_DIR="${VV_CACHE_ROOT}/jobs/docker" # in-flight container actions — chmod 700
|
||||||
|
|
||||||
# ── Version Parity ──
|
# ── Version Parity ──
|
||||||
# Controls behaviour when local and remote unRAID versions differ.
|
# Controls behaviour when local and remote unRAID versions differ.
|
||||||
# Major version mismatch always aborts regardless of this setting.
|
# Major version mismatch always aborts regardless of this setting.
|
||||||
|
|||||||
@@ -95,7 +95,9 @@ header('Content-Type: application/json');
|
|||||||
// take, because the operator's next move is to try again on a machine that already did it.
|
// take, because the operator's next move is to try again on a machine that already did it.
|
||||||
require_once dirname(__DIR__) . '/include/config.php';
|
require_once dirname(__DIR__) . '/include/config.php';
|
||||||
|
|
||||||
define('VV_JOB_DIR', '/tmp/varaverk_dk_jobs');
|
// VV_JOB_DIR is defined in config.php with every other tmpfs path, read from DOCKER_JOB_DIR in
|
||||||
|
// master.conf. It was declared here, inside an endpoint, which is why a survey of Varaverk's
|
||||||
|
// cache and job directories missed it entirely.
|
||||||
|
|
||||||
$action = trim($_POST['action'] ?? '');
|
$action = trim($_POST['action'] ?? '');
|
||||||
$name = trim($_POST['name'] ?? '');
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
|||||||
@@ -79,7 +79,8 @@
|
|||||||
|
|
||||||
require_once __DIR__ . '/config.php';
|
require_once __DIR__ . '/config.php';
|
||||||
|
|
||||||
define('VV_AI_JOB_DIR', '/tmp/varaverk_ai_jobs');
|
// VV_AI_JOB_DIR and VV_AI_TOKEN_CACHE_DIR are defined in config.php with every other cache path,
|
||||||
|
// read from master.conf so this layer and load_config.sh cannot disagree about where they are.
|
||||||
const VV_AI_KINDS = ['header', 'readme', 'manual', 'template', 'doc'];
|
const VV_AI_KINDS = ['header', 'readme', 'manual', 'template', 'doc'];
|
||||||
|
|
||||||
// Profiles — what each one is, and what it is allowed to see and do. One table, in one file,
|
// Profiles — what each one is, and what it is allowed to see and do. One table, in one file,
|
||||||
@@ -671,10 +672,9 @@ function vv_ai_token_prune(string $db): void {
|
|||||||
// Partner ledgers pulled by AI/ai_token_sync.sh into tmpfs. Same trick conf_sync.sh uses for
|
// Partner ledgers pulled by AI/ai_token_sync.sh into tmpfs. Same trick conf_sync.sh uses for
|
||||||
// partner confs: the reader treats a missing file as "unknown", never as zero.
|
// partner confs: the reader treats a missing file as "unknown", never as zero.
|
||||||
//
|
//
|
||||||
// Mirrors AI_TOKEN_CACHE_DIR in load_config.sh. Hardcoded rather than read from conf because it
|
// The directory is AI_TOKEN_CACHE_DIR from master.conf, resolved in config.php. It used to be
|
||||||
// is a derived path constant on the shell side too — neither end reads it from a conf file, so
|
// hardcoded here, on the reasoning that the shell side hardcoded it too and so there was no
|
||||||
// there is no single value to drift away from.
|
// single value to drift away from — true when it was written, and no longer true.
|
||||||
const VV_AI_TOKEN_CACHE_DIR = '/tmp/.cache/vv/ai';
|
|
||||||
|
|
||||||
// Aggregates the file into today / last 7 days / all time, both overall and per host.
|
// Aggregates the file into today / last 7 days / all time, both overall and per host.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -57,7 +57,8 @@
|
|||||||
// master.conf HOST<n> / HOST<n>_NAME — host identity
|
// master.conf HOST<n> / HOST<n>_NAME — host identity
|
||||||
// host*.conf HOST*_SSH_KEY — used for setup-state and conf push
|
// host*.conf HOST*_SSH_KEY — used for setup-state and conf push
|
||||||
// ident.cfg timeZone — Unraid's own setting, adopted for the whole PHP layer
|
// ident.cfg timeZone — Unraid's own setting, adopted for the whole PHP layer
|
||||||
// VV_CACHE_DIR /tmp/vv_cache (tmpfs — RAM speed, cleared on reboot)
|
// master.conf VV_CACHE_ROOT and the cache paths derived from it — shared with
|
||||||
|
// load_config.sh, which reads the same keys from the same file
|
||||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
// ── Timezone ──────────────────────────────────────────────────────────────────
|
// ── Timezone ──────────────────────────────────────────────────────────────────
|
||||||
@@ -113,7 +114,45 @@ define('CUSTOM_SCRIPTS_DIR', $_vv_cfg['CUSTOM_SCRIPTS_DIR'] ?? '/boot/config/plu
|
|||||||
unset($_vv_cfg);
|
unset($_vv_cfg);
|
||||||
|
|
||||||
define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db');
|
define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db');
|
||||||
define('VV_CACHE_DIR', '/tmp/vv_cache');
|
|
||||||
|
// ── Cache roots ───────────────────────────────────────────────────────────────
|
||||||
|
// Read from master.conf so this layer and load_config.sh resolve the same paths from the same
|
||||||
|
// line. They used to be literals in three PHP files, restating what load_config.sh already said,
|
||||||
|
// because PHP cannot source bash — and the two sets were kept in agreement by hand.
|
||||||
|
//
|
||||||
|
// Deliberately NOT via vv_conf_vars(). That parses master.conf and this host's conf in full and
|
||||||
|
// calls vv_detect_host() on the way, and api/monitor.php's documented fast path loads this file
|
||||||
|
// and nothing else in order to reach vv_cache_read() on a cache hit. Making every request pay a
|
||||||
|
// full conf parse to learn a directory name would tax the exact path built to be cheap. One
|
||||||
|
// file, seven keys, no host detection.
|
||||||
|
//
|
||||||
|
// The fallbacks are the pre-consolidation paths, matching load_config.sh: an installation whose
|
||||||
|
// conf has not been through conf_upgrade yet keeps using what it is already using, rather than
|
||||||
|
// silently relocating its caches because a variable was missing.
|
||||||
|
$_vv_cache = [];
|
||||||
|
foreach (@file(CONF_DIR . '/master.conf') ?: [] as $_l) {
|
||||||
|
if (preg_match('/^\s*(VV_CACHE_ROOT|VV_CACHE_DIR|CONF_RAM_CACHE_DIR|ARR_CACHE_DIR'
|
||||||
|
. '|AI_TOKEN_CACHE_DIR|AI_JOB_DIR|DOCKER_JOB_DIR)\s*=\s*"?([^"#\r\n]+?)"?\s*(?:#.*)?$/',
|
||||||
|
$_l, $_m)) {
|
||||||
|
$_vv_cache[$_m[1]] = trim($_m[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_vv_root = $_vv_cache['VV_CACHE_ROOT'] ?? '/tmp/varaverk';
|
||||||
|
// Resolves the one reference the conf actually uses. This is not a general bash expander and is
|
||||||
|
// not trying to be — vv_conf_vars() owns that, and every value here is one level deep by design.
|
||||||
|
$_vv_path = function (string $key, string $fallback) use ($_vv_cache, $_vv_root): string {
|
||||||
|
$v = trim($_vv_cache[$key] ?? '');
|
||||||
|
if ($v === '') return $fallback;
|
||||||
|
return str_replace(['${VV_CACHE_ROOT}', '$VV_CACHE_ROOT'], $_vv_root, $v);
|
||||||
|
};
|
||||||
|
define('VV_CACHE_ROOT', $_vv_root);
|
||||||
|
define('VV_CACHE_DIR', $_vv_path('VV_CACHE_DIR', '/tmp/vv_cache'));
|
||||||
|
define('VV_CONF_RAM_CACHE_DIR', $_vv_path('CONF_RAM_CACHE_DIR', '/tmp/.cache/vv/d'));
|
||||||
|
define('VV_ARR_CACHE_DIR', $_vv_path('ARR_CACHE_DIR', '/tmp/arr_cache'));
|
||||||
|
define('VV_AI_TOKEN_CACHE_DIR', $_vv_path('AI_TOKEN_CACHE_DIR', '/tmp/.cache/vv/ai'));
|
||||||
|
define('VV_AI_JOB_DIR', $_vv_path('AI_JOB_DIR', '/tmp/varaverk_ai_jobs'));
|
||||||
|
define('VV_JOB_DIR', $_vv_path('DOCKER_JOB_DIR', '/tmp/varaverk_dk_jobs'));
|
||||||
|
unset($_vv_cache, $_vv_root, $_vv_path, $_l, $_m);
|
||||||
|
|
||||||
// Read the setup state file into a key=>value array.
|
// Read the setup state file into a key=>value array.
|
||||||
function vv_setup_state_read(): array {
|
function vv_setup_state_read(): array {
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ for host_var in $(compgen -v | grep -E '^HOST[0-9]+$' | sort); do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
warn "DRY RUN — would push ${MY_ID,,}.conf → $partner_host:/tmp/.cache/vv/d/"
|
warn "DRY RUN — would push ${MY_ID,,}.conf → $partner_host:$CACHE_DIR/"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,11 @@ require_partnership
|
|||||||
[[ "${CONF_SYNC_ENABLED:-true}" != "true" ]] && exit 0
|
[[ "${CONF_SYNC_ENABLED:-true}" != "true" ]] && exit 0
|
||||||
[[ -z "${REMOTE_ID:-}" ]] && exit 0
|
[[ -z "${REMOTE_ID:-}" ]] && exit 0
|
||||||
|
|
||||||
RAM_CACHE="/tmp/.cache/vv/d"
|
# The exported variable, not a literal. This was hardcoded while load_config.sh already exported
|
||||||
|
# CONF_RAM_CACHE_DIR, so the watchdog would have gone on watching an empty directory the moment
|
||||||
|
# that path moved — and reported the cache healthy because nothing was ever missing from a
|
||||||
|
# location nothing writes to.
|
||||||
|
RAM_CACHE="$CONF_RAM_CACHE_DIR"
|
||||||
SAVE_DIR="${PERSISTENT_CONF_CACHE:-}"
|
SAVE_DIR="${PERSISTENT_CONF_CACHE:-}"
|
||||||
|
|
||||||
# SAVE_DIR is rm -rf'd below and is built from ${SCRIPTS_DIR}. If that is ever unset the
|
# SAVE_DIR is rm -rf'd below and is built from ${SCRIPTS_DIR}. If that is ever unset the
|
||||||
|
|||||||
+26
-13
@@ -76,8 +76,9 @@
|
|||||||
#
|
#
|
||||||
# It then defines the paths the rest of the ecosystem builds on:
|
# It then defines the paths the rest of the ecosystem builds on:
|
||||||
#
|
#
|
||||||
# CONF_RAM_CACHE_DIR /tmp/.cache/vv/d — tmpfs partner conf cache, cleared each reboot
|
# VV_CACHE_ROOT everything Varaverk keeps in RAM, one root, defined in master.conf
|
||||||
# ARR_CACHE_DIR /tmp/arr_cache — tmpfs, restored from DATA_DIR on demand
|
# CONF_RAM_CACHE_DIR $VV_CACHE_ROOT/conf — partner conf cache, chmod 700, snapshotted
|
||||||
|
# ARR_CACHE_DIR $VV_CACHE_ROOT/arr — restored from DATA_DIR on demand
|
||||||
#
|
#
|
||||||
# Everything else (STATE_DIR, DATA_DIR, thresholds, credentials) comes out of master.conf and
|
# Everything else (STATE_DIR, DATA_DIR, thresholds, credentials) comes out of master.conf and
|
||||||
# host*.conf, which this file sources rather than defines.
|
# host*.conf, which this file sources rather than defines.
|
||||||
@@ -130,6 +131,23 @@
|
|||||||
fi
|
fi
|
||||||
source "$LOAD_CONFIG_DIR/Configurations/master.conf"
|
source "$LOAD_CONFIG_DIR/Configurations/master.conf"
|
||||||
|
|
||||||
|
# ━━━ Cache roots ━━━
|
||||||
|
# Resolved here, immediately after master.conf, rather than with the other derived paths further
|
||||||
|
# down — the partner-conf cache is read a few lines below to source HOST2_* vars, and that block
|
||||||
|
# used to carry its own copy of the path precisely because the variable did not exist yet at that
|
||||||
|
# point. Defining these the moment master.conf provides them removes the reason for the copy.
|
||||||
|
#
|
||||||
|
# The fallbacks are the pre-consolidation paths: an installation whose conf has not been through
|
||||||
|
# conf_upgrade keeps using what it is already using rather than silently relocating its caches.
|
||||||
|
# The PHP layer reads the same keys out of the same file, with the same fallbacks.
|
||||||
|
VV_CACHE_ROOT="${VV_CACHE_ROOT:-/tmp/varaverk}"
|
||||||
|
VV_CACHE_DIR="${VV_CACHE_DIR:-/tmp/vv_cache}"
|
||||||
|
CONF_RAM_CACHE_DIR="${CONF_RAM_CACHE_DIR:-/tmp/.cache/vv/d}"
|
||||||
|
ARR_CACHE_DIR="${ARR_CACHE_DIR:-/tmp/arr_cache}"
|
||||||
|
AI_TOKEN_CACHE_DIR="${AI_TOKEN_CACHE_DIR:-/tmp/.cache/vv/ai}"
|
||||||
|
AI_JOB_DIR="${AI_JOB_DIR:-/tmp/varaverk_ai_jobs}"
|
||||||
|
DOCKER_JOB_DIR="${DOCKER_JOB_DIR:-/tmp/varaverk_dk_jobs}"
|
||||||
|
|
||||||
# ━━━ Auto-discover and source all host*.conf files ━━━
|
# ━━━ Auto-discover and source all host*.conf files ━━━
|
||||||
# Sorted for consistent load order — HOST1 before HOST2 before HOST3 etc.
|
# Sorted for consistent load order — HOST1 before HOST2 before HOST3 etc.
|
||||||
# Each host conf extends the shared PROFILE_* arrays and adds host-specific vars.
|
# Each host conf extends the shared PROFILE_* arrays and adds host-specific vars.
|
||||||
@@ -160,7 +178,7 @@
|
|||||||
# (HOST2_*, HOST3_*, …) available without committing credentials to the git repo
|
# (HOST2_*, HOST3_*, …) available without committing credentials to the git repo
|
||||||
# or violating sparse checkout — partner confs live in RAM only, cleared on reboot.
|
# or violating sparse checkout — partner confs live in RAM only, cleared on reboot.
|
||||||
# Confs already loaded from disk are skipped — disk copy is authoritative.
|
# Confs already loaded from disk are skipped — disk copy is authoritative.
|
||||||
_VV_CONF_CACHE="/tmp/.cache/vv/d"
|
_VV_CONF_CACHE="$CONF_RAM_CACHE_DIR"
|
||||||
if [[ -d "$_VV_CONF_CACHE" ]]; then
|
if [[ -d "$_VV_CONF_CACHE" ]]; then
|
||||||
while IFS= read -r _conf; do
|
while IFS= read -r _conf; do
|
||||||
[[ -f "$_conf" ]] || continue
|
[[ -f "$_conf" ]] || continue
|
||||||
@@ -195,16 +213,11 @@
|
|||||||
# re-deriving from SCRIPTS_DIR or hardcoding /var/log or /tmp paths inline.
|
# re-deriving from SCRIPTS_DIR or hardcoding /var/log or /tmp paths inline.
|
||||||
CONF_DIR="${SCRIPTS_DIR}/Configurations"
|
CONF_DIR="${SCRIPTS_DIR}/Configurations"
|
||||||
LOG_DIR="/var/log/varaverk"
|
LOG_DIR="/var/log/varaverk"
|
||||||
VV_CACHE_DIR="/tmp/vv_cache"
|
|
||||||
CONF_RAM_CACHE_DIR="/tmp/.cache/vv/d" # tmpfs — cleared every reboot, repopulated by conf_sync.sh
|
# Cache roots were resolved right after master.conf was sourced, because the partner-conf
|
||||||
ARR_CACHE_DIR="/tmp/arr_cache" # tmpfs — cleared every reboot, restored from DATA_DIR backup by arr_cache_age_seconds()
|
# cache is read before this point. Exported here with the rest.
|
||||||
# Partner AI ledgers pulled by AI/ai_token_sync.sh. A sibling of the conf cache rather than
|
export CONF_DIR LOG_DIR VV_CACHE_ROOT VV_CACHE_DIR CONF_RAM_CACHE_DIR ARR_CACHE_DIR \
|
||||||
# the same directory: that one holds credentials at chmod 700 and is snapshotted to /boot by
|
AI_TOKEN_CACHE_DIR AI_JOB_DIR DOCKER_JOB_DIR
|
||||||
# conf_cache_save.sh. These are non-secret counters that are worthless when stale, so they
|
|
||||||
# must not be preserved across a reboot — losing them just means "not collected here" until
|
|
||||||
# the next sync, which is the honest answer anyway.
|
|
||||||
AI_TOKEN_CACHE_DIR="/tmp/.cache/vv/ai" # tmpfs — cleared every reboot, repopulated by ai_token_sync.sh
|
|
||||||
export CONF_DIR LOG_DIR VV_CACHE_DIR CONF_RAM_CACHE_DIR ARR_CACHE_DIR AI_TOKEN_CACHE_DIR
|
|
||||||
|
|
||||||
# ━━━ Cleanup ━━━
|
# ━━━ Cleanup ━━━
|
||||||
unset _conf _host_confs_loaded _adapter LOAD_CONFIG_DIR
|
unset _conf _host_confs_loaded _adapter LOAD_CONFIG_DIR
|
||||||
Reference in New Issue
Block a user