gonzo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +102 -0
- data/bin/gonzo +7 -0
- data/lib/gonzo.rb +26 -0
- data/lib/gonzo/providers.rb +1 -0
- data/lib/gonzo/providers/vagrant.rb +116 -0
- data/lib/gonzo/rake_tasks.rb +10 -0
- data/lib/gonzo/runner.rb +55 -0
- data/lib/gonzo/version.rb +3 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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.
|
data/bin/gonzo
ADDED
data/lib/gonzo.rb
ADDED
@@ -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
|
data/lib/gonzo/runner.rb
ADDED
@@ -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
|
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:
|