kitchen-localhost 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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!