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 19d1fadb..f0504786 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 cbab4192..9ce703e3 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 0486b033..d1c447f5 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 f2ee74b0..4c9d3bf3 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 0d4a3800..f2964f1f 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 e2e87179..0ce095ea 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 12f7ffb6..ba68668c 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 4763f320..ede4e7c6 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 cf97c06a..21902501 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 3cd276cd..e22e6fde 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 09eda537..de0978e6 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 00000000..91e9bd01 --- /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 3f11c63a..08af20e0 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 b65fdffa..7bb31768 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 33609775..5663fa8e 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 00000000..64f543dc --- /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 22cad90d..c7369fd8 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 ca5795ab..58933616 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 f2964f1f..08e49bb2 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 d1c447f5..5d738c63 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 4c9d3bf3..c7311bed 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 0ce095ea..0bfc3f6e 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 9ce703e3..0d103762 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 ba68668c..ba21f332 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 c992a77b..97ad603b 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 c7369fd8..9ff2b6d1 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 c7311bed..301c04e9 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 58933616..d019383e 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 ede4e7c6..cd834e67 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 a3e99e8b..754e613b 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 5663fa8e..054a4b34 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 9ff2b6d1..0eb74f28 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 301c04e9..b982bade 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 cd834e67..228121bf 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 91e9bd01..e87cc3d2 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 08af20e0..efe423fe 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 0d103762..cbab4192 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 3e71e39c..d9e473bb 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 49b84e61..84e472eb 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 f0504786..b90213e3 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 08e49bb2..9f0bb9a4 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 5b72bd45..a81e38e5 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 63e72b8e..1831d97b 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 d9e473bb..8113cdca 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 84e472eb..331d5842 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 21902501..5c8677e6 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