Class: Nim
- Inherits:
-
ConnectableServer
- Object
- ConnectableServer
- Nim
- Defined in:
- lib/rbvppc/nim.rb
Instance Attribute Summary
Attributes inherited from ConnectableServer
Instance Method Summary collapse
- #add_default_route(network_name, gateway) ⇒ Object
-
#add_image(file_path, mksysb_name) ⇒ Object
Add a mksysb image to this NIM based on the name given and the local file path of the mksysb file on the NIM.
-
#add_network(network_name, network_addr, snm, gw) ⇒ Object
Add a NIM network object using the given name, network address, subnet mask, gateway.
-
#bid_exists?(client_lpar) ⇒ Boolean
Checks if BID object exists on NIM for the Client LPAR.
-
#bos_install_finished?(lpar) ⇒ Boolean
Used in populating the BOS Install status message Returns true of the specified lpar is done with is BOS build.
-
#capture_image(source_lpar, mksysb_name, path) ⇒ Object
Capture a mksysb image from a NIM client.
-
#check_install_status(client_lpar) ⇒ Object
Check the install status of a NIM client Returns current Cstate attribute of NIM client.
-
#client_defined?(client_lpar) ⇒ Boolean
Is the NIM Client defined?.
-
#create_bid(client_lpar) ⇒ Object
Creates a bosinst_data object for the client_lpar specified.
-
#deallocate_resources(client_lpar) ⇒ Object
Deallocates any/all NIM resources from the client manchine.
-
#define_client(client_lpar) ⇒ Object
Define the NIM Client.
-
#deploy_image(client_lpar, mksysb_name, firstboot_script = nil, lpp_source = nil) {|nim_ip, gateway, subnetmask| ... } ⇒ Object
Deploy mksysb image to NIM client.
-
#execute_cmd(command) ⇒ Object
Execute commands on NIM, outputting the full command with puts first.
-
#extract_spot(mksysb_name) ⇒ Object
Extracts a SPOT from the mksysb image name specified.
-
#get_lpar_network_name(client_lpar) ⇒ Object
Find NIM interface settings for client LPAR.
-
#get_master_ip ⇒ Object
Returns the IP address of the NIM master as a String.
-
#get_mksysb_location(mksysb_name) ⇒ Object
Returns the filesystem location of the mksysb with the specified name.
-
#get_network_gateway(network_name) ⇒ Object
Find Gateway IP for NIM network.
-
#get_network_subnetmask(network_name) ⇒ Object
Find Subnet mask for NIM network.
-
#get_spot(mksysb_name) ⇒ Object
Returns the name of the SPOT extracted from the supplied mksysb.
-
#list_images ⇒ Object
Return an array of names of mksysbs that exist on this NIM.
-
#list_objtype(type) ⇒ Object
list all defined objects of a specific type acceptable types are (standalone,ent,lpp_source,mksysb,spot,fb_script,script,bosinst_data,ent).
-
#master_netboot_kernel ⇒ Object
Pull the netboot_kernel attribute from NIM master object.
-
#network_exists?(network_name, network_addr = nil) ⇒ Boolean
Returns true if a network object exists on the NIM with either the specified name or network address.
-
#remove_bid(client_lpar) ⇒ Object
Remove the NIM BID object for a client LPAR.
-
#remove_client(client_lpar) ⇒ Object
Remove a NIM client.
-
#remove_image(mksysb_name) ⇒ Object
Removes a mksysb from the NIM that identifies with the name specified.
-
#remove_network(network_name, network_addr = nil) ⇒ Object
Remove a NIM network given it’s name and/or it’s network address.
-
#remove_spot(spot_name) ⇒ Object
Removes a SPOT object from a NIM based on the name.
-
#reset_client(client_lpar) ⇒ Object
Reset a NIM client.
Methods inherited from ConnectableServer
#connect, #connected?, #disconnect, #initialize, #toggle_debug
Constructor Details
This class inherits a constructor from ConnectableServer
Instance Method Details
#add_default_route(network_name, gateway) ⇒ Object
438 439 440 441 |
# File 'lib/rbvppc/nim.rb', line 438 def add_default_route(network_name,gateway) #TODO: Add more robust creation/management of NIM network routes, if necessary execute_cmd("nim -o change -a routing1='default #{gateway}' #{network_name}") end |
#add_image(file_path, mksysb_name) ⇒ Object
Add a mksysb image to this NIM based on the name given and the local file path of the mksysb file on the NIM. Returns the name of the image that is created.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/rbvppc/nim.rb', line 143 def add_image(file_path,mksysb_name) #Check to make sure a mksysb with this name doesn't already exist images = list_images if images.include?(mksysb_name) raise StandardError.new("A mksysb with the specified name #{mksysb_name} already exists, please specify another name") end #Add image to the NIM execute_cmd "nim -o define -t mksysb -F -a server=master -a location=#{file_path} -a mksysb_flags=XAe #{mksysb_name}" #Extract a SPOT from this mksysb extract_spot(mksysb_name) return mksysb_name end |
#add_network(network_name, network_addr, snm, gw) ⇒ Object
Add a NIM network object using the given name, network address, subnet mask, gateway
398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/rbvppc/nim.rb', line 398 def add_network(network_name,network_addr,snm,gw) #Ensure that network with this address doesn't already exist raise StandardError.new("Network #{network_name} already exists on this NIM") if network_exists?(network_name,network_addr) #Execute NIM command to create the network #It is assumed that the network addess and the gateway are the same execute_cmd("nim -o define -t ent -a net_addr=#{network_addr} -a snm=#{snm} #{network_name}") #Add default route to the specified gateway add_default_route(network_name,gw) end |
#bid_exists?(client_lpar) ⇒ Boolean
Checks if BID object exists on NIM for the Client LPAR
345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/rbvppc/nim.rb', line 345 def bid_exists?(client_lpar) defined_bids = list_objtype("bosinst_data") defined_bids.each do |obj_name| #Iterate through array elements returned by list_objtype #and check if any of them line up with the BID name for our LPAR if (obj_name == "#{client_lpar.name}_bid") #if (obj_name == "#{client_lpar}_bid") return true end end return false end |
#bos_install_finished?(lpar) ⇒ Boolean
Used in populating the BOS Install status message Returns true of the specified lpar is done with is BOS build. Sleeps for 15 seconds and returns false if otherwise.
230 231 232 233 234 235 236 237 |
# File 'lib/rbvppc/nim.rb', line 230 def bos_install_finished?(lpar) if check_install_status(lpar).match(/ready for a NIM operation/i) return true else sleep 15 return false end end |
#capture_image(source_lpar, mksysb_name, path) ⇒ Object
Capture a mksysb image from a NIM client
132 133 134 135 136 137 138 |
# File 'lib/rbvppc/nim.rb', line 132 def capture_image(source_lpar,mksysb_name,path) #Pull mksysb from a NIM client, give it a name and place it in some location on the NIM execute_cmd "nim -o define -t mksysb -F -a server=master -a location=#{path} -a source=#{source_lpar.name} -a mk_image=yes -a mksysb_flags=XAe #{mksysb_name}" #Create SPOT resource from this mksysb, giving it a name and a location on the NIM to store it extract_spot(mksysb_name) end |
#check_install_status(client_lpar) ⇒ Object
Check the install status of a NIM client Returns current Cstate attribute of NIM client
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/rbvppc/nim.rb', line 111 def check_install_status(client_lpar) #lsnim -Z -a Cstate -a Mstate -a Cstate_result -a info nim_client_name result = execute_cmd "lsnim -Z -a Cstate -a Mstate -a Cstate_result -a info #{client_lpar.name}" #result = execute_cmd "lsnim -Z -a Cstate -a Mstate -a Cstate_result -a info #{client_lpar}" result.each_line do |line| line.match(/#{client_lpar.name}/) do |m| #line.match(/#{client_lpar}/) do |m| #Cstate is the 2nd column of the : delimited output cstate = line.split(/:/)[1] return cstate end end return nil end |
#client_defined?(client_lpar) ⇒ Boolean
Is the NIM Client defined?
54 55 56 57 58 59 60 |
# File 'lib/rbvppc/nim.rb', line 54 def client_defined?(client_lpar) #lsnim -Z lpar_name_here 2>/dev/null | awk '(NR==2) {print $1}' | awk -F: '{print $2}' #result = execute_cmd "lsnim -Z #{client_lpar} 2>/dev/null | " + result = execute_cmd "lsnim -Z #{client_lpar.name} 2>/dev/null | " + "awk '(NR==2) {print $1}' | awk -F: '{print $2}'" return result.chomp == "machines" end |
#create_bid(client_lpar) ⇒ Object
Creates a bosinst_data object for the client_lpar specified
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/rbvppc/nim.rb', line 303 def create_bid(client_lpar) if bid_exists?(client_lpar) #Force remove the BID and then continue to create a new one. remove_bid(client_lpar) end #Use heredoc to populate the bosinst_data file in a multiline string bid_contents = <<-EOS # bosinst_data file created for #{client_lpar.name} CONSOLE = Default RECOVER_DEVICES = no INSTALL_METHOD = overwrite PROMPT = no EXISTING_SYSTEM_OVERWRITE = any ACCEPT_LICENSES = yes locale: BOSINST_LANG = en_US CULTURAL_CONVENTION = en_US MESSAGES = en_US KEYBOARD = en_US EOS #Create bid contents file on NIM execute_cmd "mkdir -p /darwin; echo '#{bid_contents}' > /darwin/#{client_lpar.name}_bid" #Define the BID object execute_cmd "nim -o define -t bosinst_data -a location=/darwin/#{client_lpar.name}_bid -a server=master #{client_lpar.name}_bid" #Return the name of the BID created return "#{client_lpar.name}_bid" end |
#deallocate_resources(client_lpar) ⇒ Object
Deallocates any/all NIM resources from the client manchine
99 100 101 |
# File 'lib/rbvppc/nim.rb', line 99 def deallocate_resources(client_lpar) execute_cmd "nim -o deallocate -a subclass=all #{client_lpar.name}" end |
#define_client(client_lpar) ⇒ Object
Define the NIM Client
63 64 65 66 67 68 69 |
# File 'lib/rbvppc/nim.rb', line 63 def define_client(client_lpar) if client_defined?(client_lpar) remove_client(client_lpar) end execute_cmd %Q{nim -o define -t standalone -a if1="find_net #{client_lpar.hostname} #{client_lpar.get_mac_address}" -a cable_type1="N/A" -a platform=chrp -a comments="Built by Darwin" -a net_settings1="auto auto" -a connect="shell" -a netboot_kernel=#{master_netboot_kernel} #{client_lpar.name}} #execute_cmd %Q{nim -o define -t standalone -a if1="find_net #{hostname} #{mac}" -a cable_type1="N/A" -a platform=chrp -a comments="Built by Darwin" -a net_settings1="auto auto" -a connect="shell" -a netboot_kernel=#{master_netboot_kernel} #{client_lpar}} end |
#deploy_image(client_lpar, mksysb_name, firstboot_script = nil, lpp_source = nil) {|nim_ip, gateway, subnetmask| ... } ⇒ Object
Deploy mksysb image to NIM client
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/rbvppc/nim.rb', line 180 def deploy_image(client_lpar, mksysb_name, firstboot_script = nil, lpp_source = nil) bosinst_data_obj = client_lpar.name+"_bid" #Create a NIM Client and a bosinst_data object if they don't #already exist for this LPAR. define_client(client_lpar) if !client_defined?(client_lpar) create_bid(client_lpar) if !bid_exists?(client_lpar) if !lpp_source.nil? #TODO: Do something different if an lpp_source is specified... end #Get the SPOT to use for this image deployment spot_name = get_spot(mksysb_name) if spot_name.nil? #Extract the spot from this mksysb and use it spot_name = extract_spot(mksysb_name) end command = "nim -o bos_inst -a source=mksysb -a mksysb=#{mksysb_name} -a bosinst_data=#{bosinst_data_obj} -a no_nim_client=no " + "-a accept_licenses=yes -a boot_client=no" command += " -a spot=#{spot_name}" if !spot_name.nil? command += " -a fb_script=#{firstboot_script}" if !firstboot_script.nil? command += " -a lpp_source=#{lpp_source}" if !lpp_source.nil? command += " #{client_lpar.name}" #NIM command to start a remote mksysb install on NIM client execute_cmd(command) #Then, in order to actually start the install the HMC needs to netboot the LPAR #Should that be called from here or just utilized separately from the HMC object? #Maybe yeild to a block that should call the HMC LPAR netboot? #Then upon returning to this function, we poll the NIM client for Cstate statuses #until the build is finished? network_name = get_lpar_network_name(client_lpar) gateway = get_network_gateway(network_name) subnetmask = get_network_subnetmask(network_name) nim_ip = get_master_ip yield(nim_ip,gateway,subnetmask) #Implemented nicer looking progress message for BOS installs print "Waiting for BOS install for #{client_lpar.name} to finish..." print "." until bos_install_finished?(client_lpar) puts "done" end |
#execute_cmd(command) ⇒ Object
Execute commands on NIM, outputting the full command with puts first.
29 30 31 32 |
# File 'lib/rbvppc/nim.rb', line 29 def execute_cmd(command) puts "#{command}" if debug super "#{command}" end |
#extract_spot(mksysb_name) ⇒ Object
Extracts a SPOT from the mksysb image name specified. places the SPOT in a directory location adjacent to where the mksysb resides If a spot already exists for this mksysb, it’s name is simply returned.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/rbvppc/nim.rb', line 260 def extract_spot(mksysb_name) #Find out if this mksysb exists on the NIM if !list_objtype("mksysb").include?(mksysb_name) #Mksysb not found - error out? end spot_name = mksysb_name+"_spot" #Find out if a SPOT already exists for this mksysb #if so, just return that name. temp_name = get_spot(mksysb_name) if !temp_name.nil? return temp_name end #Get the location of this mksysb mksysb_loc = get_mksysb_location(mksysb_name) #Make sure the mksysb location is non-null raise StandardError.new("Cannot locate where the image #{mksysb_name} exists on this NIM") if mksysb_loc.nil? #Split the mksysb location on '/', pop the mksysb name and directory it resides #in off of the array and push "spot" and the spot name onto the array to end up placing #the SPOT in ../spot/spot_name split_mksysb_path = mksysb_loc.split("/") split_mksysb_path.pop split_mksysb_path.pop split_mksysb_path.push("spot") split_mksysb_path.push(mksysb_name+"_spot") spot_path = split_mksysb_path.join("/") #Make a SPOT from this mksysb with the name <mksysb_name>_spot execute_cmd("nim -o define -t spot -a server=master -a source=#{mksysb_name} -a location=#{spot_path} -a auto_expand=yes #{spot_name}") #Return the name of the SPOT. return spot_name end |
#get_lpar_network_name(client_lpar) ⇒ Object
Find NIM interface settings for client LPAR
359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/rbvppc/nim.rb', line 359 def get_lpar_network_name(client_lpar) output = execute_cmd "lsnim -Z -a if1 #{client_lpar.name}" nim_network="" output.each_line do |line| line.chomp! if line.match(/^#{client_lpar.name}/) network_args = line.split(/:/) nim_network = network_args[1] end end return nim_network end |
#get_master_ip ⇒ Object
Returns the IP address of the NIM master as a String
78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/rbvppc/nim.rb', line 78 def get_master_ip niminfo_line = execute_cmd("cat /etc/niminfo | grep NIM_MASTER_HOSTNAME") hostname = niminfo_line.split("=")[1].chomp ipaddr_line = execute_cmd("host #{hostname}") ip = ipaddr_line.split(" is ")[1].chomp if ip.empty? raise StandardError.new("Unable to determine the NIM Master's IP Address") end return ip end |
#get_mksysb_location(mksysb_name) ⇒ Object
Returns the filesystem location of the mksysb with the specified name
240 241 242 |
# File 'lib/rbvppc/nim.rb', line 240 def get_mksysb_location(mksysb_name) execute_cmd("lsnim -l #{mksysb_name} | awk '{if ($1 ~ /location/) print $3}'").chomp end |
#get_network_gateway(network_name) ⇒ Object
Find Gateway IP for NIM network
373 374 375 376 377 378 379 380 381 382 |
# File 'lib/rbvppc/nim.rb', line 373 def get_network_gateway(network_name) output = execute_cmd "lsnim -Z -a net_addr -a snm -a routing #{network_name}" output.each_line do |line| line.chomp! if line.match(/^#{network_name}/) network_fields = line.split(/:/) return network_fields[-1] end end end |
#get_network_subnetmask(network_name) ⇒ Object
Find Subnet mask for NIM network
385 386 387 388 389 390 391 392 393 394 |
# File 'lib/rbvppc/nim.rb', line 385 def get_network_subnetmask(network_name) output = execute_cmd "lsnim -Z -a net_addr -a snm -a routing #{network_name}" output.each_line do |line| line.chomp! if line.match(/^#{network_name}/) network_fields = line.split(/:/) return network_fields[2] end end end |
#get_spot(mksysb_name) ⇒ Object
Returns the name of the SPOT extracted from the supplied mksysb
246 247 248 249 250 251 252 253 |
# File 'lib/rbvppc/nim.rb', line 246 def get_spot(mksysb_name) spot = execute_cmd("lsnim -l #{mksysb_name} | awk '{if ($1 ~ /extracted_spot/) print $3}'").chomp if spot.empty? return nil else return spot end end |
#list_images ⇒ Object
Return an array of names of mksysbs that exist on this NIM
127 128 129 |
# File 'lib/rbvppc/nim.rb', line 127 def list_images list_objtype("mksysb") end |
#list_objtype(type) ⇒ Object
list all defined objects of a specific type acceptable types are (standalone,ent,lpp_source,mksysb,spot,fb_script,script,bosinst_data,ent)
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/rbvppc/nim.rb', line 36 def list_objtype(type) case type when "standalone","ent","lpp_source","mksysb","spot","fb_script","script","bosinst_data" output = execute_cmd "lsnim -t #{type}" else raise StandardError.new("Unknown type of NIM Object passed") end objects = [] output.each_line do |line| line.chomp! columns = line.split(/[[:blank:]]+/) objects.push(columns[0]) if !columns[0].empty? end return objects end |
#master_netboot_kernel ⇒ Object
Pull the netboot_kernel attribute from NIM master object
72 73 74 75 |
# File 'lib/rbvppc/nim.rb', line 72 def master_netboot_kernel result = execute_cmd "lsnim -l master | awk '{if ($1 ~ /netboot_kernel/) print $3}'" return result.chomp end |
#network_exists?(network_name, network_addr = nil) ⇒ Boolean
Returns true if a network object exists on the NIM with either the specified name or network address. Returns false otherwise.
423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/rbvppc/nim.rb', line 423 def network_exists?(network_name,network_addr=nil) network_names = list_objtype("ent") if network_names.include?(network_name) return true end network_names.each do |net_name| address = execute_cmd("lsnim -l #{net_name} | awk '{if ($1 ~ /net_addr/) print $3}'").chomp if address == network_addr return true end end return false end |
#remove_bid(client_lpar) ⇒ Object
Remove the NIM BID object for a client LPAR
339 340 341 342 |
# File 'lib/rbvppc/nim.rb', line 339 def remove_bid(client_lpar) execute_cmd "nim -F -o remove #{client_lpar.name}_bid" #execute_cmd "nim -F -o remove #{client_lpar}_bid" end |
#remove_client(client_lpar) ⇒ Object
Remove a NIM client
104 105 106 107 |
# File 'lib/rbvppc/nim.rb', line 104 def remove_client(client_lpar) deallocate_resources(client_lpar) execute_cmd "nim -F -o remove #{client_lpar.name}" end |
#remove_image(mksysb_name) ⇒ Object
Removes a mksysb from the NIM that identifies with the name specified. Attempts to remove the SPOT that was extracted from this mksysb first.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/rbvppc/nim.rb', line 161 def remove_image(mksysb_name) #Find if this mksysb actually exists on the NIM images = list_images if !images.include?(mksysb_name) warn "#{mksysb_name} does not exist on this NIM." return end #Find and remove the SPOT for this mksysb spot_name = get_spot(mksysb_name) if !spot_name.nil? remove_spot(spot_name) end #Remove the mksysb from the NIM (along with it's mksysb file) execute_cmd("nim -o remove -a rm_image=yes #{mksysb_name}") end |
#remove_network(network_name, network_addr = nil) ⇒ Object
Remove a NIM network given it’s name and/or it’s network address
412 413 414 415 416 417 418 |
# File 'lib/rbvppc/nim.rb', line 412 def remove_network(network_name,network_addr=nil) #Ensure that the network to remove is actually defined currently raise StandardError.new("Network #{network_name} does not exist on this NIM to be removed") if !network_exists?(network_name,network_addr) #Run command that removes this network from the NIM execute_cmd("nim -Fo remove #{network_name}") end |
#remove_spot(spot_name) ⇒ Object
Removes a SPOT object from a NIM based on the name
298 299 300 |
# File 'lib/rbvppc/nim.rb', line 298 def remove_spot(spot_name) execute_cmd("nim -Fo remove #{spot_name}") end |
#reset_client(client_lpar) ⇒ Object
Reset a NIM client
93 94 95 96 |
# File 'lib/rbvppc/nim.rb', line 93 def reset_client(client_lpar) execute_cmd "nim -F -o reset #{client_lpar.name}" #execute_cmd "nim -F -o reset #{client_lpar}" end |