kitchen-localhost 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34a54cce816185c98766b75a8b87fbd38677418f
4
- data.tar.gz: b02ef1f249dc4107d3d589940995a56bce2df255
3
+ metadata.gz: f625ce9d5ceb591fc61fac2d52dc5777393d47f3
4
+ data.tar.gz: c6b4096a2eb860b334aaabff91cbb6d281d732ce
5
5
  SHA512:
6
- metadata.gz: b2a53692d0a32a238e7a05bc3e4cbe45033a5e74b8d8703054309a93a0b78299b6da601b4f64d60cc93c8e788a2562f8fbad2cb859a775a919b8e103bf5bcb01
7
- data.tar.gz: ba7c44f78e10903888be572d4fc1f4a3032974263d299d31a7baaf70ae2f613c0700ca77625baa6c6df8ac082c08d4ab34c0398b6c6be4ff451319b400070a78
6
+ metadata.gz: 1ac97bf7163a87d5b3926a6ab4d972ca1f66c31890268078f64ad361949c6749769cdf04950cd7f60551550af8dc10948c3618a1dfe8ac891b428696c3e8d748
7
+ data.tar.gz: 4bc525a72e0d528b80078ba9ec91dc7f5c89e7fb53b05648bfc4690797ab731d183bfffd9a0c355aa803ab5077caf791c3c11b0abd6858fb1e197a070e8468ac
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  driver:
3
3
  name: localhost
4
+ # Leave Busser in place so the slower CI systems can cache it
5
+ clean_up_on_destroy: false
4
6
 
5
7
  provisioner:
6
8
  name: chef_zero
@@ -1,12 +1,12 @@
1
- language: ruby
1
+ language: objective-c
2
2
 
3
- cache: bundler
4
- sudo: true
3
+ branches:
4
+ only:
5
+ - master
5
6
 
6
- script:
7
- - bundle exec rake && bundle exec kitchen test -c 2
7
+ install:
8
+ - curl -L https://www.chef.io/chef/install.sh | sudo bash -s -- -P chefdk
9
+ - chef exec bundle update
8
10
 
9
- rvm:
10
- - ruby-head
11
- - 2.0.0
12
- - 1.9.3
11
+ script:
12
+ - chef exec bundle exec kitchen test -c 2
@@ -1,19 +1,25 @@
1
1
  Kitchen-Localhost CHANGELOG
2
2
  ===========================
3
3
 
4
+ v0.3.0 (2015-08-20)
5
+ -------------------
6
+ - Add Windows support
7
+ - Add a `clean_up_on_destroy` option for saving Kitchen's temp dirs (e.g. to
8
+ save Busser plugins on a caching-capable CI system)
9
+
4
10
  v0.2.0 (2015-05-31)
5
11
  -------------------
6
- * Try to catch instances where Kitchen is running in concurrency mode and force
7
- instances of this driver to run serially.
12
+ - Try to catch instances where Kitchen is running in concurrency mode and force
13
+ instances of this driver to run serially
8
14
 
9
15
  v0.1.1 (2015-04-29)
10
16
  -------------------
11
- * Bump Kitchen dependency to the final 1.4 release
17
+ - Bump Kitchen dependency to the final 1.4 release
12
18
 
13
19
  v0.1.0 (2015-04-13)
14
20
  -------------------
15
- * Initial release!
21
+ - Initial release!
16
22
 
17
23
  v0.0.1 (2015-04-10)
18
24
  -------------------
19
- * Development started!
25
+ - Development started!
data/README.md CHANGED
@@ -1,10 +1,14 @@
1
1
  [![Gem Version](https://img.shields.io/gem/v/kitchen-localhost.svg)][gem]
2
- [![Build Status](https://img.shields.io/travis/RoboticCheese/kitchen-localhost.svg)][travis]
2
+ [![Linux Build Status](https://img.shields.io/circleci/project/RoboticCheese/kitchen-localhost.svg)][circle]
3
+ [![Windows Build Status](https://img.shields.io/appveyor/ci/RoboticCheese/kitchen-localhost.svg)][appveyor]
4
+ [![OS X Build Status](https://img.shields.io/travis/RoboticCheese/kitchen-localhost.svg)][travis]
3
5
  [![Code Climate](https://img.shields.io/codeclimate/github/RoboticCheese/kitchen-localhost.svg)][codeclimate]
4
6
  [![Coverage Status](https://img.shields.io/coveralls/RoboticCheese/kitchen-localhost.svg)][coveralls]
5
7
  [![Dependency Status](https://img.shields.io/gemnasium/RoboticCheese/kitchen-localhost.svg)][gemnasium]
6
8
 
7
9
  [gem]: https://rubygems.org/gems/kitchen-localhost
10
+ [circle]: https://circleci.com/gh/RoboticCheese/kitchen-localhost
11
+ [appveyor]: https://ci.appveyor.com/project/RoboticCheese/kitchen-localhost
8
12
  [travis]: https://travis-ci.org/RoboticCheese/kitchen-localhost
9
13
  [codeclimate]: https://codeclimate.com/github/RoboticCheese/kitchen-localhost
10
14
  [coveralls]: https://coveralls.io/r/RoboticCheese/kitchen-localhost
@@ -15,11 +19,13 @@ Kitchen::Localhost
15
19
 
16
20
  A Test Kitchen Driver for when you just want to run Chef on localhost.
17
21
 
18
- I swear, there's a reason this driver exists! Sometimes there are cases where
19
- you want to run Test Kitchen against your CI build server (e.g. using Travis
20
- CI's Objective-C build environments to do OS X cookbook testing). This driver
21
- allows you to do everything from Kitchen instead of separately shelling out
22
- for that one special platform.
22
+ I swear, there's a reason this driver exists!
23
+
24
+ TravisCI has a wonderful OS X build environment and AppVeyor a Windows one.
25
+ This driver allows you to use either as a test environment--having the platform
26
+ under test be the one running Test Kitchen, rather than a remote cloud
27
+ server--all while keeping the same Kitchen settings, behavior, and log output
28
+ you're used to.
23
29
 
24
30
  Requirements
25
31
  ------------
@@ -29,9 +35,10 @@ understanding that this driver will be running against _your local machine_. If
29
35
  you write a cookbook that formats a hard drive and run it with this driver, bad
30
36
  things will happen.
31
37
 
32
- Also note that this driver's very nature makes it likely there will be problems
33
- if you try to do a Test Kitchen run with multiple suites and/or with
34
- concurrency enabled.
38
+ This driver attempts to minimize cases of multiple test suites clobbering each
39
+ other by never running concurrently, even if the `-c` option is passed to Test
40
+ Kitchen. But everything is still running on the same machine. Don't define
41
+ multiple suites unless they're okay to run, serially, on a single server.
35
42
 
36
43
  Installation and Setup
37
44
  ----------------------
@@ -73,6 +80,17 @@ That's it!
73
80
  run_list:
74
81
  - recipe[something]
75
82
 
83
+ Optionally, you can configure the driver to leave behind Test Kitchen's temp
84
+ directories when it does a `kitchen destroy`:
85
+
86
+ ---
87
+ driver:
88
+ name: localhost
89
+ clean_up_on_destroy: false
90
+
91
+ This can be useful if, for example, you have a CI system that's slow to install
92
+ gems and you want to have it cache Busser + its plugins.
93
+
76
94
  Contributing
77
95
  ------------
78
96
 
@@ -0,0 +1,16 @@
1
+ branches:
2
+ only:
3
+ - master
4
+
5
+ cache:
6
+ - '%TEMP%\verifier\gems'
7
+
8
+ install:
9
+ - cinst chefdk
10
+ - SET PATH=C:\opscode\chefdk\bin;%PATH%
11
+
12
+ build_script:
13
+ - chef exec bundle update
14
+
15
+ test_script:
16
+ - chef exec bundle exec kitchen test -c 2
@@ -0,0 +1,21 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.1.6
4
+
5
+ dependencies:
6
+ pre:
7
+ - rvm install 2.0.0-p645
8
+ - rvm install 1.9.3-p545
9
+ override:
10
+ - bundle update
11
+ - rvm-exec 2.0.0-p645 bundle update
12
+ - rvm-exec 1.9.3-p545 bundle update
13
+ cache_directories:
14
+ - /home/ubuntu/.rvm/gems
15
+
16
+ test:
17
+ override:
18
+ - bundle exec rake
19
+ - rvm-exec 2.0.0-p645 bundle exec rake
20
+ - rvm-exec 1.9.3-p545 bundle exec rake
21
+ - bundle exec kitchen test -c 2
@@ -17,12 +17,12 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require 'fileutils'
21
20
  require 'socket'
22
21
  require 'kitchen'
23
22
  require 'kitchen/driver/base'
24
- require_relative '../localhost/version'
25
23
  require_relative '../instance_patch'
24
+ require_relative '../localhost/shell_out'
25
+ require_relative '../localhost/version'
26
26
 
27
27
  module Kitchen
28
28
  module Driver
@@ -30,43 +30,18 @@ module Kitchen
30
30
  #
31
31
  # @author Jonathan Hartman <j@p4nt5.com>
32
32
  class Localhost < Kitchen::Driver::Base
33
+ include Kitchen::Localhost::ShellOut
34
+
33
35
  kitchen_driver_api_version 2
34
36
  plugin_version Kitchen::Localhost::VERSION
35
37
 
36
- #
37
- # Define a Mutex at the class level so we can prevent instances using
38
- # this driver from colliding.
39
- #
40
- # @return [Mutex]
41
- #
42
- def self.lock
43
- @lock ||= Mutex.new
44
- end
45
-
46
- #
47
- # Lock the class-level Mutex, whatever state it's in currently.
48
- #
49
- def self.lock!
50
- lock.lock
51
- end
52
-
53
- #
54
- # Unlock the class-level Mutex, whatever state it's in currently.
55
- #
56
- def self.unlock!
57
- # Mutex#unlock raises an exception if lock is owned by another thread
58
- # and Mutex#owned? isn't available in Ruby 1.9.
59
- lock.unlock if lock.locked?
60
- rescue ThreadError
61
- nil
62
- end
38
+ default_config :clean_up_on_destroy, true
63
39
 
64
40
  #
65
41
  # Create the temp dirs on the local filesystem for Kitchen.
66
42
  #
67
43
  # (see Base#create)
68
44
  def create(state)
69
- self.class.lock!
70
45
  state[:hostname] = Socket.gethostname
71
46
  logger.info("[Localhost] Instance #{instance} ready.")
72
47
  end
@@ -77,14 +52,16 @@ module Kitchen
77
52
  # (see Base#destroy)
78
53
  #
79
54
  def destroy(_)
80
- paths = [
81
- instance.provisioner[:root_path], instance.verifier[:root_path]
82
- ]
83
- paths.each do |p|
84
- FileUtils.rm_rf(p)
85
- logger.info("[Localhost] Deleted temp dir '#{p}'.")
55
+ if config[:clean_up_on_destroy]
56
+ [
57
+ instance.provisioner[:root_path], instance.verifier[:root_path]
58
+ ].each do |p|
59
+ rm_rf(p)
60
+ logger.info("[Localhost] Deleted temp dir '#{p}'.")
61
+ end
62
+ else
63
+ logger.info('[Localhost] Leaving Kitchen temp dirs in place.')
86
64
  end
87
- self.class.unlock!
88
65
  end
89
66
  end
90
67
  end
@@ -20,6 +20,7 @@
20
20
  require 'kitchen'
21
21
  require 'kitchen/instance'
22
22
  require_relative 'driver/localhost'
23
+ require_relative 'platform/localhost'
23
24
  require_relative 'transport/localhost'
24
25
 
25
26
  module Kitchen
@@ -28,17 +29,69 @@ module Kitchen
28
29
  #
29
30
  # @author Jonathan Hartman <j@p4nt5.com>
30
31
  class Instance
32
+ class << self
33
+ #
34
+ # Define a Mutex at the class level so we can prevent instances using
35
+ # the Localhost driver from colliding.
36
+ #
37
+ # @return [Mutex]
38
+ #
39
+ def lock
40
+ @lock ||= Mutex.new
41
+ end
42
+ end
43
+
44
+ alias_method :old_test, :test
45
+
46
+ #
47
+ # If using the Localhost driver, don't start the test phase until we can
48
+ # get a lock on the class-level Mutex.
49
+ #
50
+ # (see Instance#test)
51
+ #
52
+ def test(destroy_node = :passing)
53
+ if driver.class == Kitchen::Driver::Localhost
54
+ debug("[Localhost] Waiting for a lock before #{to_str} can proceed...")
55
+ self.class.lock.synchronize do
56
+ debug("[Localhost] Lock obtained for #{to_str}; proceeding...")
57
+ old_test(destroy_node)
58
+ debug("[Localhost] Test complete for #{to_str}; releasing lock...")
59
+ end
60
+ else
61
+ old_test(destroy_node)
62
+ end
63
+ end
64
+
31
65
  alias_method :old_setup_transport, :setup_transport
32
66
 
67
+ #
33
68
  # If using the Localhost driver, force usage of the Localhost transport.
34
69
  #
35
70
  # (see Instance#setup_transport)
36
71
  #
37
72
  def setup_transport
38
- if @driver.is_a?(Kitchen::Driver::Localhost)
73
+ if driver.class == Kitchen::Driver::Localhost
39
74
  @transport = Kitchen::Transport::Localhost.new
40
75
  end
41
76
  old_setup_transport
42
77
  end
78
+
79
+ #
80
+ # If using the Localhost driver, use the custom Platform class to figure
81
+ # out whether we need to use PowerShell or not.
82
+ #
83
+ # (see Instance#platform)
84
+ #
85
+ def platform
86
+ if driver.class == Kitchen::Driver::Localhost && \
87
+ @platform.class != Kitchen::Platform::Localhost
88
+ @platform = Kitchen::Platform::Localhost.new(
89
+ name: @platform.name,
90
+ os_type: @platform.os_type,
91
+ shell_type: @platform.shell_type
92
+ )
93
+ end
94
+ @platform
95
+ end
43
96
  end
44
97
  end
@@ -0,0 +1,113 @@
1
+ # Encoding: UTF-8
2
+ #
3
+ # Author:: Jonathan Hartman (<j@p4nt5.com>)
4
+ #
5
+ # Copyright (C) 2015, Jonathan Hartman
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'fileutils'
21
+ require 'tempfile'
22
+ require 'kitchen'
23
+ require 'kitchen/shell_out'
24
+
25
+ module Kitchen
26
+ module Localhost
27
+ # Take Kitchen's ShellOut module and add support for Windows Powershell.
28
+ #
29
+ # @author Jonathan Hartman <j@p4nt5.com>
30
+ module ShellOut
31
+ include Kitchen::ShellOut
32
+
33
+ alias_method :run_command_sh, :run_command
34
+
35
+ #
36
+ # Run a given command through the regular shell on any *nix systems or
37
+ # PowerShell on Windows.
38
+ #
39
+ # @param cmd [String] a command to run
40
+ #
41
+ def run_command(cmd)
42
+ windows_os? ? run_command_psh(cmd) : run_command_sh(cmd)
43
+ end
44
+
45
+ #
46
+ # Run a given command through PowerShell, accounting for quotes and
47
+ # other difficult-to-account for characters by writing the command out
48
+ # to a temp file, executing it, and cleaning up after.
49
+ #
50
+ # @param cmd [String] a PowerShell command or script to run
51
+ #
52
+ # @raise [ShellCommandFailed] if the command exits non-zero
53
+ #
54
+ def run_command_psh(cmd)
55
+ script = Tempfile.new(%w(kitchen-localhost .ps1))
56
+ script.write(cmd)
57
+ script.close
58
+ begin
59
+ res = run_command_sh("powershell #{script.path}")
60
+ ensure
61
+ script.unlink
62
+ end
63
+ res
64
+ end
65
+
66
+ #
67
+ # Do a recursive copy of one path to another, while running the paths
68
+ # through PowerShell on Windows platforms to translate any PSH variables.
69
+ #
70
+ # @param source [String] a source path
71
+ # @param dest [String] a destination path
72
+ #
73
+ def cp_r(source, dest)
74
+ if windows_os?
75
+ source = run_command_psh("\"#{source}\"").strip
76
+ dest = run_command_psh("\"#{dest}\"").strip
77
+ end
78
+ FileUtils.cp_r(source, dest)
79
+ end
80
+
81
+ #
82
+ # Do a recursive delete of a given path, while running the path through
83
+ # PowerShell on Windows platforms to translate any PSH variables.
84
+ #
85
+ # @param path [String] a directory to create
86
+ #
87
+ def rm_rf(path)
88
+ path = run_command_psh("\"#{path}\"").strip if windows_os?
89
+ FileUtils.rm_rf(path)
90
+ end
91
+
92
+ #
93
+ # Do a recursive mkdir of a given path, while running the path through
94
+ # PowerShell on Windows platforms to translate any PSH variables.
95
+ #
96
+ # @param path [String] a directory to create
97
+ #
98
+ def mkdir_p(path)
99
+ path = run_command_psh("\"#{path}\"").strip if windows_os?
100
+ FileUtils.mkdir_p(path)
101
+ end
102
+
103
+ #
104
+ # Check whether the localhost instance is Windows
105
+ #
106
+ # @return [TrueClass, FalseClass] whether localhost is Windows
107
+ #
108
+ def windows_os?
109
+ !RUBY_PLATFORM.match(/mswin|mingw32|windows/).nil?
110
+ end
111
+ end
112
+ end
113
+ end
@@ -22,6 +22,6 @@ module Kitchen
22
22
  #
23
23
  # @author Jonathan Hartman <j@p4nt5.com>
24
24
  module Localhost
25
- VERSION = '0.2.0'
25
+ VERSION = '0.3.0'
26
26
  end
27
27
  end
@@ -0,0 +1,47 @@
1
+ # Encoding: UTF-8
2
+ #
3
+ # Author:: Jonathan Hartman (<j@p4nt5.com>)
4
+ #
5
+ # Copyright (C) 2015, Jonathan Hartman
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'kitchen'
21
+ require 'kitchen/platform'
22
+ require_relative '../localhost/shell_out'
23
+
24
+ module Kitchen
25
+ class Platform
26
+ # A customized platform class that figures out on its own whether we're on
27
+ # a Windows or *nix system, rather than relying on platform name.
28
+ #
29
+ # @author Jonathan Hartman <j@p4nt5.com>
30
+ class Localhost < Platform
31
+ include Kitchen::Localhost::ShellOut
32
+
33
+ #
34
+ # Figure out automatically whether localhost is a Windows or *nix system.
35
+ #
36
+ # (see Platform#initialize)
37
+ #
38
+ def initialize(options = {})
39
+ if windows_os?
40
+ options[:os_type] = 'windows'
41
+ options[:shell_type] = 'powershell'
42
+ end
43
+ super(options)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -18,10 +18,9 @@
18
18
  #
19
19
 
20
20
  require 'bundler'
21
- require 'fileutils'
22
21
  require 'kitchen'
23
- require 'kitchen/shell_out'
24
22
  require 'kitchen/transport/base'
23
+ require_relative '../../localhost/shell_out'
25
24
  require_relative '../localhost'
26
25
 
27
26
  module Kitchen
@@ -31,10 +30,12 @@ module Kitchen
31
30
  #
32
31
  # @author Jonathan Hartman <j@p4nt5.com>
33
32
  class Connection < Kitchen::Transport::Base::Connection
34
- include Kitchen::ShellOut
33
+ include Kitchen::Localhost::ShellOut
35
34
 
36
35
  #
37
- # Execute a given command by shelling out and just running it.
36
+ # Execute a given command. Use the ShellOut helpers so the command is
37
+ # run through PowerShell on Windows systems and the regular command
38
+ # line everywhere else.
38
39
  #
39
40
  # (see Base::Connection#execute)
40
41
  #
@@ -42,7 +43,7 @@ module Kitchen
42
43
  #
43
44
  def execute(command)
44
45
  return if command.nil?
45
- logger.debug("[Localhost] #{self} (#{command})")
46
+ logger.debug("[Localhost] Executing command '#{command}'")
46
47
  begin
47
48
  Bundler.with_clean_env { run_command(command) }
48
49
  rescue StandardError => err
@@ -51,14 +52,16 @@ module Kitchen
51
52
  end
52
53
 
53
54
  #
54
- # Upload a set of local files to a 'remote' (aka Kitchen temp dir)
55
+ # Upload a set of local files to a 'remote' (aka Kitchen temp dir). Use
56
+ # the ShellOut helpers to run the paths through PowerShell and resolve
57
+ # any input PSH variables.
55
58
  #
56
59
  # (see Base::Connection#upload)
57
60
  #
58
61
  def upload(locals, remote)
59
- FileUtils.mkdir_p(remote)
62
+ mkdir_p(remote)
60
63
  Array(locals).each do |local|
61
- FileUtils.cp_r(local, remote)
64
+ cp_r(local, remote)
62
65
  logger.debug("[Localhost] Copied '#{local}' to '#{remote}'")
63
66
  end
64
67
  logger.debug("[Localhost] File copying to '#{remote}' complete")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen-localhost
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Hartman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-01 00:00:00.000000000 Z
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-kitchen
@@ -181,10 +181,14 @@ files:
181
181
  - LICENSE.txt
182
182
  - README.md
183
183
  - Rakefile
184
+ - appveyor.yml
185
+ - circle.yml
184
186
  - kitchen-localhost.gemspec
185
187
  - lib/kitchen/driver/localhost.rb
186
188
  - lib/kitchen/instance_patch.rb
189
+ - lib/kitchen/localhost/shell_out.rb
187
190
  - lib/kitchen/localhost/version.rb
191
+ - lib/kitchen/platform/localhost.rb
188
192
  - lib/kitchen/transport/localhost.rb
189
193
  - lib/kitchen/transport/localhost/connection.rb
190
194
  homepage: https://github.com/test-kitchen/kitchen-localhost
@@ -207,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
211
  version: '0'
208
212
  requirements: []
209
213
  rubyforge_project:
210
- rubygems_version: 2.4.6
214
+ rubygems_version: 2.4.8
211
215
  signing_key:
212
216
  specification_version: 4
213
217
  summary: Use Test Kitchen on your local machine!