gonzo 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c6de463660b7b19173f1c55cc959da789352175e
4
+ data.tar.gz: 5467643687ac220822d5401813c2871e669afe91
5
+ SHA512:
6
+ metadata.gz: b525b04275760a01f3ffdfbe2fa76a6a72beb05f5badb482e3ac43cc1dee28f9ac55e7878ab923ddcc2dfb0dd092f284bd18e38758f9b4dfe5693f700a5e7979
7
+ data.tar.gz: d6de87214e480a3f41edb25b145d4591bb2a9c95e0adf9176e32cf3d83467e264e8c59e7e155f972eb10f37fd250852c4f3626249488d0095c75883a58e634b8
@@ -0,0 +1,102 @@
1
+ [![Build Status](https://travis-ci.org/danzilio/gonzo.svg?branch=master)](https://travis-ci.org/danzilio/gonzo) [![Gem Version](https://badge.fury.io/rb/gonzo.svg)](http://badge.fury.io/rb/gonzo)
2
+
3
+ ![Gonzo](http://a.dilcdn.com/bl/wp-content/uploads/sites/2/2013/11/gonzo-and-camilla-the-chicken2.jpg)
4
+
5
+ Gonzo was inspired by [Beaker](https://github.com/puppetlabs/beaker), but is meant to be a little stupider. I set out to write Gonzo because I just wanted a way to spin up a VM or group of VMs programmatically and run ServerSpec tests on them. I wasn't interested in using the Beaker helpers or matchers. I just wanted something simple and agnostic. This is the hack that ensued.
6
+
7
+ ## Installation
8
+
9
+ Install the Gem with the `gem` command:
10
+
11
+ ```
12
+ gem install gonzo
13
+ ```
14
+
15
+ Or add it to your `Gemfile`:
16
+
17
+ ```ruby
18
+ source 'https://rubygems.org'
19
+
20
+ gem 'gonzo'
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ At the root of your project, you'll need to create a `.gonzo.yml` file. This is where you'll configure VMs for Gonzo. You'll need to configure a supported provider. As of right now, the only supported provider is `vagrant`. The top-level key will be the name of the provider. Here's an example `.gonzo.yml` that contains a single VM:
26
+
27
+ ```yaml
28
+ ---
29
+ vagrant:
30
+ box: 'puppetlabs/centos-7.0-64-puppet'
31
+ env:
32
+ PUPPET_VERSION: '4.1.0'
33
+ commands:
34
+ - 'sudo yum -y install git ruby-devel libxml2-devel'
35
+ - 'sudo gem install bundler'
36
+ - 'rm Gemfile.lock'
37
+ - 'bundle install --path vendor'
38
+ - 'bundle exec rake spec'
39
+ ```
40
+
41
+ You can configure multiple boxes to run serially by giving them a name:
42
+
43
+ ```yaml
44
+ ---
45
+ vagrant:
46
+ spec_tests:
47
+ box: 'puppetlabs/centos-7.0-64-puppet'
48
+ env:
49
+ PUPPET_VERSION: '4.1.0'
50
+ commands:
51
+ - 'sudo yum -y install git ruby-devel libxml2-devel'
52
+ - 'sudo gem install bundler'
53
+ - 'bundle install --path vendor'
54
+ - 'bundle exec rake spec'
55
+ acceptance_tests:
56
+ box: 'puppetlabs/centos-7.0-64-puppet'
57
+ env:
58
+ PUPPET_VERSION: '4.1.0'
59
+ commands:
60
+ - 'sudo yum -y install git ruby-devel libxml2-devel'
61
+ - 'sudo gem install bundler'
62
+ - 'bundle install --path vendor'
63
+ - 'bundle exec rake spec_prep'
64
+ - 'bundle exec puppet apply examples/init.pp --modulepath spec/fixtures/modules'
65
+ - 'bundle exec rake acceptance'
66
+ ```
67
+
68
+ Once you've configured a `.gonzo.yml` file, you'll need to include the Rake tasks in your `Rakefile` by adding this line:
69
+
70
+ ```ruby
71
+ require 'gonzo/rake_tasks'
72
+ ```
73
+
74
+ This will make the `gonzo` rake task available to you. You can run Gonzo by running `bundle exec rake gonzo`. This will start all of the VMs serially. If one VM fails, by default Gonzo will continue on to the next VM in the list. You can configure this in `.gonzo.yml` by setting `stop_on_failure` to `true` in the `gonzo` section of `.gonzo.yml`. For example:
75
+
76
+ ```yaml
77
+ ---
78
+ gonzo:
79
+ stop_on_failure: true
80
+ ```
81
+
82
+ Gonzo will aggregate the exit statuses from all VMs and exit 1 if any of them failed, or 0 if they all succeeded.
83
+
84
+ ### Commands
85
+
86
+ Commands will be run sequentially inside the directory where your `.gonzo.yml` file is. The `vagrant` provider copies the directory to `/tmp/gonzo` instead of running in `/vagrant` to avoid changing the project in flight. If you want to retrieve test results or generated binaries, simply add a command to copy them into `/vagrant` at the end of your run:
87
+
88
+ ```yaml
89
+ ---
90
+ vagrant:
91
+ box: 'puppetlabs/centos-7.0-64-puppet'
92
+ env:
93
+ PUPPET_VERSION: '4.1.0'
94
+ commands:
95
+ - 'puppet module install puppetlabs-strings'
96
+ - 'puppet strings'
97
+ - 'cp -r doc /vagrant'
98
+ ```
99
+
100
+ ### Environment Variables
101
+
102
+ The `env` key allows you to pass environment variables to your commands. The key must be the variable name, and the value the value you wish to assign to that variable.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
3
+ require 'gonzo'
4
+
5
+ project = ARGV.last || '.'
6
+
7
+ Gonzo::Runner.new(Gonzo.config('.')).run
@@ -0,0 +1,26 @@
1
+ require 'gonzo/runner'
2
+
3
+ module Gonzo
4
+ def self.config(path = '.')
5
+ return @config if @config
6
+ project = File.expand_path(path)
7
+ config_file = File.join(project, '.gonzo.yml')
8
+ fail "No .gonzo.yml found in #{project}!" unless File.exist?(config_file)
9
+ data = YAML.load_file(config_file)
10
+ data['gonzo'] = global_defaults.merge data['gonzo'] || {}
11
+ data['gonzo']['project'] = project
12
+ data['gonzo']['statedir'] = "#{project}/.gonzo"
13
+ @config = data
14
+ end
15
+
16
+ def self.reload!
17
+ @config = nil
18
+ end
19
+
20
+ def self.global_defaults
21
+ {
22
+ 'stop_on_failure' => false,
23
+ 'cleanup' => true
24
+ }
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ require 'gonzo/providers/vagrant'
@@ -0,0 +1,116 @@
1
+ require 'fileutils'
2
+
3
+ module Gonzo
4
+ module Providers
5
+ class Vagrant
6
+ attr_reader :config, :providerdir, :global
7
+
8
+ def initialize(config, global)
9
+ @global = global
10
+ @providerdir = "#{global['statedir']}/provider/vagrant"
11
+
12
+ if config.keys.include?('box')
13
+ @config = { 'default' => config }
14
+ else
15
+ @config = config
16
+ end
17
+ end
18
+
19
+ def cleanup
20
+ FileUtils.rm_rf File.join(global['project'], '.vagrant')
21
+ FileUtils.rm_rf 'Vagrantfile'
22
+ end
23
+
24
+ def shellscript(commands, env = nil)
25
+ script = []
26
+
27
+ script << '#!/bin/bash'
28
+ script << 'set -e'
29
+ script << 'set -x'
30
+ script << 'cp -r /vagrant /tmp/gonzo'
31
+ script << 'cd /tmp/gonzo'
32
+
33
+ if env
34
+ env.each do |k,v|
35
+ script << "export #{k}=\"#{v}\""
36
+ end
37
+ end
38
+
39
+ commands.each do |command|
40
+ script << command
41
+ end
42
+
43
+ script.join("\n")
44
+ end
45
+
46
+ def vagrantfile
47
+ vf = []
48
+
49
+ vf << 'VAGRANTFILE_API_VERSION = "2"'
50
+ vf << 'Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|'
51
+
52
+ config.each do |name,conf|
53
+ vf << " config.vm.define :#{name} do |#{name}|"
54
+ vf << " #{name}.vm.box = '#{conf['box']}'"
55
+ vf << " #{name}.vm.box_url = '#{conf['box_url']}'" if conf['box_url']
56
+ vf << ' end'
57
+ end
58
+
59
+ vf << 'end'
60
+
61
+ vf.join("\n")
62
+ end
63
+
64
+ def up(box)
65
+ File.open('Vagrantfile', 'w') do |f|
66
+ f << vagrantfile
67
+ end
68
+ system "vagrant up #{box}"
69
+ end
70
+
71
+ def relative_providerdir
72
+ (providerdir.split('/') - global['project'].split('/')).join('/')
73
+ end
74
+
75
+ def provision(box, box_config)
76
+ FileUtils.mkdir_p(providerdir) unless File.directory?(providerdir)
77
+ local_script = "#{providerdir}/#{box}.sh"
78
+ relative_script = "#{relative_providerdir}/#{box}.sh"
79
+ if box_config['commands']
80
+ File.open(local_script, 'w') do |f|
81
+ f << shellscript(box_config['commands'], box_config['env'])
82
+ end
83
+ FileUtils.chmod('+x', local_script)
84
+ system "vagrant ssh #{box} -c /vagrant/#{relative_script}"
85
+ else
86
+ fail "No provisioner commands given for #{box}!"
87
+ end
88
+ end
89
+
90
+ def down(box)
91
+ system "vagrant destroy -f #{box}"
92
+ end
93
+
94
+ def run
95
+ exit_codes = []
96
+ config.each do |box, box_config|
97
+ up(box)
98
+
99
+ begin
100
+ exit_codes << provision(box, box_config)
101
+ rescue Exception => e # We want to catch all exceptions here so we make sure we don't leave a VM hanging
102
+ puts "Exception caught! Cleaning up."
103
+ down(box)
104
+ puts e
105
+ return false
106
+ end
107
+
108
+ down(box)
109
+ end
110
+
111
+ return false if exit_codes.include?(false)
112
+ true
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,10 @@
1
+ require 'rake'
2
+ require 'gonzo'
3
+ require 'rake/tasklib'
4
+
5
+ desc "Run Gonzo"
6
+ task :gonzo do
7
+ config = Gonzo.config(Dir.pwd)
8
+ gonzo = Gonzo::Runner.new(config)
9
+ gonzo.run
10
+ end
@@ -0,0 +1,55 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+ require 'gonzo/providers'
4
+
5
+ module Gonzo
6
+ class Runner
7
+ attr_reader :statedir, :config, :global
8
+
9
+ def initialize(config)
10
+ @config = config
11
+ @global = config['gonzo']
12
+ end
13
+
14
+ def supported_providers
15
+ %w(vagrant)
16
+ end
17
+
18
+ def providers
19
+ return @providers if @providers
20
+ @providers = []
21
+ provs = config.select { |k,v| k unless k == 'gonzo' }
22
+ provs.each do |provider,config|
23
+ unless supported_providers.include?(provider)
24
+ puts "Provider #{provider} is not implemented!"
25
+ break
26
+ end
27
+ @providers << Gonzo::Providers::Vagrant.new(config, global)
28
+ end
29
+ @providers
30
+ end
31
+
32
+ def cleanup
33
+ return if global['cleanup'] == false
34
+ providers.each(&:cleanup)
35
+ FileUtils.rm_r global['statedir']
36
+ end
37
+
38
+ def run
39
+ exit_codes = []
40
+ providers.each do |provider|
41
+ status = provider.run
42
+
43
+ exit_codes << status
44
+
45
+ if config['gonzo']['stop_on_failure']
46
+ exit status unless status
47
+ end
48
+ end
49
+
50
+ status = exit_codes.include?(false) ? false : true
51
+ cleanup
52
+ exit status
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Gonzo
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gonzo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Danzilio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |2
42
+ This Gem lets you programmatically spin up a Vagrant box and run a set of
43
+ commands in the root of your project. This can be useful for running RSpec
44
+ or ServerSpec tests.
45
+ email: david@danzilio.net
46
+ executables:
47
+ - gonzo
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - README.md
52
+ - bin/gonzo
53
+ - lib/gonzo.rb
54
+ - lib/gonzo/providers.rb
55
+ - lib/gonzo/providers/vagrant.rb
56
+ - lib/gonzo/rake_tasks.rb
57
+ - lib/gonzo/runner.rb
58
+ - lib/gonzo/version.rb
59
+ homepage: https://github.com/danzilio/gonzo
60
+ licenses:
61
+ - Apache-2.0
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '2.0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: A simpler Muppet for simpler Puppets
83
+ test_files: []
84
+ has_rdoc: