notes: private Obsidian vault tracker at /trackers/notes
All checks were successful
Deploy production / deploy (push) Successful in 1m19s
All checks were successful
Deploy production / deploy (push) Successful in 1m19s
Vault files stay the source of truth (bind-mounted read-write at /notes): atomic writes chowned to the vault owner, hash-checked saves (409 on a newer file), deletes to .trash. notes.* is a full-text/link index kept current by a recursive watcher plus a 60s rescan; live updates over the owner-only /ws/notes channel (paths and hashes only). Wikilinks, embeds, backlinks, tags, callouts, image paste. Owner-only everywhere (404).
This commit is contained in:
@@ -262,6 +262,30 @@ try {
|
||||
const [{ n: worldtodoTasks }] = await client`select count(*)::int as n from worldtodo.tasks`;
|
||||
if (worldtodoTasks < 68)
|
||||
throw new Error(`worldtodo.tasks has ${worldtodoTasks} rows, expected the 68 seed tasks`);
|
||||
// Notes (always private; only a search/link index of the Obsidian vault): app role read/write,
|
||||
// personal_ro none. 2 = files, links.
|
||||
const NOTES_TABLES = 2;
|
||||
const [notes] = await client`
|
||||
select
|
||||
count(*) filter (where has_table_privilege(c.oid, 'select, insert, update, delete')) as app_rw,
|
||||
count(*) filter (
|
||||
where exists (
|
||||
select 1 from aclexplode(c.relacl) a join pg_roles r on r.oid = a.grantee
|
||||
where r.rolname = 'personal_ro'
|
||||
)
|
||||
) as ro_read,
|
||||
count(*) as tables,
|
||||
has_schema_privilege('public', 'notes', 'usage') as public_usage
|
||||
from pg_class c join pg_namespace n on n.oid = c.relnamespace
|
||||
where n.nspname = 'notes' and c.relkind = 'r'
|
||||
`;
|
||||
if (
|
||||
Number(notes.tables) !== NOTES_TABLES ||
|
||||
Number(notes.app_rw) !== NOTES_TABLES ||
|
||||
Number(notes.ro_read) !== 0 ||
|
||||
notes.public_usage
|
||||
)
|
||||
throw new Error(`notes schema tables/grants are wrong: ${JSON.stringify(notes)}`);
|
||||
// Energy tracker reads the ned-collector tables (SELECT only).
|
||||
const [energy] = await client`
|
||||
select count(*) as hours, max(valid_from) as latest from energy.ned_utilization
|
||||
@@ -271,7 +295,7 @@ try {
|
||||
if (!Number(energy.hours))
|
||||
console.warn('Warning: energy.ned_utilization has no hourly data from the last 7 days');
|
||||
console.log(
|
||||
`health: ${health.tables} tables, tasks: ${tasks.tables} tables, groceries: ${groceries.tables} tables, stats: ${stats.tables} tables, ai: ${ai.tables} tables, movies: ${movies.tables} tables, worldtodo: ${worldtodo.tables} tables (${worldtodoTasks} tasks), app read/write, personal_ro none; energy: ${energy.hours} hourly rows, latest ${energy.latest ? new Date(energy.latest).toISOString() : 'none'}`
|
||||
`health: ${health.tables} tables, tasks: ${tasks.tables} tables, groceries: ${groceries.tables} tables, stats: ${stats.tables} tables, ai: ${ai.tables} tables, movies: ${movies.tables} tables, worldtodo: ${worldtodo.tables} tables (${worldtodoTasks} tasks), notes: ${notes.tables} tables, app read/write, personal_ro none; energy: ${energy.hours} hourly rows, latest ${energy.latest ? new Date(energy.latest).toISOString() : 'none'}`
|
||||
);
|
||||
const [catalog] = await client`
|
||||
select
|
||||
|
||||
@@ -108,6 +108,30 @@ YAML
|
||||
else
|
||||
echo "No $pubg_tiles_host_dir/erangel on this host; the PUBG map will have no tiles" >&2
|
||||
fi
|
||||
# Notes tracker: the Obsidian vault (Syncthing folder "obsidian-vault") is bind-mounted READ-WRITE
|
||||
# at /notes. The files are the source of truth; the site edits them in place (atomic temp+rename,
|
||||
# chowned to the vault owner) and keeps notes.* as a search/link index. Owner-only in the app.
|
||||
notes_host_dir=${NOTES_HOST_DIR:-/home/stan/obsidian-vault}
|
||||
case "$notes_host_dir" in /*) ;; *) echo 'NOTES_HOST_DIR must be absolute' >&2; exit 2 ;; esac
|
||||
if sudo docker run --rm --entrypoint sh \
|
||||
--mount "type=bind,source=$notes_host_dir,target=/notes,readonly" "$image" \
|
||||
-c 'test -d /notes/.obsidian' 2>/dev/null; then
|
||||
notes_override="$HOME/compose.notes.yml"
|
||||
rm -f "$notes_override"
|
||||
cat >"$notes_override" <<YAML
|
||||
services:
|
||||
app:
|
||||
environment:
|
||||
NOTES_ROOT: /notes
|
||||
volumes:
|
||||
- type: bind
|
||||
source: $notes_host_dir
|
||||
target: /notes
|
||||
YAML
|
||||
compose_files+=(-f "$notes_override")
|
||||
else
|
||||
echo "No Obsidian vault at $notes_host_dir on this host; the notes tracker will be empty" >&2
|
||||
fi
|
||||
previous_tag=$(sed -n 's/^IMAGE_TAG=//p' "$directory/.env" | head -n 1)
|
||||
switched=0
|
||||
rollback() {
|
||||
|
||||
Reference in New Issue
Block a user