Dynamically choose between chef cookbook versions - ruby

I know that I can specify that version to run per host with recipe[cookbook#cookbook_version] but can I use ruby code to dynamically decide which node should run which version of the cookbook?

Related

Ansible, "cisco.ios.ios_ospf_interfaces": How can I get this plugin?

I'm running Ansible version 2.9.14 and I've already downloaded the "cisco.ios" Ansible collection. However, when I look in my directory, "ansible_collections/cisco/ios/plugins/modules" I don't seem to have a .py file for ios_ospf_interfaces. Consequently when I include a task in a playbook that references this module the task produces an error.
I tried to install the cisco.ios collection again, but my system reported it already had this collection and didn't do anything further. So how can I get this particular module on my system?
Thanks!
Existing Ansible Modules On My System
(credit for this answer goes to mdaniel)
When using the standard command, "ansible-galaxy collection install cisco.ios" it's possible that you may not receive the latest version of this collection.
In this instance, the version of the collection that was installed on my system was 1.1.0 and yet to obtain the "ios_ospf_interfaces" module I needed 1.2.0
To verify the current version of the cisco.ios module the command is:
ansible-galaxy collection install -vv cisco.ios:==1.2.0
If the output displays that you are running an earlier version of this collection, repeat the command above but add the argument, "--force" at the end to force it to update to version 1.2.0

How to use a class from a module immediately after installing it with Puppet?

I am experimenting with Puppet using Vagrant. I'm new to Puppet.
I'm installing modules in my Puppet manifest using the approach suggested at: Can I install puppet modules through puppet manifest?
My default.pp contains something like:
$dsesterojava = 'dsestero-java'
exec { 'dsestero-java':
command => "puppet module install ${dsesterojava}",
unless => "puppet module list | grep ${dsesterojava}",
path => ['/usr/bin', '/bin']
}
include java::java_7
I'm trying to import a module and then immediately use the classes defined in it.
Currently, I get:
Error: Could not find class java::java_7
If I comment out the include line and re-run it. The module installs. If I then removed the comment and run the provisioning again then it works.
There is some kind of "chicken and egg" situation here. Can I use a module in the same Puppet manifest that installs it?
How should I solve it?
No, you cannot do this. When your catalog is compiled, Puppet will search in the appropriate directories for all of the required code and data. Since the java module does not exist until catalog application, the compilation of a catalog (occurs prior to application) depending upon it will fail. You are absolutely dealing with a "chicken and egg" situation here. I highly recommend against using Puppet code to install Puppet code.
Alternatively, the recommended approach to install and manage your Puppet modules is to use one of these solutions:
librarian-puppet: http://librarian-puppet.com/
r10k: https://github.com/puppetlabs/r10k
code-manager (PE only): https://puppet.com/docs/pe/2017.3/code_management/code_mgr.html
These will also solve the problem for you within the Vagrant if you are using the agent provisioner and subscribing the Vagrant instance to a Puppet Master.
If you are using the apply provisioner inside of Vagrant, then you will need to go a different route. The simplest solution is to use the shell provisioner to install Puppet modules via module install after the Puppet installation (unless you are using a Vagrant box with Puppet baked in, in which case you are probably not installing Puppet on it). Alternatively, you could share a directory with the host where your modules are installed, or install the librarian-puppet or r10k gems onto the Vagrant box and then use them to install into the appropriate path. I can go into more detail on these upon request.

Order of executing Chef recipes in a single cookbook

I have a single cookbook with two recipes: recipe/install.rb and recipe/configure.rb.
In install.rb, I install all packages, gem_packages and configure, using them in configure.rb. I am installing one gem_package in install.rb, and using it as require <that-gem> in configure.rb.
Regardless of the order of runlist, chef-client execution fails mentioning <that-gem> is missing. If I run with install recipe first and then run configure recipe, things work fine. Isn't there a way where a single chef-run runs both the recipes in order? I tried mentioning include_recipe and all possible solutions.
There are two phases to a Chef client run.
First is the resource compilation stage, where all the ruby is
loaded, node attributes are resolved and a run list generated.
Next is the execution phase, where the recipes in the run list
are executed.
Gems that your recipes rely on need to be available by the execution stage which presents a bit of a chicken or the egg problem, so you need to use a few tricks to get the gems installed first.
When installing gems for Chef to use, install them with chef_gem.
chef_gem "your_gem"
require 'your_gem'
This can get a bit tricky if you start using gems in libraries, as libraries are required at compile time and you can't get actions to occur before compile time. In this case you need to fail nicely on the load so the gem can be installed.
begin
require 'your_gem'
rescue LoadError
warn "Load of [your_gem] failed. Should be installed by install.rb"
end
Then be sure not to use any of the objects the gem provides in the Chef run before the install can occur.

In a Chef recipe, how do you specify a particular patch level for a Ruby?

I'm working with someone else's chef recipe and it consists of these references to the process of installing 1.9.3p0 on my server:
package 'ruby1.9.3'
package 'ruby1.9.1-dev'
# set ruby 1.9 to be default
execute 'update-alternatives --set ruby /usr/bin/ruby1.9.1'
execute 'update-alternatives --set gem /usr/bin/gem1.9.1'
ohai "reload" do
action :reload
end
I'm new to chef so I'm not sure where these packages reside, but seeing no other reference them to them in the repo of recipes, I'm guessing it's referring to a central repo. In that case, how could I modify this recipe to get chef (solo) to prepare my servers with a different patch level?
The documentation may clear things up a little here:
package tells the chef-client to use one of sixteen different
providers during the chef-client run, where the provider that is used
by chef-client depends on the platform of the machine on which the
chef-client run is taking place
So on Debian-based systems like the one that recipe was written for, Chef will automatically resolve the package resource to an apt_package resource, which will call apt-get to install ruby1.9.3.
Now, given none of the mainstream Linux distros or FreeBSD package up multiple patchlevels of Ruby (and, in some cases, stated patchlevels are not what they seem), you probably don't want to use package to get Ruby. Most likely you'll end up wanting to build it from source using something like the bash resource.
package will still be useful for installing the Ruby prerequisites, which you can use from your vendor's package repository without issue.

chef mysql install specific version

I want to install mysql v5.5.27 and php v5.3.15 but opscode doesn't show how to do this.
I've checked the recipes and saw the attributes and modified them but still no results.
Is there a way to force this?
Thanks in advance!
For PHP, if you want to install a different version from what is what is available in the distribution's official repository, you can use the compile from source install method instead of package (default).
Simply change default['php']['install_method'] to 'source' and run the default recipe. Alternatively explicitly run php::source ;-)
NOTE: You also need to change the default['php']['url'], default['php']['version'], default['php']['checksum'], etc to suite your needs.
For MySQL, as Mark said, it is up to the distribution (the version from its repository), looking at the mysql::server there isn't easy way to change it, as there is no such option as PHP (install by compiling from source) like the PHP cookbook.
The cookbook only has logic for choosing the version when installing on windows. On Linux the cookbook simply installs the mysql package supported by the package repositories associated with your distro.

Resources