Files

78 lines
2.9 KiB
Python

"""Install only IKAR units and its own Compose services on the mounted disk."""
from pathlib import Path
import json, os, subprocess
root = Path('/mnt/data/ikar_server')
release = root / 'releases/20261006'
assert os.path.ismount('/mnt/data') and root.resolve() == root
assert release.is_dir() and (root / 'shared/server.env').is_file()
marker = root / 'shared/data/.ikar-volume'
marker.write_text('IKAR external data volume\n')
os.chown(marker,1000,1000)
current = root / 'current'
if current.is_symlink(): current.unlink()
elif current.exists(): raise SystemExit('Unexpected current directory')
current.symlink_to(release, target_is_directory=True)
def env_read(path):
return dict(line.split('=',1) for line in path.read_text().splitlines() if '=' in line and not line.startswith('#'))
turn = env_read(root / 'shared/turn.env')
server_path = root / 'shared/server.env'
server = env_read(server_path)
ip = turn['TURN_EXTERNAL_IP']
server.update({
'WebRtc__IceServers__0__Urls__0':f'stun:{ip}:3478',
'WebRtc__IceServers__1__Urls__0':f'turn:{ip}:3478?transport=udp',
'WebRtc__IceServers__1__Urls__1':f'turn:{ip}:3478?transport=tcp',
'IkarUpdates__LocalOnly':'true',
'Logging__LogLevel__Microsoft.EntityFrameworkCore.Database.Command':'Warning',
'Logging__LogLevel__System.Net.Http.HttpClient':'Warning',
})
server_path.write_text(''.join(f'{key}={value}\n' for key,value in server.items()))
os.chmod(server_path,0o600); os.chown(server_path,1000,1000)
unit_root = Path('/etc/systemd/system')
(unit_root / 'ikar_server.service').write_text('''[Unit]
Description=IKAR messenger on the external disk
Requires=docker.service
After=docker.service network-online.target
RequiresMountsFor=/mnt/data
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/mnt/data/ikar_server/current
ExecStartPre=/usr/bin/mountpoint -q /mnt/data
ExecStart=/usr/bin/docker compose --env-file /mnt/data/ikar_server/shared/turn.env up -d
ExecStop=/usr/bin/docker compose --env-file /mnt/data/ikar_server/shared/turn.env stop
TimeoutStartSec=90
[Install]
WantedBy=multi-user.target
''')
(unit_root / 'ikar_server-backup.service').write_text('''[Unit]
Description=Consistent IKAR backup
RequiresMountsFor=/mnt/data
After=ikar_server.service
[Service]
Type=oneshot
User=sevenhill
ExecStart=/usr/bin/python3 /mnt/data/ikar_server/current/backup.py
Nice=15
IOSchedulingClass=idle
''')
(unit_root / 'ikar_server-backup.timer').write_text('''[Unit]
Description=Daily IKAR backup
[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
''')
subprocess.run(['systemctl','daemon-reload'],check=True)
subprocess.run(['docker','compose','--project-directory',str(current),'--env-file',str(root / 'shared/turn.env'),'up','-d'],check=True)
subprocess.run(['systemctl','enable','--now','ikar_server.service','ikar_server-backup.timer'],check=True)
print(json.dumps({'root':str(root),'release':str(release),'externalIp':ip,'backupTimer':'enabled'}))