daptiv-chef-ci 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,11 +1,13 @@
1
1
  # Daptiv Chef CI
2
+ [![Build Status](https://travis-ci.org/daptiv/daptiv-chef-ci.png)](https://travis-ci.org/daptiv/daptiv-chef-ci)
3
+ [![Gem Version](https://badge.fury.io/rb/daptiv-chef-ci.png)](http://badge.fury.io/rb/daptiv-chef-ci)
4
+
2
5
  Common tools to help automate Vagrant in CI
3
6
 
4
7
  This is a really thin wrapper around Vagrant that makes it a little easier to call Vagrant from a Rake build. Why on earth does this exist?
5
8
 
6
9
  1. Makes it easier to call your installed Vagrant from a Rake build.
7
10
  2. Ensures vagrant is loaded from your PATH and _not_ from a bundled gem.
8
- 3. Reduces duplication between cookbook Vagrantfiles.
9
11
 
10
12
  ## Basic Usage
11
13
 
@@ -21,39 +23,9 @@ require 'daptiv-chef-ci/vagrant_task'
21
23
  Vagrant::RakeTask.new
22
24
  ```
23
25
 
24
- The rake task will attempt to load a Vagrantfile as an Erubis template from the following locations in order:
25
-
26
- - Vagrantfile.erb
27
- - Vagrantfile
28
-
29
- If none of those exist the task will use the Vagrantfile.erb template embedded in this gem. Here's an example that specifies a Windows Vagrant box using the embedded Vagrantfile:
30
-
31
- ```
32
- require 'daptiv-chef-ci/vagrant_task'
33
-
34
- Vagrant::RakeTask.new do |task|
35
- task.guest_os = :windows
36
- task.box_name = 'vagrant-windows2008r2'
37
- task.box_url = 'http://example.com/vagrant/boxes/vagrant-windows2008r2.box'
38
- task.run_list = ['mycookbook::recipe']
39
- end
40
- ```
41
-
42
- ## Configuration
43
-
44
- The vagrant rake task provides the following configuration parameters to the ERB template, these can be configured using the same name in the rake task:
45
-
46
- - guest_os - defaults to :linux
47
- - chef_repo_dir - The chef-repo root directory, defaults to ~/src/chef-repo
48
- - box_name - defaults to 'Vagrant-hostname', this is optional.
49
- - node_name - The chef node name, defaults to 'Vagrant-hostname', this is optional.
50
- - box_url - URL to the box download location, this is optional.
51
- - run_list - The Chef run list, defaults to empty.
52
- - chef_json - Any additional Chef attributes in json format, this is optional.
53
-
54
26
  ## Logging
55
27
 
56
- By default this gem will not log anything other than errors to stderr, however quite often its useful to get more information from the running Vagrant process. To change the gem logging level set the CHEF_CI_LOG environment variable to one supported by log4r (DEBUG, INFO etc).
28
+ To change the gem logging level set the CHEF_CI_LOG environment variable to one supported by log4r (DEBUG, INFO etc).
57
29
 
58
30
  `CHEF_CI_LOG=DEBUG bundle exec rake vagrant`
59
31
 
@@ -43,10 +43,10 @@ Gem::Specification.new do |gem|
43
43
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
44
44
  gem.name = "daptiv-chef-ci"
45
45
  gem.require_paths = ["lib"]
46
- gem.version = '0.0.3'
46
+ gem.version = '0.0.4'
47
47
 
48
48
  gem.add_runtime_dependency "log4r", "~> 1.1.10"
49
- gem.add_runtime_dependency "erubis", "~> 2.7.0"
49
+ gem.add_runtime_dependency "mixlib-shellout", "~> 1.2.0"
50
50
 
51
51
  gem.add_development_dependency "rake"
52
52
  gem.add_development_dependency "rspec-core", "~> 2.12.2"
@@ -26,7 +26,7 @@ module DaptivChefCI
26
26
  level_i = Log4r::Log4rConfig::LogLevels.index(level)
27
27
  level_i + 1
28
28
  rescue
29
- return 4 # error
29
+ return 2 # info
30
30
  end
31
31
 
32
32
  end
@@ -1,5 +1,6 @@
1
1
  require 'log4r'
2
2
  require 'bundler'
3
+ require 'mixlib/shellout'
3
4
 
4
5
  module DaptivChefCI
5
6
  class Shell
@@ -16,14 +17,18 @@ module DaptivChefCI
16
17
  # @param [String] The command line to execute
17
18
  # @return [Array] Each entry represents a line from the stdout
18
19
  def exec_cmd(command)
19
- @logger.info("Calling command [#{command}]")
20
20
  path_at_start = ENV['PATH']
21
21
  begin
22
22
  ENV['PATH'] = path_without_gem_dir()
23
23
  @logger.debug("Temporarily setting PATH: #{ENV['PATH']}")
24
- out = `#{command}`
25
- @logger.debug(out)
26
- out.split("\n")
24
+
25
+ @logger.info("Calling command [#{command}]")
26
+ shell_out = Mixlib::ShellOut.new(command)
27
+ shell_out.run_command()
28
+ shell_out.invalid! if shell_out.exitstatus != 0
29
+
30
+ @logger.info(shell_out.stdout)
31
+ shell_out.stdout.split("\n")
27
32
  ensure
28
33
  @logger.debug("Resetting PATH: #{path_at_start}")
29
34
  ENV['PATH'] = path_at_start
@@ -1,6 +1,4 @@
1
1
  require 'log4r'
2
- require 'socket'
3
- require 'erubis'
4
2
  require_relative 'shell'
5
3
 
6
4
  module DaptivChefCI
@@ -9,38 +7,9 @@ module DaptivChefCI
9
7
  # Constructs a new Vagrant management instance
10
8
  #
11
9
  # @param [Shell] The CLI
12
- # @param [Hash] The options to pass to the Vagrantfile
13
- #
14
- # options[:guest_os] - defaults to :linux
15
- # options[:chef_repo_dir] - The chef-repo root directory, defaults to ~/src/chef-repo
16
- # options[:box_name] - defaults to 'Vagrant-hostname'
17
- # options[:node_name] - The chef node name, defaults to 'Vagrant-hostname'
18
- # options[:box_url] - URL to the box download location, this is optional.
19
- # options[:run_list] - The Chef run list, defaults to empty.
20
- # options[:chef_json] - Any additional Chef attributes in json format.
21
- def initialize(shell, options)
10
+ def initialize(shell)
22
11
  @logger = Log4r::Logger.new("daptiv_chef_ci::vagrant")
23
12
  @shell = shell
24
-
25
- options[:guest_os] ||= :linux
26
- options[:box_name] ||= "Vagrant-#{Socket.gethostname}"
27
- options[:box_url] ||= nil
28
- options[:node_name] ||= options[:box_name]
29
- options[:run_list] ||= []
30
- options[:chef_repo_dir] = "#{ENV['HOME']}/src/chef-repo"
31
- options[:chef_json] ||= nil
32
- @options = options
33
- end
34
-
35
- def create_vagrantfile()
36
- @logger.debug('Creating Vagrantfile')
37
- File.open('Vagrantfile', 'w') do |f|
38
- f.write render_vagrantfile()
39
- end
40
- end
41
-
42
- def render_vagrantfile()
43
- Erubis::Eruby.new(vagrantfile_erb()).result(@options)
44
13
  end
45
14
 
46
15
  def destroy()
@@ -63,33 +32,5 @@ module DaptivChefCI
63
32
  @shell.exec_cmd('vagrant reload')
64
33
  end
65
34
 
66
-
67
- private
68
-
69
- def vagrantfile_erb()
70
- path = vagrantfile_erb_path()
71
- @logger.info("Using #{path} to render Vangrantfile")
72
- File.read(vagrantfile_erb_path())
73
- end
74
-
75
- def vagrantfile_erb_path()
76
- erbs = [
77
- File.join(Dir.pwd, 'Vagrantfile.erb'),
78
- File.join(Dir.pwd, 'Vagrantfile'),
79
- File.expand_path('Vagrantfile.erb', template_dir())
80
- ]
81
-
82
- erbs.each do |erb|
83
- @logger.debug("Searching for #{erb}")
84
- return erb if File.exists?(erb)
85
- end
86
- # This should never happen
87
- raise 'Couldn\'t find a Vagrantfile.erb!'
88
- end
89
-
90
- def template_dir()
91
- File.join(File.expand_path(File.dirname(__FILE__)), 'templates')
92
- end
93
-
94
35
  end
95
36
  end
@@ -16,92 +16,53 @@ DaptivChefCI::Logger.init()
16
16
  class Vagrant
17
17
 
18
18
  # This class lets you define Rake tasks to drive Vagrant.
19
- #
20
- # @example Run the Python and NGinx cookbooks on a Linux guest
21
- # Vagrant::RakeTask.new do |task|
22
- # task.box_name = 'vagrant-FreeBSD'
23
- # task.run_list = [ 'python', 'nginx' ]
24
- # task.chef_repo_dir = '/Users/me/chef-repo'
25
- # end
26
- #
27
- # @example Run the Python and NGinx cookbooks on a Windows guest
28
- # Vagrant::RakeTask.new do |task|
29
- # task.guest_os = :windows
30
- # task.box_name = 'vagrant-windows-server-r2'
31
- # task.box_url = 'http://example.com/boxes/vagrant-windows-server-r2.box'
32
- # task.run_list = [ 'python', 'nginx' ]
33
- # task.chef_repo_dir = '/Users/me/chef-repo'
34
- # end
35
- #
36
19
  class RakeTask < ::Rake::TaskLib
37
20
  include ::Rake::DSL if defined? ::Rake::DSL
38
21
 
39
- attr_accessor :guest_os
40
- attr_accessor :box_url
41
- attr_accessor :box_name
42
- attr_accessor :run_list
43
- attr_accessor :node_name
44
- attr_accessor :chef_repo_dir
45
- attr_accessor :chef_json
46
-
47
22
  # @param [String] name The task name.
48
23
  # @param [String] desc Description of the task.
49
24
  def initialize(name = 'vagrant', desc = 'Daptiv Vagrant Tasks')
50
25
  @name, @desc = name, desc
51
- @guest_os = nil
52
- @box_url = nil
53
- @box_name = nil
54
- @run_list = []
55
- @node_name = nil
56
- @chef_repo_dir = nil
57
- @chef_json = nil
58
-
59
26
  yield self if block_given?
60
-
61
27
  define_task
62
28
  end
63
29
 
64
-
65
30
  private
66
31
 
67
32
  def define_task
68
33
  desc @desc
69
34
  task @name do
70
-
71
- options = {
72
- :guest_os => @guest_os,
73
- :box_url => @box_url,
74
- :box_name => @box_name,
75
- :run_list => @run_list,
76
- :node_name => @node_name,
77
- :chef_repo_dir => @chef_repo_dir,
78
- :chef_json => @chef_json }
79
-
80
- shell = DaptivChefCI::Shell.new()
81
- vagrant = DaptivChefCI::VagrantDriver.new(shell, options)
82
-
83
- vagrant.create_vagrantfile()
84
-
85
- begin
86
- vagrant.destroy()
87
- rescue SystemExit => ex
88
- exit(ex.status)
89
- rescue Exception => ex
90
- print_err(ex)
91
- end
92
-
93
- begin
94
- vagrant.up()
95
- rescue SystemExit => ex
96
- exit(ex.status)
97
- rescue Exception => ex
98
- print_err(ex)
99
- exit(1)
100
- ensure
101
- vagrant.halt()
102
- vagrant.destroy()
103
- end
104
-
35
+ vagrant = DaptivChefCI::VagrantDriver.new(DaptivChefCI::Shell.new())
36
+ execute_vagrant_run(vagrant)
37
+ end
38
+ end
39
+
40
+ def execute_vagrant_run(vagrant)
41
+ try_destroy_before_vagrant_up(vagrant)
42
+ try_vagrant_up(vagrant)
43
+ end
44
+
45
+ def try_destroy_before_vagrant_up(vagrant)
46
+ begin
47
+ vagrant.destroy()
48
+ rescue SystemExit => ex
49
+ exit(ex.status)
50
+ rescue Exception => ex
51
+ print_err(ex)
52
+ end
53
+ end
54
+
55
+ def try_vagrant_up(vagrant)
56
+ begin
57
+ vagrant.up()
58
+ rescue SystemExit => ex
59
+ exit(ex.status)
60
+ rescue Exception => ex
61
+ print_err(ex)
62
+ exit(1)
63
+ ensure
64
+ vagrant.halt()
65
+ vagrant.destroy()
105
66
  end
106
67
  end
107
68
 
@@ -23,10 +23,10 @@ describe DaptivChefCI::Logger, :unit => true do
23
23
  DaptivChefCI::Logger.init()
24
24
  end
25
25
 
26
- it 'should initialize logging to error by default' do
26
+ it 'should initialize logging to info by default' do
27
27
  DaptivChefCI::Logger.init()
28
28
  logger = Log4r::Logger.new("daptiv_chef_ci::logger_spec")
29
- expect(logger.level).to eq(4)
29
+ expect(logger.level).to eq(2)
30
30
  end
31
31
 
32
32
  it 'should initialize logging to the specified level' do
@@ -1,6 +1,7 @@
1
1
  require 'mocha/api'
2
2
  require 'daptiv-chef-ci/virtualbox_driver'
3
3
  require 'daptiv-chef-ci/logger'
4
+ require 'mixlib/shellout/exceptions'
4
5
  require 'bundler'
5
6
 
6
7
  describe DaptivChefCI::Shell, :unit => true do
@@ -13,6 +14,11 @@ describe DaptivChefCI::Shell, :unit => true do
13
14
  expect(out.count).to be > 1
14
15
  end
15
16
 
17
+ it 'should raise exception if exit status is non-zero' do
18
+ shell = DaptivChefCI::Shell.new()
19
+ expect { shell.exec_cmd('rm') }.to raise_error(Mixlib::ShellOut::ShellCommandFailed)
20
+ end
21
+
16
22
  it 'should revert path when method returns' do
17
23
  path_before = ENV['PATH']
18
24
  shell = DaptivChefCI::Shell.new()
@@ -6,45 +6,9 @@ describe DaptivChefCI::VagrantDriver, :unit => true do
6
6
 
7
7
  before(:each) do
8
8
  @shell = mock()
9
- @options = {}
10
- @vagrant = DaptivChefCI::VagrantDriver.new(@shell, @options)
9
+ @vagrant = DaptivChefCI::VagrantDriver.new(@shell)
11
10
  end
12
11
 
13
- describe 'render_vagrantfile' do
14
- it 'should default chef-repo dir to ~/src/chef-repo' do
15
- vagrantfile = @vagrant.render_vagrantfile()
16
- expect(vagrantfile).to include("chef_repo_dir = '#{ENV['HOME']}/src/chef-repo'")
17
- end
18
-
19
- it 'should not include box url when not set' do
20
- vagrantfile = @vagrant.render_vagrantfile()
21
- expect(vagrantfile).not_to include("config.vm.box_url")
22
- end
23
-
24
- it 'should include box url when set' do
25
- @options[:box_url] = 'http://example.com/boxes/freebsd.box'
26
- vagrantfile = @vagrant.render_vagrantfile()
27
- expect(vagrantfile).to include("config.vm.box_url = 'http://example.com/boxes/freebsd.box'")
28
- end
29
-
30
- it 'should include windows section when guest is set to windows' do
31
- @options[:guest_os] = :windows
32
- vagrantfile = @vagrant.render_vagrantfile()
33
- expect(vagrantfile).to include('config.vm.guest = :windows')
34
- expect(vagrantfile).to include('config.windows.halt_timeout = 15')
35
- expect(vagrantfile).to include('config.winrm.username = "vagrant"')
36
- expect(vagrantfile).to include('config.winrm.password = "vagrant"')
37
- expect(vagrantfile).to include('config.vm.network :forwarded_port, guest: 5985, host: 5985')
38
- end
39
-
40
- it 'should expand runlist' do
41
- @options[:run_list] = ['python', 'nginx']
42
- vagrantfile = @vagrant.render_vagrantfile()
43
- expect(vagrantfile).to include("chef.add_recipe 'python'")
44
- expect(vagrantfile).to include("chef.add_recipe 'nginx'")
45
- end
46
- end
47
-
48
12
  describe 'destroy' do
49
13
  it 'should force shutdown vagrant' do
50
14
  @shell.expects(:exec_cmd).with do |cmd|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daptiv-chef-ci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-22 00:00:00.000000000 Z
12
+ date: 2013-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: log4r
@@ -28,13 +28,13 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.1.10
30
30
  - !ruby/object:Gem::Dependency
31
- name: erubis
31
+ name: mixlib-shellout
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 2.7.0
37
+ version: 1.2.0
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 2.7.0
45
+ version: 1.2.0
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: rake
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -150,12 +150,13 @@ files:
150
150
  - Gemfile
151
151
  - lib/daptiv-chef-ci/logger.rb
152
152
  - lib/daptiv-chef-ci/shell.rb
153
- - lib/daptiv-chef-ci/templates/Vagrantfile.erb
154
153
  - lib/daptiv-chef-ci/vagrant_driver.rb
155
154
  - lib/daptiv-chef-ci/vagrant_task.rb
156
155
  - lib/daptiv-chef-ci/virtualbox_driver.rb
157
156
  - pkg/daptiv-chef-ci-0.0.1.gem
158
157
  - pkg/daptiv-chef-ci-0.0.2.gem
158
+ - pkg/daptiv-chef-ci-0.0.3.gem
159
+ - pkg/daptiv-chef-ci-0.0.4.gem
159
160
  - Rakefile
160
161
  - README.md
161
162
  - spec/daptiv-chef-ci/logger_spec.rb
@@ -177,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
178
  version: '0'
178
179
  segments:
179
180
  - 0
180
- hash: -504818496541812232
181
+ hash: -3669985751056624684
181
182
  required_rubygems_version: !ruby/object:Gem::Requirement
182
183
  none: false
183
184
  requirements:
@@ -186,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
187
  version: '0'
187
188
  segments:
188
189
  - 0
189
- hash: -504818496541812232
190
+ hash: -3669985751056624684
190
191
  requirements: []
191
192
  rubyforge_project:
192
193
  rubygems_version: 1.8.23
@@ -1,41 +0,0 @@
1
- # -*- mode: ruby -*-
2
- # vi: set ft=ruby :
3
-
4
- Vagrant.configure("2") do |config|
5
- chef_repo_dir = '<%= chef_repo_dir %>'
6
-
7
- config.berkshelf.enabled = true
8
-
9
- config.vm.box = '<%= box_name %>'
10
- <% if !box_url.nil? %>
11
- config.vm.box_url = '<%= box_url %>'
12
- <% end %>
13
-
14
- <% if guest_os == :windows %>
15
- config.vm.guest = :windows
16
-
17
- config.windows.halt_timeout = 15
18
- config.winrm.username = "vagrant"
19
- config.winrm.password = "vagrant"
20
-
21
- config.vm.network :forwarded_port, guest: 3389, host: 3389
22
- config.vm.network :forwarded_port, guest: 5985, host: 5985
23
- <% end %>
24
-
25
- config.vm.provision :chef_solo do |chef|
26
- chef.node_name = '<%= node_name %>'
27
- chef.log_level = :info
28
- chef.roles_path = File.join(chef_repo_dir, 'roles')
29
- chef.data_bags_path = File.join(chef_repo_dir, 'data_bags')
30
- chef.encrypted_data_bag_secret_key_path = '/etc/chef/encrypted_data_bag_secret'
31
- chef.add_recipe 'minitest-handler'
32
- <% run_list.each do |recipe| %>
33
- chef.add_recipe '<%= recipe %>'
34
- <% end %>
35
- <% if !chef_json.nil? %>
36
- chef.json = {
37
- <%= chef_json %>
38
- }
39
- <% end %>
40
- end
41
- end