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 moves all ci acceptance rake tasks and install/setup
utilities out of the puppet repo and into the beaker-puppet repo. This
will allow us to reuse all of this code across multiple components of
puppet-agent. The goal is to reduce the number of places we need to
duplicate code across different code bases. With this change, any future
updates or overhauls will be consistent across all our projects.
  • Loading branch information
melissa committed Feb 2, 2018
1 parent 3f7bb9a commit 7a51054
Show file tree
Hide file tree
Showing 8 changed files with 1,135 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
112 changes: 112 additions & 0 deletions lib/beaker-puppet/helpers/setup/aio.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
module Beaker
module DSL
module Helpers
module Setup
module AIO
require 'beaker-puppet/install_utils/puppet5'
require 'beaker-puppet/install_utils/foss_utils'
require 'beaker-puppet/helpers/setup/common'

include BeakerPuppet::Install::Puppet5
include Beaker::DSL::InstallUtils::FOSSUtils
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'

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

step "Install puppetserver..." do
if ENV['SERVER_VERSION'].nil? || ENV['SERVER_VERSION'] == 'latest'
install_puppetlabs_dev_repo(master, 'puppetserver', 'latest', nil, :dev_builds_url => "http://nightlies.puppet.com")
master.install_package('puppetserver')
else
server_version = ENV['SERVER_VERSION']
install_from_build_data_url('puppetserver', "#{dev_builds_url}/puppetserver/#{server_version}/artifacts/#{server_version}.yaml", master)
end
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
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
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
Loading

0 comments on commit 7a51054

Please sign in to comment.