vmopt 0.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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/devcon +0 -0
- data/bin/vmdrive +97 -0
- data/bin/vmdvd +193 -0
- data/bin/vmnetwork +172 -0
- data/bin/vmnotepad +144 -0
- data/bin/vmopt +22 -0
- data/bin/vmpower +73 -0
- data/bin/vmserial +92 -0
- data/bin/vmsysres +58 -0
- data/lib/vmopt.rb +14 -0
- data/lib/vmopt/disk_operation.rb +188 -0
- data/lib/vmopt/dvd_operation.rb +120 -0
- data/lib/vmopt/ext/string_ext.rb +104 -0
- data/lib/vmopt/network.rb +128 -0
- data/lib/vmopt/notepad.rb +145 -0
- data/lib/vmopt/power_operation.rb +57 -0
- data/lib/vmopt/serialport_operation.rb +62 -0
- data/lib/vmopt/system_resource.rb +44 -0
- data/lib/vmopt/utils/ip.rb +287 -0
- data/lib/vmopt/utils/registry.rb +13 -0
- data/lib/vmopt/utils/wmi.rb +19 -0
- data/lib/vmopt/version.rb +3 -0
- data/lib/vmopt/windows/win_net.rb +295 -0
- data/lib/vmopt/windows/win_winutils.rb +200 -0
- data/vmopt.gemspec +37 -0
- metadata +170 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
module Vmopt
|
3
|
+
class PowerOperation
|
4
|
+
|
5
|
+
=begin
|
6
|
+
参数:无
|
7
|
+
功能:关机
|
8
|
+
返回值:默认
|
9
|
+
=end
|
10
|
+
def shutdown
|
11
|
+
system("shutdown -s -t 00")
|
12
|
+
end
|
13
|
+
|
14
|
+
=begin
|
15
|
+
参数:无
|
16
|
+
功能:重启
|
17
|
+
返回值:默认
|
18
|
+
=end
|
19
|
+
def reboot
|
20
|
+
system("shutdown -r -t 00")
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
=begin
|
25
|
+
参数:无
|
26
|
+
功能:注销
|
27
|
+
返回值:默认
|
28
|
+
=end
|
29
|
+
def logoff
|
30
|
+
system("shutdown -l")
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
=begin
|
35
|
+
参数:无
|
36
|
+
功能:锁定或切换用户
|
37
|
+
返回值:默认
|
38
|
+
=end
|
39
|
+
def lock_user
|
40
|
+
system("rundll32.exe user32.dll LockWorkStation")
|
41
|
+
end
|
42
|
+
|
43
|
+
=begin
|
44
|
+
参数:无
|
45
|
+
功能:休眠,xp没有休眠的功能,win7有休眠的功能
|
46
|
+
返回值:默认
|
47
|
+
=end
|
48
|
+
def sleep
|
49
|
+
system("rundll32.exe powrprof.dll SetSuspendState")
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end #end of module vmopt
|
54
|
+
|
55
|
+
if __FILE__ == $0
|
56
|
+
PowerOperation.new().lock_user
|
57
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require "vmopt/utils/wmi"
|
3
|
+
require "serialport"
|
4
|
+
|
5
|
+
module Vmopt
|
6
|
+
class SerialPortOperation
|
7
|
+
|
8
|
+
=begin
|
9
|
+
参数:无
|
10
|
+
功能:查询串口的基本信息
|
11
|
+
返回值:默认
|
12
|
+
=end
|
13
|
+
def get_serial_port
|
14
|
+
data_value={}
|
15
|
+
colItems = WMI.execquery ("select * from Win32_SerialPort")
|
16
|
+
for objItem in colItems do
|
17
|
+
name = (objItem.Name)[-5,4]
|
18
|
+
str ={"串口名称" => name,
|
19
|
+
"状态" => objItem.Status
|
20
|
+
}
|
21
|
+
data_value["#{name}"] = str
|
22
|
+
end
|
23
|
+
return data_value
|
24
|
+
end
|
25
|
+
=begin
|
26
|
+
参数:串口号,写入的字符串
|
27
|
+
功能:将串口写入字符串
|
28
|
+
返回值:默认
|
29
|
+
=end
|
30
|
+
def write(strcom,strinput)
|
31
|
+
strinput
|
32
|
+
begin
|
33
|
+
File.open(strcom, 'w+') do |file|
|
34
|
+
file.write(strinput)
|
35
|
+
end
|
36
|
+
rescue Exception
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
=begin
|
42
|
+
参数:串口号
|
43
|
+
功能:从串口读入字符串
|
44
|
+
返回值:读到的com口字符串
|
45
|
+
=end
|
46
|
+
def read(strcom)
|
47
|
+
begin
|
48
|
+
stroutput=""
|
49
|
+
sp = SerialPort.new "#{strcom}", 9600
|
50
|
+
sp.read_timeout=4000 #定时4秒
|
51
|
+
stroutput = sp.read(50)
|
52
|
+
if stroutput.empty?
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
rescue Exception
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
return stroutput
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end #end of module vmopt
|
62
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
#$:.unshift File.join(__FILE__,"..","..")
|
3
|
+
require "vmopt/utils/wmi"
|
4
|
+
|
5
|
+
module Vmopt
|
6
|
+
class SystemResource
|
7
|
+
|
8
|
+
def get_cpu
|
9
|
+
data_value={}
|
10
|
+
colItems = WMI.execquery ("select * from Win32_Processor")
|
11
|
+
for objItem in colItems do
|
12
|
+
str={"CPU数量" => objItem.NumberOfCores,
|
13
|
+
"CPU主频" => (objItem.MaxClockSpeed/1000.0).round(2),
|
14
|
+
"CPU使用率" => "#{objItem.LoadPercentage}%"
|
15
|
+
}
|
16
|
+
data_value["#{objItem.DeviceID}"]=str
|
17
|
+
end
|
18
|
+
return data_value
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_memory
|
22
|
+
data_value={}
|
23
|
+
colItems = WMI.execquery ("select * from Win32_PhysicalMemory")
|
24
|
+
for objItem in colItems do
|
25
|
+
memsizestr = objItem.Capacity
|
26
|
+
memsizei = memsizestr.to_i/1024/1024 #str转interger
|
27
|
+
end
|
28
|
+
availMemorys = WMI.execquery ("select * from Win32_PerfRawData_PerfOS_Memory")
|
29
|
+
for availMemory in availMemorys do
|
30
|
+
availstr = availMemory.AvailableMBytes
|
31
|
+
availi = availstr.to_i #str转interger
|
32
|
+
end
|
33
|
+
|
34
|
+
str = {"总物理内存" => memsizei,
|
35
|
+
"可用内存" => availi,
|
36
|
+
"内存使用率" => "#{(((memsizei-availi) * 1.0 /memsizei) * 100).round(1)}%"
|
37
|
+
}
|
38
|
+
data_value["#{objItem.Name}"] = str
|
39
|
+
return data_value
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end #end of module vmopt
|
44
|
+
|
@@ -0,0 +1,287 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
# 功能:提供IP的规范性检查,适合所有平台
|
3
|
+
|
4
|
+
module IP
|
5
|
+
# A map of all the different regexes that work for
|
6
|
+
# a given platform or set of platforms.
|
7
|
+
REGEX_MAP = {
|
8
|
+
:linux => {
|
9
|
+
:ipaddress => /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
10
|
+
:ipaddress6 => /inet6 (?:addr: )?((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
11
|
+
:macaddress => /(?:ether|HWaddr)\s+((\w{1,2}:){5,}\w{1,2})/,
|
12
|
+
:netmask => /(?:Mask:|netmask )([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
13
|
+
:mtu => /MTU:(\d+)/
|
14
|
+
},
|
15
|
+
:bsd => {
|
16
|
+
:aliases => [:openbsd, :netbsd, :freebsd, :darwin, :"gnu/kfreebsd", :dragonfly],
|
17
|
+
:ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
18
|
+
:ipaddress6 => /inet6 ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
19
|
+
:macaddress => /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
|
20
|
+
:netmask => /netmask\s+0x(\w{8})/,
|
21
|
+
:mtu => /mtu\s+(\d+)/
|
22
|
+
},
|
23
|
+
:sunos => {
|
24
|
+
:ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
25
|
+
:ipaddress6 => /inet6 ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
26
|
+
:macaddress => /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
|
27
|
+
:netmask => /netmask\s+(\w{8})/,
|
28
|
+
:mtu => /mtu\s+(\d+)/
|
29
|
+
},
|
30
|
+
:"hp-ux" => {
|
31
|
+
:ipaddress => /\s+inet (\S+)\s.*/,
|
32
|
+
:macaddress => /(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
|
33
|
+
:netmask => /.*\s+netmask (\S+)\s.*/
|
34
|
+
},
|
35
|
+
:windows => {}
|
36
|
+
}
|
37
|
+
|
38
|
+
# Convert an interface name into purely alphanumeric characters.
|
39
|
+
def self.alphafy(interface)
|
40
|
+
interface.gsub(/[^a-z0-9_]/i, '_')
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.convert_from_hex?(kernel)
|
44
|
+
kernels_to_convert = [:sunos, :openbsd, :netbsd, :freebsd, :darwin, :"hp-ux", :"gnu/kfreebsd", :dragonfly]
|
45
|
+
kernels_to_convert.include?(kernel)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.supported_platforms
|
49
|
+
REGEX_MAP.inject([]) do |result, tmp|
|
50
|
+
key, map = tmp
|
51
|
+
if map[:aliases]
|
52
|
+
result += map[:aliases]
|
53
|
+
else
|
54
|
+
result << key
|
55
|
+
end
|
56
|
+
result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.get_interfaces
|
61
|
+
if Facter.value(:kernel) == 'windows'
|
62
|
+
require 'facter/util/ip/windows'
|
63
|
+
return Vmopt::IP::Windows.interfaces
|
64
|
+
end
|
65
|
+
|
66
|
+
return [] unless output = Vmopt::IP.get_all_interface_output()
|
67
|
+
|
68
|
+
# Our regex appears to be stupid, in that it leaves colons sitting
|
69
|
+
# at the end of interfaces. So, we have to trim those trailing
|
70
|
+
# characters. I tried making the regex better but supporting all
|
71
|
+
# platforms with a single regex is probably a bit too much.
|
72
|
+
output.scan(/^\S+/).collect { |i| i.sub(/:$/, '') }.uniq
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.get_all_interface_output
|
76
|
+
case Facter.value(:kernel)
|
77
|
+
when 'Linux', 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin', 'GNU/kFreeBSD', 'DragonFly'
|
78
|
+
output = Vmopt::IP.exec_ifconfig(["-a","2>/dev/null"])
|
79
|
+
when 'SunOS'
|
80
|
+
output = Vmopt::IP.exec_ifconfig(["-a"])
|
81
|
+
when 'HP-UX'
|
82
|
+
# (#17487)[https://projects.puppetlabs.com/issues/17487]
|
83
|
+
# Handle NIC bonding where asterisks and virtual NICs are printed.
|
84
|
+
if output = hpux_netstat_in
|
85
|
+
output.gsub!(/\*/, "") # delete asterisks.
|
86
|
+
output.gsub!(/^[^\n]*none[^\n]*\n/, "") # delete lines with 'none' instead of IPs.
|
87
|
+
output.sub!(/^[^\n]*\n/, "") # delete the header line.
|
88
|
+
output
|
89
|
+
end
|
90
|
+
end
|
91
|
+
output
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
##
|
96
|
+
# exec_ifconfig uses the ifconfig command
|
97
|
+
#
|
98
|
+
# @return [String] the output of `ifconfig #{arguments} 2>/dev/null` or nil
|
99
|
+
def self.exec_ifconfig(additional_arguments=[])
|
100
|
+
Facter::Core::Execution.exec("#{self.get_ifconfig} #{additional_arguments.join(' ')}")
|
101
|
+
end
|
102
|
+
##
|
103
|
+
# get_ifconfig looks up the ifconfig binary
|
104
|
+
#
|
105
|
+
# @return [String] path to the ifconfig binary
|
106
|
+
def self.get_ifconfig
|
107
|
+
common_paths=["/bin/ifconfig","/sbin/ifconfig","/usr/sbin/ifconfig"]
|
108
|
+
common_paths.select{|path| File.executable?(path)}.first
|
109
|
+
end
|
110
|
+
##
|
111
|
+
# hpux_netstat_in is a delegate method that allows us to stub netstat -in
|
112
|
+
# without stubbing exec.
|
113
|
+
def self.hpux_netstat_in
|
114
|
+
Facter::Core::Execution.exec("/bin/netstat -in")
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.get_infiniband_macaddress(interface)
|
118
|
+
if File.exists?("/sys/class/net/#{interface}/address") then
|
119
|
+
ib_mac_address = `cat /sys/class/net/#{interface}/address`.chomp
|
120
|
+
elsif File.exists?("/sbin/ip") then
|
121
|
+
ip_output = %x{/sbin/ip link show #{interface}}
|
122
|
+
ib_mac_address = ip_output.scan(%r{infiniband\s+((\w{1,2}:){5,}\w{1,2})})
|
123
|
+
else
|
124
|
+
ib_mac_address = "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF"
|
125
|
+
Facter.debug("ip.rb: nothing under /sys/class/net/#{interface}/address and /sbin/ip not available")
|
126
|
+
end
|
127
|
+
ib_mac_address
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.ifconfig_interface(interface)
|
131
|
+
output = Vmopt::IP.exec_ifconfig([interface,"2>/dev/null"])
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.get_single_interface_output(interface)
|
135
|
+
output = ""
|
136
|
+
case Facter.value(:kernel)
|
137
|
+
when 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin', 'GNU/kFreeBSD', 'DragonFly'
|
138
|
+
output = Vmopt::IP.ifconfig_interface(interface)
|
139
|
+
when 'Linux'
|
140
|
+
ifconfig_output = Vmopt::IP.ifconfig_interface(interface)
|
141
|
+
if interface =~ /^ib/ then
|
142
|
+
real_mac_address = get_infiniband_macaddress(interface)
|
143
|
+
output = ifconfig_output.sub(%r{(?:ether|HWaddr)\s+((\w{1,2}:){5,}\w{1,2})}, "HWaddr #{real_mac_address}")
|
144
|
+
else
|
145
|
+
output = ifconfig_output
|
146
|
+
end
|
147
|
+
when 'SunOS'
|
148
|
+
output = Vmopt::IP.exec_ifconfig([interface])
|
149
|
+
when 'HP-UX'
|
150
|
+
mac = ""
|
151
|
+
ifc = hpux_ifconfig_interface(interface)
|
152
|
+
hpux_lanscan.scan(/(\dx\S+).*UP\s+(\w+\d+)/).each {|i| mac = i[0] if i.include?(interface) }
|
153
|
+
mac = mac.sub(/0x(\S+)/,'\1').scan(/../).join(":")
|
154
|
+
output = ifc + "\n" + mac
|
155
|
+
end
|
156
|
+
output
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.hpux_ifconfig_interface(interface)
|
160
|
+
Vmopt::IP.exec_ifconfig([interface])
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.hpux_lanscan
|
164
|
+
Facter::Core::Execution.exec("/usr/sbin/lanscan")
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.get_output_for_interface_and_label(interface, label)
|
168
|
+
return get_single_interface_output(interface) unless Facter.value(:kernel) == 'windows'
|
169
|
+
|
170
|
+
require 'facter/util/ip/windows'
|
171
|
+
output = Vmopt::IP::Windows.value_for_interface_and_label(interface, label)
|
172
|
+
output ? output : ""
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.get_bonding_master(interface)
|
176
|
+
if Facter.value(:kernel) != 'Linux'
|
177
|
+
return nil
|
178
|
+
end
|
179
|
+
# We need ip instead of ifconfig because it will show us
|
180
|
+
# the bonding master device.
|
181
|
+
if not FileTest.executable?("/sbin/ip")
|
182
|
+
return nil
|
183
|
+
end
|
184
|
+
# A bonding interface can never be an alias interface. Alias
|
185
|
+
# interfaces do have a colon in their name and the ip link show
|
186
|
+
# command throws an error message when we pass it an alias
|
187
|
+
# interface.
|
188
|
+
if interface =~ /:/
|
189
|
+
return nil
|
190
|
+
end
|
191
|
+
regex = /SLAVE[,>].* (bond[0-9]+)/
|
192
|
+
ethbond = regex.match(%x{/sbin/ip link show #{interface}})
|
193
|
+
if ethbond
|
194
|
+
device = ethbond[1]
|
195
|
+
else
|
196
|
+
device = nil
|
197
|
+
end
|
198
|
+
device
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# get_interface_value obtains the value of a specific attribute of a specific
|
203
|
+
# interface.
|
204
|
+
#
|
205
|
+
# @param interface [String] the interface identifier, e.g. "eth0" or "bond0"
|
206
|
+
#
|
207
|
+
# @param label [String] the attribute of the interface to obtain a value for,
|
208
|
+
# e.g. "netmask" or "ipaddress"
|
209
|
+
#
|
210
|
+
# @api private
|
211
|
+
#
|
212
|
+
# @return [String] representing the requested value. An empty array is
|
213
|
+
# returned if the kernel is not supported by the REGEX_MAP constant.
|
214
|
+
def self.get_interface_value(interface, label)
|
215
|
+
if Facter.value(:kernel) == 'windows'
|
216
|
+
require 'facter/util/ip/windows'
|
217
|
+
return Vmopt::IP::Windows.value_for_interface_and_label(interface, label)
|
218
|
+
end
|
219
|
+
|
220
|
+
tmp1 = []
|
221
|
+
|
222
|
+
kernel = Facter.value(:kernel).downcase.to_sym
|
223
|
+
|
224
|
+
# If it's not directly in the map or aliased in the map, then we don't know how to deal with it.
|
225
|
+
unless map = REGEX_MAP[kernel] || REGEX_MAP.values.find { |tmp| tmp[:aliases] and tmp[:aliases].include?(kernel) }
|
226
|
+
return []
|
227
|
+
end
|
228
|
+
|
229
|
+
# Pull the correct regex out of the map.
|
230
|
+
regex = map[label.to_sym]
|
231
|
+
|
232
|
+
# Linux changes the MAC address reported via ifconfig when an ethernet interface
|
233
|
+
# becomes a slave of a bonding device to the master MAC address.
|
234
|
+
# We have to dig a bit to get the original/real MAC address of the interface.
|
235
|
+
bonddev = get_bonding_master(interface)
|
236
|
+
if label == 'macaddress' and bonddev
|
237
|
+
bondinfo = read_proc_net_bonding("/proc/net/bonding/#{bonddev}")
|
238
|
+
re = /^Slave Interface: #{interface}\b.*?\bPermanent HW addr: (([0-9A-F]{2}:?)*)$/im
|
239
|
+
if match = re.match(bondinfo)
|
240
|
+
value = match[1].upcase
|
241
|
+
end
|
242
|
+
else
|
243
|
+
output_int = get_output_for_interface_and_label(interface, label)
|
244
|
+
|
245
|
+
output_int.each_line do |s|
|
246
|
+
if s =~ regex
|
247
|
+
value = $1
|
248
|
+
if label == 'netmask' && convert_from_hex?(kernel)
|
249
|
+
value = value.scan(/../).collect do |byte| byte.to_i(16) end.join('.')
|
250
|
+
end
|
251
|
+
tmp1.push(value)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
if tmp1
|
256
|
+
value = tmp1.shift
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
##
|
262
|
+
# read_proc_net_bonding is a seam method for mocking purposes.
|
263
|
+
#
|
264
|
+
# @param path [String] representing the path to read, e.g. "/proc/net/bonding/bond0"
|
265
|
+
#
|
266
|
+
# @api private
|
267
|
+
#
|
268
|
+
# @return [String] modeling the raw file read
|
269
|
+
def self.read_proc_net_bonding(path)
|
270
|
+
File.read(path) if File.exists?(path)
|
271
|
+
end
|
272
|
+
private_class_method :read_proc_net_bonding
|
273
|
+
|
274
|
+
def self.get_network_value(interface)
|
275
|
+
require 'ipaddr'
|
276
|
+
|
277
|
+
ipaddress = get_interface_value(interface, "ipaddress")
|
278
|
+
netmask = get_interface_value(interface, "netmask")
|
279
|
+
|
280
|
+
if ipaddress && netmask
|
281
|
+
ip = IPAddr.new(ipaddress, Socket::AF_INET)
|
282
|
+
subnet = IPAddr.new(netmask, Socket::AF_INET)
|
283
|
+
network = ip.mask(subnet.to_s).to_s
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|