Skip to content

Latest commit

 

History

History
303 lines (236 loc) · 6.92 KB

File metadata and controls

303 lines (236 loc) · 6.92 KB

A.R.C. Template System Guide

The A.R.C. template system generates Docker Compose configurations from embedded templates.

Overview

Templates are Go text/template files that render service configurations. The system provides:

  • Embedded templates compiled into the binary
  • Template caching for performance
  • Custom functions for common operations
  • Variable substitution for customization
  • Validation at startup

Template Locations

pkg/catalog/templates/
├── docker-compose/          # Service docker-compose snippets
│   ├── generic.yml.tmpl     # Fallback template
│   ├── oracle.yml.tmpl      # PostgreSQL
│   ├── sonic.yml.tmpl       # Redis
│   └── ...
├── configs/                  # Service configuration files
│   ├── postgres/
│   │   └── postgresql.conf.tmpl
│   ├── redis/
│   │   └── redis.conf.tmpl
│   └── ...
└── shared/                   # Shared partials
    ├── networks.yml.tmpl
    └── volumes.yml.tmpl

Template Syntax

Templates use Go's text/template syntax:

# Comments
{{ .Service.Codename }}:
  image: {{ .Service.Image }}

# Conditionals
{{- if .Vars.enabled }}
  enabled: true
{{- end }}

# Loops
{{- range .Service.Ports }}
    - "{{ .Host }}:{{ .Container }}"
{{- end }}

# With blocks
{{- with .Service.Environment }}
  environment:
{{- range . }}
    - {{ .Name }}={{ .Default }}
{{- end }}
{{- end }}

Whitespace Control

Use - to trim whitespace:

  • {{- trims leading whitespace
  • -}} trims trailing whitespace

Template Data

Service Object

Field Type Description
.Service.Codename string Unique service name
.Service.Technology string Technology name
.Service.Role ServiceRole Service category
.Service.Description string Human description
.Service.Version string Version string
.Service.Image string Docker image
.Service.Ports []PortMapping Port mappings
.Service.Dependencies []string Dependency codenames
.Service.Environment []EnvVar Environment variables
.Service.Volumes []VolumeMount Volume mounts
.Service.ConfigFiles []string Config file names
.Service.Aliases []string Alternative names

PortMapping Object

Field Type Description
.Host int Host port
.Container int Container port
.Protocol string tcp or udp
.Description string Port description

Workspace Object

Field Type Description
.Workspace.Name string Workspace name
.Workspace.DataDir string Data directory
.Workspace.ConfigDir string Config directory
.Workspace.Network string Network name

Template Variables

User-provided variables via .Vars:

# Access with defaults
{{ default "default_value" .Vars.my_variable }}

# Check existence
{{- if .Vars.optional_feature }}
  feature_enabled: true
{{- end }}

Built-in Functions

String Functions

# Quote a string
{{ quote .Vars.name }}  # "value"

# Case conversion
{{ lower .Service.Codename }}  # heimdall
{{ upper .Service.Role }}      # INFRASTRUCTURE

# String operations
{{ replace "_" "-" .Name }}           # foo-bar
{{ contains "test" .Value }}          # true/false
{{ hasPrefix "arc-" .ContainerName }} # true/false
{{ hasSuffix ".yml" .FileName }}      # true/false

Environment Functions

# Reference with optional default
{{ env "DATABASE_URL" }}              # ${DATABASE_URL}
{{ env "LOG_LEVEL" "info" }}          # ${LOG_LEVEL:-info}

Platform Functions

# OS detection
{{ if isDarwin }}
  # macOS specific
{{ end }}

{{ if isLinux }}
  # Linux specific
{{ end }}

{{ platform }}  # darwin, linux, windows

Data Functions

# Default values
{{ default "fallback" .Vars.value }}

# YAML serialization
{{ toYAML .Config }}

# Indentation
{{ indent 4 .MultiLineContent }}

Collection Functions

# Join strings
{{ join "," .Service.Aliases }}  # alias1,alias2

# Split string
{{ range split "," .CSVValue }}
  - {{ . }}
{{ end }}

Examples

Basic Service Template

{{ .Service.Codename }}:
  image: {{ .Service.Image }}
  container_name: arc-{{ .Service.Codename }}
  restart: unless-stopped
{{- if .Service.Ports }}
  ports:
{{- range .Service.Ports }}
    - "{{ .Host }}:{{ .Container }}/{{ .Protocol }}"
{{- end }}
{{- end }}
  networks:
    - {{ .Workspace.Network }}

With Dependencies

{{ .Service.Codename }}:
  image: {{ .Service.Image }}
{{- if .Service.Dependencies }}
  depends_on:
{{- range .Service.Dependencies }}
    {{ . }}:
      condition: service_healthy
{{- end }}
{{- end }}

Environment Variables

{{ .Service.Codename }}:
  environment:
{{- range .Service.Environment }}
{{- if .Required }}
    - {{ .Name }}=${{ printf "{%s}" .Name }}
{{- else if .Default }}
    - {{ .Name }}={{ .Default }}
{{- end }}
{{- end }}

Conditional Features

{{ .Service.Codename }}:
{{- if .Vars.enable_debug }}
  command: ["--debug"]
{{- end }}

{{- if .Vars.resources }}
  deploy:
    resources:
      limits:
        memory: {{ default "512M" .Vars.memory_limit }}
{{- end }}

Platform-Specific Configuration

{{ .Service.Codename }}:
  volumes:
{{- if isDarwin }}
    # macOS uses delegated for performance
    - {{ .Workspace.DataDir }}/data:/data:delegated
{{- else }}
    - {{ .Workspace.DataDir }}/data:/data
{{- end }}

Testing Templates

Validate Syntax

renderer := catalog.NewTemplateRenderer()
err := renderer.ValidateTemplate("test", templateContent)
if err != nil {
    // Template has syntax error
}

Render Template

catalog, _ := catalog.NewEmbeddedCatalog()
vars := catalog.NewTemplateVars()
vars.Set("workspace_name", "my-workspace")

output, err := catalog.RenderServiceTemplate("oracle", vars)

Run Tests

# Validate all embedded templates
go test ./pkg/catalog/... -run TestValidateAllTemplates

# Update golden files after changes
go test ./pkg/catalog/... -update-golden

Best Practices

  1. Use defaults: Always provide sensible defaults for optional variables
  2. Trim whitespace: Use {{- and -}} to control output formatting
  3. Document variables: Comment what each variable controls
  4. Test edge cases: Test with empty/missing variables
  5. Follow YAML spec: Ensure output is valid YAML
  6. Include health checks: Every service should have a healthcheck