58 lines
2.2 KiB
Python
58 lines
2.2 KiB
Python
"""User-authorized SSH polling until the complete handoff transfer succeeds."""
|
|
import fcntl
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
from datetime import datetime, timezone
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
STATE = Path('/opt/neiro/.handoff-monitor')
|
|
STATE.mkdir(exist_ok=True)
|
|
|
|
|
|
def report(phase, **details):
|
|
data = {'updated_utc': datetime.now(timezone.utc).isoformat(),
|
|
'pid': os.getpid(), 'phase': phase, **details}
|
|
temporary = STATE / 'status.tmp'
|
|
temporary.write_text(json.dumps(data, ensure_ascii=False, indent=2) + '\n')
|
|
temporary.replace(STATE / 'status.json')
|
|
print(json.dumps(data, ensure_ascii=False), flush=True)
|
|
|
|
|
|
def main():
|
|
with (STATE / 'lock').open('w') as lock:
|
|
try:
|
|
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
except BlockingIOError:
|
|
print('Monitor already running', flush=True)
|
|
return
|
|
(STATE / 'pid').write_text(str(os.getpid()) + '\n')
|
|
ssh = ['ssh', '-i', str(Path.home() / '.ssh/id_ed25519_snw'),
|
|
'-o', 'IdentitiesOnly=yes', '-o', 'BatchMode=yes',
|
|
'-o', 'ConnectTimeout=8', 'int@10.9.8.230', 'true']
|
|
attempt = 0
|
|
while True:
|
|
attempt += 1
|
|
started = time.monotonic()
|
|
report('checking', attempt=attempt)
|
|
try:
|
|
probe = subprocess.run(ssh, capture_output=True, text=True, timeout=15)
|
|
if probe.returncode == 0:
|
|
report('transferring', attempt=attempt)
|
|
transfer = subprocess.run([sys.executable, str(ROOT / 'save_handoff.py')])
|
|
if transfer.returncode == 0:
|
|
report('succeeded', destination='int@10.9.8.230:/mnt/c/KNP/cats-dogs')
|
|
return
|
|
report('retrying_transfer', exit_code=transfer.returncode)
|
|
else:
|
|
report('waiting_for_ssh', attempt=attempt, error=probe.stderr.strip())
|
|
except Exception as error:
|
|
report('waiting_for_ssh', attempt=attempt, error=str(error))
|
|
time.sleep(max(1, 30 - (time.monotonic() - started)))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|