forked from lab-in-a-box/liab-deployments
155 lines
3.6 KiB
Python
155 lines
3.6 KiB
Python
#
|
|
# Deploy copyparty (https://github.com/9001/copyparty) fileserver
|
|
#
|
|
# An example inventory may look like this:
|
|
#
|
|
# group = [
|
|
# (
|
|
# 'edu.datalad.org',
|
|
# {
|
|
# 'copyparty': {
|
|
# 'sites': [
|
|
# {
|
|
# 'serve_address': 'copyparty.example.org',
|
|
# 'container_tag': 'docker.io/copyparty/ac:latest',
|
|
# 'user': ('copyparty', '5000'),
|
|
# 'host_port': 30500,
|
|
# 'config_file_asset': 'assets/copyparty-example-config.conf',
|
|
# },
|
|
# ...
|
|
#
|
|
from pyinfra.api import deploy
|
|
from pyinfra import (
|
|
host,
|
|
)
|
|
from pyinfra.operations import (
|
|
files,
|
|
server,
|
|
)
|
|
from liab_deployments.operations import (
|
|
caddy,
|
|
user,
|
|
user_systemd,
|
|
)
|
|
|
|
container_unit_tmpl = """\
|
|
[Container]
|
|
Image={container_tag}
|
|
ContainerName=copyparty
|
|
PublishPort={host_port}:3923
|
|
Volume={user_home}/config:/cfg:z
|
|
Volume={user_home}/data:/data:z
|
|
|
|
# Give the container time to stop in case the thumbnailer is still running.
|
|
# It is allowed to continue finishing up for 10s after the shutdown signal, give it a 5s buffer
|
|
StopTimeout=15
|
|
|
|
# hide it from logs with "/._" so it matches the default --lf-url filter
|
|
HealthCmd="wget --spider -q 127.0.0.1:3923/?reset=/._"
|
|
HealthInterval=1m
|
|
HealthTimeout=2s
|
|
HealthRetries=5
|
|
HealthStartPeriod=15s
|
|
|
|
[Unit]
|
|
After=default.target
|
|
|
|
[Install]
|
|
# Start by default on boot
|
|
WantedBy=default.target
|
|
|
|
[Service]
|
|
# Give the container time to start in case it needs to pull the image
|
|
TimeoutStartSec=600
|
|
"""
|
|
|
|
caddyfile_block_tmpl = """\
|
|
{serve_address} {{
|
|
reverse_proxy localhost:{host_port}
|
|
}}
|
|
"""
|
|
|
|
|
|
@deploy("Deploy copyparty")
|
|
def deploy_sites():
|
|
if not hasattr(host.data, 'copyparty'):
|
|
return
|
|
for spec in host.data.copyparty.get('sites', []):
|
|
_deploy_site(
|
|
spec['serve_address'],
|
|
spec['container_tag'],
|
|
spec['config_file_asset'],
|
|
spec['user'],
|
|
spec['host_port'],
|
|
name=spec.get('name', 'copyparty'),
|
|
caddyfile_block_tmpl=spec.get(
|
|
'caddyfile_block_tmpl', caddyfile_block_tmpl
|
|
),
|
|
)
|
|
|
|
|
|
def _deploy_site(
|
|
serve_address,
|
|
container_tag,
|
|
config_file_asset,
|
|
user_spec: tuple[str, int],
|
|
host_port,
|
|
*,
|
|
name,
|
|
caddyfile_block_tmpl,
|
|
):
|
|
user_name, uid = user_spec
|
|
user_home = f'/home/{user_name}'
|
|
|
|
user.systemd_service(
|
|
user_name,
|
|
uid,
|
|
user_home,
|
|
)
|
|
|
|
for i in ['config', 'data']:
|
|
files.directory(
|
|
path=f'{user_home}/{i}',
|
|
present=True,
|
|
_sudo_user=user_name,
|
|
)
|
|
|
|
user_systemd.container_unit(
|
|
user_name,
|
|
user_home,
|
|
name,
|
|
container_unit_tmpl.format(
|
|
user_home=user_home,
|
|
container_tag=container_tag,
|
|
host_port=host_port,
|
|
),
|
|
)
|
|
|
|
files.put(
|
|
name='Copyparty config',
|
|
src=config_file_asset,
|
|
dest=f'{user_home}/config/copyparty.conf',
|
|
_sudo_user=user_name,
|
|
)
|
|
|
|
user_systemd.run_service(
|
|
user_name,
|
|
uid,
|
|
'copyparty',
|
|
# container unit cannot be enabled, but auto-start
|
|
# is handled via "install" in the unit spec
|
|
enabled=False,
|
|
)
|
|
|
|
server.wait(
|
|
name=f"Wait for copyparty {serve_address!r} to start",
|
|
port=host_port,
|
|
)
|
|
|
|
caddy.caddyfile_block(
|
|
marker=f'COPYPARTY {serve_address}',
|
|
content=caddyfile_block_tmpl.format(
|
|
serve_address=serve_address,
|
|
host_port=host_port,
|
|
),
|
|
)
|