chef-workflow 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.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .chef-workflow
19
+ html
20
+ tasks.txt
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ if ENV["ERIKH_LOCAL"]
4
+ gem "vagrant-prison", :path => "~/repos/ht/vagrant-prison"
5
+ end
6
+
7
+ # Specify your gem's dependencies in chef-workflow.gemspec
8
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Erik Hollensbe
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,161 @@
1
+ Chef Workflow Toolkit
2
+ ---------------------
3
+
4
+ This code is the common base of
5
+ [chef-workflow-tasklib](https://github.com/chef-workflow/chef-workflow-tasklib)
6
+ and
7
+ [chef-workflow-testlib](https://github.com/chef-workflow/chef-workflow-testlib).
8
+ Unless you are looking to create extensions to these two systems, or use the
9
+ libraries contained within, you would be better served (with rare exception) by
10
+ visiting these two projects for your testing and workflow needs.
11
+
12
+ Environment Variables
13
+ ---------------------
14
+
15
+ This toolkit exposes a number of environment variables that you may want to set
16
+ to affect your experience using it:
17
+
18
+ * `CHEF_WORKFLOW_DEBUG` - set to an integer of 1-3, controls the amount of
19
+ verbosity of reporting done in the libraries themselves. 1 usually amounts to
20
+ diagnostic messages, 2 to full transactions (converges, bootstraps, VM
21
+ provision detail), and 3 to more chatty individual pain points.
22
+ * `CHEF_CONFIG` - the path to your knife.rb. Note that if you've set this up in
23
+ `KnifeSupport` or with `configure_knife` you should almost never need this.
24
+ * `TEST_CHEF_SUBNET` - specifies a /24 network that IP addresses are drawn from
25
+ for local testing with VM systems. Note that this support is fairly crude --
26
+ it's strongly suggested you use a proper /24 and make your last octet `0`.
27
+ :)
28
+
29
+ Classes
30
+ -------
31
+
32
+ Expect this to be supplemented with linked RDoc that describes the API for each
33
+ class. For now, though, you'll have to generate the docs yourself or read the
34
+ source comments.
35
+
36
+ At the time of this writing there is not a very consistent namespacing method,
37
+ expect this to be corrected before the first release.
38
+
39
+ Utility libraries:
40
+ ==================
41
+
42
+ * `Chef::Workflow::ConfigureHelper` - a mixin which provides easy-to-use methods
43
+ of driving the various support configuration systems (see below).
44
+ * `AttrSupport` - a small mixin to supply chef-style instance variable mutators;
45
+ the kind that are a little more convenient to use with `instance_eval`'d
46
+ blocks.
47
+ * `DebugSupport` - mixin which defines a method called `if_debug` which is our
48
+ gating mechanism for the `CHEF_WORKFLOW_DEBUG` environment variable.
49
+ * `GenericSupport` - mixin which keeps the configuration interface consistent by
50
+ providing a `configure` class method that uses `instance_eval` and exposes a
51
+ pre-configured object under `singleton` which can be manipulated.
52
+ * `KnifePluginSupport` - mixin which contains a routine called
53
+ `init_knife_plugin` to simplify configuration of knife plugins, which can
54
+ then be used as normal objects. Also configures a UI object with `StringIO`
55
+ so that it can be communicated with optionally.
56
+
57
+ Configuration libraries:
58
+ ========================
59
+
60
+ These all mixin `GenericSupport` and as a result are expected to be treated as
61
+ singletons, by accessing their `singleton` class method and configured with the
62
+ `configure` class method which `instance_eval`'s a block.
63
+
64
+ If you are using `chef-workflow-tasklib`, most of the bits here as you have
65
+ configured them can be described to you via `bundle exec rake chef:show_config`.
66
+
67
+ * `GeneralSupport` - "General" configuration attributes that are global to the
68
+ entire system.
69
+ * `IPSupport` - Database for associating IP addresses with a server group. See
70
+ discussion on the scheduler below for more information on server groups. This
71
+ is generally not configured externally, but by tooling within the system.
72
+ * `KnifeSupport` - Most configuration regarding chef lives here, and additional
73
+ network access.
74
+ * `VagrantSupport` - Specific bits related to using Vagrant, such as the box to
75
+ be used for provisioning.
76
+ * `EC2Support` - bits related to driving AWS EC2.
77
+
78
+ Scheduler and VM
79
+ ----------------
80
+
81
+ The Scheduler and VM system work together to make groups of machines easy to
82
+ provision.
83
+
84
+ The scheduler is responsible for scheduling provisioning of groups of machines
85
+ which are interdependent with other machines. In other words when machine C
86
+ depends on B and A to be provisioned, and B and A have no dependencies, and
87
+ they are all scheduled at the same time, the scheduler will determine that A
88
+ and B have to be provisioned immediately and as soon as they are provisioned
89
+ successfully, it will attempt to provision C. Depending on the system
90
+ controlling the scheduler and its constraints, it can do this in a serial or
91
+ parallel fashion, the latter of which will attempt to provision as much as
92
+ possible at the same time, and as things finish will provision things that are
93
+ satisfied by what finished.
94
+
95
+ In other words, provisioning takes a lot of time in a test run, and the
96
+ scheduler tries very hard to make it take as little time as is reasonably
97
+ possible given your constraints and the constraints of the system.
98
+
99
+ It manages the actual act of provisioning through the VM system, which tracks
100
+ the state of what's currently provisioned, what has already successfully
101
+ provisioned (and presumed alive), and what is waiting to be provisoned. The VM
102
+ class itself is largely responsible for exposing this data to the scheduler,
103
+ and marshalling its state to disk in the event of a failure so things can be
104
+ cleaned up or resumed in the case of resources that will always be depended on
105
+ for a test run.
106
+
107
+ In other words, provisioning takes a lot of time in a test run, and the VM
108
+ system tries very hard to not add more time to this by tracking machines that
109
+ are already provisioned so they don't have to be re-provisioned, even between
110
+ runs. It also makes it easy to clean up a bad or stale test run.
111
+
112
+ Server Groups
113
+ =============
114
+
115
+ The VM system itself is a mapping of server groups to an array of provisioning
116
+ "commands", which are implemented as classes with a consistent interface
117
+ (visitors). A provisioning command may create a [vagrant
118
+ prison](https://github.com/chef-workflow/vagrant-prison) which contains all the
119
+ servers for that server group, complete with assigning them a host-only
120
+ interface and storing that with `IPSupport` so that it can be retrieved by
121
+ other bits of the test system or task system. Another provisioning command may
122
+ execute the in-code equivalent of `knife bootstrap` to build out your servers
123
+ with a role named after the server group. For de-provisioning, the provisioning
124
+ commands are played in reverse with a `shutdown` call applied to them.
125
+
126
+ Scheduler and VM libraries
127
+ ==========================
128
+
129
+ * `Scheduler` - this is the meat; if you're driving a new testing system such
130
+ as rspec, you'll want to get real familiar with the interface presented.
131
+ * `VM` - marshalling and delegation interface. Most of this is exposed to the
132
+ scheduler interface.
133
+ * `VM::VagrantProvisioner` - creates a vagrant prison composed of n servers for
134
+ a server group with a unique host-only ip for each server.
135
+ * `VM::EC2Provisioner` - creates a group of servers provisioned on EC2.
136
+ * `VM::KnifeProvisioner` - the provisioner equivalent of `knife bootstrap`, with
137
+ additional sanity checks for both converge success and a waiting period for
138
+ search indexing. On deprovision, deletes the nodes that were created. Will
139
+ always try to bootstrap a group in parallel.
140
+ * `VM::ChefServerProvisioner` - similar to `VM::KnifeProvisioner`, it wraps the
141
+ [knife-server](https://github.com/fnichol/knife-server) toolkit to create a
142
+ chef server.
143
+
144
+ Contributing
145
+ ------------
146
+
147
+ * fork the project
148
+ * make a branch
149
+ * add your stuff
150
+ * push your branch to your repo
151
+ * send a pull request
152
+
153
+ **Note:** modifications to gem metadata, author lists, and other credits
154
+ without rationale will be rejected immediately.
155
+
156
+ Credits
157
+ -------
158
+
159
+ This work was partially sponsored by [Hotel Tonight](http://hoteltonight.com)
160
+ and is what they use to test our infrastructure internally. Primarily authored by
161
+ [Erik Hollensbe](https://github.com/erikh).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rdoc/task'
3
+
4
+ RDoc::Task.new do |r|
5
+ r.main = "README.md"
6
+ r.rdoc_files.include("README.md", "LICENSE.txt", "lib/**/*.rb")
7
+ r.options << "--all"
8
+ end
@@ -0,0 +1,149 @@
1
+ #!ruby
2
+
3
+ require 'fileutils'
4
+
5
+ unless $stdin.tty?
6
+ $stderr.puts "Please run this from a terminal in your git repository's root."
7
+ exit 1
8
+ end
9
+
10
+ if ARGV[0] =~ /^--?h(?:elp)?$/
11
+ $stderr.puts 'Creates the necessary files needed for bootstrapping chef-workflow.'
12
+ $stderr.puts 'Ignores any files that already exist.'
13
+ exit 1
14
+ end
15
+
16
+ def create(filename, content)
17
+ print "Trying to create #{filename}..."
18
+ if File.exist?(filename)
19
+ puts "ignoring, file already exists."
20
+ else
21
+ FileUtils.mkdir_p(File.dirname(filename))
22
+ File.binwrite(filename, content)
23
+ puts "done."
24
+ end
25
+ end
26
+
27
+ RAKEFILE_CONTENT = <<-EOF
28
+ require 'chef-workflow-tasklib'
29
+ #
30
+ # If you want to change the tasks, remove this next line, and see the README:
31
+ #
32
+ # https://github.com/chef-workflow/chef-workflow-tasklib#picking-your-own-workflow
33
+ #
34
+ chef_workflow_task 'default'
35
+ EOF
36
+
37
+ CONFIG_CONTENT = <<-EOF
38
+ #
39
+ # chef-workflow configuration. You can inspect the full set of configured values
40
+ # with: `bundle exec rake chef:show_config`
41
+ #
42
+
43
+ #
44
+ # This is general configuration -- related to no specific component. Use with
45
+ # caution! Most of these settings don't need to be adjusted normally.
46
+ #
47
+
48
+ configure_general do
49
+ # change the location of the chef-workflow generated files
50
+ # workflow_dir File.join(Dir.pwd, '.chef-workflow')
51
+ #
52
+ # change the location of the VM database
53
+ # vm_file '.chef-workflow/vm'
54
+ #
55
+ # change the location of the chef-server prison file (vagrant only)
56
+ # chef_server_prison '.chef-workflow/chef-server'
57
+ #
58
+ # change the type of machine provisioner. You can use a class or :ec2 or
59
+ # :vagrant which map to the appropriate provisioner classes. If you use a
60
+ # custom class, make sure you require it first!
61
+ # machine_provisioner :vagrant
62
+ end
63
+
64
+ #
65
+ # This section configures all things related to vagrant usage
66
+ #
67
+ configure_vagrant do
68
+ # if you wish to use a different box, supply it as a url here.
69
+ # box_url "http://files.vagrantup.com/precise32.box"
70
+ end
71
+
72
+ configure_knife do
73
+ #
74
+ # you shouldn't need to modify most of these! be sure to 'bundle exec rake
75
+ # chef:show_config' to see the standard values, as well as others that are
76
+ # not listed here.
77
+ #
78
+ # cookbooks_path 'cookbooks'
79
+ # roles_path 'roles'
80
+ # environments_path 'environments'
81
+ # data_bags_path 'data_bags'
82
+ # ssh_user 'vagrant'
83
+ # ssh_password 'vagrant'
84
+ # ssh_identity_file nil
85
+ # use_sudo true
86
+ # test_environment 'vagrant'
87
+
88
+ # search_index_wait is used for provisioning with VM::KnifeProvisioner. After
89
+ # provisioning, it waits a set value of seconds (60 default) for the metadata
90
+ # to appear in chef's index. If this fails to appear in this time an
91
+ # exception will be thrown. If you have a slow chef server or find yourself
92
+ # hitting this limit a lot, increase this value.
93
+ #
94
+ # search_index_wait 60
95
+ end
96
+
97
+ #
98
+ # EC2 settings.
99
+ #
100
+ configure_ec2 do
101
+ #
102
+ # You'll want to heavily edit these if you use the EC2 support. Additionally,
103
+ # it is *strongly advised* to use a separate AWS account for your testing.
104
+ #
105
+ # The access key ID - no default, uses environment if it doesn't exist.
106
+ # access_key_id "my_access_key"
107
+ #
108
+ # The secret access key - no default, uses environment if it doesn't exist.
109
+ # secret_access_key "my_secret"
110
+ #
111
+ # The AMI of provisioned boxes - no default!
112
+ # ami "ami-abcdef123"
113
+ #
114
+ # The instance type of provisioned boxes - no default!
115
+ # instance_type "m1.small"
116
+ #
117
+ # The region where the instances should be allocated - no default!
118
+ # region "us-west-1"
119
+ #
120
+ # The ssh key used for creating machines (you still have to configure knife
121
+ # separately) - no default!
122
+ # ssh_key "test"
123
+ #
124
+ # The security groups to put all machines in; if set to :auto (the default),
125
+ # creates a new one until chef:clean is run.
126
+ # security_groups :auto
127
+ #
128
+ # The open ports in the security groups that are created dynamically. If you
129
+ # need something more complicated, create your own groups by hand and set
130
+ # `security_groups` above to those values.
131
+ # security_group_open_ports [22, 4000]
132
+ end
133
+
134
+ #
135
+ # This is largely important for local VM work. If you're using something like
136
+ # EC2 support (which determines its own IPs, for obvious reasons) these
137
+ # configuration settings are meaningless.
138
+ #
139
+ configure_ips do
140
+ # this is treated as a /24, walked incrementally, and with vagrant at least,
141
+ # .1 is spoken for. You'll want 0 as your last octet. Expect this to be less
142
+ # fail in the future. :)
143
+ #
144
+ # subnet "10.10.10.0"
145
+ end
146
+ EOF
147
+
148
+ create('Rakefile', RAKEFILE_CONTENT)
149
+ create('lib/chef-workflow-config.rb', CONFIG_CONTENT)
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chef-workflow/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "chef-workflow"
8
+ gem.version = Chef::Workflow::VERSION
9
+ gem.authors = ["Erik Hollensbe"]
10
+ gem.email = ["erik+github@hollensbe.org"]
11
+ gem.description = %q{A comprehensive rake-based workflow for chef}
12
+ gem.summary = %q{A comprehensive rake-based workflow for chef}
13
+ gem.homepage = "https://github.com/chef-workflow/chef-workflow"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'vagrant-prison', '~> 0.1.0'
21
+ gem.add_dependency 'chef', '~> 10.0'
22
+ gem.add_dependency 'aws-sdk', '~> 1.7.0'
23
+ gem.add_dependency 'net-ssh', '~> 2.6.0'
24
+
25
+ gem.add_development_dependency 'rdoc'
26
+ gem.add_development_dependency 'rake'
27
+ end
@@ -0,0 +1,73 @@
1
+ require "chef-workflow/version"
2
+
3
+ require 'chef-workflow/support/general'
4
+ require 'chef-workflow/support/knife'
5
+ require 'chef-workflow/support/vagrant'
6
+ require 'chef-workflow/support/ip'
7
+ require 'chef-workflow/support/debug'
8
+ require 'chef-workflow/support/ec2'
9
+
10
+ class Chef
11
+ module Workflow
12
+ #
13
+ # Basic helpers (intended to be mixed in elsewhere) to configure the
14
+ # various support configuration systems.
15
+ #
16
+ module ConfigureHelper
17
+ #
18
+ # Configure 'GeneralSupport'
19
+ #
20
+ def configure_general(&block)
21
+ GeneralSupport.configure(&block)
22
+ end
23
+
24
+ #
25
+ # Configure 'KnifeSupport'
26
+ #
27
+ def configure_knife(&block)
28
+ KnifeSupport.configure(&block)
29
+ end
30
+
31
+ #
32
+ # Configure 'VagrantSupport'
33
+ #
34
+ def configure_vagrant(&block)
35
+ VagrantSupport.configure(&block)
36
+ end
37
+
38
+ #
39
+ # Configure 'IPSupport' - you probably don't need to do this.
40
+ #
41
+ def configure_ips(&block)
42
+ IPSupport.configure(&block)
43
+ end
44
+
45
+ #
46
+ # Configure 'EC2Support'
47
+ #
48
+ def configure_ec2(&block)
49
+ EC2Support.configure(&block)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ class << eval("self", TOPLEVEL_BINDING)
56
+ include Chef::Workflow::ConfigureHelper
57
+ end
58
+
59
+ if defined? Rake::DSL
60
+ module Rake::DSL
61
+ include Chef::Workflow::ConfigureHelper
62
+ end
63
+ end
64
+
65
+ $:.unshift 'lib'
66
+
67
+ begin
68
+ require 'chef-workflow-config'
69
+ rescue LoadError
70
+ $stderr.puts "There is no chef-workflow-config in your lib directory."
71
+ $stderr.puts "Please run chef-workflow-bootstrap or add one."
72
+ end
73
+