Skip to content

feat: global recipe templates — run once per host, depend on per-domain#63

Draft
troglodyne-bot wants to merge 1 commit into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/global-recipe-templates
Draft

feat: global recipe templates — run once per host, depend on per-domain#63
troglodyne-bot wants to merge 1 commit into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/global-recipe-templates

Conversation

@troglodyne-bot

Copy link
Copy Markdown
Contributor

What

Add support for $recipe.global.tt template files that render into host-scoped make targets, distinct from the per-domain $recipe.tt fragments that already exist.

Why

When multiple domains share a host (via _shared), global recipe steps — package installs, sysctl tuning, daemon config — ran once per domain. This created redundant operations and forced every template author to add their own idempotency guards for the host-global parts. Issue #33 asked for a clean structural split instead.

How

  • Provisioner::Recipe gains has_global_template() (filesystem check across template dirs) and render_global() (delegates to render_file with the .global.tt name).
  • new_config collects global fragments in a parallel %global_fragments hash and passes it — alongside global_state_dir (/etc/provisioner/state/_global) — to makefile.tt.
  • makefile.tt emits global targets under global_state_dir when any exist. Per-domain targets gain an explicit dependency on their global counterpart ($state_dir/$module: $global_state_dir/$module) when one is present.
  • nginxproxy.tt is split into the first real example: sysctl, worker_connections tuning, global.conf install, and apache2 removal move to nginxproxy.global.tt; only the vhost and ACME dir setup remain per-domain.

Testing

  • t/global_templates.t covers has_global_template (file present/absent, multi-dir search) and rendering paths; skips gracefully when Text::Xslate is absent from the test environment.
  • The nginxproxy split serves as a live integration test when provisioning a shared-host nginx setup.

🤖 Generated with Claude Code

Recipes can now define a $recipe.global.tt alongside their per-domain
$recipe.tt. The global template is rendered into a separate make target
(/etc/provisioner/state/_global/$module) that runs only once regardless
of how many domains share the same host. Per-domain targets depend on
their global counterpart when one exists.

Adds has_global_template()/render_global() to Provisioner::Recipe.
Updates new_config to collect global fragments and pass them to
makefile.tt. Splits nginxproxy.tt into global (sysctl, worker_connections,
global.conf, apache2 removal) and per-domain (vhost, ACME dir) parts as
the canonical example of the pattern.

Closes Troglodyne-Internet-Widgets#33

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread lib/Provisioner/Recipe.pm

=cut

sub has_global_template {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more concisely written as

sub has_global_template {
    my ($self) = @_;
    return any { -f "$_/$self->{global_template}" } @{ $self->{template_dirs} };
}

@teodesian

Copy link
Copy Markdown
Contributor

@troglodyne-bot rebase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants