Files
programming/ansible/swgalaxy/playbooks/ora_stand_patch_oh.yml
T

258 lines
8.7 KiB
YAML
Raw Normal View History

2026-06-28 12:00:23 +02:00
---
# Playbook: ora_stand_patch_oh.yml
# Usage example:
# ansible-playbook playbooks/ora_stand_patch_oh.yml \
# -e server=togoria \
# -e oracle_sid=NABOOPRD \
# -e opatch_zip=/mnt/yavin4/kit/Oracle/opatch/p6880880_190000_Linux-x86-64.zip \
# -e dbru_zip=/mnt/yavin4/kit/Oracle/Oracle_Database_19/patch/GIRU_19.29/p38298204_190000_Linux-x86-64.zip
- name: Gather facts for a specific inventory host
hosts: "{{ server }}"
gather_facts: yes
become: true
become_user: oracle
become_method: su
pre_tasks:
- name: Ensure 'server' variable is provided
assert:
that: server is defined
fail_msg: "Please provide the server via -e 'server=<server>'"
- name: Ensure 'oracle_sid' variable is provided
assert:
that: oracle_sid is defined
fail_msg: "Please provide the oracle_sid via -e 'oracle_sid=<oracle_sid>'"
- name: Ensure 'opatch_zip' variable is provided
assert:
that: opatch_zip is defined
fail_msg: "Please provide the opatch_zip via -e 'opatch_zip=<opatch_zip>'"
- name: Ensure 'dbru_zip' variable is provided
assert:
that: dbru_zip is defined
fail_msg: "Please provide the dbru_zip via -e 'dbru_zip=<dbru_zip>'"
tasks:
- name: Show selected system facts
debug:
msg:
hostname: "{{ (ansible_facts.nodename | default(ansible_facts.hostname)) | default('unknown') }}"
os_family: "{{ ansible_facts.os_family | default(ansible_facts.distribution | default('unknown')) }}"
operating_system: "{{ ansible_facts.distribution | default('unknown') }} {{ ansible_facts.distribution_version | default('') }}"
ip_address: "{{ ansible_default_ipv4.address | default('unknown') }}"
hardware_model: "{{ ansible_facts['machine'] | default('unknown') }}"
cpu_count: "{{ ansible_facts['processor_vcpus'] | default(ansible_facts['processor_count'] | default('unknown')) }}"
ram_gb: "{{ (ansible_facts['memtotal_mb'] / 1024) | int | default('unknown') }}"
- name: Source oraenv and display OPatch informations
shell: |
. oraenv <<< {{ oracle_sid }} && $ORACLE_HOME/OPatch/opatch version && echo && echo && $ORACLE_HOME/OPatch/opatch lspatches
register: opatch_output
when: oracle_sid is defined
- name: Display OPatch output
debug:
var: opatch_output.stdout_lines
when: oracle_sid is defined
- name: Check if any oracle processes are using ORACLE_HOME files
shell: |
. oraenv <<< {{ oracle_sid }} >/dev/null 2>&1
lsof +D "$ORACLE_HOME" 2>/dev/null | grep -v COMMAND | awk '{print $1}' | sort -u || true
args:
executable: /bin/bash
register: oracle_processes_using_oh
changed_when: false
failed_when: false
when: oracle_sid is defined
- name: List oracle processes using ORACLE_HOME files and fail if any found
fail:
msg: |
Found oracle user processes using files from $ORACLE_HOME.
Cannot proceed with patching while processes are active:
{{ oracle_processes_using_oh.stdout_lines }}
when:
- oracle_sid is defined
- oracle_processes_using_oh.stdout_lines | default([]) | length > 0
- name: Remove $ORACLE_HOME/OPatch directory
shell: |
. oraenv <<< {{ oracle_sid }}
if [ -d "$ORACLE_HOME/OPatch" ]; then
rm -rf "$ORACLE_HOME/OPatch"
echo removed
else
echo not_found
fi
args:
executable: /bin/bash
register: remove_opatch
changed_when: "'removed' in remove_opatch.stdout"
failed_when: false
when: oracle_sid is defined
- name: Show OPatch removal result
debug:
msg: "OPatch removal: {{ remove_opatch.stdout | default('no_output') }}"
when: oracle_sid is defined
- name: Copy OPatch zip to remote host
copy:
src: "{{ opatch_zip }}"
dest: "/tmp/{{ opatch_zip | basename }}"
mode: '0644'
when: opatch_zip is defined
- name: Extract OPatch zip into $ORACLE_HOME
shell: |
. oraenv <<< {{ oracle_sid }}
unzip -o "/tmp/{{ opatch_zip | basename }}" -d "$ORACLE_HOME"
args:
executable: /bin/bash
register: opatch_unzip
changed_when: opatch_unzip.rc == 0 and (opatch_unzip.stdout is defined)
failed_when: opatch_unzip.rc != 0
when: opatch_zip is defined
- name: Remove uploaded OPatch zip from remote
file:
path: "/tmp/{{ opatch_zip | basename }}"
state: absent
when: opatch_zip is defined
- name: Source oraenv and display OPatch informations
shell: |
. oraenv <<< {{ oracle_sid }} && $ORACLE_HOME/OPatch/opatch version && echo && echo && $ORACLE_HOME/OPatch/opatch lspatches
register: opatch_output
when: oracle_sid is defined
- name: Display OPatch output
debug:
var: opatch_output.stdout_lines
when: oracle_sid is defined
- name: Remove /app/oracle/staging_area if present
file:
path: /app/oracle/staging_area
state: absent
- name: Recreate /app/oracle/staging_area
file:
path: /app/oracle/staging_area
state: directory
mode: '0755'
- name: Check local dbru_zip path exists on controller (only if provided)
stat:
path: "{{ dbru_zip }}"
delegate_to: localhost
run_once: true
register: local_zip_stat
when: dbru_zip is defined
- name: Fail if local dbru_zip file not found on controller
fail:
msg: "Local zip file {{ dbru_zip }} not found on controller"
when: dbru_zip is defined and (local_zip_stat.stat is not defined or not local_zip_stat.stat.exists)
run_once: true
- name: Copy local dbru_zip to remote staging_area
copy:
src: "{{ dbru_zip }}"
dest: "/app/oracle/staging_area/{{ dbru_zip | basename }}"
mode: '0644'
when: dbru_zip is defined
- name: Unarchive uploaded zip into staging_area
unarchive:
src: "/app/oracle/staging_area/{{ dbru_zip | basename }}"
dest: /app/oracle/staging_area
remote_src: yes
when: dbru_zip is defined
- name: Remove uploaded zip from remote staging_area
file:
path: "/app/oracle/staging_area/{{ dbru_zip | basename }}"
state: absent
when: dbru_zip is defined
- name: Find extracted directories under staging_area
find:
paths: /app/oracle/staging_area
file_type: directory
depth: 1
register: staging_dirs
when: dbru_zip is defined
- name: Show staging directories found
debug:
var: staging_dirs.files
when: dbru_zip is defined
- name: Find all subdirectories inside extracted main dirs (depth=2)
shell: |
find /app/oracle/staging_area -mindepth 2 -maxdepth 2 -type d -not -name automation -print
args:
executable: /bin/bash
register: all_subdirs
changed_when: false
when: dbru_zip is defined
- name: Show all subdirectories to process
debug:
var: all_subdirs.stdout_lines
when: dbru_zip is defined and all_subdirs is defined
- name: Apply OPatch for each extracted subdirectory (clean chdir)
shell: |
. oraenv <<< {{ oracle_sid }}
export PATH=$PATH:$ORACLE_HOME/OPatch
if [ -x "$ORACLE_HOME/OPatch/opatch" ]; then
$ORACLE_HOME/OPatch/opatch apply -silent
else
echo "opatch_not_found"
exit 2
fi
args:
executable: /bin/bash
chdir: "{{ item }}"
loop: "{{ all_subdirs.stdout_lines | default([]) }}"
loop_control:
label: "{{ item }}"
register: opatch_apply_results
failed_when: false
changed_when: false
when: dbru_zip is defined and all_subdirs is defined and (all_subdirs.stdout_lines | length) > 0
- name: Show OPatch apply results (stdout lines)
debug:
var: opatch_apply_results.results | map(attribute='stdout_lines') | list
when: dbru_zip is defined and opatch_apply_results is defined
- name: Collect failed OPatch applies
set_fact:
failed_applies: "{{ opatch_apply_results.results | selectattr('rc','ne',0) | map(attribute='item') | list }}"
when: dbru_zip is defined and opatch_apply_results is defined
- name: Fail if any OPatch apply failed
fail:
msg: "OPatch apply failed in: {{ failed_applies }}"
when: dbru_zip is defined and failed_applies is defined and (failed_applies | length) > 0
- name: Remove /app/oracle/staging_area if present
file:
path: /app/oracle/staging_area
state: absent
- name: Recreate /app/oracle/staging_area
file:
path: /app/oracle/staging_area
state: directory
mode: '0755'