rbvppc 1.0.1 → 1.0.2
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 +4 -4
- data/lib/rbvppc/connectable_server.rb +3 -2
- data/lib/rbvppc/lpar.rb +162 -152
- data/lib/rbvppc/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4cb4ec8697b9c089a2c0a84514419436ef7af9fc
|
|
4
|
+
data.tar.gz: a034629b84befed0c0f5d8a4ed572e002028ea02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 70a412b7f4c414ec51f77880171460a22708e433f23f55fc88a3c58cc0c952a0088356c9ccfb53e1f232b950e01a0d7320925091a8eedea6176545a78ce3e57c
|
|
7
|
+
data.tar.gz: e37060004220fce4cf81d7daaf28ab4367a179d4ed9d93f17276689b8a71d476ae0ec1d1aeb4f115d4b9a8b1b9c83955dcc1f5936c05480b534b93d9c0674419
|
|
@@ -25,7 +25,7 @@ class ConnectableServer
|
|
|
25
25
|
options[:port] = 22 if (options[:protocol] == :ssh) && (!options.has_key? :port)
|
|
26
26
|
@hostname, @username, @options = hostname, username, options
|
|
27
27
|
@session = nil
|
|
28
|
-
@debug ||=
|
|
28
|
+
@debug ||= true
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def connected?
|
|
@@ -39,11 +39,12 @@ class ConnectableServer
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def connect
|
|
42
|
-
# @session = Net::SSH.start(@hostname, @username, :password => @password, :port => @port)
|
|
43
42
|
if (@options[:key] && !@options[:password]) then
|
|
44
43
|
@session = Net::SSH.start(@hostname, @username, :key => @options[:key], :port => @options[:port])
|
|
45
44
|
elsif (@options[:key] && @options[:password])
|
|
46
45
|
@session = Net::SSH.start(@hostname, @username, :key => @options[:key], :passphrase => @options[:password], :port => @options[:port])
|
|
46
|
+
elsif (@options[:key_data] && @options[:passphrase])
|
|
47
|
+
@session = Net::SSH.start(@hostname, @username, :keys => @options[:keys], :key_data => @options[:key_data], :keys_only => @options[:keys_only], :passphrase => @options[:passphrase], :port => @options[:port])
|
|
47
48
|
else
|
|
48
49
|
@session = Net::SSH.start(@hostname, @username, :password => @options[:password], :port => @options[:port])
|
|
49
50
|
end
|
data/lib/rbvppc/lpar.rb
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#
|
|
2
2
|
# Authors: Christopher M Wood (<woodc@us.ibm.com>)
|
|
3
|
-
#
|
|
3
|
+
# John F Hutchinson (<jfhutchi@us.ibm.com)
|
|
4
4
|
# © Copyright IBM Corporation 2015.
|
|
5
5
|
#
|
|
6
6
|
# LICENSE: MIT (http://opensource.org/licenses/MIT)
|
|
7
7
|
#
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
#
|
|
9
|
+
# Assumptions:
|
|
10
|
+
# Operations on LPARs will be done simultaneously to both their current profile and
|
|
11
|
+
# the LPAR's hardware itself, removing the need to abstract data into both LPAR attributes
|
|
12
|
+
# and attributes of that LPAR's profile.
|
|
13
|
+
# Future features:
|
|
14
|
+
# May split lpar_profile into a subclass of LPAR in the future, to allow greater levels of
|
|
15
|
+
# customization.
|
|
16
|
+
|
|
17
17
|
require_relative 'hmc'
|
|
18
18
|
require_relative 'vscsi'
|
|
19
19
|
require_relative 'network'
|
|
@@ -26,26 +26,26 @@ class Lpar
|
|
|
26
26
|
:min_vcpu, :max_vcpu, :desired_vcpu,
|
|
27
27
|
:hostname, :uncap_weight, :max_virtual_slots
|
|
28
28
|
|
|
29
|
-
attr_reader
|
|
29
|
+
attr_reader :hmc, :id, :name, :proc_mode, :sharing_mode, :frame,
|
|
30
30
|
:current_profile, :default_profile
|
|
31
31
|
|
|
32
32
|
#Class variable to hold all 'valid' attributes that can be set on an LPAR
|
|
33
33
|
@@valid_attributes = ["min_mem", "desired_mem", "max_mem", "min_num_huge_pages", "desired_num_huge_pages", "max_num_huge_pages",
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
"mem_mode", "hpt_ratio", "proc_mode", "min_proc_units", "desired_proc_units", "max_proc_units", "min_procs",
|
|
35
|
+
"desired_procs", "max_procs", "sharing_mode", "uncap_weight", "shared_proc_pool_id", "shared_proc_pool_name",
|
|
36
|
+
"io_slots", "lpar_io_pool_ids", "max_virtual_slots", "hca_adapters", "boot_mode", "conn_monitoring", "auto_start",
|
|
37
|
+
"power_ctrl_lpar_ids", "work_group_id", "redundant_err_path_reporting", "bsr_arrays", "lhea_logical_ports", "lhea_capabilities", "lpar_proc_compat_mode", "electronic_err_reporting"]
|
|
38
|
+
#Small hash to handle translating HMC labels to Lpar class attributes
|
|
39
39
|
@@attr_mapping = {"min_mem" => "min_memory",
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
"max_mem" => "max_memory",
|
|
41
|
+
"desired_mem" => "desired_memory",
|
|
42
|
+
"min_proc_units" => "min_proc_units",
|
|
43
|
+
"max_proc_units" => "max_proc_units",
|
|
44
|
+
"desired_proc_units" => "desired_proc_units",
|
|
45
|
+
"min_procs" => "min_vcpu",
|
|
46
|
+
"max_procs" => "max_vcpu",
|
|
47
|
+
"desired_procs" => "desired_vcpu"
|
|
48
|
+
}
|
|
49
49
|
|
|
50
50
|
def initialize(options_hash, disable_auto_reboot = false)
|
|
51
51
|
|
|
@@ -62,11 +62,11 @@ class Lpar
|
|
|
62
62
|
raise StandardError.new("An Lpar cannot be defined without specifying it's FQDN") if options_hash[:hostname].nil? && options_hash[:name].nil?
|
|
63
63
|
|
|
64
64
|
#Parameters that are explicitly required to make an LPAR object
|
|
65
|
-
@hmc
|
|
65
|
+
@hmc = options_hash[:hmc]
|
|
66
66
|
@desired_proc_units = options_hash[:des_proc].to_f
|
|
67
67
|
@desired_memory = options_hash[:des_mem].to_i
|
|
68
68
|
@desired_vcpu = options_hash[:des_vcpu].to_i
|
|
69
|
-
@frame
|
|
69
|
+
@frame = options_hash[:frame]
|
|
70
70
|
@name = options_hash[:name]
|
|
71
71
|
|
|
72
72
|
#Parameters that can be defaulted if they are not provided
|
|
@@ -79,7 +79,7 @@ class Lpar
|
|
|
79
79
|
!options_hash[:min_vcpu].nil? ? @min_vcpu = options_hash[:min_vcpu].to_i : @min_vcpu = @desired_vcpu
|
|
80
80
|
!options_hash[:max_virt_slots].nil? ? @max_virtual_slots = options_hash[:max_virt_slots].to_i : @max_virtual_slots = 30
|
|
81
81
|
!options_hash[:current_profile].nil? ? @current_profile = options_hash[:current_profile] : @current_profile = @name + "_profile"
|
|
82
|
-
!options_hash[:default_profile].nil? ? @default_profile
|
|
82
|
+
!options_hash[:default_profile].nil? ? @default_profile = options_hash[:default_profile] : @default_profile = @current_profile
|
|
83
83
|
!options_hash[:sharing_mode].nil? ? @sharing_mode = options_hash[:sharing_mode] : @sharing_mode = "cap"
|
|
84
84
|
@sharing_mode == "uncap" ? @uncap_weight = options_hash[:uncap_weight].to_i : @uncap_weight = nil
|
|
85
85
|
!options_hash[:proc_mode].nil? ? @proc_mode = options_hash[:proc_mode] : @proc_mode = "shared"
|
|
@@ -197,7 +197,7 @@ class Lpar
|
|
|
197
197
|
#Since an LPAR can have states such as "Not Activated", "Open Firmware", "Shutting Down",
|
|
198
198
|
#this function only helps for when we are explicitly looking for an LPAR to be either "Running" or not.
|
|
199
199
|
def is_running?
|
|
200
|
-
return check_state == "Running"
|
|
200
|
+
return check_state == "Running"
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
#Similar to is_running? - only returns true if the LPAR's state is "Not Activated".
|
|
@@ -248,6 +248,13 @@ class Lpar
|
|
|
248
248
|
cmd = "chsyscfg -m #{frame} -r prof -i \"name=#{current_profile}, lpar_name=#{name}, #{hmc_label}=#{units} \" "
|
|
249
249
|
hmc.execute_cmd(cmd)
|
|
250
250
|
end
|
|
251
|
+
|
|
252
|
+
# Set multiple LPAR profile attributes in a single call.
|
|
253
|
+
def set_multi_attr_profile(options)
|
|
254
|
+
profile_options = options.map{|key,val| "#{key}=#{val}"}.join(',')
|
|
255
|
+
cmd = "chsyscfg -m #{frame} -r prof -i \"name=#{current_profile}, lpar_name=#{name}, #{profile_options} \" "
|
|
256
|
+
hmc.execute_cmd(cmd)
|
|
257
|
+
end
|
|
251
258
|
|
|
252
259
|
#Function to use for all Min/Max attribute changing
|
|
253
260
|
def set_attr_and_reactivate(units,hmc_label)
|
|
@@ -258,37 +265,39 @@ class Lpar
|
|
|
258
265
|
|
|
259
266
|
# Shutdown and reactivate the LPAR so that the attribute changes take effect
|
|
260
267
|
def reactivate
|
|
261
|
-
#Shut down the LPAR
|
|
268
|
+
# Shut down the LPAR
|
|
262
269
|
soft_shutdown unless not_activated?
|
|
263
|
-
#Wait until it's state is "Not Activated"
|
|
270
|
+
# Wait until it's state is "Not Activated"
|
|
264
271
|
sleep(10) until not_activated?
|
|
265
|
-
#Reactivate the LPAR so that the attribute changes take effect
|
|
272
|
+
# Reactivate the LPAR so that the attribute changes take effect
|
|
266
273
|
activate
|
|
267
274
|
end
|
|
268
275
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
276
|
+
# Bulk modifies an LPAR's resources based on the provided hash.
|
|
277
|
+
# The Hash is required to have it's keys represent labels for HMC attributes (ie, min_mem, max_mem, etc)
|
|
278
|
+
# while it's values are what the user requests those attributes be set to for this LPAR.
|
|
279
|
+
# The LPAR is then reactivated once all of the changes are made for them to take effect.
|
|
280
|
+
# The Class Instance variable @@valid_attributes is used to determine if a key in options is a valid
|
|
281
|
+
# attribute. If an attribute in options is deemed invalid, nothing is done with respect to that attribute.
|
|
282
|
+
def modify_resources(options, reboot = true, prevalidated = false)
|
|
283
|
+
execute = false
|
|
284
|
+
options.each do |key,val|
|
|
285
|
+
execute = false
|
|
286
|
+
if @@valid_attributes.include?(key)
|
|
287
|
+
# Check for min/max/desired in the key to determine if
|
|
288
|
+
# some bound needs to be checked first
|
|
289
|
+
verify_and_handle_attr_bounds(options,key,val) unless prevalidated
|
|
290
|
+
# Handle setting of any instance variables that should change
|
|
291
|
+
# due to this
|
|
292
|
+
map_key_to_attr(key, val)
|
|
293
|
+
execute = true
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
# Set LPAR profile
|
|
297
|
+
set_multi_attr_profile(options) if execute
|
|
298
|
+
reactivate if reboot
|
|
299
|
+
end
|
|
300
|
+
|
|
292
301
|
#####################################
|
|
293
302
|
# Processing Unit functions
|
|
294
303
|
#####################################
|
|
@@ -342,7 +351,7 @@ class Lpar
|
|
|
342
351
|
set_attr_and_reactivate(units,"min_proc_units")
|
|
343
352
|
|
|
344
353
|
#Set the private member
|
|
345
|
-
@min_proc_units = units
|
|
354
|
+
@min_proc_units = units
|
|
346
355
|
end
|
|
347
356
|
|
|
348
357
|
#####################################
|
|
@@ -942,13 +951,13 @@ class Lpar
|
|
|
942
951
|
#Used by modify_resources() to handle setting attribute values
|
|
943
952
|
#on the Lpar object after modifying the value on the HMC.
|
|
944
953
|
def map_key_to_attr(key, value)
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
954
|
+
if @@attr_mapping.has_key?(key)
|
|
955
|
+
attr_name = @@attr_mapping[key]
|
|
956
|
+
#Use Object function instance_variable_set to take
|
|
957
|
+
#a string that is the name of an instance variable
|
|
958
|
+
#and change it's value
|
|
959
|
+
instance_variable_set("@" + attr_name, value)
|
|
960
|
+
end
|
|
952
961
|
end
|
|
953
962
|
|
|
954
963
|
#Private function that is used to ensure that the LPAR attribute key
|
|
@@ -958,98 +967,99 @@ class Lpar
|
|
|
958
967
|
#also be changed. If none of the bounds related to the attribute key are cited in the hash,
|
|
959
968
|
#the assumption that the attribute bounds should be changed to accomodate this is made.
|
|
960
969
|
def verify_and_handle_attr_bounds(options_hash, key, value)
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
970
|
+
split_key = key.split('_')
|
|
971
|
+
#Save the qualifier for the attribute
|
|
972
|
+
#as well it's the base name
|
|
973
|
+
qualifier = split_key[0]
|
|
974
|
+
split_key.delete_at(0)
|
|
975
|
+
base_attr = split_key.join('_')
|
|
976
|
+
fix_bounds = false
|
|
977
|
+
if ["min","max","desired"].include?(qualifier)
|
|
978
|
+
other_bounds = ["min","max","desired"].select { |x| x!=qualifier }
|
|
979
|
+
|
|
980
|
+
#Since there will only ever be 2 more array elements in other_bounds at this point,
|
|
981
|
+
#assign them, find their labels, find their attribute names,
|
|
982
|
+
#find their current values, and continue with validation
|
|
983
|
+
other_bound_a = other_bounds[0]
|
|
984
|
+
other_bound_b = other_bounds[1]
|
|
985
|
+
bound_a_label = [other_bound_a,base_attr].join('_')
|
|
986
|
+
bound_b_label = [other_bound_b,base_attr].join('_')
|
|
987
|
+
bound_a_instance_var = @@attr_mapping[bound_a_label]
|
|
988
|
+
bound_b_instance_var = @@attr_mapping[bound_b_label]
|
|
989
|
+
bound_a = instance_variable_get("@" + bound_a_instance_var)
|
|
990
|
+
bound_b = instance_variable_get("@" + bound_b_instance_var)
|
|
991
|
+
#Find out if this attribute change doesn't satisfy the current bounds
|
|
992
|
+
this_attr_label = key
|
|
993
|
+
this_attr_value = value
|
|
994
|
+
|
|
995
|
+
bound_a_new_val = nil
|
|
996
|
+
bound_b_new_val = nil
|
|
997
|
+
|
|
998
|
+
#If this value does not satisfy the current bounds, take note and
|
|
999
|
+
#rectify it later
|
|
1000
|
+
if !satisfies_bounds?(qualifier, this_attr_value, bound_a, bound_b)
|
|
1001
|
+
#Make the new bounds values be what is in the options hash, unless
|
|
1002
|
+
#it isn't specified, then just make it the same as what we're trying to change.
|
|
1003
|
+
if options_hash.has_key?(bound_a_label)
|
|
1004
|
+
bound_a_new_val = options_hash[bound_a_label]
|
|
1005
|
+
else
|
|
1006
|
+
bound_a_new_val = value
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
if options_hash.has_key?(bound_b_label)
|
|
1010
|
+
bound_b_new_val = options_hash[bound_b_label]
|
|
1011
|
+
else
|
|
1012
|
+
bound_b_new_val = value
|
|
1013
|
+
end
|
|
1014
|
+
|
|
1015
|
+
#Check if the bounds might be satisfied if *only one* of the bounds changed
|
|
1016
|
+
if satisfies_bounds?(qualifier, this_attr_value, bound_a_new_val, bound_b)
|
|
1017
|
+
bound_b_new_val = bound_b
|
|
1018
|
+
elsif satisfies_bounds?(qualifier, this_attr_value, bound_a, bound_b_new_val)
|
|
1019
|
+
bound_a_new_val = bound_a
|
|
1020
|
+
end
|
|
1021
|
+
end
|
|
1022
|
+
|
|
1023
|
+
#If this is a vCPU or a Proc Units change, we need to ensure that
|
|
1024
|
+
#the new change adheres to the fact that the ratio between vCPUs and
|
|
1025
|
+
#Proc Units needs to be 10:1
|
|
1026
|
+
if ["procs","proc_units"].include?(base_attr)
|
|
1027
|
+
#TODO: Add logic that handles ensuring this 10:1 ratio remains in
|
|
1028
|
+
#place after this change.
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
if !bound_a_new_val.nil? and !bound_b_new_val.nil?
|
|
1032
|
+
#Based on how the other_bounds array is constructed earlier,
|
|
1033
|
+
#other_bound_a can either be "min" or "max", which helps determine the order
|
|
1034
|
+
#in which to set bound_a and bound_b. Also, if the new bound is less than or greater than
|
|
1035
|
+
#the old bound will further determine this order.
|
|
1036
|
+
|
|
1037
|
+
#If other_bound_a == 'min', and it's new value is less than the old one,
|
|
1038
|
+
#Change this one first, and then the second bound
|
|
1039
|
+
#Same for if bound_a is 'max' and it's new value is greater than the old
|
|
1040
|
+
if (other_bound_a == "min" and bound_a_new_val <= bound_a) or
|
|
1041
|
+
(other_bound_a == "max" and bound_a_new_val > bound_a)
|
|
1042
|
+
set_attr_profile(bound_a_new_val, bound_a_label)
|
|
1043
|
+
set_attr_profile(bound_b_new_val, bound_b_label)
|
|
1044
|
+
elsif (other_bound_a == "min" and bound_a_new_val > bound_a) or
|
|
1045
|
+
(other_bound_a == "max" and bound_a_new_val <= bound_a)
|
|
1046
|
+
set_attr_profile(bound_b_new_val, bound_b_label)
|
|
1047
|
+
set_attr_profile(bound_a_new_val, bound_a_label)
|
|
1048
|
+
end
|
|
1049
|
+
instance_variable_set("@" + bound_a_instance_var, bound_a_new_val)
|
|
1050
|
+
instance_variable_set("@" + bound_b_instance_var, bound_b_new_val)
|
|
1051
|
+
end
|
|
1052
|
+
end
|
|
1043
1053
|
end
|
|
1044
1054
|
|
|
1045
1055
|
def satisfies_bounds?(op, val1, val2, val3)
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1056
|
+
if op == "min"
|
|
1057
|
+
return (val1 <= val2 and val1 <= val3 and val2 >= val3)
|
|
1058
|
+
elsif op == "max"
|
|
1059
|
+
return (val1 >= val2 and val1 >= val3 and val2 <= val3)
|
|
1060
|
+
elsif op == "desired"
|
|
1061
|
+
return (val1 >= val2 and val1 <= val3 and val2 <= val3)
|
|
1062
|
+
end
|
|
1053
1063
|
end
|
|
1054
1064
|
|
|
1055
1065
|
#Set the processing units for an LPAR via DLPAR
|
data/lib/rbvppc/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbvppc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John F. Hutchinson, Chris Wood
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2016-06-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: net-ssh
|
|
@@ -110,8 +110,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
110
110
|
version: '0'
|
|
111
111
|
requirements: []
|
|
112
112
|
rubyforge_project:
|
|
113
|
-
rubygems_version: 2.
|
|
113
|
+
rubygems_version: 2.4.8
|
|
114
114
|
signing_key:
|
|
115
115
|
specification_version: 4
|
|
116
116
|
summary: Remote access library for IBM P-Series
|
|
117
117
|
test_files: []
|
|
118
|
+
has_rdoc:
|