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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3bcc750013a4018b14ffe0bcc02c18db42f31df1
|
4
|
+
data.tar.gz: fb803c448f5e835d188638363b02f95412428bdb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7f87452613f678c89917a6a51fec584cfd6788456ee1216053a7238786533de1722571904833aa8e4f019a13102ea8f5f412db116065bb2b8e8843e5542ccfcb
|
7
|
+
data.tar.gz: ccc414ceeae6e6b383f47f7435dccff86b27308b67bc39ea72db89aea1c3fca4a9cacf87572d8df3613effb8318fe4c6a2ee72f6960efa1ac25f2b7567cf7fe8
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
© Copyright IBM Corporation 2014.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# Knife::Hmc
|
2
|
+
|
3
|
+
A Chef Knife plugin for creating, deleting, bootstrapping, and managing LPARs and P series virtual infrastructure.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'knife-hmc'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install knife-hmc
|
18
|
+
|
19
|
+
## Configuration
|
20
|
+
Add the path to the chef-client AIX installable on your Chef Server to your `knife.rb` file
|
21
|
+
to add support for Chef bootstrapping an AIX node as a part of 'knife hmc server create'.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
log_level :info
|
25
|
+
log_location STDOUT
|
26
|
+
node_name 'node'
|
27
|
+
client_key '/path/to/key.pem'
|
28
|
+
validation_client_name 'some-validator'
|
29
|
+
validation_key '/path/to/validator.pem'
|
30
|
+
chef_server_url 'https://example.com/organizations/org'
|
31
|
+
syntax_check_cache_path '/path/to/syntax_check_cache'
|
32
|
+
knife[:chef_client_aix_path] = "<CHEF SERVER LOCAL PATH TO AIX BINARY>"
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
See `knife hmc SUBCOMMAND --help` for help on usage. Here are subcommands that usage help
|
38
|
+
can be provided for:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
knife hmc server create --help
|
42
|
+
knife hmc server delete --help
|
43
|
+
knife hmc server config --help
|
44
|
+
knife hmc server list --help
|
45
|
+
|
46
|
+
knife hmc image list --help
|
47
|
+
|
48
|
+
knife hmc disk list --help
|
49
|
+
knife hmc disk add --help
|
50
|
+
knife hmc disk remove --help
|
51
|
+
```
|
52
|
+
|
53
|
+
EXAMPLES:
|
54
|
+
|
55
|
+
|
56
|
+
```bash
|
57
|
+
# look at all the LPARs on a frame or in an environment
|
58
|
+
user@local> knife hmc server list --hmc_host testhmc.us.ibm.com --hmc_user hscroot --hmc_pass passw0rd \
|
59
|
+
[--frame FRAME]
|
60
|
+
```
|
61
|
+
|
62
|
+
```bash
|
63
|
+
# LPAR creation and BOS install with the minimum arguments
|
64
|
+
user@local> knife hmc server create --hmc_host testhmc.us.ibm.com --hmc_user hscroot --hmc_pass passw0rd \
|
65
|
+
--frame test_frame \
|
66
|
+
--lpar test_lpar \
|
67
|
+
--primary_vio test_vio1 \
|
68
|
+
--secondary_vio test_vio2 \
|
69
|
+
--des_proc 2.0 \
|
70
|
+
--des_vcpu 2 \
|
71
|
+
--des_mem 2048 \
|
72
|
+
--nim_host testnim.us.ibm.com \
|
73
|
+
--nim_user root \
|
74
|
+
--nim_pass passw0rd \
|
75
|
+
--image image_name \
|
76
|
+
--ip_address lpar_ip \
|
77
|
+
--size 90 \
|
78
|
+
--vlan_id vlan \
|
79
|
+
--register_node chef_server_url \
|
80
|
+
--bootstrap_pass passw0rd
|
81
|
+
```
|
82
|
+
|
83
|
+
```bash
|
84
|
+
# List all of the images that an environment's
|
85
|
+
# NIM can deploy
|
86
|
+
user@local> knife hmc image list --nim_host testnim.us.ibm.com --nim_user root --nim_pass passw0rd
|
87
|
+
```
|
88
|
+
|
89
|
+
```bash
|
90
|
+
# List all of this disks
|
91
|
+
# that a VIO pair has access to
|
92
|
+
user@local> knife hmc disk list --hmc_host testhmc.us.ibm.com --hmc_user hscroot --hmc_pass passw0rd \
|
93
|
+
--primary_vio test_vio_1 \
|
94
|
+
--secondary_vio test_vio_2 \
|
95
|
+
--frame test_frame \
|
96
|
+
[--lpar test_lpar_name | --available | --used]
|
97
|
+
```
|
98
|
+
|
99
|
+
#### Legal stuff
|
100
|
+
Use of this software requires runtime dependencies. Those dependencies and their respective software licenses are listed below.
|
101
|
+
|
102
|
+
* [net-ssh](https://github.com/net-ssh/net-ssh/) - LICENSE: [MIT](https://github.com/net-ssh/net-ssh/blob/master/LICENSE.txt)
|
103
|
+
* [net-scp](https://github.com/net-ssh/net-scp/) - LICENSE: [MIT](https://github.com/net-ssh/net-scp/blob/master/LICENSE.txt)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/knife-hmc.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'knife-hmc/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "knife-hmc"
|
8
|
+
spec.version = Knife::Hmc::VERSION
|
9
|
+
spec.authors = ["John J. Rofrano,Christopher M. Wood, John F. Hutchinson"]
|
10
|
+
spec.email = ["rofrano@us.ibm.com, woodc@us.ibm.com, jfhutchi@us.ibm.com"]
|
11
|
+
spec.summary = %q{IBM Hardware Management Console support for Chef's Knife Command}
|
12
|
+
spec.description = "Knife plugin for use with IBM Hardware Management Console"
|
13
|
+
spec.homepage = "http://github.com/pseries/knife-hmc"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency("rbvppc", "~> 1.0.0")
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake", "~> 0"
|
25
|
+
spec.required_ruby_version = '>= 2.1.0'
|
26
|
+
end
|
@@ -0,0 +1,131 @@
|
|
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 'knife-hmc/version'
|
10
|
+
|
11
|
+
class Chef
|
12
|
+
class Knife
|
13
|
+
module HmcBase
|
14
|
+
|
15
|
+
# :nodoc:
|
16
|
+
#####################################################
|
17
|
+
# included
|
18
|
+
#####################################################
|
19
|
+
def self.included(includer)
|
20
|
+
includer.class_eval do
|
21
|
+
|
22
|
+
deps do
|
23
|
+
require 'chef/json_compat'
|
24
|
+
require 'chef/knife'
|
25
|
+
require 'readline'
|
26
|
+
require 'rbvppc'
|
27
|
+
require 'netaddr'
|
28
|
+
Chef::Knife.load_deps
|
29
|
+
end
|
30
|
+
|
31
|
+
option :hmc_host,
|
32
|
+
:short => "-h HOST",
|
33
|
+
:long => "--hmc_host HOST",
|
34
|
+
:description => "The fully qualified domain name of the HMC host",
|
35
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:hmc_host] = key }
|
36
|
+
|
37
|
+
option :hmc_username,
|
38
|
+
:short => "-U USERNAME",
|
39
|
+
:long => "--hmc_user USERNAME",
|
40
|
+
:description => "The username for the HMC",
|
41
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:hmc_username] = key }
|
42
|
+
|
43
|
+
option :hmc_password,
|
44
|
+
:short => "-P PASSWORD",
|
45
|
+
:long => "--hmc_pass PASSWORD",
|
46
|
+
:description => "The password for hmc",
|
47
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:hmc_password] = key }
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#####################################################
|
53
|
+
# tcp_ssh_alive
|
54
|
+
# Returns true if the hostname specified is
|
55
|
+
# accepting SSH connections. Returns false otherwise
|
56
|
+
#####################################################
|
57
|
+
def tcp_ssh_alive(hostname,port=22)
|
58
|
+
tcp_socket = TCPSocket.new(hostname, port)
|
59
|
+
readable = IO.select([tcp_socket], nil, nil, 5)
|
60
|
+
if readable
|
61
|
+
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
|
62
|
+
true
|
63
|
+
else
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
rescue Errno::ETIMEDOUT
|
68
|
+
false
|
69
|
+
rescue Errno::EPERM
|
70
|
+
false
|
71
|
+
rescue Errno::ECONNREFUSED
|
72
|
+
sleep 2
|
73
|
+
false
|
74
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
75
|
+
sleep 2
|
76
|
+
false
|
77
|
+
ensure
|
78
|
+
tcp_socket && tcp_socket.close
|
79
|
+
end
|
80
|
+
|
81
|
+
#####################################################
|
82
|
+
# validate!
|
83
|
+
#####################################################
|
84
|
+
def validate!(keys=[:hmc_host, :hmc_username, :hmc_password])
|
85
|
+
errors = []
|
86
|
+
|
87
|
+
keys.each do |k|
|
88
|
+
pretty_key = k.to_s.gsub(/_/, ' ').gsub(/\w+/){ |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize }
|
89
|
+
if Chef::Config[:knife][k].nil? and config[k].nil?
|
90
|
+
errors << "You did not provide a valid '#{pretty_key}' value."
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if errors.each{|e| ui.error(e)}.any?
|
95
|
+
exit 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
#####################################################
|
100
|
+
# validate - no exit on errors
|
101
|
+
#####################################################
|
102
|
+
def validate(keys)
|
103
|
+
errors = []
|
104
|
+
|
105
|
+
keys.each do |k|
|
106
|
+
pretty_key = k.to_s.gsub(/_/, ' ').gsub(/\w+/){ |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize }
|
107
|
+
if Chef::Config[:knife][k].nil? and config[k].nil?
|
108
|
+
errors << "You did not provide a valid '#{pretty_key}' value."
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
if errors.empty?
|
113
|
+
return true
|
114
|
+
else
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#####################################################
|
120
|
+
# get config
|
121
|
+
#####################################################
|
122
|
+
def get_config(key)
|
123
|
+
key = key.to_sym
|
124
|
+
rval = config[key] || Chef::Config[:knife][key] || $default[key]
|
125
|
+
Chef::Log.debug("value for config item #{key}: #{rval}")
|
126
|
+
rval
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,116 @@
|
|
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 HmcDiskAdd < Knife
|
14
|
+
|
15
|
+
include Knife::HmcBase
|
16
|
+
|
17
|
+
banner "knife hmc disk add (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 :size,
|
40
|
+
:short => "-S SIZE",
|
41
|
+
:long => "--size_in_GB SIZE",
|
42
|
+
:description => "The size in GB you require, will find the size requested or larger."
|
43
|
+
|
44
|
+
option :volume_group,
|
45
|
+
:short => "-g NAME",
|
46
|
+
:long => "--volume_group NAME",
|
47
|
+
:description => "Name of volume group disk will be used in. If rootvg is passed then script will find a single LUN vs multiple smaller luns to fit request."
|
48
|
+
|
49
|
+
def run
|
50
|
+
Chef::Log.debug("Adding disk...")
|
51
|
+
|
52
|
+
validate!([:frame_name,:lpar_name,:vio2_name,:vio1_name,:size])
|
53
|
+
|
54
|
+
hmc = Hmc.new(get_config(:hmc_host), get_config(:hmc_username) , {:password => get_config(:hmc_password)})
|
55
|
+
hmc.connect
|
56
|
+
|
57
|
+
#Populate hash to make LPAR object
|
58
|
+
lpar_hash = hmc.get_lpar_options(get_config(:frame_name),get_config(:lpar_name))
|
59
|
+
#Create LPAR object based on hash, and VIO objects
|
60
|
+
lpar = Lpar.new(lpar_hash)
|
61
|
+
vio1 = Vio.new(hmc, get_config(:frame_name), get_config(:vio1_name))
|
62
|
+
vio2 = Vio.new(hmc, get_config(:frame_name), get_config(:vio2_name))
|
63
|
+
|
64
|
+
#Get vSCSI Information
|
65
|
+
lpar_vscsi = lpar.get_vscsi_adapters
|
66
|
+
first_slot = nil
|
67
|
+
second_slot = nil
|
68
|
+
adapter_cnt = 0
|
69
|
+
|
70
|
+
if lpar_vscsi.empty? == true
|
71
|
+
#Add vSCSI Adapters
|
72
|
+
lpar.add_vscsi(vio1)
|
73
|
+
lpar.add_vscsi(vio2)
|
74
|
+
lpar_vscsi = lpar.get_vscsi_adapters
|
75
|
+
else
|
76
|
+
lpar_vscsi.each do |adapter|
|
77
|
+
if adapter.remote_lpar_name == vio1.name
|
78
|
+
first_slot = adapter.remote_slot_num
|
79
|
+
adapter_cnt += 1
|
80
|
+
elsif adapter.remote_lpar_name == vio2.name
|
81
|
+
second_slot = adapter.remote_slot_num
|
82
|
+
adapter_cnt += 1
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
if first_slot.nil? or second_slot.nil? or adapter_cnt != 2
|
87
|
+
#Could not determine which vSCSIs to use
|
88
|
+
error = "Unable to determine which vSCSI adapters to use"
|
89
|
+
puts "#{error}"
|
90
|
+
ui.error(error)
|
91
|
+
exit 1
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#Find the vHosts
|
96
|
+
first_vhost = vio1.find_vhost_given_virtual_slot(lpar_vscsi[0].remote_slot_num)
|
97
|
+
second_vhost = vio2.find_vhost_given_virtual_slot(lpar_vscsi[1].remote_slot_num)
|
98
|
+
|
99
|
+
#Check for volume group flag and add LUN to LPAR
|
100
|
+
if validate([:volume_group])
|
101
|
+
if get_config(:volume_group).to_s.downcase == "rootvg"
|
102
|
+
vio1.map_single_disk_by_size(first_vhost,vio2,second_vhost,get_config(:size).to_i)
|
103
|
+
puts "Successfully attached LUN to #{get_config(:lpar_name)}"
|
104
|
+
else
|
105
|
+
vio1.map_by_size(first_vhost,vio2,second_vhost,get_config(:size).to_i)
|
106
|
+
puts "Successfully attached LUN(s) to #{get_config(:lpar_name)}"
|
107
|
+
end
|
108
|
+
else
|
109
|
+
vio1.map_by_size(first_vhost,vio2,second_vhost,get_config(:size).to_i)
|
110
|
+
puts "Successfully attached LUN(s) to #{get_config(:lpar_name)}"
|
111
|
+
end
|
112
|
+
hmc.disconnect
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,173 @@
|
|
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 HmcDiskList < Knife
|
14
|
+
|
15
|
+
include Knife::HmcBase
|
16
|
+
|
17
|
+
banner "knife hmc disk list -r VIONAME1 -s VIONAME2 -f FRAMENAME [-l LPARNAME | -a | -x]"
|
18
|
+
|
19
|
+
option :primary_vio,
|
20
|
+
:short => "-r VIONAME",
|
21
|
+
:long => "--primary_vio VIONAME",
|
22
|
+
:description => "The LPAR name of the Primary VIO"
|
23
|
+
|
24
|
+
option :secondary_vio,
|
25
|
+
:short => "-s VIONAME",
|
26
|
+
:long => "--secondary_vio VIONAME",
|
27
|
+
:description => "The LPAR name of the Secondary VIO"
|
28
|
+
|
29
|
+
option :frame,
|
30
|
+
:short => "-f FRAMENAME",
|
31
|
+
:long => "--frame FRAMENAME",
|
32
|
+
:description => "The name of the Frame in which the VIOs reside"
|
33
|
+
|
34
|
+
option :lpar,
|
35
|
+
:short => "-l LPARNAME",
|
36
|
+
:long => "--lpar LPARNAME",
|
37
|
+
:description => "The name of the LPAR whose disks should be listed (optional)"
|
38
|
+
|
39
|
+
option :only_available,
|
40
|
+
:short => "-a",
|
41
|
+
:long => "--available",
|
42
|
+
:boolean => true,
|
43
|
+
:default => false,
|
44
|
+
:description => "List ONLY the available disks in this VIO pair (optional)"
|
45
|
+
|
46
|
+
option :only_used,
|
47
|
+
:short => "-x",
|
48
|
+
:long => "--used",
|
49
|
+
:boolean => true,
|
50
|
+
:default => false,
|
51
|
+
:description => "List ONLY the used disks in this VIO pair (optional)"
|
52
|
+
|
53
|
+
|
54
|
+
def run
|
55
|
+
Chef::Log.debug("Listing disks...")
|
56
|
+
|
57
|
+
validate!
|
58
|
+
hmc = Hmc.new(get_config(:hmc_host), get_config(:hmc_username) , {:password => get_config(:hmc_password)})
|
59
|
+
hmc.connect
|
60
|
+
|
61
|
+
validate!([:primary_vio,:secondary_vio,:frame])
|
62
|
+
|
63
|
+
frame = get_config(:frame)
|
64
|
+
primary_vio_name = get_config(:primary_vio)
|
65
|
+
secondary_vio_name = get_config(:secondary_vio)
|
66
|
+
|
67
|
+
#Make Vio objects for the two VIOs
|
68
|
+
primary_vio = Vio.new(hmc,frame,primary_vio_name)
|
69
|
+
secondary_vio = Vio.new(hmc,frame,secondary_vio_name)
|
70
|
+
|
71
|
+
#Arrays that will hold the disks to list
|
72
|
+
vio1_disks = []
|
73
|
+
vio2_disks = []
|
74
|
+
|
75
|
+
if validate([:lpar])
|
76
|
+
#Show only disks attached to the specified LPAR
|
77
|
+
lpar_name = get_config(:lpar)
|
78
|
+
options_hash = hmc.get_lpar_options(frame,lpar_name)
|
79
|
+
lpar = Lpar.new(options_hash)
|
80
|
+
|
81
|
+
#Get the vSCSIs from this LPAR and determine the virtual adapter
|
82
|
+
#slots used by each VIO
|
83
|
+
vscsi_adapters = lpar.get_vscsi_adapters
|
84
|
+
primary_vio_slot = nil
|
85
|
+
secondary_vio_slot = nil
|
86
|
+
adapter_cnt=0
|
87
|
+
vscsi_adapters.each do |adapter|
|
88
|
+
if adapter.remote_lpar_name == primary_vio.name
|
89
|
+
primary_vio_slot = adapter.remote_slot_num
|
90
|
+
adapter_cnt += 1
|
91
|
+
elsif adapter.remote_lpar_name == secondary_vio.name
|
92
|
+
secondary_vio_slot = adapter.remote_slot_num
|
93
|
+
adapter_cnt += 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if primary_vio_slot.nil? or secondary_vio_slot.nil? or adapter_cnt != 2
|
98
|
+
#Could not determine which vSCSIs to use
|
99
|
+
error = "Unable to determine which vSCSI adapters have storage attached to it from #{primary_vio_name} and #{secondary_vio_name}\n" +
|
100
|
+
"Cannot list disks attached to #{lpar_name}"
|
101
|
+
puts "#{error}"
|
102
|
+
ui.error(error)
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
|
106
|
+
#Find the vhosts that hold this LPARs disks
|
107
|
+
primary_vhost = primary_vio.find_vhost_given_virtual_slot(primary_vio_slot)
|
108
|
+
secondary_vhost = secondary_vio.find_vhost_given_virtual_slot(secondary_vio_slot)
|
109
|
+
|
110
|
+
#Get the names (known to the VIOs) of the disks attached to the LPAR
|
111
|
+
vio1_disks = primary_vio.get_attached_disks(primary_vhost)
|
112
|
+
vio2_disks = secondary_vio.get_attached_disks(secondary_vhost)
|
113
|
+
elsif get_config(:only_available)
|
114
|
+
#Show only available disks
|
115
|
+
vio1_disks = primary_vio.available_disks
|
116
|
+
vio2_disks = secondary_vio.available_disks
|
117
|
+
elsif get_config(:only_used)
|
118
|
+
#Show only used disks
|
119
|
+
vio1_disks = primary_vio.used_disks
|
120
|
+
vio2_disks = secondary_vio.used_disks
|
121
|
+
else
|
122
|
+
#None of :lpar, :only_available, and :only_used options were specified.
|
123
|
+
#Show used *and* available disks
|
124
|
+
vio1_disks = primary_vio.available_disks + primary_vio.used_disks
|
125
|
+
vio2_disks = secondary_vio.available_disks + secondary_vio.used_disks
|
126
|
+
end
|
127
|
+
|
128
|
+
#List the disks populated in vio1_disks and vio2_disks
|
129
|
+
print_header
|
130
|
+
|
131
|
+
vio1_disks.each do |v1_disk|
|
132
|
+
vio2_disks.each do |v2_disk|
|
133
|
+
if v1_disk == v2_disk
|
134
|
+
print_line(v1_disk,v2_disk)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
hmc.disconnect
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
##################################################
|
144
|
+
# print_header
|
145
|
+
# => Prints table header for disk list
|
146
|
+
##################################################
|
147
|
+
def print_header
|
148
|
+
if validate([:lpar])
|
149
|
+
puts "Listing information on all disks attached to #{get_config(:lpar)}\n"
|
150
|
+
elsif get_config(:only_available)
|
151
|
+
puts "Listing only available disks on this VIO Pair\n"
|
152
|
+
elsif get_config(:only_used)
|
153
|
+
puts "Listing only used disks on this VIO Pair\n"
|
154
|
+
else
|
155
|
+
puts "Listing all disks on this VIO Pair\n"
|
156
|
+
end
|
157
|
+
|
158
|
+
printf "%-20s %10s %20s %20s\n", "PVID", "Size (MB)", "Name (on #{get_config(:primary_vio)})", "Name (on #{get_config(:secondary_vio)})"
|
159
|
+
printf "-----------------------------------------------------------------------------------------\n"
|
160
|
+
end
|
161
|
+
|
162
|
+
##################################################
|
163
|
+
# print_line
|
164
|
+
# => Prints a single line of the output table
|
165
|
+
# given two Lun objects representing the same
|
166
|
+
# disk on a pair of VIOs
|
167
|
+
##################################################
|
168
|
+
def print_line(vio1_disk,vio2_disk)
|
169
|
+
printf "%-20s %10s %20s %20s\n", vio1_disk.pvid, "#{vio1_disk.size_in_mb} MB", vio1_disk.name, vio2_disk.name
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|