sous-chefs/logrotate

logrotate_global doesn't write paths options to template

rolffujino opened this issue · 4 comments

Brief Description

When using the logrotate_global resource's paths parameter, options are not written to the logrotate template file.

Cookbook version

3.0.0

Chef-Infra Version

15.8.23

Platform details

CentOS 7

Steps To Reproduce

Run a recipe in Kitchen using this resource:

logrotate_global 'logrotate' do
  options %w(create weekly dateext)
  parameters(
    'rotate' => 4
  )
  paths(
    '/var/log/wtmp' => {
      'missingok' => true,
      'monthly' => true,
      'create' => '0664 root utmp',
      'rotate' => 1,
    },
    '/var/log/btmp' => {
      'missingok' => true,
      'monthly' => true,
      'create' => '0600 root utmp',
      'rotate' => 1,
    }
  )
end

Expected behavior

A file with the following contents should be generated:

[vagrant@default-centos-7 ~]$ cat /etc/logrotate.conf 
#
# Generated by Chef for default-centos-7.vagrantup.com
# Do NOT modify this file by hand, changes will be overwritten.
#

# Options
compress
dateext
weekly

# Parameters
rotate 4
create

# Includes
include /etc/logrotate.d

# Paths
/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

Unfortunately 'missingok' and 'monthly' are missing from the 2 Paths.

I believe this might be caused by 'options_from' being initially created for an array of strings and does work properly for a hash.

This will provide some additional info:

           Resource Declaration:
           ---------------------
           # In /tmp/kitchen/cache/cookbooks/citd_logrotate/recipes/default.rb
           
             9: logrotate_global 'logrotate' do
            10:   options %w(weekly dateext compress)
            11:   template_name 'log.erb'
            12:   parameters(
            13:     'rotate' => 4,
            14:     'create' => nil
            15:   )
            16:   paths(
            17:     '/var/log/wtmp' => {
            18:       'missingok' => true,
            19:       'monthly' => true,
            20:       'create' => '0664 root utmp',
            21:       'rotate' => 1,
            22:     },
            23:     '/var/log/btmp' => {
            24:       'missingok' => true,
            25:       'monthly' => true,
            26:       'create' => '0600 root utmp',
            27:       'rotate' => 1,
            28:     }
            29:   )
            30: end
           
           Compiled Resource:
           ------------------
           # Declared in /tmp/kitchen/cache/cookbooks/citd_logrotate/recipes/default.rb:9:in `from_file'
           
           logrotate_global("logrotate") do
             action [:create]
             default_guard_interpreter :default
             declared_type :logrotate_global
             cookbook_name "citd_logrotate"
             recipe_name "default"
             options ["compress", "dateext", "weekly"]
             template_name "log.erb"
             parameters {"rotate"=>4, "create"=>nil}
             paths {"/var/log/wtmp"=>{"parameters"=>{"create"=>"0664 root utmp", "rotate"=>1}, "options"=>[], "scripts"=>{}}, "/var/log/btmp"=>{"parameters"=>{"create"=>"0600 root utmp", "rotate"=>1}, "options"=>[], "scripts"=>{}}}
             scripts {}
           end
           
           System Info:
           ------------
           chef_version=15.8.23
           platform=centos
           platform_version=7.7.1908
           ruby=ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
           program_name=/opt/chef/bin/chef-client
           executable=/opt/chef/bin/chef-client

It isn't parsing the paths options properly and they are left empty.

It is caused by the .sort in from_paths, which is converting the hash into an array of string arrays:
[["create", "0600 root utmp"], ["missingok", true], ["monthly", true], ["rotate", 1]]
Which causes the .include? to fail its test.

If you remove the .sort it will return the expected hashes:

{"missingok"=>true, "monthly"=>true}
{"missingok"=>true, "monthly"=>true}

You should then probably also update the template from:

<% config['options'].each do |opt, _|-%>
<%= opt %>
<% end -%>