diff --git a/check-swlib.sh b/check-swlib.sh index 19d1fadbe..b90213e32 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,7 @@ while true; do ;; --ora-version) ORA_VERSION="$2" + 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 @@ -113,6 +114,11 @@ done exit 1 } +# Oracle Database free edition parameter overrides +if [[ "${ORA_EDITION}" = "FREE" && ! "${ORA_VERSION}" =~ ^23\. ]]; then + ORA_VERSION="23.0.0.0.0" +fi + # Mandatory options if [ "${ORA_SWLIB_BUCKET}" = "" ]; then echo "Please specify a GS bucket with --ora-swlib-bucket" diff --git a/docs/user-guide.md b/docs/user-guide.md index 0486b0337..5d738c637 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 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: + + ```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..b982bade4 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 @@ -79,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) }}" @@ -118,7 +122,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 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 +130,7 @@ run_initial_bu: true # Installation options: create_db: true create_listener: true -install_gi: true +install_gi: "{% if free_edition %}false{% else %}true{% endif %}" install_rdbms: true disable_firewall: false diff --git a/install-oracle.sh b/install-oracle.sh index 0d4a38006..9f0bb9a46 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,7 @@ while true; do case "$1" in --ora-version) ORA_VERSION="$2" + 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 @@ -700,6 +701,24 @@ shopt -s nocasematch exit 1 } +# 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 + ORA_DISK_MGMT=UDEV + ORA_ROLE_SEPARATION=FALSE + 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 + 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..0bfc3f6e0 100644 --- a/install-sw.yml +++ b/install-sw.yml @@ -54,7 +54,6 @@ - cluster_type in ("NONE", "DG") tags: rdbms-setup - - hosts: dbasm tasks: - name: rac-gi-install | defaults from common @@ -95,12 +94,12 @@ - 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: @@ -151,4 +150,4 @@ - include_role: name: patch-vulns tasks_from: main - tags: patch-vulns \ No newline at end of file + tags: patch-vulns diff --git a/roles/base-provision/defaults/main.yml b/roles/base-provision/defaults/main.yml index ca5795ab6..d019383e6 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 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%}" +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: diff --git a/roles/check-swlib/tasks/main.yml b/roles/check-swlib/tasks/main.yml index 12f7ffb6d..ba21f3322 100644 --- a/roles/check-swlib/tasks/main.yml +++ b/roles/check-swlib/tasks/main.yml @@ -45,7 +45,9 @@ 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 register: patch_repo_files # We can't reliably check hashes for opatch, as the same file name @@ -62,7 +64,9 @@ ignore_errors: true with_items: - "{{ opatch_patches }}" - when: item.release == oracle_ver and oracle_rel != "base" + when: + - item.release == oracle_ver + - oracle_rel != "base" 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..228121bf4 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 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: "{{ oracle_root }}/oracle" -oracle_home: "{{ oracle_root }}/oracle/product/{{ oracle_ver_dir }}/{{ home_name }}" +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" @@ -69,9 +69,15 @@ 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" } +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" @@ -88,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 %}" @@ -152,6 +162,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/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 diff --git a/roles/db-adjustements/templates/archivelog_mode.sh.j2 b/roles/db-adjustements/templates/archivelog_mode.sh.j2 index cf97c06ad..5c8677e6f 100644 --- a/roles/db-adjustements/templates/archivelog_mode.sh.j2 +++ b/roles/db-adjustements/templates/archivelog_mode.sh.j2 @@ -1,8 +1,14 @@ source oraenv <<< {{ oracle_sid }} -srvctl stop db -d {{ db_name }} -o immediate +srvctl_status="$(srvctl status database -d {{ db_name }})" -sqlplus -s / as sysdba << EOF +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 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..e87cc3d21 --- /dev/null +++ b/roles/db-create/defaults/main.yml @@ -0,0 +1,16 @@ +# 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. + +--- +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 3f11c63a3..efe423fe0 100644 --- a/roles/db-create/tasks/main.yml +++ b/roles/db-create/tasks/main.yml @@ -56,7 +56,9 @@ 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" tags: db-create - name: Run DBCA response file script @@ -64,7 +66,9 @@ 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" tags: db-create - name: Script cleanup @@ -79,7 +83,9 @@ 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" tags: db-create - name: Copy to instance the pwgen.sh script @@ -92,7 +98,8 @@ - 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" tags: db-create - name: Generate command for password randomization (11.2 only) @@ -103,17 +110,19 @@ - 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 + become: yes + become_user: "{{ oracle_user }}" + shell: | + set -o pipefail + export PATH={{ oracle_home }}/bin:${PATH} + {{ 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" + tags: db-create rescue: - name: Retrieve DBCA logs slurp: @@ -128,7 +137,9 @@ - "{{ dbca_output.cmd }}" - "{{ dbca_output.stdout_lines }}" #verbosity: 1 - when: pmon_proc.stdout == "0" and check_oratab.stdout == "0" + when: + - pmon_proc.stdout == "0" + - check_oratab.stdout == "0" tags: db-create - name: Save PDBs state @@ -147,3 +158,12 @@ become: yes become_user: "{{ oracle_user }}" tags: db-create + +- name: Enable service for FREE edition + systemd: + state: started + enabled: true + daemon_reload: true + name: "{{ systemd_service_name }}" + when: free_edition + tags: db-create diff --git a/roles/db-create/templates/dbca.rsp.sh.j2 b/roles/db-create/templates/dbca.rsp.sh.j2 index de8f47567..5334018e9 100644 --- a/roles/db-create/templates/dbca.rsp.sh.j2 +++ b/roles/db-create/templates/dbca.rsp.sh.j2 @@ -1,24 +1,36 @@ #!/bin/bash -cp {{ oracle_home }}/assistants/dbca/dbca.rsp {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp +response_file="{{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp" -sed -i '/^\#\{0,\} \{0,\}gdbName \{0,\}=/I s~\#\{0,\} \{0,\}gdbName \{0,\}=.*~gdbName='{{ db_name }}'.'{{ db_domain }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}sid \{0,\}=/I s~\#\{0,\} \{0,\}sid \{0,\}=.*~sid='{{ db_name }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}databaseConfigType \{0,\}=/I s~\#\{0,\} \{0,\}databaseConfigType \{0,\}=.*~databaseConfigType='{{ db_config_type }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}createAsContainerDatabase \{0,\}=/I s~\#\{0,\} \{0,\}createAsContainerDatabase \{0,\}=.*~createAsContainerDatabase='{{ container_db }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}numberOfPDBs \{0,\}=/I s~\#\{0,\} \{0,\}numberOfPDBs \{0,\}=.*~numberOfPDBs='{{ pdb_count }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}pdbName \{0,\}=/I s~\#\{0,\} \{0,\}pdbName \{0,\}=.*~pdbName='{{ pdb_prefix }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}templateName \{0,\}=/I s~\#\{0,\} \{0,\}templateName \{0,\}=.*~templateName=General_Purpose.dbc~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}emConfiguration \{0,\}=/I s~\#\{0,\} \{0,\}emConfiguration \{0,\}=.*~emConfiguration=NONE~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}storageType \{0,\}=/I s~\#\{0,\} \{0,\}storageType \{0,\}=.*~storageType=ASM~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}diskGroupName \{0,\}=/I s~\#\{0,\} \{0,\}diskGroupName \{0,\}=.*~diskGroupName='{{ data_diskgroup }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}recoveryGroupName \{0,\}=/I s~\#\{0,\} \{0,\}recoveryGroupName \{0,\}=.*~recoveryGroupName='{{ reco_diskgroup }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}characterSet \{0,\}=/I s~\#\{0,\} \{0,\}characterSet \{0,\}=.*~characterSet='{{ charset }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}nationalCharacterSet \{0,\}=/I s~\#\{0,\} \{0,\}nationalCharacterSet \{0,\}=.*~nationalCharacterSet='{{ ncharset }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}databaseType \{0,\}=/I s~\#\{0,\} \{0,\}databaseType \{0,\}=.*~databaseType='{{ db_type }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}automaticMemoryManagement \{0,\}=/I s~\#\{0,\} \{0,\}automaticMemoryManagement \{0,\}=.*~automaticMemoryManagement=false~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}initParams \{0,\}=/I s~\#\{0,\} \{0,\}initParams \{0,\}=.*~initParams=pga_aggregate_target='{{ pga_aggtar_bytes }}',sga_target='{{ sga_target_bytes }}',streams_pool_size=64M,use_large_pages=ONLY,db_domain='{{ db_domain }}',diagnostic_dest='{{ oracle_base }}'~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp +cp "{{ oracle_home }}/assistants/dbca/dbca.rsp" "${response_file}" -sed -i '/^\#\{0,\} \{0,\}sysPassword \{0,\}=/I s~\#\{0,\} \{0,\}sysPassword \{0,\}=.*~#sysPassword=~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}systemPassword \{0,\}=/I s~\#\{0,\} \{0,\}systemPassword \{0,\}=.*~#systemPassword=~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp -sed -i '/^\#\{0,\} \{0,\}pdbAdminPassword \{0,\}=/I s~\#\{0,\} \{0,\}pdbAdminPassword \{0,\}=.*~#pdbAdminPassword=~I' {{ swlib_unzip_path }}/dbca_{{ db_name }}.rsp +sed -i '/^\#\{0,\} \{0,\}gdbName \{0,\}=/I s~\#\{0,\} \{0,\}gdbName \{0,\}=.*~gdbName='{{ db_name }}'.'{{ db_domain }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}sid \{0,\}=/I s~\#\{0,\} \{0,\}sid \{0,\}=.*~sid='{{ db_name }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}databaseConfigType \{0,\}=/I s~\#\{0,\} \{0,\}databaseConfigType \{0,\}=.*~databaseConfigType='{{ db_config_type }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}createAsContainerDatabase \{0,\}=/I s~\#\{0,\} \{0,\}createAsContainerDatabase \{0,\}=.*~createAsContainerDatabase='{{ container_db }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}numberOfPDBs \{0,\}=/I s~\#\{0,\} \{0,\}numberOfPDBs \{0,\}=.*~numberOfPDBs='{{ pdb_count }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}pdbName \{0,\}=/I s~\#\{0,\} \{0,\}pdbName \{0,\}=.*~pdbName='{{ pdb_prefix }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}emConfiguration \{0,\}=/I s~\#\{0,\} \{0,\}emConfiguration \{0,\}=.*~emConfiguration=NONE~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}characterSet \{0,\}=/I s~\#\{0,\} \{0,\}characterSet \{0,\}=.*~characterSet='{{ charset }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}nationalCharacterSet \{0,\}=/I s~\#\{0,\} \{0,\}nationalCharacterSet \{0,\}=.*~nationalCharacterSet='{{ ncharset }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}databaseType \{0,\}=/I s~\#\{0,\} \{0,\}databaseType \{0,\}=.*~databaseType='{{ db_type }}'~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}automaticMemoryManagement \{0,\}=/I s~\#\{0,\} \{0,\}automaticMemoryManagement \{0,\}=.*~automaticMemoryManagement=false~I' "${response_file}" + +sed -i '/^\#\{0,\} \{0,\}sysPassword \{0,\}=/I s~\#\{0,\} \{0,\}sysPassword \{0,\}=.*~#sysPassword=~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}systemPassword \{0,\}=/I s~\#\{0,\} \{0,\}systemPassword \{0,\}=.*~#systemPassword=~I' "${response_file}" +sed -i '/^\#\{0,\} \{0,\}pdbAdminPassword \{0,\}=/I s~\#\{0,\} \{0,\}pdbAdminPassword \{0,\}=.*~#pdbAdminPassword=~I' "${response_file}" + +if [[ "{{ free_edition }}" == "True" ]]; then + sed -i '/^\#\{0,\} \{0,\}templateName \{0,\}=/I s~\#\{0,\} \{0,\}templateName \{0,\}=.*~templateName=FREE_Database.dbc~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}storageType \{0,\}=/I s~\#\{0,\} \{0,\}storageType \{0,\}=.*~storageType=FS~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}sampleSchema \{0,\}=/I s~\#\{0,\} \{0,\}sampleSchema \{0,\}=.*~sampleSchema=FALSE~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}datafileDestination \{0,\}=/I s~\#\{0,\} \{0,\}datafileDestination \{0,\}=.*~datafileDestination='{{ data_diskgroup }}'~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}recoveryAreaDestination \{0,\}=/I s~\#\{0,\} \{0,\}recoveryAreaDestination \{0,\}=.*~recoveryAreaDestination='{{ reco_diskgroup }}'~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}initParams \{0,\}=/I s~\#\{0,\} \{0,\}initParams \{0,\}=.*~initParams=pga_aggregate_target=400M,sga_target=1600M,streams_pool_size=64M,use_large_pages=AUTO_ONLY,db_domain='{{ db_domain }}',diagnostic_dest='{{ oracle_base }}'~I' "${response_file}" +else + sed -i '/^\#\{0,\} \{0,\}templateName \{0,\}=/I s~\#\{0,\} \{0,\}templateName \{0,\}=.*~templateName=General_Purpose.dbc~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}storageType \{0,\}=/I s~\#\{0,\} \{0,\}storageType \{0,\}=.*~storageType=ASM~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}diskGroupName \{0,\}=/I s~\#\{0,\} \{0,\}diskGroupName \{0,\}=.*~diskGroupName='{{ data_diskgroup }}'~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}recoveryGroupName \{0,\}=/I s~\#\{0,\} \{0,\}recoveryGroupName \{0,\}=.*~recoveryGroupName='{{ reco_diskgroup }}'~I' "${response_file}" + sed -i '/^\#\{0,\} \{0,\}initParams \{0,\}=/I s~\#\{0,\} \{0,\}initParams \{0,\}=.*~initParams=pga_aggregate_target='{{ pga_aggtar_bytes }}',sga_target='{{ sga_target_bytes }}',streams_pool_size=64M,use_large_pages=ONLY,db_domain='{{ db_domain }}',diagnostic_dest='{{ oracle_base }}'~I' "${response_file}" +fi diff --git a/roles/lsnr-create/tasks/main.yml b/roles/lsnr-create/tasks/main.yml index 9d8bf1b59..754e613b1 100644 --- a/roles/lsnr-create/tasks/main.yml +++ b/roles/lsnr-create/tasks/main.yml @@ -55,7 +55,7 @@ when: create_listener tags: lsnr-create -- name: Create listener +- name: Create listener via srvctl become: yes become_user: "{{ grid_user }}" shell: | @@ -65,7 +65,11 @@ srvctl config listener -l {{ listener_name }} srvctl status listener -l {{ listener_name }} register: lsnr_output - when: create_listener and lsnr_port_check.stdout == "0" and lsnr_name_check.stdout == "0" + when: + - create_listener + - lsnr_port_check.stdout == "0" + - lsnr_name_check.stdout == "0" + - not free_edition tags: lsnr-create - name: Listener creation output @@ -74,5 +78,38 @@ - "{{ lsnr_output.cmd }}" - "{{ lsnr_output.stdout_lines }}" #verbosity: 1 - when: create_listener and lsnr_port_check.stdout == "0" and lsnr_name_check.stdout == "0" + when: lsnr_output.cmd is defined + tags: lsnr-create + +- name: Create listener via netca + become: yes + become_user: "{{ oracle_user }}" + shell: | + set -o pipefail + {{ oracle_home }}/bin/netca \ + /orahome {{ oracle_home }} \ + /instype typical \ + /inscomp client,oraclenet,javavm,server,ano \ + /insprtcl tcp \ + /cfg local \ + /authadp NO_VALUE \ + /responseFile {{ oracle_home }}/network/install/netca_typ.rsp \ + /silent \ + /listenerparameters DEFAULT_SERVICE={{ oracle_sid }} \ + /lisport {{ listener_port }} + register: lsnr_output_netca + when: + - create_listener + - lsnr_port_check.stdout == "0" + - lsnr_name_check.stdout == "0" + - free_edition + tags: lsnr-create + +- name: Listener creation output from netca + debug: + msg: + - "{{ lsnr_output_netca.cmd }}" + - "{{ lsnr_output_netca.stdout_lines }}" + #verbosity: 1 + when: lsnr_output_netca.cmd is defined tags: lsnr-create diff --git a/roles/ora-host/tasks/main.yml b/roles/ora-host/tasks/main.yml index fd65bec1b..1831d97bf 100644 --- a/roles/ora-host/tasks/main.yml +++ b/roles/ora-host/tasks/main.yml @@ -165,9 +165,7 @@ name: "{{ item.group }}" gid: "{{ item.gid }}" state: present - with_items: - - "{{ oracle_groups }}" - - "{{ asm_groups }}" + with_items: "{{ oracle_groups if free_edition else oracle_groups + asm_groups }}" tags: os-groups - name: Add OS users @@ -187,6 +185,7 @@ with_items: - "{{ asm_groups }}" - "{{ extra_asm_groups }}" + when: not free_edition tags: os-users,os-groups - name: Add necessary groups to the oracle user @@ -194,9 +193,7 @@ name: "{{ oracle_user }}" groups: "{{ item.group }}" append: yes - with_items: - - "{{ oracle_groups }}" - - "{{ extra_oracle_groups }}" + with_items: "{{ oracle_groups if free_edition else oracle_groups + extra_oracle_groups }}" tags: os-users,os-groups - name: Add sysctl entries @@ -209,8 +206,8 @@ - "{{ sysctl_entries }}" tags: sysctl -# Setting vm.hugetlb_shm_group to the ID of the "oinstall" group to allow its members to create -# SysV shared memory segment using hugetlb page. +# Setting vm.hugetlb_shm_group to the ID of the "oinstall" group to allow its members to create +# SysV shared memory segment using hugetlb page. # By default only the root user has permissions to create shared memory segments. # This is needed to prevent the occurrence of "ORA-27125: unable to create shared memory segment" error. - name: Set hugetlb_shm_group to the ID of the oinstall group @@ -242,7 +239,7 @@ owner: "{{ item.owner }}" group: "{{ item.group }}" mode: "{{ item.mode }}" - with_items: "{{ oracle_dirs }}" + with_items: "{{ oracle_dirs + fs_dirs if free_edition else oracle_dirs + grid_dirs }}" tags: os-dirs - name: Create backup directory @@ -258,7 +255,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,7 +305,8 @@ dest: "/home/{{ grid_user }}/.bash_profile" marker: "# {mark} Oracle Grid Infrastructure Settings:" backup: yes - when: role_separation|bool + when: + - role_separation|bool tags: os-users - name: (asmlib) | ASM device managment via asmlib or udev? @@ -393,8 +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" + when: "'mapper' in item.1.blk_device" with_subelements: - "{{ asm_disks }}" - disks 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..054a4b34c 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 + - not free_edition + 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 + - free_edition 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..0eb74f28a 100644 --- a/roles/swlib/tasks/gcscopy.yml +++ b/roles/swlib/tasks/gcscopy.yml @@ -23,14 +23,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: - "{{ 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 changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -48,7 +50,8 @@ executable: /bin/bash with_items: - "{{ gi_patches }}" - when: item.release == oracle_rel + when: + - item.release == oracle_rel changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -65,7 +68,9 @@ executable: /bin/bash with_items: - "{{ opatch_patches }}" - when: item.release == oracle_ver and oracle_rel != "base" + when: + - item.release == oracle_ver + - oracle_rel != "base" changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -79,13 +84,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 + - not free_edition changed_when: "'Date Time Name' not in shell_result.stdout" delegate_to: 127.0.0.1 @@ -103,6 +111,29 @@ executable: /bin/bash with_items: - "{{ rdbms_patches }}" - when: item.release == oracle_rel + when: + - item.release == oracle_rel 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 + - free_edition + changed_when: "'File copied' in shell_result.stdout" + delegate_to: 127.0.0.1 diff --git a/roles/validation-scripts/defaults/main.yml b/roles/validation-scripts/defaults/main.yml index 3e71e39c9..8113cdcab 100644 --- a/roles/validation-scripts/defaults/main.yml +++ b/roles/validation-scripts/defaults/main.yml @@ -13,7 +13,9 @@ # limitations under the License. --- -script_list: +cluster_scripts: - asm_disks.sh - crs_check.sh - cluvfy_checks.sh + +common_scripts: [] diff --git a/roles/validation-scripts/tasks/main.yml b/roles/validation-scripts/tasks/main.yml index 49b84e610..331d5842f 100644 --- a/roles/validation-scripts/tasks/main.yml +++ b/roles/validation-scripts/tasks/main.yml @@ -13,6 +13,11 @@ # limitations under the License. --- +- name: Build script list + set_fact: + script_list: "{{ common_scripts + (cluster_scripts if not free_edition else []) }}" + tags: validation-scripts + - name: Copy validation scripts to server template: src: "{{ item }}.j2"