Skip to content

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 02 Oct 13:59

Changed

  • The shell template engine now claims the .shtpl suffix only (it claimed
    every suffix before, as the documented fallback). The suffix picks the engine
    and the stem names the artifact, which is the convention install.ks.j2
    already used: rename boot.cfg to boot.cfg.shtpl and ctx.render("boot.cfg")
    keeps working unchanged. A file no engine claims is copied as is by the new
    CopyTemplate, last in the default template_types — so a static grub.cfg
    needs no engine, and a file that does carry %{NAME} placeholders ships them
    unrendered until it is renamed. That one case logs a warning naming the rename.
    Narrowing template_types so nothing claims a file raises
    netboot.templates.TemplateEngineError, which names the file and every
    engine's suffixes.

Added

  • Seven more template engines, each claiming its own suffix and costing
    nothing when unused: MakoTemplate (.mako, netboot[mako]),
    LiquidTemplate (.liquid, netboot[liquid]), HandlebarsTemplate
    (.hbs/.handlebars, netboot[handlebars]), MustacheTemplate (.mustache,
    netboot[mustache]), and ERBTemplate (.erb) / EppTemplate (.epp),
    which render through the system ruby and puppet epp render so an existing
    template behaves as its author tested it (PIXIE_RUBY / PIXIE_PUPPET name
    the program if it is not on PATH). Every engine is registered whether or not
    its dependency is present — a claimed file reports what is missing instead of
    being copied — and nothing is imported until a file claims it. What each engine
    does with templates_undefined differs by library and is tabulated in the
    configuration guide; handlebars and mustache cannot fail on an undefined name
    at all.
  • template_data() / DataView / jsonable() — a lazy mapping view of the
    render context for engines that read data rather than evaluate Python
    ({{ target.hostname }} beside {{ ctx.target.hostname }}), and its
    JSON-serialisable form for the subprocess engines.
  • SubprocessTemplate — the base for an engine that renders through another
    language's own tooling: program lookup with an env override, a temporary
    template and values file, a timeout, and the program's stderr in the error.
  • ShellTemplate is configured by subclassing, through three class attributes:
    EXT (a string or a sequence, dots optional, case-insensitive; None or
    "*" claims any suffix), DELIMITER (default "%") and PATTERN —
    "braced" (default, %{NAME}), "unbraced" (%NAME) or "all".
  • POSIX default expressions in the braced form: %{NAME:-fallback} substitutes
    the fallback when the value is unset or empty, %{NAME-fallback} only when
    it is unset. One layer of '/" quotes is stripped, the fallback is literal
    text, and a placeholder with a default never fails whatever
    templates_undefined says. :=, :? and :+ are not implemented and stay
    literal text.
  • CopyTemplate — the copy-as-is engine described above, working in bytes:
    the loader no longer decodes a file before knowing which engine claims it, so
    the copy is byte-exact for anything (CRLF, latin-1, a binary) and
    ctx.render() returns bytes for such a file. EXT narrows it to chosen
    suffixes; Template.BINARY is the flag any engine can set to be handed raw
    bytes. A non-UTF-8 file claimed by a text engine now raises
    TemplateEngineError naming the file, where it used to fail inside the read.
  • Loader.find_source() — the byte-returning counterpart of get_source()
    (which keeps jinja2's text contract).
  • A template-engine registry: register_template_type() (bare or as a
    decorator, with an optional priority=), unregister_template_type(),
    TEMPLATE_TYPES and by_priority(). Loader(template_types=None) — the new
    default — uses every registered engine, so a --load-module plugin is picked
    up without rebuilding the list, and the list is snapshotted at construction.
  • Template.PRIORITY, so engine selection does not depend on registration
    order: engines are consulted highest first, DEFAULT_PRIORITY (0) for an
    ordinary engine and FALLBACK_PRIORITY (-100) for CopyTemplate. A plugin is
    registered after the shipped engines, so without this every plugin would sit
    behind the catch-all and never see a file. Equal priorities keep the order they
    were given, so an explicit template_types list still means what it says.
  • Template.EXT and JinjaTemplate.EXT, so suffix ownership is one declarative
    attribute per engine, plus netboot.templates.template_extensions() to read it
    back normalised.

Full Changelog: v0.2.4...v0.3.0