feat(components,version): add extra components, new version
[arvados-formula.git] / arvados / libtofs.jinja
1 {%- macro files_switch(source_files,
2                        lookup=None,
3                        default_files_switch=['id', 'os_family'],
4                        indent_width=6,
5                        use_subpath=False) %}
6   {#-
7     Returns a valid value for the "source" parameter of a "file.managed"
8     state function. This makes easier the usage of the Template Override and
9     Files Switch (TOFS) pattern.
10
11     Params:
12       * source_files: ordered list of files to look for
13       * lookup: key under '<tplroot>:tofs:source_files' to prepend to the
14         list of source files
15       * default_files_switch: if there's no config (e.g. pillar)
16         '<tplroot>:tofs:files_switch' this is the ordered list of grains to
17         use as selector switch of the directories under
18         "<path_prefix>/files"
19       * indent_width: indentation of the result value to conform to YAML
20       * use_subpath: defaults to `False` but if set, lookup the source file
21         recursively from the current state directory up to `tplroot`
22
23     Example (based on a `tplroot` of `xxx`):
24
25     If we have a state:
26
27       Deploy configuration:
28         file.managed:
29           - name: /etc/yyy/zzz.conf
30           - source: {{ files_switch(['/etc/yyy/zzz.conf', '/etc/yyy/zzz.conf.jinja'],
31                                     lookup='Deploy configuration'
32                     ) }}
33           - template: jinja
34
35     In a minion with id=theminion and os_family=RedHat, it's going to be
36     rendered as:
37
38       Deploy configuration:
39         file.managed:
40           - name: /etc/yyy/zzz.conf
41           - source:
42             - salt://xxx/files/theminion/etc/yyy/zzz.conf
43             - salt://xxx/files/theminion/etc/yyy/zzz.conf.jinja
44             - salt://xxx/files/RedHat/etc/yyy/zzz.conf
45             - salt://xxx/files/RedHat/etc/yyy/zzz.conf.jinja
46             - salt://xxx/files/default/etc/yyy/zzz.conf
47             - salt://xxx/files/default/etc/yyy/zzz.conf.jinja
48           - template: jinja
49   #}
50   {#- Get the `tplroot` from `tpldir` #}
51   {%- set tplroot = tpldir.split('/')[0] %}
52   {%- set path_prefix = salt['config.get'](tplroot ~ ':tofs:path_prefix', tplroot) %}
53   {%- set files_dir = salt['config.get'](tplroot ~ ':tofs:dirs:files', 'files') %}
54   {%- set files_switch_list = salt['config.get'](
55       tplroot ~ ':tofs:files_switch',
56       default_files_switch
57   ) %}
58   {#- Lookup source_files (v2), files (v1), or fallback to an empty list #}
59   {%- set src_files = salt['config.get'](
60       tplroot ~ ':tofs:source_files:' ~ lookup,
61       salt['config.get'](tplroot ~ ':tofs:files:' ~ lookup, [])
62   ) %}
63   {#- Append the default source_files #}
64   {%- set src_files = src_files + source_files %}
65   {#- Only add to [''] when supporting older TOFS implementations #}
66   {%- set path_prefix_exts = [''] %}
67   {%- if use_subpath and tplroot != tpldir %}
68     {#- Walk directory tree to find {{ files_dir }} #}
69     {%- set subpath_parts = tpldir.lstrip(tplroot).lstrip('/').split('/') %}
70     {%- for path in subpath_parts %}
71       {%- set subpath = subpath_parts[0:loop.index] | join('/') %}
72       {%- do path_prefix_exts.append('/' ~ subpath) %}
73     {%- endfor %}
74   {%- endif %}
75   {%- for path_prefix_ext in path_prefix_exts|reverse %}
76     {%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %}
77     {#- For older TOFS implementation, use `files_switch` from the config #}
78     {#- Use the default, new method otherwise #}
79     {%- set fsl = salt['config.get'](
80         tplroot ~ path_prefix_ext|replace('/', ':') ~ ':files_switch',
81         files_switch_list
82     ) %}
83     {#- Append an empty value to evaluate as `default` in the loop below #}
84     {%- if '' not in fsl %}
85       {%- set fsl = fsl + [''] %}
86     {%- endif %}
87     {%- for fs in fsl %}
88       {%- for src_file in src_files %}
89         {%- if fs %}
90           {%- set fs_dirs = salt['config.get'](fs, fs) %}
91         {%- else %}
92           {%- set fs_dirs = salt['config.get'](tplroot ~ ':tofs:dirs:default', 'default') %}
93         {%- endif %}
94         {#- Force the `config.get` lookup result as a list where necessary #}
95         {#- since we need to also handle grains that are lists #}
96         {%- if fs_dirs is string %}
97           {%- set fs_dirs = [fs_dirs] %}
98         {%- endif %}
99         {%- for fs_dir in fs_dirs %}
100           {%- set url = [
101               '- salt:/',
102               path_prefix_inc_ext.strip('/'),
103               files_dir.strip('/'),
104               fs_dir.strip('/'),
105               src_file.strip('/'),
106           ] | select | join('/') %}
107 {{ url | indent(indent_width, true) }}
108         {%- endfor %}
109       {%- endfor %}
110     {%- endfor %}
111   {%- endfor %}
112 {%- endmacro %}