gonzo 0.1.0 → 0.2.1

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: c6de463660b7b19173f1c55cc959da789352175e
4
- data.tar.gz: 5467643687ac220822d5401813c2871e669afe91
3
+ metadata.gz: 9073924988a4eece01433e99a9ebd3f969485d4d
4
+ data.tar.gz: 7db3c68d6a6cc4e5acbf49b3ea4b3fe12b5661c9
5
5
  SHA512:
6
- metadata.gz: b525b04275760a01f3ffdfbe2fa76a6a72beb05f5badb482e3ac43cc1dee28f9ac55e7878ab923ddcc2dfb0dd092f284bd18e38758f9b4dfe5693f700a5e7979
7
- data.tar.gz: d6de87214e480a3f41edb25b145d4591bb2a9c95e0adf9176e32cf3d83467e264e8c59e7e155f972eb10f37fd250852c4f3626249488d0095c75883a58e634b8
6
+ metadata.gz: 69703ec5ea2d82fe6e7e9952ebe9b1637f2614ae41d77228cb355132b37f7250e4a9c04a37a8802c3fd3ebad84af352c1f6e60e5dec89b506c74f291d2e72c81
7
+ data.tar.gz: ccc1869b11e2ada68a2dd259726b57bcbab0dbdc273433b29e09c66bdecc855f34377ecd3c9fd972605e19ab54287368bbd549222d9516013848525a98e9adde
data/README.md CHANGED
@@ -22,7 +22,7 @@ gem 'gonzo'
22
22
 
23
23
  ## Usage
24
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:
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 providers are `vagrant` and `docker`. The top-level key will be the name of the provider. Here's an example `.gonzo.yml` that contains a single VM:
26
26
 
27
27
  ```yaml
28
28
  ---
@@ -83,7 +83,7 @@ Gonzo will aggregate the exit statuses from all VMs and exit 1 if any of them fa
83
83
 
84
84
  ### Commands
85
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:
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 `/gonzo` 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 `/gonzo` at the end of your run:
87
87
 
88
88
  ```yaml
89
89
  ---
@@ -94,9 +94,62 @@ Commands will be run sequentially inside the directory where your `.gonzo.yml` f
94
94
  commands:
95
95
  - 'puppet module install puppetlabs-strings'
96
96
  - 'puppet strings'
97
- - 'cp -r doc /vagrant'
97
+ - 'cp -r doc /gonzo'
98
98
  ```
99
99
 
100
100
  ### Environment Variables
101
101
 
102
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.
103
+
104
+ ## Providers
105
+
106
+ Gonzo has the ability to support multiple providers. Each provider defines the options available in `.gonzo.yml`. The working directory will be available in the VM/container at `/gonzo` but will build in `/tmp/gonzo` as to not make destructive changes to the project.
107
+
108
+ All providers implement the `env` and `commands` parameters.
109
+
110
+ - `env`: The `env` parameter takes a hash of variable names and values that should be available to the commands defined in the `commands` parameter.
111
+
112
+ - `commands`: The `commands` parameter takes an array of commands to be executed inside the VM/container.
113
+
114
+ When defining multiple execution environments with multiple providers, they will execute serially:
115
+
116
+ ```yaml
117
+ ---
118
+ docker:
119
+ image: 'centos:centos7'
120
+ env:
121
+ PUPPET_VERSION: '3.8.0'
122
+ commands:
123
+ - 'yum -y install rubygem-bundler'
124
+ - 'bundle install --path vendor'
125
+ - 'bundle exec rake spec'
126
+ vagrant:
127
+ box: 'puppetlabs/centos-7.0-64-puppet'
128
+ env:
129
+ PUPPET_VERSION: '4.1.0'
130
+ commands:
131
+ - 'puppet module install puppetlabs-strings'
132
+ - 'puppet strings'
133
+ - 'cp -r doc /gonzo'
134
+ ```
135
+
136
+ The example above will run the `docker` provider first, followed by the `vagrant` provider.
137
+
138
+ ### Docker
139
+
140
+ The Docker provider requires the `image` parameter to be defined in `.gonzo.yml`. This tells `docker` what image to run the commands in. If the image is not available, `docker` will try and download it.
141
+
142
+ #### Available Parameters:
143
+
144
+ - `image`: The image that `docker` should use to run the commands defined in the `commands` section.
145
+ - `user`: The user under which the commands defined in the `command` array should be run. This user must exist in the container for the command to succeed.
146
+
147
+ ### Vagrant
148
+
149
+ The Vagrant provider requires the `box` paramater to be defined in `.gonzo.yml`.
150
+
151
+ #### Available Parameters:
152
+
153
+ - `box`: The Vagrant box that should be used.
154
+ - `box_url`: The URL for the Vagrant box specified in the `box` parameter. If the `box` is not available on the system, this tells Vagrant where to download the box from.
155
+ i
data/bin/gonzo CHANGED
@@ -4,4 +4,6 @@ require 'gonzo'
4
4
 
5
5
  project = ARGV.last || '.'
6
6
 
7
- Gonzo::Runner.new(Gonzo.config('.')).run
7
+ Dir.chdir(project) do
8
+ Gonzo::Runner.new(Gonzo.config(project)).run
9
+ end
@@ -1,26 +1,37 @@
1
1
  require 'gonzo/runner'
2
2
 
3
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
4
+ class << self
5
+ def config(path = '.')
6
+ return @config if @config
7
+ project = File.expand_path(path)
8
+ config_file = File.join(project, '.gonzo.yml')
9
+ fail "No .gonzo.yml found in #{project}!" unless File.exist?(config_file)
10
+ data = YAML.load_file(config_file)
11
+ data['gonzo'] = global_defaults.merge data['gonzo'] || {}
12
+ data['gonzo']['project'] = project
13
+ data['gonzo']['statedir'] = "#{project}/.gonzo"
14
+ @config = data
15
+ end
15
16
 
16
- def self.reload!
17
- @config = nil
18
- end
17
+ def reload!
18
+ @config = nil
19
+ end
20
+
21
+ def global_defaults
22
+ {
23
+ 'stop_on_failure' => false,
24
+ 'cleanup' => true
25
+ }
26
+ end
27
+
28
+ def required_command(cmd)
29
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
30
+ bin = File.join(path, cmd)
31
+ return if File.executable?(bin) && !File.directory?(bin)
32
+ end
19
33
 
20
- def self.global_defaults
21
- {
22
- 'stop_on_failure' => false,
23
- 'cleanup' => true
24
- }
34
+ fail "Required command #{cmd} not found in $PATH!"
35
+ end
25
36
  end
26
37
  end
@@ -1 +1,2 @@
1
1
  require 'gonzo/providers/vagrant'
2
+ require 'gonzo/providers/docker'
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+
3
+ module Gonzo
4
+ module Providers
5
+ class Abstract
6
+ def shellscript(provider_config)
7
+ script = []
8
+
9
+ script << '#!/bin/bash'
10
+ script << 'set -e'
11
+ script << 'set -x'
12
+ script << 'cp -r /gonzo /tmp/gonzo'
13
+ script << 'cd /tmp/gonzo'
14
+
15
+ if env = provider_config['env']
16
+ env.each do |k,v|
17
+ script << "export #{k}=\"#{v}\""
18
+ end
19
+ end
20
+
21
+ provider_config['commands'].each do |command|
22
+ script << command
23
+ end
24
+
25
+ script.join("\n")
26
+ end
27
+
28
+ def cleanup
29
+ FileUtils.rm_rf providerdir
30
+ end
31
+
32
+ def relative_providerdir
33
+ (providerdir.split('/') - global['project'].split('/')).join('/')
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,50 @@
1
+ require 'gonzo/providers/abstract'
2
+
3
+ module Gonzo
4
+ module Providers
5
+ class Docker < Gonzo::Providers::Abstract
6
+ attr_reader :config, :providerdir, :global
7
+
8
+ def initialize(config, global)
9
+ @global = global
10
+ @providerdir = "#{global['statedir']}/provider/docker"
11
+
12
+ Gonzo.required_command 'docker'
13
+
14
+ if config.keys.include?('image')
15
+ @config = { 'default' => config }
16
+ else
17
+ @config = config
18
+ end
19
+ end
20
+
21
+ def provision(container, container_config)
22
+ FileUtils.mkdir_p(providerdir) unless File.directory?(providerdir)
23
+ local_script = "#{providerdir}/#{container}.sh"
24
+ relative_script = "#{relative_providerdir}/#{container}.sh"
25
+ if container_config['commands']
26
+ command = ['docker', 'run', "-v #{Dir.pwd}:/gonzo"]
27
+ command << "-u #{container_config['user']}" if container_config['user']
28
+ File.open(local_script, 'w') do |f|
29
+ f << shellscript(container_config)
30
+ end
31
+ FileUtils.chmod('+x', local_script)
32
+ command << "#{container_config['image']} /bin/bash /gonzo/#{relative_script}"
33
+ system command.join(' ')
34
+ else
35
+ fail "No provisioner commands given for #{container}!"
36
+ end
37
+ end
38
+
39
+ def run
40
+ exit_codes = []
41
+ config.each do |container, container_config|
42
+ exit_codes << provision(container, container_config)
43
+ end
44
+
45
+ return false if exit_codes.include?(false)
46
+ true
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,14 +1,16 @@
1
- require 'fileutils'
1
+ require 'gonzo/providers/abstract'
2
2
 
3
3
  module Gonzo
4
4
  module Providers
5
- class Vagrant
5
+ class Vagrant < Gonzo::Providers::Abstract
6
6
  attr_reader :config, :providerdir, :global
7
7
 
8
8
  def initialize(config, global)
9
9
  @global = global
10
10
  @providerdir = "#{global['statedir']}/provider/vagrant"
11
11
 
12
+ Gonzo.required_command 'vagrant'
13
+
12
14
  if config.keys.include?('box')
13
15
  @config = { 'default' => config }
14
16
  else
@@ -21,28 +23,6 @@ module Gonzo
21
23
  FileUtils.rm_rf 'Vagrantfile'
22
24
  end
23
25
 
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
26
  def vagrantfile
47
27
  vf = []
48
28
 
@@ -53,6 +33,7 @@ module Gonzo
53
33
  vf << " config.vm.define :#{name} do |#{name}|"
54
34
  vf << " #{name}.vm.box = '#{conf['box']}'"
55
35
  vf << " #{name}.vm.box_url = '#{conf['box_url']}'" if conf['box_url']
36
+ vf << " #{name}.vm.synced_folder '.', '/gonzo'"
56
37
  vf << ' end'
57
38
  end
58
39
 
@@ -68,20 +49,17 @@ module Gonzo
68
49
  system "vagrant up #{box}"
69
50
  end
70
51
 
71
- def relative_providerdir
72
- (providerdir.split('/') - global['project'].split('/')).join('/')
73
- end
74
-
75
52
  def provision(box, box_config)
76
53
  FileUtils.mkdir_p(providerdir) unless File.directory?(providerdir)
77
54
  local_script = "#{providerdir}/#{box}.sh"
78
55
  relative_script = "#{relative_providerdir}/#{box}.sh"
79
56
  if box_config['commands']
80
57
  File.open(local_script, 'w') do |f|
81
- f << shellscript(box_config['commands'], box_config['env'])
58
+ f << shellscript(box_config)
82
59
  end
83
60
  FileUtils.chmod('+x', local_script)
84
- system "vagrant ssh #{box} -c /vagrant/#{relative_script}"
61
+ command = box_config['sudo'] ? "'sudo /gonzo/#{relative_script}'" : "/gonzo/#{relative_script}"
62
+ system "vagrant ssh #{box} -c #{command}"
85
63
  else
86
64
  fail "No provisioner commands given for #{box}!"
87
65
  end
@@ -12,7 +12,7 @@ module Gonzo
12
12
  end
13
13
 
14
14
  def supported_providers
15
- %w(vagrant)
15
+ %w(docker vagrant)
16
16
  end
17
17
 
18
18
  def providers
@@ -24,7 +24,7 @@ module Gonzo
24
24
  puts "Provider #{provider} is not implemented!"
25
25
  break
26
26
  end
27
- @providers << Gonzo::Providers::Vagrant.new(config, global)
27
+ @providers << Object.const_get("Gonzo::Providers::#{provider.capitalize}").new(config, global)
28
28
  end
29
29
  @providers
30
30
  end
@@ -1,3 +1,3 @@
1
1
  module Gonzo
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gonzo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Danzilio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-04 00:00:00.000000000 Z
11
+ date: 2015-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -52,6 +52,8 @@ files:
52
52
  - bin/gonzo
53
53
  - lib/gonzo.rb
54
54
  - lib/gonzo/providers.rb
55
+ - lib/gonzo/providers/abstract.rb
56
+ - lib/gonzo/providers/docker.rb
55
57
  - lib/gonzo/providers/vagrant.rb
56
58
  - lib/gonzo/rake_tasks.rb
57
59
  - lib/gonzo/runner.rb
@@ -81,4 +83,3 @@ signing_key:
81
83
  specification_version: 4
82
84
  summary: A simpler Muppet for simpler Puppets
83
85
  test_files: []
84
- has_rdoc: