vagrant-soa 0.3.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f9bad216eb549f706c4703ddce8629bf2bd37630
4
+ data.tar.gz: cde6e442ca52860d4b2ca09db2f50a62d25517dc
5
+ SHA512:
6
+ metadata.gz: f849a15385437ad9e59b00f21dbf9fce34413eb04b38f29567696e048b3a07e18c81757bfba4fe5e5acb9061b865802c107f32d9b70f96a4cac2c5078392afde
7
+ data.tar.gz: 3766e2e26edb30b200257f00941cff9f72d7e19a64161a546db69d0bc37733a08f6e9153f0928377a4ffad767c2552379f6fc874483bea1ca9cf145c46688061
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.rbc
2
+ .bundle
3
+ .config
4
+ .yardoc
5
+ Gemfile.lock
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ rdoc
12
+ spec/reports
13
+ test/tmp
14
+ test/version_tmp
15
+ tmp
16
+ pkg
17
+
18
+ # ignore vagrant directory
19
+ .vagrant
20
+
21
+ # ignore dev files
22
+ .SERVICES
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "vagrant", github: "mitchellh/vagrant"
7
+ gem "debugger"
8
+ end
9
+
10
+ group :plugins do
11
+ gem 'vagrant-puppet-fact-generator', :git => 'git@github.com:eventbrite/vagrant-puppet-fact-generator.git'
12
+ gem 'vagrant-puppet-module-registry', :git => 'git@github.com:eventbrite/vagrant-puppet-module-registry.git'
13
+ gem 'vagrant-soa', path: '.'
14
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Hahn
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # vagrant-soa
2
+
3
+ A [Vagrant](http://www.vagrantup.com/) plugin to handle our SOA infrastructre within vagrant.
4
+
5
+ ## Installation
6
+
7
+ ``` bash
8
+ vagrant plugin install vagrant-soa
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ This plugin allows you to specify one or more services to run within the VM. By
14
+ "services", we mean github repos that define puppet modules which can then be
15
+ included in the main manifest.
16
+
17
+ This structure allows developers of services to easily distribute services to
18
+ the rest of the team. Any changes to the service will be synced when users
19
+ provision.
20
+
21
+ Services are defined within the ``Vagrantfile``::
22
+
23
+ config.soa.services = {
24
+ 'example_service' => {
25
+ 'puppet_path' => 'services/example_service/puppet',
26
+ 'github_url' => 'git@github.com:eventbrite/vagrant-soa.git',
27
+ 'home_dir' => 'services/example_service',
28
+ 'branch' => 'test_branch',
29
+ },
30
+ }
31
+
32
+ The attributes of the service are optional, with the following defaults:
33
+
34
+ * puppet_path: The location of the puppet module from the root of the service
35
+ repository. If this isn't specified, we'll default to "puppet"
36
+ * github_url: The github url for the service. If this isn't provided, we'll
37
+ fallback to: #{config.soa.github_base}/#{service}.git
38
+ * branch: The specific branch we want to checkout. Defaults to "master".
39
+ * home_dir: The home directory of the service. This is useful if the service
40
+ isn't contained within its own repo.
41
+
42
+ ## Development
43
+
44
+ ``` bash
45
+ $ bundle
46
+ $ bundle exec vagrant up
47
+ ```
48
+
49
+ ## Contributing
50
+
51
+ 1. Create your feature branch (`git checkout -b my-new-feature`)
52
+ 2. Commit your changes (`git commit -am 'Add some feature'`)
53
+ 3. Push to the branch (`git push origin my-new-feature`)
54
+ 4. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/Vagrantfile ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+ # vi: set ft=ruby :
4
+
5
+ Vagrant.configure('2') do |config|
6
+ config.vm.box = 'precise64'
7
+ config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
8
+
9
+ config.soa.services = {
10
+ 'example_service' => {
11
+ 'puppet_path' => 'services/example_service/puppet',
12
+ 'github_url' => 'git@github.com:eventbrite/vagrant-soa.git'
13
+ },
14
+ }
15
+
16
+ config.vm.provision 'puppet' do |puppet|
17
+ puppet.manifests_path = 'manifests'
18
+ puppet.manifest_file = 'init.pp'
19
+ puppet.module_path = config.puppet_module_registry.get_puppet_module_paths()
20
+ end
21
+
22
+ end
@@ -0,0 +1,196 @@
1
+ require_relative '../errors'
2
+
3
+ module VagrantPlugins
4
+ module Soa
5
+ class Action
6
+ class InstallServices
7
+
8
+ def initialize(app, env)
9
+ @app = app
10
+ @env = env
11
+ @soa = env[:machine].config.soa
12
+ @puppet_fact_generator = env[:machine].config.puppet_fact_generator
13
+ @puppet_module_registry = env[:machine].config.puppet_module_registry
14
+ @git = get_local_git()
15
+ # we use the local_data_path of the machine since vagrant ensures it
16
+ # exists as well as mounts it to the VM for us.
17
+ @install_dir = env[:machine].env.local_data_path.join('services')
18
+ # this "/vagrant" dir is hard coded in vagrant as well:
19
+ # https://github.com/mitchellh/vagrant/blob/master/plugins/kernel_v2/config/vm.rb#L385-L389
20
+ @vagrant_install_dir = '/vagrant/.vagrant/services'
21
+ end
22
+
23
+ # Get the proper git to clone the service repos.
24
+ def get_local_git
25
+ git = `which git`.chomp
26
+ if git == ""
27
+ raise Soa::Errors::GitRequired.new
28
+ else
29
+ return git
30
+ end
31
+ end
32
+
33
+ def update_repo(service, target_branch, pwd, chdir_on_success=true)
34
+ # make sure the branch is up to date
35
+ updated = system "#{@git} pull --rebase"
36
+ if not updated
37
+ # pop back to the original directory
38
+ Dir.chdir pwd
39
+ raise Soa::Errors::UpdatingRepoFailed,
40
+ target_branch: target_branch,
41
+ service: service
42
+ else
43
+ # pop back to the original directory
44
+ if chdir_on_success
45
+ Dir.chdir pwd
46
+ end
47
+ @env[:ui].success(
48
+ "Successfully updated branch: #{target_branch} for #{service}"
49
+ )
50
+ end
51
+ end
52
+
53
+ # When installing a service we have to clone the service repository.
54
+ # Ideally, we would manage these modules with librarian-puppet and the
55
+ # Puppetfile, but because services depend on files that aren't
56
+ # contained within their puppet module (ie. requirements.txt or uwsgi
57
+ # handlers etc.), cloning the repo is the next best solution.
58
+ def clone_service_repo(service, config)
59
+ target_directory = File.join @install_dir, service
60
+
61
+ # make sure the repo is checked out
62
+ if File.directory? target_directory
63
+ @env[:ui].info "Service: #{service} is already checked out"
64
+ else
65
+ if not config['github_url'] || @soa.github_base
66
+ raise Soa::Errors::NoGithubUrlProvided,
67
+ service: service
68
+ end
69
+
70
+ github_target = config['github_url'] ? config['github_url'] : "#{@soa.github_base}/#{service}.git"
71
+ @env[:ui].info(
72
+ "Cloning service: #{service} (#{github_target}) to target directory:"\
73
+ " #{target_directory}"
74
+ )
75
+ success = system "#{@git} clone --recurse-submodules #{github_target} #{target_directory}"
76
+ if not success
77
+ raise Soa::Errors::CloningServiceFailed,
78
+ service: service
79
+ else
80
+ @env[:ui].success "Successfully checked out service: #{service}"
81
+ end
82
+ end
83
+
84
+ # move to the target_directory so we can examine it with git
85
+ pwd = Dir.pwd
86
+ Dir.chdir(target_directory)
87
+ update_repo = true
88
+
89
+ # don't attempt to auto-update if we've found any changes in the repo we
90
+ # already have checked out (stolen from boxen)
91
+ clean = `#{@git} status --porcelain`.empty?
92
+ current_branch = `#{@git} rev-parse --abbrev-ref HEAD`.chomp
93
+ fast_forwardable = `#{@git} rev-list --count origin/master..master`.chomp == '0'
94
+ if current_branch.empty?
95
+ ref = `#{@git} log -1 --pretty=format:%h`
96
+ @env[:ui].warn "#{service} not currently on any branch (ref: #{ref}), won't auto-update!"
97
+ update_repo = false
98
+ elsif !fast_forwardable
99
+ @env[:ui].warn "#{service}'s master branch is out of sync, won't auto-update!"
100
+ update_repo = false
101
+ elsif !clean
102
+ @env[:ui].warn "#{service} has a dirty tree, won't auto-update!"
103
+ update_repo = false
104
+ end
105
+
106
+ # make sure we're on the correct branch
107
+ target_branch = config.fetch('branch', 'master')
108
+ if !update_repo
109
+ # pop back to the original directory
110
+ Dir.chdir(pwd)
111
+ return target_directory
112
+ elsif target_branch != current_branch
113
+ # we have to pull first to ensure that we have all available branches
114
+ update_repo(service, current_branch, pwd, false)
115
+ checkout_target = system("#{@git} checkout #{target_branch}")
116
+ if not checkout_target
117
+ # pop back to the original directory
118
+ Dir.chdir(pwd)
119
+ raise Soa::Errors::BranchCheckoutFailed,
120
+ target_branch: target_branch,
121
+ service: service
122
+ else
123
+ @env[:ui].success(
124
+ "Successfully checked out branch: #{target_branch}"\
125
+ " for service #{service}"
126
+ )
127
+ end
128
+ end
129
+
130
+ if clean
131
+ update_repo(service, target_branch, pwd)
132
+ end
133
+ return target_directory
134
+ end
135
+
136
+ # When services are installed they can specify a 'home_dir' in their
137
+ # vagrant config. This needs to be a path that exists within the VM and
138
+ # points to their desired home directory.
139
+ #
140
+ # These custom facts will be of the form: "#{service}_home_dir"
141
+ def register_service_home_fact(service, config)
142
+ home_dir = config.fetch('home_dir', nil)
143
+ # not sure if there is a better way to do this in ruby, we don't want a
144
+ # trailing slash if "home_dir" is empty
145
+ if home_dir
146
+ full_path = File.join(
147
+ @vagrant_install_dir,
148
+ service,
149
+ home_dir
150
+ )
151
+ else
152
+ full_path = File.join(
153
+ @vagrant_install_dir,
154
+ service
155
+ )
156
+ end
157
+ if File.directory?(full_path)
158
+ @env[:ui].warn "Invalid home_dir passed for service:"\
159
+ " #{service}, home_dir: #{full_path}"
160
+ else
161
+ @puppet_fact_generator.add_fact("#{service}_home_dir", full_path)
162
+ end
163
+ end
164
+
165
+ # To install a service we clone the service repo and add the puppet
166
+ # path to @puppet_module_registry.puppet_module_paths.
167
+ def install_service(service, config)
168
+ target_directory = clone_service_repo(service, config)
169
+ puppet_path = config.fetch('puppet_path', 'puppet')
170
+ full_path = File.join(target_directory, puppet_path)
171
+ register_service_home_fact(service, config)
172
+ @puppet_module_registry.register_module_path(service, full_path)
173
+ end
174
+
175
+ # If any services are specified, install them
176
+ def install_services()
177
+ if @soa.services
178
+ @soa.services.each_pair do |service, config|
179
+ install_service(service, config)
180
+ end
181
+ end
182
+ end
183
+
184
+ def call(env)
185
+ # determine if provision is enabled, if we provided the
186
+ # "--no-provision" flag this would be false. if it isn't present, we
187
+ # should consider provision enabled
188
+ provision_enabled = env.has_key?(:provision_enabled) ? env[:provision_enabled] : true
189
+ install_services() if provision_enabled
190
+ @app.call(env)
191
+ end
192
+
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,36 @@
1
+ module VagrantPlugins
2
+ module Soa
3
+ class Config < Vagrant.plugin(2, :config)
4
+ attr_accessor :services
5
+ attr_accessor :github_base
6
+
7
+ def initialize
8
+ @services = UNSET_VALUE
9
+ @github_base = UNSET_VALUE
10
+ end
11
+
12
+ def finalize!
13
+ @services = nil if @services == UNSET_VALUE
14
+ @github_base = nil if @github_base == UNSET_VALUE
15
+ end
16
+
17
+ def validate(machine)
18
+ errors = []
19
+
20
+ if @services
21
+ if not @services.kind_of?(Hash)
22
+ errors << '`services` must be a hash of form service => {service config hash}'
23
+ end
24
+ @services.each_pair do |service, config|
25
+ if not config.kind_of?(Hash)
26
+ errors << "Invalid configuration for #{service}, config must be a hash, not #{config}"
27
+ end
28
+ end
29
+ end
30
+
31
+ return { 'soa' => errors }
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module VagrantPlugins
2
+ module Soa
3
+ module Errors
4
+
5
+ class GitRequired < Vagrant::Errors::VagrantError
6
+ error_key('git_required')
7
+ end
8
+
9
+ class UpdatingRepoFailed < Vagrant::Errors::VagrantError
10
+ error_key('git_update_failed')
11
+ end
12
+
13
+ class CloningServiceFailed < Vagrant::Errors::VagrantError
14
+ error_key('git_clone_failed')
15
+ end
16
+
17
+ class BranchCheckoutFailed < Vagrant::Errors::VagrantError
18
+ error_key('git_checkout_failed')
19
+ end
20
+
21
+ class NoGithubUrlProvided < Vagrant::Errors::VagrantError
22
+ error_key('missing_github_url')
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ begin
2
+ require 'vagrant'
3
+ rescue LoadError
4
+ abort 'vagrant-soa must be loaded in a Vagrant environment.'
5
+ end
6
+
7
+ begin
8
+ require 'vagrant-puppet-module-registry'
9
+ rescue LoadError
10
+ abort 'vagrant-soa depends on the `vagrant-puppet-module-registry` plugin.'
11
+ end
12
+
13
+ # Add our custom translations to the load path
14
+ I18n.load_path << File.expand_path("../../../locales/en.yml", __FILE__)
15
+
16
+ module VagrantPlugins
17
+ module Soa
18
+ class Plugin < Vagrant.plugin('2')
19
+ name 'vagrant-soa'
20
+ description <<-DESC
21
+ A Vagrant plugin to manage vagrant SOA infrastructure.
22
+ DESC
23
+
24
+ # define configs
25
+ config 'soa' do
26
+ require_relative 'config'
27
+ Config
28
+ end
29
+
30
+ # define hooks
31
+ action_hook 'install_services' do |hook|
32
+ require_relative 'actions/install_services'
33
+ # we need to install services before we AddModuleFacts
34
+ hook.before VagrantPlugins::PuppetModuleRegistry::Action::AddModuleFacts, Action::InstallServices
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module Soa
3
+ VERSION = "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ require "vagrant-soa/version"
2
+ require "vagrant-soa/plugin"
data/locales/en.yml ADDED
@@ -0,0 +1,15 @@
1
+ en:
2
+ vagrant:
3
+ errors:
4
+ git_required: |-
5
+ Please install `git` before continuing.
6
+ git_update_failed: |-
7
+ Error updating branch: '%{target_branch}' for '%{service}'.
8
+ git_clone_faield: |-
9
+ Error cloning service: '%{service}'.
10
+ git_checkout_failed: |-
11
+ Error checking out branch: '%{target_branch}' for '%{service}'.
12
+ missing_github_url: |-
13
+ No `github_url` specified for service: '%{service}'. Either
14
+ specify the `github_url` or set `cofing.soa.github_base` to
15
+ the organization's github.
data/manifests/init.pp ADDED
@@ -0,0 +1,6 @@
1
+ class dev {
2
+ notify { 'Development provision!':}
3
+ include example_service
4
+ }
5
+
6
+ include dev
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,3 @@
1
+ class example_service {
2
+ notify { 'including example service': }
3
+ }
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-soa/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vagrant-soa"
8
+ spec.version = VagrantPlugins::Soa::VERSION
9
+ spec.authors = ["Michael Hahn"]
10
+ spec.email = ["mhahn@eventbrite.com"]
11
+ spec.description = %q{Vagrant plugin to manage vagrant SOA infrastructure.}
12
+ spec.summary = spec.description
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-soa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Hahn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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: Vagrant plugin to manage vagrant SOA infrastructure.
42
+ email:
43
+ - mhahn@eventbrite.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - Vagrantfile
54
+ - lib/vagrant-soa.rb
55
+ - lib/vagrant-soa/actions/install_services.rb
56
+ - lib/vagrant-soa/config.rb
57
+ - lib/vagrant-soa/errors.rb
58
+ - lib/vagrant-soa/plugin.rb
59
+ - lib/vagrant-soa/version.rb
60
+ - locales/en.yml
61
+ - manifests/init.pp
62
+ - pkg/vagrant-soa-0.1.0.gem
63
+ - pkg/vagrant-soa-0.2.0.gem
64
+ - pkg/vagrant-soa-0.2.1.gem
65
+ - pkg/vagrant-soa-0.3.0.gem
66
+ - services/example_service/puppet/example_service/manifests/init.pp
67
+ - vagrant-soa.gemspec
68
+ homepage: ''
69
+ licenses:
70
+ - MIT
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.0.3
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Vagrant plugin to manage vagrant SOA infrastructure.
92
+ test_files: []
93
+ has_rdoc: