Initial commit
This commit is contained in:
commit
dd302c83a3
288
.gitignore
vendored
Normal file
288
.gitignore
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
out
|
||||
sample
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/python,vim,pycharm+all
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=python,vim,pycharm+all
|
||||
|
||||
### PyCharm+all ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### PyCharm+all Patch ###
|
||||
# Ignore everything but code style settings and run configurations
|
||||
# that are supposed to be shared within teams.
|
||||
|
||||
.idea/*
|
||||
|
||||
!.idea/codeStyles
|
||||
!.idea/runConfigurations
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
### Python Patch ###
|
||||
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
||||
poetry.toml
|
||||
|
||||
# ruff
|
||||
.ruff_cache/
|
||||
|
||||
# LSP config files
|
||||
pyrightconfig.json
|
||||
|
||||
### Vim ###
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg # comment out if you don't need vector files
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# Session
|
||||
Session.vim
|
||||
Sessionx.vim
|
||||
|
||||
# Temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/python,vim,pycharm+all
|
12
Pipfile
Normal file
12
Pipfile
Normal file
@ -0,0 +1,12 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
pyyaml = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.12"
|
81
Pipfile.lock
generated
Normal file
81
Pipfile.lock
generated
Normal file
@ -0,0 +1,81 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "27a55b76dc774eff1af052a9de8b0c6b059a44578b80abeb18dbe190986011e0"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.12"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff",
|
||||
"sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48",
|
||||
"sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086",
|
||||
"sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e",
|
||||
"sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133",
|
||||
"sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5",
|
||||
"sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484",
|
||||
"sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee",
|
||||
"sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5",
|
||||
"sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68",
|
||||
"sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a",
|
||||
"sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf",
|
||||
"sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99",
|
||||
"sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8",
|
||||
"sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85",
|
||||
"sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19",
|
||||
"sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc",
|
||||
"sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a",
|
||||
"sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1",
|
||||
"sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317",
|
||||
"sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c",
|
||||
"sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631",
|
||||
"sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d",
|
||||
"sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652",
|
||||
"sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5",
|
||||
"sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e",
|
||||
"sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b",
|
||||
"sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8",
|
||||
"sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476",
|
||||
"sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706",
|
||||
"sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563",
|
||||
"sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237",
|
||||
"sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b",
|
||||
"sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083",
|
||||
"sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180",
|
||||
"sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425",
|
||||
"sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e",
|
||||
"sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f",
|
||||
"sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725",
|
||||
"sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183",
|
||||
"sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab",
|
||||
"sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774",
|
||||
"sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725",
|
||||
"sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e",
|
||||
"sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5",
|
||||
"sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d",
|
||||
"sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290",
|
||||
"sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44",
|
||||
"sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed",
|
||||
"sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4",
|
||||
"sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba",
|
||||
"sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12",
|
||||
"sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==6.0.2"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
181
main.py
Normal file
181
main.py
Normal file
@ -0,0 +1,181 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
class IniFile:
|
||||
PREAMBLE = "### Generated by dcqc - do not edit ###"
|
||||
def __init__(self):
|
||||
self._data = {}
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._data[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._data[key] = value
|
||||
|
||||
def write(self, f):
|
||||
f.write(self.PREAMBLE)
|
||||
f.write("\n\n")
|
||||
for section, section_data in self._data.items():
|
||||
f.write(f"[{section}]\n")
|
||||
for key, value in section_data.items():
|
||||
if isinstance(value, list):
|
||||
for item in value:
|
||||
f.write(f"{key}={item}\n")
|
||||
else:
|
||||
f.write(f"{key}={value}\n")
|
||||
f.write("\n")
|
||||
|
||||
def abort(msg):
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def enforce_list(key, dict_):
|
||||
if not isinstance(dict_[key], list):
|
||||
abort(f"{key} is not a list. Offending dict: {dict_}")
|
||||
|
||||
|
||||
def write_build_unit(args, yaml_dict, service_name):
|
||||
out_file = args.output_dir / f"{service_name}.build"
|
||||
print(f'Generating build "{service_name}" ({out_file})')
|
||||
build = yaml_dict["services"][service_name]["build"]
|
||||
|
||||
unit_file = IniFile()
|
||||
unit_file["Unit"] = {}
|
||||
unit_file["Unit"]["Description"] = f"{service_name.capitalize()} build"
|
||||
|
||||
unit_file["Build"] = {}
|
||||
unit_file["Build"]["ImageTag"] = f"localhost/{service_name}"
|
||||
if isinstance(build, str):
|
||||
unit_file["Build"]["SetWorkingDirectory"] = build
|
||||
elif isinstance(build, dict):
|
||||
if "context" in build:
|
||||
unit_file["Build"]["SetWorkingDirectory"] = build["context"]
|
||||
if "dockerfile" in build:
|
||||
unit_file["Build"]["File"] = build["dockerfile"]
|
||||
|
||||
with open(out_file, "w", encoding="utf-8") as f:
|
||||
unit_file.write(f)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("compose_file")
|
||||
parser.add_argument("-o", "--output-dir", default="/etc/containers/systemd", type=Path)
|
||||
parser.add_argument("-u", "--user")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
with open(args.compose_file, encoding="utf-8") as f:
|
||||
yaml_dict = yaml.safe_load(f)
|
||||
|
||||
for network_name in yaml_dict.get("networks", []):
|
||||
out_file = args.output_dir / f"{network_name}.network"
|
||||
print(f'Generating network "{network_name}" ({out_file})')
|
||||
network = yaml_dict["networks"].get(network_name)
|
||||
if network is None:
|
||||
network = {}
|
||||
|
||||
unit_file = IniFile()
|
||||
unit_file["Unit"] = {}
|
||||
unit_file["Unit"]["Description"] = f"{network_name.capitalize()} network"
|
||||
|
||||
unit_file["Network"] = {}
|
||||
unit_file["Network"]["NetworkName"] = network_name
|
||||
unit_file["Network"]["Internal"] = str(network.get("internal", True)).lower()
|
||||
if "enable_ipv6" in network:
|
||||
unit_file["Network"]["IPv6"] = str(network["enable_ipv6"]).lower()
|
||||
|
||||
unit_file["Service"] = {}
|
||||
unit_file["Service"]["Restart"] = "on-failure"
|
||||
|
||||
unit_file["Install"] = {}
|
||||
unit_file["Install"]["WantedBy"] = "default.target"
|
||||
|
||||
with open(out_file, "w", encoding="utf-8") as f:
|
||||
unit_file.write(f)
|
||||
|
||||
for service_name in yaml_dict["services"]:
|
||||
out_file = args.output_dir / f"{service_name}.container"
|
||||
print(f'Generating container "{service_name}" ({out_file})')
|
||||
service = yaml_dict["services"][service_name]
|
||||
|
||||
unit_file = IniFile()
|
||||
unit_file["Unit"] = {}
|
||||
unit_file["Unit"]["Description"] = f"{service_name.capitalize()} container"
|
||||
if "depends_on" in service:
|
||||
enforce_list("depends_on", service)
|
||||
for dependency in service["depends_on"]:
|
||||
unit_file["Unit"].setdefault("Requires", []).append(f"{dependency}.service")
|
||||
unit_file["Unit"].setdefault("After", []).append(f"{dependency}.service")
|
||||
|
||||
unit_file["Container"] = {}
|
||||
if "container_name" in service:
|
||||
unit_file["Container"]["ContainerName"] = service["container_name"]
|
||||
if "image" in service:
|
||||
unit_file["Container"]["Image"] = service["image"]
|
||||
unit_file["Container"]["AutoUpdate"] = "registry"
|
||||
elif "build" in service:
|
||||
write_build_unit(args, yaml_dict, service_name)
|
||||
unit_file["Container"]["Image"] = f"{service_name}.build"
|
||||
unit_file["Container"]["AutoUpdate"] = "local"
|
||||
if "ports" in service:
|
||||
enforce_list("ports", service)
|
||||
unit_file["Container"]["PublishPort"] = service["ports"]
|
||||
if "command" in service:
|
||||
enforce_list("command", service)
|
||||
command = service["command"]
|
||||
cmd = command[0]
|
||||
if len(command) > 1:
|
||||
cmd += " \\\n"
|
||||
for i, cmd_part in enumerate(command[1:]):
|
||||
cmd += f" {cmd_part}"
|
||||
if i < len(command) - 2:
|
||||
cmd += " \\\n"
|
||||
unit_file["Container"]["Exec"] = cmd
|
||||
if "labels" in service:
|
||||
enforce_list("labels", service)
|
||||
unit_file["Container"]["Label"] = service["labels"]
|
||||
if "environment" in service:
|
||||
if isinstance(service["environment"], dict):
|
||||
env_vars = []
|
||||
for key, value in service["environment"].items():
|
||||
env_vars.append(f"{key}={value}")
|
||||
service["environment"] = env_vars
|
||||
enforce_list("environment", service)
|
||||
unit_file["Container"]["Environment"] = service["environment"]
|
||||
if "env_file" in service:
|
||||
unit_file["Container"]["EnvironmentFile"] = service["env_file"]
|
||||
if "volumes" in service:
|
||||
enforce_list("volumes", service)
|
||||
unit_file["Container"]["Volume"] = service["volumes"]
|
||||
if "devices" in service:
|
||||
unit_file["Container"]["AddDevice"] = service["devices"]
|
||||
if "userns_mode" in service:
|
||||
unit_file["Container"]["UserNS"] = service["userns_mode"]
|
||||
if "group_add" in service:
|
||||
enforce_list("group_add", service)
|
||||
unit_file["Container"]["GroupAdd"] = service["group_add"]
|
||||
|
||||
|
||||
unit_file["Service"] = {}
|
||||
unit_file["Service"]["Restart"] = "on-failure"
|
||||
|
||||
unit_file["Install"] = {}
|
||||
unit_file["Install"]["WantedBy"] = "default.target"
|
||||
|
||||
with open(out_file, "w", encoding="utf-8") as f:
|
||||
unit_file.write(f)
|
||||
|
||||
print('\n==> Remember to run "systemctl daemon-reload"')
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user