kitchen-salt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ module Kitchen
2
+ module Salt
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,212 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Simon McCartney <simon.mccartney@hp.com>
4
+ #
5
+ # Copyright (C) 2013, Chris Lundquist, Simon McCartney
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
+ require 'kitchen/provisioner/base'
20
+ require 'yaml'
21
+
22
+ module Kitchen
23
+
24
+ module Provisioner
25
+
26
+ # Basic Salt Masterless Provisioner, based on work by
27
+ #
28
+ # @author Chris Lundquist (<chris.ludnquist@github.com>)
29
+ class SaltSolo < Base
30
+
31
+ default_config :salt_bootstrap, true
32
+ default_config :salt_bootstrap_url, "http://bootstrap.saltstack.org"
33
+ default_config :salt_bootstrap_options, ""
34
+
35
+ default_config :chef_bootstrap_url, "https://www.getchef.com/chef/install.sh"
36
+
37
+ default_config :salt_config, "/etc/salt"
38
+ default_config :salt_minion_config, "/etc/salt/minion"
39
+ default_config :salt_file_root, "/srv/salt"
40
+ default_config :salt_pillar_root, "/srv/pillar"
41
+ default_config :salt_state_top, "/srv/salt/top.sls"
42
+ default_config :pillars, {}
43
+ default_config :state_top, {}
44
+ default_config :salt_run_highstate, true
45
+
46
+ def install_command
47
+ return unless config[:salt_bootstrap]
48
+
49
+ salt_url = config[:salt_bootstrap_url]
50
+ chef_url = config[:chef_bootstrap_url]
51
+ bootstrap_options = config[:salt_bootstrap_options]
52
+
53
+ <<-INSTALL
54
+ sh -c '
55
+ #{Util.shell_helpers}
56
+
57
+ # install salt, if not already installed
58
+ SALT_CALL=`which salt-call`
59
+ if [ -z "${SALT_CALL}" ]
60
+ then
61
+ do_download #{salt_url} /tmp/bootstrap-salt.sh
62
+ #{sudo('sh')} /tmp/bootstrap-salt.sh #{bootstrap_options}
63
+ fi
64
+
65
+ # install chef omnibus so that busser works :(
66
+ # TODO: work out how to install enough ruby
67
+ # and set busser: { :ruby_bindir => '/usr/bin/ruby' } so that we dont need the
68
+ # whole chef client
69
+ if [ ! -d "/opt/chef" ]
70
+ then
71
+ echo "-----> Installing Chef Omnibus"
72
+ do_download #{chef_url} /tmp/install.sh
73
+ #{sudo('sh')} /tmp/install.sh
74
+ fi
75
+
76
+ '
77
+ INSTALL
78
+ end
79
+
80
+ def create_sandbox
81
+ super
82
+ prepare_data
83
+ prepare_minion
84
+ prepare_state_top
85
+ prepare_pillars
86
+ prepare_formula
87
+ end
88
+
89
+ def init_command
90
+ debug("initialising Driver #{self.name}")
91
+ data = File.join(config[:root_path], "data")
92
+ "#{sudo('rm')} -rf #{data} ; mkdir -p #{config[:root_path]}"
93
+ end
94
+
95
+ def run_command
96
+ debug("running driver #{self.name}")
97
+ # sudo(File.join(config[:root_path], File.basename(config[:script])))
98
+ debug(diagnose())
99
+ if config[:salt_run_highstate]
100
+ sudo("salt-call --config-dir=#{File.join(config[:root_path], config[:salt_config])} --local state.highstate")
101
+ end
102
+ end
103
+
104
+ protected
105
+
106
+ def prepare_data
107
+ return unless config[:data_path]
108
+
109
+ info("Preparing data")
110
+ debug("Using data from #{config[:data_path]}")
111
+
112
+ tmpdata_dir = File.join(sandbox_path, "data")
113
+ FileUtils.mkdir_p(tmpdata_dir)
114
+ FileUtils.cp_r(Dir.glob("#{config[:data_path]}/*"), tmpdata_dir)
115
+ end
116
+
117
+ def prepare_minion
118
+ info("Preparing salt-minion")
119
+
120
+ minion_config_content = <<-MINION_CONFIG.gsub(/^ {10}/, '')
121
+ state_top: top.sls
122
+
123
+ file_client: local
124
+
125
+ file_roots:
126
+ base:
127
+ - #{File.join(config[:root_path], config[:salt_file_root])}
128
+
129
+ pillar_roots:
130
+ base:
131
+ - #{File.join(config[:root_path], config[:salt_pillar_root])}
132
+ MINION_CONFIG
133
+
134
+ # create the temporary path for the salt-minion config file
135
+ debug("sandbox is #{sandbox_path}")
136
+ sandbox_minion_config_path = File.join(sandbox_path, config[:salt_minion_config])
137
+
138
+ # create the directory & drop the file in
139
+ FileUtils.mkdir_p(File.dirname(sandbox_minion_config_path))
140
+ File.open(sandbox_minion_config_path, "wb") do |file|
141
+ file.write(minion_config_content)
142
+ end
143
+
144
+ end
145
+
146
+ def unsymbolize(obj)
147
+ return obj.inject({}){|memo,(k,v)| memo[k.to_s] = unsymbolize(v); memo} if obj.is_a? Hash
148
+ return obj.inject([]){|memo,v| memo << unsymbolize(v); memo} if obj.is_a? Array
149
+ return obj
150
+ end
151
+
152
+ def prepare_state_top
153
+ info("Preparing state_top")
154
+
155
+ # we get a hash with all the keys converted to symbols, salt doesn't like this
156
+ # to convert all the keys back to strings again
157
+ state_top_content = unsymbolize(config[:attributes][:state_top]).to_yaml
158
+ # .to_yaml will produce ! '*' for a key, Salt doesn't like this either
159
+ state_top_content.gsub!(/(!\s'\*')/, "'*'")
160
+ sandbox_state_top_path = File.join(sandbox_path, config[:salt_state_top])
161
+
162
+ # create the directory & drop the file in
163
+ FileUtils.mkdir_p(File.dirname(sandbox_state_top_path))
164
+ File.open(sandbox_state_top_path, "wb") do |file|
165
+ file.write(state_top_content)
166
+ end
167
+ end
168
+
169
+ def prepare_pillars
170
+ info("Preparing pillars into #{config[:salt_pillar_root]}")
171
+ debug("Pillars Hash: #{config[:attributes][:pillars]}")
172
+
173
+ # we get a hash with all the keys converted to symbols, salt doesn't like this
174
+ # to convert all the keys back to strings again
175
+ pillars = unsymbolize(config[:attributes][:pillars])
176
+ debug("unsymbolized pillars hash: #{pillars}")
177
+
178
+ # write out each pillar (we get key/contents pairs)
179
+ pillars.each do |key,contents|
180
+
181
+ # convert the hash to yaml
182
+ pillar = contents.to_yaml
183
+
184
+ # .to_yaml will produce ! '*' for a key, Salt doesn't like this either
185
+ pillar.gsub!(/(!\s'\*')/, "'*'")
186
+
187
+ # generate the filename
188
+ sandbox_pillar_path = File.join(sandbox_path, config[:salt_pillar_root], key)
189
+
190
+ # create the directory where the pillar file will go
191
+ FileUtils.mkdir_p(File.dirname(sandbox_pillar_path))
192
+
193
+ debug("Rendered pillar yaml for #{key}:\n #{pillar}")
194
+ # create the directory & drop the file in
195
+ File.open(sandbox_pillar_path, "wb") do |file|
196
+ file.write(pillar)
197
+ end
198
+ end
199
+ end
200
+
201
+ def prepare_formula
202
+ info("Preparing formula")
203
+ debug("Using config #{config}")
204
+
205
+ formula_dir = File.join(sandbox_path, config[:salt_file_root], config[:formula])
206
+ FileUtils.mkdir_p(formula_dir)
207
+ FileUtils.cp_r(Dir.glob(File.join(config[:kitchen_root], config[:formula], "*")), formula_dir)
208
+
209
+ end
210
+ end
211
+ end
212
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kitchen-salt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Simon McCartney
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-14 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: salt provisioner for test-kitchen
15
+ email:
16
+ - simon@mccartney.ie
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/kitchen-salt/version.rb
22
+ - lib/kitchen/provisioner/salt_solo.rb
23
+ homepage: https://github.com//kitchen-salt
24
+ licenses: []
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project: ! '[none]'
43
+ rubygems_version: 1.8.25
44
+ signing_key:
45
+ specification_version: 3
46
+ summary: salt provisioner for test-kitchen
47
+ test_files: []