Thursday, August 17, 2017

RHEL Alternatives

When changing environments for certain applications, Java being a key one which has many different files and variables to be configured you want to be able to gt the full environment changed in one go, rather than having to set different paths, etc.

The RHEL alternatives command does just that, allowing you to change your Java environment so that java, javac, javadoc all get set to the correct location without having to change your PATH and other environment variables.

Here's how you can set Java to the Oracle version after you have installed it on to your RHEL system.  You'll note that if you use the alternatives command you will get the JRE rather than the JDK, and if you're developing or require the JDK you will want to change the settings.

Before we can add a new option, we need to find out the next available number to use;

sudo alternatives --config java

There are 3 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.141-2.6.10.1.el7_3.x86_64/jre/bin/java)
 + 2           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.141-1.b16.el7_3.x86_64/jre/bin/java)

   3           /usr/java/jdk1.8.0_131/jre/bin/java


Enter to keep the current selection[+], or type selection number: 

From the above output we can see that our next available slot is 4, so we need to add Oracle JDK to this location;

sudo alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_131/bin/java 4

The above command will also identify the javac and javadoc commands too, so no other changes are required.

Now we can set Oracle Java as our default JDK;

sudo alternatives --config java

There are 4 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
   1           java-1.7.0-openjdk.x86_64 (/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.141-2.6.10.1.el7_3.x86_64/jre/bin/java)
 + 2           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.141-1.b16.el7_3.x86_64/jre/bin/java)
   3           /usr/java/jdk1.8.0_131/jre/bin/java
   4           /usr/java/jdk1.8.0_131/bin/java

Enter to keep the current selection[+], or type selection number:

Select 4 and you will have Oracle JDK default system wide.

Thursday, May 4, 2017

Puppet Rake serverspec testing

Using Rake to ServerSpec test

If you don't like kitchen, or your team is using Rake you may choose to use the rake spec command for serverspec testing.  The directory layout is simpler than Kitchen, but requires more configuration as you need to create the following files;
  • Rakefile
  • spec_helper.rb
  • Vagrantfile
  • Provisioning script for the Vagrant VMs
These files need further configuration to make serverspec work using Rake.  The Rakefile and the spec_helper.rb files will live within the test directory, but spec_helper.rb will live in a spec subdirectory.
You'll notice the key difference compared to RSpec is the localhost directory. Each host will need it's spec test included. For example;
 Vagrantfile
 test
 ├── coretests
 │   ├── nginx_spec.rb
 │   └── dns_spec.rb
 ├── Rakefile
 └── spec
     └── web
     │   ├── nginx_spec.rb -> ../../coretests/nginx_spec.rb
     └── webserver1.al.local
     │   └── nginx_spec.rb -> ../../coretests/nginx_spec.rb 
     └── spec_helper.rb
      
Example diagramatic view of a project and where the directory structure fits;

Above we now have an SSH host for web and weberver1.al.local. The difference between the localhost and the SSH version is in the spec_helper.rb file, so be sure to check your configurations.
In the above we symlink each host with the required tests in the coretests folder.

Rakefile

Here is an example Rake file to perform build, config and run;
require 'rake'
require 'rspec/core/rake_task'
 
hosts = %w(
  web
)
 
task :spec => 'spec:all'
 
namespace :spec do
  task :all => hosts.map {|h| 'spec:' + h.split('.')[0] }
  hosts.each do |host|
    short_name = host.split('.')[0]
    role       = short_name.match(/.+/)[0]
 
    desc "Run serverspec to #{host}"
    RSpec::Core::RakeTask.new(short_name) do |t|
      ENV['TARGET_HOST'] = host
      t.pattern = "spec/{base,#{role}}/*_spec.rb"
      t.verbose = true
    end
  end
end
The important elements about the above file are;
  • hosts = %w (
    • Each line in this list will be a host in your Vagrantfile
    • The name specified here will be the same as the name of the define :web for example, which is the beginning of the definition of the VM
  • task :spec => 'spec:all'
    • This line defines what tasks to run within the file.  This file will run the all task.
  • task :all
    • This is the main task that tells rake to use the hosts variable to loop through
    • The hosts.each starts the real work
    • If you have more than one host you will need to add them to the hosts array
  • t.pattern
    • This line defines the name of the directory that will be used to target the tests to run for the current host in the loop

spec/spec_helper.rb

This file defines how the VM will be created and the connection to it, as well as other environmental information to be used within the VM.
Example;
require 'serverspec'
require 'net/ssh'
require 'tempfile'
 
set :backend, :ssh
 
if ENV['ASK_SUDO_PASSWORD']
  begin
    require 'highline/import'
  rescue LoadError
    fail "highline is not available. Try installing it."
  end
  set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false }
else
  set :sudo_password, ENV['SUDO_PASSWORD']
end
 
host = ENV['TARGET_HOST']
`vagrant up #{host}`
 
config = Tempfile.new('', Dir.tmpdir)
config.write(`vagrant ssh-config #{host}`)
config.close
 
options = Net::SSH::Config.for(host, [config.path])
 
options[:user] ||= Etc.getlogin
 
set :host,        options[:host_name] || host
set :ssh_options, options
 
# Disable sudo
# set :disable_sudo, true
 
# Set environment variables
# set :env, :LANG => 'C', :LC_MESSAGES => 'C'
 
# Set PATH
# set :path, '/sbin:/usr/local/sbin:$PATH'
#

Vagrantfile

This will live above the test directory.  For our example so far we would need a VM with the name of web;
Vagrant.configure("2"do |config|
  config.vm.define :web do | web |
    web.vm.provider "virtualbox" do | vb |
        vb.memory = 1024
        vb.cpus = 1
        vb.name = "WebNode"
    end
    web.vm.hostname = "web.al.local"
    web.vm.network "private_network", ip: "192.168.100.23"
    web.vm.provision "shell", path: "bin/web.sh"
    web.vm.box = "bento/centos-7.2"
  end
end
The define :web matches the web in the Rakefile.  The bin/web.sh will call the necessary commands to provision the VM, prior to serverspec running.

Running the test

To run a serverspec test using rake simply run the following;
rake spec
Unlike kitchen, rake does not show the build and configuration of the VM, so you will be waiting some time until it gets to the test phase, which means the output is cleaner, since it is only the tests.