ohai 8.7.0 → 8.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/lib/ohai/application.rb +3 -1
  4. data/lib/ohai/loader.rb +4 -3
  5. data/lib/ohai/mixin/dmi_decode.rb +47 -0
  6. data/lib/ohai/mixin/os.rb +2 -0
  7. data/lib/ohai/plugins/aix/kernel.rb +2 -1
  8. data/lib/ohai/plugins/{freebsd → bsd}/filesystem.rb +21 -3
  9. data/lib/ohai/plugins/bsd/virtualization.rb +80 -0
  10. data/lib/ohai/plugins/dragonflybsd/cpu.rb +58 -0
  11. data/lib/ohai/plugins/dragonflybsd/memory.rb +60 -0
  12. data/lib/ohai/plugins/dragonflybsd/network.rb +126 -0
  13. data/lib/ohai/plugins/dragonflybsd/os.rb +32 -0
  14. data/lib/ohai/plugins/dragonflybsd/platform.rb +29 -0
  15. data/lib/ohai/plugins/freebsd/cpu.rb +14 -8
  16. data/lib/ohai/plugins/freebsd/os.rb +1 -1
  17. data/lib/ohai/plugins/hostname.rb +1 -1
  18. data/lib/ohai/plugins/kernel.rb +12 -0
  19. data/lib/ohai/plugins/linux/virtualization.rb +8 -37
  20. data/lib/ohai/plugins/network_listeners.rb +5 -0
  21. data/lib/ohai/plugins/ps.rb +2 -2
  22. data/lib/ohai/plugins/solaris2/filesystem.rb +9 -1
  23. data/lib/ohai/plugins/uptime.rb +1 -1
  24. data/lib/ohai/plugins/virtualbox.rb +44 -0
  25. data/lib/ohai/plugins/windows/cpu.rb +26 -27
  26. data/lib/ohai/plugins/windows/virtualization.rb +29 -17
  27. data/lib/ohai/system.rb +1 -1
  28. data/lib/ohai/version.rb +1 -1
  29. data/ohai.gemspec +50 -0
  30. data/spec/functional/loader_spec.rb +53 -0
  31. data/spec/unit/loader_spec.rb +51 -53
  32. data/spec/unit/plugins/aix/kernel_spec.rb +5 -0
  33. data/spec/unit/plugins/bsd/filesystem_spec.rb +126 -0
  34. data/spec/unit/plugins/{freebsd → bsd}/virtualization_spec.rb +7 -4
  35. data/spec/unit/plugins/freebsd/cpu_spec.rb +60 -14
  36. data/spec/unit/plugins/linux/virtualization_spec.rb +58 -5
  37. data/spec/unit/plugins/solaris2/filesystem.rb +84 -0
  38. data/spec/unit/plugins/virtualbox_spec.rb +88 -0
  39. data/spec/unit/plugins/windows/cpu_spec.rb +3 -1
  40. data/spec/unit/plugins/windows/virtualization_spec.rb +182 -32
  41. metadata +21 -26
  42. data/lib/ohai/plugins/freebsd/virtualization.rb +0 -94
  43. data/lib/ohai/plugins/netbsd/filesystem.rb +0 -57
  44. data/lib/ohai/plugins/netbsd/virtualization.rb +0 -68
  45. data/lib/ohai/plugins/openbsd/filesystem.rb +0 -57
  46. data/lib/ohai/plugins/openbsd/virtualization.rb +0 -68
@@ -0,0 +1,32 @@
1
+ #
2
+ # Authors:: Adam Jacob (<adam@opscode.com>)
3
+ # Richard Manyanza (<liseki@nyikacraftsmen.com>)
4
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
5
+ # Copyright:: Copyright (c) 2014 Richard Manyanza.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require 'ohai/mixin/os'
22
+
23
+ Ohai.plugin(:OS) do
24
+ provides "os", "os_version"
25
+
26
+ collect_data(:dragonflybsd) do
27
+ os collect_os
28
+
29
+ # This is __DragonFly_version. See sys/param.h
30
+ os_version shell_out("sysctl -n kern.osreldate").stdout.split($/)[0]
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ #
2
+ # Author:: Bryan McLellan (btm@loftninjas.org)
3
+ # Copyright:: Copyright (c) 2009 Bryan McLellan
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ Ohai.plugin(:Platform) do
20
+ provides "platform", "platform_version", "platform_family"
21
+
22
+ collect_data(:dragonflybsd) do
23
+ so = shell_out("uname -s")
24
+ platform so.stdout.split($/)[0].downcase
25
+ so = shell_out("uname -r")
26
+ platform_version so.stdout.split($/)[0]
27
+ platform_family "dragonflybsd"
28
+ end
29
+ end
@@ -1,5 +1,6 @@
1
1
  #
2
2
  # Author:: Bryan McLellan (btm@loftninjas.org)
3
+ # Author:: Tim Smith (tsmith@chef.io)
3
4
  # Copyright:: Copyright (c) 2008 Bryan McLellan
4
5
  # License:: Apache License, Version 2.0
5
6
  #
@@ -27,21 +28,26 @@ Ohai.plugin(:CPU) do
27
28
  cpuinfo["flags"] = []
28
29
 
29
30
  # /var/run/dmesg.boot
30
- # CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz (3516.61-MHz K8-class CPU)
31
- # Origin = "GenuineIntel" Id = 0x306a9 Family = 6 Model = 3a Stepping = 9
32
- # Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
33
- # Features2=0x209<SSE3,MON,SSSE3>
34
- # AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
35
- # AMD Features2=0x1<LAHF>
31
+ # CPU: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz (2793.59-MHz K8-class CPU)
32
+ # Origin="GenuineIntel" Id=0x40661 Family=0x6 Model=0x46 Stepping=1
33
+ # Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
34
+ # Features2=0x5ed8220b<SSE3,PCLMULQDQ,MON,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,RDRAND>
35
+ # AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
36
+ # AMD Features2=0x21<LAHF,ABM>
37
+ # Structured Extended Features=0x2000<NFPUSG>
38
+ # TSC: P-state invariant
36
39
 
37
40
  File.open("/var/run/dmesg.boot").each do |line|
38
41
  case line
39
42
  when /CPU:\s+(.+) \(([\d.]+).+\)/
40
43
  cpuinfo["model_name"] = $1
41
44
  cpuinfo["mhz"] = $2
42
- when /Origin = "(.+)"\s+Id = (.+)\s+Stepping = (.+)/
45
+ when /Origin.*"(.*)".*Family.*0x(\S+).*Model.*0x(\S+).*Stepping.*(\S+)/
43
46
  cpuinfo["vendor_id"] = $1
44
- cpuinfo["stepping"] = $3
47
+ # convert from hex value to int, but keep a string to match Linux ohai
48
+ cpuinfo["family"] = $2.to_i(16).to_s
49
+ cpuinfo["model"] = $3.to_i(16).to_s
50
+ cpuinfo["stepping"] = $4
45
51
  # These _should_ match /AMD Features2?/ lines as well
46
52
  when /Features=.+<(.+)>/
47
53
  cpuinfo["flags"].concat($1.downcase.split(','))
@@ -26,7 +26,7 @@ Ohai.plugin(:OS) do
26
26
  collect_data(:freebsd) do
27
27
  os collect_os
28
28
 
29
- # This is __FreeBSD_version. See sys/param.h or
29
+ # This is __FreeBSD_version. See sys/param.h or
30
30
  # http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
31
31
  os_version shell_out("sysctl -n kern.osreldate").stdout.split($/)[0]
32
32
  end
@@ -97,7 +97,7 @@ Ohai.plugin(:Hostname) do
97
97
  collect_domain
98
98
  end
99
99
 
100
- collect_data(:darwin, :netbsd, :openbsd) do
100
+ collect_data(:darwin, :netbsd, :openbsd, :dragonflybsd) do
101
101
  hostname from_cmd("hostname -s")
102
102
  fqdn resolve_fqdn
103
103
  machinename from_cmd("hostname")
@@ -132,6 +132,18 @@ Ohai.plugin(:Kernel) do
132
132
  kernel[:modules] = bsd_modules("/usr/bin/modstat")
133
133
  end
134
134
 
135
+ collect_data(:dragonflybsd) do
136
+ kernel init_kernel
137
+ kernel[:os] = kernel[:name]
138
+
139
+ so = shell_out("uname -i")
140
+ kernel[:ident] = so.stdout.split($/)[0]
141
+ so = shell_out("sysctl kern.securelevel")
142
+ kernel[:securelevel] = so.stdout.split($/).select { |e| e =~ /kern.securelevel: (.+)$/ }
143
+
144
+ kernel[:modules] = bsd_modules("/sbin/kldstat")
145
+ end
146
+
135
147
  collect_data(:solaris2) do
136
148
  kernel init_kernel
137
149
 
@@ -17,8 +17,10 @@
17
17
  #
18
18
 
19
19
  require 'ohai/util/file_helper'
20
+ require 'ohai/mixin/dmi_decode'
20
21
 
21
22
  include Ohai::Util::FileHelper
23
+ include Ohai::Mixin::DmiDecode
22
24
 
23
25
  Ohai.plugin(:Virtualization) do
24
26
  provides "virtualization"
@@ -114,44 +116,13 @@ Ohai.plugin(:Virtualization) do
114
116
  end
115
117
  end
116
118
 
117
- # http://www.dmo.ca/blog/detecting-virtualization-on-linux
119
+ # parse dmidecode to discover various virtualization guests
118
120
  if File.exists?("/usr/sbin/dmidecode")
119
- so = shell_out("dmidecode")
120
- case so.stdout
121
- when /Manufacturer: Microsoft/
122
- if so.stdout =~ /Product Name: Virtual Machine/
123
- virtualization[:system] = "virtualpc"
124
- virtualization[:role] = "guest"
125
- virtualization[:systems][:virtualpc] = "guest"
126
- end
127
- when /Manufacturer: VMware/
128
- if so.stdout =~ /Product Name: VMware Virtual Platform/
129
- virtualization[:system] = "vmware"
130
- virtualization[:role] = "guest"
131
- virtualization[:systems][:vmware] = "guest"
132
- end
133
- when /Manufacturer: Xen/
134
- if so.stdout =~ /Product Name: HVM domU/
135
- virtualization[:system] = "xen"
136
- virtualization[:role] = "guest"
137
- virtualization[:systems][:xen] = "guest"
138
- end
139
- when /Manufacturer: Oracle Corporation/
140
- if so.stdout =~ /Product Name: VirtualBox/
141
- virtualization[:system] = "vbox"
142
- virtualization[:role] = "guest"
143
- virtualization[:systems][:vbox] = "guest"
144
- end
145
- when /Product Name: OpenStack/
146
- virtualization[:system] = "openstack"
147
- virtualization[:role] = "guest"
148
- virtualization[:systems][:openstack] = "guest"
149
- when /Manufacturer: QEMU|Product Name: KVM/
150
- virtualization[:system] = "kvm"
151
- virtualization[:role] = "guest"
152
- virtualization[:systems][:kvm] = "guest"
153
- else
154
- nil
121
+ guest = determine_guest(shell_out('dmidecode').stdout)
122
+ if guest
123
+ virtualization[:system] = guest
124
+ virtualization[:role] = 'guest'
125
+ virtualization[:systems][guest.to_sym] = 'guest'
155
126
  end
156
127
  end
157
128
 
@@ -39,6 +39,11 @@ Ohai.plugin(:NetworkListeners) do
39
39
  listeners[port][:address] = addr
40
40
  begin
41
41
  pid = sigar.proc_port(conn.type, port)
42
+ # workaround for a failure of proc_state to throw
43
+ # after the first 0 has been supplied to it
44
+ #
45
+ # no longer required when hyperic/sigar#48 is fixed
46
+ throw ArgumentError.new("No such process") if pid == 0
42
47
  listeners[port][:pid] = pid
43
48
  listeners[port][:name] = sigar.proc_state(pid).name
44
49
  rescue
@@ -27,8 +27,8 @@ Ohai.plugin(:PS) do
27
27
  command[:ps] = 'ps -ef'
28
28
  end
29
29
 
30
- collect_data(:freebsd, :netbsd, :openbsd) do
30
+ collect_data(:freebsd, :netbsd, :openbsd, :dragonflybsd) do
31
31
  # ps -e requires procfs
32
- command[:ps] = 'ps -ax'
32
+ command[:ps] = 'ps -axww'
33
33
  end
34
34
  end
@@ -63,7 +63,15 @@ Ohai.plugin(:Filesystem) do
63
63
 
64
64
  # Grab any zfs data from "zfs get"
65
65
  zfs = Mash.new
66
- so = shell_out("zfs get -p -H all")
66
+ # ohai.plugin[:filesystem][:zfs_properties] = 'used'
67
+ # ohai.plugin[:filesystem][:zfs_properties] = ['mountpoint', 'creation', 'available', 'used']
68
+ zfs_get = "zfs get -p -H "
69
+ if configuration(:zfs_properties).nil? || configuration(:zfs_properties).empty?
70
+ zfs_get << "all"
71
+ else
72
+ zfs_get << [configuration(:zfs_properties)].join(',')
73
+ end
74
+ so = shell_out(zfs_get)
67
75
  so.stdout.lines do |line|
68
76
  next unless (line =~ /^([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)$/)
69
77
  filesystem = $1
@@ -57,7 +57,7 @@ Ohai.plugin(:Uptime) do
57
57
  uptime data.last
58
58
  end
59
59
 
60
- collect_data(:freebsd, :netbsd) do
60
+ collect_data(:freebsd, :netbsd, :dragonflybsd) do
61
61
  data = collect_uptime("/sbin/sysctl")
62
62
  uptime_seconds data.first
63
63
  uptime data.last
@@ -0,0 +1,44 @@
1
+ #
2
+ # Author:: "Tim Smith" <tsmith@chef.io>
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ Ohai.plugin(:Virtualbox) do
20
+ provides 'virtualbox'
21
+
22
+ collect_data do
23
+ so = shell_out('VBoxControl guestproperty enumerate')
24
+ if so.exitstatus == 0
25
+ virtualbox Mash.new
26
+ virtualbox[:host] = Mash.new
27
+ virtualbox[:guest] = Mash.new
28
+ so.stdout.lines.each do |line|
29
+ case line
30
+ when /LanguageID, value: (\S*),/
31
+ virtualbox[:host][:language] = Regexp.last_match(1)
32
+ when /VBoxVer, value: (\S*),/
33
+ virtualbox[:host][:version] = Regexp.last_match(1)
34
+ when /VBoxRev, value: (\S*),/
35
+ virtualbox[:host][:revision] = Regexp.last_match(1)
36
+ when /GuestAdd\/VersionExt, value: (\S*),/
37
+ virtualbox[:guest][:guest_additions_version] = Regexp.last_match(1)
38
+ when /GuestAdd\/Revision, value: (\S*),/
39
+ virtualbox[:guest][:guest_additions_revision] = Regexp.last_match(1)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -22,50 +22,49 @@ Ohai.plugin(:CPU) do
22
22
  collect_data(:windows) do
23
23
  require 'wmi-lite/wmi'
24
24
 
25
- cpuinfo = Mash.new
26
- cpu_number = 0
27
- index = 0
25
+ cpu Mash.new
26
+ cores = 0
27
+ logical_processors = 0
28
28
 
29
29
  wmi = WmiLite::Wmi.new
30
30
  processors = wmi.instances_of('Win32_Processor')
31
31
 
32
- processors.each do |processor|
32
+ processors.each_with_index do |processor, index|
33
+ current_cpu = index.to_s
34
+ cpu[current_cpu] = Mash.new
33
35
  #
34
- # On Windows Server 2003 R2 (i.e. 5.2.*), numberofcores property
36
+ # On Windows Server 2003 R2 (i.e. 5.2.*), numberofcores property
35
37
  # doesn't exist on the Win32_Processor class unless the user has
36
38
  # patched their system with:
37
39
  # http://support.microsoft.com/kb/932370
38
- #
39
- # We're returning nil for cpu["cores"] and cpu["count"]
40
+ #
41
+ # We're returning nil for cpu["cores"]
40
42
  # when we don't see numberofcores property
41
43
  #
42
44
 
43
- number_of_cores = nil
44
45
  begin
45
- number_of_cores = processor['numberofcores']
46
- cpu_number += number_of_cores
46
+ cpu[current_cpu]["cores"] = processor['numberofcores']
47
+ cores += processor['numberofcores']
47
48
  rescue NoMethodError => e
48
49
  Ohai::Log.info("Can not find numberofcores property on Win32_Processor. Consider applying this patch: http://support.microsoft.com/kb/932370")
50
+ cpu[current_cpu]["cores"] = nil
49
51
  end
50
52
 
51
- current_cpu = index.to_s
52
- index += 1
53
- cpuinfo[current_cpu] = Mash.new
54
- cpuinfo[current_cpu]["vendor_id"] = processor['manufacturer']
55
- cpuinfo[current_cpu]["family"] = processor['family'].to_s
56
- cpuinfo[current_cpu]["model"] = processor['revision'].to_s
57
- cpuinfo[current_cpu]["stepping"] = processor['stepping']
58
- cpuinfo[current_cpu]["physical_id"] = processor['deviceid']
59
- #cpuinfo[current_cpu]["core_id"] = XXX
60
- cpuinfo[current_cpu]["cores"] = number_of_cores
61
- cpuinfo[current_cpu]["model_name"] = processor['description']
62
- cpuinfo[current_cpu]["mhz"] = processor['maxclockspeed'].to_s
63
- cpuinfo[current_cpu]["cache_size"] = "#{processor['l2cachesize']} KB"
64
- #cpuinfo[current_cpu]["flags"] = XXX
53
+ logical_processors += processor['numberoflogicalprocessors']
54
+ cpu[current_cpu]["vendor_id"] = processor['manufacturer']
55
+ cpu[current_cpu]["family"] = processor['family'].to_s
56
+ cpu[current_cpu]["model"] = processor['revision'].to_s
57
+ cpu[current_cpu]["stepping"] = processor['stepping'].nil? \
58
+ ? processor['description'].match(/Stepping\s+(\d+)/)[1] \
59
+ : processor['stepping']
60
+ cpu[current_cpu]["physical_id"] = processor['deviceid']
61
+ cpu[current_cpu]["model_name"] = processor['description']
62
+ cpu[current_cpu]["mhz"] = processor['maxclockspeed'].to_s
63
+ cpu[current_cpu]["cache_size"] = "#{processor['l2cachesize']} KB"
65
64
  end
66
65
 
67
- cpu cpuinfo
68
- cpu[:total] = (cpu_number == 0) ? nil : cpu_number
69
- cpu[:real] = index
66
+ cpu[:total] = logical_processors
67
+ cpu[:cores] = cores
68
+ cpu[:real] = processors.length
70
69
  end
71
70
  end
@@ -1,6 +1,8 @@
1
1
  #
2
2
  # Author:: Pavel Yudin (<pyudin@parallels.com>)
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
3
4
  # Copyright:: Copyright (c) 2015 Pavel Yudin
5
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
6
  # License:: Apache License, Version 2.0
5
7
  #
6
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,29 +18,39 @@
16
18
  # limitations under the License.
17
19
  #
18
20
 
19
- require 'ohai/util/file_helper'
20
-
21
- include Ohai::Util::FileHelper
22
-
23
21
  Ohai.plugin(:Virtualization) do
24
- provides "virtualization"
25
-
26
- def powershell_exists?
27
- which('powershell.exe')
28
- end
22
+ provides 'virtualization'
29
23
 
30
24
  collect_data(:windows) do
25
+ require 'wmi-lite/wmi'
26
+
31
27
  virtualization Mash.new unless virtualization
32
28
  virtualization[:systems] = Mash.new unless virtualization[:systems]
33
29
 
34
- # Detect Parallels virtual machine from BIOS information
35
- if powershell_exists?
36
- so = shell_out('powershell.exe "Get-WmiObject -Class Win32_BIOS"')
37
- if so.stdout =~ /Parallels Software International Inc./
38
- virtualization[:system] = 'parallels'
39
- virtualization[:role] = 'guest'
40
- virtualization[:systems][:parallels] = 'guest'
41
- end
30
+ # Grab BIOS data from WMI to determine vendor information
31
+ wmi = WmiLite::Wmi.new
32
+ bios = wmi.instances_of('Win32_BIOS')
33
+
34
+ case bios[0]['manufacturer']
35
+ when 'innotek GmbH'
36
+ virtualization[:system] = 'vbox'
37
+ virtualization[:role] = 'guest'
38
+ virtualization[:systems][:vbox] = 'guest'
39
+ when 'Parallels Software International Inc.'
40
+ virtualization[:system] = 'parallels'
41
+ virtualization[:role] = 'guest'
42
+ virtualization[:systems][:parallels] = 'guest'
43
+ when 'Bochs'
44
+ virtualization[:system] = "kvm"
45
+ virtualization[:role] = "guest"
46
+ virtualization[:systems][:kvm] = "guest"
47
+ end
48
+
49
+ # vmware fusion detection
50
+ if bios[0]['serialnumber'] =~ /VMware/
51
+ virtualization[:system] = 'vmware'
52
+ virtualization[:role] = 'guest'
53
+ virtualization[:systems][:vmware] = 'guest'
42
54
  end
43
55
  end
44
56
  end