soloist 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm ruby-1.8.7-p299@soloist
1
+ rvm --create ruby-1.9.3-p194@soloist
data/.travis.yml CHANGED
@@ -5,5 +5,5 @@ rvm:
5
5
  - rbx-19mode
6
6
  - rbx-18mode
7
7
  - jruby
8
- - ruby-head
8
+ # - ruby-head
9
9
  - ree
data/Gemfile.lock CHANGED
@@ -1,53 +1,58 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- soloist (0.9.4)
4
+ soloist (0.9.6)
5
5
  chef
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- bunny (0.7.6)
11
- chef (0.10.4)
10
+ bunny (0.8.0)
11
+ chef (10.12.0)
12
12
  bunny (>= 0.6.0)
13
13
  erubis
14
- highline
15
- json (>= 1.4.4, <= 1.5.2)
14
+ highline (>= 1.6.9)
15
+ json (>= 1.4.4, <= 1.6.1)
16
16
  mixlib-authentication (>= 1.1.0)
17
17
  mixlib-cli (>= 1.1.0)
18
18
  mixlib-config (>= 1.1.2)
19
19
  mixlib-log (>= 1.3.0)
20
+ mixlib-shellout
20
21
  moneta
21
- net-ssh (~> 2.1.3)
22
+ net-ssh (~> 2.2.2)
22
23
  net-ssh-multi (~> 1.1.0)
23
24
  ohai (>= 0.6.0)
24
25
  rest-client (>= 1.0.4, < 1.7.0)
25
26
  treetop (~> 1.4.9)
26
27
  uuidtools
28
+ yajl-ruby (~> 1.1)
27
29
  diff-lcs (1.1.2)
28
30
  erubis (2.7.0)
29
- highline (1.6.2)
30
- json (1.5.2)
31
- mime-types (1.16)
32
- mixlib-authentication (1.1.4)
31
+ highline (1.6.14)
32
+ ipaddress (0.8.0)
33
+ json (1.6.1)
34
+ mime-types (1.19)
35
+ mixlib-authentication (1.3.0)
33
36
  mixlib-log
34
37
  mixlib-cli (1.2.2)
35
38
  mixlib-config (1.1.2)
36
- mixlib-log (1.3.0)
39
+ mixlib-log (1.4.1)
40
+ mixlib-shellout (1.1.0)
37
41
  moneta (0.6.0)
38
- net-ssh (2.1.4)
42
+ net-ssh (2.2.2)
39
43
  net-ssh-gateway (1.1.0)
40
44
  net-ssh (>= 1.99.1)
41
45
  net-ssh-multi (1.1)
42
46
  net-ssh (>= 2.1.4)
43
47
  net-ssh-gateway (>= 0.99.0)
44
- ohai (0.6.8)
48
+ ohai (6.14.0)
49
+ ipaddress
45
50
  mixlib-cli
46
51
  mixlib-config
47
52
  mixlib-log
48
53
  systemu
49
54
  yajl-ruby
50
- polyglot (0.3.2)
55
+ polyglot (0.3.3)
51
56
  rake (0.8.7)
52
57
  rest-client (1.6.7)
53
58
  mime-types (>= 1.16)
@@ -59,12 +64,12 @@ GEM
59
64
  rspec-expectations (2.4.0)
60
65
  diff-lcs (~> 1.1.2)
61
66
  rspec-mocks (2.4.0)
62
- systemu (2.4.0)
67
+ systemu (2.5.2)
63
68
  treetop (1.4.10)
64
69
  polyglot
65
70
  polyglot (>= 0.3.1)
66
- uuidtools (2.1.2)
67
- yajl-ruby (1.0.0)
71
+ uuidtools (2.1.3)
72
+ yajl-ruby (1.1.0)
68
73
 
69
74
  PLATFORMS
70
75
  ruby
data/README.markdown CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://secure.travis-ci.org/mkocher/soloist.png)](http://travis-ci.org/mkocher/soloist)
2
+
1
3
  Soloist: Making chef-solo easier
2
4
  ================================
3
5
 
@@ -33,42 +35,39 @@ Example soloistrc Files
33
35
  directory layout:
34
36
 
35
37
  /Users/mkocher/workspace/project/soloistrc <-Config File
36
- /Users/mkocher/workspace/project/chef/
37
- /Users/mkocher/workspace/project/chef/cookbooks/pivotal_workstation/
38
+ /Users/mkocher/workspace/project/cookbooks/pivotal_workstation/
38
39
 
39
40
 
40
41
  soloistrc
41
42
  ---------
42
43
  cookbook_paths:
43
- - ./chef/cookbooks/
44
+ - ./cookbooks/
44
45
  recipes:
45
46
  - pivotal_workstation::ack
46
47
  - pivotal_workstation::bash_path_order
47
- - pivotal_workstation::bash_profile
48
48
  - pivotal_workstation::bash_profile-better_history
49
49
  - pivotal_workstation::defaults_fast_key_repeat_rate
50
- - pivotal_workstation::dock_preferences
51
- - pivotal_workstation::ec2_api_tools
52
50
  - pivotal_workstation::finder_display_full_path
53
- - pivotal_workstation::git
54
51
  - pivotal_workstation::git_config_global_defaults
55
52
  - pivotal_workstation::git_scripts
56
53
  - pivotal_workstation::google_chrome
57
54
  - pivotal_workstation::inputrc
58
- - pivotal_workstation::mysql
59
- - pivotal_workstation::osx_turn_on_locate
60
55
  - pivotal_workstation::rvm
61
- - pivotal_workstation::safari_preferences
62
- - pivotal_workstation::set_multitouch_preferences
63
- - pivotal_workstation::text_mate
64
- - pivotal_workstation::textmate_set_defaults
65
56
  - pivotal_workstation::turn_on_ssh
66
- - pivotal_workstation::user_owns_usr_local
67
- - pivotal_workstation::workspace_directory
57
+
58
+ Packaging Gems as Cookbooks (alpha)
59
+ ===========================
60
+
61
+ If you're a ruby developer, you're probably very comfortable wrangling gems. Bundler makes it easy to lock your dependencies and keep them in sync in all your environments. Soloist adds the ability to load cookbooks out of these gems. This means you can install the pivotal_workstation_cookbook gem, and add it to your soloistrc like so:
62
+
63
+ cookbook_gems:
64
+ - pivotal_workstation_cookbook
65
+
66
+ Easy cookbook dependency tracking, no more git cloning, no more chef recipes that aren't yours checked into your project and easy forking with bundler and github.
68
67
 
69
68
  Environment Variable Switching
70
69
  ==============================
71
- I'm trying out adding support in the soloistrc file for selecting recipes based on environment variables. Cap should allow setting environment variables fairly easily on deploy, and they can be set permanently on the machine if desired. To use these, add a env_variable_switches key to your soloistrc. They keys of the hash should be the environment variable you wish to change the configuration based on, and the value should be a hash keyed by the value of the variable. It's easier than it sounds - see the example below. (NB: Note that the CamelSnake is gone in the soloistrc, and while the basic config accepts the old keys, environment variable switching requires snake case keys)
70
+ The soloistrc file allows for selecting all options based on environment variables. Cap should allow setting environment variables fairly easily on deploy, and they can be set permanently on the machine if desired. To use these, add a env_variable_switches key to your soloistrc. They keys of the hash should be the environment variable you wish to change the configuration based on, and the value should be a hash keyed by the value of the variable. It's easier than it sounds - see the example below.
72
71
 
73
72
  cookbook_paths:
74
73
  - ./chef/cookbooks/
@@ -97,7 +96,7 @@ Log Level
97
96
  =========
98
97
  Soloist runs chef at log level info by default. Debug is very verbose, but makes debugging chef recipes much easier. Just set the LOG_LEVEL environment variable to 'debug' (or other valid chef log level) and it will be passed through.
99
98
 
100
- Local Overrides (experimental)
99
+ Local Overrides
101
100
  ==============================
102
101
  Soloist is an easy way to share configuration across workstations. If you want to have configuration in chef that you don't want to share with the rest of the project, you can create a soloistrc_local file in addition to the soloistrc file. This file will be processed after the soloistrc, and everything in it will be added to the run list. Be careful that you are clear what goes where - if it's a dependency of the project, it should be checked into the soloistrc file in the project.
103
102
 
data/bin/soloist CHANGED
@@ -19,7 +19,8 @@ end
19
19
  solo_rb = fileify(config_generator.solo_rb)
20
20
  metadata_json = fileify(config_generator.json_file)
21
21
 
22
- command = "sudo bash -c '#{config_generator.preserved_environment_variables_string} chef-solo -j #{metadata_json.path} -c #{solo_rb.path} -l #{log_level}'"
22
+ system "sudo mkdir -p /var/chef/cache" unless File.directory?("/var/chef/cache")
23
23
 
24
+ command = "sudo bash -c '#{config_generator.preserved_environment_variables_string} chef-solo -j #{metadata_json.path} -c #{solo_rb.path} -l #{log_level}'"
24
25
  puts "running chef: " + command
25
26
  system(command) || exit(1)
data/lib/soloist.rb CHANGED
@@ -3,7 +3,9 @@ require "json"
3
3
  require 'fileutils'
4
4
  require 'yaml'
5
5
  require 'tempfile'
6
+ require 'tmpdir'
7
+ require 'set'
6
8
 
7
9
  require File.join(File.dirname(__FILE__), 'soloist', 'util')
8
10
  require File.join(File.dirname(__FILE__), 'soloist', 'chef_config_generator')
9
-
11
+ require File.join(File.dirname(__FILE__), 'soloist', 'cookbook_gem_linker')
@@ -55,14 +55,11 @@ module Soloist
55
55
  end
56
56
 
57
57
  def solo_rb
58
- all_cookbook_paths = cookbook_paths
59
- cookbook_gems.each do |gem_cookbook|
60
- require gem_cookbook
61
- all_cookbook_paths << Kernel.const_get(camelize(gem_cookbook)).const_get('COOKBOOK_PATH')
62
- end
63
- "cookbook_path #{all_cookbook_paths.inspect}"
58
+ linker = CookbookGemLinker.new(cookbook_gems)
59
+ linker.link_gem_cookbooks
60
+ "cookbook_path #{(cookbook_paths+[linker.cookbook_gem_temp_dir]).inspect}"
64
61
  end
65
-
62
+
66
63
  def json_hash
67
64
  {
68
65
  "recipes" => @recipes
@@ -0,0 +1,54 @@
1
+ class CookbookGemLinker
2
+ include Soloist::Util
3
+ attr_reader :gems_and_dependencies
4
+ def initialize(gems=[])
5
+ @gems = gems
6
+ end
7
+
8
+ def link_gem_cookbooks
9
+ gems_and_dependencies.each do |gem_cookbook|
10
+ link_cookbook(gem_cookbook)
11
+ end
12
+ end
13
+
14
+ def gems_and_dependencies
15
+ unless @gems_and_dependencies
16
+ @gems_and_dependencies = Set.new
17
+ calculate_gems_and_dependencies
18
+ end
19
+ @gems_and_dependencies
20
+ end
21
+
22
+ def cookbook_gem_temp_dir
23
+ @cookbook_gem_temp_dir ||= Dir.mktmpdir
24
+ end
25
+
26
+ def path_to(gem_name)
27
+ require gem_name
28
+ path = Kernel.const_get(camelize(gem_name)).const_get('COOKBOOK_PATH')
29
+ end
30
+
31
+ def link_cookbook(gem_name)
32
+ File.symlink(path_to(gem_name), File.join(cookbook_gem_temp_dir, gem_name.chomp("_cookbook")))
33
+ end
34
+
35
+ private
36
+
37
+ def dependencies_of(gem_name)
38
+ if Gem::Specification.respond_to?(:find_by_name)
39
+ Gem::Specification.find_by_name(gem_name)
40
+ else
41
+ Gem.searcher.find(gem_name)
42
+ end.dependencies.map(&:name)
43
+ end
44
+
45
+ def calculate_gems_and_dependencies(gems=@gems)
46
+ gems.each do |gem_cookbook|
47
+ @gems_and_dependencies.add(gem_cookbook)
48
+ dependencies_of(gem_cookbook).each do |dependency|
49
+ @gems_and_dependencies.add(dependency)
50
+ calculate_gems_and_dependencies([dependency])
51
+ end
52
+ end
53
+ end
54
+ end
data/lib/soloist/util.rb CHANGED
@@ -6,6 +6,7 @@ module Soloist
6
6
 
7
7
  def fileify(contents)
8
8
  file = Tempfile.new("soloist")
9
+ puts "==== Temp File Contents ====\n#{contents}" if ENV['LOG_LEVEL'] == 'debug'
9
10
  file << contents
10
11
  file.flush
11
12
  file
@@ -1,3 +1,3 @@
1
1
  module Soloist
2
- VERSION = "0.9.6"
2
+ VERSION = "0.9.7"
3
3
  end
@@ -1,5 +1,4 @@
1
- require 'rspec'
2
- require File.dirname(__FILE__) + '/../lib/soloist'
1
+ require 'spec_helper'
3
2
 
4
3
  describe Soloist::ChefConfigGenerator do
5
4
  describe "generation" do
@@ -15,6 +14,7 @@ CONFIG
15
14
  @config = YAML.load(@config)
16
15
  FileUtils.stub(:pwd).and_return("/current/working/directory")
17
16
  @generator = Soloist::ChefConfigGenerator.new(@config, "../..")
17
+ mock_gem("pivotal_workstation_cookbook")
18
18
  end
19
19
 
20
20
  it "appends the current path and relative path to the cookbooks directory" do
@@ -26,20 +26,24 @@ CONFIG
26
26
  @generator = Soloist::ChefConfigGenerator.new(@config, "../..")
27
27
  @generator.cookbook_paths.should == ["/foo/bar"]
28
28
  end
29
-
30
- it "can generate a solo.rb contents" do
31
- module ::PivotalWorkstationCookbook
32
- COOKBOOK_PATH = "/var/lib/ruby/gems/pivotal_workstation/cookbooks/"
29
+
30
+ describe ".solo_rb" do
31
+ it "can generate a solo.rb contents" do
32
+ @generator.solo_rb.should =~ %r{cookbook_path \["/current/working/directory/../.././chef/cookbooks/"}
33
+ end
34
+
35
+ it "should include a tempdir with pivotal_workstation in it" do
36
+ @generator.solo_rb.match(%r{cookbook_path \[".*", "(.*)"\]})
37
+ File.exist?("#{$1}/pivotal_workstation").should be
33
38
  end
34
- @generator.solo_rb.should == 'cookbook_path ["/current/working/directory/../.././chef/cookbooks/", "/var/lib/ruby/gems/pivotal_workstation/cookbooks/"]'
35
39
  end
36
-
40
+
37
41
  it "can generate the json contents" do
38
42
  @generator.json_hash.should == {
39
43
  "recipes" => ['pivotal_workstation::ack']
40
44
  }
41
45
  end
42
-
46
+
43
47
  it "can generate json files" do
44
48
  JSON.parse(@generator.json_file).should == {
45
49
  "recipes" => ['pivotal_workstation::ack']
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe CookbookGemLinker do
4
+ let(:linker) { CookbookGemLinker.new(["pivotal_workstation_cookbook"]) }
5
+
6
+ describe ".cookbook_gem_temp_dir" do
7
+ it "returns a tmpdir" do
8
+ Dir.should_receive(:mktmpdir).once.and_return("/tmp/foo")
9
+ 2.times { linker.cookbook_gem_temp_dir.should == "/tmp/foo" }
10
+ end
11
+ end
12
+
13
+ describe ".path_to" do
14
+ it "returns the path to the gem" do
15
+ linker.path_to("pivotal_workstation_cookbook").should == File.expand_path('../..', __FILE__)
16
+ end
17
+ end
18
+
19
+ describe ".link_cookbook" do
20
+ it "creates a symbolic link in the tempdir" do
21
+ linker.link_cookbook("pivotal_workstation_cookbook")
22
+ File.exist?(File.expand_path('pivotal_workstation', linker.cookbook_gem_temp_dir)).should be
23
+ end
24
+ end
25
+
26
+ describe '.gems_and_dependencies' do
27
+ it "returns what you pass in dependencies" do
28
+ mock_gem("pivotal_workstation_cookbook")
29
+
30
+ linker.gems_and_dependencies.to_a.should == ["pivotal_workstation_cookbook"]
31
+ end
32
+
33
+ it "gets the dependencies from rubygems" do
34
+ mock_gem("pivotal_workstation_cookbook", ['osx_dmg_cookbook'])
35
+ mock_gem("osx_dmg_cookbook")
36
+
37
+ linker.gems_and_dependencies.to_a.should =~ ["pivotal_workstation_cookbook", 'osx_dmg_cookbook']
38
+ end
39
+
40
+ it "gets dependencies for dependencies" do
41
+ mock_gem("pivotal_workstation_cookbook", ['osx_dmg_cookbook'])
42
+ mock_gem("osx_dmg_cookbook", ["osx_installer_thing"])
43
+ mock_gem("osx_installer_thing")
44
+
45
+ linker.gems_and_dependencies.to_a.should =~ ["pivotal_workstation_cookbook", 'osx_dmg_cookbook', 'osx_installer_thing']
46
+ end
47
+
48
+ it "works on old rubygems" do
49
+ Gem::Specification.stub('respond_to?').with(:find_by_name).and_return(false)
50
+ Gem::Specification.should_receive(:find_by_name).exactly(0).times
51
+ mock_gem("pivotal_workstation_cookbook")
52
+
53
+ linker.gems_and_dependencies.to_a.should == ["pivotal_workstation_cookbook"]
54
+ end
55
+ end
56
+
57
+ describe ".link_gem_cookbooks" do
58
+ it "creates a directory of symlinks" do
59
+ mock_gem("pivotal_workstation_cookbook")
60
+ linker.link_gem_cookbooks
61
+ File.exist?(File.expand_path('pivotal_workstation', linker.cookbook_gem_temp_dir)).should be
62
+ end
63
+ end
64
+ end
@@ -1 +1,6 @@
1
- # this file is loaded by the tests instead of the actual pivotal_workstation_cookbook
1
+ # this file is loaded by the tests instead of the actual pivotal_workstation_cookbook
2
+
3
+ module PivotalWorkstationCookbook
4
+ COOKBOOK_PATH = File.expand_path('../..', __FILE__)
5
+ VERSION = "1.0.0"
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec'
2
+ require File.dirname(__FILE__) + '/../lib/soloist'
3
+
4
+ def mock_gem(name, dependencies=[])
5
+ mock_dependencies = dependencies.map { |depenency| mock(:name => depenency) }
6
+ mock_gemspec = mock("#{name} gemspec", :dependencies => mock_dependencies)
7
+ Gem::Specification.stub(:find_by_name).with(name).and_return(mock_gemspec)
8
+ Gem.stub(:searcher).and_return(mock({:find => mock_gemspec}))
9
+ end
data/spec/util_spec.rb CHANGED
@@ -1,5 +1,4 @@
1
- require 'rspec'
2
- require File.dirname(__FILE__) + '/../lib/soloist'
1
+ require 'spec_helper'
3
2
 
4
3
  describe Soloist::Util do
5
4
  class TestClass
metadata CHANGED
@@ -1,46 +1,40 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: soloist
3
- version: !ruby/object:Gem::Version
4
- hash: 55
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.7
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 9
9
- - 6
10
- version: 0.9.6
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Matthew Kocher
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-07-21 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-09-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: chef
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :runtime
33
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
34
30
  description: Soloist is an easy way of running chef solo, but it's not doing much.
35
- email:
31
+ email:
36
32
  - kocher@gmail.com
37
- executables:
33
+ executables:
38
34
  - soloist
39
35
  extensions: []
40
-
41
36
  extra_rdoc_files: []
42
-
43
- files:
37
+ files:
44
38
  - .gitignore
45
39
  - .rvmrc
46
40
  - .travis.yml
@@ -52,46 +46,42 @@ files:
52
46
  - bin/soloist
53
47
  - lib/soloist.rb
54
48
  - lib/soloist/chef_config_generator.rb
49
+ - lib/soloist/cookbook_gem_linker.rb
55
50
  - lib/soloist/util.rb
56
51
  - lib/soloist/version.rb
57
52
  - soloist.gemspec
58
53
  - spec/chef_config_generator_spec.rb
54
+ - spec/cookbook_gem_linker_spec.rb
59
55
  - spec/pivotal_workstation_cookbook.rb
56
+ - spec/spec_helper.rb
60
57
  - spec/util_spec.rb
61
58
  homepage: http://github.com/mkocher/soloist
62
59
  licenses: []
63
-
64
60
  post_install_message:
65
61
  rdoc_options: []
66
-
67
- require_paths:
62
+ require_paths:
68
63
  - lib
69
- required_ruby_version: !ruby/object:Gem::Requirement
64
+ required_ruby_version: !ruby/object:Gem::Requirement
70
65
  none: false
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- hash: 3
75
- segments:
76
- - 0
77
- version: "0"
78
- required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
71
  none: false
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- hash: 3
84
- segments:
85
- - 0
86
- version: "0"
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
87
76
  requirements: []
88
-
89
77
  rubyforge_project: soloist
90
- rubygems_version: 1.8.17
78
+ rubygems_version: 1.8.24
91
79
  signing_key:
92
80
  specification_version: 3
93
81
  summary: Soloist is a simple way of running chef-solo
94
- test_files:
82
+ test_files:
95
83
  - spec/chef_config_generator_spec.rb
84
+ - spec/cookbook_gem_linker_spec.rb
96
85
  - spec/pivotal_workstation_cookbook.rb
86
+ - spec/spec_helper.rb
97
87
  - spec/util_spec.rb