knife-joyent 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -66,10 +66,10 @@ or, your ssh key
66
66
 
67
67
  **joyent_api_url**
68
68
 
69
- Specify a custom API endpoint, this is required if you want to specify
69
+ Specify a custom API endpoint, this is required if you want to specify
70
70
  where you want to provision your machines, or if you are using knife with a
71
71
  provider powered by [SmartDataCenter](http://www.joyent.com/products/smartdatacenter/).
72
-
72
+
73
73
  # Defaults to https://us-west-1.api.joyentcloud.com/
74
74
  knife[:joyent_api_url] = "https://us-sw-1.api.joyentcloud.com/"
75
75
 
@@ -83,6 +83,12 @@ the form of a hash with a single level of nesting. See the
83
83
  "some_data" => "value"
84
84
  }
85
85
 
86
+ **provisioner**
87
+
88
+ Machines provisioned will be tagged with key ``provisioner`` containing the value specified.
89
+ This is useful for tracking source of provisions for accounts where machines are provisioned
90
+ by/from different sources / users.
91
+
86
92
  ## Contributors
87
93
 
88
94
  - [Sean Omera](https://github.com/someara) - Opscode
data/knife-joyent.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.add_dependency "fog", "~> 1.6"
19
+ s.add_dependency "fog", "~> 1.11"
20
20
  s.add_dependency "chef", ">= 0.10.10"
21
21
  s.require_paths = ["lib"]
22
22
 
@@ -21,7 +21,7 @@ class Chef
21
21
 
22
22
  option :joyent_password,
23
23
  :short => '-P PASSWORD',
24
- :long => '--joyent-password PASSOWRD',
24
+ :long => '--joyent-password PASSWORD',
25
25
  :description => 'Your Joyent password',
26
26
  :proc => Proc.new {|key| Chef::Config[:knife][:joyent_password] = key }
27
27
 
@@ -45,7 +45,7 @@ class Chef
45
45
 
46
46
  def connection
47
47
  @connection ||= begin
48
- connection = Fog::Compute.new(
48
+ Fog::Compute.new(
49
49
  :provider => 'Joyent',
50
50
  :joyent_username => Chef::Config[:knife][:joyent_username],
51
51
  :joyent_password => Chef::Config[:knife][:joyent_password],
@@ -108,31 +108,26 @@ class Chef
108
108
  return (block_a.include?(ip) or block_b.include?(ip) or block_c.include?(ip))
109
109
  end
110
110
 
111
- # wait for ssh to come up
112
111
  def tcp_test_ssh(hostname)
113
- tcp_socket = TCPSocket.new(hostname, 22)
114
- readable = IO.select([tcp_socket], nil, nil, 5)
115
- if readable
116
- Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
117
- yield
118
- true
119
- else
120
- false
121
- end
122
- rescue Errno::ETIMEDOUT
123
- false
124
- rescue Errno::EPERM
125
- false
126
- rescue Errno::ECONNREFUSED
127
- sleep 2
128
- false
129
- rescue Errno::EHOSTUNREACH
130
- sleep 2
131
- false
132
- ensure
133
- tcp_socket && tcp_socket.close
112
+ ssh_test_max = 10*60
113
+ ssh_test = 0
114
+
115
+ begin
116
+ if ssh_test < ssh_test_max
117
+ print(".")
118
+ ssh_test += 1
119
+ sleep 1
120
+ else
121
+ ui.error("Unable to ssh to node (#{bootstrap_ip_address}), exiting")
122
+ exit 1
123
+ end
124
+ end until _tcp_test_ssh(bootstrap_id) {
125
+ sleep @initial_sleep_delay ||= 10
126
+ puts("done")
127
+ }
134
128
  end
135
129
 
130
+
136
131
  def run
137
132
  $stdout.sync = true
138
133
 
@@ -151,45 +146,35 @@ class Chef
151
146
  print "\n#{ui.color("Waiting for server", :magenta)}"
152
147
  server.wait_for { print "."; ready? }
153
148
 
154
- #which IP address to bootstrap
155
- bootstrap_ip_addresses = server.ips.select{ |ip| ip and not(is_loopback(ip) or is_linklocal(ip)) }
149
+ bootstrap_ip = self.determine_bootstrap_ip(server)
156
150
 
157
- if bootstrap_ip_addresses.count == 1
158
- bootstrap_ip_address = bootstrap_ip_addresses.first
159
- else
160
- if config[:private_network]
161
- bootstrap_ip_address = bootstrap_ip_addresses.find{|ip| is_private(ip)}
162
- else
163
- bootstrap_ip_address = bootstrap_ip_addresses.find{|ip| not is_private(ip)}
164
- end
165
- end
166
-
167
- Chef::Log.debug("Bootstrap IP Address #{bootstrap_ip_address}")
168
- if bootstrap_ip_address.nil?
151
+ Chef::Log.debug("Bootstrap IP Address #{bootstrap_ip}")
152
+ unless bootstrap_ip
169
153
  ui.error("No IP address available for bootstrapping.")
170
154
  exit 1
171
155
  end
172
156
 
173
- puts ui.color("attempting to bootstrap on #{bootstrap_ip_address}", :cyan)
174
-
175
- ssh_test_max = 10*60
176
- ssh_test = 0
177
-
178
- begin
179
- if ssh_test < ssh_test_max
180
- print(".")
181
- ssh_test += 1
182
- sleep 1
183
- else
184
- ui.error("Unable to ssh to node (#{bootstrap_ip_address}), exiting")
185
- exit 1
157
+ puts ui.color("attempting to bootstrap on #{bootstrap_ip}", :cyan)
158
+
159
+ if Chef::Config[:knife][:provisioner]
160
+ # tag the provision with 'provisioner'
161
+ tagkey = 'provisioner'
162
+ tagvalue = Chef::Config[:knife][:provisioner]
163
+ tags = [
164
+ ui.color('Name', :bold),
165
+ ui.color('Value', :bold),
166
+ ]
167
+ server.add_tags({tagkey => tagvalue}).each do |k, v|
168
+ tags << k
169
+ tags << v
186
170
  end
187
- end until tcp_test_ssh(bootstrap_ip_address) {
188
- sleep @initial_sleep_delay ||= 10
189
- puts("done")
190
- }
171
+ puts ui.color("Updated tags for #{node_name}", :cyan)
172
+ puts ui.list(tags, :uneven_columns_across, 2)
173
+ else
174
+ puts ui.color("No user defined in knife config for provision tagging", :magenta)
175
+ end
191
176
 
192
- bootstrap_for_node(server, bootstrap_ip_address).run
177
+ bootstrap_for_node(server, bootstrap_ip).run
193
178
 
194
179
  puts ui.color("Created machine:", :cyan)
195
180
  msg_pair("ID", server.id.to_s)
@@ -197,39 +182,77 @@ class Chef
197
182
  msg_pair("State", server.state)
198
183
  msg_pair("Type", server.type)
199
184
  msg_pair("Dataset", server.dataset)
200
- msg_pair("IP's", server.ips)
185
+ msg_pair("IP's", server.ips.join(" "))
201
186
  msg_pair("JSON Attributes",config[:json_attributes]) unless config[:json_attributes].empty?
187
+
188
+ rescue Excon::Errors::Conflict => e
189
+ if e.response && e.response.body.kind_of?(String)
190
+ error = ::Fog::JSON.decode(e.response.body)
191
+ puts ui.error(error['message'])
192
+ exit 1
193
+ else
194
+ puts ui.error(e.message)
195
+ exit 1
196
+ end
197
+ rescue => e
198
+ puts ui.error('Unexpected Error Occured:' + e.message)
199
+ exit 1
202
200
  end
203
201
 
204
202
  # Run Chef bootstrap script
205
- def bootstrap_for_node(server, bootstrap_ip_address)
203
+ def bootstrap_for_node(server, bootstrap_ip)
206
204
  bootstrap = Chef::Knife::Bootstrap.new
207
- Chef::Log.debug("Bootstrap name_args = [ #{bootstrap_ip_address} ]")
208
- bootstrap.name_args = [ bootstrap_ip_address ]
205
+ Chef::Log.debug("Bootstrap name_args = [ #{bootstrap_ip} ]")
206
+ bootstrap.name_args = [ bootstrap_ip ]
207
+
209
208
  Chef::Log.debug("Bootstrap run_list = #{config[:run_list]}")
210
209
  bootstrap.config[:run_list] = config[:run_list]
210
+
211
211
  Chef::Log.debug("Bootstrap ssh_user = #{config[:ssh_user]}")
212
212
  bootstrap.config[:ssh_user] = config[:ssh_user]
213
+
213
214
  Chef::Log.debug("Bootstrap identity_file = #{config[:identity_file]}")
214
215
  bootstrap.config[:identity_file] = config[:identity_file]
216
+
215
217
  Chef::Log.debug("Bootstrap chef_node_name = #{config[:chef_node_name]}")
216
218
  bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
219
+
217
220
  Chef::Log.debug("Bootstrap prerelease = #{config[:prerelease]}")
218
221
  bootstrap.config[:prerelease] = config[:prerelease]
222
+
219
223
  Chef::Log.debug("Bootstrap distro = #{config[:distro]}")
220
224
  bootstrap.config[:distro] = config[:distro]
225
+
221
226
  #Chef::Log.debug("Bootstrap use_sudo = #{config[:use_sudo]}")
222
227
  #bootstrap.config[:use_sudo] = true
228
+
223
229
  Chef::Log.debug("Bootstrap environment = #{config[:environment]}")
224
230
  bootstrap.config[:environment] = config[:environment]
231
+
225
232
  Chef::Log.debug("Bootstrap no_host_key_verify = #{config[:no_host_key_verify]}")
226
233
  bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
234
+
227
235
  Chef::Log.debug("Bootstrap json_attributes = #{config[:json_attributes]}")
228
236
  bootstrap.config[:first_boot_attributes] = config[:json_attributes]
229
237
 
230
238
  bootstrap
231
239
  end
232
240
 
241
+ def determine_bootstrap_ip(server)
242
+ server_ips = server.ips.select{ |ip|
243
+ ip and not(is_loopback(ip) or is_linklocal(ip))
244
+ }
245
+ if server_ips.count === 1
246
+ server_ips.first
247
+ else
248
+ if config[:private_network]
249
+ server_ips.find{|ip| is_private(ip)}
250
+ else
251
+ server_ips.find{|ip| not is_private(ip)}
252
+ end
253
+ end
254
+ end
255
+
233
256
  private
234
257
 
235
258
  def validate_server_name
@@ -248,6 +271,31 @@ class Chef
248
271
  return {} if metadata.empty?
249
272
  Hash[metadata.map { |k, v| ["metadata.#{k}", v] }]
250
273
  end
274
+
275
+ def _tcp_test_ssh(hostname)
276
+ tcp_socket = TCPSocket.new(hostname, 22)
277
+ readable = IO.select([tcp_socket], nil, nil, 5)
278
+ if readable
279
+ Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
280
+ yield
281
+ true
282
+ else
283
+ false
284
+ end
285
+ rescue Errno::ETIMEDOUT
286
+ false
287
+ rescue Errno::EPERM
288
+ false
289
+ rescue Errno::ECONNREFUSED
290
+ sleep 2
291
+ false
292
+ rescue Errno::EHOSTUNREACH
293
+ sleep 2
294
+ false
295
+ ensure
296
+ tcp_socket && tcp_socket.close
297
+ end
298
+
251
299
  end
252
300
  end
253
301
  end
@@ -25,7 +25,7 @@ class Chef
25
25
  msg("State", server.state)
26
26
  msg("Type", server.type)
27
27
  msg("Dataset", server.dataset)
28
- msg("IP's", server.ips)
28
+ msg("IP's", server.ips.join(" "))
29
29
 
30
30
  unless server
31
31
  puts ui.error("Unable to locate server: #{id}")
@@ -1,3 +1,3 @@
1
1
  module KnifeJoyent
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-joyent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-15 00:00:00.000000000 Z
12
+ date: 2013-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '1.6'
21
+ version: '1.11'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: '1.6'
29
+ version: '1.11'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: chef
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -101,8 +101,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  version: '0'
102
102
  requirements: []
103
103
  rubyforge_project:
104
- rubygems_version: 1.8.21
104
+ rubygems_version: 1.8.25
105
105
  signing_key:
106
106
  specification_version: 3
107
107
  summary: Joyent CloudAPI Support for Chef's Knife Command
108
108
  test_files: []
109
+ has_rdoc: true