chef-solo-wrapper 0.0.1
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/bin/cs +198 -0
- metadata +65 -0
data/bin/cs
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# chef-solo-wrapper (cs)
|
4
|
+
#
|
5
|
+
# Copyright 2011, Chris Fordham
|
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
|
+
CHEF_SOLO_WRAPPER_VERSION = '0.0.1'
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
require 'trollop'
|
23
|
+
require 'json'
|
24
|
+
|
25
|
+
opts = Trollop::options do
|
26
|
+
version 'chef-solo-wrapper '+CHEF_SOLO_WRAPPER_VERSION+' (c) 2011 Chris Fordham'
|
27
|
+
banner <<-EOS
|
28
|
+
A CLI wrapper for Chef Solo w/ RightScale integration.
|
29
|
+
|
30
|
+
Usage:
|
31
|
+
cs [options]
|
32
|
+
where [options] are:
|
33
|
+
EOS
|
34
|
+
opt :server, "Use attribute data from a RightScale server by nickname or ID.", :short => "-s", :type => String # flag --server, default false
|
35
|
+
opt :sandbox, "Use the Ruby environment in the local RightLink sandbox." # flag --sandbox, default false
|
36
|
+
opt :config, "Use alternate Chef Solo configuration (default used, ~/solo.rb.)", :short => "-c" # flag --config, default false
|
37
|
+
opt :json, "Use alternate Chef Solo JSON data (default used, ~/node.json.)", :short => "-j", :type => String # flag --json, default false
|
38
|
+
opt :dry, "Dry run only, don't run chef-solo.", :short => "-d" # flag --dry, default false
|
39
|
+
opt :run, "Use alernative run_list for chef-solo run.", :short => "-r", :type => String # flag --run, default false
|
40
|
+
opt :write, "Write back to local JSON file.", :short => "-w" # flag --write, default false
|
41
|
+
opt :loglevel, "The Chef log level to use: debug, info, warn, error, fatal", :short => "-l", :default => "info", :type => String # flag --loglevel, default info
|
42
|
+
opt :verbose, "Verbose mode.", :short => "-v" # flag --verbose, default false
|
43
|
+
opt :debug, "Debug mode." # flag --debug, default faulse
|
44
|
+
opt :help, "Print usage info and exit.", :short => "-h"
|
45
|
+
end
|
46
|
+
puts "options: #{opts.to_json}" unless !(opts.verbose || opts.debug and !opts.help)
|
47
|
+
puts 'chef-solo-wrapper '+CHEF_SOLO_WRAPPER_VERSION
|
48
|
+
|
49
|
+
solo = false
|
50
|
+
server = false
|
51
|
+
|
52
|
+
# ensure a solo.rb exists for run
|
53
|
+
if File.file?('/etc/chef/solo.rb')
|
54
|
+
solo = '/etc/chef/solo.rb'
|
55
|
+
else
|
56
|
+
puts ' DEBUG: /etc/chef/solo.rb: not found.' unless !opts.debug
|
57
|
+
end
|
58
|
+
if File.file?("#{ENV['HOME']}/solo.rb")
|
59
|
+
solo = "#{ENV['HOME']}/solo.rb"
|
60
|
+
else
|
61
|
+
puts ' DEBUG: ~/solo.rb: not found.' unless !opts.debug
|
62
|
+
end
|
63
|
+
unless solo
|
64
|
+
puts 'FATAL: No solo.rb file found (see http://wiki.opscode.com/display/chef/Chef+Solo), exiting.'
|
65
|
+
exit 1
|
66
|
+
else
|
67
|
+
puts "==> Using #{solo}." unless !opts.debug
|
68
|
+
if File.zero?(solo) then
|
69
|
+
puts "FATAL: #{solo} is empty, exiting."
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
puts File.new(solo, 'r').read unless !opts.debug
|
73
|
+
end
|
74
|
+
|
75
|
+
# get json if available
|
76
|
+
if opts.json
|
77
|
+
attributes = File.new(opts.json, "r").read
|
78
|
+
else
|
79
|
+
if File.file?('/etc/chef/node.json')
|
80
|
+
node_file = '/etc/chef/node.json'
|
81
|
+
attributes = JSON.parse(File.new(node_file, "r").read)
|
82
|
+
elsif File.file?("#{File.expand_path('~')}/node.json")
|
83
|
+
node_file = "#{File.expand_path('~')}/node.json"
|
84
|
+
attributes = JSON.parse(File.new("#{File.expand_path('~')}/node.json", "r").read)
|
85
|
+
else
|
86
|
+
node_file = "#{File.expand_path('~')}/node.json"
|
87
|
+
attributes = JSON.parse("{\n}\n")
|
88
|
+
end
|
89
|
+
chef_json = " -j #{node_file}"
|
90
|
+
end
|
91
|
+
|
92
|
+
# when a rs server is specified
|
93
|
+
if opts.server
|
94
|
+
|
95
|
+
# import rest_connection
|
96
|
+
puts 'Importing RestConnection RubyGem.' unless !opts.verbose
|
97
|
+
require 'rest_connection'
|
98
|
+
|
99
|
+
# fetch server via rest_connection
|
100
|
+
if opts.server.to_i > 0
|
101
|
+
puts "Finding server: #{opts.server}."
|
102
|
+
server = Server.find(opts.server.to_i)
|
103
|
+
else
|
104
|
+
puts "Finding server: '%#{opts.server}%'"
|
105
|
+
server = Server.find(:first) { |s| s.nickname =~ /#{opts.server}/ }
|
106
|
+
end
|
107
|
+
puts "Found server, '#{server.nickname}'."
|
108
|
+
puts server.to_yaml unless !opts.verbose
|
109
|
+
|
110
|
+
# get current instance of server
|
111
|
+
server.reload_current
|
112
|
+
puts JSON.pretty_generate(server.settings) unless !opts.debug
|
113
|
+
|
114
|
+
# assign inputs from server params
|
115
|
+
inputs = server.parameters
|
116
|
+
puts " DEBUG: #{JSON.pretty_generate(inputs)}" unless !opts.debug
|
117
|
+
server_attributes = Hash.new
|
118
|
+
inputs.each { |input,v|
|
119
|
+
if inputs.to_s =~ /^[A-Z]+$/
|
120
|
+
puts " DEBUG: right_script input #{k} discarded." unless !opts.debug
|
121
|
+
else
|
122
|
+
puts " DEBUG: #{input} => #{v}" unless !opts.debug
|
123
|
+
keys = input.split("/")
|
124
|
+
if keys.count == 2
|
125
|
+
type = v.split(':')[0]
|
126
|
+
value = v.split(':')[1]
|
127
|
+
value = '' unless value != "$ignore"
|
128
|
+
if keys[0] != 'rightscale'
|
129
|
+
puts " DEBUG: node attribute #{keys[1]} detected for cookbook, #{keys[0]}." unless !opts.debug
|
130
|
+
puts " DEBUG: attribute:#{keys[0]}[\"#{keys[1]}\"] type:#{type} value:#{value}" unless !opts.debug
|
131
|
+
puts " DEBUG: [#{keys[0]}][#{keys[1]}] => type: #{type}" unless !opts.debug
|
132
|
+
puts " DEBUG: [#{keys[0]}][#{keys[1]}] => value: #{value}" unless !opts.debug
|
133
|
+
server_attributes["#{keys[0]}"] = {} unless server_attributes["#{keys[0]}"]
|
134
|
+
server_attributes["#{keys[0]}"]["#{keys[1]}"] = "#{value}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
}
|
139
|
+
puts " DEBUG:\n#{p server_attributes}" unless !opts.debug
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
if server_attributes
|
144
|
+
puts server_attributes.to_json
|
145
|
+
puts ' DEBUG: Merging attributes.' unless !opts.debug
|
146
|
+
attributes = server_attributes.merge(attributes)
|
147
|
+
else
|
148
|
+
puts ' DEBUG: No server attributes to merge.' unless !opts.debug
|
149
|
+
end
|
150
|
+
|
151
|
+
if opts.run
|
152
|
+
# override runlist
|
153
|
+
attributes['run_list'] = "#{opts.run}"
|
154
|
+
end
|
155
|
+
|
156
|
+
# write attributes back to local node.json
|
157
|
+
if opts.write and server_attributes
|
158
|
+
node_json = JSON.pretty_generate(attributes)
|
159
|
+
puts "Node Attributes: \n #{node_json}" unless !opts.debug
|
160
|
+
# open file for write back
|
161
|
+
fh = File.new(node_file, "w")
|
162
|
+
fh.write(node_json)
|
163
|
+
fh.close
|
164
|
+
end
|
165
|
+
|
166
|
+
# prepare options
|
167
|
+
chef_config = " -c #{opts.config}" unless !opts.config
|
168
|
+
chef_json = " -j #{opts.json}" unless !opts.json
|
169
|
+
|
170
|
+
# depict if sandbox chef-solo binary is used
|
171
|
+
if opts.sandbox
|
172
|
+
cs = '/opt/rightscale/sandbox/bin/chef-solo'
|
173
|
+
else
|
174
|
+
cs = 'chef-solo'
|
175
|
+
end
|
176
|
+
|
177
|
+
# build chef solo command
|
178
|
+
cmd = "#{cs}#{chef_config}#{chef_json} --log_level #{opts.loglevel} || ( echo 'Chef run failed!'; cat /var/chef-solo/chef-stacktrace.out; exit 1 )"
|
179
|
+
puts " DEBUG: running #{cmd}" unless !opts.debug
|
180
|
+
|
181
|
+
# import chef
|
182
|
+
puts 'Importing Chef RubyGem.' unless !opts.verbose
|
183
|
+
require 'chef'
|
184
|
+
|
185
|
+
# prepend sudo if not run as root
|
186
|
+
if Process.uid != 0
|
187
|
+
cmd.insert(0, 'sudo ')
|
188
|
+
puts " DEBUG: Non-root user, appending sudo (#{cmd})." unless !opts.debug
|
189
|
+
end
|
190
|
+
|
191
|
+
# finally, run chef-solo
|
192
|
+
puts 'Starting Chef Solo.' unless !(opts.verbose || opts.debug)
|
193
|
+
unless opts.dry
|
194
|
+
system(cmd)
|
195
|
+
else
|
196
|
+
puts 'Dry run only, exiting.'
|
197
|
+
exit
|
198
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chef-solo-wrapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Chris Fordham
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-05-29 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: A basic wrapper for chef-solo with RightScale integration.
|
22
|
+
email: chris@xhost.com.au
|
23
|
+
executables:
|
24
|
+
- cs
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- bin/cs
|
31
|
+
homepage: https://github.com/flaccid/chef-solo-wrapper
|
32
|
+
licenses: []
|
33
|
+
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
hash: 3
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.8.10
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: chef-solo-wrapper
|
64
|
+
test_files: []
|
65
|
+
|