Illegal rabbitmq cluster nodes with Puppet - ruby

I rely on Librarian-puppet to install rabbitmq in a vagrant box.
Puppet version is 3.4.0
My Puppetfile contains
forge "http://forge.puppetlabs.com"
[...]
mod 'rabbitmq', :git => 'git://github.com/puppetlabs/puppetlabs-rabbitmq'
By following the documentation, I intend to install RabbitMQ server with the next instruction:
class { '::rabbitmq':
service_manage => false,
port => '5672',
delete_guest_user => true,
}
By doing so, I've encountered the following error message:
Error: Illegal name. The given name _cluster_nodes does not conform to the naming rule
\A((::)?[a-z0-9]w*)(::[a-z0-9]w*)*\z at
/etc/puppet/modules/rabbitmq/manifests/config.pp:45:5
Error: Illegal name. The given name _cluster_nodes does not conform to the naming rule
\A((::)?[a-z0-9]w*)(::[a-z0-9]w*)*\z at
/etc/puppet/modules/rabbitmq/manifests/config.pp:47:5
The actual config.pp file contains the next code block:
# Handle deprecated option.
if $cluster_disk_nodes != [] {
notify { 'cluster_disk_nodes':
message => 'WARNING: The cluster_disk_nodes is deprecated.
Use cluster_nodes instead.',
}
$_cluster_nodes = $cluster_disk_nodes # line 45
} else {
$_cluster_nodes = $cluster_nodes # line 47
}
Could anyone provide me with a valid instance of cluster node name?
The regular expression apparently used for validation looks a bit cryptic to me.
I'm also wondering how the _cluster_nodes values are validated... Where does the regular expression used for validation comes from?

This issue was not about the value of variables ($cluster_nodes or $cluster_disk_nodes) and it was rather the variables names which were incorrect. A variable name shall not start with '_' anymore (as expressed by the regular expression and the actual error message). I just got lost in translation.
I've opened an issue on github and I've sent a PR, which attempts to fix it:
https://github.com/puppetlabs/puppetlabs-rabbitmq/issues/163
https://github.com/puppetlabs/puppetlabs-rabbitmq/pull/164
To follow up with this issue, it was equally fixed by another PR, which got actually merged:
https://github.com/puppetlabs/puppetlabs-rabbitmq/pull/160

Related

Puppet not handling squared brackets in the source attribute for file resource

I am still facing this issue, when trying to copy git installation files by copying a folder and making it recursive. There is a file called [.exe and it is failing with:
Error: /Stage[main]/Tcagents/File[Copy Team City agent tools]: Failed to generate additional resources using 'eval_generate': Parameter source failed on File[D:/TeamCityTools/git-2.5.0/usr/bin/[.exe]: Could not understand source puppet:///tools/TeamCityTools/git-2.5.0/usr/bin/[.exe: bad URI(is not URI?): puppet:///tools/TeamCityTools/git-2.5.0/usr/bin/[.exe`
While reading other requests, I saw that is is due to the URI library Puppet uses for validating the path. I also found the same issue in https://tickets.puppetlabs.com/browse/PUP-3135 but it is accepted without a solution.
I wonder if there is a workaround you recommend or a fix for this. Using Puppet 4.4.2.
Resource is:
file{'Copy Team City agent tools':
ensure => directory,
path => $tc_tools_path,
source => 'puppet:///tools/TeamCityTools',
recurse => true,
}
Puppet has not still resolved this (https://tickets.puppetlabs.com/browse/PUP-3135).

Get hiera value in puppet manifest with nested keys

I'm new to using hiera with puppet (and somewhat new to puppet).
I've written this bit of yaml:
---
web_mysql_server:
mysql_database: "my_production"
and then I try to use it in a puppet manifest thus:
database => hiera('web_mysql_server::mysql_database'),
And this does not work, generating the error
Error: Could not find data item web_mysql_server::mysql_database
in any Hiera data file and no default supplied at
/vagrant/puppet/modules/web_mysql_server/manifests/init.pp:33
on node railstest.vm
(where I've added some '\n''s for readability here).
I suspect (hope!) this is a simple syntax error that I'm not getting. Anyone see what I'm doing wrong?
Based in hiera documentation, the proper syntax for accessing nested keys is
hiera('web_mysql_server.mysql_database')
This syntax for qualified keys has not been around always, the documentation says it's from Hiera 2.0.
I know we use puppet 3.8.3 and qualified keys are not supported yet in our setup. We work around this limitation with this approach:
$mysql_configuration = hiera('web_mysql_server')
# ...
database => $mysql_configuration['mysql_database']

Puppet: generate statement fails when trying to retrieve default path of an executable

I have built a stanza to remove a ruby gem package from our servers. The problem is that the ruby gem executable is installed in different paths on the servers, so on one server it could be in /opt/ruby/bin/gem on other servers it's in /usr/local/rvm/rubies/ruby-2.0.0-p353/bin/gem
My stanza uses the generate function in puppet to pull out the default ruby gem installation as follows:
$ruby_gem_location = generate('which', 'gem')
exec { "remove-remote_syslog":
command => "gem uninstall remote_syslog",
path => "$ruby_gem_location:/opt/ruby/bin:/usr/bin:/usr/sbin",
onlyif => "$ruby_gem_location list|grep remote_syslog"
}
When I run puppet agent I get the following error:
Generators must be fully qualified at ****redacted*
I have also tried to provide a default path for the which command as follows:
$ruby_gem_location = generate('/usr/bin/which', 'gem')
and now the error says : Could not evaluate: Could not find command '/usr/bin/gem
I checked the target server and the gem command is in
/usr/local/rvm/rubies/ruby-2.0.0-p353/bin/gem
What am I doing wrong?
How can I pull out the default ruby gem location on our servers?
Thank you in advance
Your code
$ruby_gem_location = generate('/usr/bin/which', 'gem')
will generate a full path to your gem command (if it succeeds). From the result you describe, I think it is generating '/usr/bin/gem', which is perhaps a symlink to the real gem command. You are putting that into your command path instead of just the directory part, and that will not be helpful. It is not, however, the source of the error message you report.
The real problem here is that generate(), like all DSL fucntions, runs during catalog building. I infer from your results that you are using a master / agent setup, so generate() is giving you a full path to gem -- evidently /usr/bin/gem -- on the master. Since the whole point is that different servers have gem installed in different places, this is unhelpful. The actual error message arises from an attempt to execute your onlyif command with the wrong path to gem.
Your best way forward is probably to create a custom fact with which each node can report the appropriate location of the gem binary. You can then use that fact's value in your Exec, maybe:
exec { "remove-remote_syslog":
command => "$::ruby_gem_path uninstall remote_syslog",
onlyif => "$::ruby_gem_path list | grep remote_syslog"
}
Note that you don't need a path attribute if you give a complete path to the executable in the first place.
Details on creating the $::ruby_gem_path custom fact depend on a number of factors, and in their full generality they are rather too broad for SO, but PL provides good documentation.

Ohai thinks my plugin is version 6. Why?

I'm trying to write a plugin for ohai. It seems like a pretty straightforward task:
Ohai.plugin(:Uname) do
provides 'uname'
depends 'kernel'
collect_data do
uname Mash.new
uname[:message] = `uname -a`
end
end
To me this looks like the online examples provided by Opscode, O'Reilly and others. But here's what happens when I try to test it:
% irb -rohai
irb(main):001:0> Ohai::Config[:plugin_path] << "."
=> ["/home/ll0359/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/ohai-8.3.0/lib/ohai/plugins", "."]
irb(main):002:0> o = Ohai::System.new
=> #<Ohai::System:0x007fed82e43078 #plugin_path="", #data={}, #provides_map=#<Ohai::ProvidesMap:0x007fed82e42fd8 #map={}>, #v6_dependency_solver={}, #d82e42f38 #controller=#<Ohai::System:0x007fed82e43078 ...>, #v6_plugin_classes=[], #v7_plugin_classes=[]>, #runner=#<Ohai::Runner:0x007fed82e42ec0 #prp:0x007fed82e42fd8 #map={}>, #safe_run=true>>
irb(main):003:0> o.all_plugins
And here's where the fun begins. I get this output, over and over and over:
[2015-05-20T03:13:09+00:00] WARN: Plugin Definition Error: <./ohai_uname.rb>: collect_data already defined on platform default
[2015-05-20T03:13:09+00:00] WARN: [DEPRECATION] Plugin at ./test_ohai.rb is a version 6 plugin. Version 6 plugins will not be supported in future releases....
your plugin to version 7 plugin syntax. For more information visit here: docs.chef.io/ohai_custom.html
(the text on my second line was clipped by my screen but you get the idea)
I've tried running this code with and without the 'depends' line. Same result.
I've tried running this code with and without the Mash line, substituing 'uname uname -a' for the assignment line. Same result.
I've tried running with and without passing ":linux" as a parameter to collect_data. The only difference is I get a warning about collect_data(:linux) already being defined instead of :default.
I've tried renaming the plugin to a random 8 character identifier just in case it was tripping over being called :Uname. Same result.
I've tried passing "uname" (capital and lower) as a parameter to o.all_plugins. Same result.
So my questions are:
Why does ohai (8.3, running under Ruby 2.2.1) think this is a version 6 plugin? I can't see anything in it that would make it look like it's not version 7.
How can I get this working?
Thanks
Note to self: Next time you do this, don't try to test from the directory your plugin is in and add "." to your plugin_path. Moving to a different directory and adding the absolute path to the plugin solved the problem.
I plan to leave this up in case someone else has this happen to them.

Chef Solo - Role Data in Ruby DSL or JSON?

I am playing with Roles with Chef Solo (11.4.4 and 11.6.0). A bit Confused.
For Chef Solo runs, should roles be written in Ruby or JSON?
As per the official docs: About Roles, Roles can be stored as domain-specific Ruby (DSL) files or JSON data.
NOTE: chef-client uses Ruby for Roles, when these files are uploaded to Chef Server, they are converted to JSON. Whenever chef-repo is refreshed, the contents of all domain-specific Ruby files are re-compiled to JSON and re-uploaded to the server.
My question is, if the requirement is to run Chef in solo mode without a server and roles are needed, should the roles be written in Ruby or JSON (we don't have a server to convert Ruby to JSON)?
My guess is the latter. Does anyone know the correct answer?
BTW: I've seen people mixing Ruby and JSON in role files...
What is the Ruby DSL equivalent for rbenv.rb below?
Example, run rbenv + ruby-build cookbooks to install rbenv on Ubuntu.
rbenv.json
{
"run_list": ["role[rbenv]"]
}
roles/rbenv.rb
name "rbenv"
description "rbenv + ruby-build"
run_list(
"recipe[rbenv]",
"recipe[ruby_build]"
)
override_attributes(
:rbenv => {
:git_repository => "https://github.com/sstephenson/rbenv.git"
},
:ruby_build => {
:git_repository => "https://github.com/sstephenson/ruby-build.git"
}
)
Chef Solo run chef-solo -c solo.rb -j rbenv.json -l debug works as expected. This is to achieve cloning via HTTPS because it easier behind the firewall.
However, using a Ruby DSL version of role rbenv.rb like below
name "rbenv"
description "rbenv + ruby-build"
run_list "recipe[rbenv]", "recipe[ruby_build]"
# default_attributes ":rbenv" => {":install_prefix" => "/opt"}
override_attributes ":rbenv" => {":git_repository" => "https://github.com/sstephenson/rbenv.git"}, ":ruby_build" => {":git_repository" => "https://github.com/sstephenson/ruby-build.git"}
It didn't seem to work because it still used the default attributes (clone via git URL instead of HTTPS).
I am new to Ruby so most likely I made some mistakes in the DSL code, please help;-)
* git[/opt/rbenv] action sync[2013-09-03T03:44:53+00:00] INFO: Processing git[/opt/rbenv] action sync (rbenv::default line 91)
[2013-09-03T03:44:53+00:00] DEBUG: git[/opt/rbenv] finding current git revision
[2013-09-03T03:44:53+00:00] DEBUG: git[/opt/rbenv] resolving remote reference
================================================================================
Error executing action `sync` on resource 'git[/opt/rbenv]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '128'
---- Begin output of git ls-remote "git://github.com/sstephenson/rbenv.git" master* ----
STDOUT:
STDERR: fatal: unable to connect to github.com:
github.com[0: 192.30.252.128]: errno=Connection timed out
---- End output of git ls-remote "git://github.com/sstephenson/rbenv.git" master* ----
Ran git ls-remote "git://github.com/sstephenson/rbenv.git" master* returned 128
I prefer to use JSON format wherever possible for one simple reason - it's easy to parse and validate with a script. Here are three things that you can do if all your Chef data is in JSON format:
Easily perform a syntax check in a git pre-commit hook, something that's much harder to do when the file is in the Ruby DSL format.
Validate the keys and values in a data bag entry. This can be useful to check that you are not going to deploy invalid or nonsensical data bag entries to production.
Compare (with a little extra work - key ordering in a dictionary needs to be taken into account) the value of an object on a server with what's in git. The --format json argument is useful here.

Resources