knife-hmc 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|