mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 17:47:05 +01:00
warp-window: home window 07:00-17:00
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Shell tests / shell-tests (push) Has been cancelled
Shell tests / lib-tests (push) Has been cancelled
Shell tests / arch-tests (push) Has been cancelled
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Has been cancelled
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Shell tests / shell-tests (push) Has been cancelled
Shell tests / lib-tests (push) Has been cancelled
Shell tests / arch-tests (push) Has been cancelled
Mon/Thu/Fri WARP window at home widens from 08:00-16:00 to 07:00-17:00. Away from home WARP stays always available. Prunes the oldest evidence file for the 60-file cap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzxdWVh2cxQQcZ54imRZXw
This commit is contained in:
parent
1a56a77ff6
commit
7e9fdefde4
@ -120,8 +120,8 @@ with no internet. So the laptop runs `warp-home` (user timer, every 30 s): at
|
||||
home with no window open it turns WARP off, and plain internet with the
|
||||
blocklist comes back. On any other network (office) it never touches WARP.
|
||||
|
||||
- Mon/Thu/Fri 08:00-16:00 at home: `warp-home on` asks the PC, then connects.
|
||||
The PC opens WARP for the LAN until 16:00 sharp, then closes by itself.
|
||||
- Mon/Thu/Fri 07:00-17:00 at home: `warp-home on` asks the PC, then connects.
|
||||
The PC opens WARP for the LAN until 17:00 sharp, then closes by itself.
|
||||
Outside that window the PC refuses. `warp-home off` / `warp-home status`.
|
||||
- Window closed early (the PC firewall was re-applied): `warp-home on` again.
|
||||
- PC side by hand: `sudo warp-window open|close|status`.
|
||||
@ -139,4 +139,4 @@ blocklist comes back. On any other network (office) it never touches WARP.
|
||||
real IPv6 address); Firefox DoH canary + DoH hostnames blocked; DHCP lease
|
||||
12h -> 2h; gateway mode added (nextcloud-pi and the P110 plug exempt).
|
||||
- 2026-10-25: WARP tunnel dropped at the gateway (work laptop bypassed the
|
||||
DNS block through it); Mon/Thu/Fri 08:00-16:00 window via `warp-home on`.
|
||||
DNS block through it); Mon/Thu/Fri 07:00-17:00 window via `warp-home on`.
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "WARP home window: widen to 07:00-17:00",
|
||||
"objective": "kuhy can run `warp-home on` on the work laptop at home Mon/Thu/Fri 07:00-17:00 (was 08:00-16:00); the PC's clock still decides, WARP stays blocked at home outside that window, and on any other network WARP is always available.",
|
||||
"acceptance_criteria": [
|
||||
"warp_window.sh open succeeds only Mon/Thu/Fri 07:00:00-16:59:59 and fills warp_open with a timeout ending at 17:00; Tue/Wed/Sat/Sun stay closed (test_warp_window.sh)",
|
||||
"warp_home.sh messages name Mon/Thu/Fri 07:00-17:00 and the 17:00 cut-off; away from home tick never touches WARP and on connects without the PC (test_warp_home.sh)",
|
||||
"Live: Monday 07:56 the installed PC script reports the window open until 17:00 and `warp-home on` connects WARP"
|
||||
],
|
||||
"out_of_scope": [
|
||||
"Window days, install path, sudoers entry and authorized_keys forced command (unchanged)",
|
||||
"Jail-only suites in features/lib/tests (dwm, nc_php, rpi_nc, dot_resolver_install, website_admin)"
|
||||
],
|
||||
"verifier": "linux_configuration/features/lib/tests/test_warp_window.sh; linux_configuration/features/lib/tests/test_warp_home.sh; on the laptop: warp-home on && warp-home status"
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"intent": "The home WARP window for the work laptop opens Mon/Thu/Fri 07:00-17:00 instead of 08:00-16:00. Away from home WARP stays always available, any day or time.",
|
||||
"scope": [
|
||||
"linux_configuration/features/warp_window.sh (PC, enforces the window)",
|
||||
"linux_configuration/features/warp_home.sh (laptop, messages only)",
|
||||
"DOCS-lan-blocker-contingency.md, test_warp_window.sh, test_warp_home.sh",
|
||||
"No change to days, install, sudoers, the ssh forced command or the away-from-home path"
|
||||
],
|
||||
"changes": [
|
||||
"OPEN_SEC 08:00 -> 07:00; CLOSE_SEC 16:00 -> 17:00; refusal/open/warning messages updated",
|
||||
"test_warp_window.sh asserts the 06:59:59/07:00/16:59:59/17:00 edges and a 25200 s timeout at Mon 10:00"
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "linux_configuration/features/lib/tests/test_warp_window.sh (before the change)",
|
||||
"result": "fail",
|
||||
"evidence": "red first: 27 passed, 8 failed (07:00 closed, 14400 instead of 18000 at Friday noon)"
|
||||
},
|
||||
{
|
||||
"command": "linux_configuration/features/lib/tests/test_warp_window.sh; test_warp_home.sh",
|
||||
"result": "pass",
|
||||
"evidence": "35 passed, 0 failed; 35 passed, 0 failed (incl. away-from-home tick never touches WARP, on away connects without the PC)"
|
||||
},
|
||||
{
|
||||
"command": "sudo install -m 0755 warp_window.sh /usr/local/sbin/warp-window; scp warp_home.sh to laptop ~/.local/bin/warp-home; . /usr/local/sbin/warp-window; window_seconds_left",
|
||||
"result": "pass",
|
||||
"evidence": "Mon 2026-11-09 07:56:42 -> 32598 s left (open until 17:00; closed under the old window); kuhy ran warp-home on and confirmed it works"
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"Laptop copy is installed by hand; a later warp_home.sh install overwrites it with the repo version (same content now)"
|
||||
],
|
||||
"rollback": [
|
||||
"git revert this commit, then sudo install -m 0755 warp_window.sh /usr/local/sbin/warp-window and copy warp_home.sh to the laptop again",
|
||||
"Then: window_seconds_left is closed at Mon 07:30 and 16:30"
|
||||
]
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
{
|
||||
"intent": "Kept /wsg/ videos go to the dufs cloud folder (or ~/Downloads as fallback) instead of a buried data dir, and trash/ is capped at the newest 200 passes with everything older deleted.",
|
||||
"scope": [
|
||||
"python_pkg/wsg_grabber/paths.py: cloud_root, downloads_dir, cloud_keep_dir, keep_dir (cloud or Downloads), legacy_keep_dir, kept_candidates",
|
||||
"python_pkg/wsg_grabber/_prune.py, _migrate_keep.py, housekeeping.py (new); files.remove; FileState.PURGED; store_verdicts recent_passed_names / purge_older_passes / rename_kept",
|
||||
"app.py wires on_startup / after_verdict / locate_reviewed; cli.py and README drop the 'nothing is ever deleted' promise",
|
||||
"Non-goal: capping kept files, touching dufs-cloud or the media sync timer"
|
||||
],
|
||||
"changes": [
|
||||
"keep_dir() resolves per call to ~/data/cloud/Media/<year>/wsg when the cloud folder exists, else ~/Downloads",
|
||||
"prune_trash deletes every trash/ file outside the 200 newest reviewed_at passes (orphans included) and marks the rows purged; runs at startup and after each pass",
|
||||
"migrate_keep moves the legacy keep/ into the current keep dir once (dedupe by name+size, suffix + index rename on clash) and removes the empty dir",
|
||||
"undo locates a kept file through kept_candidates so year rollover, cloud absence and the media sync sweep do not lose the verdict"
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "~/.claude/scripts/capped.sh python -m pytest python_pkg/wsg_grabber/tests -q",
|
||||
"result": "pass",
|
||||
"evidence": "303 passed; every python_pkg/wsg_grabber module at 100% line+branch coverage"
|
||||
},
|
||||
{
|
||||
"command": "HOME=/tmp/wsgfake/home XDG_DATA_HOME=$HOME/.local/share python -m python_pkg.wsg_grabber scrape --seconds 1 (copy of the real index, 23218 stand-in trash files, 50 stand-in keep files, fake data/cloud)",
|
||||
"result": "pass",
|
||||
"evidence": "keep.migrated moved=50; trash.pruned removed=23018 purged_rows=23018 retained=200; all 200 newest reviewed_at names present; keep/ removed; stats shows keep dir under data/cloud, and ~/Downloads after rm -rf data/cloud"
|
||||
},
|
||||
{
|
||||
"command": "python -m python_pkg.wsg_grabber scrape --seconds 1 (real home)",
|
||||
"result": "pass",
|
||||
"evidence": "keep/ 342 -> ~/data/cloud/Media/2026/wsg 647 (was 305), keep/ gone; trash 23218 files / 77G -> 200 files / 823M; stats: kept 648, passed 200, purged 23018"
|
||||
},
|
||||
{
|
||||
"command": "pre-commit run --files <18 changed files>",
|
||||
"result": "pass",
|
||||
"evidence": "no hook output beyond Passed/Skipped"
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"Purging is irreversible; the first run deleted 77 GB of passed videos, as agreed (Q3).",
|
||||
"A keep made while the cloud folder is absent lands in ~/Downloads and is swept by media-cloud-sync into Media/<year>/<month>; undo follows it via kept_candidates but a same-name suffix applied by that sync would break the link.",
|
||||
"Kept videos in Media/<year>/wsg now appear in the dufs gallery and get thumbnails."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit; kept files stay in the cloud folder (undo will still find them there through the old keep_dir only if moved back by hand)",
|
||||
"Validate with `python -m python_pkg.wsg_grabber stats` and the test suite"
|
||||
]
|
||||
}
|
||||
@ -120,7 +120,7 @@ _t_not "the early-closed window is forgotten" test -e "$OPEN_UNTIL"
|
||||
SSH_OUT="seconds_left=600"
|
||||
|
||||
printf '\n-- on: a refusal connects nothing --\n'
|
||||
SSH_OUT="WARP window is Mon/Thu/Fri 08:00-16:00 only"
|
||||
SSH_OUT="WARP window is Mon/Thu/Fri 07:00-17:00 only"
|
||||
SSH_RC=1
|
||||
reset_calls
|
||||
on_refused() { cmd_on; }
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# Tests for warp_window.sh -- the PC side of the work-from-home WARP window.
|
||||
#
|
||||
# Gateway mode drops the Cloudflare WARP tunnel because it carries everything
|
||||
# past the DNS block. kuhy may open it only Mon/Thu/Fri 08:00-16:00; the laptop
|
||||
# past the DNS block. kuhy may open it only Mon/Thu/Fri 07:00-17:00; the laptop
|
||||
# asks over an SSH key whose forced command can run nothing but open/status.
|
||||
# The window edges and the forced-command filter are the security boundary,
|
||||
# so both are asserted exactly. The clock and nft are stubbed.
|
||||
@ -28,26 +28,26 @@ left_at() {
|
||||
window_seconds_left || printf 'closed'
|
||||
}
|
||||
|
||||
printf '\n-- the window is Mon/Thu/Fri 08:00-16:00, nothing else --\n'
|
||||
_t_eq "closed" "$(left_at '1 07 59 59')" "Monday 07:59:59 is closed"
|
||||
_t_eq "28800" "$(left_at '1 08 00 00')" "Monday 08:00 opens until 16:00"
|
||||
_t_eq "1" "$(left_at '1 15 59 59')" "Monday 15:59:59 has one second left"
|
||||
_t_eq "closed" "$(left_at '1 16 00 00')" "Monday 16:00 is closed"
|
||||
_t_eq "14400" "$(left_at '5 12 00 00')" "Friday noon is open"
|
||||
_t_eq "28800" "$(left_at '4 08 00 00')" "Thursday 08:00 opens until 16:00"
|
||||
_t_eq "closed" "$(left_at '4 16 00 00')" "Thursday 16:00 is closed"
|
||||
printf '\n-- the window is Mon/Thu/Fri 07:00-17:00, nothing else --\n'
|
||||
_t_eq "closed" "$(left_at '1 06 59 59')" "Monday 06:59:59 is closed"
|
||||
_t_eq "36000" "$(left_at '1 07 00 00')" "Monday 07:00 opens until 17:00"
|
||||
_t_eq "1" "$(left_at '1 16 59 59')" "Monday 16:59:59 has one second left"
|
||||
_t_eq "closed" "$(left_at '1 17 00 00')" "Monday 17:00 is closed"
|
||||
_t_eq "18000" "$(left_at '5 12 00 00')" "Friday noon is open"
|
||||
_t_eq "36000" "$(left_at '4 07 00 00')" "Thursday 07:00 opens until 17:00"
|
||||
_t_eq "closed" "$(left_at '4 17 00 00')" "Thursday 17:00 is closed"
|
||||
for day in 2 3 6 7; do
|
||||
_t_eq "closed" "$(left_at "$day 12 00 00")" "weekday $day noon is closed"
|
||||
done
|
||||
_t_eq "28260" "$(left_at '5 08 09 00')" "a leading-zero hour is decimal, not octal"
|
||||
_t_eq "31860" "$(left_at '5 08 09 00')" "a leading-zero hour is decimal, not octal"
|
||||
|
||||
printf '\n-- open fills the set with a timeout ending at 16:00 --\n'
|
||||
printf '\n-- open fills the set with a timeout ending at 17:00 --\n'
|
||||
FAKE_DATE="1 10 00 00"
|
||||
out="$(cmd_open)"
|
||||
_t_called 'nft add element inet filter warp_open { 0.0.0.0/0 timeout 21600s }' \
|
||||
_t_called 'nft add element inet filter warp_open { 0.0.0.0/0 timeout 25200s }' \
|
||||
"open adds the catch-all element with the time left"
|
||||
_t_has "$out" "seconds_left=21600" "open reports the seconds left for the laptop"
|
||||
_t_has "$out" "until 16:00" "open names the 16:00 cut-off"
|
||||
_t_has "$out" "seconds_left=25200" "open reports the seconds left for the laptop"
|
||||
_t_has "$out" "until 17:00" "open names the 17:00 cut-off"
|
||||
|
||||
printf '\n-- outside the window open refuses and touches nothing --\n'
|
||||
: >"$TEST_TMPDIR/calls.log"
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
# plain internet (with the DNS blocklist) comes back. On any other network,
|
||||
# e.g. the office, it never touches WARP.
|
||||
#
|
||||
# warp-home on Mon/Thu/Fri 08:00-16:00 at home: ask the PC, then connect.
|
||||
# warp-home on Mon/Thu/Fri 07:00-17:00 at home: ask the PC, then connect.
|
||||
# Anywhere else: just connect.
|
||||
# warp-home off disconnect and forget the window
|
||||
# warp-home status network, window, WARP and the PC's view
|
||||
@ -23,7 +23,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
readonly PC_IP="192.168.1.43" PC_MAC="9c:6b:00:5c:c5:6d" PC_USER="kuhy"
|
||||
readonly WARN_SEC=300 # warn five minutes before the 16:00 cut-off
|
||||
readonly WARN_SEC=300 # warn five minutes before the 17:00 cut-off
|
||||
KEY="$HOME/.ssh/warp_window_ed25519"
|
||||
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/warp-home"
|
||||
OPEN_UNTIL="$STATE_DIR/open-until"
|
||||
@ -70,17 +70,17 @@ warp_off_because() {
|
||||
cmd_tick() {
|
||||
at_home || return 0
|
||||
window_open || {
|
||||
warp_off_because "WARP turned off at home. 'warp-home on' works Mon/Thu/Fri 08:00-16:00."
|
||||
warp_off_because "WARP turned off at home. 'warp-home on' works Mon/Thu/Fri 07:00-17:00."
|
||||
return 0
|
||||
}
|
||||
# Any re-apply of the PC firewall empties its set before 16:00. Only an
|
||||
# Any re-apply of the PC firewall empties its set before 17:00. Only an
|
||||
# explicit "closed" counts: an unreachable PC proves nothing.
|
||||
if [[ $(pc status 2>/dev/null) == closed ]]; then
|
||||
warp_off_because "The PC closed the WARP window early; run 'warp-home on' again."
|
||||
return 0
|
||||
fi
|
||||
if (($(<"$OPEN_UNTIL") - $(date +%s) <= WARN_SEC)) && [[ ! -e $WARNED ]]; then
|
||||
notify "WARP closes at 16:00, in five minutes."
|
||||
notify "WARP closes at 17:00, in five minutes."
|
||||
touch "$WARNED"
|
||||
fi
|
||||
}
|
||||
@ -96,7 +96,7 @@ cmd_on() {
|
||||
printf '%s\n' "$(($(date +%s) + left))" >"$OPEN_UNTIL"
|
||||
fi
|
||||
warp connect >/dev/null
|
||||
printf 'WARP connecting.%s\n' "$(at_home && printf ' Home window ends at 16:00.')"
|
||||
printf 'WARP connecting.%s\n' "$(at_home && printf ' Home window ends at 17:00.')"
|
||||
}
|
||||
|
||||
cmd_off() {
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
#
|
||||
# Gateway mode (setup_dns_blocker.sh gateway) drops the WARP tunnel, because
|
||||
# WARP carries all traffic past the DNS block. This opens it for every LAN
|
||||
# device, but ONLY Mon/Thu/Fri 08:00-16:00 by this PC's clock: the open adds one
|
||||
# element to the nft set warp_open whose timeout ends at 16:00, so the kernel
|
||||
# device, but ONLY Mon/Thu/Fri 07:00-17:00 by this PC's clock: the open adds one
|
||||
# element to the nft set warp_open whose timeout ends at 17:00, so the kernel
|
||||
# closes it again with nothing left to fail. The office days (Tue/Wed) need
|
||||
# nothing here: the home gateway never touches the work network.
|
||||
#
|
||||
@ -23,7 +23,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
readonly WINDOW_DAYS=" 1 4 5 " # date +%u: Monday, Thursday, Friday
|
||||
readonly OPEN_SEC=$((8 * 3600)) CLOSE_SEC=$((16 * 3600))
|
||||
readonly OPEN_SEC=$((7 * 3600)) CLOSE_SEC=$((17 * 3600))
|
||||
readonly NFT_SET="inet filter warp_open"
|
||||
readonly KEY_FROM="192.168.1.0/24" # the key works only from the LAN
|
||||
INSTALL_PATH="/usr/local/sbin/warp-window"
|
||||
@ -36,8 +36,8 @@ die() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Seconds until 16:00 while the window is open; fails when it is closed.
|
||||
# Plain arithmetic, not `date -d 16:00`: DST never changes on a window day.
|
||||
# Seconds until 17:00 while the window is open; fails when it is closed.
|
||||
# Plain arithmetic, not `date -d 17:00`: DST never changes on a window day.
|
||||
window_seconds_left() {
|
||||
local day h m s now
|
||||
read -r day h m s <<<"$(date '+%u %H %M %S')"
|
||||
@ -49,13 +49,13 @@ window_seconds_left() {
|
||||
|
||||
cmd_open() {
|
||||
local left
|
||||
left="$(window_seconds_left)" || die "WARP window is Mon/Thu/Fri 08:00-16:00 only."
|
||||
left="$(window_seconds_left)" || die "WARP window is Mon/Thu/Fri 07:00-17:00 only."
|
||||
# Re-opening must refresh the timeout, and add keeps an old one: flush first.
|
||||
# shellcheck disable=SC2086 # NFT_SET is three words on purpose
|
||||
nft flush set $NFT_SET 2>/dev/null || die "no warp_open set: is gateway mode on?"
|
||||
# shellcheck disable=SC2086
|
||||
nft add element $NFT_SET "{ 0.0.0.0/0 timeout ${left}s }"
|
||||
printf 'WARP open for the LAN until 16:00.\nseconds_left=%s\n' "$left"
|
||||
printf 'WARP open for the LAN until 17:00.\nseconds_left=%s\n' "$left"
|
||||
}
|
||||
|
||||
cmd_close() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user