mirror of
https://github.com/selfhosters/docker-compose-to-UR-template.git
synced 2025-12-21 05:59:30 -06:00
Add projectfiles
This commit is contained in:
208
.gitignore
vendored
Normal file
208
.gitignore
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
|
||||
data/*compose.yml
|
||||
data/*.xml
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||
# 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
|
||||
.idea/
|
||||
|
||||
# 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/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
|
||||
|
||||
# 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
|
||||
|
||||
### Python template
|
||||
# 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/
|
||||
pip-wheel-metadata/
|
||||
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/
|
||||
|
||||
# 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
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.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
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__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/
|
||||
|
||||
93
CLI - Copy.py
Normal file
93
CLI - Copy.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import argparse
|
||||
from Converter import Generator, ReadYAML, run
|
||||
|
||||
|
||||
def str2bool(v):
|
||||
if isinstance(v, bool):
|
||||
return v
|
||||
if v.lower() in ('yes', 'true', 't', 'y', '1'):
|
||||
return True
|
||||
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
|
||||
return False
|
||||
else:
|
||||
raise argparse.ArgumentTypeError('Boolean value expected.')
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='WIP CLI for compose>template',)
|
||||
|
||||
li_ = []
|
||||
services = ReadYAML().services
|
||||
|
||||
service = ""
|
||||
|
||||
msg = """Please choose from this list:"""
|
||||
for i in services:
|
||||
it = i + 1
|
||||
msg += "\n" + str(it) + ": " + str(services[i])
|
||||
li_.append(it)
|
||||
|
||||
parser.add_argument('-s', '--service', choices=li_, type=int,
|
||||
help='list servers, storage, or both (default: %(default)s)')
|
||||
|
||||
parser.add_argument('-a', '--automated', action='store_true', help="Generates files from best-guess")
|
||||
parser.add_argument('-m', '--manual', action='store_true', help="To escape entrypoint imn docker")
|
||||
|
||||
parser.add_argument('-t', '--templateurl', help="Sets Template URL")
|
||||
parser.add_argument('-n', '--name', help="Sets Name")
|
||||
parser.add_argument('-g', '--repository', help="Sets Repository")
|
||||
parser.add_argument('-r', '--registry', help="Sets Registry")
|
||||
parser.add_argument('-u', '--project', help="Sets Project")
|
||||
parser.add_argument('-i', '--icon', help="Sets Icon URL")
|
||||
parser.add_argument('-b', '--bindtime', help="Sets Bindtime", type=str2bool)
|
||||
parser.add_argument('-p', '--privileged', help="Sets Privileged")
|
||||
parser.add_argument('-o', '--overview', help="Sets Overview")
|
||||
parser.add_argument('-d', '--description', help="Sets Description")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
meta_kwargs = {}
|
||||
|
||||
if args.description:
|
||||
meta_kwargs["description"] = args.description
|
||||
|
||||
if args.name:
|
||||
meta_kwargs["name"] = args.name
|
||||
|
||||
if args.repository:
|
||||
meta_kwargs["repository"] = args.repository
|
||||
|
||||
if args.registry:
|
||||
meta_kwargs["registry"] = args.registry
|
||||
|
||||
if args.project:
|
||||
meta_kwargs["project"] = args.project
|
||||
|
||||
if args.icon:
|
||||
meta_kwargs["icon"] = args.icon
|
||||
|
||||
if args.bindtime:
|
||||
meta_kwargs["bindtime"] = args.bindtime
|
||||
|
||||
if args.privileged:
|
||||
meta_kwargs["privileged"] = args.privileged
|
||||
|
||||
if args.overview:
|
||||
meta_kwargs["overview"] = args.overview
|
||||
|
||||
if args.automated:
|
||||
run()
|
||||
|
||||
elif args.manual:
|
||||
print(msg)
|
||||
|
||||
elif not args.service:
|
||||
print(msg)
|
||||
|
||||
if args.service:
|
||||
service = services[args.service - 1]
|
||||
elm = Generator(service)
|
||||
elm.metadata(**meta_kwargs)
|
||||
elm.variable()
|
||||
elm.network()
|
||||
elm.data()
|
||||
elm.write()
|
||||
93
CLI.py
Normal file
93
CLI.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import argparse
|
||||
from Converter import Generator, ReadYAML, run
|
||||
|
||||
|
||||
def str2bool(v):
|
||||
if isinstance(v, bool):
|
||||
return v
|
||||
if v.lower() in ('yes', 'true', 't', 'y', '1'):
|
||||
return True
|
||||
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
|
||||
return False
|
||||
else:
|
||||
raise argparse.ArgumentTypeError('Boolean value expected.')
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='WIP CLI for compose>template',)
|
||||
|
||||
li_ = []
|
||||
services = ReadYAML().services
|
||||
|
||||
service = ""
|
||||
|
||||
msg = """Please choose from this list:"""
|
||||
for i in services:
|
||||
it = i + 1
|
||||
msg += "\n" + str(it) + ": " + str(services[i])
|
||||
li_.append(it)
|
||||
|
||||
parser.add_argument('-s', '--service', choices=li_, type=int,
|
||||
help='list servers, storage, or both (default: %(default)s)')
|
||||
|
||||
parser.add_argument('-a', '--automated', action='store_true', help="Generates files from best-guess")
|
||||
parser.add_argument('-m', '--manual', action='store_true', help="To escape entrypoint imn docker")
|
||||
|
||||
parser.add_argument('-t', '--templateurl', help="Sets Template URL")
|
||||
parser.add_argument('-n', '--name', help="Sets Name")
|
||||
parser.add_argument('-g', '--repository', help="Sets Repository")
|
||||
parser.add_argument('-r', '--registry', help="Sets Registry")
|
||||
parser.add_argument('-u', '--project', help="Sets Project")
|
||||
parser.add_argument('-i', '--icon', help="Sets Icon URL")
|
||||
parser.add_argument('-b', '--bindtime', help="Sets Bindtime", type=str2bool)
|
||||
parser.add_argument('-p', '--privileged', help="Sets Privileged")
|
||||
parser.add_argument('-o', '--overview', help="Sets Overview")
|
||||
parser.add_argument('-d', '--description', help="Sets Description")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
meta_kwargs = {}
|
||||
|
||||
if args.description:
|
||||
meta_kwargs["description"] = args.description
|
||||
|
||||
if args.name:
|
||||
meta_kwargs["name"] = args.name
|
||||
|
||||
if args.repository:
|
||||
meta_kwargs["repository"] = args.repository
|
||||
|
||||
if args.registry:
|
||||
meta_kwargs["registry"] = args.registry
|
||||
|
||||
if args.project:
|
||||
meta_kwargs["project"] = args.project
|
||||
|
||||
if args.icon:
|
||||
meta_kwargs["icon"] = args.icon
|
||||
|
||||
if args.bindtime:
|
||||
meta_kwargs["bindtime"] = args.bindtime
|
||||
|
||||
if args.privileged:
|
||||
meta_kwargs["privileged"] = args.privileged
|
||||
|
||||
if args.overview:
|
||||
meta_kwargs["overview"] = args.overview
|
||||
|
||||
if args.automated:
|
||||
run()
|
||||
|
||||
elif args.manual:
|
||||
print(msg)
|
||||
|
||||
elif not args.service:
|
||||
print(msg)
|
||||
|
||||
if args.service:
|
||||
service = services[args.service - 1]
|
||||
elm = Generator(service)
|
||||
elm.metadata(**meta_kwargs)
|
||||
elm.variable()
|
||||
elm.network()
|
||||
elm.data()
|
||||
elm.write()
|
||||
230
Converter.py
Normal file
230
Converter.py
Normal file
@@ -0,0 +1,230 @@
|
||||
import yaml
|
||||
import xml.etree.ElementTree as ET
|
||||
from xml.dom import minidom
|
||||
|
||||
base = ET.Element('Container', attrib={'version': '2'})
|
||||
base.append(ET.Comment("Generated with Selfhosters compose>template script"))
|
||||
|
||||
|
||||
class ReadYAML:
|
||||
def __init__(self):
|
||||
with open('./data/docker-compose.yml') as f:
|
||||
self.compose = yaml.load(f, Loader=yaml.FullLoader)
|
||||
with open('./data/defaults.yml') as f:
|
||||
self.defaults = yaml.load(f, Loader=yaml.FullLoader)
|
||||
self.services = self._getservices(self)
|
||||
|
||||
def list_field(self, service, field):
|
||||
decrim = {"environment": "=", "ports": "=", "volumes": ":"}
|
||||
fields = []
|
||||
try:
|
||||
for entries in self.compose['services'][service][field]:
|
||||
entries_list = []
|
||||
for entry in entries.split(decrim[field]):
|
||||
entries_list.append(entry)
|
||||
fields.append(entries_list)
|
||||
return fields
|
||||
except KeyError:
|
||||
print(f"{field} is not present, skipping")
|
||||
|
||||
def list_data(self, service, field):
|
||||
return self.compose['services'][service][field]
|
||||
|
||||
def load_defaults(self, field):
|
||||
return self.defaults['branding'][field]
|
||||
|
||||
@staticmethod
|
||||
def _getservices(self):
|
||||
_services = {}
|
||||
ind = 0
|
||||
if not _services:
|
||||
for service in self.compose['services']:
|
||||
_services[ind] = service
|
||||
ind += 1
|
||||
return _services
|
||||
elif _services:
|
||||
return _services
|
||||
else:
|
||||
print("FATAL ERROR")
|
||||
|
||||
|
||||
class Generator:
|
||||
def __init__(self, service):
|
||||
self.elem = base
|
||||
self.service = service
|
||||
self.reader = ReadYAML()
|
||||
self.gen = GenXML(service)
|
||||
|
||||
def write(self):
|
||||
self.gen.write()
|
||||
|
||||
def variable(self, **kwargs2: {}):
|
||||
kwargs = {}
|
||||
fields = self.reader.list_field(self.service, "environment")
|
||||
if fields:
|
||||
for name, value in fields:
|
||||
if name == "TZ":
|
||||
continue
|
||||
|
||||
best_guess = {"Name": {"PUID": {"Target": "100", "Display": "advanced-hide", "Required": "true"},
|
||||
"PGID": {"Target": "99", "Display": "advanced-hide", "Required": "true"}},
|
||||
"should_mask": {"password": {"Mask": "true"}}, "token": {"Mask": "true"}
|
||||
}
|
||||
try:
|
||||
for names in best_guess["Name"][name]:
|
||||
kwargs[names] = best_guess["Name"][name][names]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
for i in best_guess["should_mask"]:
|
||||
if i.lower() in name.lower():
|
||||
kwargs["Mask"] = "true"
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
kwargs = {**kwargs, **kwargs2}
|
||||
GenXML.variable(self, name, value, **kwargs)
|
||||
return self.elem
|
||||
|
||||
def network(self, **kwargs2: {}):
|
||||
kwargs = {}
|
||||
ports = self.reader.list_field(self.service, "ports")
|
||||
if ports:
|
||||
for host, container in ports:
|
||||
best_guess = {"Port": {"80": {"Name": "WebUI", "type": "port"}, "8080": {"Name": "WebUI", "type": "port"}}}
|
||||
try:
|
||||
container, proto = container.split("/")
|
||||
kwargs["Protocol"] = proto
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
kwargs["Name"] = best_guess["Port"][container]["Name"]
|
||||
except KeyError:
|
||||
pass
|
||||
kwargs = {**kwargs, **kwargs2}
|
||||
GenXML.networking(self, host, container, **kwargs)
|
||||
return self.elem
|
||||
|
||||
def data(self, **kwargs2: {}):
|
||||
kwargs = {}
|
||||
for volumes in self.reader.list_field(self.service, "volumes"):
|
||||
for host, container, *vargs in volumes:
|
||||
if vargs:
|
||||
kwargs["Mode"] = vargs[0]
|
||||
kwargs = {**kwargs, **kwargs2}
|
||||
GenXML.data(self, host, container, **kwargs)
|
||||
return self.elem
|
||||
|
||||
def metadata(self, **kwargs2: {}):
|
||||
kwargs = {}
|
||||
kwargs["name"] = self.reader.list_data(self.service, "container_name")
|
||||
kwargs["repository"] = self.reader.list_data(self.service, "image")
|
||||
kwargs["registry"] = f"https://hub.docker.com/r/{kwargs['repository'].split(':')[0]}"
|
||||
kwargs["templateurl"] = self.reader.load_defaults("TemplateURLPrefix") + kwargs["name"] + ".xml"
|
||||
kwargs["icon"] = self.reader.load_defaults("IconPrefix") + kwargs["name"] + ".png"
|
||||
|
||||
kwargs = {**kwargs, **kwargs2}
|
||||
GenXML.metadata(self, **kwargs)
|
||||
|
||||
|
||||
class GenXML:
|
||||
conf_list = []
|
||||
|
||||
def __init__(self, service):
|
||||
self.elem = base
|
||||
self.service = service
|
||||
self.name = "output2"
|
||||
|
||||
def write(self):
|
||||
self._write(self.elem)
|
||||
|
||||
def variable(self, name, value, **kwargs):
|
||||
env = ET.SubElement(self.elem, 'Environment')
|
||||
variable = ET.SubElement(env, 'Variable')
|
||||
ET.SubElement(variable, 'Name').text = name
|
||||
ET.SubElement(variable, 'Value')
|
||||
ET.SubElement(variable, 'Mode')
|
||||
atr = {"Name": kwargs.get("Name", name),
|
||||
"Target": kwargs.get("Target", value),
|
||||
"Default": kwargs.get("Default", value),
|
||||
"Mode": kwargs.get("Mode", ""),
|
||||
"Description": kwargs.get("Description", f"Container Variable: {name}"),
|
||||
"Type": "Variable",
|
||||
"Display": kwargs.get("Display", "always"),
|
||||
"Required": kwargs.get("Required", "false"),
|
||||
"Mask": kwargs.get("Mask", "false")}
|
||||
GenXML.conf_list.append(atr)
|
||||
return self.elem
|
||||
|
||||
def networking(self, host, container, **kwargs):
|
||||
ET.SubElement(self.elem, 'Network').text = "bridge"
|
||||
net = ET.SubElement(self.elem, 'Networking')
|
||||
ET.SubElement(net, 'Mode').text = "bridge"
|
||||
variable = ET.SubElement(net, 'Publish')
|
||||
ET.SubElement(variable, 'HostPort').text = host
|
||||
ET.SubElement(variable, 'ContainerPort').text = container
|
||||
ET.SubElement(variable, 'Protocol').text = kwargs.get("Protocol", "tcp")
|
||||
atr = {"Name": kwargs.get("Name", "tcp"),
|
||||
"Target": kwargs.get("Target", container),
|
||||
"Default": kwargs.get("Default", host),
|
||||
"Mode": kwargs.get("Protocol", "tcp"),
|
||||
"Description": kwargs.get("Description", f"Container Port: {container}"),
|
||||
"Type": "Port",
|
||||
"Display": kwargs.get("Display", "always"),
|
||||
"Required": kwargs.get("Required", "false"),
|
||||
"Mask": kwargs.get("Mask", "false")}
|
||||
GenXML.conf_list.append(atr)
|
||||
return self.elem
|
||||
|
||||
def data(self, host, container, **kwargs):
|
||||
vol = ET.SubElement(self.elem, 'Data')
|
||||
variable = ET.SubElement(vol, 'Volume')
|
||||
ET.SubElement(variable, 'HostDir')
|
||||
ET.SubElement(variable, 'ContainerDir').text = container
|
||||
ET.SubElement(variable, 'Mode').text = kwargs.get("Mode", "rw")
|
||||
atr = {"Name": kwargs.get("Name", f"Container path {container}"),
|
||||
"Target": kwargs.get("Target", container),
|
||||
"Default": kwargs.get("Default", host),
|
||||
"Mode": kwargs.get("Protocol", "rw"),
|
||||
"Description": kwargs.get("Description", f"Container Path: {container}"),
|
||||
"Type": "Path",
|
||||
"Display": kwargs.get("Display", "always"),
|
||||
"Required": kwargs.get("Required", "false"),
|
||||
"Mask": kwargs.get("Mask", "false")}
|
||||
GenXML.conf_list.append(atr)
|
||||
return self.elem
|
||||
|
||||
def metadata(self, **kwargs):
|
||||
self.name = kwargs.get("name", "SomeString")
|
||||
ET.SubElement(self.elem, 'TemplateURL').text = kwargs.get("templateurl", "SomeString")
|
||||
ET.SubElement(self.elem, 'Name').text = kwargs.get("name", "SomeString")
|
||||
ET.SubElement(self.elem, 'Repository').text = kwargs.get("repository", "SomeString")
|
||||
ET.SubElement(self.elem, 'Registry').text = kwargs.get("registry", "SomeString")
|
||||
ET.SubElement(self.elem, 'Project').text = kwargs.get("project", "SomeString")
|
||||
ET.SubElement(self.elem, 'Icon').text = kwargs.get("icon", "SomeString")
|
||||
ET.SubElement(self.elem, 'BindTime').text = kwargs.get("bindtime", "true")
|
||||
ET.SubElement(self.elem, 'Privileged').text = kwargs.get("privileged", "false")
|
||||
ET.SubElement(self.elem, 'Overview').text = kwargs.get("overview", "SomeString")
|
||||
ET.SubElement(self.elem, 'Description').text = kwargs.get("description", "SomeString")
|
||||
|
||||
def _write(self, elem):
|
||||
for atr in self.conf_list:
|
||||
ET.SubElement(elem, 'Config', attrib=atr)
|
||||
xmlstr = minidom.parseString(ET.tostring(elem)).toprettyxml(indent=" ")
|
||||
myfile = open(f"./data/{self.service}.xml", "w")
|
||||
myfile.write(xmlstr)
|
||||
print(f"{self.service} Created\n")
|
||||
|
||||
|
||||
def run():
|
||||
services = ReadYAML().services
|
||||
for service in services:
|
||||
elm = Generator(services[service])
|
||||
elm.metadata()
|
||||
elm.variable()
|
||||
elm.network()
|
||||
elm.data()
|
||||
GenXML(services[service])._write(elm.elem)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM python:3.7-alpine3.10
|
||||
|
||||
LABEL maintainer="Roxedus"\ state="WIP"
|
||||
|
||||
COPY / /app
|
||||
|
||||
RUN python3 -m pip install -r /app/requirements.txt
|
||||
|
||||
WORKDIR /app/
|
||||
|
||||
ENTRYPOINT ["python3", "/app/CLI.py"]
|
||||
CMD ["-a"]
|
||||
3
data/defaults.yml
Normal file
3
data/defaults.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
branding:
|
||||
TemplateURLPrefix: https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/
|
||||
IconPrefix: https://raw.githubusercontent.com/selfhosters/unRAID-CA-templates/master/templates/img/
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
PyYAML
|
||||
Reference in New Issue
Block a user