Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oracle_opatch: optionally stop processes when remove a patch #110

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ab87f3c
added stop_processes for remove_patch
duhlig Jun 28, 2019
e0927f8
Merge remote-tracking branch 'rendanic-aom/prstartdb'
duhlig Jul 4, 2019
6078799
Some interim patches are PSU/RU dependent. The patch ID is the same b…
duhlig Nov 25, 2019
42e65ec
oracle_opatch: Find running listener more robust
duhlig Dec 6, 2019
031b16a
First version of oracle_sqldba.
duhlig Jan 16, 2020
b99ad50
Fix broken sqlselect in oracle_sqldba
duhlig Jan 17, 2020
49dea15
Fix broken run_catcon_pl in oracle_sqldba.
duhlig Jan 17, 2020
a6bfa79
Merge remote-tracking branch 'oravirt_20200305/master'
duhlig Mar 5, 2020
a0e9c90
Merge https://github.com/oravirt/ansible-oracle-modules
Aug 6, 2020
dfba654
Merge branch 'prsuplogging' of https://github.com/Rendanic/ansible-or…
Aug 6, 2020
fff6a7a
added stop_processes for remove_patch
duhlig Jun 28, 2019
192aa5f
oracle_db: Bugfix for start_db in Oracle Restart
Rendanic Apr 21, 2019
c10fe26
Some interim patches are PSU/RU dependent. The patch ID is the same b…
duhlig Nov 25, 2019
3ec6f89
Use Thorsten's fix over mine.
duhlig Dec 6, 2019
43fda6b
oracle_db: fixed ORA-00904: invalid identifier sql: select SUPPLEMENT…
Rendanic May 29, 2020
64bd72a
oracle_db: Bugfix for empty slsql
Rendanic Jun 6, 2020
0271b99
Merge branch 'master' of https://github.com/duhlig/ansible-oracle-mod…
duhlig Dec 17, 2021
716c31f
Minor fixes, oracle_parameter: changed default of scope to spfile
duhlig Dec 17, 2021
1d062a2
Merge remote-tracking branch 'upstream/master'
duhlig Nov 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions oracle_datapatch
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ def check_db_exists(module, msg, oracle_home, db_name, sid, db_unique_name ):
return False
elif 'Database name: %s' % (db_name) in stdout: #<-- Database already exist
return True
else:
msg = '%s' % (stdout) # this assignment does nothing as msg is not global --> should be fixed later
return True
else:
existingdbs = []
oratabfile = '/etc/oratab'
Expand Down
23 changes: 16 additions & 7 deletions oracle_db
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ oracle_db:
'''
import os, re, time

msg = ['']

try:
import cx_Oracle
except ImportError:
Expand All @@ -301,7 +303,8 @@ def get_version(module, msg, oracle_home):


# Check if the database exists
def check_db_exists(module, msg, oracle_home, db_name, sid, db_unique_name ):
def check_db_exists(module, oracle_home, db_name, sid, db_unique_name ):
global msg

if sid is None:
sid = ''
Expand Down Expand Up @@ -391,8 +394,14 @@ def create_db (module, msg, oracle_home, sys_password, system_password, dbsnmp_p
if system_password is not None:
command += ' -systemPassword \"%s\"' % (system_password)
else:
system_password = sys_password
command += ' -systemPassword \"%s\"' % (system_password)
pw_found = False
with open(responsefile) as rspfile:
for line in rspfile:
if re.match('systemPassword=.+', line):
pw_found = True
break
if not pw_found:
command += ' -systemPassword \"%s\"' % (sys_password)
if dbsnmp_password is not None:
command += ' -dbsnmpPassword \"%s\"' % (dbsnmp_password)
else:
Expand Down Expand Up @@ -897,8 +906,8 @@ def getconn(module,msg):

def main():

msg = ['']
cursor = None
global msg
global gimanaged
global major_version
global user
Expand Down Expand Up @@ -1044,7 +1053,7 @@ def main():

if state == 'started':
msg = "oracle_home: %s db_name: %s sid: %s db_unique_name: %s" % (oracle_home, db_name, sid, db_unique_name)
if not check_db_exists(module, msg, oracle_home,db_name, sid, db_unique_name):
if not check_db_exists(module, oracle_home,db_name, sid, db_unique_name):
msg = "Database not found. %s" % msg
module.fail_json(msg=msg, changed=False)
else:
Expand All @@ -1062,7 +1071,7 @@ def main():


elif state == 'present':
if not check_db_exists(module, msg, oracle_home,db_name, sid, db_unique_name):
if not check_db_exists(module, oracle_home,db_name, sid, db_unique_name):
if create_db(module, msg, oracle_home, sys_password, system_password, dbsnmp_password, db_name, sid, db_unique_name, responsefile, template, cdb, local_undo, datafile_dest, recoveryfile_dest,
storage_type, dbconfig_type, racone_service, characterset, memory_percentage, memory_totalmb, nodelist, db_type, amm, initparams, customscripts,datapatch, domain):
newdb = True
Expand All @@ -1075,7 +1084,7 @@ def main():
# module.exit_json(msg=msg, changed=False)

elif state == 'absent':
if check_db_exists(module, msg, oracle_home, db_name, sid, db_unique_name):
if check_db_exists(module, oracle_home, db_name, sid, db_unique_name):
if remove_db(module, msg, oracle_home, db_name, sid, db_unique_name, sys_password):
msg = 'Successfully removed database %s' % (db_name)
module.exit_json(msg=msg, changed=True)
Expand Down
70 changes: 48 additions & 22 deletions oracle_opatch
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ options:
required: False
default: None
aliases: ['version_added']
exclude_upi:
description:
- The unique patch identifier that should not be rolled back
e.g 22990084
- This option will be honored only when state=absent.
- It helps to write idempotent playbooks when changing interim patches that are dependent on a specific PSU/RU.
required: False
default: None
aliases: ['exclude_unique_patch_id']
opatch_minversion:
description:
- The minimum version of opatch needed
Expand Down Expand Up @@ -93,14 +102,14 @@ options:

notes:
-
requirements: [ "os","pwd","distutils.version" ]
author: Mikael Sandström, [email protected], @oravirt
requirements: [ "os","pwd","re","distutils.version" ]
author: Mikael Sandström, [email protected], @oravirt
'''

EXAMPLES = '''

'''
import os, pwd
import os, pwd, re
from distutils.version import LooseVersion
#
# try:
Expand Down Expand Up @@ -155,7 +164,7 @@ def get_file_owner(module, msg, oracle_home):
msg = 'Could not determine owner of %s ' % (checkfile)
module.fail_json(msg=msg)

def check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatchauto):
def check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatchauto, exclude_upi):
'''
Gets all patches already applied and compares to the
intended patch
Expand All @@ -169,18 +178,28 @@ def check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatc
(rc, stdout, stderr) = module.run_command(command)
#module.exit_json(msg=stdout, changed=False)
if rc != 0:
msg = 'Error - STDOUT: %s, STDERR: %s, COMMAND: %s' % (stdout, stderr, command)
module.fail_json(msg=msg, changed=False)
msg = 'Error - STDOUT: %s, STDERR: %s, COMMAND: %s' % (stdout, stderr, command)
module.fail_json(msg=msg, changed=False)
else:
if opatchauto:
chk = '%s' % (patch_version)
elif not opatchauto and patch_id is not None and patch_version is not None:
chk = '%s (%s)' % (patch_version,patch_id)
chk = r'%s \(%s\)' % (patch_version,patch_id)
else:
chk = '%s' % (patch_id)
chk = '^%s;' % (patch_id)

if chk in stdout:
return True
if re.search(chk, stdout, re.MULTILINE):
if exclude_upi is None:
return True
else:
command += ' -id %s' % patch_id
(rc, stdout, stderr) = module.run_command(command)
if rc != 0:
msg = 'Error - STDOUT: %s, STDERR: %s, COMMAND: %s' % (stdout, stderr, command)
module.fail_json(msg=msg, changed=False)
else:
chk = 'unique_patch_id:%s' % exclude_upi
return (chk not in stdout)
else:
return False

Expand Down Expand Up @@ -296,7 +315,7 @@ def stop_process(module, oracle_home):
elif len(line.split(':')) >= 2 and line.split(':')[1] == oracle_home:

# Find listener for ORACLE_HOME
p = subprocess.Popen('ps -o cmd -C tnslsnr | grep "^%s/bin/tnslsnr "' % (line) , shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p = subprocess.Popen('ps -o cmd -C tnslsnr | grep "^%s/bin/tnslsnr "' % (line.split(':')[1]) , shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = p.communicate()
p_status = p.wait()

Expand Down Expand Up @@ -341,7 +360,7 @@ def stop_process(module, oracle_home):
if msg:
module.fail_json(msg=msg, changed=False)

def remove_patch (module, msg, oracle_home, patch_base, patch_id, opatchauto, ocm_response_file,output):
def remove_patch (module, msg, oracle_home, patch_base, patch_id, opatchauto, ocm_response_file, stop_processes, output):
'''
Removes the patch
'''
Expand All @@ -354,6 +373,9 @@ def remove_patch (module, msg, oracle_home, patch_base, patch_id, opatchauto, oc

command = '%s/OPatch/%s %s -oh %s ' % (oracle_home,opatch_cmd, patch_base, oracle_home)
else:
if stop_processes:
stop_process(module, oracle_home)

opatch_cmd = 'opatch rollback'
command = '%s/OPatch/%s -id %s -silent' % (oracle_home,opatch_cmd, patch_id)

Expand Down Expand Up @@ -447,6 +469,7 @@ def main():
patch_base = dict(default=None, aliases = ['path','source','patch_source','phBaseDir']),
patch_id = dict(default=None, aliases = ['id']),
patch_version = dict(required=None, aliases = ['version']),
exclude_upi = dict(required=None, aliases = ['exclude_unique_patch_id']),
opatch_minversion = dict(default=None, aliases = ['opmv']),
opatchauto = dict(default='False', type='bool',aliases = ['autopatch']),
rolling = dict(default='True', type='bool',aliases = ['rolling']),
Expand All @@ -458,7 +481,7 @@ def main():
output = dict(default="short", choices = ["short","verbose"]),
state = dict(default="present", choices = ["present", "absent", "opatchversion"]),
hostname = dict(required=False, default = 'localhost', aliases = ['host']),
port = dict(required=False, default = 1521),
port = dict(required=False, type='int', default = 1521),



Expand All @@ -470,6 +493,7 @@ def main():
patch_base = module.params["patch_base"]
patch_id = module.params["patch_id"]
patch_version = module.params["patch_version"]
exclude_upi = module.params["exclude_upi"]
opatch_minversion = module.params["opatch_minversion"]
opatchauto = module.params["opatchauto"]
rolling = module.params["rolling"]
Expand Down Expand Up @@ -512,8 +536,12 @@ def main():


# Get the Oracle % Opatch version
major_version = get_version(module,msg,oracle_home)
opatch_version = get_opatch_version(module,msg,oracle_home)

if state == 'opatchversion':
module.exit_json(msg=opatch_version,changed=False)

major_version = get_version(module,msg,oracle_home)
opatch_version_noocm = '12.2.0.1.5'

if opatch_minversion is not None:
Expand All @@ -526,11 +554,8 @@ def main():
msg='An OCM response file is needed when the opatch version is < %s. Current opatch version: %s' % (opatch_version_noocm,opatch_version)
module.fail_json(msg=msg,changed=False)

if state == 'opatchversion':
module.exit_json(msg=opatch_version,changed=False)

if state == 'present':
if not check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatchauto):
if not check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatchauto, None):
if apply_patch(module, msg, oracle_home, patch_base, patch_id,patch_version, opatchauto,ocm_response_file,offline,stop_processes,rolling,output):
if patch_version is not None:
msg = 'Patch %s (%s) successfully applied to %s' % (patch_id,patch_version, oracle_home)
Expand All @@ -546,8 +571,8 @@ def main():
module.exit_json(msg=msg, changed=False)

elif state == 'absent':
if check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatchauto):
if remove_patch(module, msg, oracle_home, patch_base, patch_id, opatchauto,ocm_response_file, output):
if check_patch_applied(module, msg, oracle_home, patch_id, patch_version, opatchauto, exclude_upi):
if remove_patch(module, msg, oracle_home, patch_base, patch_id, opatchauto,ocm_response_file, stop_processes, output):
if patch_version is not None:
msg = 'Patch %s (%s) successfully removed from %s' % (patch_id,patch_version, oracle_home)
else:
Expand All @@ -557,8 +582,9 @@ def main():
module.fail_json(msg=msg, changed=False)
else:
if patch_version is not None:
msg = 'Patch %s (%s) is not applied to %s' % (patch_id,patch_version, oracle_home)

msg = 'Patch %s (%s) is not applied to %s' % (patch_id, patch_version, oracle_home)
elif exclude_upi is not None:
msg = 'Patch %s (UPI %s) has already been applied and will not be removed from %s' % (patch_id, exclude_upi, oracle_home)
else:
msg = 'Patch %s is not applied to %s' % (patch_id, oracle_home)

Expand Down
39 changes: 22 additions & 17 deletions oracle_parameter
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ else:
cx_oracle_exists = True


# Check if the parameter exists
def check_parameter_exists(module, mode, msg, cursor, name):
msg = ['']

# Check if the parameter exists
def check_parameter_exists(module, mode, cursor, name):
global msg

if not(name):
module.fail_json(msg='Error: Missing parameter name', changed=False)
Expand Down Expand Up @@ -115,7 +117,8 @@ def check_parameter_exists(module, mode, msg, cursor, name):



def modify_parameter(module, mode, msg, cursor, name, value, comment, scope, sid):
def modify_parameter(module, mode, cursor, name, value, comment, scope, sid):
global msg

contains = re.compile(r'[?*$%#()!\s,._/=+-]')
starters = ('+','_','"','"_','/')
Expand All @@ -126,7 +129,7 @@ def modify_parameter(module, mode, msg, cursor, name, value, comment, scope, sid



currval = get_curr_value(module, mode, msg, cursor, name, scope)
currval = get_curr_value(module, mode, cursor, name, scope)

if currval == value.lower() or not currval and value == "''":
module.exit_json(msg='The parameter (%s) is already set to %s' % (name, value), changed=False)
Expand Down Expand Up @@ -179,7 +182,8 @@ def clean_string(item):

return item

def reset_parameter(module, mode, msg, cursor, name, value, comment, scope, sid):
def reset_parameter(module, mode, cursor, name, value, comment, scope, sid):
global msg

starters = ('+','_','"','"_')
if not(name):
Expand Down Expand Up @@ -212,20 +216,21 @@ def reset_parameter(module, mode, msg, cursor, name, value, comment, scope, sid)
return True


def get_curr_value(module, mode, msg, cursor, name, scope):
def get_curr_value(module, mode, cursor, name, scope):
global msg

name = clean_string(name)

if scope == 'spfile':
parameter_source = 'v$spparameter'
else:
if scope == 'memory':
parameter_source = 'v$parameter'
else:
parameter_source = 'v$spparameter'

if mode == 'sysdba':
if scope == 'spfile':
sql = 'select lower(KSPSPFFTCTXSPDVALUE) from x$kspspfile where lower(KSPSPFFTCTXSPNAME) = lower(\'%s\')' % (name)
else:
if scope == 'memory':
sql = 'select lower(y.ksppstdvl) from sys.x$ksppi x, sys.x$ksppcv y where x.indx = y.indx and x.ksppinm = lower(\'%s\')' % (name)
else:
sql = 'select lower(KSPSPFFTCTXSPDVALUE) from x$kspspfile where lower(KSPSPFFTCTXSPNAME) = lower(\'%s\')' % (name)
else:
sql = 'select lower(display_value) from %s where name = lower(\'%s\')' % (parameter_source, name)

Expand All @@ -242,8 +247,8 @@ def get_curr_value(module, mode, msg, cursor, name, scope):


def main():
global msg

msg = ['']
module = AnsibleModule(
argument_spec = dict(
hostname = dict(default='localhost'),
Expand Down Expand Up @@ -312,17 +317,17 @@ def main():
cursor = conn.cursor()

if state == 'present':
if check_parameter_exists(module, mode, msg, cursor, name):
if modify_parameter(module, mode, msg, cursor, name, value, comment, scope, sid):
if check_parameter_exists(module, mode, cursor, name):
if modify_parameter(module, mode, cursor, name, value, comment, scope, sid):
module.exit_json(msg=msg, changed=True)
else:
module.fail_json(msg=msg, changed=False)
else:
module.fail_json(msg=msg, changed=False)

elif state == 'reset' or state == 'absent':
if check_parameter_exists(module, mode, msg, cursor, name):
if reset_parameter(module, mode, msg, cursor, name, value, comment, scope, sid):
if check_parameter_exists(module, mode, cursor, name):
if reset_parameter(module, mode, cursor, name, value, comment, scope, sid):
module.exit_json(msg=msg, changed=True)
else:
module.fail_json(msg=msg, changed=False)
Expand Down
Loading