Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tofs): allow TOFS for master+minion configuration #398

Merged
merged 3 commits into from
Jun 13, 2019

Conversation

myii
Copy link
Member

@myii myii commented Jan 31, 2019

  • Sourced from master config files for all major versions since 2016.11:
    • 2016.11
    • 2017.7
    • 2018.3
    • 2019.2

The current master.d/f_defaults.conf is limited to settings from 2016.11. There have been two more major releases since then and another on the way soon.

This PR starts the process of ensuring that this file works for any master since 2016.11. I've done most of the work but I'd appreciate this being reviewed, due to the importance of this configuration as well as some of the complexity in it.

Of particular importance is the new get_jinja_env_config_block macro and how it populates the two Jinja environment sections. Problems here can cause breakages in templates and state files and I've spent a lot of time ensuring this all works. It has also resulted in uncovering a bug that I've reported in a new upstream issue. I've applied the workaround for that in this PR.

If this all works well, the same can be done for the minion.d/f_defaults.conf file as well.

For ease of comparison, the four source (master config) files are:

  1. https://github.com/saltstack/salt/blob/2016.11/conf/master
  2. https://github.com/saltstack/salt/blob/2017.7/conf/master
  3. https://github.com/saltstack/salt/blob/2018.3/conf/master
  4. https://github.com/saltstack/salt/blob/2019.2/conf/master

@myii myii added the WIP Work in Progress, only merge after review label Jan 31, 2019
@aboe76
Copy link
Member

aboe76 commented Jan 31, 2019

Wow, this will take some time....

@myii
Copy link
Member Author

myii commented Jan 31, 2019

@aboe76 Tell me now if this is a bad idea!! Is this something that the formula should handle or not?

@myii
Copy link
Member Author

myii commented Jan 31, 2019

@aboe76 Another way this could be done is by having separate source master files for each major version. But that still requires the time to check each setting and the complexity of the Jinja environment parameters cannot be avoided (that I've attempted with the macro get_jinja_env_config_block). I can't see any advantage to doing this separation.

What it really boils down to is whether this should be supported by this formula or not. If not, we will have to reconsider removing the current f_defaults.conf files, since these could end up causing big problems with the latest installations of Salt.


Update: Retract this proposal due to the findings in my comment below.

@getSurreal
Copy link

getSurreal commented Jan 31, 2019

Would having a template for each major release vs one template with a bunch of if statements be easier to maintain long term?

@myii
Copy link
Member Author

myii commented Jan 31, 2019

@getSurreal Thanks for the feedback. That's what I've mentioned in the comment just above yours. Personally, I'm not so sure the if statements really bring much of the complexity. Testing the macros and settings being applied is where it really gets difficult (even worse if across multiple files). And then having to separate this in the pillar seems even more complex. Not to mention making modifications across multiple master config files when there are fixes/improvements required (for the common bits, which is most of the file).

@myii
Copy link
Member Author

myii commented Feb 1, 2019

@aboe76 @getSurreal Actually, I've looked into this and I'm convinced that using multiple files would be far worse to maintain.

Only 4 releases need to covered by the file at any one time

https://s.saltstack.com/product-support-lifecycle/:

Salt Open releases Phase 1 support ends Phase 2 support ends Phase 3 support ends Extended life support ends
Salt Open 2018.3 Oct 31, 2018 Apr 30, 2019 Oct 31, 2019 Oct 31, 2020
Salt Open 2017.7 Jan 31, 2018 Jun 30, 2018 Dec 31, 2018 Dec 31, 2019
Salt Open 2016.11 May 31, 2017 Nov. 30, 2017 May 31, 2018 May 31, 2019
  • Roughly 8 months between releases.
  • No more than 32 months until extended life support ends.
  • 32 / 8 = 4 active major versions at one time.

To assist with this process of maintenance, I propose using the same method as the main docs as a comment for each if block, such as:

  • versionadded: 2017.7
  • versionchanged: 2017.7
  • deprecated: 2018.3

That will make it much easier to clear blocks once a major version is no longer supported (without having to check each if block to work out if it needs to be removed or not).

Git similarity between versions is always > 90%

Tested using the similarity algorithm used by git for detecting file renames:

 1 file changed, 91 insertions(+), 33 deletions(-)
 rename 2016.11 => 2017.7 (92%)

 1 file changed, 85 insertions(+), 22 deletions(-)
 rename 2017.7 => 2018.3 (93%)

 1 file changed, 14 insertions(+), 6 deletions(-)
 rename 2018.3 => 2019.2 (99%)
  • With such a high similarity index, the duplication across 4 active files will be far more difficult to maintain than a single file.

@getSurreal
Copy link

@myii You make a good case for a single file and I like matching it to the actual salt release cycle.

@myii
Copy link
Member Author

myii commented Feb 1, 2019

@getSurreal Thanks again for your time and feedback.

@myii
Copy link
Member Author

myii commented Feb 1, 2019

To assist with this process of maintenance, I propose using the same method as the main docs as a comment for each if block, such as:

  • versionadded: 2017.7
  • versionchanged: 2017.7
  • deprecated: 2018.3

I've just pushed another commit to show these comments added in after each {%- if major_svi ... %} and its respective {%- else %} where applicable.

@aboe76
Copy link
Member

aboe76 commented Feb 1, 2019

What about a radical change, instead of mimicking /etc/salt/minion and /etc/salt/master everytime, only parse / serialize the changes from pillar data into the f_defaults.conf

because the f_defaults.conf file is specially there so the package system of the OS can update the files in /etc/salt/master and /etc/salt/minion and gain new features variables commented for the version. f_defaults.conf should only override those values.

Downside to that aproach is we don't have any documentation on what features could be set....

@myii
Copy link
Member Author

myii commented Feb 1, 2019

@aboe76 above:

What about a radical change, instead of mimicking /etc/salt/minion and /etc/salt/master everytime, only parse / serialize the changes from pillar data into the f_defaults.conf

So if I understand you correctly:

  • This will get rid off:
    • The need to check for saltversioninfo like I'm doing in this PR.
    • All of the commented default values.
    • All of the commented documentation.
  • What will still remain:
    • All of the macros.
    • All of the logic.

because the f_defaults.conf file is specially there so the package system of the OS can update the files in /etc/salt/master and /etc/salt/minion and gain new features variables commented for the version. f_defaults.conf should only override those values.

That makes sense and saves unnecessary duplication of commented values from the /etc/salt/master and /etc/salt/minion files.

Downside to that aproach is we don't have any documentation on what features could be set....

What documentation are you referring to here? The documentation that is kept in f_defaults.conf?


While we're here throwing curveballs, I've got another idea to add to the discussion.

Make use of a new svimap.yaml

Globbing works since 2016.11 so this PR (up to now) could be replaced by an alternative method built upon a structure like this:

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

2016.11.*:
  master_f_defaults:
    salt_event_pub_hwm: '20000'
    event_publisher_pub_hwm: '10000'
    external_nodes: 'None'
    renderer: 'yaml_jinja'
    jinja_trim_blocks: 'False'
    jinja_lstrip_blocks: 'False'
2017.7.*:
  master_f_defaults:
    keep_acl_in_token: 'False'
    eauth_acl_module: 'django'
    renderer: 'yaml_jinja'
    jinja_trim_blocks: 'False'
    jinja_lstrip_blocks: 'False'
    gitfs_refspecs:
      - '+refs/heads/*:refs/remotes/origin/*'
      - '+refs/tags/*:refs/tags/*'
2018.3.*:
  master_f_defaults:
    batch_safe_limit: 100
    batch_safe_size: 8
    master_stats: 'False'
    master_stats_event_iter: 60
    key_pass: 'sdb://masterkeyring/key_pass'
    master_sign_pubkey: 'True'
    signing_key_pass: 'sdb://masterkeyring/signing_pass'
    autosign_grains_dir: '/etc/salt/autosign_grains'
    keep_acl_in_token: 'False'
    eauth_acl_module: 'django'
    roster: 'flat'
    ssh_update_roster: 'False'
    utils_dirs: '[]'
    renderer: 'yaml_jinja'
    jinja_env:
      block_start_string: '{{ "{%" }}'
      block_end_string: '{{ "%}" }}'
      variable_start_string: '{{ "{{" }}'
      variable_end_string: '{{ "}}" }}'
      comment_start_string: '{{ "{#" }}'
      comment_end_string: '{{ "#}" }}'
      line_statement_prefix:
      line_comment_prefix:
      trim_blocks: False
      lstrip_blocks: False
      # Using double-quotes until https://github.com/saltstack/salt/issues/51447 resolved
      newline_sequence: '"\n"'
      keep_trailing_newline: False
    jinja_sls_env:
      block_start_string: '{{ "{%" }}'
      block_end_string: '{{ "%}" }}'
      variable_start_string: '{{ "{{" }}'
      variable_end_string: '{{ "}}" }}'
      comment_start_string: '{{ "{#" }}'
      comment_end_string: '{{ "#}" }}'
      line_statement_prefix:
      line_comment_prefix:
      trim_blocks: False
      lstrip_blocks: False
      # Using double-quotes until https://github.com/saltstack/salt/issues/51447 resolved
      newline_sequence: '"\n"'
      keep_trailing_newline: False
    gitfs_refspecs:
      - '+refs/heads/*:refs/remotes/origin/*'
      - '+refs/tags/*:refs/tags/*'
2019.2.*:
  master_f_defaults:
    ipc_mode: 'ipc'
    tcp_master_pub_port: 4510
    tcp_master_pull_port: 4511
    batch_safe_limit: 100
    batch_safe_size: 8
    master_stats: 'False'
    master_stats_event_iter: 60
    key_pass: 'sdb://masterkeyring/key_pass'
    master_sign_pubkey: 'True'
    signing_key_pass: 'sdb://masterkeyring/signing_pass'
    autosign_grains_dir: '/etc/salt/autosign_grains'
    keep_acl_in_token: 'False'
    eauth_acl_module: 'django'
    roster: 'flat'
    ssh_update_roster: 'False'
    utils_dirs: '[]'
    renderer: 'jinja|yaml'
    jinja_env:
      block_start_string: '{{ "{%" }}'
      block_end_string: '{{ "%}" }}'
      variable_start_string: '{{ "{{" }}'
      variable_end_string: '{{ "}}" }}'
      comment_start_string: '{{ "{#" }}'
      comment_end_string: '{{ "#}" }}'
      line_statement_prefix:
      line_comment_prefix:
      trim_blocks: False
      lstrip_blocks: False
      # Using double-quotes until https://github.com/saltstack/salt/issues/51447 resolved
      newline_sequence: '"\n"'
      keep_trailing_newline: False
    jinja_sls_env:
      block_start_string: '{{ "{%" }}'
      block_end_string: '{{ "%}" }}'
      variable_start_string: '{{ "{{" }}'
      variable_end_string: '{{ "}}" }}'
      comment_start_string: '{{ "{#" }}'
      comment_end_string: '{{ "#}" }}'
      line_statement_prefix:
      line_comment_prefix:
      trim_blocks: False
      lstrip_blocks: False
      # Using double-quotes until https://github.com/saltstack/salt/issues/51447 resolved
      newline_sequence: '"\n"'
      keep_trailing_newline: False
    gitfs_refspecs:
      - '+refs/heads/*:refs/remotes/origin/*'
      - '+refs/tags/*:refs/tags/*'

That shows all of the changes I have done so far. Imagine all of the common config settings are represented in defaults.yaml. The above can then be merged on top of the common defaults in the usual manner in map.jinja:

{% import_yaml "salt/svimap.yaml" as svimap %}

{# merge the svimap #}
{% set svi = salt['grains.filter_by'](svimap, grain='saltversion') or {} %}
{% do salt['defaults.merge'](defaults['salt'], svi) %}

The map will then contain all of the config settings specific to the version of Salt. With some clever use of the pillar, preparing a limited f_defaults.conf could be achieved, only containing the settings differing from the default values.

@aboe76
Copy link
Member

aboe76 commented Feb 1, 2019

@myii why do you want to keep the deafults per salt-version, they are already programmed inside salt.
the only thing needed to configure it to your liking is to add overriding key in ```f_defaults.conf````

@myii
Copy link
Member Author

myii commented Feb 1, 2019

@aboe76 There are a number of reasons. Listing them in no particular order:

  1. For refactoring and reverting QA:
    1. When refactoring, it's important to ensure that the results before and after are identical -- can't do that without keeping track of the default settings somewhere.
    2. If this major change doesn't work well, we may need to revert back to the current method of using f_defaults.conf -- that will require the default settings; and then we have to choose between the ugly Jinja from this PR or to use these maps to provide the defaults instead.
  2. Limit the settings from the pillar into f_defaults.conf:
    1. Limit to those that work for the specific Salt version on each master and minion -- this can be achieved by comparing if the pillar value is actually in the map for the specific version of Salt.
    2. Limit further to only use those which actually differ from the default settings in the first place -- this can be achieved by direct comparison between the defaults and the pillar values.
  3. Use as documentation of all of the possible settings as well as how to actually set them:
    1. defaults.yaml and svimap.yaml contain all of the possible settings as well as the format they need to be provided in the pillar (e.g. look at the difficulty of providing the jinja_env and jinja_sls_env settings without a previous example).
    2. Can do this instead of flooding pillar.example with numerous examples across all of the possible settings.
  4. Every single setting requires some logic or even relies on a macro:
    1. This method will help to trim out unnecessary content as versions become unsupported.
    2. Ultimately, splitting out all of the logic/macros from the monolithic f_defaults.conf files would help with maintenance -- and this method would make that much easier.

Reading the above is very dense because I'm summarising each point to avoid writing an essay. I'm happy to explain if further clarification is needed.

@myii
Copy link
Member Author

myii commented Feb 2, 2019

@aboe76 Let me approach this from the other direction. As you said, the right idea is to only use the values from the pillar to populate f_defaults.conf. However, we need to be able to support any of the available settings. So in terms of the f_defaults.conf template, what really changes? It still needs to be able to handle every available setting and convert them to the right format/layout within the file. So all of the logic and macros can't be removed.

@aboe76
Copy link
Member

aboe76 commented Feb 2, 2019

@myii the salt understanding of its configuration can be default yaml or json structured, so if we can make the pillar yaml input and output the same then there is no need for jinja manipulation.
However the way salt ingests pillar data we need to serialize it back to yaml. instead of mere passthrough.

Downside to this approach is:

  • the output ordering isn't the same.
  • the readability and comments are lost.

@myii
Copy link
Member Author

myii commented Feb 2, 2019

the salt understanding of its configuration can be default yaml or json structured, so if we can make the pillar yaml input and output the same then there is no need for jinja manipulation.

Now this sounds very interesting if it can be achieved.

However the way salt ingests pillar data we need to serialize it back to yaml. instead of mere passthrough.

Is there any risk of the yaml coming out differently at the other end due to this process?

Downside to this approach is:

  • the output ordering isn't the same.
  • the readability and comments are lost.

If the output matches the pillar, then that can be relied on instead. Ultimately, it's an output file controlled by Salt. The actual master and minion files are still available for the documentation.

@myii
Copy link
Member Author

myii commented Feb 2, 2019

@aboe76 If we do follow through with this method, will have to carefully consider what to do about these available settings:

# This state will remove "/etc/salt/minion" when you set this to true.
minion_remove_config: True
# This state will remove "/etc/salt/master" when you set this to true.
master_remove_config: True

@myii
Copy link
Member Author

myii commented Feb 2, 2019

# This state will remove "/etc/salt/minion" when you set this to true.
minion_remove_config: True
# This state will remove "/etc/salt/master" when you set this to true.
master_remove_config: True

@aboe76 Just realised, we don't just have to worry about these pillar values... rather, there may be installations out there that have used these values and no longer have the default master and minion configuration files. So then these files aren't present to refer back to for all of the available settings and comments.

@aboe76
Copy link
Member

aboe76 commented Feb 3, 2019

@myii for those setups that have removed the files there is also docs.saltstack....

@myii
Copy link
Member Author

myii commented Feb 5, 2019

@aboe76 After some testing, I'm definite that this idea is not achievable without serious consequences to existing setups. The following diff is based on using pillar.example. To prepare it, I've had to merge the output from different files, as mentioned in the notes after the diff:

--- Current implementation
+++ YAML-only proposal
@@ -1,4 +1,4 @@
-auth.ldap.filter: "uid={{ username }}"
+auth.ldap.filter: uid={{ username }}
 engines:
   - slack:
       aliases:
@@ -16,47 +16,6 @@
 file_roots:
   base:
     - /srv/salt
-      - [Numerous file_roots sourced from other parts of the pillar, e.g. formulas]
-      - ...
-      - ...
-      - ...
-      - ...
-      - ...
-  [Second env]:
-      - [Numerous file_roots sourced from other parts of the pillar, e.g. formulas]
-      - ...
-      - ...
-      - ...
-      - ...
-      - ...
-  [Third env]:
-      - [Numerous file_roots sourced from other parts of the pillar, e.g. formulas]
-      - ...
-      - ...
-      - ...
-      - ...
-      - ...
 fileserver_backend:
   - git
   - s3fs
@@ -83,16 +42,20 @@
 pillar_roots:
   base:
     - /srv/pillar
-reactor:
-  - 'master/deploy':
+reactors:
+  - master/deploy:
     - /srv/salt/reactors/deploy.sls
 rest_tornado:
-  debug: False
-  disable_ssl: False
+  debug: false
+  disable_ssl: false
   port: 8000
   ssl_crt: /etc/pki/api/certs/server.crt
   ssl_key: /etc/pki/api/certs/server.key
-s3.buckets: ["bucket1", "bucket2", "bucket3", "bucket4"]
-s3.key: "askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs"
-s3.keyid: "GKTADJGHEIQSXMKKRBJ08H"
-winrepo_provider: "gitpython"
+s3.buckets:
+  - bucket1
+  - bucket2
+  - bucket3
+  - bucket4
+s3.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
+s3.keyid: GKTADJGHEIQSXMKKRBJ08H
+winrepo_provider: gitpython
  1. The existing system involves more than managing only f_defaults.conf; this pillar also results in managing:
    1. engine.conf
    2. lxc_profiles.conf
    3. reactor.conf
  2. Use of single and double quotation marks:
    1. Not maintained in the straight YAML rendering -- specifically set in the templates.
    2. Maybe not in the diff above but some of these are significant and will not work without the quotes.
  3. file_roots and many other settings sources from more than just the salt:master pillar.
    1. All of that logic would have to be reproduced.
  4. reactors => reactor modified by the template.
    1. All of these would have to be reproduced.

Who knows what will happen with all of the other possible settings?


Basically, testing a massive change like this would take even more effort than the changes proposed in this PR (which are bad enough). I see two ways forward for working with the 4 supported versions of Salt at any given time:

  1. Continue with the method in this PR, i.e. using Jinja-based conditionals.
  2. Use the svimap.yaml idea, as mentioned in the comment above.

Update: Reversed the diff direction for clarity.

@aboe76
Copy link
Member

aboe76 commented Feb 5, 2019

@myii 4 supported versions?

I thought only three?

Salt Open 2018.3 | Oct 31, 2018 | Apr 30, 2019 | Oct 31, 2019 | Oct 31, 2020
Salt Open 2017.7 | Jan 31, 2018 | Jun 30, 2018 | Dec 31, 2018 | Dec 31, 2019
Salt Open 2016.11 | May 31, 2017 | Nov. 30, 2017 | May 31, 2018 | May 31, 2019

see https://s.saltstack.com/product-support-lifecycle/

But then again Is it necessary to support the same versions as saltstack enterprise support?
I would think that is a massive undertaking....

@aboe76
Copy link
Member

aboe76 commented Feb 5, 2019

@myii you are right about the other files, I haven't considered those.
your setup about svimap.yaml looks doable.

@myii
Copy link
Member Author

myii commented Feb 5, 2019

@aboe76 According to the current schedule, there will only be 4 active, supported versions at the same time. Discontinued versions can be stripped out. Guessing the dates for the upcoming version 2019.2:

Salt Open releases Phase 1 support ends Phase 2 support ends Phase 3 support ends Extended life support ends
Salt Open 2019.2 Sep 30, 2021
Salt Open 2018.3 Oct 31, 2018 Apr 30, 2019 Oct 31, 2019 Oct 31, 2020
Salt Open 2017.7 Jan 31, 2018 Jun 30, 2018 Dec 31, 2018 Dec 31, 2019
Salt Open 2016.11 May 31, 2017 Nov. 30, 2017 May 31, 2018 May 31, 2019

By the time the next version comes out, 2016.11 will no longer be supported. And so on.

In terms of complexity, not really. Quoting from above again:

 1 file changed, 91 insertions(+), 33 deletions(-)
 rename 2016.11 => 2017.7 (92%)

 1 file changed, 85 insertions(+), 22 deletions(-)
 rename 2017.7 => 2018.3 (93%)

 1 file changed, 14 insertions(+), 6 deletions(-)
 rename 2018.3 => 2019.2 (99%)

The files change very little per version. The work I've done for this PR is mostly done. The only reason it was so complex was due to the new features around jinja_env & jinja_sls_env. But regular changes are easy to accommodate.

@aboe76
Copy link
Member

aboe76 commented Feb 5, 2019

@myii if it is possible we could cut out the macros and put them in a macros.jinja file and import that
this will make the f_defaults.conf a bit less daunting.

@myii
Copy link
Member Author

myii commented Feb 5, 2019

@aboe76 OK, I will look further into using svimap.yaml. And I will look at the macros as well, to see what can be done to simplify the file(s).

Thanks for all of your feedback.

@aboe76
Copy link
Member

aboe76 commented Jun 6, 2019

@myii yes I'm happy with this method and a good solution.

@myii myii changed the title WIP: Update master f_defaults.conf based on major releases of Salt feat(tofs): allow TOFS for master+minion configuration Jun 7, 2019
@myii
Copy link
Member Author

myii commented Jun 7, 2019

@aboe76 @vutny OK, I've finalised this particular PR so that the minion configuration can be provided via. TOFS (opt-in, mirroring same method for the master configuration). If all is OK, I'd appreciate if this can be merged, so that the next steps can commence. I'll start a new issue with a checklist based upon the one below (note, transferred to #417, this remains quoted here for reference):

  • README: Update to explain how TOFS can be used instead of pillar for master/minion co
    nfiguration.
  • salt.cloud: (After due consideration) Use the same method to allow TOFS to be used for these configurations: cloud.maps.d, cloud.profiles.d & cloud.providers.d.
  • Deprecation step 1: Display deprecation warning when configuration is being done by pillar.
  • Deprecation step 2: Make TOFS the default, making pillar-based opt-in.
  • Deprecation step 3: Remove pillar-based method, with breaking change commit.
  • Alongside deprecation (at some point): Remove code to clean up old _defaults.conf file if they have it around -- all .conf files must be permitted, should a user choose to use that filename.

In terms of the unrelated centos-7 failure, we can by-pass this manually until it is fixed (via. a separate PR).


Update: centos-7 is now passing https://travis-ci.com/saltstack-formulas/salt-formula/jobs/206207046. I've already removed WIP so all status lights are green, ready for merging.

Copy link
Member

@noelmcloughlin noelmcloughlin left a comment

Choose a reason for hiding this comment

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

Nice work @myii and thanks to all the reviewers

@myii myii removed the WIP Work in Progress, only merge after review label Jun 7, 2019
@myii
Copy link
Member Author

myii commented Jun 7, 2019

Thanks for the review, @noelmcloughlin.

@myii
Copy link
Member Author

myii commented Jun 11, 2019

@vutny Are you satisfied with this implementation? Can we proceed with the merge?

Copy link
Contributor

@vutny vutny left a comment

Choose a reason for hiding this comment

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

Looks great, good to go @myii

@myii
Copy link
Member Author

myii commented Jun 12, 2019

@vutny Thanks, do you mind merging?

@vutny
Copy link
Contributor

vutny commented Jun 12, 2019

@myii Wanna me to do that?

@myii
Copy link
Member Author

myii commented Jun 12, 2019

@vutny I could always do it myself but I prefer to let others do it when it's a PR authored by me! If it was a minor change, I would have merged it myself.

@vutny
Copy link
Contributor

vutny commented Jun 12, 2019

Okay, let's wait a day if there would be no objections, I'll merge it.

@myii
Copy link
Member Author

myii commented Jun 12, 2019

@vutny I don't think there's anyone left to put up an objection, this PR has been around since the end of January! But I'm absolutely fine with that, it's not like I'm going to be doing the next stage very soon anyway.

@aboe76
Copy link
Member

aboe76 commented Jun 12, 2019 via email

@vutny vutny merged commit 05b71ab into saltstack-formulas:master Jun 13, 2019
@myii myii deleted the PR_master-f_defaults branch June 13, 2019 08:49
@myii
Copy link
Member Author

myii commented Jun 13, 2019

Thanks to all involved for your input along the way.

@saltstack-formulas-travis

🎉 This PR is included in version 0.58.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Successfully merging this pull request may close these issues.

6 participants