knife-hmc 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +103 -0
- data/Rakefile +1 -0
- data/knife-hmc.gemspec +26 -0
- data/lib/chef/knife/hmc_base.rb +131 -0
- data/lib/chef/knife/hmc_disk_add.rb +116 -0
- data/lib/chef/knife/hmc_disk_list.rb +173 -0
- data/lib/chef/knife/hmc_disk_remove.rb +67 -0
- data/lib/chef/knife/hmc_image_list.rb +54 -0
- data/lib/chef/knife/hmc_server_config.rb +111 -0
- data/lib/chef/knife/hmc_server_create.rb +368 -0
- data/lib/chef/knife/hmc_server_delete.rb +102 -0
- data/lib/chef/knife/hmc_server_list.rb +55 -0
- data/lib/chef/knife/hmc_server_state.rb +82 -0
- data/lib/knife-hmc/version.rb +6 -0
- data/vendor/bundle/placeholder +0 -0
- metadata +104 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
#
|
2
|
+
# Authors: Christopher M Wood (<woodc@us.ibm.com>)
|
3
|
+
# John F Hutchinson (<jfhutchi@us.ibm.com>)
|
4
|
+
# © Copyright IBM Corporation 2015.
|
5
|
+
#
|
6
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'chef/knife/hmc_base'
|
10
|
+
|
11
|
+
class Chef
|
12
|
+
class Knife
|
13
|
+
class HmcDiskRemove < Knife
|
14
|
+
|
15
|
+
include Knife::HmcBase
|
16
|
+
|
17
|
+
banner "knife hmc disk remove (options)"
|
18
|
+
|
19
|
+
option :frame_name,
|
20
|
+
:short => "-f NAME",
|
21
|
+
:long => "--frame NAME",
|
22
|
+
:description => "Name of the Host in which the LPAR resides."
|
23
|
+
|
24
|
+
option :lpar_name,
|
25
|
+
:short => "-l NAME",
|
26
|
+
:long => "--lpar",
|
27
|
+
:description => "Name of LPAR you wish to delete."
|
28
|
+
|
29
|
+
option :vio1_name,
|
30
|
+
:short => "-p NAME",
|
31
|
+
:long => "--primary_vio NAME",
|
32
|
+
:description => "Name of the primary vio."
|
33
|
+
|
34
|
+
option :vio2_name,
|
35
|
+
:short => "-s NAME",
|
36
|
+
:long => "--secondary_vio NAME",
|
37
|
+
:description => "Name of the secondary vio."
|
38
|
+
|
39
|
+
option :pvid,
|
40
|
+
:short => "-i PVID",
|
41
|
+
:long => "--pvid PVID",
|
42
|
+
:description => "Physical Volume Identification Number."
|
43
|
+
|
44
|
+
def run
|
45
|
+
Chef::Log.debug("Removing disk...")
|
46
|
+
|
47
|
+
validate!([:frame_name,:lpar_name,:vio2_name,:vio1_name,:pvid])
|
48
|
+
#Create HMC Object and connect to the HMC
|
49
|
+
hmc = Hmc.new(get_config(:hmc_host), get_config(:hmc_username) , {:password => get_config(:hmc_password)})
|
50
|
+
hmc.connect
|
51
|
+
#Populate hash to make LPAR object
|
52
|
+
lpar_hash = hmc.get_lpar_options(get_config(:frame_name),get_config(:lpar_name))
|
53
|
+
#Create LPAR object based on hash, and VIO objects
|
54
|
+
lpar = Lpar.new(lpar_hash)
|
55
|
+
vio1 = Vio.new(hmc, get_config(:frame_name), get_config(:vio1_name))
|
56
|
+
vio2 = Vio.new(hmc, get_config(:frame_name), get_config(:vio2_name))
|
57
|
+
#Remove disk by pvid
|
58
|
+
vio1.unmap_by_pvid(vio2,get_config(:pvid))
|
59
|
+
puts "Successfully removed LUN with PVID #{get_config(:pvid)}"
|
60
|
+
#Disconnect from HMC
|
61
|
+
hmc.disconnect
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Authors: Christopher M Wood (<woodc@us.ibm.com>)
|
3
|
+
# John F Hutchinson (<jfhutchi@us.ibm.com>)
|
4
|
+
# © Copyright IBM Corporation 2015.
|
5
|
+
#
|
6
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'chef/knife/hmc_base'
|
10
|
+
|
11
|
+
class Chef
|
12
|
+
class Knife
|
13
|
+
class HmcImageList < Knife
|
14
|
+
|
15
|
+
include Knife::HmcBase
|
16
|
+
|
17
|
+
banner "knife hmc image list --nim_host HOSTNAME --nim_user USER --nim_pass PASSWORD"
|
18
|
+
|
19
|
+
option :nim_host,
|
20
|
+
:short => "-n HOST",
|
21
|
+
:long => "--nim_host HOST",
|
22
|
+
:description => "The fully qualified domain name of the NIM server"
|
23
|
+
|
24
|
+
option :nim_user,
|
25
|
+
:short => "-l USER",
|
26
|
+
:long => "--nim_user USER",
|
27
|
+
:description => "The username for the NIM server"
|
28
|
+
|
29
|
+
|
30
|
+
option :nim_pass,
|
31
|
+
:short => "-m PASSWORD",
|
32
|
+
:long => "--nim_pass PASSWORD",
|
33
|
+
:description => "The password of the user specified in --nim_user"
|
34
|
+
|
35
|
+
|
36
|
+
def run
|
37
|
+
Chef::Log.debug("Listing images...")
|
38
|
+
|
39
|
+
validate!([:nim_host,:nim_user,:nim_pass])
|
40
|
+
|
41
|
+
nim = Nim.new(get_config(:nim_host),get_config(:nim_user),{:password => get_config(:nim_pass)})
|
42
|
+
nim.connect
|
43
|
+
|
44
|
+
puts "Mksysb Image Names: "
|
45
|
+
nim.list_images.each do |image_name|
|
46
|
+
puts "#{image_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
nim.disconnect
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Authors: Christopher M Wood (<woodc@us.ibm.com>)
|
3
|
+
# John F Hutchinson (<jfhutchi@us.ibm.com>)
|
4
|
+
# © Copyright IBM Corporation 2015.
|
5
|
+
#
|
6
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'chef/knife/hmc_base'
|
10
|
+
|
11
|
+
class Chef
|
12
|
+
class Knife
|
13
|
+
class HmcServerConfig < Knife
|
14
|
+
|
15
|
+
include Knife::HmcBase
|
16
|
+
|
17
|
+
banner "knife hmc server config -f FRAME -l LPARNAME -a A=V[,A=V,A=V...]"
|
18
|
+
|
19
|
+
option :lpar,
|
20
|
+
:short => "-l LPARNAME",
|
21
|
+
:long => "--lpar LPARNAME",
|
22
|
+
:description => "The name of the LPAR to configure"
|
23
|
+
|
24
|
+
option :frame,
|
25
|
+
:short => "-f FRAME",
|
26
|
+
:long => "--frame FRAME",
|
27
|
+
:description => "The name of the frame on which the LPAR resides"
|
28
|
+
|
29
|
+
option :attributes,
|
30
|
+
:short => "-a A=V[,A=V,...]",
|
31
|
+
:long => "--attributes Attr=Value[,Attr=Value,...]",
|
32
|
+
:description => "A list of LPAR attributes and what their values should be changed to",
|
33
|
+
:proc => Proc.new { |attributes| attributes.split(',') }
|
34
|
+
|
35
|
+
def run
|
36
|
+
Chef::Log.debug("Configuring server...")
|
37
|
+
|
38
|
+
validate!
|
39
|
+
validate!([:lpar,:frame, :attributes])
|
40
|
+
hmc = Hmc.new(get_config(:hmc_host), get_config(:hmc_username) , {:password => get_config(:hmc_password)})
|
41
|
+
hmc.connect
|
42
|
+
|
43
|
+
options_hash = hmc.get_lpar_options(get_config(:frame),get_config(:lpar))
|
44
|
+
lpar = Lpar.new(options_hash)
|
45
|
+
|
46
|
+
puts "Configuring #{lpar.name}..."
|
47
|
+
|
48
|
+
attrs = get_config(:attributes)
|
49
|
+
attrs.each do |operation|
|
50
|
+
key,value = operation.split('=')
|
51
|
+
case key
|
52
|
+
when "name"
|
53
|
+
old_name = lpar.name
|
54
|
+
lpar.rename(value)
|
55
|
+
puts "Changed name from #{old_name} to #{lpar.name}"
|
56
|
+
when "max_virtual_slots"
|
57
|
+
old_max = lpar.max_virtual_slots
|
58
|
+
lpar.max_virtual_slots = value.to_i
|
59
|
+
puts "Changed max_virtual_slots from #{old_max} to #{lpar.max_virtual_slots}"
|
60
|
+
when "uncap_weight"
|
61
|
+
old_weight = lpar.uncap_weight
|
62
|
+
unless (lpar.uncap_weight = value.to_i).nil?
|
63
|
+
puts "Changed uncap_weight from #{old_weight} to #{lpar.uncap_weight}"
|
64
|
+
end
|
65
|
+
when "desired_proc_units"
|
66
|
+
old_units = lpar.desired_proc_units
|
67
|
+
lpar.desired_proc_units = value.to_f
|
68
|
+
puts "Changed desired_proc_units from #{old_units} to #{lpar.desired_proc_units}"
|
69
|
+
when "max_proc_units"
|
70
|
+
old_units = lpar.max_proc_units
|
71
|
+
lpar.max_proc_units = value.to_f
|
72
|
+
puts "Changed max_proc_units from #{old_units} to #{lpar.max_proc_units}"
|
73
|
+
when "min_proc_units"
|
74
|
+
old_units = lpar.min_proc_units
|
75
|
+
lpar.min_proc_units = value.to_f
|
76
|
+
puts "Changed min_proc_units from #{old_units} to #{lpar.min_proc_units}"
|
77
|
+
when "desired_vcpu"
|
78
|
+
old_units = lpar.desired_vcpu
|
79
|
+
lpar.desired_vcpu = value.to_i
|
80
|
+
puts "Changed desired_vcpu from #{old_units} to #{lpar.desired_vcpu}"
|
81
|
+
when "max_vcpu"
|
82
|
+
old_units = lpar.max_vcpu
|
83
|
+
lpar.max_vcpu = value.to_i
|
84
|
+
puts "Changed max_vcpu from #{old_units} to #{lpar.max_vcpu}"
|
85
|
+
when "min_vcpu"
|
86
|
+
old_units = lpar.min_vcpu
|
87
|
+
lpar.min_vcpu = value.to_i
|
88
|
+
puts "Changed min_vcpu from #{old_units} to #{lpar.min_vcpu}"
|
89
|
+
when "desired_memory"
|
90
|
+
old_units = lpar.desired_memory
|
91
|
+
lpar.desired_memory = value.to_i
|
92
|
+
puts "Changed desired_memory from #{old_units} to #{lpar.desired_memory}"
|
93
|
+
when "max_memory"
|
94
|
+
old_units = lpar.max_memory
|
95
|
+
lpar.max_memory = value.to_i
|
96
|
+
puts "Changed max_memory from #{old_units} to #{lpar.max_memory}"
|
97
|
+
when "min_memory"
|
98
|
+
old_units = lpar.min_memory
|
99
|
+
lpar.min_memory = value.to_i
|
100
|
+
puts "Changed min_memory from #{old_units} to #{lpar.min_memory}"
|
101
|
+
else
|
102
|
+
puts "Unrecognized attribute #{key}, proceeding to next config change..."
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
hmc.disconnect
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,368 @@
|
|
1
|
+
#
|
2
|
+
# Authors: Christopher M Wood (<woodc@us.ibm.com>)
|
3
|
+
# John F Hutchinson (<jfhutchi@us.ibm.com>)
|
4
|
+
# © Copyright IBM Corporation 2015.
|
5
|
+
#
|
6
|
+
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'chef/knife/hmc_base'
|
10
|
+
|
11
|
+
|
12
|
+
class Chef
|
13
|
+
class Knife
|
14
|
+
class HmcServerCreate < Knife
|
15
|
+
|
16
|
+
include Knife::HmcBase
|
17
|
+
|
18
|
+
deps do
|
19
|
+
require 'net/scp'
|
20
|
+
require 'chef/knife/bootstrap'
|
21
|
+
Chef::Knife::Bootstrap.load_deps
|
22
|
+
end
|
23
|
+
|
24
|
+
banner "knife hmc server create (options)"
|
25
|
+
|
26
|
+
option :nim_host,
|
27
|
+
:short => "-n HOST",
|
28
|
+
:long => "--nim_host HOST",
|
29
|
+
:description => "The fully qualified domain name of the NIM server"
|
30
|
+
|
31
|
+
option :nim_username,
|
32
|
+
:short => "-k USER",
|
33
|
+
:long => "--nim_user USER",
|
34
|
+
:description => "The username for the NIM server"
|
35
|
+
|
36
|
+
option :nim_password,
|
37
|
+
:short => "-m PASSWORD",
|
38
|
+
:long => "--nim_pass PASSWORD",
|
39
|
+
:description => "The password of the user specified in --nim_user"
|
40
|
+
|
41
|
+
option :image,
|
42
|
+
:short => "-I IMAGE",
|
43
|
+
:long => "--image image",
|
44
|
+
:description => "The name of the mksysb image on the NIM."
|
45
|
+
|
46
|
+
option :fb_script,
|
47
|
+
:short => "-d NAME",
|
48
|
+
:long => "--fb_script NAME",
|
49
|
+
:description => "Name of the first boot script to use."
|
50
|
+
|
51
|
+
option :ip_address,
|
52
|
+
:short => "-i IPADDRESS",
|
53
|
+
:long => "--ip_address IPADDRESS",
|
54
|
+
:description => "The IP address to use on the LPAR."
|
55
|
+
|
56
|
+
option :vlan_id,
|
57
|
+
:short => "-N VLANID",
|
58
|
+
:long => "--vlan_id VLANID",
|
59
|
+
:description => "The VLAN ID number the NIC on the LPAR should use. --ip_address should reside in this VLAN."
|
60
|
+
|
61
|
+
option :frame_name,
|
62
|
+
:short => "-f NAME",
|
63
|
+
:long => "--frame NAME",
|
64
|
+
:description => "Name of the Host in which the LPAR resides."
|
65
|
+
|
66
|
+
option :lpar_name,
|
67
|
+
:short => "-l NAME",
|
68
|
+
:long => "--lpar",
|
69
|
+
:description => "Name of LPAR you wish to delete."
|
70
|
+
|
71
|
+
option :vio1_name,
|
72
|
+
:short => "-p NAME",
|
73
|
+
:long => "--primary_vio NAME",
|
74
|
+
:description => "Name of the primary vio."
|
75
|
+
|
76
|
+
option :vio2_name,
|
77
|
+
:short => "-s NAME",
|
78
|
+
:long => "--secondary_vio NAME",
|
79
|
+
:description => "Name of the secondary vio."
|
80
|
+
|
81
|
+
option :min_proc,
|
82
|
+
:short => "-a PROCVAL",
|
83
|
+
:long => "--min_proc PROCVAL",
|
84
|
+
:description => "Minimum Processor Units to use on LPAR."
|
85
|
+
|
86
|
+
option :des_proc,
|
87
|
+
:short => "-b PROCVAL",
|
88
|
+
:long => "--des_proc PROCVAL",
|
89
|
+
:description => "Desired Processor Units to use on LPAR."
|
90
|
+
|
91
|
+
option :max_proc,
|
92
|
+
:short => "-c PROCVAL",
|
93
|
+
:long => "--max_proc PROCVAL",
|
94
|
+
:description => "Maximum Processor Units to use on LPAR."
|
95
|
+
|
96
|
+
option :min_vcpu,
|
97
|
+
:short => "-A PROCVAL",
|
98
|
+
:long => "--min_vcpu PROCVAL",
|
99
|
+
:description => "Minimum virtual CPU to use on LPAR."
|
100
|
+
|
101
|
+
option :des_vcpu,
|
102
|
+
:short => "-B PROCVAL",
|
103
|
+
:long => "--des_vcpu PROCVAL",
|
104
|
+
:description => "Desired virtual CPU to use on LPAR."
|
105
|
+
|
106
|
+
option :max_vcpu,
|
107
|
+
:short => "-C PROCVAL",
|
108
|
+
:long => "--max_vcpu PROCVAL",
|
109
|
+
:description => "Maximum virtual CPU to use on LPAR."
|
110
|
+
|
111
|
+
option :min_mem,
|
112
|
+
:short => "-D PROCVAL",
|
113
|
+
:long => "--min_mem PROCVAL",
|
114
|
+
:description => "Minimum memory to use on LPAR."
|
115
|
+
|
116
|
+
option :des_mem,
|
117
|
+
:short => "-E PROCVAL",
|
118
|
+
:long => "--des_mem PROCVAL",
|
119
|
+
:description => "Desired memory to use on LPAR."
|
120
|
+
|
121
|
+
option :max_mem,
|
122
|
+
:short => "-F PROCVAL",
|
123
|
+
:long => "--max_mem PROCVAL",
|
124
|
+
:description => "Maximum memory to use on LPAR."
|
125
|
+
|
126
|
+
option :size,
|
127
|
+
:short => "-S SIZEINGB",
|
128
|
+
:long => "--size SIZEINGB",
|
129
|
+
:description => "Size in GB of the LUN to use for the rootvg."
|
130
|
+
|
131
|
+
option :register_node,
|
132
|
+
:short => "-r CHEF_SERVER_URL",
|
133
|
+
:long => "--register_node CHEF_SERVER_URL",
|
134
|
+
:description => "Bootstraps this server as a Chef node and registers it with the specified Chef server"
|
135
|
+
|
136
|
+
option :bootstrap_user,
|
137
|
+
:short => "-u BOOTSTRAP_USER",
|
138
|
+
:long => "--bootstrap_user BOOTSTRAP_USER",
|
139
|
+
:description => "User to bootstrap the Chef Node as (if not specified, assumed to be 'root'). Completely ignored if --register_node isn't used"
|
140
|
+
|
141
|
+
option :bootstrap_pass,
|
142
|
+
:short => "-w BOOTSTRAP_PASS",
|
143
|
+
:long => "--bootstrap_pass BOOTSTRAP_PASS",
|
144
|
+
:description => "Password to use on the client LPAR when bootstrapping it. Ignored if --register_node is not specified"
|
145
|
+
|
146
|
+
|
147
|
+
def run
|
148
|
+
Chef::Log.debug("Creating server...")
|
149
|
+
|
150
|
+
validate!([:frame_name,:lpar_name,:vio1_name,:vio2_name,:des_mem,:des_vcpu,:des_proc])
|
151
|
+
#Create Objects
|
152
|
+
hmc = Hmc.new(get_config(:hmc_host), get_config(:hmc_username), {:password => get_config(:hmc_password)})
|
153
|
+
vio1 = Vio.new(hmc, get_config(:frame_name), get_config(:vio1_name))
|
154
|
+
vio2 = Vio.new(hmc, get_config(:frame_name), get_config(:vio2_name))
|
155
|
+
|
156
|
+
#Option checking for LPAR and NIM objects
|
157
|
+
#Since we only technically need desired proc,vcpu, mem to make an lpar we
|
158
|
+
#need to check for the optional flags. And Deploying the OS is optional we
|
159
|
+
#also need to check for those.
|
160
|
+
if validate([:min_mem,:max_mem,:min_vcpu,:max_vcpu,:min_proc,:max_proc])
|
161
|
+
lpar = Lpar.new({:hmc => hmc,:min_proc => get_config(:min_proc),:des_proc => get_config(:des_proc), :max_proc => get_config(:max_proc), :min_mem => get_config(:min_mem), :des_mem => get_config(:des_mem), :max_mem => get_config(:max_mem), :min_vcpu => get_config(:min_vcpu), :des_vcpu => get_config(:des_vcpu), :max_vcpu => get_config(:max_vcpu), :frame => get_config(:frame_name), :name => get_config(:lpar_name)})
|
162
|
+
else
|
163
|
+
lpar = Lpar.new({:hmc => hmc,:des_proc => get_config(:des_proc),:des_mem => get_config(:des_mem),:des_vcpu => get_config(:des_vcpu), :frame => get_config(:frame_name), :name => get_config(:lpar_name)})
|
164
|
+
end
|
165
|
+
|
166
|
+
image_deploy = false
|
167
|
+
first_bootscript = nil
|
168
|
+
if validate([:nim_host,:nim_username,:nim_password,:image,:ip_address,:size,:vlan_id])
|
169
|
+
image_deploy = true
|
170
|
+
nim = Nim.new(get_config(:nim_host),get_config(:nim_username), {:password => get_config(:nim_password)})
|
171
|
+
end
|
172
|
+
|
173
|
+
if image_deploy == true
|
174
|
+
if validate([:fb_script])
|
175
|
+
first_bootscript = get_config(:fb_script)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
#Open connections
|
180
|
+
hmc.connect
|
181
|
+
puts "Connected to #{get_config(:hmc_host)} as #{get_config(:hmc_username)}."
|
182
|
+
if image_deploy == true
|
183
|
+
nim.connect
|
184
|
+
puts "Connected to #{get_config(:nim_host)} as #{get_config(:nim_username)}."
|
185
|
+
end
|
186
|
+
|
187
|
+
#Create LPAR
|
188
|
+
lpar.create
|
189
|
+
puts "LPAR created."
|
190
|
+
|
191
|
+
if image_deploy == true
|
192
|
+
#Add vSCSI adapters
|
193
|
+
lpar.add_vscsi(vio1)
|
194
|
+
lpar.add_vscsi(vio2)
|
195
|
+
puts "vSCSI Adapters added to #{get_config(:lpar_name)}."
|
196
|
+
|
197
|
+
#Get vSCSI information
|
198
|
+
lpar_vscsi = lpar.get_vscsi_adapters
|
199
|
+
|
200
|
+
#Find the vHosts
|
201
|
+
#TO-DO: Need to update the logic here. 1st element doesn't necessarily
|
202
|
+
#have to map to the 1st VIO's vSCSI.
|
203
|
+
first_vhost = vio1.find_vhost_given_virtual_slot(lpar_vscsi[0].remote_slot_num)
|
204
|
+
second_vhost = vio2.find_vhost_given_virtual_slot(lpar_vscsi[1].remote_slot_num)
|
205
|
+
|
206
|
+
#Attach a Disk
|
207
|
+
vio1.map_single_disk_by_size(first_vhost,vio2,second_vhost,get_config(:size).to_i)
|
208
|
+
puts "LUN attached to #{get_config(:lpar_name)}."
|
209
|
+
|
210
|
+
#Attach vNIC, will activate and deactive LPAR to assign MAC address to NIC
|
211
|
+
lpar.create_vnic(get_config(:vlan_id))
|
212
|
+
puts "vNIC attached to #{get_config(:lpar_name)}."
|
213
|
+
|
214
|
+
##Deploy Mksysb, booting LPAR
|
215
|
+
nim.deploy_image(lpar,get_config(:image),first_bootscript) do |nimIp,gw,snm|
|
216
|
+
hmc.lpar_net_boot(nimIp,get_config(:ip_address),gw,snm,lpar)
|
217
|
+
end
|
218
|
+
puts "#{get_config(:image)} deployed to #{get_config(:lpar_name)}."
|
219
|
+
end
|
220
|
+
|
221
|
+
if image_deploy == true
|
222
|
+
nim.disconnect
|
223
|
+
puts "Disconnected from #{get_config(:nim_host)}."
|
224
|
+
|
225
|
+
#Check to see if the :register_node option has been specified
|
226
|
+
#since we can only connect to bootstrap this server if it has
|
227
|
+
#a working OS on it.
|
228
|
+
if validate([:register_node])
|
229
|
+
#Branch here in case we can use Chef::Knife::Bootstrap
|
230
|
+
#to handle this sometime in the future. For now, hardcode the
|
231
|
+
#manual bootstrap
|
232
|
+
manual_bootstrap = true
|
233
|
+
|
234
|
+
#Wait here until the client is alive
|
235
|
+
print "Bootstrapping client. Waiting for sshd..."
|
236
|
+
print "." until tcp_ssh_alive(get_config(:ip_address))
|
237
|
+
puts "done\nInitiating bootstrap."
|
238
|
+
|
239
|
+
if manual_bootstrap
|
240
|
+
manual_bootstrap_for_node
|
241
|
+
else
|
242
|
+
bootstrap_for_node
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
#Close connection
|
248
|
+
hmc.disconnect
|
249
|
+
puts "Disconnected from #{get_config(:hmc_host)}."
|
250
|
+
|
251
|
+
puts "Successfully created #{get_config(:lpar_name)}."
|
252
|
+
end
|
253
|
+
|
254
|
+
#Manually execute the Chef bootstrap of an AIX server
|
255
|
+
def manual_bootstrap_for_node
|
256
|
+
validate!([:bootstrap_pass])
|
257
|
+
|
258
|
+
#Where the validation pem and chef-client exist on
|
259
|
+
#the chef workstation this is run from
|
260
|
+
validation_pem_path = Chef::Config[:validation_key]
|
261
|
+
puts "Using client key #{validation_pem_path}"
|
262
|
+
chef_client_path = Chef::Config[:knife][:chef_client_aix_path]
|
263
|
+
puts "Using chef-client located in #{chef_client_path}"
|
264
|
+
|
265
|
+
if validation_pem_path.nil? or chef_client_path.nil?
|
266
|
+
puts "No client validation pem or chef-client installable specified in knife.rb. Skipping Chef Bootstrap..."
|
267
|
+
return nil
|
268
|
+
end
|
269
|
+
|
270
|
+
#Where to place these files on the target server
|
271
|
+
remote_chef_client_path = "/tmp/2014-02-06-chef.11.10.0.0.bff"
|
272
|
+
remote_validation_pem_path = "/etc/chef/validation.pem"
|
273
|
+
|
274
|
+
#For some reason, Net::SSH and Net::SCP only work on
|
275
|
+
#AIX using :kex => "diffie-hellman-group1-sha1" and
|
276
|
+
# :encryption => ["blowfish-cbc", "3des-cbc"]
|
277
|
+
# :paranoid => false (avoids host key verification)
|
278
|
+
Net::SSH.start(get_config(:ip_address),
|
279
|
+
get_config(:bootstrap_user) || "root",
|
280
|
+
:password => get_config(:bootstrap_pass),
|
281
|
+
:kex => "diffie-hellman-group1-sha1",
|
282
|
+
:encryption => ["blowfish-cbc", "3des-cbc"],
|
283
|
+
:paranoid => false) do |ssh|
|
284
|
+
|
285
|
+
#Copy the chef-client .bff file to the client machine in /tmp
|
286
|
+
puts "Copying chef client binary to client"
|
287
|
+
ssh.scp.upload!(chef_client_path, remote_chef_client_path)
|
288
|
+
|
289
|
+
#Run the install command
|
290
|
+
puts "Running chef client install"
|
291
|
+
output = ssh.exec!("installp -aYFq -d #{remote_chef_client_path} chef")
|
292
|
+
Chef::Log.debug("Chef Client install output:\n#{output}")
|
293
|
+
|
294
|
+
#Run the configure client command
|
295
|
+
puts "Running knife configure client command"
|
296
|
+
output = ssh.exec!("knife configure client -s #{get_config(:register_node)} /etc/chef")
|
297
|
+
Chef::Log.debug("Knife Configure output:\n#{output}")
|
298
|
+
|
299
|
+
#Copy the validation key to /etc/chef on the client
|
300
|
+
puts "Uploading validation.pem to client"
|
301
|
+
ssh.scp.upload!(validation_pem_path, remote_validation_pem_path)
|
302
|
+
|
303
|
+
#Edit /etc/chef/client.rb so that it points at the location of the validator
|
304
|
+
puts "Adding validator key path to client.rb"
|
305
|
+
cmd = %Q{echo "validator_key '#{remote_validation_pem_path}'" >> /etc/chef/client.rb}
|
306
|
+
output = ssh.exec!(cmd)
|
307
|
+
Chef::Log.debug("#{output}")
|
308
|
+
|
309
|
+
#Register the client node with the Chef server, by running chef-client
|
310
|
+
#Add additional handling of this command to determine if the chef-client
|
311
|
+
#run finished successfully or not.
|
312
|
+
puts "Running chef-client to register as a Chef node"
|
313
|
+
output = ""
|
314
|
+
stderr_out = ""
|
315
|
+
exit_code = nil
|
316
|
+
ssh.exec("chef-client") do |ch, success|
|
317
|
+
unless success
|
318
|
+
abort "FAILED: chef-client command failed to execute on client"
|
319
|
+
end
|
320
|
+
ch.on_data do |ch,data|
|
321
|
+
output+=data
|
322
|
+
end
|
323
|
+
ch.on_extended_data do |ch,type,data|
|
324
|
+
stderr_out+=data
|
325
|
+
end
|
326
|
+
ch.on_request("exit-status") do |ch,data|
|
327
|
+
exit_code = data.read_long
|
328
|
+
end
|
329
|
+
end
|
330
|
+
ssh.loop
|
331
|
+
if exit_code != 0
|
332
|
+
puts "Initial chef-client run failed. Please verify client settings and rerun chef-client to register this server as a node with #{get_config(:register_node)}"
|
333
|
+
return nil
|
334
|
+
end
|
335
|
+
Chef::Log.debug("chef-client command output:\n#{output}")
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
#Bootstrapping a Chef node using all Chef faculties
|
340
|
+
#TO-DO: fix up the body of this once normal bootstrap
|
341
|
+
#works on AIX nodes.
|
342
|
+
def bootstrap_for_node
|
343
|
+
bootstrap = Chef::Knife::Bootstrap.new
|
344
|
+
bootstrap.name_args = [config[:fqdn]]
|
345
|
+
bootstrap.config[:run_list] = get_config(:run_list).split(/[\s,]+/)
|
346
|
+
bootstrap.config[:secret_file] = get_config(:secret_file)
|
347
|
+
bootstrap.config[:hint] = get_config(:hint)
|
348
|
+
bootstrap.config[:ssh_user] = get_config(:ssh_user)
|
349
|
+
bootstrap.config[:ssh_password] = get_config(:ssh_password)
|
350
|
+
bootstrap.config[:ssh_port] = get_config(:ssh_port)
|
351
|
+
bootstrap.config[:identity_file] = get_config(:identity_file)
|
352
|
+
bootstrap.config[:chef_node_name] = get_config(:chef_node_name)
|
353
|
+
bootstrap.config[:prerelease] = get_config(:prerelease)
|
354
|
+
bootstrap.config[:bootstrap_version] = get_config(:bootstrap_version)
|
355
|
+
bootstrap.config[:distro] = get_config(:distro)
|
356
|
+
bootstrap.config[:use_sudo] = true unless get_config(:ssh_user) == 'root'
|
357
|
+
bootstrap.config[:template_file] = get_config(:template_file)
|
358
|
+
bootstrap.config[:environment] = get_config(:environment)
|
359
|
+
bootstrap.config[:first_boot_attributes] = get_config(:first_boot_attributes)
|
360
|
+
bootstrap.config[:log_level] = get_config(:log_level)
|
361
|
+
# may be needed for vpc_mode
|
362
|
+
bootstrap.config[:no_host_key_verify] = get_config(:no_host_key_verify)
|
363
|
+
bootstrap
|
364
|
+
end
|
365
|
+
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|