left4dead
This commit is contained in:
parent
afe04ae6c8
commit
6b0e92447a
10 changed files with 164 additions and 140 deletions
|
@ -1,106 +1,71 @@
|
|||
assert node.has_bundle('steam') and node.has_bundle('steam-workshop-download')
|
||||
|
||||
directories = {
|
||||
'/opt/left4dead2': {
|
||||
'/opt/steam/left4dead2/left4dead2/ems/admin system': {
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
'mode': '0744',
|
||||
},
|
||||
'/opt/left4dead2/ems/admin system': {
|
||||
'/opt/steam/left4dead2/left4dead2/cfg/server': {
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
'purge': True,
|
||||
},
|
||||
'/opt/left4dead2/left4dead2/cfg': {
|
||||
'owner': 'steam',
|
||||
},
|
||||
'/opt/left4dead2/left4dead2/addons': {
|
||||
'/opt/steam/left4dead2/left4dead2/addons': {
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
'purge': True,
|
||||
},
|
||||
}
|
||||
|
||||
files = {
|
||||
'/opt/left4dead2/ems/admin system/admins.txt': {
|
||||
'/opt/steam/left4dead2/left4dead2/ems/admin system/admins.txt': {
|
||||
'owner': 'steam',
|
||||
'content': '\n'.join(node.metadata.get('left4dead2/admins')),
|
||||
'content': '\n'.join(sorted(node.metadata.get('left4dead2/admins'))),
|
||||
}
|
||||
}
|
||||
|
||||
svc_systemd = {
|
||||
'left4dead2-workshop': {
|
||||
'running': False,
|
||||
'needs': [
|
||||
'svc_systemd:steam-update',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
for id in node.metadata.get('left4dead2/workshop'):
|
||||
directories[f'/opt/left4dead2/left4dead2/addons/{id}'] = {
|
||||
'owner': 'steam',
|
||||
'triggers': [
|
||||
'svc_systemd:left4dead2-workshop:restart',
|
||||
],
|
||||
}
|
||||
|
||||
server_units = set()
|
||||
for name, config in node.metadata.get('left4dead2/servers').items():
|
||||
config.pop('port')
|
||||
config = {
|
||||
'hostname': name,
|
||||
'sv_steamgroup': ','.join(
|
||||
str(gid) for gid in node.metadata.get('left4dead2/steamgroups')
|
||||
),
|
||||
'z_difficulty': 'Impossible',
|
||||
'sv_gametypes': 'realism',
|
||||
'sv_region': 3, # europe
|
||||
'log': 'on',
|
||||
'sv_logecho': 1,
|
||||
'sv_logfile': 1,
|
||||
'sv_log_onefile': 0,
|
||||
'sv_logbans': 1,
|
||||
'sv_logflush': 0,
|
||||
'sv_logsdir': 'logs', # /opt/left4dead2/left4dead2/logs
|
||||
**config,
|
||||
}
|
||||
|
||||
files[f'/opt/left4dead2/left4dead2/cfg/server-{name}.cfg'] = {
|
||||
'content': '\n'.join(
|
||||
f'{key} "{value}"' for key, value in sorted(config.items())
|
||||
) + '\n',
|
||||
files[f'/opt/steam/left4dead2/left4dead2/cfg/server/{name}.cfg'] = {
|
||||
'content_type': 'mako',
|
||||
'source': 'server.cfg',
|
||||
'context': {
|
||||
'name': name,
|
||||
'steamgroups': node.metadata.get('left4dead2/steamgroups'),
|
||||
},
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
'triggers': [
|
||||
f'svc_systemd:left4dead2-server-{name}:restart',
|
||||
f'svc_systemd:left4dead2-{name}.service:restart',
|
||||
],
|
||||
}
|
||||
svc_systemd[f'left4dead2-server-{name}'] = {
|
||||
svc_systemd[f'left4dead2-{name}.service'] = {
|
||||
'needs': [
|
||||
f'file:/usr/local/lib/systemd/system/left4dead2-server-{name}.service',
|
||||
f'file:/opt/steam/left4dead2/left4dead2/cfg/server/{name}.cfg',
|
||||
f'file:/usr/local/lib/systemd/system/left4dead2-{name}.service',
|
||||
],
|
||||
}
|
||||
server_units.add(f'left4dead2-server-{name}')
|
||||
|
||||
|
||||
|
||||
files[f'/opt/steam/left4dead2/left4dead2/addons/readme.txt'] = {
|
||||
'content_type': 'any',
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
}
|
||||
|
||||
|
||||
for id in node.metadata.get('left4dead2/workshop'):
|
||||
directories[f'/opt/left4dead2/addons/{id}'] = {
|
||||
files[f'/opt/steam/left4dead2/left4dead2/addons/{id}.vpk'] = {
|
||||
'content_type': 'any',
|
||||
'owner': 'steam',
|
||||
'triggers': [
|
||||
'svc_systemd:left4dead2-workshop:restart',
|
||||
],
|
||||
'group': 'steam',
|
||||
}
|
||||
|
||||
# TIDYUP
|
||||
|
||||
find_obsolete_units = (
|
||||
'find /usr/local/lib/systemd/system -type f -name "left4dead2-server-*.service" ' +
|
||||
' '.join(f"! -name '{name}.service'" for name in server_units)
|
||||
)
|
||||
actions['remove_obsolete_left4dead2_units'] = {
|
||||
'command': (
|
||||
f'for unitfile in $({find_obsolete_units}); '
|
||||
f'do '
|
||||
f'systemctl stop $(basename "$unitfile"); '
|
||||
f'systemctl disable $(basename "$unitfile"); '
|
||||
f'rm "$unitfile"; '
|
||||
f'systemctl daemon-reload; '
|
||||
f'done'
|
||||
),
|
||||
'unless': (
|
||||
find_obsolete_units + " | wc -l | grep -q '^0$'"
|
||||
),
|
||||
# /opt/steam/steam/.steam/sdk32/steamclient.so: cannot open shared object file: No such file or directory
|
||||
symlinks = {
|
||||
'/opt/steam/steam/.steam/sdk32': {
|
||||
'target': '/opt/steam/steam/linux32',
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,43 +17,20 @@ defaults = {
|
|||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'systemd/units',
|
||||
'steam-workshop-download/left4dead',
|
||||
)
|
||||
def workshop(metadata):
|
||||
command = (
|
||||
'set -x; '
|
||||
'for ID in ' + ' '.join(metadata.get('left4dead2/workshop')) + '; '
|
||||
'do '
|
||||
'if ! ls /opt/left4dead2/left4dead2/addons/$ID/*.vpk; '
|
||||
'then '
|
||||
'cd /opt/left4dead2/left4dead2/addons/$ID; '
|
||||
'/opt/steam-workshop-downloader https://steamcommunity.com/sharedfiles/filedetails\?id\=$ID; '
|
||||
'unzip $ID.zip; '
|
||||
'fi; '
|
||||
'done'
|
||||
)
|
||||
|
||||
def workshop_download(metadata):
|
||||
if not metadata.get('left4dead2/workshop'):
|
||||
return {}
|
||||
|
||||
return {
|
||||
'systemd': {
|
||||
'units': {
|
||||
'left4dead2-workshop.service': {
|
||||
'Unit': {
|
||||
'Description': 'install workshop items',
|
||||
'After': 'network.target',
|
||||
'Requires': 'steam-update.service',
|
||||
'PartOf': 'steam-update.service'
|
||||
},
|
||||
'Service': {
|
||||
'Type': 'oneshot',
|
||||
'User': 'steam',
|
||||
'ExecStart': f'/bin/bash -c {quote(command)}',
|
||||
},
|
||||
'Install': {
|
||||
'WantedBy': {'multi-user.target'},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
'steam-workshop-download': {
|
||||
'left4dead': {
|
||||
'ids': metadata.get('left4dead2/workshop'),
|
||||
'path': '/opt/steam/left4dead2/left4dead2/addons',
|
||||
'user': 'steam',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,19 +39,18 @@ def workshop(metadata):
|
|||
)
|
||||
def server_units(metadata):
|
||||
units = {}
|
||||
|
||||
|
||||
for name, config in metadata.get('left4dead2/servers').items():
|
||||
units[f'left4dead2-server-{name}.service'] = {
|
||||
units[f'left4dead2-{name}.service'] = {
|
||||
'Unit': {
|
||||
'Description': f'left4dead2 server {name}',
|
||||
'After': 'network.target',
|
||||
'Requires': 'steam-update.service',
|
||||
'After': {'steam.target'},
|
||||
},
|
||||
'Service': {
|
||||
'User': 'steam',
|
||||
'Group': 'steam',
|
||||
'WorkingDirectory': '/opt/left4dead2',
|
||||
'ExecStart': f'/opt/left4dead2/srcds_run -port {config["port"]} -insecure +map {config["map"]} +exec server-{name}.cfg',
|
||||
'WorkingDirectory': '/opt/steam/left4dead2',
|
||||
'ExecStart': f'/opt/steam/left4dead2/srcds_run -port {config["port"]} +exec server/{name}.cfg',
|
||||
'Restart': 'on-failure',
|
||||
},
|
||||
'Install': {
|
||||
|
@ -87,3 +63,19 @@ def server_units(metadata):
|
|||
'units': units,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'nftables/input',
|
||||
)
|
||||
def firewall(metadata):
|
||||
ports = set(str(server['port']) for server in metadata.get('left4dead2/servers').values())
|
||||
|
||||
return {
|
||||
'nftables': {
|
||||
'input': {
|
||||
f"tcp dport {{ {', '.join(ports)} }} accept",
|
||||
f"udp dport {{ {', '.join(ports)} }} accept",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
7
bundles/steam-workshop-download/items.py
Normal file
7
bundles/steam-workshop-download/items.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
files = {
|
||||
'/opt/steam-workshop-download': {
|
||||
'content_type': 'download',
|
||||
'source': 'https://git.sublimity.de/cronekorkn/steam-workshop-downloader/raw/branch/master/steam-workshop-download',
|
||||
'mode': '755',
|
||||
},
|
||||
}
|
39
bundles/steam-workshop-download/metadata.py
Normal file
39
bundles/steam-workshop-download/metadata.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from shlex import quote
|
||||
|
||||
|
||||
defaults = {
|
||||
'steam-workshop-download': {},
|
||||
}
|
||||
|
||||
|
||||
@metadata_reactor.provides(
|
||||
'systemd/units',
|
||||
)
|
||||
def workshop(metadata):
|
||||
units = {}
|
||||
|
||||
for name, conf in metadata.get('steam-workshop-download').items():
|
||||
units[f'steam-workshop-download-{name}.service'] = {
|
||||
'Unit': {
|
||||
'Description': 'install workshop items',
|
||||
'After': {
|
||||
'network-online.target',
|
||||
'steam-update.target',
|
||||
},
|
||||
'Before': 'steam.target',
|
||||
},
|
||||
'Service': {
|
||||
'Type': 'oneshot',
|
||||
'User': conf['user'],
|
||||
'ExecStart': f"/opt/steam-workshop-download {' '.join(quote(str(id)) for id in conf['ids'])} --out {quote(conf['path'])}",
|
||||
},
|
||||
'Install': {
|
||||
'WantedBy': {'multi-user.target'},
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
'systemd': {
|
||||
'units': units,
|
||||
},
|
||||
}
|
|
@ -22,7 +22,7 @@ for game in node.metadata.get('steam/games'):
|
|||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
'needed_by': [
|
||||
'svc_systemd:steam-update',
|
||||
'svc_systemd:steam-update.service',
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -33,22 +33,8 @@ files = {
|
|||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
},
|
||||
'/opt/steam/steam/workshop-downloader': {
|
||||
'content_type': 'download',
|
||||
'source': 'https://github.com/SegoCode/swd/releases/download/1.1/swd-linux-amd64',
|
||||
'owner': 'steam',
|
||||
'group': 'steam',
|
||||
'mode': '750',
|
||||
},
|
||||
}
|
||||
|
||||
# symlinks = {
|
||||
# # /opt/steam/.steam/sdk32/steamclient.so: cannot open shared object file: No such file or directory
|
||||
# '/opt/steam/.steam/sdk32': {
|
||||
# 'target': '/opt/steam/linux32',
|
||||
# }
|
||||
# }
|
||||
|
||||
actions = {
|
||||
'extract_steamcmd': {
|
||||
'command': """su - steam -c 'tar xfvz /opt/steam/steam/steamcmd_linux.tar.gz --directory /opt/steam/steam'""",
|
||||
|
@ -59,7 +45,7 @@ actions = {
|
|||
},
|
||||
}
|
||||
|
||||
svc_systemd['steam-update'] = {
|
||||
svc_systemd['steam-update.service'] = {
|
||||
'running': False,
|
||||
'enabled': False,
|
||||
'needs': {
|
||||
|
|
|
@ -10,6 +10,15 @@ defaults = {
|
|||
'left4dead2': 222860,
|
||||
},
|
||||
},
|
||||
'systemd': {
|
||||
'units': {
|
||||
'steam.target': {
|
||||
'Unit': {
|
||||
'Description': 'steam is ready',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'zfs': {
|
||||
'datasets': {
|
||||
'tank/steam': {
|
||||
|
@ -31,7 +40,8 @@ def initial_unit(metadata):
|
|||
'steam-update.service': {
|
||||
'Unit': {
|
||||
'Description': 'steam: install and update games',
|
||||
'After': 'network.target',
|
||||
'After': 'network-online.target',
|
||||
'Before': 'steam.target',
|
||||
},
|
||||
'Service': {
|
||||
'Type': 'oneshot',
|
||||
|
|
|
@ -14,7 +14,7 @@ actions = {
|
|||
'command': 'systemctl daemon-reload',
|
||||
'cascade_skip': False,
|
||||
'triggered': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, unit in node.metadata.get('systemd/units').items():
|
||||
|
@ -30,7 +30,7 @@ for name, unit in node.metadata.get('systemd/units').items():
|
|||
'svc_systemd:systemd-networkd:restart',
|
||||
],
|
||||
}
|
||||
elif extension in ['timer', 'service', 'mount', 'swap']:
|
||||
elif extension in ['timer', 'service', 'mount', 'swap', 'target']:
|
||||
path = f'/usr/local/lib/systemd/system/{name}'
|
||||
dependencies = {
|
||||
'triggers': [
|
||||
|
|
|
@ -25,9 +25,6 @@ def units(metadata):
|
|||
|
||||
type = name.split('.')[-1]
|
||||
|
||||
if type not in ['timer', 'service', 'network', 'netdev', 'mount', 'swap']:
|
||||
raise Exception(f'unknown type {type}')
|
||||
|
||||
if not config.get('Install/WantedBy'):
|
||||
if type == 'service':
|
||||
units[name] = {
|
||||
|
|
7
groups/applications/left4dead2.py
Normal file
7
groups/applications/left4dead2.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
'bundles': [
|
||||
'steam',
|
||||
'steam-workshop-download',
|
||||
'left4dead2',
|
||||
],
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
'monitored',
|
||||
'webserver',
|
||||
'dnsserver',
|
||||
'left4dead2',
|
||||
],
|
||||
'bundles': [
|
||||
'bind-acme',
|
||||
|
@ -68,6 +69,26 @@
|
|||
'download-server': {
|
||||
'hostname': 'dl.sublimity.de',
|
||||
},
|
||||
'left4dead2': {
|
||||
'servers': {
|
||||
'standard': {
|
||||
'port': 27020,
|
||||
},
|
||||
},
|
||||
'admins': {
|
||||
'STEAM_1:0:12376499', # CroneKorkN ☮️UKRAINE❤
|
||||
'STEAM_1:1:169960486', # *RED*
|
||||
'STEAM_1:1:112940736', # Ðark-AnGeℓ❤
|
||||
'STEAM_1:1:34263261', # Alekc
|
||||
'STEAM_1:1:79349632', # VOID
|
||||
},
|
||||
'workshop': {
|
||||
214630948,
|
||||
1229957234,
|
||||
698857882,
|
||||
},
|
||||
'steamgroups': {'103582791467869287'},
|
||||
},
|
||||
'letsencrypt': {
|
||||
'domains': {
|
||||
'ckn.li': {},
|
||||
|
|
Loading…
Reference in a new issue