knife-joyent 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,11 +34,11 @@ module KnifeJoyent
34
34
  :description => 'path to ssh private key for signature auth',
35
35
  :proc => Proc.new {|key| Chef::Config[:knife][:joyent_keyfile] = key }
36
36
 
37
- option :joyent_url,
37
+ option :joyent_api_url,
38
38
  :short => "-L JOYENT_API_URL",
39
39
  :long => "--joyent-api-url JOYENT_API_URL",
40
40
  :description => "Joyent API URL",
41
- :proc => Proc.new {|key| Chef::Config[:knife][:joyent_url] = key }
41
+ :proc => Proc.new {|key| Chef::Config[:knife][:joyent_api_url] = key }
42
42
  end
43
43
 
44
44
  def connection
@@ -49,7 +49,7 @@ module KnifeJoyent
49
49
  :joyent_password => Chef::Config[:knife][:joyent_password],
50
50
  :joyent_keyname => Chef::Config[:knife][:joyent_keyname],
51
51
  :joyent_keyfile => Chef::Config[:knife][:joyent_keyfile],
52
- :joyent_url => Chef::Config[:knife][:joyent_url]
52
+ :joyent_url => Chef::Config[:knife][:joyent_api_url]
53
53
  )
54
54
  end
55
55
  end
@@ -3,35 +3,160 @@ module KnifeJoyent
3
3
 
4
4
  include KnifeJoyent::Base
5
5
 
6
+ deps do
7
+ require 'chef/knife/bootstrap'
8
+ Chef::Knife::Bootstrap.load_deps
9
+ require 'fog'
10
+ require 'socket'
11
+ require 'net/ssh/multi'
12
+ require 'readline'
13
+ require 'chef/json_compat'
14
+ end
15
+
6
16
  banner 'knife joyent server create (options)'
7
17
 
18
+ # mixlib option parsing
8
19
  option :name,
9
20
  :long => '--name <name>',
10
21
  :description => 'name for this machine'
11
22
 
12
23
  option :package,
13
- :long => '--flavor <name>',
24
+ :short => '-f FLAVOR_NAME',
25
+ :long => '--flavor FLAVOR_NAME',
14
26
  :description => 'specify flavor/package for the server'
15
27
 
16
28
  option :dataset,
17
- :short => '--image <id>',
29
+ :short => '-I IMAGE_ID',
30
+ :long => '--image IMAGE_ID',
18
31
  :description => 'specify image for the server'
19
32
 
33
+ option :run_list,
34
+ :short => "-r RUN_LIST",
35
+ :long => "--run-list RUN_LIST",
36
+ :description => "Comma separated list of roles/recipes to apply",
37
+ :proc => lambda { |o| o.split(/[\s,]+/) },
38
+ :default => []
39
+
40
+ option :ssh_user,
41
+ :short => "-x USERNAME",
42
+ :long => "--ssh-user USERNAME",
43
+ :description => "The ssh username",
44
+ :default => "root"
45
+
46
+ option :identity_file,
47
+ :short => "-i IDENTITY_FILE",
48
+ :long => "--identity-file IDENTITY_FILE",
49
+ :description => "The SSH identity file used for authentication"
50
+
51
+ option :chef_node_name,
52
+ :short => "-N NAME",
53
+ :long => "--node-name NAME",
54
+ :description => "The Chef node name for your new node"
55
+
56
+ option :prerelease,
57
+ :long => "--prerelease",
58
+ :description => "Install the pre-release chef gems"
59
+
60
+ option :distro,
61
+ :short => "-d DISTRO",
62
+ :long => "--distro DISTRO",
63
+ :description => "Bootstrap a distro using a template",
64
+ :proc => Proc.new { |d| Chef::Config[:knife][:distro] = d },
65
+ :default => "chef-full"
66
+
67
+ option :environment,
68
+ :short => "-E Environment",
69
+ :long => "--environment ENVIRONMENT",
70
+ :description => "Assign an environment to Chef Node",
71
+ :proc => Proc.new { |e| Chef::Config[:environment][:distro] = e },
72
+ :default => "_default"
73
+
74
+ option :no_host_key_verify,
75
+ :long => "--no-host-key-verify",
76
+ :description => "Disable host key verification",
77
+ :boolean => true,
78
+ :default => false
79
+
80
+ # wait for ssh to come up
81
+ def tcp_test_ssh(hostname)
82
+ tcp_socket = TCPSocket.new(hostname, 22)
83
+ readable = IO.select([tcp_socket], nil, nil, 5)
84
+ if readable
85
+ Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
86
+ yield
87
+ true
88
+ else
89
+ false
90
+ end
91
+ rescue Errno::ETIMEDOUT
92
+ false
93
+ rescue Errno::EPERM
94
+ false
95
+ rescue Errno::ECONNREFUSED
96
+ sleep 2
97
+ false
98
+ rescue Errno::EHOSTUNREACH
99
+ sleep 2
100
+ false
101
+ ensure
102
+ tcp_socket && tcp_socket.close
103
+ end
104
+
105
+
106
+ # Run Chef bootstrap script
107
+ def bootstrap_for_node(server)
108
+ bootstrap = Chef::Knife::Bootstrap.new
109
+ Chef::Log.debug("Bootstrap name_args = [ #{server.ips.last} ]")
110
+ bootstrap.name_args = [ server.ips.last ]
111
+ Chef::Log.debug("Bootstrap run_list = #{config[:run_list]}")
112
+ bootstrap.config[:run_list] = config[:run_list]
113
+ Chef::Log.debug("Bootstrap ssh_user = #{config[:ssh_user]}")
114
+ bootstrap.config[:ssh_user] = config[:ssh_user]
115
+ Chef::Log.debug("Bootstrap identity_file = #{config[:identity_file]}")
116
+ bootstrap.config[:identity_file] = config[:identity_file]
117
+ Chef::Log.debug("Bootstrap chef_node_name = #{config[:chef_node_name]}")
118
+ bootstrap.config[:chef_node_name] = config[:chef_node_name] || server.id
119
+ Chef::Log.debug("Bootstrap prerelease = #{config[:prerelease]}")
120
+ bootstrap.config[:prerelease] = config[:prerelease]
121
+ Chef::Log.debug("Bootstrap distro = #{config[:distro]}")
122
+ bootstrap.config[:distro] = config[:distro]
123
+ #Chef::Log.debug("Bootstrap use_sudo = #{config[:use_sudo]}")
124
+ #bootstrap.config[:use_sudo] = true
125
+ Chef::Log.debug("Bootstrap environment = #{config[:environment]}")
126
+ bootstrap.config[:environment] = config[:environment]
127
+ Chef::Log.debug("Bootstrap no_host_key_verify = #{config[:no_host_key_verify]}")
128
+ bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
129
+
130
+ bootstrap
131
+ end
132
+
133
+ # Go
20
134
  def run
21
- if s = self.connection.servers.create(:dataset => config[:dataset],
135
+ begin
136
+ server = self.connection.servers.create(:dataset => config[:dataset],
22
137
  :package => config[:package],
23
138
  :name => config[:name])
24
- puts ui.color("Created machine: #{s.id}", :cyan)
25
- exit 0
26
- end
27
- rescue => e
28
- if e.response && e.response.body.kind_of?(String)
29
- error = MultiJson.decode(e.response.body)
30
- puts ui.error(error['message'])
31
- exit 1
32
- else
33
- raise
139
+
140
+ rescue => e
141
+ Chef::Log.debug("e: #{e}")
142
+ if e.response && e.response.body.kind_of?(String)
143
+ error = MultiJson.decode(e.response.body)
144
+ puts ui.error(error['message'])
145
+ exit 1
146
+ else
147
+ raise
148
+ end
34
149
  end
150
+
151
+ puts ui.color("Created machine: #{server.id}", :cyan)
152
+ puts ui.color("attempting to bootstrap on #{server.ips.last}", :cyan)
153
+
154
+ print(".") until tcp_test_ssh(server.ips.last) {
155
+ sleep 1
156
+ puts("done")
157
+ }
158
+ bootstrap_for_node(server).run
159
+ exit 0
35
160
  end
36
161
 
37
162
  end
@@ -1,3 +1,3 @@
1
1
  module KnifeJoyent
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
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.0.6
4
+ version: 0.0.7
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: 2012-05-15 00:00:00.000000000 Z
12
+ date: 2012-07-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog