mirror of https://github.com/apache/cloudstack.git
Massively simpler serverspec invocation
Give up on using test-kitchen, busser, and more of its complexity and simply run serverspec directly, via SSH.
This commit is contained in:
parent
04ad01a064
commit
8fb1deb33e
|
|
@ -49,5 +49,3 @@ systemvm.iso
|
|||
iso/*
|
||||
|
||||
rspec.xml
|
||||
vagrant_ssh_config
|
||||
.kitchen/
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
driver:
|
||||
name: vagrant
|
||||
vagrantfile_erb: Vagrantfile.kitchen
|
||||
|
||||
provisioner:
|
||||
name: shell
|
||||
|
||||
platforms:
|
||||
- name: systemvm
|
||||
|
||||
suites:
|
||||
- name: default
|
||||
run_list:
|
||||
attributes:
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
--format documentation
|
||||
--format RspecJunitFormatter
|
||||
--out rspec.xml
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'test-kitchen', :git => 'https://github.com/test-kitchen/test-kitchen.git', :branch => 'master'
|
||||
gem 'kitchen-vagrant'
|
||||
gem 'vagrant-wrapper'
|
||||
gem 'rake'
|
||||
gem 'rspec', '~> 2.99'
|
||||
gem 'serverspec', '~> 1.11.0'
|
||||
gem 'rspec_junit_formatter'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
require 'rake'
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
t.pattern = 'spec/*/*_spec.rb'
|
||||
end
|
||||
|
||||
task :default => :spec
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
# In some cases, while booting a virtual machine, an IDE controller
|
||||
# will be created for it. It seems that the VirtualBox GUI likes doing
|
||||
# this: when a particular machine has booted at least once with its
|
||||
# GUI turned on, this will happen pretty consistently.
|
||||
#
|
||||
# Having an IDE controller and a SATA controller breaks the assumptions
|
||||
# in the systemvm scripts about what disks are attached, causing it to
|
||||
# not find the systemvm.iso.
|
||||
#
|
||||
# So, we delete the IDE controller using Vagrant.
|
||||
#
|
||||
# Unfortunately, when the IDE controller does not exist, that deletion
|
||||
# fails, causing vagrant to fail. To work around this, we inject this
|
||||
# script into the path, causing vagrant to try to continue booting.
|
||||
|
||||
/usr/bin/VBoxManage "$@"
|
||||
exitcode=$?
|
||||
|
||||
if [[ "$1" == "storagectl" ]]; then
|
||||
exit 0
|
||||
else
|
||||
exit ${exitcode}
|
||||
fi
|
||||
|
|
@ -62,7 +62,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||
|
||||
config.vm.provider 'virtualbox' do |vb|
|
||||
# enable or disable headless mode
|
||||
vb.gui = true
|
||||
vb.gui = false
|
||||
vb.customize ['modifyvm', :id, '--memory', '256']
|
||||
vb.customize ['storagectl', :id, '--name', 'IDE Controller', '--remove']
|
||||
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', '1', '--type', 'dvddrive',
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
#-*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
include RbConfig
|
||||
|
||||
VAGRANTFILE_API_VERSION = '2'
|
||||
|
||||
unless ENV['VPC_IP']
|
||||
puts 'Please specify the VPC IP by settings the VPC_IP environment variable'
|
||||
puts 'Example: export VPC_IP=192.168.56.30'
|
||||
puts ''
|
||||
exit 1
|
||||
end
|
||||
VPC_NAME='r-' + ENV['VPC_IP'].split('.').last + '-VM'
|
||||
|
||||
if ARGV[0] == 'up'
|
||||
iso_util=''
|
||||
case CONFIG['host_os']
|
||||
when /mswin|windows/i
|
||||
puts 'Windows is not supported'
|
||||
exit 1
|
||||
when /linux|arch/i
|
||||
iso_util='mkisofs -J -o systemvm.iso ./iso'
|
||||
when /sunos|solaris/i
|
||||
puts 'Solaris is not supported'
|
||||
exit 1
|
||||
when /darwin/i
|
||||
iso_util='hdiutil makehybrid -iso -joliet -o systemvm.iso ./iso/'
|
||||
else
|
||||
puts 'This OS is not supported'
|
||||
exit 1
|
||||
end
|
||||
|
||||
system 'rm -rf ./systemvm.iso'
|
||||
system 'mkdir -p iso/'
|
||||
unless File.exist? '../../../../../../systemvm/dist/cloud-scripts.tgz'
|
||||
puts 'No cloud-scripts.tgz found. Did you run the maven build?'
|
||||
exit 1
|
||||
end
|
||||
system 'cp ../../../../../../systemvm/dist/cloud-scripts.tgz iso/'
|
||||
unless File.exist? '../../../../../../systemvm/dist/systemvm.zip'
|
||||
puts 'No systemvm.zip found. Did you run the maven build?'
|
||||
exit 1
|
||||
end
|
||||
system 'cp ../../../../../../systemvm/dist/systemvm.zip iso/'
|
||||
|
||||
unless File.exist? '../../../vagrant.pub'
|
||||
puts 'No vagrant.pub found!'
|
||||
exit 1
|
||||
end
|
||||
system 'cp ../../../vagrant.pub iso/authorized_keys'
|
||||
system 'chmod 600 iso/authorized_keys'
|
||||
|
||||
system iso_util
|
||||
end
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
config.vm.box = 'cloudstack/systemvm'
|
||||
config.vm.network 'private_network', ip: ENV['VPC_IP'], auto_config: false
|
||||
config.vm.synced_folder 'vagrant', '/vagrant', disabled: true
|
||||
<% config[:synced_folders].each do |source, destination, options| %>
|
||||
config.vm.synced_folder "<%= source %>", "<%= destination %>", type: 'rsync', <%= options %>
|
||||
<% end %>
|
||||
config.ssh.forward_agent = true
|
||||
config.ssh.username = 'root'
|
||||
config.ssh.host = ENV['VPC_IP']
|
||||
config.ssh.port = 3922
|
||||
config.ssh.guest_port = 3922
|
||||
|
||||
config.vm.provider 'virtualbox' do |vb|
|
||||
# enable or disable headless mode
|
||||
vb.gui = true
|
||||
vb.customize ['modifyvm', :id, '--memory', '256']
|
||||
vb.customize ['storagectl', :id, '--name', 'IDE Controller', '--remove']
|
||||
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', '1', '--type', 'dvddrive',
|
||||
'--medium', './systemvm.iso']
|
||||
vb.customize('pre-boot', ['modifyvm', :id, '--nic1', 'none'])
|
||||
extra_data='cmdline:console=hvc0 vpccidr=172.16.0.0/16 domain=devcloud.local dns1=8.8.8.8 dns2=8.8.8.4' +
|
||||
" template=domP name=#{VPC_NAME} eth0ip=#{ENV['VPC_IP']}" +
|
||||
' eth0mask=255.255.255.0 type=vpcrouter disable_rp_filter=true'
|
||||
vb.customize('pre-boot', ['setextradata', :id, 'VBoxInternal/Devices/pcbios/0/Config/DmiOEMVBoxRev', extra_data])
|
||||
|
||||
# for internet access
|
||||
vb.customize ['modifyvm', :id, '--nic8', 'nat']
|
||||
end
|
||||
end
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# script invoked by Test-Kitchen shell provisioner to further
|
||||
# customize the VM prior to running tests
|
||||
|
||||
function setup_networking() {
|
||||
# for internet access
|
||||
if [[ ! `grep eth1 /etc/network/interfaces` ]]; then
|
||||
cat >>/etc/network/interfaces <<END
|
||||
|
||||
iface eth1 inet dhcp
|
||||
auto eth1
|
||||
END
|
||||
fi
|
||||
ifup eth1
|
||||
}
|
||||
|
||||
function install_packages() {
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export DEBIAN_PRIORITY=critical
|
||||
|
||||
local apt_get="apt-get -q -y --force-yes"
|
||||
|
||||
${apt_get} update
|
||||
|
||||
if [[ ! `which curl` ]]; then
|
||||
${apt_get} install curl
|
||||
fi
|
||||
if [[ ! `which patch` ]]; then
|
||||
${apt_get} install patch
|
||||
fi
|
||||
if [[ ! `which git` ]]; then
|
||||
${apt_get} install git
|
||||
fi
|
||||
}
|
||||
|
||||
function install_chef() {
|
||||
if [[ ! -f '/opt/chef/embedded/bin/gem' ]]; then
|
||||
curl -L https://www.opscode.com/chef/install.sh | bash
|
||||
fi
|
||||
}
|
||||
function add_junit_reports_to_serverspec() {
|
||||
local gem="/opt/chef/embedded/bin/gem"
|
||||
local gem_install="${gem} install --no-rdoc --no-ri"
|
||||
|
||||
${gem_install} rspec rspec_junit_formatter
|
||||
|
||||
if [[ ! -d 'serverspec' ]]; then
|
||||
git clone https://github.com/serverspec/serverspec.git
|
||||
(cd serverspec; git submodule update --init --recursive)
|
||||
fi
|
||||
cd serverspec
|
||||
git reset --hard
|
||||
cat >serverspec.patch <<END
|
||||
diff -u serverspec.gemspec serverspec-spec3.gemspec
|
||||
--- serverspec.gemspec
|
||||
+++ serverspec.gemspec
|
||||
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
spec.add_runtime_dependency "net-ssh"
|
||||
- spec.add_runtime_dependency "rspec", "~> 2.99"
|
||||
+ spec.add_runtime_dependency "rspec", [">= 2.99", '< 4.0']
|
||||
spec.add_runtime_dependency "rspec-its"
|
||||
spec.add_runtime_dependency "highline"
|
||||
spec.add_runtime_dependency "specinfra", "~> 1.22"
|
||||
END
|
||||
patch -p0 <serverspec.patch
|
||||
|
||||
${gem} build serverspec.gemspec
|
||||
${gem_install} serverspec-*.gem
|
||||
cd ..
|
||||
|
||||
|
||||
if [[ ! -d 'busser-serverspec' ]]; then
|
||||
git clone https://github.com/test-kitchen/busser-serverspec.git
|
||||
fi
|
||||
cd busser-serverspec
|
||||
git reset --hard
|
||||
cat >busser-serverspec.patch <<END
|
||||
diff -u lib/busser/serverspec/runner.rb lib/busser/serverspec/runner-spec3.rb
|
||||
--- lib/busser/serverspec/runner.rb
|
||||
+++ lib/busser/serverspec/runner.rb
|
||||
@@ -42,7 +42,7 @@ RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
end
|
||||
|
||||
t.rspec_path = rspec_bin if rspec_bin
|
||||
- t.rspec_opts = ['--color', '--format documentation']
|
||||
+ t.rspec_opts = ['--color', '--format documentation', '--format RspecJunitFormatter', '--out /tmp/rspec.xml']
|
||||
t.ruby_opts = "-I#{base_path}"
|
||||
t.pattern = "#{base_path}/**/*_spec.rb"
|
||||
end
|
||||
END
|
||||
|
||||
patch -p0 <busser-serverspec.patch
|
||||
${gem} build busser-serverspec.gemspec
|
||||
${gem_install} busser-serverspec-*.gem
|
||||
cd ..
|
||||
}
|
||||
|
||||
function main() {
|
||||
setup_networking
|
||||
install_packages
|
||||
install_chef
|
||||
add_junit_reports_to_serverspec
|
||||
}
|
||||
|
||||
# we only run main() if not source-d
|
||||
return 2>/dev/null || main
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
require 'serverspec'
|
||||
require 'pathname'
|
||||
require 'net/ssh'
|
||||
require 'pp'
|
||||
|
||||
include SpecInfra::Helper::Ssh
|
||||
include SpecInfra::Helper::DetectOS
|
||||
|
||||
#RSpec.configure do |c|
|
||||
# c.before :all do
|
||||
# c.path = '/sbin:/usr/sbin'
|
||||
# end
|
||||
#end
|
||||
|
||||
RSpec.configure do |c|
|
||||
if ENV['ASK_SUDO_PASSWORD']
|
||||
require 'highline/import'
|
||||
c.sudo_password = ask('Enter sudo password: ') { |q| q.echo = false }
|
||||
else
|
||||
c.sudo_password = ENV['SUDO_PASSWORD']
|
||||
end
|
||||
c.before :all do
|
||||
block = self.class.metadata[:example_group_block]
|
||||
if RUBY_VERSION.start_with?('1.8')
|
||||
file = block.to_s.match(/.*@(.*):[0-9]+>/)[1]
|
||||
else
|
||||
file = block.source_location.first
|
||||
end
|
||||
host = File.basename(Pathname.new(file).dirname)
|
||||
if c.host != host
|
||||
c.ssh.close if c.ssh
|
||||
c.host = host
|
||||
options = Net::SSH::Config.for(c.host)
|
||||
user = options[:user] || Etc.getlogin
|
||||
config = `vagrant ssh-config default`
|
||||
if config != ''
|
||||
config.each_line do |line|
|
||||
if match = /HostName (.*)/.match(line)
|
||||
host = match[1]
|
||||
elsif match = /User (.*)/.match(line)
|
||||
user = match[1]
|
||||
elsif match = /IdentityFile (.*)/.match(line)
|
||||
options[:keys] = [match[1].gsub(/"/,'')]
|
||||
elsif match = /Port (.*)/.match(line)
|
||||
options[:port] = match[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
c.ssh = Net::SSH.start(host, user, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe file('/etc/cloudstack-release') do
|
||||
it { should be_file }
|
||||
its(:content) { should match /Cloudstack Release [0-9]+(\.[0-9]+)+/ }
|
||||
end
|
||||
|
|
@ -44,16 +44,12 @@ if [[ ! -z "${JENKINS_HOME}" ]]; then
|
|||
DEBUG=1
|
||||
fi
|
||||
|
||||
kitchen_args=
|
||||
if [[ "${DEBUG}" == "1" ]]; then
|
||||
kitchen_args="-l debug"
|
||||
fi
|
||||
kitchen="bundle exec kitchen"
|
||||
|
||||
# optional (jenkins) build number tag to put into the image filename
|
||||
VPC_IP="${VPC_IP:-192.168.56.30}"
|
||||
VPC_IP="${VPC_IP:-192.168.56.254}"
|
||||
export VPC_IP
|
||||
|
||||
# inject our custom VBoxManage wrapper script
|
||||
export PATH=$PWD:$PATH
|
||||
|
||||
###
|
||||
### Generic helper functions
|
||||
###
|
||||
|
|
@ -166,39 +162,28 @@ function box_update() {
|
|||
log INFO "vagrant box update complete"
|
||||
}
|
||||
|
||||
function converge_kitchen() {
|
||||
log INFO "invoking test-kitchen converge"
|
||||
${kitchen} create ${kitchen_args}
|
||||
${kitchen} converge ${kitchen_args}
|
||||
log INFO "test-kitchen complete"
|
||||
function vagrant_up() {
|
||||
log INFO "invoking vagrant up"
|
||||
vagrant up --no-provision
|
||||
log INFO "vagrant up complete"
|
||||
}
|
||||
|
||||
function verify_kitchen() {
|
||||
log INFO "invoking test-kitchen verify"
|
||||
|
||||
${kitchen} verify ${kitchen_args}
|
||||
|
||||
# re-run busser test with patched serverspec gem to get a rspec.xml
|
||||
${kitchen} exec ${kitchen_args} -c '
|
||||
BUSSER_ROOT="/tmp/busser" GEM_HOME="/tmp/busser/gems" GEM_PATH="/tmp/busser/gems" GEM_CACHE="/tmp/busser/gems/cache"
|
||||
export BUSSER_ROOT GEM_HOME GEM_PATH GEM_CACHE
|
||||
/tmp/kitchen/bootstrap.sh
|
||||
sudo -E /tmp/busser/bin/busser test
|
||||
'
|
||||
|
||||
# ssh to machine ourselves to avoid kitchen output
|
||||
(cd .kitchen/kitchen-vagrant/default-systemvm; vagrant ssh-config) > vagrant_ssh_config
|
||||
add_on_exit rm -f vagrant_ssh_config
|
||||
scp -F vagrant_ssh_config default:/tmp/rspec.xml rspec.xml
|
||||
log INFO "test results in rspec.xml"
|
||||
|
||||
log INFO "test-kitchen complete"
|
||||
function vagrant_provision() {
|
||||
log INFO "invoking vagrant provision"
|
||||
vagrant provision
|
||||
log INFO "vagrant up complete"
|
||||
}
|
||||
|
||||
function destroy_kitchen() {
|
||||
log INFO "invoking test-kitchen destroy"
|
||||
${kitchen} destroy ${kitchen_args}
|
||||
log INFO "test-kitchen destroy complete"
|
||||
function serverspec() {
|
||||
log INFO "invoking serverspec"
|
||||
bundle exec rake spec
|
||||
log INFO "serverspec complete"
|
||||
}
|
||||
|
||||
function vagrant_destroy() {
|
||||
log INFO "invoking vagrant destroy"
|
||||
vagrant destroy -f
|
||||
log INFO "vagrant destroy complete"
|
||||
}
|
||||
###
|
||||
### Main invocation
|
||||
|
|
@ -207,9 +192,11 @@ function destroy_kitchen() {
|
|||
function main() {
|
||||
prepare
|
||||
box_update
|
||||
add_on_exit destroy_kitchen
|
||||
converge_kitchen
|
||||
verify_kitchen
|
||||
vagrant_destroy
|
||||
add_on_exit vagrant_destroy
|
||||
vagrant_up
|
||||
vagrant_provision
|
||||
serverspec
|
||||
add_on_exit log INFO "BUILD SUCCESSFUL"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
require 'serverspec'
|
||||
|
||||
include Serverspec::Helper::Exec
|
||||
include Serverspec::Helper::DetectOS
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.before :all do
|
||||
c.path = '/sbin:/usr/sbin'
|
||||
end
|
||||
end
|
||||
|
||||
describe file('/etc/cloudstack-release') do
|
||||
it { should be_file }
|
||||
its(:content) { should match /Cloudstack Release [0-9]+(\.[0-9]+)+/ }
|
||||
end
|
||||
Loading…
Reference in New Issue