Skip to content

Commit

Permalink
Add docker compose generator (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
svrnm authored Jan 7, 2025
1 parent db2b7b4 commit 7cd6aa2
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 0 deletions.
3 changes: 3 additions & 0 deletions scripts/generators/docker-compose/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
docker-compose.yaml
config.yaml
example.yml
18 changes: 18 additions & 0 deletions scripts/generators/docker-compose/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.14-alpine

WORKDIR /app

RUN apk addgroup -S appgroup && adduser -S appuser -G appgroup

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY createComposeFile.py .

COPY docker-compose.j2 .

RUN chown -R appuser:appgroup /app && chmod +x createComposeFile.py
USER appuser

# Define the default entrypoint to run the script
ENTRYPOINT ["python", "createComposeFile.py", "--template", "/app/docker-compose.j2"]
67 changes: 67 additions & 0 deletions scripts/generators/docker-compose/createComposeFile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import argparse
from jinja2 import Environment, FileSystemLoader
import os
import yaml

debug_mode = False

def read_yaml(file_path):
with open(os.path.expanduser(file_path), 'r') as file:
# Parse the YAML file
data = yaml.safe_load(file)
return data

def main():
global debug_mode
parser = argparse.ArgumentParser(description='Process some configuration file.')
parser.add_argument(
'--config',
type=str,
default='config.yaml', # Set your default config file here
help='Path to the configuration file (default: config.yaml)'
)
parser.add_argument(
'--debug',
action='store_true',
help='Enable debug mode'
)
parser.add_argument(
'--template',
type=str,
default='docker-compose.j2',
help='Path to the Jinja2 template file (default: docker-compose.j2)'
)
parser.add_argument(
'--output',
type=str,
default='docker-compose.yaml',
help='Path to the output file (default: docker-compose.yaml)'
)
args = parser.parse_args()
config_path = args.config
debug_mode = args.debug
template_path = args.template
output_path = args.output

yaml_data = read_yaml(config_path)
if isinstance(yaml_data, dict):
env = Environment(loader=FileSystemLoader('.'))

template = env.get_template(template_path)

rendered_content = template.render(yaml_data)

with open(output_path, 'w') as output_file:
output_file.write(rendered_content)

else:
raise Exception(f"Failed to read the configuration file {config_file}: The top-level structure is not a dictionary.")

try:
main()
except Exception as e:
if not debug_mode:
print(e)
else:
raise e
exit(1)
72 changes: 72 additions & 0 deletions scripts/generators/docker-compose/docker-compose.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
{%- set global = global | default({}) -%}
{%- set imageNamePrefix = global.imageNamePrefix | default('ghcr.io/cisco-open/') -%}
{%- set imageNameSuffix = global.imageNameSuffix | default('latest') -%}
{%- set serviceDefaultPort = global.serviceDefaultPort | default(80) -%}
{# Ensure the variable always ends with a slash #}
{%- set imageNamePrefix = imageNamePrefix if imageNamePrefix.endswith('/') else imageNamePrefix + '/' %}
services:
{%- if services is defined and services is mapping %}
## services
{%- for name, details in services.items() %}
{{ name }}:
image: {{ imageNamePrefix }}app-simulator-services-{{ details.type }}:{{ imageNameSuffix }}
{%- if details.port is defined %}
ports:
- "{{ details.port }}:8080"
{%- endif %}
{%- if serviceDefaultPort != 8080 %}
environment:
SERVICE_DEFAULT_PORT: "{{ serviceDefaultPort }}"
{%- if serviceDefaultPort <= 1024 %}
cap_add:
- NET_BIND_SERVICE
{%- endif %}
{%- endif %}
configs:
- source: service_{{ name | replace("-", "_") }}_config
target: /config.json
{%- endfor %}
{%- endif -%}
{%- if databases is defined and databases is mapping %}
## databases
{%- for name, details in databases.items() %}
{{ name }}:
image: {{ imageNamePrefix }}app-simulator-databases-{{ details.type }}:{{ imageNameSuffix }}
configs:
- source: database_{{ name | replace("-", "_") }}_config
target: /config.json
{%- endfor %}
{%- endif -%}
{%- if loaders is defined and loaders is mapping %}
## loaders
{%- for name, details in loaders.items() %}
{{ name }}:
image: {{ imageNamePrefix }}app-simulator-loaders-{{ details.type }}:{{ imageNameSuffix }}
configs:
- source: loader_{{ name | replace("-", "_") }}_config
target: /config.json
{%- endfor %}
{%- endif %}
configs:
{%- if services is defined and services is mapping %}
{%- for name, details in services.items() %}
service_{{ name | replace("-", "_") }}_config:
content: |
{{ details | tojson }}
{%- endfor -%}
{%- endif %}
{%- if databases is defined and databases is mapping %}
{%- for name, details in databases.items() %}
database_{{ name | replace("-", "_") }}_config:
content: |
{{ details | tojson }}
{%- endfor -%}
{%- endif %}
{%- if loaders is defined and loaders is mapping %}
{%- for name, details in loaders.items() %}
loader_{{ name | replace("-", "_") }}_config:
content: |
{{ details | tojson }}
{%- endfor -%}
{%- endif %}
4 changes: 4 additions & 0 deletions scripts/generators/docker-compose/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Jinja2==3.1.4
opentelemetry-api==1.29.0
opentelemetry-sdk==1.29.0
PyYAML==6.0.2

0 comments on commit 7cd6aa2

Please sign in to comment.