Skip to content

Commit

Permalink
(BKR-1342) Import ci rake tasks and install utils
Browse files Browse the repository at this point in the history
This commit pulls all the ci acceptance rake tasks and install/setup
utilities previously defined in puppet into beaker-puppet.
  • Loading branch information
melissa committed Feb 2, 2018
1 parent 3f7bb9a commit 7d7fbe3
Show file tree
Hide file tree
Showing 8 changed files with 1,127 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/beaker-puppet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require 'beaker-puppet/version'
require 'beaker-puppet/wrappers'

require 'beaker-puppet/helpers/rake_helpers'

[ 'aio', 'foss' ].each do |lib|
require "beaker-puppet/install_utils/#{lib}_defaults"
end
Expand All @@ -12,6 +14,9 @@
[ 'tk', 'facter', 'puppet' ].each do |lib|
require "beaker-puppet/helpers/#{lib}_helpers"
end
['aio', 'common', 'gem', 'git', 'pe'].each do |lib|
require "beaker-puppet/helpers/setup/#{lib}"
end

require 'beaker-puppet/install_utils/puppet5'

Expand All @@ -33,6 +38,7 @@ module Helpers
include Beaker::DSL::Helpers::TKHelpers
include Beaker::DSL::Helpers::FacterHelpers
include Beaker::DSL::Helpers::PuppetHelpers
include Beaker::DSL::Helpers::RakeHelpers
end

include Beaker::DSL::Wrappers
Expand Down
21 changes: 21 additions & 0 deletions lib/beaker-puppet/helpers/rake_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Beaker
module DSL
module Helpers
# Methods that help you interact with rake during ci setup
module RakeHelpers
class << self
def load_tasks(beaker_root = '/Users/melissa/beaker-puppet')
task_dir = File.join(beaker_root, 'tasks')
tasks = [
'ci.rake'
]

tasks.each do |task|
load File.join(task_dir, task)
end
end
end
end
end
end
end
105 changes: 105 additions & 0 deletions lib/beaker-puppet/helpers/setup/aio.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
module Beaker
module DSL
module Helpers
module Setup
module AIO
require 'beaker-puppet/helpers/setup/common'
require 'beaker-puppet/install_utils/puppet5'

include BeakerPuppet::Install::Puppet5
include Beaker::DSL::Helpers::Setup::Common

def aio_install
test_name "Installl Packages" do
dev_builds_url = ENV['DEV_BUILDS_URL'] || 'http://builds.delivery.puppetlabs.net'
sha = ENV['SHA']
server_version = ENV['SERVER_VERSION']

step "Install puppet-agent..." do
install_from_build_data_url('puppet-agent', "#{dev_builds_url}/puppet-agent/#{sha}/artifacts/#{sha}.yaml", hosts)
end

step "Install puppetserver..." do
install_from_build_data_url('puppetserver', "#{dev_builds_url}/puppetserver/#{server_version}/artifacts/#{server_version}.yaml", master)
end

# make sure install is sane, beaker has already added puppet and ruby
# to PATH in ~/.ssh/environment
hosts.each do |host|
on host, puppet('--version')
ruby = ruby_command(host)
on host, "#{ruby} --version"
end

# Get a rough estimate of clock skew among hosts
times = []
hosts.each do |host|
ruby = ruby_command(host)
on(host, "#{ruby} -e 'puts Time.now.strftime(\"%Y-%m-%d %T.%L %z\")'") do |result|
times << result.stdout.chomp
end
end
times.map! do |time|
(Time.strptime(time, "%Y-%m-%d %T.%L %z").to_f * 1000.0).to_i
end
diff = times.max - times.min
if diff < 60000
logger.info "Host times vary #{diff} ms"
else
logger.warn "Host times vary #{diff} ms, tests may fail"
end

configure_gem_mirror(hosts)
end
end

def install_cumulus_modules
test_name "Install Cumulus Modules" do
platforms = hosts.map{|val| val[:platform]}
skip_test "No cumulus hosts present" unless platforms.any? { |val| /cumulus/ =~ val }
confine :to, {}, hosts.select { |host| host[:roles].include?('master') }

step 'install Cumulus Modules on masters' do
hosts.each do |node|
on(node, puppet('module','install','cumuluslinux-cumulus_license'))
on(node, puppet('module','install','cumuluslinux-cumulus_interfaces'))
on(node, puppet('module','install','cumuluslinux-cumulus_interface_policy'))
on(node, puppet('module','install','cumuluslinux-cumulus_ports'))
end
end
end
end

def install_arista_module
platforms = hosts.map{|val| val[:platform]}
skip_test "No arista hosts present" unless platforms.any? { |val| /^eos-/ =~ val }
test_name 'Arista Switch Pre-suite' do
masters = select_hosts({:roles => ['master', 'compile_master']})
switchs = select_hosts({:platform => ['eos-4-i386']})

step 'install Arista Module on masters' do
masters.each do |node|
on(node, puppet('module','install','aristanetworks-netdev_stdlib_eos'))
end
end

step 'add puppet user to switch' do
switchs.each do |switch|
on(switch, "useradd -U puppet")
on(switch, "/opt/puppetlabs/bin/puppet config --confdir /etc/puppetlabs/puppet set user root")
on(switch, "/opt/puppetlabs/bin/puppet config --confdir /etc/puppetlabs/puppet set group root")
end
end
end
end

def ensure_master_started
test_name 'Ensure the master service is running' do
on(master, puppet('resource', 'service', master['puppetservice'], "ensure=running"))
end
end
end
end
end
end
end
187 changes: 187 additions & 0 deletions lib/beaker-puppet/helpers/setup/common.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
module Beaker
module DSL
module Helpers
module Setup
module Common

# Installs packages on the hosts.
#
# @param hosts [Array<Host>] Array of hosts to install packages to.
# @param package_hash [Hash{Symbol=>Array<String,Array<String,String>>}]
# Keys should be a symbol for a platform in PLATFORM_PATTERNS. Values
# should be an array of package names to install, or of two element
# arrays where a[0] is the command we expect to find on the platform
# and a[1] is the package name (when they are different).
# @param options [Hash{Symbol=>Boolean}]
# @option options [Boolean] :check_if_exists First check to see if
# command is present before installing package. (Default false)
# @return true
def install_packages_on(hosts, package_hash, options = {})
platform_patterns = {
:redhat => /fedora|el-|centos/,
:debian => /debian|ubuntu|cumulus/,
:debian_ruby18 => /debian|ubuntu-lucid|ubuntu-precise/,
:solaris_10 => /solaris-10/,
:solaris_11 => /solaris-11/,
:windows => /windows/,
:eos => /^eos-/,
}.freeze

check_if_exists = options[:check_if_exists]
Array(hosts).each do |host|
package_hash.each do |platform_key,package_list|
if pattern = platform_patterns[platform_key]
if pattern.match(host['platform'])
package_list.each do |cmd_pkg|
if cmd_pkg.kind_of?(Array)
command, package = cmd_pkg
else
command = package = cmd_pkg
end
if !check_if_exists || !host.check_for_package(command)
host.logger.notify("Installing #{package}")
additional_switches = '--allow-unauthenticated' if platform_key == :debian
host.install_package(package, additional_switches)
end
end
end
else
raise("Unknown platform '#{platform_key}' in package_hash")
end
end
end
return true
end

def ruby_command(host)
"env PATH=\"#{host['privatebindir']}:${PATH}\" ruby"
end

def gem_command(host, type = 'aio')
if type == 'aio'
if host['platform'] =~ /windows/
"env PATH=\"#{host['privatebindir']}:${PATH}\" cmd /c gem"
else
"env PATH=\"#{host['privatebindir']}:${PATH}\" gem"
end
else
on(host, 'which gem').stdout.chomp
end
end

# Configures gem sources on hosts to use a mirror, if specified
# This is a duplicate of the Gemfile logic.
def configure_gem_mirror(hosts)
hosts = Array(hosts)
gem_source = ENV['GEM_SOURCE'] || 'https://rubygems.org'

hosts.each do |host|
gem = gem_command(host)
on host, "#{gem} source --clear-all"
on host, "#{gem} source --add #{gem_source}"
end
end

# Ensure that the any previous installations of puppet
# are removed from the host if it is not managed by a
# provisioning hypervisor.
def delete_puppet_when_none
test_name "Expunge puppet bits if hypervisor is none" do
hosts.each do |host|
if host[:hypervisor] == "none"
remove_puppet_on(host)
end
end
end
end

def stop_firewall
test_name "Stop firewall" do
hosts.each do |host|
case host['platform']
when /debian/
on host, 'iptables -F'
when /fedora|el-7/
on host, puppet('resource', 'service', 'firewalld', 'ensure=stopped')
when /el-|centos/
on host, puppet('resource', 'service', 'iptables', 'ensure=stopped')
when /ubuntu/
on host, puppet('resource', 'service', 'ufw', 'ensure=stopped')
else
logger.notify("Not sure how to clear firewall on #{host['platform']}")
end
end
end
end

# The sssd service causes local users/groups to be cached,
# which can cause unexpected results when tests are trying
# to restore state. We ensure that it is not running to
# prevent such caching from occurring.
def stop_sssd(hosts)
test_name "Stop sssd" do
hosts.each do |host|
on(host, puppet('resource', 'service', 'sssd', 'ensure=stopped'), :accept_all_exit_codes => true)
end
end
end

def validate_sign_cert(hosts)
test_name "Validate Sign Cert" do
hostname = on(master, 'facter hostname').stdout.strip
fqdn = on(master, 'facter fqdn').stdout.strip

if master.use_service_scripts?
step "Ensure puppet is stopped"
# Passenger, in particular, must be shutdown for the cert setup steps to work,
# but any running puppet master will interfere with webrick starting up and
# potentially ignore the puppet.conf changes.
on(master, puppet('resource', 'service', master['puppetservice'], "ensure=stopped"))
end

step "Clear SSL on all hosts"
hosts.each do |host|
ssldir = on(host, puppet('agent --configprint ssldir')).stdout.chomp
on(host, "rm -rf '#{ssldir}'")
end

step "Master: Start Puppet Master"
master_opts = {
:main => {
:dns_alt_names => "puppet,#{hostname},#{fqdn}",
},
:__service_args__ => {
# apache2 service scripts can't restart if we've removed the ssl dir
:bypass_service_script => true,
},
}
with_puppet_running_on(master, master_opts) do

hosts.each do |host|
next if host['roles'].include? 'master'

step "Agents: Run agent --test first time to gen CSR"
on host, puppet("agent --test --server #{master}"), :acceptable_exit_codes => [1]
end

# Sign all waiting certs
step "Master: sign all certs"
on master, puppet("cert --sign --all"), :acceptable_exit_codes => [0,24]

step "Agents: Run agent --test second time to obtain signed cert"
on agents, puppet("agent --test --server #{master}"), :acceptable_exit_codes => [0,2]
end
end
end

# TODO I don't believe this is used anywhere
#def set_pe_puppet_service
# test_name "Set puppetservice to pe-puppetserver" do
# master['puppetservice'] = 'pe-puppetserver'
# end
#end
end
end
end
end
end
54 changes: 54 additions & 0 deletions lib/beaker-puppet/helpers/setup/gem.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module Beaker
module DSL
module Helpers
module Setup
module Gem

require 'beaker-puppet/helpers/setup/common'
include Beaker::DSL::Helpers::Setup::Common

def gem_install
test_name "Install puppet gem" do
agents.each do |agent|
sha = ENV['SHA']
base_url = "http://builds.delivery.puppetlabs.net/puppet/#{sha}/artifacts"

ruby = ruby_command(agent)
gem = gem_command(agent)

# retrieve the build data, since the gem version is based on the short git
# describe, not the full git SHA
on(agent, "curl -s -o build_data.yaml #{base_url}/#{sha}.yaml")
gem_version = on(agent, "#{ruby} -ryaml -e 'puts YAML.load_file(\"build_data.yaml\")[:gemversion]'").stdout.chomp

if agent['platform'] =~ /windows/
# wipe existing gems first
default_dir = on(agent, "#{ruby} -rrbconfig -e 'puts Gem.default_dir'").stdout.chomp
on(agent, "rm -rf '#{default_dir}'")

arch = agent[:ruby_arch] || 'x86'
gem_arch = arch == 'x64' ? 'x64-mingw32' : 'x86-mingw32'
url = "#{base_url}/puppet-#{gem_version}-#{gem_arch}.gem"
else
url = "#{base_url}/puppet-#{gem_version}.gem"
end

step "Download puppet gem from #{url}"
on(agent, "curl -s -o puppet.gem #{url}")

step "Install puppet.gem"
on(agent, "#{gem} install puppet.gem")

step "Verify it's sane"
on(agent, puppet('--version'))
on(agent, puppet('apply', "-e \"notify { 'hello': }\"")) do |result|
assert_match(/defined 'message' as 'hello'/, result.stdout)
end
end
end
end
end
end
end
end
end
Loading

0 comments on commit 7d7fbe3

Please sign in to comment.