knife-solo 0.0.3 → 0.0.4
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/lib/chef/knife/cook.rb +10 -1
- data/lib/chef/knife/kitchen.rb +2 -1
- data/lib/chef/knife/patches/parser.rb +211 -0
- data/lib/chef/knife/patches/search_patch.rb +81 -0
- data/lib/chef/knife/prepare.rb +0 -2
- data/lib/knife-solo/info.rb +3 -1
- metadata +14 -19
- data/lib/chef/knife/patches/data_bags_patch.rb +0 -42
data/lib/chef/knife/cook.rb
CHANGED
@@ -27,6 +27,8 @@ class Chef
|
|
27
27
|
|
28
28
|
add_patches
|
29
29
|
|
30
|
+
check_chef_version
|
31
|
+
|
30
32
|
logging_arg = "-l debug" if config[:verbosity] > 0
|
31
33
|
stream_command <<-BASH
|
32
34
|
sudo chef-solo -c #{chef_path}/solo.rb \
|
@@ -64,7 +66,6 @@ class Chef
|
|
64
66
|
Array(Chef::Config.cookbook_path).first + "/chef_solo_patches/libraries"
|
65
67
|
end
|
66
68
|
|
67
|
-
# TODO (mat): Let rsync write to /var/chef-solo with sudo somehow
|
68
69
|
def rsync_kitchen
|
69
70
|
system %Q{rsync -rlP --rsh="ssh #{ssh_args}" --delete --exclude '.*' ./ :#{chef_path}}
|
70
71
|
end
|
@@ -75,6 +76,14 @@ class Chef
|
|
75
76
|
system %Q{rsync -rlP --rsh="ssh #{ssh_args}" #{patch} :#{patch_path}}
|
76
77
|
end
|
77
78
|
end
|
79
|
+
|
80
|
+
def check_chef_version
|
81
|
+
constraint = "~>0.10.4"
|
82
|
+
result = run_command <<-BASH
|
83
|
+
ruby -rubygems -e "gem 'chef', '#{constraint}'"
|
84
|
+
BASH
|
85
|
+
raise "The chef gem on #{host} is out of date. Please run `#{$0} prepare #{ssh_args}` to upgrade Chef to #{constraint}." unless result.success?
|
86
|
+
end
|
78
87
|
end
|
79
88
|
end
|
80
89
|
end
|
data/lib/chef/knife/kitchen.rb
CHANGED
@@ -16,11 +16,12 @@ class Chef
|
|
16
16
|
mkdir name + "/site-cookbooks"
|
17
17
|
mkdir name + "/cookbooks"
|
18
18
|
File.open(name + "/solo.rb", 'w') do |f|
|
19
|
-
f << <<-RUBY.gsub(
|
19
|
+
f << <<-RUBY.gsub(/^ {12}/, '')
|
20
20
|
file_cache_path "/tmp/chef-solo"
|
21
21
|
data_bag_path "/tmp/chef-solo/data_bags"
|
22
22
|
cookbook_path [ "/tmp/chef-solo/site-cookbooks",
|
23
23
|
"/tmp/chef-solo/cookbooks" ]
|
24
|
+
role_path "/tmp/chef-solo/roles"
|
24
25
|
RUBY
|
25
26
|
end
|
26
27
|
end
|
@@ -0,0 +1,211 @@
|
|
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
|
+
require 'treetop'
|
21
|
+
require 'chef/solr_query/query_transform'
|
22
|
+
|
23
|
+
# mock QueryTransform such that we can access the location of the lucene grammar
|
24
|
+
class Chef
|
25
|
+
class SolrQuery
|
26
|
+
class QueryTransform
|
27
|
+
def self.base_path
|
28
|
+
class_variable_get(:@@base_path)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_flat_hash(hsh, prefix="")
|
35
|
+
result = {}
|
36
|
+
hsh.each_pair do |key, value|
|
37
|
+
if value.kind_of?(Hash)
|
38
|
+
result.merge!(build_flat_hash(value, "#{prefix}#{key}_"))
|
39
|
+
else
|
40
|
+
result[prefix+key] = value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
module Lucene
|
47
|
+
|
48
|
+
class Term < Treetop::Runtime::SyntaxNode
|
49
|
+
# compares a query value and a value, tailing '*'-wildcards are handled correctly.
|
50
|
+
# Value can either be a string or an array, all other objects are converted
|
51
|
+
# to a string and than checked.
|
52
|
+
def match( value )
|
53
|
+
if value.is_a?(Array)
|
54
|
+
value.any?{ |x| self.match(x) }
|
55
|
+
else
|
56
|
+
File.fnmatch(self.text_value, value.to_s)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Field < Treetop::Runtime::SyntaxNode
|
62
|
+
# simple field -> value matches, supporting tailing '*'-wildcards in keys
|
63
|
+
# as well as in values
|
64
|
+
def match( item )
|
65
|
+
keys = self.elements[0].match(item)
|
66
|
+
if keys.nil?
|
67
|
+
false
|
68
|
+
else
|
69
|
+
keys.any?{ |key| self.elements[1].match(item[key]) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# we don't support range matches
|
75
|
+
# range of integers would be easy to implement
|
76
|
+
# but string ranges are hard
|
77
|
+
class FiledRange < Treetop::Runtime::SyntaxNode
|
78
|
+
end
|
79
|
+
|
80
|
+
class InclFieldRange < FieldRange
|
81
|
+
end
|
82
|
+
|
83
|
+
class ExclFieldRange < FieldRange
|
84
|
+
end
|
85
|
+
|
86
|
+
class RangeValue < Treetop::Runtime::SyntaxNode
|
87
|
+
end
|
88
|
+
|
89
|
+
class FieldName < Treetop::Runtime::SyntaxNode
|
90
|
+
def match( item )
|
91
|
+
if self.text_value.count("_") > 0
|
92
|
+
item.merge!(build_flat_hash(item))
|
93
|
+
end
|
94
|
+
if self.text_value.end_with?("*")
|
95
|
+
part = self.text_value.chomp("*")
|
96
|
+
item.keys.collect{ |key| key.start_with?(part)? key: nil}.compact
|
97
|
+
else
|
98
|
+
if item.has_key?(self.text_value)
|
99
|
+
[self.text_value,]
|
100
|
+
else
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Body < Treetop::Runtime::SyntaxNode
|
108
|
+
def match( item )
|
109
|
+
self.elements[0].match( item )
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Group < Treetop::Runtime::SyntaxNode
|
114
|
+
def match( item )
|
115
|
+
self.elements[0].match(item)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class BinaryOp < Treetop::Runtime::SyntaxNode
|
120
|
+
def match( item )
|
121
|
+
self.elements[1].match(
|
122
|
+
self.elements[0].match(item),
|
123
|
+
self.elements[2].match(item)
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class OrOperator < Treetop::Runtime::SyntaxNode
|
129
|
+
def match( cond1, cond2 )
|
130
|
+
cond1 or cond2
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class AndOperator < Treetop::Runtime::SyntaxNode
|
135
|
+
def match( cond1, cond2 )
|
136
|
+
cond1 and cond2
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# we don't support fuzzy string matching
|
141
|
+
class FuzzyOp < Treetop::Runtime::SyntaxNode
|
142
|
+
end
|
143
|
+
|
144
|
+
class BoostOp < Treetop::Runtime::SyntaxNode
|
145
|
+
end
|
146
|
+
|
147
|
+
class FuzzyParam < Treetop::Runtime::SyntaxNode
|
148
|
+
end
|
149
|
+
|
150
|
+
class UnaryOp < Treetop::Runtime::SyntaxNode
|
151
|
+
def match( item )
|
152
|
+
self.elements[0].match(
|
153
|
+
self.elements[1].match(item)
|
154
|
+
)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class NotOperator < Treetop::Runtime::SyntaxNode
|
159
|
+
def match( cond )
|
160
|
+
not cond
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class RequiredOperator < Treetop::Runtime::SyntaxNode
|
165
|
+
end
|
166
|
+
|
167
|
+
class ProhibitedOperator < Treetop::Runtime::SyntaxNode
|
168
|
+
end
|
169
|
+
|
170
|
+
class Phrase < Treetop::Runtime::SyntaxNode
|
171
|
+
# a quoted ::Term
|
172
|
+
def match( value )
|
173
|
+
self.elements[0].match(value)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class Query
|
179
|
+
# initialize the parser by using the grammar shipped with chef
|
180
|
+
@@grammar = File.join(Chef::SolrQuery::QueryTransform.base_path, "lucene.treetop")
|
181
|
+
Treetop.load(@@grammar)
|
182
|
+
@@parser = LuceneParser.new
|
183
|
+
|
184
|
+
def self.parse(data)
|
185
|
+
# parse the query into a query tree
|
186
|
+
if data.nil?
|
187
|
+
data = "*:*"
|
188
|
+
end
|
189
|
+
tree = @@parser.parse(data)
|
190
|
+
if tree.nil?
|
191
|
+
msg = "Parse error at offset: #{@@parser.index}\n"
|
192
|
+
msg += "Reason: #{@@parser.failure_reason}"
|
193
|
+
raise "Query #{data} is not supported: #{msg}"
|
194
|
+
end
|
195
|
+
self.clean_tree(tree)
|
196
|
+
tree
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
def self.clean_tree(root_node)
|
202
|
+
# remove all SyntaxNode elements from the tree, we don't need them as
|
203
|
+
# the related ruby class already knowns what to do.
|
204
|
+
return if root_node.elements.nil?
|
205
|
+
root_node.elements.delete_if do |node|
|
206
|
+
node.class.name == "Treetop::Runtime::SyntaxNode"
|
207
|
+
end
|
208
|
+
root_node.elements.each { |node| self.clean_tree(node) }
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
@@ -0,0 +1,81 @@
|
|
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
|
data/lib/chef/knife/prepare.rb
CHANGED
@@ -30,7 +30,6 @@ class Chef
|
|
30
30
|
@packages.join(' ')
|
31
31
|
end
|
32
32
|
|
33
|
-
# TODO (mat): integration test this, not a gem install
|
34
33
|
def emerge_gem_install
|
35
34
|
ui.msg("Installing required packages...")
|
36
35
|
run_command("sudo USE='-test' ACCEPT_KEYWORDS='~amd64' emerge -u chef")
|
@@ -51,7 +50,6 @@ class Chef
|
|
51
50
|
raise result.stderr unless result.success? || result.stdout.match(installed)
|
52
51
|
end
|
53
52
|
|
54
|
-
# TODO (mat): integration test this, will probably break without sudo
|
55
53
|
def rpm_gem_install
|
56
54
|
ui.msg("Installing required packages...")
|
57
55
|
@packages = %w(ruby ruby-shadow gcc gcc-c++ ruby-devel wget rsync)
|
data/lib/knife-solo/info.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-solo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-10-07 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70138524107880 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70138524107880
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: mocha
|
27
|
-
requirement: &
|
27
|
+
requirement: &70138524105520 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70138524105520
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: virtualbox
|
38
|
-
requirement: &
|
38
|
+
requirement: &70138524103420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70138524103420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: chef
|
49
|
-
requirement: &
|
49
|
+
requirement: &70138524099600 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 0.10.0
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70138524099600
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: net-ssh
|
60
|
-
requirement: &
|
60
|
+
requirement: &70138524098780 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: 2.1.3
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70138524098780
|
69
69
|
description: Handles bootstrapping, running chef solo, rsyncing cookbooks etc
|
70
70
|
email: mat@schaffer.me
|
71
71
|
executables: []
|
@@ -74,7 +74,8 @@ extra_rdoc_files: []
|
|
74
74
|
files:
|
75
75
|
- lib/chef/knife/cook.rb
|
76
76
|
- lib/chef/knife/kitchen.rb
|
77
|
-
- lib/chef/knife/patches/
|
77
|
+
- lib/chef/knife/patches/parser.rb
|
78
|
+
- lib/chef/knife/patches/search_patch.rb
|
78
79
|
- lib/chef/knife/prepare.rb
|
79
80
|
- lib/knife-solo/info.rb
|
80
81
|
- lib/knife-solo/kitchen_command.rb
|
@@ -92,18 +93,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
93
|
- - ! '>='
|
93
94
|
- !ruby/object:Gem::Version
|
94
95
|
version: '0'
|
95
|
-
segments:
|
96
|
-
- 0
|
97
|
-
hash: -2883154116349428333
|
98
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
97
|
none: false
|
100
98
|
requirements:
|
101
99
|
- - ! '>='
|
102
100
|
- !ruby/object:Gem::Version
|
103
101
|
version: '0'
|
104
|
-
segments:
|
105
|
-
- 0
|
106
|
-
hash: -2883154116349428333
|
107
102
|
requirements: []
|
108
103
|
rubyforge_project: nowarning
|
109
104
|
rubygems_version: 1.8.6
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# Taken from Vagrant's patch: https://gist.github.com/867960
|
2
|
-
# based on Brian Akins's patch: http://lists.opscode.com/sympa/arc/chef/2011-02/msg00000.html
|
3
|
-
if Chef::Config[:solo]
|
4
|
-
class Chef
|
5
|
-
module Mixin
|
6
|
-
module Language
|
7
|
-
def data_bag(bag)
|
8
|
-
@solo_data_bags = {} if @solo_data_bags.nil?
|
9
|
-
unless @solo_data_bags[bag]
|
10
|
-
@solo_data_bags[bag] = {}
|
11
|
-
data_bag_path = Chef::Config[:data_bag_path]
|
12
|
-
Dir.glob(File.join(data_bag_path, bag, "*.json")).each do |f|
|
13
|
-
item = JSON.parse(IO.read(f))
|
14
|
-
@solo_data_bags[bag][item['id']] = item
|
15
|
-
end
|
16
|
-
end
|
17
|
-
@solo_data_bags[bag].keys
|
18
|
-
end
|
19
|
-
|
20
|
-
def data_bag_item(bag, item)
|
21
|
-
data_bag(bag) unless ( !@solo_data_bags.nil? && @solo_data_bags[bag])
|
22
|
-
@solo_data_bags[bag][item]
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class Chef
|
30
|
-
class Recipe
|
31
|
-
def search(bag_name, query=nil)
|
32
|
-
Chef::Log.warn("Simplistic search patch, ignoring query of %s" % [query]) unless query.nil?
|
33
|
-
data_bag(bag_name.to_s).each do |bag_item_id|
|
34
|
-
bag_item = data_bag_item(bag_name.to_s, bag_item_id)
|
35
|
-
yield bag_item
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|