From 1603e4e5d886eeb56985964ab5f68056614540f1 Mon Sep 17 00:00:00 2001 From: jeanluc Date: Sun, 11 Jun 2023 16:07:53 +0200 Subject: [PATCH] feat: Update template --- .cruft.json | 2 +- bin/slsdoc | 15 +++-- gitea/config/file.sls | 8 ++- gitea/libtofsstack.jinja | 108 +++++++++++++++++++++++++++++++++ gitea/parameters/defaults.yaml | 5 ++ 5 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 gitea/libtofsstack.jinja diff --git a/.cruft.json b/.cruft.json index f940eb4..d1a3a2b 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/lkubb/salt-template-formula", - "commit": "480ee76119cf46d599a1ef29b9e0472958c827c6", + "commit": "b65b98c8b0f95cfed8bf31868cedbd08b9da3e8c", "checkout": null, "context": { "cookiecutter": { diff --git a/bin/slsdoc b/bin/slsdoc index 48d64ba..4d65349 100755 --- a/bin/slsdoc +++ b/bin/slsdoc @@ -19,9 +19,9 @@ ignore = ["_mapdata"] # Given a directory with `package.init`, `package.install` # and `package.clean`, only dump init and clean. avoid_init_dup = True - # By default, states are ordered alphabetically, but init + # By default, states are ordered according to the top `init.sls`, but init # always comes first and all clean states are separated. - # This overrides the purely alphabetical order for the roots. + # This overrides the order for the roots. Defaults to `"auto"`. sort_list = ["init", "clean", "package", "config", "service"] [tool.slsdoc.single_renderer] @@ -79,6 +79,7 @@ cut_prefix = true include_formula_root = false ''' +import re from pathlib import Path import toml @@ -196,7 +197,7 @@ class StateRegistry: """ sort_key = () if a[0] in self.sort_list: - sort_key += (str(self.sort_list.index(a[0])),) + sort_key += (str(self.sort_list.index(a[0])).zfill(3),) else: sort_key += (str(len(self.sort_list)),) if a[-1] == "init": @@ -779,9 +780,15 @@ if __name__ == "__main__": else: raise ValueError(f"Invalid value for renderer: {renderer}") + base = list(base_dir.glob("*/init.sls"))[0].parent + sort_list = options.get("sort_list", "auto") + if sort_list == "auto": + init = (base / "init.sls").read_text() + sort_list = ["init", "clean"] + re.findall(r"\n[^\S\n]+\-\ \.(\S+)", re.findall(r"include:((?:\n(?:[^\S\n]+|\{\%.*)\S.*)+)", init)[0]) + reg = StateRegistry( avoid_init_dup=options.get("avoid_init_dup", True), - sort_list=options.get("sort_list"), + sort_list=sort_list, ) doc = SaltAutodoc( rendr=rend, diff --git a/gitea/config/file.sls b/gitea/config/file.sls index f302780..c6279d3 100644 --- a/gitea/config/file.sls +++ b/gitea/config/file.sls @@ -3,7 +3,7 @@ {%- set tplroot = tpldir.split("/")[0] %} {%- set sls_package_install = tplroot ~ ".package.install" %} {%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %} -{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} +{%- from tplroot ~ "/libtofsstack.jinja" import files_switch with context %} include: - {{ sls_package_install }} @@ -25,8 +25,10 @@ Gitea internal token file is generated: Gitea configuration is managed: file.managed: - name: {{ gitea.lookup.paths.conf | path_join("app.ini") }} - - source: {{ files_switch(["app.ini", "app.ini.j2"], - lookup="Gitea configuration is managed" + - source: {{ files_switch( + ["app.ini", "app.ini.j2"], + config=gitea, + lookup="Gitea configuration is managed" ) }} - template: jinja diff --git a/gitea/libtofsstack.jinja b/gitea/libtofsstack.jinja new file mode 100644 index 0000000..eb17df5 --- /dev/null +++ b/gitea/libtofsstack.jinja @@ -0,0 +1,108 @@ +{%- macro files_switch( + source_files, + config, + lookup=none, + default_files_switch=["id", "os_family"], + indent_width=6, + use_subpath=false, + json=false + ) %} +{#- + Renders a list of `salt://` URI for the `source` parameter of a `file.managed` + state function. This helps with applying the Template Override and + Files Switch (TOFS) pattern. + + Based on `libtofs.jinja`, but homogenized with how `libmapstack` works: + + * Instead of calling `config.get` for configuration parameters to this macro, + the configuration is passed in by the caller. This allows setting + the values together with the other parameters for `libmapstack.jinja` + instead of (unexpectedly) relying on pillar/grains/opts only. + + * Like the `parameters` for `libmapstack`, the name of the switch is prepended + to its value. Hence for a Debian minion named `db` with `["id", "os_family"]`, the + paths would be: + - /files/id/db (instead of `/files/db`) + - /files/os_family/Debian (instead of `/files/Debian`) + - /files/default + + source_files + Ordered list of files to check for. + + config + Externally merged configuration dict, usually the imported value of `map.jinja`. + + lookup + Key under `tofs:source_files` to prepend to the list of source files. + + default_files_switch + If `tofs:files_switch` is unset, this is the ordered list of + parameters to `config.get` to use as selector switch of the directories under + `/files`. + + indent_width + Indentation of the result value to conform to YAML. + + use_subpath + Lookup the source file recursively from the including + state's directory up to `tplroot`. Defaults to false. +#} +{%- set tplroot = tpldir.split("/")[0] %} +{%- set path_prefix = config | traverse("tofs:path_prefix", tplroot) %} +{%- set files_dir = config | traverse("tofs:dirs:files", "files") %} +{%- set files_switch_list = config | traverse("tofs:files_switch", default_files_switch) %} +{#- Lookup source_files (v2), files (v1), or fallback to an empty list #} +{%- set src_files = config | traverse("tofs:source_files:" ~ lookup, config | traverse("tofs:files:" ~ lookup, [])) %} +{#- Append the default source_files #} +{%- set src_files = src_files + source_files %} +{#- Only add to [""] when supporting older TOFS implementations #} +{%- set path_prefix_exts = [""] %} +{%- if use_subpath and tplroot != tpldir %} +{#- Walk directory tree to find {{ files_dir }} #} +{%- set subpath_parts = tpldir.lstrip(tplroot).lstrip("/").split("/") %} +{%- for path in subpath_parts %} +{%- set subpath = subpath_parts[0 : loop.index] | join("/") %} +{%- do path_prefix_exts.append("/" ~ subpath) %} +{%- endfor %} +{%- endif %} +{%- for path_prefix_ext in path_prefix_exts | reverse %} +{%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %} +{#- For older TOFS implementation, use `files_switch` from the config #} +{#- Use the default, new method otherwise #} +{%- set fsl = config | traverse(path_prefix_ext | replace("/", ":") ~ ":files_switch", files_switch_list) %} +{#- Append an empty value to evaluate as `default` in the loop below #} +{%- if "" not in fsl %} +{%- set fsl = fsl + [""] %} +{%- endif %} +{%- for fs in fsl %} +{%- for src_file in src_files %} +{%- if fs %} +{%- set fs_dirs = salt["config.get"](fs, fs) %} +{%- else %} +{%- set fs_dirs = config | traverse("tofs:dirs:default", "default") %} +{%- endif %} +{#- Force the `config.get` lookup result as a list where necessary #} +{#- since we need to also handle grains that are lists #} +{%- if fs_dirs is string %} +{%- set fs_dirs = [fs_dirs] %} +{%- endif %} +{%- for fs_dir in fs_dirs %} +{#- strip empty elements by using a select #} +{%- set url = ( + [ + "- salt:/", + path_prefix_inc_ext.strip("/"), + files_dir.strip("/"), + fs, + fs_dir.strip("/"), + src_file.strip("/"), + ] + | select + | join("/") + ) %} +{{ url | indent(indent_width, true) }} +{%- endfor %} +{%- endfor %} +{%- endfor %} +{%- endfor %} +{%- endmacro %} diff --git a/gitea/parameters/defaults.yaml b/gitea/parameters/defaults.yaml index d2c5dd3..9200b45 100644 --- a/gitea/parameters/defaults.yaml +++ b/gitea/parameters/defaults.yaml @@ -77,6 +77,11 @@ values: socket_activation: false wants: [] version: latest + tofs: + files_switch: + - id + - roles + - os_family # Just here for testing added_in_defaults: defaults_value winner: defaults