78 lines
2.9 KiB
Python
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'}))
|