knife-solo 0.1.0.pre1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +1,39 @@
1
- # 0.1.0: In progress
1
+ # 0.1.0: January 12, 2013
2
2
 
3
- ## Goals
4
-
5
- * Cleaner bootstrap code
6
- * Local integration testing
7
- * Compatibility with plugins like knife-ec2
8
-
9
- # Not released yet
3
+ ## Changes and new features
10
4
 
11
5
  * Move all commands under "knife solo" namespace (#118)
12
6
  - Rename `knife kitchen` to `knife solo init`
13
7
  - Rename `knife wash_up` to `knife solo clean`
14
8
  * Add `knife solo bootstrap` command (#120)
9
+ * OmniOS support (#144)
15
10
  * Detect Fedora 17 (#141)
11
+ * Update chef-solo-search and add support of encrypted data bags (#127)
12
+ * Support Librarian (#36)
13
+ * Always install rsync from yum on RPM-based Linuxes (#157)
14
+ * Debian wheezy (7) support (#165)
15
+
16
+ ## Fixes
17
+
16
18
  * Improve help/error messages and validation (#142)
17
19
  * Fix exit status of "cook" if chef-solo fails (#97)
20
+ * Fix option passing to the Omnibus installer (#163)
21
+ * Other fixes: SuSE omnibus #146, #155, #158, #160, #164
22
+
23
+ ## Documentation
24
+
25
+ * Include documentation and tests in the gem (e01c23)
26
+ * [Home page](http://matschaffer.github.com/knife-solo/)
27
+ that reflects always the current release (#151)
18
28
 
19
29
  ## Thanks to our contributors!
20
30
 
21
31
  * [Marek Hulan][ares]
32
+ * [Anton Orel][skyeagle]
33
+ * [Adam Carlile][Frozenproduce]
34
+ * [Chris Lundquist][ChrisLundquist]
35
+ * [Hiten Parmar][hrp]
36
+ * [Patrick Connolly][patcon]
22
37
 
23
38
  # 0.0.15: November 29th, 2012
24
39
 
@@ -182,7 +197,9 @@ And a special thanks to [Teemu Matilainen][tmatilai] who is now on the list of d
182
197
  * Generate node config on prepare
183
198
  * Cook via rsync
184
199
 
200
+ [ChrisLundquist]:https://github.com/ChrisLundquist
185
201
  [DrGonzo65]: https://github.com/DrGonzo65
202
+ [Frozenproduce]: https://github.com/Frozenproduce
186
203
  [Motiejus]: https://github.com/Motiejus
187
204
  [Nix-wie-weg]: https://github.com/Nix-wie-weg
188
205
  [TylerRick]: https://github.com/TylerRick
@@ -195,10 +212,11 @@ And a special thanks to [Teemu Matilainen][tmatilai] who is now on the list of d
195
212
  [davidsch]: https://github.com/davidsch
196
213
  [deepak]: https://github.com/deepak
197
214
  [fnichol]: https://github.com/fnichol
198
- [funglaub]: https://github/funglaub
215
+ [funglaub]: https://github.com/funglaub
199
216
  [gregf]: https://github.com/gregf
200
217
  [gsterndale]: https://github.com/gsterndale
201
218
  [hectcastro]: https://github.com/hectcastro
219
+ [hrp]: https://github.com/hrp
202
220
  [jgarber]: https://github.com/jgarber
203
221
  [jgrevich]: https://github.com/jgrevich
204
222
  [natlownes]: https://github.com/natlownes
@@ -207,10 +225,11 @@ And a special thanks to [Teemu Matilainen][tmatilai] who is now on the list of d
207
225
  [pferdefleisch]: https://github.com/pferdefleisch
208
226
  [portertech]: https://github.com/portertech
209
227
  [retr0h]: https://github.com/retr0h
210
- [rmoriz]: http://github.com/rmoriz
228
+ [rmoriz]: https://github.com/rmoriz
211
229
  [rosstimson]: https://github.com/rosstimson
212
230
  [rubiojr]: https://github.com/rubiojr
213
231
  [ryandub]: https://github.com/ryandub
232
+ [skyeagle]: https://github.com/skyeagle
214
233
  [tmatilai]: https://github.com/tmatilai
215
234
  [vjpr]: https://github.com/vjpr
216
235
  [zeph]: https://github.com/zeph
@@ -1,11 +1,8 @@
1
1
  = knife-solo
2
2
 
3
- {<img src="https://secure.travis-ci.org/matschaffer/knife-solo.png" alt="Build Status" />}[http://travis-ci.org/matschaffer/knife-solo]
4
- {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/matschaffer/knife-solo]
5
-
6
3
  == DESCRIPTION:
7
4
 
8
- Knife-solo is a gem plugin for Chef's knife utility. It currently adds 5 subcommands to knife:
5
+ knife-solo adds a handful of commands that aim to make working with chef-solo as powerful as chef-server. It currently adds 5 subcommands to knife:
9
6
 
10
7
  - <tt>knife solo init</tt> is used to create a new directory structure (i.e. "kitchen") that fits with Chef's standard structure and can be used to build and store recipes.
11
8
 
@@ -27,13 +24,13 @@ Installation is a normal gem installation.
27
24
 
28
25
  If you need to install from git run:
29
26
 
30
- rake install
27
+ bundle && bundle exec rake install
31
28
 
32
29
  === Init command
33
30
 
34
31
  The init command simply takes a name of the directory to store the kitchen structure. Use "." to initialize the current directory.
35
32
 
36
- knife init mychefrepo
33
+ knife solo init mychefrepo
37
34
 
38
35
  Currently the directory structure looks like this, but could change as development continues.
39
36
 
data/Rakefile CHANGED
@@ -1,18 +1,63 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
3
 
4
+ MANIFEST_IGNORES = %w[
5
+ .travis.yml
6
+ .gitignore
7
+ Gemfile
8
+ Gemfile.lock
9
+ Manifest.txt
10
+ README.md
11
+ knife-solo.gemspec
12
+ script/newb
13
+ script/test
14
+ ]
15
+
4
16
  desc 'Updates Manifest.txt with a list of files from git'
5
17
  task :manifest do
6
18
  git_files = `git ls-files`.split("\n")
7
- ignored = %w(.gitignore Gemfile Gemfile.lock Manifest.txt knife-solo.gemspec script/newb script/test)
8
19
 
9
20
  File.open('Manifest.txt', 'w') do |f|
10
- f.puts (git_files - ignored).join("\n")
21
+ f.puts (git_files - MANIFEST_IGNORES).join("\n")
11
22
  end
12
23
  end
13
-
14
24
  task :release => :manifest
15
25
 
26
+ # Returns the parsed RDoc for a single file as HTML
27
+ # Somewhat gnarly, but does the job.
28
+ def parsed_rdoc file
29
+ options = RDoc::Options.new
30
+ options.template_dir = options.template_dir_for 'darkfish'
31
+
32
+ rdoc = RDoc::RDoc.current = RDoc::RDoc.new
33
+ rdoc.options = options
34
+ rdoc.generator = RDoc::Generator::Darkfish.new(options)
35
+ parsed = rdoc.parse_files([file])
36
+ parsed.first.description
37
+ end
38
+
39
+ desc 'Renerates gh-pages from project'
40
+ task 'gh-pages' do
41
+ require 'tmpdir'
42
+ gem 'rdoc'; require 'rdoc/rdoc'
43
+
44
+ Dir.mktmpdir do |clone|
45
+ sh "git clone -b gh-pages git@github.com:matschaffer/knife-solo.git #{clone}"
46
+ File.open(clone + "/index.html", 'w') do |f|
47
+ f.puts '---'
48
+ f.puts 'layout: default'
49
+ f.puts '---'
50
+ f.puts parsed_rdoc("README.rdoc")
51
+ end
52
+ rev = `git rev-parse HEAD`[0..7]
53
+ Dir.chdir(clone) do
54
+ sh "git commit --allow-empty -m 'Updated index from README.rdoc rev #{rev}' index.html"
55
+ sh "git push origin gh-pages"
56
+ end
57
+ end
58
+ end
59
+ task :release => 'gh-pages'
60
+
16
61
  namespace :test do
17
62
  Rake::TestTask.new(:integration) do |t|
18
63
  t.libs << "test"
@@ -23,6 +68,9 @@ namespace :test do
23
68
  t.libs << "test"
24
69
  t.test_files = FileList['test/*_test.rb']
25
70
  end
71
+
72
+ desc 'Run both unit and integration tests'
73
+ task :all => [:units, :integration]
26
74
  end
27
75
 
28
76
  desc "Alias for test:units"
@@ -70,22 +70,34 @@ module Lucene
70
70
  end
71
71
  end
72
72
  end
73
-
73
+
74
74
  # we don't support range matches
75
75
  # range of integers would be easy to implement
76
76
  # but string ranges are hard
77
77
  class FiledRange < Treetop::Runtime::SyntaxNode
78
78
  end
79
-
80
- class InclFieldRange < FieldRange
79
+
80
+ # we handle '[* TO *]' as a special case since it is common in
81
+ # cookbooks for matching the existence of keys
82
+ class InclFieldRange
83
+ def match(item)
84
+ field = self.elements[0].text_value
85
+ range_start = self.elements[1].transform
86
+ range_end = self.elements[2].transform
87
+ if range_start == "*" and range_end == "*"
88
+ !!item[field]
89
+ else
90
+ raise "Ranges not really supported yet"
91
+ end
92
+ end
81
93
  end
82
-
94
+
83
95
  class ExclFieldRange < FieldRange
84
96
  end
85
-
97
+
86
98
  class RangeValue < Treetop::Runtime::SyntaxNode
87
99
  end
88
-
100
+
89
101
  class FieldName < Treetop::Runtime::SyntaxNode
90
102
  def match( item )
91
103
  if self.text_value.count("_") > 0
@@ -95,7 +107,7 @@ module Lucene
95
107
  part = self.text_value.chomp("*")
96
108
  item.keys.collect{ |key| key.start_with?(part)? key: nil}.compact
97
109
  else
98
- if item.has_key?(self.text_value)
110
+ if item[self.text_value]
99
111
  [self.text_value,]
100
112
  else
101
113
  nil
@@ -109,13 +121,13 @@ module Lucene
109
121
  self.elements[0].match( item )
110
122
  end
111
123
  end
112
-
124
+
113
125
  class Group < Treetop::Runtime::SyntaxNode
114
126
  def match( item )
115
127
  self.elements[0].match(item)
116
128
  end
117
129
  end
118
-
130
+
119
131
  class BinaryOp < Treetop::Runtime::SyntaxNode
120
132
  def match( item )
121
133
  self.elements[1].match(
@@ -124,29 +136,29 @@ module Lucene
124
136
  )
125
137
  end
126
138
  end
127
-
139
+
128
140
  class OrOperator < Treetop::Runtime::SyntaxNode
129
141
  def match( cond1, cond2 )
130
142
  cond1 or cond2
131
143
  end
132
144
  end
133
-
145
+
134
146
  class AndOperator < Treetop::Runtime::SyntaxNode
135
147
  def match( cond1, cond2 )
136
148
  cond1 and cond2
137
149
  end
138
150
  end
139
-
151
+
140
152
  # we don't support fuzzy string matching
141
153
  class FuzzyOp < Treetop::Runtime::SyntaxNode
142
154
  end
143
-
155
+
144
156
  class BoostOp < Treetop::Runtime::SyntaxNode
145
157
  end
146
-
158
+
147
159
  class FuzzyParam < Treetop::Runtime::SyntaxNode
148
160
  end
149
-
161
+
150
162
  class UnaryOp < Treetop::Runtime::SyntaxNode
151
163
  def match( item )
152
164
  self.elements[0].match(
@@ -154,19 +166,19 @@ module Lucene
154
166
  )
155
167
  end
156
168
  end
157
-
169
+
158
170
  class NotOperator < Treetop::Runtime::SyntaxNode
159
171
  def match( cond )
160
172
  not cond
161
173
  end
162
174
  end
163
-
175
+
164
176
  class RequiredOperator < Treetop::Runtime::SyntaxNode
165
177
  end
166
-
178
+
167
179
  class ProhibitedOperator < Treetop::Runtime::SyntaxNode
168
180
  end
169
-
181
+
170
182
  class Phrase < Treetop::Runtime::SyntaxNode
171
183
  # a quoted ::Term
172
184
  def match( value )
@@ -195,7 +207,7 @@ class Query
195
207
  self.clean_tree(tree)
196
208
  tree
197
209
  end
198
-
210
+
199
211
  private
200
212
 
201
213
  def self.clean_tree(root_node)
@@ -0,0 +1,110 @@
1
+ #
2
+ # Copyright 2011, edelight GmbH
3
+ #
4
+ # Authors:
5
+ # Markus Korn <markus.korn@edelight.de>
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ if Chef::Config[:solo]
21
+
22
+ if (defined? require_relative).nil?
23
+ # defenition of 'require_relative' for ruby < 1.9, found on stackoverflow.com
24
+ def require_relative(relative_feature)
25
+ c = caller.first
26
+ fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/)
27
+ file = $`
28
+ if /\A\((.*)\)/ =~ file # eval, etc.
29
+ raise LoadError, "require_relative is called in #{$1}"
30
+ end
31
+ absolute = File.expand_path(relative_feature, File.dirname(file))
32
+ require absolute
33
+ end
34
+ end
35
+
36
+ require_relative 'parser.rb'
37
+
38
+ class Chef
39
+ module Mixin
40
+ module Language
41
+
42
+ # Overwrite the search method of recipes to operate locally by using
43
+ # data found in data_bags.
44
+ # Only very basic lucene syntax is supported and also sorting the result
45
+ # is not implemented, if this search method does not support a given query
46
+ # an exception is raised.
47
+ # This search() method returns a block iterator or an Array, depending
48
+ # on how this method is called.
49
+ def search(obj, query=nil, sort=nil, start=0, rows=1000, &block)
50
+ if !sort.nil?
51
+ raise "Sorting search results is not supported"
52
+ end
53
+ @_query = Query.parse(query)
54
+ if @_query.nil?
55
+ raise "Query #{query} is not supported"
56
+ end
57
+ @_result = []
58
+
59
+ case obj
60
+ when :node
61
+ search_nodes(start, rows, &block)
62
+ when :role
63
+ search_roles(start, rows, &block)
64
+ else
65
+ search_data_bag(obj, start, rows, &block)
66
+ end
67
+
68
+
69
+ if block_given?
70
+ pos = 0
71
+ while (pos >= start and pos < (start + rows) and pos < @_result.size)
72
+ yield @_result[pos]
73
+ pos += 1
74
+ end
75
+ else
76
+ return @_result.slice(start, rows)
77
+ end
78
+ end
79
+
80
+ def search_nodes(start, rows, &block)
81
+ Dir.glob(File.join(Chef::Config[:data_bag_path], "node", "*.json")).map do |f|
82
+ # parse and hashify the node
83
+ node = JSON.parse(IO.read(f))
84
+ if @_query.match(node.to_hash)
85
+ @_result << node
86
+ end
87
+ end
88
+ end
89
+
90
+ def search_roles(start, rows, &block)
91
+ raise "Role searching not implemented"
92
+ end
93
+
94
+ def search_data_bag(bag_name, start, rows, &block)
95
+ secret_path = Chef::Config[:encrypted_data_bag_secret]
96
+ data_bag(bag_name.to_s).each do |bag_item_id|
97
+ if secret_path && secret = Chef::EncryptedDataBagItem.load_secret(secret_path)
98
+ bag_item = Chef::EncryptedDataBagItem.load(bag_name, bag_item_id, secret)
99
+ else
100
+ bag_item = data_bag_item(bag_name.to_s, bag_item_id)
101
+ end
102
+ if @_query.match(bag_item)
103
+ @_result << bag_item
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -10,8 +10,8 @@ class Chef
10
10
  # Approach ported from spatula (https://github.com/trotter/spatula)
11
11
  # Copyright 2009, Trotter Cashion
12
12
  class SoloCook < Knife
13
- OMNIBUS_EMBEDDED_PATHS ||= ["/opt/chef/embedded/bin", "/opt/opscode/embedded/bin"]
14
- OMNIBUS_EMBEDDED_GEM_PATHS ||= ["/opt/chef/embedded/lib/ruby/gems/1.9.1", "/opt/opscode/embedded/lib/ruby/gems/1.9.1"]
13
+ OMNIBUS_EMBEDDED_PATHS ||= %w[/opt/chef/embedded/bin /opt/opscode/embedded/bin]
14
+ OMNIBUS_EMBEDDED_GEM_PATHS ||= %w[/opt/chef/embedded/lib/ruby/gems/1.9.1 /opt/opscode/embedded/lib/ruby/gems/1.9.1]
15
15
  CHEF_VERSION_CONSTRAINT ||= ">=0.10.4"
16
16
 
17
17
  include KnifeSolo::SshCommand
@@ -21,6 +21,8 @@ class Chef
21
21
 
22
22
  deps do
23
23
  require 'chef/cookbook/chefignore'
24
+ require 'librarian/action'
25
+ require 'librarian/chef'
24
26
  require 'pathname'
25
27
  KnifeSolo::SshCommand.load_deps
26
28
  KnifeSolo::NodeConfigCommand.load_deps
@@ -29,20 +31,17 @@ class Chef
29
31
  banner "knife solo cook [USER@]HOSTNAME [JSON] (options)"
30
32
 
31
33
  option :skip_chef_check,
32
- :long => '--skip-chef-check',
33
- :boolean => true,
34
- :description => "Skip the version check on the Chef gem"
34
+ :long => '--skip-chef-check',
35
+ :description => 'Skip the version check on the Chef gem'
35
36
 
36
37
  option :sync_only,
37
- :long => '--sync-only',
38
- :boolean => false,
39
- :description => "Only sync the cookbook - do not run Chef"
38
+ :long => '--sync-only',
39
+ :description => 'Only sync the cookbook - do not run Chef'
40
40
 
41
41
  option :why_run,
42
- :short => '-W',
43
- :long => '--why-run',
44
- :boolean => true,
45
- :description => "Enable whyrun mode"
42
+ :short => '-W',
43
+ :long => '--why-run',
44
+ :description => 'Enable whyrun mode'
46
45
 
47
46
  def run
48
47
  time('Run') do
@@ -50,6 +49,7 @@ class Chef
50
49
  Chef::Config.from_file('solo.rb')
51
50
  check_chef_version unless config[:skip_chef_check]
52
51
  generate_node_config
52
+ librarian_install
53
53
  rsync_kitchen
54
54
  add_patches
55
55
  cook unless config[:sync_only]
@@ -96,6 +96,17 @@ class Chef
96
96
  ui.msg "#{msg} finished in #{Time.now - start} seconds"
97
97
  end
98
98
 
99
+ def librarian_install
100
+ return unless File.exist? 'Cheffile'
101
+ Chef::Log.debug("Installing Librarian cookbooks")
102
+ Librarian::Action::Resolve.new(librarian_env).run
103
+ Librarian::Action::Install.new(librarian_env).run
104
+ end
105
+
106
+ def librarian_env
107
+ @librarian_env ||= Librarian::Chef::Environment.new
108
+ end
109
+
99
110
  def rsync_kitchen
100
111
  time('Rsync kitchen') do
101
112
  cmd = %Q{rsync -rl --rsh="ssh #{ssh_args}" --delete #{rsync_exclude.collect{ |ignore| "--exclude #{ignore} " }.join} ./ :#{adjust_rsync_path(chef_path)}}
@@ -23,8 +23,6 @@ class Chef
23
23
  end
24
24
  end
25
25
 
26
- private
27
-
28
26
  def create_cupboards(base, dirs)
29
27
  dirs.each do |dir|
30
28
  cupboard_dir = File.join(base, dir)
@@ -21,16 +21,16 @@ class Chef
21
21
  banner "knife solo prepare [USER@]HOSTNAME [JSON] (options)"
22
22
 
23
23
  option :omnibus_version,
24
- :long => "--omnibus-version VERSION",
25
- :description => "The version of Omnibus to install"
24
+ :long => '--omnibus-version VERSION',
25
+ :description => 'The version of Omnibus to install'
26
26
 
27
27
  option :omnibus_url,
28
- :long => "--omnibus-url URL",
29
- :description => "URL to download install.sh from"
28
+ :long => '--omnibus-url URL',
29
+ :description => 'URL to download install.sh from'
30
30
 
31
31
  option :omnibus_options,
32
- :long => "--omnibus-options \"-r -n\"",
33
- :description => "Pass options to the install.sh script"
32
+ :long => '--omnibus-options "OPTIONS"',
33
+ :description => 'Pass options to the install.sh script'
34
34
 
35
35
  def run
36
36
  validate!
@@ -57,7 +57,7 @@ module KnifeSolo
57
57
 
58
58
  def http_client_get_url(url, file)
59
59
  stream_command <<-BASH
60
- if which curl 2>/dev/null; then
60
+ if command -v curl >/dev/null 2>&1; then
61
61
  curl -L -o #{file} #{url}
62
62
  else
63
63
  wget -O #{file} #{url}
@@ -73,7 +73,7 @@ module KnifeSolo
73
73
  # `omnibus_version` is not provided.
74
74
  install_command = "sudo bash #{file}"
75
75
  install_command << " -v #{prepare.config[:omnibus_version]}" if prepare.config[:omnibus_version]
76
- install_command << " #{prepare.config[:options]}" if prepare.config[:options]
76
+ install_command << " #{prepare.config[:omnibus_options]}" if prepare.config[:omnibus_options]
77
77
 
78
78
  stream_command(install_command)
79
79
  end
@@ -81,7 +81,7 @@ module KnifeSolo
81
81
  def yum_omnibus_install
82
82
  omnibus_install
83
83
  # Make sure we have rsync on builds that don't include it by default
84
- # (for example Scientific Linux minimal)
84
+ # (for example Scientific Linux minimal, CentOS minimal)
85
85
  run_command("sudo yum -y install rsync")
86
86
  end
87
87
 
@@ -2,7 +2,7 @@ module KnifeSolo::Bootstraps
2
2
  class Linux < Base
3
3
 
4
4
  def issue
5
- prepare.run_command("cat /etc/issue").stdout.strip || perepare.run_command("lsb_release -d -s").stdout.strip
5
+ prepare.run_command("cat /etc/issue").stdout.strip || prepare.run_command("lsb_release -d -s").stdout.strip
6
6
  end
7
7
 
8
8
  def x86?
@@ -76,6 +76,8 @@ module KnifeSolo::Bootstraps
76
76
  {:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => "lenny"}
77
77
  when %r{Debian GNU/Linux 6}
78
78
  {:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => "squeeze"}
79
+ when %r{Debian GNU/Linux 7}
80
+ {:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => "wheezy"}
79
81
  when %r{Debian GNU/Linux wheezy}
80
82
  {:type => "debian_gem", :version => "wheezy"}
81
83
  when %r{Ubuntu}i
@@ -85,21 +87,21 @@ module KnifeSolo::Bootstraps
85
87
  version = run_command("lsb_release -cs").stdout.strip
86
88
  {:type => "debian_gem", :version => version}
87
89
  when %r{CentOS.*? 5}
88
- {:type => "omnibus", :version => "RHEL5"}
90
+ {:type => "yum_omnibus", :version => "RHEL5"}
89
91
  when %r{CentOS.*? 6}
90
- {:type => "omnibus", :version => "RHEL6"}
92
+ {:type => "yum_omnibus", :version => "RHEL6"}
91
93
  when %r{Red Hat Enterprise.*? 5}
92
- {:type => "omnibus", :version => "RHEL5"}
94
+ {:type => "yum_omnibus", :version => "RHEL5"}
93
95
  when %r{Red Hat Enterprise.*? 6}
94
- {:type => "omnibus", :version => "RHEL6"}
96
+ {:type => "yum_omnibus", :version => "RHEL6"}
95
97
  when %r{Fedora release.*? 15}
96
- {:type => "omnibus", :version => "FC15"}
98
+ {:type => "yum_omnibus", :version => "FC15"}
97
99
  when %r{Fedora release.*? 16}
98
- {:type => "omnibus", :version => "FC16"}
100
+ {:type => "yum_omnibus", :version => "FC16"}
99
101
  when %r{Fedora release.*? 17}
100
- {:type => "omnibus", :version => "FC17"}
102
+ {:type => "yum_omnibus", :version => "FC17"}
101
103
  when %r{Scientific Linux.*? 5}
102
- {:type => "omnibus", :version => "RHEL5"}
104
+ {:type => "yum_omnibus", :version => "RHEL5"}
103
105
  when %r{Scientific Linux.*? 6}
104
106
  {:type => "yum_omnibus", :version => "RHEL6"}
105
107
  when %r{SUSE Linux Enterprise Server 1[12]}
@@ -1,5 +1,5 @@
1
1
  module KnifeSolo
2
2
  def self.version
3
- '0.1.0.pre1'
3
+ '0.1.0'
4
4
  end
5
5
  end
@@ -12,23 +12,23 @@ module KnifeSolo
12
12
  deps { KnifeSolo::NodeConfigCommand.load_deps } unless @dependency_loader
13
13
 
14
14
  option :chef_node_name,
15
- :short => "-N NAME",
16
- :long => "--node-name NAME",
17
- :description => "The Chef node name for your new node"
15
+ :short => '-N NAME',
16
+ :long => '--node-name NAME',
17
+ :description => 'The Chef node name for your new node'
18
18
 
19
19
  option :run_list,
20
- :short => "-r RUN_LIST",
21
- :long => "--run-list RUN_LIST",
22
- :description => "Comma separated list of roles/recipes to put to node config (if it does not exist)",
23
- :proc => lambda { |o| o.split(/[\s,]+/) },
24
- :default => []
20
+ :short => '-r RUN_LIST',
21
+ :long => '--run-list RUN_LIST',
22
+ :description => 'Comma separated list of roles/recipes to put to node config (if it does not exist)',
23
+ :proc => lambda { |o| o.split(/[\s,]+/) },
24
+ :default => []
25
25
 
26
26
  option :first_boot_attributes,
27
- :short => "-j JSON_ATTRIBS",
28
- :long => "--json-attributes",
29
- :description => "A JSON string to be added to node config (if it does not exist)",
30
- :proc => lambda { |o| JSON.parse(o) },
31
- :default => {}
27
+ :short => '-j JSON_ATTRIBS',
28
+ :long => '--json-attributes',
29
+ :description => 'A JSON string to be added to node config (if it does not exist)',
30
+ :proc => lambda { |o| JSON.parse(o) },
31
+ :default => {}
32
32
  end
33
33
  end
34
34
 
@@ -22,29 +22,29 @@ module KnifeSolo
22
22
  deps { KnifeSolo::SshCommand.load_deps } unless @dependency_loader
23
23
 
24
24
  option :ssh_config,
25
- :short => "-F CONFIG_FILE",
26
- :long => "--ssh-config-file CONFIG_FILE",
27
- :description => "Alternate location for ssh config file"
25
+ :short => '-F CONFIG_FILE',
26
+ :long => '--ssh-config-file CONFIG_FILE',
27
+ :description => 'Alternate location for ssh config file'
28
28
 
29
29
  option :ssh_password,
30
- :short => "-P PASSWORD",
31
- :long => "--ssh-password PASSWORD",
32
- :description => "The ssh password"
30
+ :short => '-P PASSWORD',
31
+ :long => '--ssh-password PASSWORD',
32
+ :description => 'The ssh password'
33
33
 
34
34
  option :ssh_identity,
35
- :short => "-i FILE",
36
- :long => "--ssh-identity FILE",
37
- :description => "The ssh identity file"
35
+ :short => '-i FILE',
36
+ :long => '--ssh-identity FILE',
37
+ :description => 'The ssh identity file'
38
38
 
39
39
  option :ssh_port,
40
- :short => "-p PORT",
41
- :long => "--ssh-port PORT",
42
- :description => "The ssh port"
40
+ :short => '-p PORT',
41
+ :long => '--ssh-port PORT',
42
+ :description => 'The ssh port'
43
43
 
44
44
  option :startup_script,
45
- :short => "-s FILE",
46
- :long => "--startup-script FILE",
47
- :description => "The startup script on the remote server containing variable definitions"
45
+ :short => '-s FILE',
46
+ :long => '--startup-script FILE',
47
+ :description => 'The startup script on the remote server containing variable definitions'
48
48
  end
49
49
  end
50
50
 
@@ -8,7 +8,6 @@ module Apache2Bootstrap
8
8
 
9
9
  def test_apache2
10
10
  write_cheffile
11
- system "librarian-chef install >> #{log_file}"
12
11
  assert_subcommand "bootstrap --run-list=recipe[apache2]"
13
12
  assert_match default_apache_message, http_response
14
13
  end
@@ -11,16 +11,15 @@ module Apache2Cook
11
11
  end
12
12
 
13
13
  def http_response
14
- Net::HTTP.get(URI.parse("http://"+server.public_ip_address))
14
+ Net::HTTP.get(URI.parse("http://#{server.public_ip_address}"))
15
15
  end
16
16
 
17
17
  def default_apache_message
18
- /It works!/
18
+ /Apache Server/
19
19
  end
20
20
 
21
21
  def test_apache2
22
22
  write_cheffile
23
- system "librarian-chef install >> #{log_file}"
24
23
  write_nodefile(run_list: ["recipe[apache2]"])
25
24
  assert_subcommand "cook"
26
25
  assert_match default_apache_message, http_response
@@ -9,10 +9,6 @@ class Centos5_6Test < IntegrationTest
9
9
  "ami-3fe42456"
10
10
  end
11
11
 
12
- def default_apache_message
13
- /Apache 2 Test Page/
14
- end
15
-
16
12
  include EmptyCook
17
13
  include Apache2Cook
18
14
  include EncryptedDataBag
@@ -1,9 +1,8 @@
1
1
  require 'rubygems'
2
- require 'bundler'
2
+ require 'bundler/setup'
3
3
 
4
- Bundler.require
5
4
  require 'minitest/parallel'
6
- Bundler.require(:test)
5
+ require 'minitest/autorun'
7
6
 
8
7
  require 'pathname'
9
8
  $base_dir = Pathname.new(__FILE__).dirname
@@ -4,6 +4,7 @@ require 'support/validation_helper'
4
4
 
5
5
  require 'chef/cookbook/chefignore'
6
6
  require 'chef/knife/solo_cook'
7
+ require 'librarian/action/install'
7
8
 
8
9
  class SuccessfulResult
9
10
  def success?
@@ -38,6 +39,21 @@ class SoloCookTest < TestCase
38
39
  end
39
40
  end
40
41
 
42
+ def test_does_not_run_librarian_if_no_cheffile
43
+ in_kitchen do
44
+ Librarian::Action::Install.any_instance.expects(:run).never
45
+ command.librarian_install
46
+ end
47
+ end
48
+
49
+ def test_runs_librarian_if_cheffile_found
50
+ in_kitchen do
51
+ File.open("Cheffile", 'w') {}
52
+ Librarian::Action::Install.any_instance.expects(:run)
53
+ command.librarian_install
54
+ end
55
+ end
56
+
41
57
  def test_passes_node_name_to_chef_solo
42
58
  assert_chef_solo_option "--node-name=mynode", "-N mynode"
43
59
  end
@@ -1,4 +1,5 @@
1
1
  require 'yaml'
2
+ require 'fog'
2
3
 
3
4
  # A custom runner that serves as a common point for EC2 control
4
5
  class EC2Runner < MiniTest::Unit
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
- require 'bundler'
2
+ require 'bundler/setup'
3
3
 
4
- Bundler.require
5
- Bundler.require(:test)
4
+ require 'minitest/autorun'
5
+ require 'mocha/setup'
6
6
 
7
7
  require 'support/test_case'
metadata CHANGED
@@ -1,16 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-solo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre1
5
- prerelease: 6
4
+ version: 0.1.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Mat Schaffer
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-28 00:00:00.000000000 Z
12
+ date: 2013-01-12 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: rake
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -44,43 +60,101 @@ dependencies:
44
60
  - !ruby/object:Gem::Version
45
61
  version: '0'
46
62
  - !ruby/object:Gem::Dependency
47
- name: chef
63
+ name: rdoc
48
64
  requirement: !ruby/object:Gem::Requirement
49
65
  none: false
50
66
  requirements:
51
67
  - - ! '>='
52
68
  - !ruby/object:Gem::Version
53
- version: 0.10.10
54
- type: :runtime
69
+ version: '0'
70
+ type: :development
55
71
  prerelease: false
56
72
  version_requirements: !ruby/object:Gem::Requirement
57
73
  none: false
58
74
  requirements:
59
75
  - - ! '>='
60
76
  - !ruby/object:Gem::Version
61
- version: 0.10.10
77
+ version: '0'
62
78
  - !ruby/object:Gem::Dependency
63
- name: net-ssh
79
+ name: fog
64
80
  requirement: !ruby/object:Gem::Requirement
65
81
  none: false
66
82
  requirements:
67
83
  - - ! '>='
68
84
  - !ruby/object:Gem::Version
69
- version: 2.1.3
70
- - - <
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
71
92
  - !ruby/object:Gem::Version
72
- version: 2.3.0
73
- type: :runtime
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: minitest
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
74
103
  prerelease: false
75
104
  version_requirements: !ruby/object:Gem::Requirement
76
105
  none: false
77
106
  requirements:
78
107
  - - ! '>='
79
108
  - !ruby/object:Gem::Version
80
- version: 2.1.3
81
- - - <
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: parallel
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
82
116
  - !ruby/object:Gem::Version
83
- version: 2.3.0
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: chef
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '10.12'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '10.12'
142
+ - !ruby/object:Gem::Dependency
143
+ name: net-ssh
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 2.2.2
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 2.2.2
84
158
  - !ruby/object:Gem::Dependency
85
159
  name: librarian
86
160
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +184,7 @@ files:
110
184
  - lib/chef/knife/cook.rb
111
185
  - lib/chef/knife/kitchen.rb
112
186
  - lib/chef/knife/patches/parser.rb
113
- - lib/chef/knife/patches/search_patch.rb
187
+ - lib/chef/knife/patches/search.rb
114
188
  - lib/chef/knife/prepare.rb
115
189
  - lib/chef/knife/solo_bootstrap.rb
116
190
  - lib/chef/knife/solo_clean.rb
@@ -184,9 +258,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
184
258
  required_rubygems_version: !ruby/object:Gem::Requirement
185
259
  none: false
186
260
  requirements:
187
- - - ! '>'
261
+ - - ! '>='
188
262
  - !ruby/object:Gem::Version
189
- version: 1.3.1
263
+ version: '0'
190
264
  requirements: []
191
265
  rubyforge_project:
192
266
  rubygems_version: 1.8.24
@@ -233,3 +307,4 @@ test_files:
233
307
  - test/support/test_case.rb
234
308
  - test/support/validation_helper.rb
235
309
  - test/test_helper.rb
310
+ has_rdoc:
@@ -1,81 +0,0 @@
1
- #
2
- # Copyright 2011, edelight GmbH
3
- #
4
- # Authors:
5
- # Markus Korn <markus.korn@edelight.de>
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- if Chef::Config[:solo]
21
-
22
- if (defined? require_relative).nil?
23
- # defenition of 'require_relative' for ruby < 1.9, found on stackoverflow.com
24
- def require_relative(relative_feature)
25
- c = caller.first
26
- fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/)
27
- file = $`
28
- if /\A\((.*)\)/ =~ file # eval, etc.
29
- raise LoadError, "require_relative is called in #{$1}"
30
- end
31
- absolute = File.expand_path(relative_feature, File.dirname(file))
32
- require absolute
33
- end
34
- end
35
-
36
- require_relative 'parser.rb'
37
-
38
- class Chef
39
- class Recipe
40
-
41
- # Overwrite the search method of recipes to operate locally by using
42
- # data found in data_bags.
43
- # Only very basic lucene syntax is supported and also sorting the result
44
- # is not implemented, if this search method does not support a given query
45
- # an exception is raised.
46
- # This search() method returns a block iterator or an Array, depending
47
- # on how this method is called.
48
- def search(bag_name, query=nil, sort=nil, start=0, rows=1000, &block)
49
- if !sort.nil?
50
- raise "Sorting search results is not supported"
51
- end
52
- @_query = Query.parse(query)
53
- if @_query.nil?
54
- raise "Query #{query} is not supported"
55
- end
56
- if block_given?
57
- pos = 0
58
- else
59
- result = []
60
- end
61
- data_bag(bag_name.to_s).each do |bag_item_id|
62
- bag_item = data_bag_item(bag_name.to_s, bag_item_id)
63
- if @_query.match(bag_item)
64
- if block_given?
65
- if (pos >= start and pos < (start + rows))
66
- yield bag_item
67
- end
68
- pos += 1
69
- else
70
- result << bag_item
71
- end
72
- end
73
- end
74
- if !block_given?
75
- return result.slice(start, rows)
76
- end
77
- end
78
- end
79
- end
80
-
81
- end