Giter VIP home page Giter VIP logo

template-formula's Introduction

TEMPLATE-formula

Travis CI Build Status Semantic Release pre-commit

A SaltStack formula that is empty. It has dummy content to help with a quick start on a new formula and it serves as a style guide.

Table of Contents

General notes

See the full SaltStack Formulas installation and usage instructions.

If you are interested in writing or contributing to formulas, please pay attention to the Writing Formula Section.

If you want to use this formula, please pay attention to the FORMULA file and/or git tag, which contains the currently released version. This formula is versioned according to Semantic Versioning.

See Formula Versioning Section for more details.

If you need (non-default) configuration, please refer to:

Contributing to this repo

Commit messages

Commit message formatting is significant!!

Please see How to contribute for more details.

pre-commit

pre-commit is configured for this formula, which you may optionally use to ease the steps involved in submitting your changes. First install the pre-commit package manager using the appropriate method, then run bin/install-hooks and now pre-commit will run automatically on each git commit. :

$ bin/install-hooks
pre-commit installed at .git/hooks/pre-commit
pre-commit installed at .git/hooks/commit-msg

Special notes

Using this template

The easiest way to use this template formula as a base for a new formula is to use GitHub's Use this template button to create a new repository. For consistency with the rest of the formula ecosystem, name your formula repository following the pattern <formula theme>-formula, where <formula theme> consists of lower-case alphabetic characters, numbers, '-' or '_'.

In the rest of this example we'll use example as the <formula theme>.

Follow these steps to complete the conversion from template-formula to example-formula. :

$ git clone [email protected]:YOUR-USERNAME/example-formula.git
$ cd example-formula/
$ bin/convert-formula.sh example
$ git push --force

Alternatively, it's possible to clone template-formula into a new repository and perform the conversion there. For example:

$ git clone https://github.com/saltstack-formulas/template-formula example-formula
$ cd example-formula/
$ bin/convert-formula.sh example

To take advantage of semantic-release for automated changelog generation and release tagging, you will need a GitHub Personal Access Token with at least the public_repo scope.

In the Travis repository settings for your new repository, create an environment variable named GH_TOKEN with the personal access token as value, restricted to the master branch for security.

Note that this repository uses a CODEOWNERS file to assign ownership to various parts of the formula. The conversion process removes overall ownership, but you should consider assigning ownership to yourself or your organisation when contributing your new formula to the saltstack-formulas organisation.

Available states

TEMPLATE

Meta-state (This is a state that includes other states).

This installs the TEMPLATE package, manages the TEMPLATE configuration file and then starts the associated TEMPLATE service.

TEMPLATE.package

This state will install the TEMPLATE package only.

TEMPLATE.config

This state will configure the TEMPLATE service and has a dependency on TEMPLATE.install via include list.

TEMPLATE.service

This state will start the TEMPLATE service and has a dependency on TEMPLATE.config via include list.

TEMPLATE.clean

Meta-state (This is a state that includes other states).

this state will undo everything performed in the TEMPLATE meta-state in reverse order, i.e. stops the service, removes the configuration file and then uninstalls the package.

TEMPLATE.service.clean

This state will stop the TEMPLATE service and disable it at boot time.

TEMPLATE.config.clean

This state will remove the configuration of the TEMPLATE service and has a dependency on TEMPLATE.service.clean via include list.

TEMPLATE.package.clean

This state will remove the TEMPLATE package and has a depency on TEMPLATE.config.clean via include list.

TEMPLATE.subcomponent

Meta-state (This is a state that includes other states).

This state installs a subcomponent configuration file before configuring and starting the TEMPLATE service.

TEMPLATE.subcomponent.config

This state will configure the TEMPLATE subcomponent and has a dependency on TEMPLATE.config via include list.

TEMPLATE.subcomponent.config.clean

This state will remove the configuration of the TEMPLATE subcomponent and reload the TEMPLATE service by a dependency on TEMPLATE.service.running via include list and watch_in requisite.

Testing

Linux testing is done with kitchen-salt.

Requirements

  • Ruby
  • Docker
$ gem install bundler
$ bundle install
$ bin/kitchen test [platform]

Where [platform] is the platform name defined in kitchen.yml, e.g. debian-9-2019-2-py3.

bin/kitchen converge

Creates the docker instance and runs the TEMPLATE main state, ready for testing.

bin/kitchen verify

Runs the inspec tests on the actual instance.

bin/kitchen destroy

Removes the docker instance.

bin/kitchen test

Runs all of the stages above in one go: i.e. destroy + converge + verify + destroy.

bin/kitchen login

Gives you SSH access to the instance for manual testing.

template-formula's People

Contributors

aboe76 avatar alxwr avatar andygabby avatar baby-gnu avatar blu-base avatar dafyddj avatar daks avatar duk3luk3 avatar gmazrael avatar gravyboat avatar javierbertoli avatar jeff350 avatar johnkeates avatar jokipii avatar k-hamza avatar myii avatar n-rodriguez avatar nmadhok avatar noelmcloughlin avatar puneetk avatar semantic-release-bot avatar sroegner avatar stasjok avatar tacerus avatar vutny avatar whiteinge avatar wwentland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

template-formula's Issues

The case for/against an osarchmap.yaml

The osarch and kernel grains are pretty important when handling tarball archives.

Should template-formula provide example for osarchmap.yaml?
Do advantages outweigh any disadvantages?

( A ) Disadvantages

proposal for defaults.yaml

  kernel: {{ grains.kernel | lower }}
  arch: {{ grains.osarch }}

( B ) advantages

  • Sometimes the default value is unsuitable.
  • At least four formulas need different value.

https://github.com/saltstack-formulas/consul-formula/blob/9324564cdf5cbf78bd881322571529c4e8c53673/consul/map.jinja

https://github.com/saltstack-formulas/nomad-formula/blob/1060beada2fb0e06781abfe2f4cf1e2957e780a4/nomad/map.jinja

https://github.com/saltstack-formulas/kibana-formula/blob/c2b8c2c91f021a75a7cbdb432f09945e2437ccf0/kibana/source.sls

https://github.com/saltstack-formulas/node-formula/blob/fdbcde9daf7dba218a47853656ef4a1ecce0704e/node/binary.sls

proposal for defaults.yaml

  kernel: {{ grains.kernel | lower }}

proposal for osarchmap.yaml

# -*- coding: utf-8 -*-
# vim: ft=yaml
#
# Setup variables using grains['osarch'] based logic.
# You just need to add the key:values for an `osarch` that differ
# from `defaults.yaml` + `os_family.yaml`.
# Only add an `osarch` which is/will be supported by the formula
#
# If you do not need to provide defaults via the `osarch` grain,
# you will need to provide at least an empty dict in this file, e.g.
# osarch: {}
---
amd64:
  arch: amd64

x86_64:
  arch: amd64

386:
  arch: 386

arm64:
  arch: arm64

armv6l:
  arch: armv6l

armv7l:
  arch: armv6l

ppc64le:
  arch: ppc64le

s390x:
  arch: s390x

I can raise a PR once we have guidance on what people prefer.

Remove tags when running bin/convert-formula.sh

Is your feature request related to a problem?

When I clone the template-formula to a new one and run the bin/convert-formula.sh I have the tags related to template-formula locally.

Describe the solution you'd like

I clean the tags with the following command:

git tag -l | xargs git tag -d

Describe alternatives you've considered

Additional context

[BUG] Failure when running the formula on FreeBSD

Your setup

Formula commit hash / release tag

14ebf92

Versions reports (master & minion)

FreeBSD via. kitchen-vagrant:

$ salt -V
Salt Version:
           Salt: 2019.2.0
 
Dependency Versions:
           cffi: 1.12.3
       cherrypy: Not Installed
       dateutil: Not Installed
      docker-py: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
          ioflo: Not Installed
         Jinja2: 2.10.1
        libgit2: Not Installed
        libnacl: Not Installed
       M2Crypto: Not Installed
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.6.2
   mysql-python: Not Installed
      pycparser: 2.19
       pycrypto: 2.6.1
   pycryptodome: Not Installed
         pygit2: Not Installed
         Python: 3.6.9 (default, Aug 22 2019, 01:16:05)
   python-gnupg: Not Installed
         PyYAML: 5.1
          PyZMQ: 18.1.0
           RAET: Not Installed
          smmap: Not Installed
        timelib: Not Installed
        Tornado: 4.5.3
            ZMQ: 4.3.1
 
System Versions:
           dist:   
         locale: US-ASCII
        machine: amd64
        release: 12.0-RELEASE-p6
         system: FreeBSD
        version: Not Installed

Pillar / config used

Using the default suite:

pillars_from_files:
template.sls: pillar.example
define_roles.sls: test/salt/pillar/define_roles.sls


Bug details

Describe the bug

       ----------   
                 ID: template-service-running-service-running
           Function: service.running
               Name: systemd-udevd
             Result: False    
            Comment: The named service systemd-udevd is not available

Steps to reproduce the bug

$ export KITCHEN_LOCAL_YAML=kitchen.vagrant.yml \
  && bin/kitchen verify ${INSTANCE}

Expected behaviour

All states and InSpec tests must pass.

Attempts to fix the bug

Probably needs to be resolved based around devd:

Will almost definitely require using a separate test pillar.

Additional context

Inline comments for os*.yaml files is wrong, can't be empty

It seems that if any of the os*.yaml files is empty, salt crashes with

       {%- import_yaml topdir ~ "/osmap.yaml" as osmap %}
       {%- import_yaml topdir ~ "/osfingermap.yaml" as osfingermap %}
 
       {% set defaults = salt['grains.filter_by'](default_settings,    <======================
           default='template',
           merge=salt['grains.filter_by'](osfamilymap, grain='os_family',
             merge=salt['grains.filter_by'](osmap, grain='os',
        merge=salt['grains.filter_by'](osfingermap, grain='osfinger',
          merge=salt['pillar.get']('template:lookup', default={})
       [...]
       ---
       Traceback (most recent call last):
         File "/usr/lib/python2.7/dist-packages/salt/utils/templates.py", line 392, in render_jinja_tmpl
           output = template.render(**decoded_context)
         File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 1008, in render
           return self.environment.handle_exception(exc_info, True)
         File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 780, in handle_exception
           reraise(exc_type, exc_value, tb)
         File "<template>", line 4, in top-level template code
         File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 1073, in make_module
           return TemplateModule(self, self.new_context(vars, shared, locals))
         File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 1152, in __init__
           body_stream = list(template.root_render_func(context))
         File "/tmp/kitchen/var/cache/salt/minion/files/base/template/map.jinja", line 12, in top-level template code
           {% set defaults = salt['grains.filter_by'](default_settings,
         File "/usr/lib/python2.7/dist-packages/salt/modules/grains.py", line 600, in filter_by
           base=base)
         File "/usr/lib/python2.7/dist-packages/salt/utils/data.py", line 412, in filter_by
           for key in lookup_dict:
       TypeError: 'NoneType' object is not iterable

I think it should be said explicitely in the inline comments that you need to have at least an empty dict inside.

gitlab-ci.yml file can be split to increase readability

Is your feature request related to a problem?

gitlab-ci.yml is now a big long file with different tasks, which is hard to read and understand.

Describe the solution you'd like

gitlab-ci.yml file has the option to include external yml files:
see: https://docs.gitlab.com/ee/ci/yaml/#include

Especially the local and remote includes are interesting.

Describe alternatives you've considered

not needed

Additional context

improve readability and interoperability between the formulas is also possible.
No need to duplicate code (dry)

[Discussion] TOFS/pillar.stack/stack-formula for map.jinja

Currently map.jinja relies heavily on Pillar data. This shifts the load to the master which does not scale well. With the recent introduction of config.get by @myii other data sources are accessible¹, but there are some caveats:

  • no merging (not implemented in salt-ssh)
  • merging not configurable (as in pillar.stack
  • fixed lookup sequence¹

@claudekenni implemented a prototype mimicking pillar.stack: https://github.com/claudekenni/stack-formula
He also wrote an execution module https://github.com/claudekenni/stack_module which provides stack.items, stack.get and others,
and a SDB module: https://github.com/claudekenni/sdbstack.

How can we take the experience of TOFS, pillar.stack and @claudekenni's prototypes and move ~80% of our Pillar data onto the minions?

  • with configurable lookup sequence
  • with configurable merging
  • with support for various data sources (Like Pillar, which supports i.e. Jinja and the Py renderer.)
  • with computation on the minion
  • with support for salt (ZMQ), salt-call (local) and salt-ssh (SSH)
  • while still supporting Pillar for secrets
  • while still keeping the formulas independent of one another and independent of code which is not part of the Salt Module Index

¹ SDB <; Minion configuration <; Minion's grains <; Minion's pillar data < ... (credit: @myii)


Common checklist

@alxwr Hope you don't mind me hijacking this part of the comment as a common checklist for anyone to edit! It shows up properly in the GitHub UI if it's in the first comment:

  • [Ref] Make the tests pass with the new config.get on existing formulas with semantic-release and a valid test suite -- PR.

[BUG] `convert-formula` calls ex with unknown argument

Your setup

Host OS: Archlinux

Formula commit hash / release tag

f48a727


Bug details

Describe the bug

When running bin/convert-formula.sh, the following error occurs multiple times:

ex: illegal option -- u                                                                                              
Usage: ex [- | -s] [-l] [-L] [-R] [-r [file]] [-t tag]    
       [-v] [-V] [-w size] [+cmd | -c cmd] file...

The -u flag is not available in ex (or even vi as far as I can tell).

Debian-based systems tend to have /usr/bin/ex symlinked to /usr/bin/vim.basic, so the -u flag will work. But on my Arch box, /usr/bin/ex is the ex binary.

This error means that none of the search & replacements for TEMPLATE work.

Steps to reproduce the bug

(On an Arch installation)

  • Clone the formula repo locally
  • cd into the formula directory
  • Run bin/convert-formula.sh example

Expected behaviour

convert-formula.sh should complete without errors and replace TEMPLATE strings correctly.

Additional context

Maybe checking to see if ex is really vim in ex clothing, and then excluding the -u as required would fix it and not break any existing vim users.

Establish `template-formula` as the go-to resource for all formula development

This issue is a collection of ideas initially taken from the log of discussions[1][2][3][4] captured in the wiki.

Visibility

  • Make this template-formula a sticky formula for the whole SaltStack Formulas project.
    • Probably best to wait until most of these changes have been made, to prevent premature use of the template.

Release tagging (for each merged PR)

YAML & Jinja

  • Update to new map.jinja style -- #20.
  • Issue with new map.jinja style due to defaults.merge vs. salt-ssh -- Upstream bug report: saltstack/salt#51605.
  • Use intermediate map.jinja style for the time being -- #25.
  • Update YAML to show all possible OSes that can be supported -- #23.
  • Add other used OS grains-based YAML files; also update map.jinja accordingly.
  • Add a macros.jinja template with common macros that "Any formulae would find useful":
    • Repeatable patterns deserve repeatable code.
  • Evaluate whether the 'masterless' extra_yamls approach outlined by @javierbertoli is another approach to solve scalability issues (awaiting sample PR).
  • Decide a consistent method to work with jinja_lstrip_blocks and more specfically jinja_trim_blocks until the upstream issue is resolved.
  • Confirm (and then globally apply) standard of always using ~ for string concatenation instead of +.
  • Use | json instead of | tojson, at least until 2017.7 support is required -- refer back to this comment.
  • Prefer {%- ... %} as a standard due to linked issues raised in this comment.
  • Consider tracking "custom" grain values to the map to cover for situations when the actual grain
    is unavailable, such as osmajorrelease and osfinger on Arch Linux.
    • PR mentioning the issue: saltstack-formulas/firewalld-formula#29
    • Potential solution at the end of map.jinja:
      • {%- do template.update({'osmajorrelease': salt['grains.get']('osmajorrelease', 0)|int }) %}
  • Determine strategy regarding YAML keys with no given value such as comp_lzo: -- insist on explicit values at all times by modifying our yamllint configurations based on https://yamllint.readthedocs.io/en/stable/rules.html#module-yamllint.rules.empty_values?
  • Discuss the use of yaml_dump.sls (via. ssf-formula) in all formulas so that changes to the map before and after can easily be picked up in the CI logs.

TOFS pattern vs. pillar

  • Switch to the TOFS pattern (files_switch) -- #19.
  • If required, update TOFS pattern to allow working with custom files -- #28.
  • Use source_files instead of files in the pillar (otherwise there are two files, which will cause confusion) -- #76.
  • Use libtofs.jinja instead of macros.jinja, to work towards the simplest drop-in solution for other formulas -- #79.

Other pillar-avoidance methods to consider

  • Consider changing all uses of pillar.get to config.get globally (as in, for all formulas eventually).
  • Work through discussions captured from Slack where alternatives are discussed (TODO: capture the discussions in a wiki page here).

Make the formula portable

Documentation

Tests and CI

  • Add a test scaffold with kitchen-ci and inspec (or testinfra) examples for the basic tasks (add/remove package, check service, etc) -- want to replace old serverspec tests -- #34.
    • Discussions so far seem to be leaning towards inspec.
    • Goss and saltcheck also mentioned -- perhaps alongside for the latter?
    • Also consider saltscaffold.
  • Compare this with the formula-test-harness introduced to the nginx-formula in this pull.
    • See discussion from here to see why no longer considering this.
  • Find solution for opensuse not working -- #45.
  • For instances that requiring restarting (e.g. opensuse usually works the second time its run), evaluate ways of minimising these delays:
  • Add tests for all clean stages -- @javierbertoli looking into this.
  • Work through this list, closing (and even reverting?) the PRs for the formula-test-harness, since it only has 1 contributor and is no longer maintained.
  • Add tests for TOFS, as suggested by @daks in #76.
  • Use specific versions in Gemfile, to avoid test failures -- #81.
  • Consider merging (locale-specific) provision_command for each platform, as used in the systemd-formula -- only if actually useful, not just for the sake of it.
  • Use pre-salted images for testing for improved performance and reliability -- @javierbertoli has provided the image and @myii has made PR #92.
  • Update: .kitchen.yml => kitchen.yml -- done in #40.
  • Update: pillars-from-files => pillars_from_files -- done in #74.

States

  • Make the formula "actually functional" so that all parts can be run, to aid understanding and quality assurance.
  • Adapt template-formula to not be too focussed on pkg:
    • Must also consider archives, tarball releases, GitHub repos, etc.
  • Add the remove state advocated by @noelmcloughlin.
  • Ensure that each file does only one thing and do it well (instead of monolithic files):
    • E.g. pkg/install.sls, pkg/clean.sls, repo/install.sls, repo/clean.sls, etc.
  • Add 'formula components' that can be reused in a formula as suggested by @javierbertoli, such as:
    • 'service-template'
    • 'pkg-template'
    • 'ini-config-template'
    • 'yaml-config-template'
    • Etc.
  • Prevent the formula from running on unsupported minions -- #91.

Repo standards

Other resources to evaluate for inclusion

Generic support for init.d scripts

There are a number of formula which drop file into /etc/default/ because its needed for some situations (PATHs). *nix software is allowed to support two type of configurations-

  1. software config: /etc/template/template.conf
  2. system config (node, java, golang, PATHS, ENV). /etc/default/template.sh

The template formula needs to be extended for the second use case. The libtofs implementation can be extended here but dict and file naming conventions may need to be refactored.

For CentOS it is unclear if /etc/default or /etc/sysconfig is most appropriate so the directory for a system config file should be configurable.

Background:

Configuring init.d Scripts - http://wwudevops.github.io/curriculum/06_boot_filesystem.html#configuring-init-d-scripts

The Linux FileSystem Hierarchy Standard-

CentOS hier(7):

/etc. Contains configuration files which are local to the machine. Some larger software packages, like X11, can have their own subdirectories below /etc. Site-wide configuration files may be placed here or in /usr/etc. Nevertheless, programs should always look for these files in /etc and you may have links for these files to /usr/etc.

 /etc/opt. Host-specific configuration files for add-on applications installed in /opt.

FreeBSD hier(7):

/etc/ system configuration files and scripts

defaults/  default system configuration	files; see rc(8)

Darwin hier(7)

 /etc/         system configuration files and scripts

Ubuntu hier(7)

/etc Contains configuration files which are local to the machine. Some larger software packages, like X11, can have their own subdirectories below /etc. Site-wide configuration files may be placed here or in /usr/etc. Nevertheless, programs should always look for these files in /etc and you may have links for these files to /usr/etc.

/etc/opt.  
    Host-specific configuration files for add-on applications installed in /opt.

Use `yamllint` config to prevent `empty-values` & use new `yaml-files` setting

This has come up before and there was a reminder of it here:

Having empty values in pillar.example (or any of the YAML files) is never a good idea, leading to confusion and rendering errors. Values should be set explicitly, with it being easy to set null if that's what's really required.

With yamllint now active in our repos, this can easily be enforced from its configuration file:

 rules:
+  empty-values:
+    forbid-in-block-mappings: true
+    forbid-in-flow-mappings: true
+
   line-length:
     # Increase from default of `80`
     # Based on https://github.com/PyCQA/flake8-bugbear#opinionated-warnings (`B950`)
     max: 88

Propagating this is straightforward using the ssf-formula.

[Discussion] [Idea] Move all utilities for formulas outside of edited files (states, yaml)

On several discussions about TOFS or config.get, I have expressed my main problem with those 'tools': they clutter/complicate the files that contributors needs to write.

My point of view on this is that such basic/simple formulas tools should not complicate any new comer which want to create a simple formula without any knowledge of them before.
They are too intrusive to keep this principe.

Part of TOFS is already abstracted in libtofs.jinja but it still needs 4-5 lines for each file.managed.
I know less config.get but I think it also had a lot of code (can't find now the PR I am looking) and especialy to deal with cases like salt-ssh.

I wonder if there is some way to do it. Puppet modules uses lib to add specific code. Ansible roles seems to use handlers.
Couldn't _modules or _states or whatever be used to do it? Even if we need to convert jinja/state code to Python.

cc @myii, @javierbertoli @aboe76 @n-rodriguez to open-mindly discuss this idea :)

Improve `libtofs.jinja` to handle custom grains that are lists, etc.

While debugging TOFS on Slack (see https://freenode.logbot.info/saltstack-formulas/20190722#c2428921), found that a custom grains for role (using a list) crashes out libtofs.jinja.

    Data failed to compile:
----------
    Rendering SLS 'base:ssf.config.file' failed: Jinja variable 'list object' has no attribute 'strip'
/var/cache/salt/minion/files/base/ssf/libtofs.jinja(90):
---
[...]
        {%- if fs %}
          {%- set fs_dir = salt['config.get'](fs, fs) %}
        {%- else %}
          {%- set fs_dir = salt['config.get'](tplroot ~ ':tofs:dirs:default', 'default') %}
        {%- endif %}
        {%- set url = [    <======================
            '- salt:/',
            path_prefix_inc_ext.strip('/'),
            files_dir.strip('/'),
            fs_dir.strip('/'),
            src_file.strip('/'),
[...]

Need to improve the library to deal with these cases as well.

Fancy taking this on @baby-gnu? Or shall I work on it?

Change file_switch to append source_file lookups, rather than override

To give a concrete example from nginx-formula:

 {{ files_switch([server, 'server.conf'],
                      'server_conf_file_managed'
         )
      }}

On any given host, I may have many managed server values. Therefore, it's important that it's possible to use the dynamic server filename.

If I configure nginx.tofs.source_files.server_conf_file_managed to, e.g. default.conf, I expect this to be appended to the list of files that get looked for.

However instead, nginx-formula will now only look for default.conf, removing the ability to have multiple servers per host.

My expectation is that setting server_conf_file_managed adds a cascading override - i.e. it appends to the beginning of the list of file names to look for, not overrides the full existing list.

TOFSv2: Change duplicate use of `files`; use `templates` list instead

The current implementation uses files twice.

Here:

# dirs:
# files: files_alt

And here:

# files:
# template-config:
# - 'example_alt.tmpl'
# - 'example_alt.tmpl.jinja'

Since the second one is a list of templates to use, I suggest this is changed to:

    # templates:
    #   template-config:
    #     - 'example_alt.tmpl'
    #     - 'example_alt.tmpl.jinja'

The impact is fairly significant, since this needs to be done throughout:

  1. pillar.example
  2. macros.jinja
  3. TOFS_pattern.md
  4. All formulas that have already adapted to TOFSv2

Since TOFSv2 is very new, this change needs to be brought in ASAP. It hardly can be in use right now but it soon could be.

[FEATURE] Use https://editorconfig.org/

Is your feature request related to a problem?

Default indention and file encoding is not specified.

Describe the solution you'd like

Use https://editorconfig.org/.

Describe alternatives you've considered

  • Let the editor guess it (advanced).
  • Let the user deal with it (set it manually for each file).

Additional context

The 'do update' pattern in map.jinja is not working properly for nested defaults when overriden by lookup

I think the map.jinja pattern is not working ideally as it is now as it completely falls apart if you have nested defaults.yaml file and you try to use lookup to change a single dictionary value somewhere in deeper levels of the default config.

The problematic part is the dictionary update where default_settings is updated with os_family_map as it does not do deep merging.

My main issue with this is not that I can't work around it, it's just that this template is for many seen as "best practice" and reused, and this issue is rather hard to diagnose as it works most of the time, until it just doesn't just because you added a lookup value to a formula with important nested defaults.

The most intuitive solution I have seen is using the base attribute of grains.filter_by. Is there any reason that the base attribute of grains.filter_by is not used today?

A pattern like this has none of these issues as far as I have experienced:

map.jinja:

# -*- coding: utf-8 -*-
# vim: ft=jinja

{## Start with defaults from defaults.yaml ##}
{% import_yaml 'template/defaults.yaml' as default_settings %}

{##
Setup variables using grains['os_family'] based logic, only add key:values
that differ from what is in defaults.yaml
##}
{% set base_settings = salt['grains.filter_by'](
  default_settings,
  , grain="os_family"
  , merge=salt['pillar.get']('template:lookup')
  , base='template')
%}

{## Merge in template:lookup pillar ##}
{% set template = salt['pillar.get'](
        'template',
        default=base_settings,
        merge=True
    )
%}

defaults.yaml:

# -*- coding: utf-8 -*-
# vim: ft=yaml
template:
  pkg: template
  config: '/etc/template'
  service:
    name: template

Debian: {}
Suse: {}
Arch:
  pkg: template-arch
RedHat:
  config: /etc/template.conf

An additional benefit is that since all the default settings is stored in defaults.yaml the os family map is much easier to write.

Improvements (enhancement backlog?) needed

It would be nice to be able to produce working formula rapidly from a template.

For example this template is not supporting repo / release / container mediums for deployment. But modern digital companies are heavily using these channels for DevOps and Cloud Native deployments and solutions. It would be good to improve this formula so people can producer a formula rapidly.

Features:

  • release support: archive download, checksum, extraction of tarballs.
  • repo support: git latest from url
  • repo-make support: previous plus make command.
  • container
  • every init state having a corresponding clean state!!!

There are lot of tools (i.e. chrome, gnuPG. scala, VS, git-review,, postman, firefox developer edition, pulse secure, citrix workspace, etc) and technologies (quicc, gprc, or whatever) that could be hosted but developing formulas is too hard ... template-formula should be improved!!!

map.jinja and yaml speed improvements on large formula's

see saltstack/salt#39017

if we can convert some formula's which have a big or multiple yaml files
we can convert these to json and import those.

oneliner to convert

python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)' < file.yaml > file.json

We could keep the yaml files for easier maintenance but have a nice readme about why
this formula needs json files for importing...

Finalise standardisations remaining from the `_mapdata` implementation

#203 has been merged but there are outstanding issues that need to be finalised, particularly when standardising across all of the formulas in our organisation (using the ssf-formula). Quoting the relevant comment here:

init.sls uses 'absolute path' to include states

In init.sls https://github.com/saltstack-formulas/template-formula/blob/master/template/init.sls#L4 we can see

include:
  - template.install
  - template.config
  - template.service

It uses 'absolute path' to include other states. In our private formulas, we tend to use the following pattern with relative paths

include:
  - .install
  - .config
  - .service

and it works well, and lets you name the formula as you want (eg: if you 'vendor' it in your repository).

If we don't identify any problem with this pattern, I think we should use it.

I can make a PR if we agree to change this.

Resolve Travis concurrent jobs or consider Azure pipelines

https://freenode.logbot.info/saltstack-formulas/20190516#c2180979:

- - -
09:59 myii @​gtmanfred A problem is beginning to manifest: as we convert more formulas to semantic-release (and generally get inspec testing working on formulas), our Travis queuing is slowing things down. It only appears to handle 3 jobs at a time; the most I've ever seen is 5, but that may have been on my own forks. So it's not uncommon to see 3/50 active jobs and when things get bad, it can take up to an hour to get results.I'm usually manually cancelling and rerunning (my own) jobs to minimise loads but contributors won't be able to do that. This load will only increase in time, as more formulas get converted. We could start limiting the number of jobs per formula but is there anything else that can be done?
10:06 slack1872 except paying for more concurrent builds, I'm not sure...
10:06 myii I reckon we're going to have to start limiting testing per formula.
10:07 myii Unless a formula has specific tests that need to be run on specific combinations of platform/salt-version.
10:08 slack1872 Same problem always pops: you had tests (which is great) and then your tests take too much time...We have the same problem @ work, with 8 kitchen VM created and highstate taking near 15 min. But on Jenkins at least we can run VM in parallel
10:09 myii What do you say to this idea:
10:09 myii 5 instances max, one from each os.
10:10 myii 2019.2 x2, 2018.3 x2 and 2017.7 x1.
10:12 myii We've got a nice set to choose from but now this is about how to select which ones to use per formula.
10:12 myii Is 5 sufficient for testing purposes?

https://freenode.logbot.info/saltstack-formulas/20190516#c2181226:

- - -
12:39 gtmanfred no, limit concurrent jobs
12:39 gtmanfred in travis
12:39 gtmanfred you can have as many runs as you want, but it will only run one per repo at a time

https://freenode.logbot.info/saltstack-formulas/20190516#c2181237:

- - -
12:41 gtmanfred if that doesn’t work, we can look into moving to azure pipelines
12:41 gtmanfred i have been playing with that recently and it is pretty good
12:41 myii Excellent.
12:41 gtmanfred not as easy to build a matrix automatically for, but still pretty easy
12:42 myii Look forward to it.
12:43 gtmanfred Here is a version that builds the matrix https://github.com/saltstack/pepper/blob/develop/azure-pipelines.yml
12:43 myii Looks decent.
12:43 gtmanfred and here is a version where you just define it https://github.com/gtmanfred/pepper/blob/f15ce586a02b377ef1f8bdb48e378c5505179074/azure-pipelines.yml
12:44 myii The loop is nicer.
12:44 gtmanfred agreed
12:44 gtmanfred one thing that it does not have is allowed_failures
12:44 gtmanfred and the yaml can be gross
12:45 myii I don't think we're really using that.
12:45 myii So it shouldn't be a problem.
12:45 gtmanfred There is also this limitation with the yaml https://twitter.com/resticbackup/status/1117327446456655873
12:45 gtmanfred it does not parse whole elements in dot net, it parses one line at a time
12:46 myii OK, good to be aware of that.
12:47 myii If this comes to fruition, we'll put these notes in a little doc.

How to add multiple sub config files

I tried reading the documentation but can't seem to find info on this; Does this template allow for supporting multiple subconfig files? For example I have an application I am trying to make a community formula for that has one main config, and then a bunch of other config files like this:

nifi:
  pkg:
    name: myapp
  rootgroup: root
  config: '/etc/myapp'
  service:
    name: myapp
  subcomponent:
    config1: '/etc/myapp-subcomponent1-formula.conf'
    config2: '/etc/myapp-subcomponent2-formula.conf'
    config3: '/etc/myapp-subcomponent3-formula.conf'
    config4: '/etc/myapp-subcomponent4-formula.conf'
    config5: '/etc/myapp-subcomponent5-formula.conf'
  # Just here for testing
  added_in_defaults: defaults_value
  winner: defaults

or {} changes don't work for me

The changes for default empty dictionary don't work for me,...

{%- import_yaml topdir ~ "/defaults.yaml" or {} as default_settings %}
{%- import_yaml topdir ~ "/osfamilymap.yaml" or {} as osfamilymap %}
{%- import_yaml topdir ~ "/osmap.yaml" or {} as osmap %}
{%- import_yaml topdir ~ "/osfingermap.yaml" or {} as osfingermap %}

do I need a special version of a component?

file.managed error: is not an absolute path

Hi,

Im trying to make a new formula based on this template as it seems like a great starting point. Please be aware; this is one of my first formulas and i might be prone to beginner mistakes.

Running this state:

exabgp-config-file-file-managed:
  file.managed:
    - names:
      - {{ exabgp.config.path }}/{{ exabgp.config.name }}:
        - source: {{ files_switch(['exabgp.conf.jinja']) }}
      - {{ exabgp.env.path }}/{{ exabgp.env.name }}:
        - source: {{ files_switch(['exabgp.env.jinja']) }}
    - mode: 644
    - user: {{ exabgp.user }}
    - group: {{ exabgp.group }}
    - template: jinja
    - require:
      - sls: {{ sls_package_install }}

with defaults.yaml:

exabgp:
  user: nobody
  group: nobody
  config: 
    path: '/etc/exabgp'
    name: 'exabgp.conf'
  env:
    path: '/etc/exabgp'
    name: 'exabgp.env'

Gives me errors like this (with different paths) at the minion:

----------
          ID: exabgp-config-file-file-managed
    Function: file.managed
        Name: salt://exabgp/files/default/exabgp.env.jinja
      Result: False
     Comment: Specified file salt://exabgp/files/default/exabgp.env.jinja is not an absolute path
     Started: 09:11:22.911320
    Duration: 1.762 ms
     Changes:
----------

Let me know if i need to provide more data or a better explanation.

Thanks,
Martin

[FEATURE] Use Copier to keep formulas up-to-date with template development automatically

Is your feature request related to a problem?

This template can only be instantiated once. Both the template and the instantiated formula will develop. It should be easy for formula maintainers to keep their formulas up to the latest standards.

Describe the solution you'd like

Copier is the only project template program I know that can not only generate the initial project, but using git history update the project with the diff from the template.

Describe alternatives you've considered

Additional context

Improve testing section in README mentioning suite as well

Improve this section:

$ bin/kitchen test [platform]
Where ``[platform]`` is the platform name defined in ``kitchen.yml``,
e.g. ``debian-9-2019-2-py3``.

  1. Should be be based on suite-platform including the example.
  2. Would also be useful to mention using bin/kitchen list or even bin/kitchen list -b.

Once done, need this to be propagated to all of the other formulas using this section.

[FEATURE] Use https://reuse.software/

Is your feature request related to a problem?

Apache-2.0 is chosen for the user. This choice should be explicit. Additionally this choice should be machine readable and linted.

Describe the solution you'd like

Integrate https://reuse.software/. As this is a template, this means two things:

  1. Make the template itself comply with https://reuse.software/.
  2. Help the user to make a license choice and make the converted project comply with https://reuse.software/.

Describe alternatives you've considered

Additional context

It seems the copyright framework was put together 2014. Now that https://reuse.software/ exists I think this can be reconsidered.

The question is also how the template itself should/is licensed and what that means for derived projects? Is the assumption that this "skeleton" is in itself not copyrightable? I guess not as you have a LICENSE file. But than I start of with Apache-2.0 license.

Evaluate if `dbus` fix is required for `opensuse`

Evaluate: https://dhenandi.com/how-to-running-systemd-on-opensuse-docker-container/.


This was first mentioned at https://freenode.logbot.info/saltstack-formulas/20190221#c2013870:

11:52onslack
<noel.mcloughlin> <dhenandi.com/how-to-running-systemd-on-opensuse-docker-container>
11:53onslack
<noel.mcloughlin> <github.com/reszelaz/leap-systemd>

And again (log didn't come through properly, so copy-pasting from Slack):

Dominik Bessler [16:09]
yeah got sles working too

Imran Iqbal [16:09]
What did you need to do?

Dominik Bessler [16:09]
https://dhenandi.com/how-to-running-systemd-on-opensuse-docker-container/

this
+ some stuff for our internal repos

Daniel Wallace [16:10]
oh yeah, dbus.socket is important


@aboe76 After all of our opensuse fun, what do you think of this?

Evaluate the `WIP` GitHub bot

While looking at #54, came across this bot, which I'm also evaluating on my repos. I believe this would also be useful to apply to all of the SaltStack Formulas' repos. In the meantime, I've already started the request for it to be applied to this template-formula.

[BUG] Debian Docker image should have dbus installed

Your setup

Formula commit hash / release tag

Versions reports (master & minion)

Pillar / config used


Bug details

Describe the bug

If dbus is missing Inspec tests fail with error (I had to dig in Inspec and add some debug logs to find it) :

nicolas@laptop:~/PROJECTS/saltstack$ bin/kitchen verify default-debian-9-2019-2-py3
-----> Starting Test Kitchen (v2.5.3)
-----> Verifying <default-debian-9-2019-2-py3>...
       Loaded tests from {:path=>".home.nicolas.PROJECTS.saltstack.test.integration.default"} 
#<Inspec::Resources::Systemd:0x00007f00e8289cc8 @service_ctl="systemctl", @inspec=Inspec::Backend::Class @transport=Train::Transports::SSH::Connection>
#<Inspec::Resources::Systemd:0x00007f00e8289cc8 @service_ctl="systemctl", @inspec=Inspec::Backend::Class @transport=Train::Transports::SSH::Connection>
#<#<Class:0x00007f00e822dea0>:0x00007f00e85fbca8 @resource_skipped=false, @resource_failed=false, @supports=[{:platform=>"unix"}, {:platform=>"windows"}], @resource_exception_message=nil, @__backend_runner__=Inspec::Backend::Class @transport=Train::Transports::SSH::Connection, @__resource_name__=:command, @command="systemctl show --no-pager --all prometheus-alertmanager">
1
Failed to connect to bus: No such file or directory

Edit: it fails on Debian 9 and Debian 10

Steps to reproduce the bug

Expected behaviour

Attempts to fix the bug

Additional context

Add link to official documentation in default pillar

It could be nice to add a pillar key with the link to the official documentation so it could be retrieved within Salt to generate documentation.

Like:

---
rkhunter:
  doc_link: http://rkhunter.sourceforge.net/

Of course it should not be used in the configuration itself, but it could be added in TOFS templates.

Remove tags when doing the bin/convert-formula.sh

Is your feature request related to a problem?

When I clone the template-formula to a new one and run the bin/convert-formula.sh I have the tags related to template-formula locally.

Describe the solution you'd like

I clean the tags with the following command:

git tag -l | xargs git tag -d

Describe alternatives you've considered

Additional context

Add extension `.sls` or `.yml` to `pillar.example`

Suggested by @getSurreal on our Slack/IRC/Matrix room from here:

22:47onslack
@myii With all the changes going on in template-formula, has anyone discussed renaming pillare.example to something like pillare_example.sls or .yml or something that will be recognized in an IDE?
22:48myii[m]
No-one has discussed that.
22:49myii[m]
Usually, you can set your IDE to recognise the file type.
22:53onslack
Of course that's true, just seems like an unnecessary workaround
22:58onslack
never even considered it :P_if_ you decide that it's worth, then I'd vote for pillar.example.yaml?
23:17onslack
@getSurreal Having thought about it, I think you're absolutely right. Why should anyone have to make any changes from their end? It should work out of the box.
23:17onslack
@javierbertoli Since all of the pillars end up as .sls files, shouldn't that be pillar.example.sls?
23:18onslack
@getSurreal Can you submit a PR or even an issue? You've got my backing and @javierbertoli's -- it's really just a matter of .yaml vs. .yml vs. .sls.
23:30onslack
@myii didn't thought about the pillars' extension, just the content of the file :-)Any extension that make sense has my vote, so I'm ok with pillar.example.sls too

WIP: Extend for upstream repos/archives/subcomponents

Adapting the template-formula to handle installation of package/archives from an upstream repository will require extra configuration data. The following is my learnings from creating a newcloudfoundry-formula from template-formula.

New configuration data is needed in defaults.yaml updates and osfamilymap-

template:
  rootuser: root              ##needed for brew cmd.runs
  tmpdir: '/tmp/template' ##might be needed
  pkg_deps:                   ##general dependencies
    - curl
    - bzip2
    - gzip
  subcomponent:                    ###subcomponent of template
    pkg:                           ###package handling
      name: template-subcomponent
      use_upstream_repo: True      ###use of pkgrepo.managed (linux) or cmd.run brew tap (MacOS)
      use_upstream_archive: False. ###alternative to repos are archives

      archive:                     ###use by template.subcomponent.archive states
        source: https://packages.template.org/stable?release=linux64-binary&version=1.0.0&source=github-rel
        extracted:
          name: /usr/local/bin     
          source: /tmp/template/cf-cli.tgz.   ### sometimes salt cannot detect archive_format from above url (tbc).
          source_hash: 343j34kj34kl43jk43jk432j43j43kj43kj43lj3j4k3jk3j4k3j443j3
          extract_perms: False                ### whatever kwargs you need go here.
          overwrite: True
          trim_output: True
          enforce_toplevel: False
        installer: False                      ### if archive is an installer then we need to do more (future)
        binary: cf                            ### if archive is a binary we need to know its name (for clean states)
    repo:                         ###use by template.subcomponent.package.repo states
        managed:                  ###whatever kwargs you need go here.
          humanname: template-subcomponent
          name: template-subcomponent
          comments:
            - installed by salt
          gpgcheck: 1

New install and clean States are needed.

- template.package
- template.package.repo
- template.archive

I am documenting my learnings in this issue to share knowledge.

Should we restructure the init file?

This came up here: saltstack-formulas/haproxy-formula#28 where the user wants to only include specific items. This seems redundant to me, and as pointed out by @puneetk it's the default used here: https://github.com/saltstack-formulas/template-formula/blob/master/template/init.sls

I should note that I HATE this structure of including other states in the init, it just seems lazy to me, and confusing for new users who are not explicitly including states. @whiteinge What's your opinion of modifying the init to remove this sort of inclusion?

Suggestion: add saltcheck tests for formula validation

Experpt from Neon release notes and docs: https://docs.saltstack.com/en/develop/topics/releases/neon.html
https://docs.saltstack.com/en/develop/ref/modules/all/salt.modules.saltcheck.html

Saltcheck provides unittest like functionality requiring only the knowledge of salt module execution and yaml. Saltcheck uses salt modules to return data, then runs an assertion against that return. This allows for testing with all the features included in salt modules. tst files are run through the salt rendering system, enabling tests to be written in yaml (or renderer of choice), and include jinja, as well as the usual grain and pillar information.

saltcheck can be used for formula tests as part of a CI pipeline and can also be run on machines in your environment as part of a QA validation step. Personally, I see a lot of benefit to including saltcheck-tests directories in upstream formulas, as it allows for instant testing capability without other dependencies and using a state-like yaml syntax which understands pillars. For example, validating that 100 users (defined in a pillar) are properly provisioned is trivial and clear in saltcheck, while writing the same in inspec would require duplication of the salt pillar data as well as needing inspec and its dependencies which might not be appropriate in a production environment.

Example file system layout:

/srv/salt/apache/
    init.sls
    config.sls
    saltcheck-tests/
        init.tst
        config.tst
        deployment_validation.tst

Tests can be run for each state by name, for all apache/saltcheck/*.tst files, or for all states assigned to the minion in top.sls. Tests may also be created with no associated state. These tests will be run through the use of saltcheck.run_state_tests, but will not be automatically run by saltcheck.run_highstate_tests.

salt '*' saltcheck.run_state_tests apache,apache.config
salt '*' saltcheck.run_state_tests apache check_all=True
salt '*' saltcheck.run_highstate_tests
salt '*' saltcheck.run_state_tests apache.deployment_validation

Verify package installed:

verify_vim:
  module_and_function: pkg.version
  args:
    - vim
  assertion: assertNotEmpty

Ensure latest package installed:

{% for package in ["apache2", "openssh"] %}
{# or another example #}
{# for package in salt['pillar.get']("packages") #}
jinja_test_{{ package }}_latest:
  module_and_function: pkg.upgrade_available
  args:
    - {{ package }}
  assertion: assertFalse
{% endfor %}

Ensure python can load boto and boto3 libraries:
common/saltcheck-tests/init.tst

boto-installed:
  module_and_function: cmd.run
  args:
    - python -c 'import pkgutil; print(1 if pkgutil.find_loader("boto") else 0)'
  assertion: assertNotEqual
  expected-return: 0

boto3-installed:
  module_and_function: cmd.run
  args:
    - python -c 'import pkgutil; print(1 if pkgutil.find_loader("boto3") else 0)'
  assertion: assertEqual
  expected-return: 1

Test that all users exist and have the expected ssh keys. Might be appropriate for the users formula, for example.
users/saltcheck-tests/init.tst

{% for usr,data in salt['pillar.get']('users').items() %}

validate_user_{{ usr }}:
  module_and_function: user.info
  assertion_section: shell
  args:
    - {{ usr }}
  assertion: assertEqual
  expected-return: /bin/bash

{%- if 'key' in data %}
check_ssh_key_{{ usr }}:
  module_and_function: ssh.check_key
  args:
    - {{ usr }}
    - {{ data.key }}
    - ssh-rsa
    - ''
    - ''
  assertion: assertEqual
  expected-return: exists
{%- endif %}

{% endfor %}

I'd envision having basic tests like pkg.version is notNull, service.status is True, and maybe a file.contains is True live in most formulas. Since salt already has the map.jina and pkg manager abstractions, these tests can easily be upstreamed allowing for everyone's use.

Change template.config to template.config.default

Instead of

  config: '/etc/template'

Can we instead have:

  config: 
    default: '/etc/template'

I want formulas to support multiple providers/implementations of a technology.
Basically I want {{ template.config[provider] }} to evaluate to correct config file name.

[FEATURE] Adopt `quoted-strings` rule from `yamllint` for selected files [ssf]

Is your feature request related to a problem?

No.

Describe the solution you'd like

Use the quoted-strings rule, only for .travis.yml and .yamllint for the time being.

I've adopted this throughout the ssf-formula, since I ran into some YAML ambiguity errors. It would make things easier if these two files are managed here as well.

Actually, the changes are pretty much complete already in the files themselves, it's just a matter of adding the rules to the .yamllint file.

Describe alternatives you've considered

N/A.

Additional context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.