Module: PuppetX::EnterpriseModules::OraInstall::Facts

Includes:
GetHomes
Defined in:
lib/puppet_x/enterprisemodules/ora_install/facts.rb

Instance Method Summary collapse

Instance Method Details

#cleanup_opatch_residue(home) ⇒ Object



136
137
138
139
140
141
142
143
144
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 136

def cleanup_opatch_residue(home)
  # Some older versions of Opatch leave files and directories arround
  # When running opatch often, this causes some issues. This is to make
  # sure all files created by running Opatch as part of the fact, are remopved
  basename = Time.now.strftime("%Y-%m-%d_%H-%M-*%p")
  Puppet.debug `rm -rf /tmp/OraInstall*`
  Puppet.debug `rm -rf /tmp/opatch`
  FileUtils.rm_f("#{home}/cfgtoollogs/opatch/lsinv/lsinventory#{basename}.txt")
end

#first_non_root_file(dir) ⇒ Object



132
133
134
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 132

def first_non_root_file(dir)
  Dir.new(dir).each { |file| break file if File.stat("#{dir}/#{file}").uid.nonzero? }
end

#get_database_user(home) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 14

def get_database_user(home)
  databaseUser = Facter.value('override_database_user')
  if databaseUser.nil?
    # puts "database user is oracle"
    if File.directory?("#{home}/bin")
      Facter::Util::Resolution.exec("/bin/stat --format=%U #{home}/bin/oracle")
    else
      'oracle'
    end
  else
    # puts "database user is " + databaseUser
    return databaseUser
  end
end

#get_defined_sids(home) ⇒ Object



146
147
148
149
150
151
152
153
154
155
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 146

def get_defined_sids(home)
  if os == 'windows'
    home_name = get_home_name(home)
    regkey = Win32::Registry::HKEY_LOCAL_MACHINE.open("SOFTWARE\\Oracle\\KEY_#{home_name}")
    regkey.select { |k,_v1, v| k.scan(/ORA_(.*)_AUTOSTART/) != [] }.flatten.collect {|k| k.to_s.scan(/ORA_(.*)_AUTOSTART/)}.flatten.uniq
  else
    quoted_home = Regexp.quote(home)
    oratab_content.scan(/^([+-_A-Za-z].*):#{quoted_home}:[YN].*$/).flatten.uniq
  end
end

#get_home_name(home) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 66

def get_home_name(home)
  inventory_loc = get_orainst_loc
  if File.exist?(inventory_loc + '/ContentsXML/inventory.xml')
    file = File.read(inventory_loc + '/ContentsXML/inventory.xml')
    doc = REXML::Document.new(file)
    doc.elements.each('/INVENTORY/HOME_LIST/HOME') do |element|
      if element.attributes['LOC'] == home
        return element.attributes['NAME']
      end
    end
  else
    return 'Invalid'
  end
end

#get_installed_patches(oracle_home) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 86

def get_installed_patches(oracle_home)
  if File.directory?(oracle_home)
    unless os == 'windows'
      ora_user = user_for_file(oracle_home)
    end
    installed_patches = patches_in_home(oracle_home, ora_user).flatten.sort
  else
    installed_patches = ['Invalid']
  end
  cleanup_opatch_residue(oracle_home) if Facter.value(:kernel) == 'Linux'
  installed_patches
end

#get_mode_role(sid, home) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 215

def get_mode_role(sid, home)
  command     = %Q(sqlplus -S /nolog << EOF
    connect / as sysdba
    set heading off
    select replace(open_mode, chr(32), chr(95)) as open_mode
         , replace(database_role, chr(32), chr(95)) as database_role
      from v\\$database;
EOF)
  `su #{user_for_file(home)} -c 'export ORACLE_HOME="#{home}"; \
                                 export PATH="#{home}/bin:$PATH"; \
                                 export ORACLE_SID="#{sid}"; \
                                 unset TNS_ADMIN; \
                                 unset TWO_TASK; \
                                 export LD_LIBRARY_PATH="#{home}/lib"; \
                                 #{command}'`
end

#get_opatch_version(home) ⇒ Object



38
39
40
41
42
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 38

def get_opatch_version(home)
  version = lsinventory(home).scan(/OPatch [V|v]ersion\s*:\s*(.*)/).flatten.first
  Puppet.debug "ora_install opatch version #{home}/OPatch/opatch: #{version}"
  (version.nil?) ? 'Invalid' : version
end

#get_product_version(oracle_home) ⇒ Object



232
233
234
235
236
237
238
239
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 232

def get_product_version(oracle_home)
  product_version = { 'name'    => get_home_name(oracle_home),
                      'os_user' => user_for_file(oracle_home),
                      'version' => get_version(oracle_home)
                    }
  cleanup_opatch_residue(oracle_home) if Facter.value(:kernel) == 'Linux'
  product_version
end

#get_running_listeners(home) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 198

def get_running_listeners(home)
  command = %Q(ps -eo pid,cmd | grep "#{home}/bin/tns[l]snr" | sed 's/-inherit//' | sed 's/-no_crs_notify//' |
               while read pid command listener; do
                   printf "%-9s %-80s\n" $listener  $(ls -l /proc/$pid/exe | awk '{ print $NF }' | sort | uniq)
               done)
  raw_info = Facter::Util::Resolution.exec(command)
  if $?.success?
    return [] if raw_info.empty?
    raw_info.split("\n").select{|e| e.include?(home)}.collect {|e| e.split.first}.sort
  else
    puts "Fetching running listeners, needs access to /proc/pid/exe file system."
    puts "Probably using docker in non-privileged mode."
    puts "Run docker in privileged mode to fix the issue."
    nil
  end
end

#get_running_processes(home) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 157

def get_running_processes(home)
  if os == 'Linux'
    {
      'sids'      => get_running_sids(home),
      'listeners' => get_running_listeners(home)
    }
  else
    {
      'sids'      => 'n/a',
      'listeners' => 'n/a'
    }
  end
end

#get_running_sids(home) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 171

def get_running_sids(home)
  command = %Q(ps aux | egrep "(ora|asm)_pmon" | awk '{gsub("(ora|asm)_pmon_", ""); print $2, $NF}' |
               while read pid sid; do
                   printf "%-20s,%-80s\n" $sid  $(ls -l /proc/$pid/exe | awk '{ print $NF }' | sed 's/\\/bin\\/oracle$//' | sort | uniq)
               done)
  raw_info = Facter::Util::Resolution.exec(command)
  if $?.success?
    return {} if raw_info.empty?
    databases = raw_info.split("\n").select{|e| e.include?(home)}.collect {|e| e.split(',').first.strip}.sort
    db_hash = databases.collect do |db|
      if db =~ /ASM/
        db_mode_role = ['n/a','n/a']
      else
        db_mode_role = get_mode_role(db, home).split
      end
      {db => { 'open_mode'     => db_mode_role[0],
               'database_role' => db_mode_role[1] }}
    end
    Hash[*db_hash.collect {|h| h.to_a}.flatten]
  else
    puts "Fetching running SIDS, needs access to /proc/pid/exe file system."
    puts "Probably using docker in non-privileged mode."
    puts "Run docker in privileged mode to fix the issue."
    nil
  end
end

#get_su_commandObject



29
30
31
32
33
34
35
36
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 29

def get_su_command
  if os == 'Linux'
    return 'su -l '
  elsif os == 'SunOS'
    return 'su - '
  end
  'su -l '
end

#get_version(home) ⇒ Object



81
82
83
84
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 81

def get_version(home)
  version = opatch_installed?(home) ? lsinventory(home).scan(/^(?:Oracle Database|Oracle Client|Oracle Grid Infrastructure|Oracle GoldenGate)\s.+?\s+(.*)$/).flatten.first : 'Invalid'
  (version.nil?) ? 'Invalid' : version
end

#lsinventory(home) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 44

def lsinventory(home)
  @lsinventory ||= {}
  if os == 'windows'
    @lsinventory[home] ||= `#{home}/OPatch/opatch lsinventory`
  else
    if supports_nolog?(home)
      @lsinventory[home] ||= Facter::Util::Resolution.exec("su #{user_for_file(home)} -c 'ORACLE_HOME=#{home} #{home}/OPatch/opatch lsinventory -customLogDir /tmp'")
      # We remove the created directory here, because it sometimes creates a dir with an other owner, which causes troubles for the next oracle home
      Puppet.debug `rm -rf /tmp/opatch`
      @lsinventory[home]
    else
      @lsinventory[home] ||= Facter::Util::Resolution.exec("su #{user_for_file(home)} -c 'ORACLE_HOME=#{home} #{home}/OPatch/opatch lsinventory'")
    end
  end
end

#opatch_installed?(oracle_home) ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 110

def opatch_installed?(oracle_home)
  File.exist?("#{oracle_home}/OPatch/opatch")
end

#patches_in_home(oracle_product_home_dir, os_user) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 99

def patches_in_home(oracle_product_home_dir, os_user)
  if opatch_installed?(oracle_product_home_dir)
    lsinventory(oracle_product_home_dir).scan(/Patch\s.(\d+)\s.*:\sapplied on/).flatten
  else
    #
    # When Opatch is not installed, we don't report any patches
    #
    ['Invalid']
  end
end

#supports_nolog?(home) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
63
64
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 60

def supports_nolog?(home)
  @lsinventory_help ||= {}
  @lsinventory_help[home] ||= Facter::Util::Resolution.exec("su #{user_for_file(home)} -c 'ORACLE_HOME=#{home} #{home}/OPatch/opatch lsinventory -help'")
  @lsinventory_help[home] =~ /customLogDir/
end

#user_for_file(home) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/puppet_x/enterprisemodules/ora_install/facts.rb', line 114

def user_for_file(home)
  #
  # To run opatch, we need the owner of the grid and oracle directory. The mechanism
  # we use to get this user, is to fetch the owner of the bin directory in the grid or
  # oracle home. Sometimes however, these directories also contain files with root as owner.
  # since root can never be the user of the grid or oracle processen, we skip those.
  #
  if os == 'windows'
    # On Windows all files and dirs have uid=0, use 'oracle' for now
    # TODO: find a way to determine the real owner on Windows
    'oracle'
  else
    a_file = first_non_root_file(home)
    uid = File.stat("#{home}/#{a_file}").uid
    Etc.getpwuid(uid).name
  end
end