Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Windows in the Kitchen #324

Open
wants to merge 1 commit into from

2 participants

@maxlinc

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)
@maxlinc

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 :)

@henrikhodne 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. @maxlinc
This page is out of date. Refresh to see the latest.
View
33 .kitchen.yml
@@ -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]
View
9 Gemfile
@@ -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
-
View
2  Vagrantfile
@@ -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:
View
46 Vagrantfile.windows.erb
@@ -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
View
9 test/integration/worker_windows/serverspec/compilers_spec.rb
@@ -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
View
13 test/integration/worker_windows/serverspec/networking_tools_spec.rb
@@ -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
View
44 test/integration/worker_windows/serverspec/runtimes_spec.rb
@@ -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
View
15 test/integration/worker_windows/serverspec/spec_helper.rb
@@ -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
View
24 test/integration/worker_windows/serverspec/version_control_spec.rb
@@ -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.