You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
53 lines
2.9 KiB
53 lines
2.9 KiB
|
4 days ago
|
#!/usr/bin/env python3
|
||
|
|
"""Native configuration. Existing database credentials are preserved."""
|
||
|
|
import os
|
||
|
|
import pathlib
|
||
|
|
import grp
|
||
|
|
import secrets
|
||
|
|
import subprocess
|
||
|
|
|
||
|
|
if os.geteuid() != 0:
|
||
|
|
raise SystemExit('Run as root on the target VM.')
|
||
|
|
settings = pathlib.Path('/etc/mesa-abierta')
|
||
|
|
files = [settings / name for name in ('game.env', 'web.env', 'backup.env')]
|
||
|
|
if all(file.is_file() for file in files):
|
||
|
|
app_file = settings / 'game.env'
|
||
|
|
configuration = dict(line.split('=', 1) for line in app_file.read_text().splitlines()
|
||
|
|
if line and not line.startswith('#') and '=' in line)
|
||
|
|
configuration.update(HOST='0.0.0.0', PORT='3000',
|
||
|
|
ORIGIN='https://juegoland.imaginacion.com',
|
||
|
|
APP_ORIGIN='https://juegoland.imaginacion.com,http://192.168.18.155:3000',
|
||
|
|
TRUST_PROXY='0')
|
||
|
|
app_file.write_text(''.join(f'{key}={value}\n' for key, value in configuration.items()))
|
||
|
|
os.chmod(app_file, 0o640)
|
||
|
|
print('Single application port configured; existing credentials preserved.')
|
||
|
|
raise SystemExit(0)
|
||
|
|
if any(file.exists() for file in files):
|
||
|
|
raise SystemExit('Partial configuration: inspect it before continuing.')
|
||
|
|
|
||
|
|
def psql(sql):
|
||
|
|
return subprocess.run(['runuser', '-u', 'postgres', '--', 'psql', '-X', '-At', '-v', 'ON_ERROR_STOP=1'],
|
||
|
|
input=sql, text=True, capture_output=True, cwd='/tmp', check=True).stdout.strip()
|
||
|
|
|
||
|
|
if psql("SELECT 1 FROM pg_roles WHERE rolname='mesa_app';") or psql("SELECT 1 FROM pg_database WHERE datname='mesa_abierta';"):
|
||
|
|
raise SystemExit('Existing application database or role: refuse automatic credential replacement.')
|
||
|
|
database_password = secrets.token_hex(32)
|
||
|
|
pepper = secrets.token_hex(48)
|
||
|
|
psql(f"CREATE ROLE mesa_app LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD '{database_password}';\nCREATE DATABASE mesa_abierta OWNER mesa_app;")
|
||
|
|
settings.mkdir(mode=0o750, exist_ok=True)
|
||
|
|
gid = grp.getgrnam('mesa').gr_gid
|
||
|
|
os.chown(settings, 0, gid)
|
||
|
|
os.chmod(settings, 0o750)
|
||
|
|
environments = {
|
||
|
|
'game.env': f'NODE_ENV=production\nHOST=0.0.0.0\nPORT=3000\nORIGIN=https://juegoland.imaginacion.com\nAPP_ORIGIN=https://juegoland.imaginacion.com,http://192.168.18.155:3000\nDATABASE_URL=postgresql://mesa_app:{database_password}@127.0.0.1:5432/mesa_abierta\nTRUST_PROXY=0\nPIN_PEPPER={pepper}\n',
|
||
|
|
'web.env': 'NODE_ENV=production\nHOST=127.0.0.1\nPORT=3000\nPROTOCOL_HEADER=x-forwarded-proto\nHOST_HEADER=x-forwarded-host\n',
|
||
|
|
'backup.env': f'PGHOST=127.0.0.1\nPGPORT=5432\nPGDATABASE=mesa_abierta\nPGUSER=mesa_app\nPGPASSWORD={database_password}\nBACKUP_DIR=/var/backups/mesa-abierta\n',
|
||
|
|
}
|
||
|
|
os.umask(0o077)
|
||
|
|
for name, value in environments.items():
|
||
|
|
with (settings / name).open('x', encoding='utf-8', newline='\n') as output:
|
||
|
|
output.write(value)
|
||
|
|
os.chown(settings / name, 0, gid)
|
||
|
|
os.chmod(settings / name, 0o640)
|
||
|
|
print('Dedicated database and environment created; secrets remain on this server.')
|