Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Windows in the Kitchen #324

Open
wants to merge 1 commit into from

2 participants

Max Lincoln Henrik Hodne
Max Lincoln

I'm sending two related PRs. I thought it would be a little clearer and easier to discuss than a single PR.

This PR continues the work started in #289 to setup development/testing tools. So this PR is good for discussion about "how do we want to test travis-cookbooks" and windows support specifically.

Note that I've created a "worker_windows" which is basically a copy of "worker_standard". They might be merge together into a platform agnostic "worker_standard", pending discussing on the other PR.

test-kitchen is looking promising, but there are a number of workarounds necessary to use windows in the kitchen:

  • test-kitchen/kitchen-vagrant do not currently support windows over winrm, but @docwhat created a workaround driver that uses vagrant for provisioning
  • test-kitchen has serverspec support, but it only supports transferring suites over SSH and running them on the guest machine. I want to run serverspec on the host machine and use the WinRM transport. So although I followed the test-kitchen layout, I am not using test-kitchen to run serverspec (i.e. you currently can do kitchen converge but not kitchen verify or kitchen test... run the tests directly via rspec)
  • vagrant-berkshelf isn't working for me. I'm manually doing a berks vendor and setting the cookbooks_path to use berks-cookbooks

Other notes:

  • I found packer-windows, which is working well. It can build more Windows images, but currently install OpenSSH (which I don't really want). I'm currently testing with both Windows 2012 Server Core (including OpenSSH) built via packer-windows, and with Windows 8.1 built manually (without OpenSSH)
Max Lincoln

Since it may not be obvious and I didn't include a README update or any Rake tasks, here's how you would currently test:

  • bundle install, of course ;)
  • Build one or both Windows Vagrant boxes:
    • You can create either image with packer-windows... they will have OpenSSH unless you remove it.
    • Or you can follow the instructions from vagrant-windows and use images from modern.ie (at least for win8)
  • vagrant box add ... the images created above
  • Once the boxes are imported, run kitchen list to make sure everything is working okay. You should see something like:
Instance                        Driver            Provisioner  Last Action
worker-windows-precise          Vagrant           ChefSolo     <Not Created>
worker-windows-trusty           Vagrant           ChefSolo     <Not Created>
worker-windows-win2012-r2-core  VagrantProvision  ChefSolo     <Not Created>
worker-windows-win8             VagrantProvision  ChefSolo     <Not Created>
  • Choose which windows instance you want to test (I'll assume win8), and run kitchen converge win8 (in the future, you'll hopefully be able to do kitchen test win8, but kitchen can't run the tests right now)
  • Once it finishes converging, you can run bundle exec rspec rspec test/integration/worker_windows/serverspec/ (in the future this will hopefully be part of kitchen verify)

If you want to successfully converge and test, you'll need to merge #325 or something similar :)

Henrik Hodne henrikhodne added the windows label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 4, 2014
  1. Max Lincoln
This page is out of date. Refresh to see the latest.
33 .kitchen.yml
View
@@ -2,18 +2,45 @@
driver:
name: vagrant
driver_config:
+ require_chef_omnibus: true
customize:
cpus: 2
memory: 1024
+# Disabled at top level... see workaround on win8
provisioner:
name: chef_solo
platforms:
- - name: ubuntu-12.04
+ - name: precise
+ driver:
+ box: ubuntu/precise64
+ - name: trusty
+ driver:
+ box: ubuntu/trusty64
+ - name: win2012_r2_core
+ # Temporary (hopefully) workaround:
+ # https://github.com/test-kitchen/kitchen-vagrant/issues/77#issuecomment-39931279
+ driver:
+ name: vagrant_provision
+ box: win2012_r2_core
+ guest: :windows
+ vagrantfile_erb: 'Vagrantfile.windows.erb'
+ customize:
+ memory: 2048 # yeah... you probably want more memory on windows
+ - name: win8
+ # Temporary (hopefully) workaround:
+ # https://github.com/test-kitchen/kitchen-vagrant/issues/77#issuecomment-39931279
+ driver:
+ name: vagrant_provision
+ box: win8
+ guest: :windows
+ vagrantfile_erb: 'Vagrantfile.windows.erb'
+ customize:
+ memory: 2048 # yeah... you probably want more memory on windows
suites:
# based on https://github.com/travis-ci/travis-images/tree/master/templates, should find a way to link the projects
- - name: worker_python
+ - name: worker_windows
run_list:
- - role[worker_python]
+ - role[worker_windows]
9 Gemfile
View
@@ -8,11 +8,16 @@ group :test do
gem 'chefspec', '~> 2.0.1'
gem 'rubocop', '~> 0.18'
gem 'rainbow', '< 2.0'
- gem 'test-kitchen', '~> 1.2'
+ gem 'test-kitchen'
gem 'kitchen-vagrant'
gem 'strainer', :github => 'customink/strainer'
+ gem 'serverspec'
+ # Serverspec examples use "its" which is deprecated... we can switch to an rspec 3 syntax or use the rspec-its gem
+ gem 'rspec-its'
+ gem 'winrm'
+ # kitchen-driver-vagrant_provision is a workaround for https://github.com/test-kitchen/kitchen-vagrant/issues/77#issuecomment-40939023
+ gem 'kitchen-driver-vagrant_provision'
# Workaround: There is a ChefSpec regression when integrating with Chef 11.10+
gem 'chef', '~> 11.8.0'
end
-
2  Vagrantfile
View
@@ -62,7 +62,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
end
win.vm.provision "chef_solo" do |chef|
- chef.log_level = :debug
+ chef.log_level = :info
chef.cookbooks_path = %w(ci_environment berks-cookbooks)
# Role-based Provisioning:
46 Vagrantfile.windows.erb
View
@@ -0,0 +1,46 @@
+Vagrant.configure('2') do |c|
+ c.vm.box = '<%= config[:box] %>'
+ c.vm.box_url = '<%= config[:box_url] %>'
+ c.omnibus.chef_version = :latest
+
+ c.vm.hostname = '<%= config[:vm_hostname] %>'
+ c.vm.guest = :windows
+ c.vm.communicator = "winrm"
+ c.winrm.username = 'vagrant'
+ c.winrm.password = 'vagrant'
+
+ # Needed for WinRM
+ c.vm.network(:forwarded_port, guest: 5985, host: 5985)
+<% Array(config[:network]).each do |opts| %>
+ c.vm.network(:<%= opts[0] %>, <%= opts[1..-1].join(", ") %>)
+<% end %>
+
+ c.vm.synced_folder '.', '/vagrant', disabled: true
+<% config[:synced_folders].each do |source, destination, options|
+ l_source = source.gsub("%{instance_name}", instance.name)
+ l_destination = destination.gsub("%{instance_name}", instance.name)
+ opt = (options.nil? ? '' : ", #{options}")
+%>
+ c.vm.synced_folder '<%= l_source %>', '<%= l_destination %>'<%= opt %>
+<% end %>
+
+ c.vm.provider :virtualbox do |p|
+ p.gui = true
+ p.customize ["modifyvm", :id, '--memory', '2048']
+ end
+
+ # c.berkshelf.berksfile_path = '<%= File.join(Dir.pwd, 'Berksfile') %>'
+ # c.berkshelf.enabled = true
+
+ c.vm.provision :chef_solo do |chef|
+ chef.cookbooks_path = "<%= File.join(Dir.pwd, 'berks-cookbooks') %>"
+ chef.roles_path = "<%= File.join(Dir.pwd, 'roles') %>"
+ # chef.json = JSON.load(<%= instance.provisioner[:attributes].to_json.inspect %>)
+ chef.json = <%= instance.provisioner[:attributes].to_hash.inspect %>
+ <% instance.provisioner[:run_list].each do |recipe| %>
+ <% type, name = recipe.match(/(\w+)\[(.*)\]/).captures %>
+ <% raise "Invalid run_list item: #{recipe}" if type.nil? or name.nil? %>
+ chef.add_<%= type %> '<%= name %>'
+ <% end %>
+ end
+end
9 test/integration/worker_windows/serverspec/compilers_spec.rb
View
@@ -0,0 +1,9 @@
+require_relative 'spec_helper'
+
+include Serverspec::Helper::Exec
+include Serverspec::Helper::DetectOS
+
+describe "Compilers" do
+ skip "Microsoft Visual Studio Express"
+ skip "Go"
+end
13 test/integration/worker_windows/serverspec/networking_tools_spec.rb
View
@@ -0,0 +1,13 @@
+require_relative 'spec_helper'
+
+include Serverspec::Helper::Exec
+include Serverspec::Helper::DetectOS
+
+describe "Networking Tools" do
+ skip "PowerShell"
+ describe "OpenSSL" do
+ describe command('openssl version') do
+ its(:stdout) { should match(/OpenSSL \d+\.\d+\.\d+/) }
+ end
+ end
+end
44 test/integration/worker_windows/serverspec/runtimes_spec.rb
View
@@ -0,0 +1,44 @@
+require 'serverspec'
+
+include Serverspec::Helper::Exec
+include Serverspec::Helper::DetectOS
+
+describe "Version Control tools" do
+ describe "Ruby" do
+ describe command('ruby --version') do
+ its(:stdout) { should match(/ruby \d+\.\d+\.\d+/) }
+ end
+
+ describe command('bundle --version') do
+ its(:stdout) { should match(/Bundler version */) }
+ end
+ end
+
+ describe "Java" do
+ describe command('java -version') do
+ its(:stdout) { should match(/Java\(TM\) SE Runtime Environment \(build/) }
+ end
+ end
+
+ describe "Python" do
+ describe command('svn --version') do
+ its(:stdout) { should match(/svn, version */) }
+ end
+ end
+
+ describe "Node.js" do
+ describe command('node --version') do
+ its(:stdout) { should match(/v\d+\.\d+\.\d+/) }
+ end
+
+ describe command('npm --version') do
+ its(:stdout) { should match(/\d+\.\d+\.\d+*/) }
+ end
+ end
+
+ describe "Go" do
+ describe command('go version') do
+ its(:stdout) { should match(/go version go\d+\.\d+\.\d/) }
+ end
+ end
+end
15 test/integration/worker_windows/serverspec/spec_helper.rb
View
@@ -0,0 +1,15 @@
+require 'rspec/its'
+require 'serverspec'
+require 'winrm'
+
+include SpecInfra::Helper::WinRM
+include SpecInfra::Helper::Windows
+
+RSpec.configure do |c|
+ user = 'vagrant'
+ pass = 'vagrant'
+ endpoint = "http://localhost:5985/wsman"
+
+ c.winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true)
+ c.winrm.set_timeout 300 # 5 minutes max timeout for any operation
+end
24 test/integration/worker_windows/serverspec/version_control_spec.rb
View
@@ -0,0 +1,24 @@
+require 'serverspec'
+
+include Serverspec::Helper::Exec
+include Serverspec::Helper::DetectOS
+
+describe "Version Control tools" do
+ describe "git" do
+ describe command('git --version') do
+ its(:stdout) { should match(/git version.*/) }
+ end
+ end
+
+ describe "mercurial" do
+ describe command('hg --version') do
+ its(:stdout) { should match(/Mercurial Distributed SCM \(version \d.\d\)/) }
+ end
+ end
+
+ describe "subversion" do
+ describe command('svn --version') do
+ its(:stdout) { should match(/svn, version */) }
+ end
+ end
+end
Something went wrong with that request. Please try again.