From dd4d208e887e5987cb190d4163fdfaa5e817d598 Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Wed, 22 Jan 2025 18:14:59 -0700 Subject: [PATCH 01/13] Changes to support 23c/23ai Free Edition and installation via RPM Toolkit required significant modification to support installing Oracle Database Free Edition. Summarized as: * Must support an RPM based installation (only option for installing Free Edition). * Must support installing the Oracle pre-installation RPM. * Must support installation in to /opt. * Some options and Grid Infrastructure (ASM) are not applicable/excluded. * Version can be specified or can default to the latest version (software must be staged in the swlib). Documentation is updated with additional details. --- check-swlib.sh | 16 +- config-db.yml | 13 +- docs/user-guide.md | 391 +++++++++++++++++- group_vars/all.yml | 2 +- install-oracle.sh | 28 +- install-sw.yml | 23 +- roles/check-swlib/tasks/main.yml | 10 +- roles/common/defaults/main.yml | 73 +++- .../templates/archivelog_mode.sh.j2 | 6 +- .../templates/rman_arch_backup.sh.j2 | 1 + .../templates/rman_full_backup.sh.j2 | 1 + roles/db-create/defaults/main.yml | 18 + roles/db-create/tasks/main.yml | 111 ++++- roles/lsnr-create/tasks/main.yml | 43 +- roles/ora-host/tasks/main.yml | 50 ++- roles/rdbms-setup/defaults/main.yml | 45 ++ roles/rdbms-setup/tasks/main.yml | 20 +- roles/rdbms-setup/tasks/rdbms-rpm-install.yml | 23 ++ roles/swlib/tasks/gcscopy.yml | 49 ++- 19 files changed, 862 insertions(+), 61 deletions(-) create mode 100644 roles/db-create/defaults/main.yml create mode 100644 roles/rdbms-setup/tasks/rdbms-rpm-install.yml diff --git a/check-swlib.sh b/check-swlib.sh index 19d1fadbe..f05047861 100755 --- a/check-swlib.sh +++ b/check-swlib.sh @@ -28,13 +28,13 @@ if [ $? != 4 ]; then fi ORA_VERSION="${ORA_VERSION:-19.3.0.0.0}" -ORA_VERSION_PARAM='^(19\.3\.0\.0\.0|18\.0\.0\.0\.0|12\.2\.0\.1\.0|12\.1\.0\.2\.0|11\.2\.0\.4\.0)$' +ORA_VERSION_PARAM='^(23\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,6}|19\.3\.0\.0\.0|18\.0\.0\.0\.0|12\.2\.0\.1\.0|12\.1\.0\.2\.0|11\.2\.0\.4\.0)$' ORA_RELEASE="${ORA_RELEASE:-latest}" ORA_RELEASE_PARAM="^(base|latest|[0-9]{,2}\.[0-9]{,2}\.[0-9]{,2}\.[0-9]{,2}\.[0-9]{,6})$" ORA_EDITION="${ORA_EDITION:-EE}" -ORA_EDITION_PARAM="^(EE|SE|SE2)$" +ORA_EDITION_PARAM="^(EE|SE|SE2|FREE)$" ORA_SWLIB_BUCKET="${ORA_SWLIB_BUCKET}" ORA_SWLIB_BUCKET_PARAM='^gs://.+[^/]$' @@ -62,6 +62,11 @@ while true; do ;; --ora-version) ORA_VERSION="$2" + if [[ "${ORA_VERSION}" = "23.6" ]] ; then ORA_VERSION="23.6.0.24.10"; fi + if [[ "${ORA_VERSION}" = "23.5" ]] ; then ORA_VERSION="23.5.0.24.07"; fi + if [[ "${ORA_VERSION}" = "23.4" ]] ; then ORA_VERSION="23.4.0.24.05"; fi + if [[ "${ORA_VERSION}" = "23.3" ]] ; then ORA_VERSION="23.3.0.23.09"; fi + if [[ "${ORA_VERSION}" = "23.2" ]] ; then ORA_VERSION="23.2.0.0.0"; fi if [[ "${ORA_VERSION}" = "19" ]] ; then ORA_VERSION="19.3.0.0.0"; fi if [[ "${ORA_VERSION}" = "18" ]] ; then ORA_VERSION="18.0.0.0.0"; fi if [[ "${ORA_VERSION}" = "12" ]] ; then ORA_VERSION="12.2.0.1.0"; fi @@ -113,6 +118,13 @@ done exit 1 } +# Oracle Database free edition parameter overrides +if [ "${ORA_EDITION}" = "FREE" ]; then + if [[ "${ORA_RELEASE}" == "latest" && ! "${ORA_VERSION}" =~ ^23\.[0-9]{1,2} ]]; then + ORA_VERSION="23.6.0.24.10" + fi +fi + # Mandatory options if [ "${ORA_SWLIB_BUCKET}" = "" ]; then echo "Please specify a GS bucket with --ora-swlib-bucket" diff --git a/config-db.yml b/config-db.yml index cbab41924..9ce703e38 100644 --- a/config-db.yml +++ b/config-db.yml @@ -36,7 +36,6 @@ - db-create - db-adjustements - db-backups - - validation-scripts loop_control: loop_var: role_item when: @@ -45,6 +44,16 @@ - lookup('env', 'PRIMARY_IP_ADDR') is not defined or lookup('env', 'PRIMARY_IP_ADDR') | length == 0 tags: primary-db + - include_role: + name: validation-scripts + tasks_from: main + when: + - create_db|bool + - cluster_type != "RAC" + - lookup('env', 'PRIMARY_IP_ADDR') is not defined or lookup('env', 'PRIMARY_IP_ADDR') | length == 0 + - oracle_edition != 'FREE' + tags: primary-db + - include_role: name: db-copy tasks_from: active-copy @@ -53,6 +62,7 @@ - cluster_type != "RAC" - lookup('env', 'PRIMARY_IP_ADDR') is defined - lookup('env', 'PRIMARY_IP_ADDR') | length > 0 + - oracle_edition != 'FREE' tags: active-duplicate - include_role: @@ -60,4 +70,5 @@ tasks_from: main when: - cluster_type == "DG" + - oracle_edition != 'FREE' tags: dg-create diff --git a/docs/user-guide.md b/docs/user-guide.md index 0486b0337..d1c447f5f 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -11,6 +11,7 @@ published: True - [Command quick reference for single instance deployments](#command-quick-reference-for-single-instance-deployments) - [Command quick reference for RAC deployments](#command-quick-reference-for-rac-deployments) - [Command quick reference for DR deployments](#command-quick-reference-for-dr-deployments) + - [Command quick reference for Oracle Database "Free Edition" deployments](#command-quick-reference-for-oracle-database-free-edition-deployments) - [Overview](#overview) - [Software Stack](#software-stack) - [Requirements and Prerequisites](#requirements-and-prerequisites) @@ -42,7 +43,11 @@ published: True - [RAC configuration parameters](#rac-configuration-parameters) - [Backup configuration parameters](#backup-configuration-parameters) - [Additional operational parameters](#additional-operational-parameters) - - [Example Toolkit Execution](#example-toolkit-execution) + - [Example Toolkit Execution](#example-toolkit-execution) + - [Oracle Database Free Edition Specific Details and Changes](#oracle-database-free-edition-specific-details-and-changes) + - [Free Edition Version Details](#free-edition-version-details) + - [Sample Invocations for Oracle Database Free Edition](#sample-invocations-for-oracle-database-free-edition) + - [Example Toolkit Execution for Free Edition](#example-toolkit-execution-for-free-edition) - [Post installation tasks](#post-installation-tasks) - [Reset passwords](#reset-passwords) - [Validate the environment](#validate-the-environment) @@ -156,6 +161,42 @@ To create a standby database, add the following options to the command options t --cluster-type DG ``` +## Command quick reference for Oracle Database "Free Edition" deployments + +The toolkit supports installing the Oracle Database Free edition, which is downloadable from the Oracle website: [Oracle Database Free Get Started](https://www.oracle.com/database/free/get-started/). + +Unlike with other Oracle Database editions, the Free edition is available in [RPM package](https://en.wikipedia.org/wiki/RPM_Package_Manager) format only. Consequently, the Enterprise Linux 8 pre-installation and database RPM files must be downloaded and staged in the GCS storage bucket. + +1. Validate media specifying GCS storage bucket and specify `FREE` as the database edition: + + ```bash + ./check-swlib.sh --ora-swlib-bucket gs://[cloud-storage-bucket-name] \ + --ora-edition FREE + ``` + +1. Validate access to target server (optionally include -i and location of + private key file): + + ```bash + ssh ${INSTANCE_SSH_USER:-`whoami`}@${INSTANCE_IP_ADDR} sudo -u root hostname + ``` + +1. Review toolkit parameters: + + ```bash + ./install-oracle.sh --help + ``` + +1. Run an installation: + + ```bash + ./install-oracle.sh \ + --ora-edition FREE \ + --ora-swlib-bucket gs://[cloud-storage-bucket-name] \ + --backup-dest [backup-directory] \ + --instance-ip-addr ${INSTANCE_IP_ADDR} + ``` + ## Overview The Implementation Toolkit for Oracle provides an automated (scripted) mechanism @@ -171,6 +212,8 @@ The toolkit defines default values for most options, so you can run the toolkit with only a few specifications. Your configuration options are listed later in this guide. +> **NOTE:** This toolkit does support installing the Oracle Database 23ai Free edition. For details on installing the free edition refer to the section [Oracle Database Free Edition Specific Details and Changes](#oracle-database-free-edition-specific-details-and-changes). + The toolkit supports the following major releases of Oracle Database and applies the most recent quarterly patches, also known as Oracle Release Updates or RUs: @@ -1272,7 +1315,8 @@ ORA_EDITION EE
SE, for 11.2.0.4.0 only
-SE2, for 12.1.0.2.0 and above +SE2, for 12.1.0.2.0 and above
+FREE, for Oracle Database Free SE or SE2 depending on the Oracle version chosen. @@ -2071,6 +2115,349 @@ $ ./install-oracle.sh --ora-version=7.3.4 --ora-swlib-bucket gs://oracle-softwar Incorrect parameter provided for ora-version: 7.3.4 ``` +## Oracle Database Free Edition Specific Details and Changes + +This toolkit supports the installation of the Oracle Database "Free Edition", availble for download from [Oracle Database Free Get Started](https://www.oracle.com/database/free/get-started/). + +However, Oracle Database "Free Edition" has a number of differences, including: + +1. Does not include Oracle Grid Infrastructure and consequently does not use ASM. +1. Does not support RAC or Data Guard (single-instance only). +1. Only one database/instance can be created per server. +1. Installs via RPM packages only. +1. Requires that the [Oracle Database Preinstallation RPM](https://docs.oracle.com/en/database/oracle/oracle-database/23/ladbi/about-the-oracle-preinstallation-rpm.html) be installed as it is a dependent package. +1. Has CPU, memory, and user-data storage limits – see [Oracle Database Free FAQ – Installation](https://www.oracle.com/database/free/faq/#installation) for details. + +Similar to with the other editions, creation of an initial database and implementation of RMAN based backups is possible through this toolkit for Oracle Database free edition. + +### Free Edition Version Details + +Oracle has released serveral versions of free edition, often **without chaning the RPM file name**. This toolkit can install _any_ free edition version. Which version is actually installed depends on the the actual RPM file in the software library, and possibly the command line switches. + +Specific supported versions of Oracle Database 23 free edition currently includes: + +| Product | Specific Version | Software RPM Filename | Preinstall RPM Filename | +| :-----: | :--------------: | :----------------------------------------------------- | :----------------------------------------------------- | +| 23ai | 23.6.0.24.10 | `oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm` | `oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm` | +| 23ai | 23.5.0.24.07 | `oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm` | `oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm` | +| 23ai | 23.4.0.24.05 | `oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm` | `oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm` | +| 23c | 23.3.0.23.09 | `oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm` | `oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm` | +| 23c | 23.2.0.0.0 | `oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm` | `oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm` | + +Even though the file names may be the same while the version changes, multiple files with the same name can be kept in the software library. Possibly by manually changing the file names (and then updating the `rdbms_software` variables in the YAML files accoridingly.) Or more simply, by placing the unique files with the same file name in different Google Cloud Storage bucket **folders** for uniquness. + +If the specific version desired is not specified via a command line switch (or corresponding environment variable) , the toolkit will default to the most recent version – currently version `23.6.0.24.10`. + +Otherwise, one of the following command line switches should be used to install a specific free edition version: + +```bash + --ora-version 23.6.0.24.10 + --ora-version 23.5.0.24.07 + --ora-version 23.4.0.24.05 + --ora-version 23.3.0.23.09 + --ora-version 23.2.0.0.0 +``` + +#### Free edition specific parameter changes + +When using this toolkit to install the free edition, serveral toolkits parameters becomes irrelevant, or are set to specific values – possibly overriding user provided values. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeParametersParameter ValuesNotes
Oracle edition

+ORA_EDITION
+--ora-edition
+

FREESpecify "FREE" to install the free edition.
Oracle version

+ORA_VERSION
+--ora-version
+

+23.6.0.24.10
+23.5.0.24.07
+23.4.0.24.05
+23.3.0.23.09
+23.2.0.0.0
Specific version to install.
+
+Defaults to the latest release.
Data disk group name

+ORA_DATA_DISKGROUP
+--ora-data-diskgroup
+

user defined file system locationMust be an existing Linux file system location – ASM disk groups are incompatible with the free edition.
Reco disk group name

+ORA_RECO_DISKGROUP
+--ora-reco-diskgroup
+

user defined file system locationMust be an existing Linux file system location – ASM disk groups are incompatible with the free edition.
PDB count

+ORA_PDB_COUNT
+--ora-pdb-count
+

user defined integer
+
1 (default)
If greater than 1, a numeric is appended to each PDB name.
+
+Maximum value for free edition is 16.
Database name

+ORA_DB_NAME
+--ora-db-name
+

FREE (default)Defaults to "FREE" when installing free edition.
+
+User-provided values are ignored.
Grid user role separation

+ORA_ROLE_SEPARATION
+--ora-role-separation
+

FALSE (default)Grid Infrastructure is not used with free edition and therefore role separation is irrelevant.
+
+User-provided values are ignored.
ASM disk management

+ORA_DISK_MGMT
+--ora-disk-mgmt
+

UDEV (default)ASMlib is incompatible with free edition.
+
+User-provided values are ignored.
Cluster type

+CLUSTER_TYPE
+--cluster-type
+

NONE (default)Only single instance databases are possible with free edition.
+
+User-provided values are ignored.
+ +Most other parameters are applicable – there usage described in the previous sections of this document. + +### Sample Invocations for Oracle Database Free Edition + +In the following sample invocations, the IP address of the target server is referenced as environment variable `INSTANCE_IP_ADDR`. + +Check that software is available: + +```bash +./check-swlib.sh --ora-swlib-bucket gs://oracle-software --ora-edition FREE +``` + +Validate parameters only: + +```bash +./install-oracle.sh \ + --ora-edition FREE \ + --ora-swlib-bucket gs://oracle-software \ + --backup-dest /u02/backups \ + --validate +``` + +Run the host (server) preparation steps only: + +```bash +./install-oracle.sh \ + --ora-edition FREE \ + --instance-ip-addr ${INSTANCE_IP_ADDR} \ + --ora-swlib-bucket gs://oracle-software \ + --prep-host +``` + +Run the software install steps only: + +```bash +./install-oracle.sh \ + --ora-edition FREE \ + --instance-ip-addr ${INSTANCE_IP_ADDR} \ + --ora-swlib-bucket gs://oracle-software \ + --install-sw +``` + +Run the database creation steps only: + +```bash +./install-oracle.sh \ + --ora-edition FREE \ + --instance-ip-addr ${INSTANCE_IP_ADDR} \ + --ora-swlib-bucket gs://oracle-software \ + --backup-dest /u02/backups \ + --config-db +``` + +Run the full toolkit end-to-end: + +```bash +./install-oracle.sh \ + --ora-edition FREE \ + --instance-ip-addr ${INSTANCE_IP_ADDR} \ + --ora-swlib-bucket gs://oracle-software \ + --backup-dest /opt/oracle/fast_recovery_area/FREE \ + --ora-pdb-count 2 \ + --ora-pdb-name-prefix FREEPDB +``` + +### Example Toolkit Execution for Free Edition + +In the following example, environment variables are used to specify the +following values: + +- The IP address of the target instance + +For all other parameters, command line provided values are used, or default values are accepted. + +Note: Unless you specify a hostname on the `INSTANCE_HOSTNAME` environment +variable or the `--instance-hostname` command line argument, the target hostname +defaults to the target IP address. + +```bash +$ export INSTANCE_IP_ADDR=10.2.83.197 +$ ./install-oracle.sh \ +> --ora-edition FREE \ +> --instance-ip-addr ${INSTANCE_IP_ADDR} \ +> --ora-swlib-bucket gs://oracle-software \ +> --backup-dest /opt/oracle/fast_recovery_area/FREE \ +> --ora-pdb-count 2 \ +> --ora-pdb-name-prefix FREEPDB + +Command used: +./install-oracle.sh --ora-edition FREE --instance-ip-addr 10.2.83.197 --ora-swlib-bucket gs://oracle-software --backup-dest /opt/oracle/fast_recovery_area/FREE --ora-pdb-count 2 --ora-pdb-name-prefix FREEPDB --allow-install-on-vm + + +Inventory file for this execution: ./inventory_files/inventory_10.2.83.197_FREE. + +Running with parameters from command line or environment variables: + +ANSIBLE_DISPLAY_SKIPPED_HOSTS=false +ANSIBLE_LOG_PATH=./logs/log_10.2.83.197_FREE_20250109_115429.log +ARCHIVE_BACKUP_MIN=30 +ARCHIVE_ONLINE_DAYS=7 +ARCHIVE_REDUNDANCY=2 +BACKUP_DEST=/opt/oracle/fast_recovery_area/FREE +BACKUP_LEVEL0_DAYS=0 +BACKUP_LEVEL1_DAYS=1-6 +BACKUP_LOG_LOCATION=/home/oracle/logs +BACKUP_REDUNDANCY=2 +BACKUP_SCRIPT_LOCATION=/home/oracle/scripts +BACKUP_START_HOUR=01 +BACKUP_START_MIN=00 +CLUSTER_CONFIG=cluster_config.json +CLUSTER_TYPE=NONE +INSTANCE_HOSTGROUP_NAME=dbasm +INSTANCE_HOSTNAME=10.2.83.197 +INSTANCE_IP_ADDR=10.2.83.197 +INSTANCE_SSH_EXTRA_ARGS=''\''-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentityAgent=no'\''' +INSTANCE_SSH_KEY='~/.ssh/id_rsa' +INSTANCE_SSH_USER=pane +ORA_ASM_DISKS=asm_disk_config.json +ORA_DATA_DISKGROUP=/u02/oradata +ORA_DATA_MOUNTS=data_mounts_config.json +ORA_DB_CHARSET=AL32UTF8 +ORA_DB_CONTAINER=TRUE +ORA_DB_DOMAIN= +ORA_DB_NAME=FREE +ORA_DB_NCHARSET=AL16UTF16 +ORA_DB_TYPE=MULTIPURPOSE +ORA_DISK_MGMT=UDEV +ORA_EDITION=FREE +ORA_LISTENER_NAME=LISTENER +ORA_LISTENER_PORT=1521 +ORA_PDB_COUNT=2 +ORA_PDB_NAME_PREFIX=FREEPDB +ORA_RECO_DISKGROUP=/opt/oracle/fast_recovery_area +ORA_REDO_LOG_SIZE=100MB +ORA_RELEASE=latest +ORA_ROLE_SEPARATION=FALSE +ORA_STAGING=/u01/swlib +ORA_SWLIB_BUCKET=gs://oracle-software +ORA_SWLIB_CREDENTIALS= +ORA_SWLIB_PATH=/u01/swlib +ORA_SWLIB_TYPE=GCS +ORA_VERSION=23.0.0.0.0 +PB_CHECK_INSTANCE=check-instance.yml +PB_CONFIG_DB=config-db.yml +PB_CONFIG_RAC_DB=config-rac-db.yml +PB_INSTALL_SW=install-sw.yml +PB_LIST='check-instance.yml prep-host.yml install-sw.yml config-db.yml' +PB_PREP_HOST=prep-host.yml +PRIMARY_IP_ADDR= + +Ansible params: +Found Ansible: ansible-playbook is /usr/bin/ansible-playbook + +Running Ansible playbook: ansible-playbook -i ./inventory_files/inventory_10.2.83.197_FREE -e allow_install_on_vm=true check-instance.yml + +PLAY [dbasm] ************************************************************************************************************************************************************************************************* + +TASK [Verify that Ansible on control node meets the version requirements] ************************************************************************************************************************************ +ok: [10.2.83.197] => { + "changed": false, + "msg": "Ansible version is 2.16.3, continuing" +} + +TASK [Confirm JSON parsing works] **************************************************************************************************************************************************************************** +ok: [10.2.83.197] => { + "changed": false, + "msg": "All assertions passed" +} + +TASK [Test connectivity to target instance via ping] ********************************************************************************************************************************************************* +ok: [10.2.83.197] + +TASK [Abort if ping module fails] **************************************************************************************************************************************************************************** +ok: [10.2.83.197] => { + "changed": false, + "msg": "The instance has an usable python installation, continuing" +} + +TASK [Collect facts from target] ***************************************************************************************************************************************************************************** +ok: [10.2.83.197] + +... output truncated for brevity +``` + ## Post installation tasks ### Reset passwords diff --git a/group_vars/all.yml b/group_vars/all.yml index f2ee74b06..4c9d3bf37 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -118,7 +118,7 @@ oracle_group: oinstall grid_user: "{% if role_separation|bool %}grid{% else %}{{ oracle_user }}{% endif %}" grid_group: asmadmin oracle_root: "/u01/app" -home_name: "dbhome_1" +home_name: "{% if oracle_edition != 'FREE' %}dbhome_1{% else %}dbhomeFree{% endif %}" oracle_sid: "{% if db_config_type == 'SI' %}{{ db_name }}{% else %}{{ db_name }}{{ instance_num }}{% endif %}" asm_sid: "{% if db_config_type == 'SI' %}+ASM{% else %}+ASM{{ instance_num }}{% endif %}" run_initial_bu: true diff --git a/install-oracle.sh b/install-oracle.sh index 0d4a38006..f2964f1f0 100755 --- a/install-oracle.sh +++ b/install-oracle.sh @@ -83,19 +83,19 @@ shopt -s nocasematch # Check if we're using the Mac stock getopt and fail if true out=`getopt -T` if [ $? != 4 ]; then - echo -e "Your getopt does not support long parametrs, possibly you're on a Mac, if so please install gnu-getopt with brew" + echo -e "Your getopt does not support long parameters, possibly you're on a Mac, if so please install gnu-getopt with brew" echo -e "\thttps://brewformulas.org/Gnu-getopt" exit fi ORA_VERSION="${ORA_VERSION:-19.3.0.0.0}" -ORA_VERSION_PARAM='^(19\.3\.0\.0\.0|18\.0\.0\.0\.0|12\.2\.0\.1\.0|12\.1\.0\.2\.0|11\.2\.0\.4\.0)$' +ORA_VERSION_PARAM='^(23\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,6}|19\.3\.0\.0\.0|18\.0\.0\.0\.0|12\.2\.0\.1\.0|12\.1\.0\.2\.0|11\.2\.0\.4\.0)$' ORA_RELEASE="${ORA_RELEASE:-latest}" ORA_RELEASE_PARAM="^(base|latest|[0-9]{,2}\.[0-9]{,2}\.[0-9]{,2}\.[0-9]{,2}\.[0-9]{,6})$" ORA_EDITION="${ORA_EDITION:-EE}" -ORA_EDITION_PARAM="^(EE|SE|SE2)$" +ORA_EDITION_PARAM="^(EE|SE|SE2|FREE)$" CLUSTER_TYPE="${CLUSTER_TYPE:-NONE}" CLUSTER_TYPE_PARAM="NONE|RAC|DG" @@ -259,6 +259,11 @@ while true; do case "$1" in --ora-version) ORA_VERSION="$2" + if [[ "${ORA_VERSION}" = "23.6" ]] ; then ORA_VERSION="23.6.0.24.10"; fi + if [[ "${ORA_VERSION}" = "23.5" ]] ; then ORA_VERSION="23.5.0.24.07"; fi + if [[ "${ORA_VERSION}" = "23.4" ]] ; then ORA_VERSION="23.4.0.24.05"; fi + if [[ "${ORA_VERSION}" = "23.3" ]] ; then ORA_VERSION="23.3.0.23.09"; fi + if [[ "${ORA_VERSION}" = "23.2" ]] ; then ORA_VERSION="23.2.0.0.0"; fi if [[ "${ORA_VERSION}" = "19" ]] ; then ORA_VERSION="19.3.0.0.0"; fi if [[ "${ORA_VERSION}" = "18" ]] ; then ORA_VERSION="18.0.0.0.0"; fi if [[ "${ORA_VERSION}" = "12" ]] ; then ORA_VERSION="12.2.0.1.0"; fi @@ -700,6 +705,23 @@ shopt -s nocasematch exit 1 } +# Oracle Database free edition parameter overrides +if [ "${ORA_EDITION}" = "FREE" ]; then + CLUSTER_TYPE=NONE + ORA_DB_NAME=FREE + ORA_DISK_MGMT=UDEV + ORA_ROLE_SEPARATION=FALSE + if [[ "${ORA_RELEASE}" == "latest" && ! "${ORA_VERSION}" =~ ^23\.[0-9]{1,2} ]]; then + ORA_VERSION="23.6.0.24.10" + fi + [[ ! "${ORA_DATA_DISKGROUP}" =~ ^(/([^/]+))*/?$ ]] && ORA_DATA_DISKGROUP="/u02/oradata" || true + [[ ! "${ORA_RECO_DISKGROUP}" =~ ^(/([^/]+))*/?$ ]] && ORA_RECO_DISKGROUP="/opt/oracle/fast_recovery_area" || true + if (( ORA_PDB_COUNT > 16 )); then + echo "WARNING: Maximum number of PDBs for this edition is 16: Reducing from ${ORA_PDB_COUNT} to 16" + ORA_PDB_COUNT=16 + fi +fi + if [[ "${skip_compatible_rdbms}" != "true" ]]; then # # compatible-rdbms cannot be > ORA-VERSION diff --git a/install-sw.yml b/install-sw.yml index e2e871793..0ce095ead 100644 --- a/install-sw.yml +++ b/install-sw.yml @@ -35,6 +35,7 @@ when: - install_gi|bool - cluster_type in ("NONE", "DG") + - oracle_edition != 'FREE' tags: gi-setup - hosts: dbasm @@ -54,17 +55,19 @@ - cluster_type in ("NONE", "DG") tags: rdbms-setup - - hosts: dbasm tasks: - name: rac-gi-install | defaults from common include_vars: dir: roles/common/defaults + when: + - oracle_edition != 'FREE' - name: rac-gi-install | open firewall include_role: name: rac-lsnr-firewall when: - cluster_type == "RAC" + - oracle_edition != 'FREE' tags: lsnr-firewall - hosts: dbasm @@ -73,6 +76,8 @@ - name: rac-gi-install | defaults from common include_vars: dir: roles/common/defaults + when: + - oracle_edition != 'FREE' - name: rac-gi-install | setup ssh keys include_role: name: ssh-setup @@ -82,6 +87,7 @@ ssh_nodes: "{{ groups['dbasm'] }}" when: - cluster_type == "RAC" + - oracle_edition != 'FREE' tags: rac-gi,ssh-keys - hosts: dbasm[0] @@ -92,19 +98,22 @@ - name: rac-gi-install | defaults from common include_vars: dir: roles/common/defaults + when: + - oracle_edition != 'FREE' - name: rac-gi-install | GI installation include_role: name: rac-gi-setup - #if 11.2 or 12.1 then rac-gi-install-.yml otherwise rac-gi-install.yml + #if 11.2 or 12.1 then rac-gi-install-.yml otherwise rac-gi-install.yml tasks_from: rac-gi-install{% if oracle_ver_base in ('11.2','12.1') %}-{{ oracle_ver }}{% endif %}.yml - #tasks_from: rac-gi-install.yml + #tasks_from: rac-gi-install.yml public: yes loop: - - "{{ gi_software | json_query('[?version==`' + oracle_ver + '`].files[*]') | join() }}" + - "{{ gi_software | default([]) | json_query('[?version==`' + oracle_ver + '`].files[*]') | join() }}" loop_control: loop_var: osw_files when: - cluster_type == "RAC" + - oracle_edition != 'FREE' tags: rac-gi - hosts: dbasm @@ -122,6 +131,7 @@ ssh_nodes: "{{ groups['dbasm'] }}" when: - cluster_type == "RAC" + - oracle_edition != 'FREE' tags: rac-db,ssh-keys - hosts: dbasm[0] @@ -144,6 +154,7 @@ loop_var: osw_files when: - cluster_type == "RAC" + - oracle_edition != 'FREE' tags: rac-db - hosts: dbasm @@ -151,4 +162,6 @@ - include_role: name: patch-vulns tasks_from: main - tags: patch-vulns \ No newline at end of file + when: + - oracle_edition != 'FREE' + tags: patch-vulns diff --git a/roles/check-swlib/tasks/main.yml b/roles/check-swlib/tasks/main.yml index 12f7ffb6d..ba68668cc 100644 --- a/roles/check-swlib/tasks/main.yml +++ b/roles/check-swlib/tasks/main.yml @@ -45,7 +45,10 @@ with_items: - "{{ gi_patches }}" - "{{ rdbms_patches }}" - when: item.base == oracle_ver and item.release == oracle_rel + when: + - item.base == oracle_ver + - item.release == oracle_rel + - oracle_edition != 'FREE' register: patch_repo_files # We can't reliably check hashes for opatch, as the same file name @@ -62,7 +65,10 @@ ignore_errors: true with_items: - "{{ opatch_patches }}" - when: item.release == oracle_ver and oracle_rel != "base" + when: + - item.release == oracle_ver + - oracle_rel != "base" + - oracle_edition != 'FREE' register: opatch_repo_files - name: check-swlib | Report gsutil failures (base) diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 4763f3201..ede4e7c6a 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -15,10 +15,10 @@ --- # Variables used by more than one role -oracle_ver_dir: "{{ oracle_ver [:6] }}" +oracle_ver_dir: "{% if oracle_edition != 'FREE' %}{{ oracle_ver [:6] }}{% else %}{% if oracle_ver[:4] == '23.2' or oracle_ver[:4] == '23.3' %}23c{% else %}{{ oracle_ver[:2] }}ai{% endif %}{% endif %}" oracle_inventory: "{{ oracle_root }}/oraInventory" -oracle_base: "{{ oracle_root }}/oracle" -oracle_home: "{{ oracle_root }}/oracle/product/{{ oracle_ver_dir }}/{{ home_name }}" +oracle_base: "{% if oracle_edition != 'FREE' %}{{ oracle_root }}/oracle{% else %}/opt/oracle{% endif %}" +oracle_home: "{{ oracle_base }}/product/{{ oracle_ver_dir }}/{{ home_name }}" grid_home: "{{ oracle_root }}/{{ oracle_ver_dir }}/grid" grid_base: "{{ oracle_root }}/grid" @@ -69,6 +69,8 @@ oracle_dirs: - { name: "{{ oracle_inventory }}", owner: "{{ grid_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } - { name: "{{ oracle_home }}", owner: "{{ oracle_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } - { name: "/home/{{ oracle_user }}/.ansible/tmp", owner: "{{ oracle_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } + +grid_dirs: - { name: "{{ grid_home }}", owner: "{{ grid_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } - { name: "/home/{{ grid_user }}/.ansible/tmp", owner: "{{ grid_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } @@ -152,6 +154,71 @@ gi_software: - "BM7zeZHbGPgZD31KGbJpEg==" rdbms_software: + - name: 23aiFREE_23_6 + version: 23.6.0.24.10 + edition: FREE + files: + - "oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm" + - "oracle-database-free-23ai-1.0-1.el8.x86_64.rpm" + sha256sum: + - "4578e6d1cf566e04541e0216b07a0372725726a7c339423ee560255cb918138b" + - "03ae958784e9443c0380e4d387cb0522016c72d029ab85cf55ee124489833e0e" + md5sum: + - "TmjqUT878Owv7NbXGECpTA==" + - "Y70TVN1a7dV6TnNOeN1pYA==" + + - name: 23aiFREE_23_5 + version: 23.5.0.24.07 + edition: FREE + files: + - "oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm" + - "oracle-database-free-23ai-1.0-1.el8.x86_64.version_23_5.rpm" + sha256sum: + - "4578e6d1cf566e04541e0216b07a0372725726a7c339423ee560255cb918138b" + - "80c1ceae3b158cffe71fa4cfa8e4f540161659f79f777bcf48935f79031c054c" + md5sum: + - "TmjqUT878Owv7NbXGECpTA==" + - "cWcZFOhqt4Bnwt4rft6wpw==" + + - name: 23aiFREE_23_4 + version: 23.4.0.24.05 + edition: FREE + files: + - "oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm" + - "oracle-database-free-23ai-1.0-1.el8.x86_64.version_23_4.rpm" + sha256sum: + - "4578e6d1cf566e04541e0216b07a0372725726a7c339423ee560255cb918138b" + - "e6cccec7f101325c233f374c2aa86f77d62123edd3125450d79404c3eec30b65" + md5sum: + - "TmjqUT878Owv7NbXGECpTA==" + - "nZiDvGPHVa8iDkR110gB8A==" + + - name: 23cFREE_23_3 + version: 23.3.0.23.09 + edition: FREE + files: + - "oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm" + - "oracle-database-free-23c-1.0-1.el8.x86_64.version_23_3.rpm" + sha256sum: + - "f41059c22a610a2180cc6286179a7da148bfe14b0d88211f006c9998ce03ba0e" + - "1319bcd7cb706cb727501cbd98abf3f3980a4fdabeb613a1abffc756925c7374" + md5sum: + - "lVoplyvF66eUXign+DuZ8Q==" + - "k+q8twMOziARmih9mF79ow==" + + - name: 23cFREE_23_2 + version: 23.2.0.0.0 + edition: FREE + files: + - "oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm" + - "oracle-database-free-23c-1.0-1.el8.x86_64.version_23_2.rpm" + sha256sum: + - "f41059c22a610a2180cc6286179a7da148bfe14b0d88211f006c9998ce03ba0e" + - "63b6c0ec9464682cfd9814e7e2a5d533139e5c6aeb9d3e7997a5f976d6677ca6" + md5sum: + - "lVoplyvF66eUXign+DuZ8Q==" + - "RRinLLsJM2hpuFcE+3zURA==" + - name: 19c_base version: 19.3.0.0.0 edition: diff --git a/roles/db-adjustements/templates/archivelog_mode.sh.j2 b/roles/db-adjustements/templates/archivelog_mode.sh.j2 index cf97c06ad..219025017 100644 --- a/roles/db-adjustements/templates/archivelog_mode.sh.j2 +++ b/roles/db-adjustements/templates/archivelog_mode.sh.j2 @@ -1,8 +1,12 @@ source oraenv <<< {{ oracle_sid }} +{% if groups['dbasm'] | length > 1 %} srvctl stop db -d {{ db_name }} -o immediate +{% else %} +echo "shutdown immediate" | sqlplus -s -L / as sysdba +{% endif %} -sqlplus -s / as sysdba << EOF +sqlplus -s -L / as sysdba << EOF startup mount alter database archivelog; alter database open; diff --git a/roles/db-backups/templates/rman_arch_backup.sh.j2 b/roles/db-backups/templates/rman_arch_backup.sh.j2 index 3cd276cdf..e22e6fde8 100644 --- a/roles/db-backups/templates/rman_arch_backup.sh.j2 +++ b/roles/db-backups/templates/rman_arch_backup.sh.j2 @@ -45,6 +45,7 @@ if [[ $backup_dest == "/"* ]]; then # Filesystem destination autobackup_format="${backup_dest}/${ora_inst_name}_%F" channel_format="${backup_dest}/${ora_inst_name}_${type}_level_${rman_level}_%U" + reco_diskgroup="${reco_diskgroup#+}" else # ASM destination; no need for format specifiers autobackup_format="${backup_dest}" diff --git a/roles/db-backups/templates/rman_full_backup.sh.j2 b/roles/db-backups/templates/rman_full_backup.sh.j2 index 09eda5371..de0978e69 100644 --- a/roles/db-backups/templates/rman_full_backup.sh.j2 +++ b/roles/db-backups/templates/rman_full_backup.sh.j2 @@ -40,6 +40,7 @@ if [[ $backup_dest == "/"* ]]; then # Filesystem destination autobackup_format="${backup_dest}/${ora_inst_name}_%F" channel_format="${backup_dest}/${ora_inst_name}_${type}_level_${rman_level}_%U" + reco_diskgroup="${reco_diskgroup#+}" else # ASM destination; no need for format specifiers autobackup_format="${backup_dest}" diff --git a/roles/db-create/defaults/main.yml b/roles/db-create/defaults/main.yml new file mode 100644 index 000000000..91e9bd015 --- /dev/null +++ b/roles/db-create/defaults/main.yml @@ -0,0 +1,18 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- + +recovery_area_size: 16384 +systemd_service_name: "{% if oracle_edition == 'FREE' %}{% if oracle_ver[:4] == '23.2' or oracle_ver[:4] == '23.3' %}oracle-free-23c.service{% else %}oracle-free-{{ oracle_ver[:2] }}ai.service{% endif %}{% endif %}" diff --git a/roles/db-create/tasks/main.yml b/roles/db-create/tasks/main.yml index 3f11c63a3..08af20e07 100644 --- a/roles/db-create/tasks/main.yml +++ b/roles/db-create/tasks/main.yml @@ -56,7 +56,10 @@ dest: "{{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp.sh" owner: "{{ oracle_user }}" group: "{{ oracle_group }}" - when: pmon_proc.stdout == "0" and check_oratab.stdout == "0" + when: + - pmon_proc.stdout == "0" + - check_oratab.stdout == "0" + - oracle_edition != 'FREE' tags: db-create - name: Run DBCA response file script @@ -64,7 +67,10 @@ become_user: "{{ oracle_user }}" command: "sh {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp.sh" register: rspout - when: pmon_proc.stdout == "0" and check_oratab.stdout == "0" + when: + - pmon_proc.stdout == "0" + - check_oratab.stdout == "0" + - oracle_edition != 'FREE' tags: db-create - name: Script cleanup @@ -73,13 +79,18 @@ file: path: "{{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp.sh" state: absent + when: + - oracle_edition != 'FREE' tags: db-create - name: DBCA response file differences to template debug: msg: "{{ rspout.stdout_lines }}" verbosity: 1 - when: pmon_proc.stdout == "0" and check_oratab.stdout == "0" + when: + - pmon_proc.stdout == "0" + - check_oratab.stdout == "0" + - oracle_edition != 'FREE' tags: db-create - name: Copy to instance the pwgen.sh script @@ -88,11 +99,15 @@ dest: "{{ pwgen_path }}/{{ pwgen_file }}" owner: root mode: u=rwx,go=rx + when: + - oracle_edition != 'FREE' - name: Generate command for password randomization (not 11.2) set_fact: pwd_gen_cmd: echo -e "$({{ pass_param }})\n$({{ pass_param }})\n$({{ pass_param }})" - when: oracle_ver != "11.2.0.4.0" + when: + - oracle_ver != "11.2.0.4.0" + - oracle_edition != 'FREE' tags: db-create - name: Generate command for password randomization (11.2 only) @@ -103,17 +118,60 @@ - name: Create database using DBCA block: - - name: Run DBCA - become: yes - become_user: "{{ oracle_user }}" - shell: | - set -o pipefail - export PATH={{ oracle_home }}/bin:${PATH} - {{ pwd_gen_cmd }} | dbca -silent -createDatabase -redoLogFileSize {{ redologsize }} -responseFile {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp - register: dbca_output - failed_when: "'Completing Database Creation' not in dbca_output.stdout or '100% complete' not in dbca_output.stdout" - when: pmon_proc.stdout == "0" and check_oratab.stdout == "0" - tags: db-create + - name: Run DBCA using response file + become: yes + become_user: "{{ oracle_user }}" + shell: | + set -o pipefail + export PATH={{ oracle_home }}/bin:${PATH} + {{ pwd_gen_cmd }} | dbca -silent -createDatabase -redoLogFileSize {{ redologsize }} -responseFile {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp + register: dbca_output + failed_when: "'Completing Database Creation' not in dbca_output.stdout or '100% complete' not in dbca_output.stdout" + when: + - pmon_proc.stdout == "0" + - check_oratab.stdout == "0" + - oracle_edition != 'FREE' + tags: db-create + - name: Run DBCA with command line arguments + become: yes + become_user: "{{ oracle_user }}" + shell: | + set -o pipefail + export PATH={{ oracle_home }}/bin:${PATH} + dbca -silent \ + -createDatabase \ + -sid {{ oracle_sid }} \ + -gdbName {{ db_name }}.{{ db_domain }} \ + -templateName FREE_Database.dbc \ + -characterSet {{ charset }} \ + -nationalCharacterSet {{ ncharset }} \ + -createAsContainerDatabase TRUE \ + -numberOfPDBs {{ pdb_count }} \ + -pdbName {{ pdb_prefix }} \ + -pdbAdminPassword $(tr -dc A-Za-z + {{ oracle_dirs + grid_dirs if oracle_edition != 'FREE' + else oracle_dirs + + [ + {'name': data_diskgroup, 'owner': oracle_user, 'group': oracle_group, 'mode': 'u=rwx,g=rx,o='}, + {'name': reco_diskgroup, 'owner': oracle_user, 'group': oracle_group, 'mode': 'u=rwx,g=rx,o='} + ] + }} tags: os-dirs - name: Create backup directory @@ -258,7 +263,8 @@ - name: Check ASM backup destination set_fact: dg_exists: "{{ asm_disks | json_query('[?diskgroup==`' + backup_dest[1:] + '`].diskgroup') }}" - when: backup_dest[0:1] == "+" + when: + - backup_dest[0:1] == "+" tags: backup-dest - name: Fail if ASM backup diskgroup not defined @@ -307,12 +313,16 @@ dest: "/home/{{ grid_user }}/.bash_profile" marker: "# {mark} Oracle Grid Infrastructure Settings:" backup: yes - when: role_separation|bool + when: + - role_separation|bool + - oracle_edition != 'FREE' tags: os-users - name: (asmlib) | ASM device managment via asmlib or udev? debug: msg: "asm_disk_management is set to {{ asm_disk_management }}" + when: + - oracle_edition != 'FREE' tags: asm-disks - name: Partition all ASM raw disks @@ -321,7 +331,9 @@ number: 1 state: present label: gpt - when: "'mapper' not in item.1.blk_device" + when: + - "'mapper' not in item.1.blk_device" + - oracle_edition != 'FREE' run_once: true with_subelements: - "{{ asm_disks }}" @@ -331,6 +343,8 @@ - include_role: name: common tasks_from: populate-asm-disks.yml + when: + - oracle_edition != 'FREE' - name: (debug) asm disk configuration debug: @@ -338,6 +352,8 @@ - asm_disks {{ asm_disks }} - asm_def_file {{ asm_definition_file }} - asm_disk_input {{ asm_disk_input }} + when: + - oracle_edition != 'FREE' tags: asm-disks ######## Udev rules for non-multipath disks ######## @@ -350,6 +366,7 @@ when: - asm_disk_management == "udev" - "'mapper' not in item.1.blk_device" + - oracle_edition != 'FREE' with_subelements: - "{{ asm_disks }}" - disks @@ -360,6 +377,7 @@ uuid_result_nonmultipath: [] when: - udevadm_result_nonmultipath.results.0.stdout is defined + - oracle_edition != 'FREE' tags: udev-mpath - name: (udev) Add ASM non-multipath disk rules (filling dict) @@ -367,6 +385,7 @@ uuid_result_nonmultipath: "{{ uuid_result_nonmultipath | combine({item.stdout: item.item}) }}" when: - udevadm_result_nonmultipath.results.0.stdout is defined + - oracle_edition != 'FREE' with_items: - "{{ udevadm_result_nonmultipath.results }}" tags: udev-mpath @@ -382,6 +401,7 @@ register: udevRules_nonmultipath when: - uuid_result_nonmultipath is defined + - oracle_edition != 'FREE' with_dict: - "{{ uuid_result_nonmultipath }}" tags: udev-mpath @@ -395,6 +415,7 @@ register: udevadm_result when: - "'mapper' in item.1.blk_device" + - oracle_edition != 'FREE' with_subelements: - "{{ asm_disks }}" - disks @@ -405,6 +426,7 @@ uuid_result: [] when: - udevadm_result.results.0.stdout is defined + - oracle_edition != 'FREE' tags: udev-mpath - name: (udev) Add ASM mpath disk rules on BM (filling dict) @@ -412,6 +434,7 @@ uuid_result: "{{ uuid_result | combine({item.stdout: item.item}) }}" when: - udevadm_result.results.0.stdout is defined + - oracle_edition != 'FREE' with_items: - "{{ udevadm_result.results }}" tags: udev-mpath @@ -427,6 +450,7 @@ register: udevRules when: - uuid_result is defined + - oracle_edition != 'FREE' with_dict: - "{{ uuid_result }}" tags: udev-mpath @@ -435,6 +459,8 @@ become: yes become_user: root shell: ( /sbin/udevadm control --reload-rules && /sbin/udevadm trigger && /sbin/partprobe ) + when: + - oracle_edition != 'FREE' tags: asm-disks - name: (asmlib) Install Oracle ASM libraries diff --git a/roles/rdbms-setup/defaults/main.yml b/roles/rdbms-setup/defaults/main.yml index b65fdffa9..7bb31768a 100644 --- a/roles/rdbms-setup/defaults/main.yml +++ b/roles/rdbms-setup/defaults/main.yml @@ -14,6 +14,51 @@ --- rdbms_software: + - name: 23aiFREE_23_6 + version: 23.6.0.24.10 + edition: FREE + files: + - "oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm" + - "oracle-database-free-23ai-1.0-1.el8.x86_64.rpm" + sha256sum: + - "4578e6d1cf566e04541e0216b07a0372725726a7c339423ee560255cb918138b" + - "03ae958784e9443c0380e4d387cb0522016c72d029ab85cf55ee124489833e0e" + - name: 23aiFREE_23_5 + version: 23.5.0.24.07 + edition: FREE + files: + - "oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm" + - "oracle-database-free-23ai-1.0-1.el8.x86_64.version_23_5.rpm" + sha256sum: + - "4578e6d1cf566e04541e0216b07a0372725726a7c339423ee560255cb918138b" + - "80c1ceae3b158cffe71fa4cfa8e4f540161659f79f777bcf48935f79031c054c" + - name: 23aiFREE_23_4 + version: 23.4.0.24.05 + edition: FREE + files: + - "oracle-database-preinstall-23ai-1.0-2.el8.x86_64.rpm" + - "oracle-database-free-23ai-1.0-1.el8.x86_64.version_23_4.rpm" + sha256sum: + - "4578e6d1cf566e04541e0216b07a0372725726a7c339423ee560255cb918138b" + - "e6cccec7f101325c233f374c2aa86f77d62123edd3125450d79404c3eec30b65" + - name: 23cFREE_23_3 + version: 23.3.0.23.09 + edition: FREE + files: + - "oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm" + - "oracle-database-free-23c-1.0-1.el8.x86_64.version_23_3.rpm" + sha256sum: + - "f41059c22a610a2180cc6286179a7da148bfe14b0d88211f006c9998ce03ba0e" + - "1319bcd7cb706cb727501cbd98abf3f3980a4fdabeb613a1abffc756925c7374" + - name: 23cFREE_23_2 + version: 23.2.0.0.0 + edition: FREE + files: + - "oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm" + - "oracle-database-free-23c-1.0-1.el8.x86_64.version_23_2.rpm" + sha256sum: + - "f41059c22a610a2180cc6286179a7da148bfe14b0d88211f006c9998ce03ba0e" + - "63b6c0ec9464682cfd9814e7e2a5d533139e5c6aeb9d3e7997a5f976d6677ca6" - name: 19c_base version: 19.3.0.0.0 edition: diff --git a/roles/rdbms-setup/tasks/main.yml b/roles/rdbms-setup/tasks/main.yml index 336097752..5663fa8ed 100644 --- a/roles/rdbms-setup/tasks/main.yml +++ b/roles/rdbms-setup/tasks/main.yml @@ -37,7 +37,7 @@ group: "{{ item.group }}" mode: "{{ item.mode }}" when: home_name in item.name - with_items: "{{ oracle_dirs }}" + with_items: "{{ oracle_dirs + grid_dirs }}" tags: rdbms-setup,os-dirs - include_tasks: rdbms-install.yml @@ -45,7 +45,23 @@ - "{{ rdbms_software }}" loop_control: loop_var: osw - when: existing_dbhome.stdout == "0" and osw.version == oracle_ver and oracle_edition in osw.edition + when: + - existing_dbhome.stdout == "0" + - osw.version == oracle_ver + - oracle_edition in osw.edition + - oracle_edition != 'FREE' + tags: rdbms-setup + +- include_tasks: rdbms-rpm-install.yml + with_items: + - "{{ rdbms_software }}" + loop_control: + loop_var: osw + when: + - existing_dbhome.stdout == "0" + - osw.version == oracle_ver + - oracle_edition in osw.edition + - oracle_edition == 'FREE' tags: rdbms-setup - name: Create sqlnet.ora file diff --git a/roles/rdbms-setup/tasks/rdbms-rpm-install.yml b/roles/rdbms-setup/tasks/rdbms-rpm-install.yml new file mode 100644 index 000000000..64f543dc6 --- /dev/null +++ b/roles/rdbms-setup/tasks/rdbms-rpm-install.yml @@ -0,0 +1,23 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +- name: Install Oracle RPM + dnf: + name: "{{ swlib_path }}/{{ item }}" + state: present + disable_gpg_check: true + with_items: "{{ osw.files }}" + register: rpm_install + tags: rdbms-setup diff --git a/roles/swlib/tasks/gcscopy.yml b/roles/swlib/tasks/gcscopy.yml index 22cad90d3..c7369fd8e 100644 --- a/roles/swlib/tasks/gcscopy.yml +++ b/roles/swlib/tasks/gcscopy.yml @@ -23,14 +23,17 @@ gsutil cat gs://{{ swlib_mount_src }}/{{ i }} | ssh -i {{ ansible_ssh_private_key_file }} {{ ansible_ssh_extra_args }} \ {{ ansible_ssh_user }}@{{ ansible_ssh_host }} "cat > {{ swlib_path }}/{{ i }}" fi - {% endfor %} + {% endfor %} register: shell_result args: executable: /bin/bash with_items: - "{{ gi_software }}" - "{{ gi_interim_patches }}" - when: item.version == oracle_ver and patch_only is not defined + when: + - item.version == oracle_ver + - patch_only is not defined + - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -48,7 +51,9 @@ executable: /bin/bash with_items: - "{{ gi_patches }}" - when: item.release == oracle_rel + when: + - item.release == oracle_rel + - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -65,7 +70,10 @@ executable: /bin/bash with_items: - "{{ opatch_patches }}" - when: item.release == oracle_ver and oracle_rel != "base" + when: + - item.release == oracle_ver + - oracle_rel != "base" + - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -79,13 +87,16 @@ gsutil cat gs://{{ swlib_mount_src }}/{{ i }} | ssh -i {{ ansible_ssh_private_key_file }} {{ ansible_ssh_extra_args }} \ {{ ansible_ssh_user }}@{{ ansible_ssh_host }} "cat > {{ swlib_path }}/{{ i }}" fi - {% endfor %} + {% endfor %} register: shell_result args: executable: /bin/bash with_items: - "{{ rdbms_software }}" - when: item.version == oracle_ver and patch_only is not defined + when: + - item.version == oracle_ver + - patch_only is not defined + - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -103,6 +114,30 @@ executable: /bin/bash with_items: - "{{ rdbms_patches }}" - when: item.release == oracle_rel + when: + - item.release == oracle_rel + - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 + +- name: gcscopy | Copy RPM software from GCS to target instance + shell: | + set -o pipefail + {% for i in item.files %} + if ! ssh -i {{ ansible_ssh_private_key_file }} {{ ansible_ssh_extra_args }} {{ ansible_ssh_user }}@{{ ansible_ssh_host }} \ + "rpm -qp {{ swlib_path }}/{{ i }}" + then + gsutil cat gs://{{ swlib_mount_src }}/{{ i }} | ssh -i {{ ansible_ssh_private_key_file }} {{ ansible_ssh_extra_args }} \ + {{ ansible_ssh_user }}@{{ ansible_ssh_host }} "cat > {{ swlib_path }}/{{ i }}" && echo "File copied" + fi + {% endfor %} + register: shell_result + args: + executable: /bin/bash + with_items: + - "{{ rdbms_software }}" + when: + - item.version == oracle_ver + - oracle_edition == 'FREE' + changed_when: "'File copied' in shell_result.stdout" + delegate_to: 127.0.0.1 From 16d9182d2015353d0c225d6232009d9957cde27d Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Fri, 24 Jan 2025 09:37:09 -0500 Subject: [PATCH 02/13] Verify that OS is EL8 for Free Edition --- roles/base-provision/defaults/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/base-provision/defaults/main.yml b/roles/base-provision/defaults/main.yml index ca5795ab6..589336167 100644 --- a/roles/base-provision/defaults/main.yml +++ b/roles/base-provision/defaults/main.yml @@ -14,9 +14,9 @@ --- os_family_supported: "RedHat" -os_min_supported_version: "7.3" +os_min_supported_version: "{% if oracle_edition == 'FREE' %}8{% else %}7.3{% endif %}" -etc_hosts_ip: "{% if 'virtualbox' in ansible_virtualization_type %}{{ ansible_all_ipv4_addresses[1] }}{% else %}{{ ansible_default_ipv4.address }}{%endif%}" +etc_hosts_ip: "{% if 'virtualbox' in ansible_virtualization_type %}{{ ansible_all_ipv4_addresses[1] }}{% else %}{{ ansible_default_ipv4.address }}{% endif %}" install_os_packages: true packages: From 3ed6350b2cbe6bde688739068c61f97632ea4fb4 Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 14:48:10 -0500 Subject: [PATCH 03/13] Expand comment text to detail features that Free Edition does not support --- install-oracle.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install-oracle.sh b/install-oracle.sh index f2964f1f0..08e49bb2e 100755 --- a/install-oracle.sh +++ b/install-oracle.sh @@ -705,7 +705,8 @@ shopt -s nocasematch exit 1 } -# Oracle Database free edition parameter overrides +# Parameter overrides for features that Free Edition does not support +# (incl. RAC, ASM, role separation, and customized database name) if [ "${ORA_EDITION}" = "FREE" ]; then CLUSTER_TYPE=NONE ORA_DB_NAME=FREE From a5e6009df0bb9ca2b81f028626b05cb5a368243f Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 15:31:52 -0500 Subject: [PATCH 04/13] Remove quotes and specific reference to EL8 --- docs/user-guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user-guide.md b/docs/user-guide.md index d1c447f5f..5d738c637 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -11,7 +11,7 @@ published: True - [Command quick reference for single instance deployments](#command-quick-reference-for-single-instance-deployments) - [Command quick reference for RAC deployments](#command-quick-reference-for-rac-deployments) - [Command quick reference for DR deployments](#command-quick-reference-for-dr-deployments) - - [Command quick reference for Oracle Database "Free Edition" deployments](#command-quick-reference-for-oracle-database-free-edition-deployments) + - [Command quick reference for Oracle Database Free Edition deployments](#command-quick-reference-for-oracle-database-free-edition-deployments) - [Overview](#overview) - [Software Stack](#software-stack) - [Requirements and Prerequisites](#requirements-and-prerequisites) @@ -161,11 +161,11 @@ To create a standby database, add the following options to the command options t --cluster-type DG ``` -## Command quick reference for Oracle Database "Free Edition" deployments +## Command quick reference for Oracle Database Free Edition deployments The toolkit supports installing the Oracle Database Free edition, which is downloadable from the Oracle website: [Oracle Database Free Get Started](https://www.oracle.com/database/free/get-started/). -Unlike with other Oracle Database editions, the Free edition is available in [RPM package](https://en.wikipedia.org/wiki/RPM_Package_Manager) format only. Consequently, the Enterprise Linux 8 pre-installation and database RPM files must be downloaded and staged in the GCS storage bucket. +Unlike with other Oracle Database editions, the Free edition is available in [RPM package](https://en.wikipedia.org/wiki/RPM_Package_Manager) format only. Consequently, the associated Enterprise Linux pre-installation and database RPM files must be downloaded and staged in the GCS storage bucket. 1. Validate media specifying GCS storage bucket and specify `FREE` as the database edition: From 4a98130e29a60f728473fccb1d427b6bfbea0fff Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 15:56:31 -0500 Subject: [PATCH 05/13] Removed all checks for Free Edition from install-sw.yml and instead handled by setting install_gi=false --- group_vars/all.yml | 2 +- install-sw.yml | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/group_vars/all.yml b/group_vars/all.yml index 4c9d3bf37..c7311beda 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -126,7 +126,7 @@ run_initial_bu: true # Installation options: create_db: true create_listener: true -install_gi: true +install_gi: "{% if oracle_edition == 'FREE' %}false{% else %}true{% endif %}" install_rdbms: true disable_firewall: false diff --git a/install-sw.yml b/install-sw.yml index 0ce095ead..0bfc3f6e0 100644 --- a/install-sw.yml +++ b/install-sw.yml @@ -35,7 +35,6 @@ when: - install_gi|bool - cluster_type in ("NONE", "DG") - - oracle_edition != 'FREE' tags: gi-setup - hosts: dbasm @@ -60,14 +59,11 @@ - name: rac-gi-install | defaults from common include_vars: dir: roles/common/defaults - when: - - oracle_edition != 'FREE' - name: rac-gi-install | open firewall include_role: name: rac-lsnr-firewall when: - cluster_type == "RAC" - - oracle_edition != 'FREE' tags: lsnr-firewall - hosts: dbasm @@ -76,8 +72,6 @@ - name: rac-gi-install | defaults from common include_vars: dir: roles/common/defaults - when: - - oracle_edition != 'FREE' - name: rac-gi-install | setup ssh keys include_role: name: ssh-setup @@ -87,7 +81,6 @@ ssh_nodes: "{{ groups['dbasm'] }}" when: - cluster_type == "RAC" - - oracle_edition != 'FREE' tags: rac-gi,ssh-keys - hosts: dbasm[0] @@ -98,8 +91,6 @@ - name: rac-gi-install | defaults from common include_vars: dir: roles/common/defaults - when: - - oracle_edition != 'FREE' - name: rac-gi-install | GI installation include_role: name: rac-gi-setup @@ -113,7 +104,6 @@ loop_var: osw_files when: - cluster_type == "RAC" - - oracle_edition != 'FREE' tags: rac-gi - hosts: dbasm @@ -131,7 +121,6 @@ ssh_nodes: "{{ groups['dbasm'] }}" when: - cluster_type == "RAC" - - oracle_edition != 'FREE' tags: rac-db,ssh-keys - hosts: dbasm[0] @@ -154,7 +143,6 @@ loop_var: osw_files when: - cluster_type == "RAC" - - oracle_edition != 'FREE' tags: rac-db - hosts: dbasm @@ -162,6 +150,4 @@ - include_role: name: patch-vulns tasks_from: main - when: - - oracle_edition != 'FREE' tags: patch-vulns From 2ae5e83421eee2b53d28e8a75fc4d359fc6f60af Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 18:56:35 -0500 Subject: [PATCH 06/13] Remove superfluous Free Edition conditional clauses --- config-db.yml | 2 -- roles/check-swlib/tasks/main.yml | 2 -- roles/ora-host/tasks/main.yml | 7 ------- roles/swlib/tasks/gcscopy.yml | 4 ---- 4 files changed, 15 deletions(-) diff --git a/config-db.yml b/config-db.yml index 9ce703e38..0d103762c 100644 --- a/config-db.yml +++ b/config-db.yml @@ -62,7 +62,6 @@ - cluster_type != "RAC" - lookup('env', 'PRIMARY_IP_ADDR') is defined - lookup('env', 'PRIMARY_IP_ADDR') | length > 0 - - oracle_edition != 'FREE' tags: active-duplicate - include_role: @@ -70,5 +69,4 @@ tasks_from: main when: - cluster_type == "DG" - - oracle_edition != 'FREE' tags: dg-create diff --git a/roles/check-swlib/tasks/main.yml b/roles/check-swlib/tasks/main.yml index ba68668cc..ba21f3322 100644 --- a/roles/check-swlib/tasks/main.yml +++ b/roles/check-swlib/tasks/main.yml @@ -48,7 +48,6 @@ when: - item.base == oracle_ver - item.release == oracle_rel - - oracle_edition != 'FREE' register: patch_repo_files # We can't reliably check hashes for opatch, as the same file name @@ -68,7 +67,6 @@ when: - item.release == oracle_ver - oracle_rel != "base" - - oracle_edition != 'FREE' register: opatch_repo_files - name: check-swlib | Report gsutil failures (base) diff --git a/roles/ora-host/tasks/main.yml b/roles/ora-host/tasks/main.yml index c992a77ba..97ad603be 100644 --- a/roles/ora-host/tasks/main.yml +++ b/roles/ora-host/tasks/main.yml @@ -315,7 +315,6 @@ backup: yes when: - role_separation|bool - - oracle_edition != 'FREE' tags: os-users - name: (asmlib) | ASM device managment via asmlib or udev? @@ -377,7 +376,6 @@ uuid_result_nonmultipath: [] when: - udevadm_result_nonmultipath.results.0.stdout is defined - - oracle_edition != 'FREE' tags: udev-mpath - name: (udev) Add ASM non-multipath disk rules (filling dict) @@ -385,7 +383,6 @@ uuid_result_nonmultipath: "{{ uuid_result_nonmultipath | combine({item.stdout: item.item}) }}" when: - udevadm_result_nonmultipath.results.0.stdout is defined - - oracle_edition != 'FREE' with_items: - "{{ udevadm_result_nonmultipath.results }}" tags: udev-mpath @@ -401,7 +398,6 @@ register: udevRules_nonmultipath when: - uuid_result_nonmultipath is defined - - oracle_edition != 'FREE' with_dict: - "{{ uuid_result_nonmultipath }}" tags: udev-mpath @@ -426,7 +422,6 @@ uuid_result: [] when: - udevadm_result.results.0.stdout is defined - - oracle_edition != 'FREE' tags: udev-mpath - name: (udev) Add ASM mpath disk rules on BM (filling dict) @@ -434,7 +429,6 @@ uuid_result: "{{ uuid_result | combine({item.stdout: item.item}) }}" when: - udevadm_result.results.0.stdout is defined - - oracle_edition != 'FREE' with_items: - "{{ udevadm_result.results }}" tags: udev-mpath @@ -450,7 +444,6 @@ register: udevRules when: - uuid_result is defined - - oracle_edition != 'FREE' with_dict: - "{{ uuid_result }}" tags: udev-mpath diff --git a/roles/swlib/tasks/gcscopy.yml b/roles/swlib/tasks/gcscopy.yml index c7369fd8e..9ff2b6d1b 100644 --- a/roles/swlib/tasks/gcscopy.yml +++ b/roles/swlib/tasks/gcscopy.yml @@ -33,7 +33,6 @@ when: - item.version == oracle_ver - patch_only is not defined - - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -53,7 +52,6 @@ - "{{ gi_patches }}" when: - item.release == oracle_rel - - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -73,7 +71,6 @@ when: - item.release == oracle_ver - oracle_rel != "base" - - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -116,7 +113,6 @@ - "{{ rdbms_patches }}" when: - item.release == oracle_rel - - oracle_edition != 'FREE' changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 From 018b5774cdfada78b32547e36f5de887a70ca373 Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 21:00:09 -0500 Subject: [PATCH 07/13] Create and use new free_edition boolean instead of string comparisons --- group_vars/all.yml | 9 ++++++--- roles/base-provision/defaults/main.yml | 2 +- roles/common/defaults/main.yml | 4 ++-- roles/lsnr-create/tasks/main.yml | 4 ++-- roles/rdbms-setup/tasks/main.yml | 4 ++-- roles/swlib/tasks/gcscopy.yml | 4 ++-- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/group_vars/all.yml b/group_vars/all.yml index c7311beda..301c04e99 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -14,6 +14,9 @@ --- +# Defined boolean if installing Free Edition +free_edition: "{{ oracle_edition == 'FREE' }}" + # Installation related variables: swlib_path: "{{ lookup('env','ORA_SWLIB_PATH')|lower|default(swlib_path_default,true) }}" swlib_unzip_path: "{{ lookup('env','ORA_STAGING')|lower|default(swlib_path,true) }}" @@ -44,7 +47,7 @@ asm_disks_default: blk_device: /dev/BOGUS asm_definition_file: "{{ lookup('env','ORA_ASM_DISKS')|default('asm_disk_config.json',true) }}" asm_disk_input: "{{ lookup('file',asm_definition_file,errors='ignore') }}" -asm_disks: "{{ asm_disk_input | default(asm_disks_default,true) }}" +asm_disks: "{% if free_edition %}[]{% else %}{{ asm_disk_input | default(asm_disks_default,true) }}{% endif %}" ## The toolkit can optionally configure swap space #If your RAM size is less than or equal to 2 GB, your swap size should be 1.5 times of the RAM. For example, if your RAM size is 2 GB, you should create swap space of 3GB @@ -118,7 +121,7 @@ oracle_group: oinstall grid_user: "{% if role_separation|bool %}grid{% else %}{{ oracle_user }}{% endif %}" grid_group: asmadmin oracle_root: "/u01/app" -home_name: "{% if oracle_edition != 'FREE' %}dbhome_1{% else %}dbhomeFree{% endif %}" +home_name: "{% if free_edition %}dbhomeFree{% else %}dbhome_1{% endif %}" oracle_sid: "{% if db_config_type == 'SI' %}{{ db_name }}{% else %}{{ db_name }}{{ instance_num }}{% endif %}" asm_sid: "{% if db_config_type == 'SI' %}+ASM{% else %}+ASM{{ instance_num }}{% endif %}" run_initial_bu: true @@ -126,7 +129,7 @@ run_initial_bu: true # Installation options: create_db: true create_listener: true -install_gi: "{% if oracle_edition == 'FREE' %}false{% else %}true{% endif %}" +install_gi: "{% if free_edition %}false{% else %}true{% endif %}" install_rdbms: true disable_firewall: false diff --git a/roles/base-provision/defaults/main.yml b/roles/base-provision/defaults/main.yml index 589336167..d019383e6 100644 --- a/roles/base-provision/defaults/main.yml +++ b/roles/base-provision/defaults/main.yml @@ -14,7 +14,7 @@ --- os_family_supported: "RedHat" -os_min_supported_version: "{% if oracle_edition == 'FREE' %}8{% else %}7.3{% endif %}" +os_min_supported_version: "{% if free_edition %}8{% else %}7.3{% endif %}" etc_hosts_ip: "{% if 'virtualbox' in ansible_virtualization_type %}{{ ansible_all_ipv4_addresses[1] }}{% else %}{{ ansible_default_ipv4.address }}{% endif %}" install_os_packages: true diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index ede4e7c6a..cd834e671 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -15,9 +15,9 @@ --- # Variables used by more than one role -oracle_ver_dir: "{% if oracle_edition != 'FREE' %}{{ oracle_ver [:6] }}{% else %}{% if oracle_ver[:4] == '23.2' or oracle_ver[:4] == '23.3' %}23c{% else %}{{ oracle_ver[:2] }}ai{% endif %}{% endif %}" +oracle_ver_dir: "{% if free_edition %}{% if oracle_ver[:4] == '23.2' or oracle_ver[:4] == '23.3' %}23c{% else %}{{ oracle_ver[:2] }}ai{% endif %}{% else %}{{ oracle_ver[:6] }}{% endif %}" oracle_inventory: "{{ oracle_root }}/oraInventory" -oracle_base: "{% if oracle_edition != 'FREE' %}{{ oracle_root }}/oracle{% else %}/opt/oracle{% endif %}" +oracle_base: "{% if free_edition %}/opt/oracle{% else %}{{ oracle_root }}/oracle{% endif %}" oracle_home: "{{ oracle_base }}/product/{{ oracle_ver_dir }}/{{ home_name }}" grid_home: "{{ oracle_root }}/{{ oracle_ver_dir }}/grid" grid_base: "{{ oracle_root }}/grid" diff --git a/roles/lsnr-create/tasks/main.yml b/roles/lsnr-create/tasks/main.yml index a3e99e8bd..754e613b1 100644 --- a/roles/lsnr-create/tasks/main.yml +++ b/roles/lsnr-create/tasks/main.yml @@ -69,7 +69,7 @@ - create_listener - lsnr_port_check.stdout == "0" - lsnr_name_check.stdout == "0" - - oracle_edition != 'FREE' + - not free_edition tags: lsnr-create - name: Listener creation output @@ -102,7 +102,7 @@ - create_listener - lsnr_port_check.stdout == "0" - lsnr_name_check.stdout == "0" - - oracle_edition == 'FREE' + - free_edition tags: lsnr-create - name: Listener creation output from netca diff --git a/roles/rdbms-setup/tasks/main.yml b/roles/rdbms-setup/tasks/main.yml index 5663fa8ed..054a4b34c 100644 --- a/roles/rdbms-setup/tasks/main.yml +++ b/roles/rdbms-setup/tasks/main.yml @@ -49,7 +49,7 @@ - existing_dbhome.stdout == "0" - osw.version == oracle_ver - oracle_edition in osw.edition - - oracle_edition != 'FREE' + - not free_edition tags: rdbms-setup - include_tasks: rdbms-rpm-install.yml @@ -61,7 +61,7 @@ - existing_dbhome.stdout == "0" - osw.version == oracle_ver - oracle_edition in osw.edition - - oracle_edition == 'FREE' + - free_edition tags: rdbms-setup - name: Create sqlnet.ora file diff --git a/roles/swlib/tasks/gcscopy.yml b/roles/swlib/tasks/gcscopy.yml index 9ff2b6d1b..0eb74f28a 100644 --- a/roles/swlib/tasks/gcscopy.yml +++ b/roles/swlib/tasks/gcscopy.yml @@ -93,7 +93,7 @@ when: - item.version == oracle_ver - patch_only is not defined - - oracle_edition != 'FREE' + - not free_edition changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -134,6 +134,6 @@ - "{{ rdbms_software }}" when: - item.version == oracle_ver - - oracle_edition == 'FREE' + - free_edition changed_when: "'File copied' in shell_result.stdout" delegate_to: 127.0.0.1 From 18dcbf7d65c063b0a681a8295669659d7d723ebe Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 22:03:05 -0500 Subject: [PATCH 08/13] Change to using DBCA for Free Edition installations --- group_vars/all.yml | 1 + roles/common/defaults/main.yml | 8 +++ roles/db-create/defaults/main.yml | 4 +- roles/db-create/tasks/main.yml | 85 ++++-------------------- roles/db-create/templates/dbca.rsp.sh.j2 | 52 +++++++++------ roles/ora-host/tasks/main.yml | 33 ++------- 6 files changed, 62 insertions(+), 121 deletions(-) diff --git a/group_vars/all.yml b/group_vars/all.yml index 301c04e99..b982bade4 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -82,6 +82,7 @@ asm_disk_management: "{{ lookup('env','ORA_DISK_MGMT')|lower|default('udev',true role_separation: "{{ lookup('env','ORA_ROLE_SEPARATION')|lower|default('true',true) }}" data_diskgroup: "{{ lookup('env','ORA_DATA_DISKGROUP')|default('DATA',true) }}" reco_diskgroup: "{{ lookup('env','ORA_RECO_DISKGROUP')|default('RECO',true) }}" +use_omf: true # Used for file system storage (currently applicable only for Free Edition) # Listener related variables: listener_port: "{{ lookup('env','ORA_LISTENER_PORT')|default('1521',true) }}" diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index cd834e671..228121bf4 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -74,6 +74,10 @@ grid_dirs: - { name: "{{ grid_home }}", owner: "{{ grid_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } - { name: "/home/{{ grid_user }}/.ansible/tmp", owner: "{{ grid_user }}", group: "{{ oracle_group }}", mode: "ug=rwx,o=rx" } +fs_dirs: + - { name: "{{ data_diskgroup }}", owner: "{{ oracle_user }}", group: "{{ oracle_group }}", mode: "u=rwx,g=rx,o=" } + - { name: "{{ reco_diskgroup }}", owner: "{{ oracle_user }}", group: "{{ oracle_group }}", mode: "u=rwx,g=rx,o=" } + pwgen_file: pwgen.sh pwgen_path: /usr/local/bin pass_param: "{{pwgen_path}}/{{pwgen_file}} 16" @@ -90,6 +94,10 @@ diskgroup_compatible_rdbms: "{# assign to variable c compatible parameter and se run_cluvfy: false +# Systemd service name used with Free Edition +free_edition_name: "{% if free_edition %}{% if oracle_ver[:4] == '23.2' or oracle_ver[:4] == '23.3' %}23c{% else %}{{ oracle_ver[:2] }}ai{% endif %}{% endif %}" +systemd_service_name: "{% if free_edition %}oracle-free-{{ free_edition_name }}.service{% endif %}" + # ignorance of prerequisites depending on version prereq_option: "{% if oracle_ver_base in ('11.2', '12.1') %}-ignorePrereq{% else %}-ignorePrereqFailure{% endif %}" diff --git a/roles/db-create/defaults/main.yml b/roles/db-create/defaults/main.yml index 91e9bd015..e87cc3d21 100644 --- a/roles/db-create/defaults/main.yml +++ b/roles/db-create/defaults/main.yml @@ -13,6 +13,4 @@ # limitations under the License. --- - -recovery_area_size: 16384 -systemd_service_name: "{% if oracle_edition == 'FREE' %}{% if oracle_ver[:4] == '23.2' or oracle_ver[:4] == '23.3' %}oracle-free-23c.service{% else %}oracle-free-{{ oracle_ver[:2] }}ai.service{% endif %}{% endif %}" +dbca_extra_args: "{% if free_edition %}-skipDatapatch TRUE -useOMF {{ use_omf }} -recoveryAreaSize 1638{% endif %}" diff --git a/roles/db-create/tasks/main.yml b/roles/db-create/tasks/main.yml index 08af20e07..efe423fe0 100644 --- a/roles/db-create/tasks/main.yml +++ b/roles/db-create/tasks/main.yml @@ -59,7 +59,6 @@ when: - pmon_proc.stdout == "0" - check_oratab.stdout == "0" - - oracle_edition != 'FREE' tags: db-create - name: Run DBCA response file script @@ -70,7 +69,6 @@ when: - pmon_proc.stdout == "0" - check_oratab.stdout == "0" - - oracle_edition != 'FREE' tags: db-create - name: Script cleanup @@ -79,8 +77,6 @@ file: path: "{{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp.sh" state: absent - when: - - oracle_edition != 'FREE' tags: db-create - name: DBCA response file differences to template @@ -90,7 +86,6 @@ when: - pmon_proc.stdout == "0" - check_oratab.stdout == "0" - - oracle_edition != 'FREE' tags: db-create - name: Copy to instance the pwgen.sh script @@ -99,15 +94,12 @@ dest: "{{ pwgen_path }}/{{ pwgen_file }}" owner: root mode: u=rwx,go=rx - when: - - oracle_edition != 'FREE' - name: Generate command for password randomization (not 11.2) set_fact: pwd_gen_cmd: echo -e "$({{ pass_param }})\n$({{ pass_param }})\n$({{ pass_param }})" when: - oracle_ver != "11.2.0.4.0" - - oracle_edition != 'FREE' tags: db-create - name: Generate command for password randomization (11.2 only) @@ -118,59 +110,18 @@ - name: Create database using DBCA block: - - name: Run DBCA using response file + - name: Run DBCA become: yes become_user: "{{ oracle_user }}" shell: | set -o pipefail export PATH={{ oracle_home }}/bin:${PATH} - {{ pwd_gen_cmd }} | dbca -silent -createDatabase -redoLogFileSize {{ redologsize }} -responseFile {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp + {{ pwd_gen_cmd }} | dbca -silent -createDatabase {{ dbca_extra_args }} -redoLogFileSize {{ redologsize }} -responseFile {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp register: dbca_output failed_when: "'Completing Database Creation' not in dbca_output.stdout or '100% complete' not in dbca_output.stdout" when: - pmon_proc.stdout == "0" - check_oratab.stdout == "0" - - oracle_edition != 'FREE' - tags: db-create - - name: Run DBCA with command line arguments - become: yes - become_user: "{{ oracle_user }}" - shell: | - set -o pipefail - export PATH={{ oracle_home }}/bin:${PATH} - dbca -silent \ - -createDatabase \ - -sid {{ oracle_sid }} \ - -gdbName {{ db_name }}.{{ db_domain }} \ - -templateName FREE_Database.dbc \ - -characterSet {{ charset }} \ - -nationalCharacterSet {{ ncharset }} \ - -createAsContainerDatabase TRUE \ - -numberOfPDBs {{ pdb_count }} \ - -pdbName {{ pdb_prefix }} \ - -pdbAdminPassword $(tr -dc A-Za-z - {{ oracle_dirs + grid_dirs if oracle_edition != 'FREE' - else oracle_dirs + - [ - {'name': data_diskgroup, 'owner': oracle_user, 'group': oracle_group, 'mode': 'u=rwx,g=rx,o='}, - {'name': reco_diskgroup, 'owner': oracle_user, 'group': oracle_group, 'mode': 'u=rwx,g=rx,o='} - ] - }} + with_items: "{{ oracle_dirs + fs_dirs if free_edition else oracle_dirs + grid_dirs }}" # TODO tags: os-dirs - name: Create backup directory @@ -320,8 +312,6 @@ - name: (asmlib) | ASM device managment via asmlib or udev? debug: msg: "asm_disk_management is set to {{ asm_disk_management }}" - when: - - oracle_edition != 'FREE' tags: asm-disks - name: Partition all ASM raw disks @@ -330,9 +320,7 @@ number: 1 state: present label: gpt - when: - - "'mapper' not in item.1.blk_device" - - oracle_edition != 'FREE' + when: "'mapper' not in item.1.blk_device" run_once: true with_subelements: - "{{ asm_disks }}" @@ -342,8 +330,6 @@ - include_role: name: common tasks_from: populate-asm-disks.yml - when: - - oracle_edition != 'FREE' - name: (debug) asm disk configuration debug: @@ -351,8 +337,6 @@ - asm_disks {{ asm_disks }} - asm_def_file {{ asm_definition_file }} - asm_disk_input {{ asm_disk_input }} - when: - - oracle_edition != 'FREE' tags: asm-disks ######## Udev rules for non-multipath disks ######## @@ -365,7 +349,6 @@ when: - asm_disk_management == "udev" - "'mapper' not in item.1.blk_device" - - oracle_edition != 'FREE' with_subelements: - "{{ asm_disks }}" - disks @@ -409,9 +392,7 @@ become_user: root shell: udevadm info --query=all --name={{ item.1.blk_device }} | grep DM_UUID | awk -F'=' '{print $2}' register: udevadm_result - when: - - "'mapper' in item.1.blk_device" - - oracle_edition != 'FREE' + when: "'mapper' in item.1.blk_device" with_subelements: - "{{ asm_disks }}" - disks @@ -452,8 +433,6 @@ become: yes become_user: root shell: ( /sbin/udevadm control --reload-rules && /sbin/udevadm trigger && /sbin/partprobe ) - when: - - oracle_edition != 'FREE' tags: asm-disks - name: (asmlib) Install Oracle ASM libraries From 615a0a5eff46b21999a44b38c0e528d4c47dd5d8 Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Mon, 27 Jan 2025 22:38:04 -0500 Subject: [PATCH 09/13] Restore validation-scripts for Free Edition and adjust to apply to all editions --- config-db.yml | 11 +---------- roles/validation-scripts/defaults/main.yml | 6 +++++- roles/validation-scripts/tasks/main.yml | 4 ++++ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/config-db.yml b/config-db.yml index 0d103762c..cbab41924 100644 --- a/config-db.yml +++ b/config-db.yml @@ -36,6 +36,7 @@ - db-create - db-adjustements - db-backups + - validation-scripts loop_control: loop_var: role_item when: @@ -44,16 +45,6 @@ - lookup('env', 'PRIMARY_IP_ADDR') is not defined or lookup('env', 'PRIMARY_IP_ADDR') | length == 0 tags: primary-db - - include_role: - name: validation-scripts - tasks_from: main - when: - - create_db|bool - - cluster_type != "RAC" - - lookup('env', 'PRIMARY_IP_ADDR') is not defined or lookup('env', 'PRIMARY_IP_ADDR') | length == 0 - - oracle_edition != 'FREE' - tags: primary-db - - include_role: name: db-copy tasks_from: active-copy diff --git a/roles/validation-scripts/defaults/main.yml b/roles/validation-scripts/defaults/main.yml index 3e71e39c9..d9e473bbb 100644 --- a/roles/validation-scripts/defaults/main.yml +++ b/roles/validation-scripts/defaults/main.yml @@ -13,7 +13,11 @@ # limitations under the License. --- -script_list: +scripts_all_editions: [] + +scripts_commercial_editions: - asm_disks.sh - crs_check.sh - cluvfy_checks.sh + +scripts_free_editions: [] diff --git a/roles/validation-scripts/tasks/main.yml b/roles/validation-scripts/tasks/main.yml index 49b84e610..84e472ebb 100644 --- a/roles/validation-scripts/tasks/main.yml +++ b/roles/validation-scripts/tasks/main.yml @@ -13,6 +13,10 @@ # limitations under the License. --- +- name: Build script list + set_fact: + script_list: "{{ scripts_all_editions + (scripts_free_editions if free_edition else scripts_commercial_editions) }}" + - name: Copy validation scripts to server template: src: "{{ item }}.j2" From a878d300cf441267694a1ccac8a33d1ef3aa2b1c Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Tue, 28 Jan 2025 00:06:50 -0500 Subject: [PATCH 10/13] Change to simplify Free Edition short version to just ORA_VERSION=23 --- check-swlib.sh | 12 +++--------- install-oracle.sh | 10 +++------- roles/common/tasks/populate-vars.yml | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/check-swlib.sh b/check-swlib.sh index f05047861..b90213e32 100755 --- a/check-swlib.sh +++ b/check-swlib.sh @@ -62,11 +62,7 @@ while true; do ;; --ora-version) ORA_VERSION="$2" - if [[ "${ORA_VERSION}" = "23.6" ]] ; then ORA_VERSION="23.6.0.24.10"; fi - if [[ "${ORA_VERSION}" = "23.5" ]] ; then ORA_VERSION="23.5.0.24.07"; fi - if [[ "${ORA_VERSION}" = "23.4" ]] ; then ORA_VERSION="23.4.0.24.05"; fi - if [[ "${ORA_VERSION}" = "23.3" ]] ; then ORA_VERSION="23.3.0.23.09"; fi - if [[ "${ORA_VERSION}" = "23.2" ]] ; then ORA_VERSION="23.2.0.0.0"; fi + if [[ "${ORA_VERSION}" = "23" ]] ; then ORA_VERSION="23.0.0.0.0"; fi if [[ "${ORA_VERSION}" = "19" ]] ; then ORA_VERSION="19.3.0.0.0"; fi if [[ "${ORA_VERSION}" = "18" ]] ; then ORA_VERSION="18.0.0.0.0"; fi if [[ "${ORA_VERSION}" = "12" ]] ; then ORA_VERSION="12.2.0.1.0"; fi @@ -119,10 +115,8 @@ done } # Oracle Database free edition parameter overrides -if [ "${ORA_EDITION}" = "FREE" ]; then - if [[ "${ORA_RELEASE}" == "latest" && ! "${ORA_VERSION}" =~ ^23\.[0-9]{1,2} ]]; then - ORA_VERSION="23.6.0.24.10" - fi +if [[ "${ORA_EDITION}" = "FREE" && ! "${ORA_VERSION}" =~ ^23\. ]]; then + ORA_VERSION="23.0.0.0.0" fi # Mandatory options diff --git a/install-oracle.sh b/install-oracle.sh index 08e49bb2e..9f0bb9a46 100755 --- a/install-oracle.sh +++ b/install-oracle.sh @@ -259,11 +259,7 @@ while true; do case "$1" in --ora-version) ORA_VERSION="$2" - if [[ "${ORA_VERSION}" = "23.6" ]] ; then ORA_VERSION="23.6.0.24.10"; fi - if [[ "${ORA_VERSION}" = "23.5" ]] ; then ORA_VERSION="23.5.0.24.07"; fi - if [[ "${ORA_VERSION}" = "23.4" ]] ; then ORA_VERSION="23.4.0.24.05"; fi - if [[ "${ORA_VERSION}" = "23.3" ]] ; then ORA_VERSION="23.3.0.23.09"; fi - if [[ "${ORA_VERSION}" = "23.2" ]] ; then ORA_VERSION="23.2.0.0.0"; fi + if [[ "${ORA_VERSION}" = "23" ]] ; then ORA_VERSION="23.0.0.0.0"; fi if [[ "${ORA_VERSION}" = "19" ]] ; then ORA_VERSION="19.3.0.0.0"; fi if [[ "${ORA_VERSION}" = "18" ]] ; then ORA_VERSION="18.0.0.0.0"; fi if [[ "${ORA_VERSION}" = "12" ]] ; then ORA_VERSION="12.2.0.1.0"; fi @@ -712,8 +708,8 @@ if [ "${ORA_EDITION}" = "FREE" ]; then ORA_DB_NAME=FREE ORA_DISK_MGMT=UDEV ORA_ROLE_SEPARATION=FALSE - if [[ "${ORA_RELEASE}" == "latest" && ! "${ORA_VERSION}" =~ ^23\.[0-9]{1,2} ]]; then - ORA_VERSION="23.6.0.24.10" + if [[ ! "${ORA_VERSION}" =~ ^23\. ]]; then + ORA_VERSION="23.0.0.0.0" fi [[ ! "${ORA_DATA_DISKGROUP}" =~ ^(/([^/]+))*/?$ ]] && ORA_DATA_DISKGROUP="/u02/oradata" || true [[ ! "${ORA_RECO_DISKGROUP}" =~ ^(/([^/]+))*/?$ ]] && ORA_RECO_DISKGROUP="/opt/oracle/fast_recovery_area" || true diff --git a/roles/common/tasks/populate-vars.yml b/roles/common/tasks/populate-vars.yml index 5b72bd456..a81e38e5b 100644 --- a/roles/common/tasks/populate-vars.yml +++ b/roles/common/tasks/populate-vars.yml @@ -25,10 +25,26 @@ {{ matched_patch.release | default((gi_patches | selectattr('base', 'equalto', oracle_ver) | list | last | default({})).release) if matched_patch is defined else (gi_patches | selectattr('base', 'equalto', oracle_ver) | list | last | default({})).release }} {% endif %} when: + - not free_edition - oracle_rel is defined - oracle_rel != "base" tags: oracle-rel +- name: populate-vars | Resolve Free Edition software release + set_fact: + oracle_ver: "{{ + (oracle_rel == 'latest') and (free_versions | last) or + (oracle_rel == 'base') and (free_versions | first) or + (oracle_rel in free_versions) and oracle_rel or + (free_versions | last) + }}" + vars: + free_versions: "{{ rdbms_software | selectattr('edition', 'equalto', 'FREE') | map(attribute='version') | sort | list }}" + when: + - free_edition + - oracle_ver == "23.0.0.0.0" + tags: oracle-rel + - name: populate-vars | Show resolved release debug: var: oracle_rel From 4963f09b4418867e5fb9aff95edefd442fd44607 Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Tue, 28 Jan 2025 00:21:27 -0500 Subject: [PATCH 11/13] Remove left-over comment --- roles/ora-host/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/ora-host/tasks/main.yml b/roles/ora-host/tasks/main.yml index 63e72b8e1..1831d97bf 100644 --- a/roles/ora-host/tasks/main.yml +++ b/roles/ora-host/tasks/main.yml @@ -239,7 +239,7 @@ owner: "{{ item.owner }}" group: "{{ item.group }}" mode: "{{ item.mode }}" - with_items: "{{ oracle_dirs + fs_dirs if free_edition else oracle_dirs + grid_dirs }}" # TODO + with_items: "{{ oracle_dirs + fs_dirs if free_edition else oracle_dirs + grid_dirs }}" tags: os-dirs - name: Create backup directory From 1893cf7502cb3f69057da2ba1ce2fc5c3d5f0bb0 Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Tue, 28 Jan 2025 14:00:16 -0500 Subject: [PATCH 12/13] Change name of script variables; Add missing tag to task --- roles/validation-scripts/defaults/main.yml | 6 ++---- roles/validation-scripts/tasks/main.yml | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/roles/validation-scripts/defaults/main.yml b/roles/validation-scripts/defaults/main.yml index d9e473bbb..8113cdcab 100644 --- a/roles/validation-scripts/defaults/main.yml +++ b/roles/validation-scripts/defaults/main.yml @@ -13,11 +13,9 @@ # limitations under the License. --- -scripts_all_editions: [] - -scripts_commercial_editions: +cluster_scripts: - asm_disks.sh - crs_check.sh - cluvfy_checks.sh -scripts_free_editions: [] +common_scripts: [] diff --git a/roles/validation-scripts/tasks/main.yml b/roles/validation-scripts/tasks/main.yml index 84e472ebb..331d5842f 100644 --- a/roles/validation-scripts/tasks/main.yml +++ b/roles/validation-scripts/tasks/main.yml @@ -15,7 +15,8 @@ --- - name: Build script list set_fact: - script_list: "{{ scripts_all_editions + (scripts_free_editions if free_edition else scripts_commercial_editions) }}" + script_list: "{{ common_scripts + (cluster_scripts if not free_edition else []) }}" + tags: validation-scripts - name: Copy validation scripts to server template: From 46af82549aeac5ab84afaf6d008646938aba239e Mon Sep 17 00:00:00 2001 From: Simon Pane Date: Tue, 28 Jan 2025 14:36:20 -0500 Subject: [PATCH 13/13] Re-write to remove jinja templating and instead use shell commands to determine whether srvctl should be used --- .../db-adjustements/templates/archivelog_mode.sh.j2 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/roles/db-adjustements/templates/archivelog_mode.sh.j2 b/roles/db-adjustements/templates/archivelog_mode.sh.j2 index 219025017..5c8677e6f 100644 --- a/roles/db-adjustements/templates/archivelog_mode.sh.j2 +++ b/roles/db-adjustements/templates/archivelog_mode.sh.j2 @@ -1,10 +1,12 @@ source oraenv <<< {{ oracle_sid }} -{% if groups['dbasm'] | length > 1 %} -srvctl stop db -d {{ db_name }} -o immediate -{% else %} -echo "shutdown immediate" | sqlplus -s -L / as sysdba -{% endif %} +srvctl_status="$(srvctl status database -d {{ db_name }})" + +if [[ "${srvctl_status}" == "Database is running." ]]; then + srvctl stop db -d {{ db_name }} -o immediate +else + echo "shutdown immediate" | sqlplus -s -L / as sysdba +fi sqlplus -s -L / as sysdba << EOF startup mount