diff --git a/OracleDatabase/SingleInstance/COPYRIGHT b/OracleDatabase/SingleInstance/COPYRIGHT index add69dcb73..384e0d0a32 100644 --- a/OracleDatabase/SingleInstance/COPYRIGHT +++ b/OracleDatabase/SingleInstance/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (c) 1982 - 2026, Oracle Corporation. All rights reserved. +Copyright (c) 1982 - 2026, Oracle Corporation. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/OracleDatabase/SingleInstance/FAQ.md b/OracleDatabase/SingleInstance/FAQ.md index 5768a37698..6e89865dfb 100644 --- a/OracleDatabase/SingleInstance/FAQ.md +++ b/OracleDatabase/SingleInstance/FAQ.md @@ -14,7 +14,7 @@ An example would be: `docker run ... -e TZ="Europe/Vienna" oracle/database:12.2. ## Can I run Oracle Database containers on Apple M1 (Arm) devices? -Oracle Database 19c Enterprise Edition and 26ai Free Edition are now supported on ARM64 platforms. You will have to provide the installation binaries of [Oracle Database 19c](https://www.oracle.com/database/technologies/oracle19c-linux-arm64-downloads.html) and place them in the `dockerfiles/19.3.0` folder before running the `buildContainerImage.sh` script. +Oracle Database 19c Enterprise Edition and 26ai Free Edition are now supported on ARM64 platforms. You will have to provide the installation binaries of [Oracle Database 19c](https://www.oracle.com/database/technologies/oracle19c-linux-arm64-downloads.html) and place them in the `containerfiles/19.3.0` folder before running the `buildContainerImage.sh` script. ## checkSpace.sh: ERROR - There is not enough space available in the container @@ -48,6 +48,68 @@ podman unshare chown 54321:54321 ~/data/my_db Last but not least, if SELinux is enabled, the mapped folder should be properly labeled. If you encounter SELinux permission issues, you can add the `:Z` flag to the bind mounts. +### Rootless Podman: bind-mount startup failures + +When a rootless Podman container fails while expanding the prebuilt database and +the log contains errors such as `Cannot utime`, `Cannot change mode`, or +`Permission denied`, check both the host directory ownership and the Podman +storage configuration. The database image is not necessarily the cause of the +failure. + +Use either rootless Podman or rootful Podman consistently for a data directory. +Do not use `sudo podman` to create or modify a directory that will later be +used by rootless `podman`. + +The following example is POSIX-shell syntax. Only move the old directory if its +database contents are disposable or backed up: + +```shell +HOST_DATA_ROOT=/path/to/containers +cd "$HOST_DATA_ROOT" +mv primdb1 "primdb1.bak.$(date +%Y%m%d%H%M%S)" +mkdir -p primdb1 +chmod 750 primdb1 +podman unshare chown -R 54321:54321 "$HOST_DATA_ROOT/primdb1" +podman unshare stat -c '%u:%g %a %n' "$HOST_DATA_ROOT/primdb1" +``` + +The `chown` must be run through `podman unshare`: container UID 54321 is +normally represented by a subordinate host UID, not by host UID 54321. The +rootless user must have suitable ranges in `/etc/subuid` and `/etc/subgid`. +If the existing data must be retained, use a new directory and make a +database-aware backup or copy instead of deleting or blindly changing the old +directory. + +Rootless overlay storage also requires a mount program when `force_mask` is +configured. In the rootless user's `~/.config/containers/storage.conf`, use +the installed `fuse-overlayfs` path and do not enable `force_mask` when it +masks the modes required by the database files: + +```toml +[storage.options.overlay] +mount_program = "/bin/fuse-overlayfs" +# force_mask = "700" +``` + +An active `force_mask = "700"` can cause listener and database permission +errors, including `TNS-12546` and `ORA-49801`, even after the bind directory +ownership has been corrected. Confirm the effective rootless configuration with +`podman info --debug`; it reports the user storage configuration, graph options, +and whether SELinux is enabled. + +For persistent database data, a named volume is another option and avoids most +host bind-mount UID and labeling issues: + +```shell +podman volume create oracle-data +podman run ... -v oracle-data:/opt/oracle/oradata ... +``` + +On an SELinux-enabled host, apply the documented bind-mount labeling (usually +`:Z`) in addition to the ownership steps above. A host with SELinux disabled +does not need an SELinux relabel; it can still fail because of rootless UID +mapping, stale ownership, or `force_mask`. + ## ORA-00600: internal error code, arguments: [pesldl03_MMap: errno 1 errmsg Operation not permitted], [], [], [], [], [], [], [], [], [], [], [] This error happens if you try to use native compilation for PL/SQL but haven't assigned `exec` rights to `/dev/shm`. diff --git a/OracleDatabase/SingleInstance/README.md b/OracleDatabase/SingleInstance/README.md index 914f443cde..55facfdbc5 100644 --- a/OracleDatabase/SingleInstance/README.md +++ b/OracleDatabase/SingleInstance/README.md @@ -49,14 +49,14 @@ The `buildContainerImage.sh` script is just a utility shell script that performs ### Building Oracle Database container images -**IMPORTANT:** You will have to provide the installation binaries of Oracle Database (except for Oracle Database 21c XE and 26ai Free) and put them into the `dockerfiles/` folder. +**IMPORTANT:** For versions before 19.3.0, put the installation binaries in `dockerfiles/`. For 19.3.0 and later, use `containerfiles/`. You only need to provide the binaries for the edition you are going to install. The binaries can be downloaded from the [Oracle Technology Network](http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html), make sure you use the linux link: *Linux x86-64*. The needed file is named *linuxx64_\_database.zip*. -**Linux ARM64 Support:** Oracle Database 19c Enterprise Edition and 26ai Free Edition are now supported on ARM64 platforms. You will have to provide the installation binaries of [Oracle Database 19c](https://www.oracle.com/database/technologies/oracle19c-linux-arm64-downloads.html) and put them into the dockerfiles/19.3.0 folder. The needed file is named *LINUX.ARM64_1919000_db_home.zip*. +**Linux ARM64 Support:** Oracle Database 19c Enterprise Edition and 26ai Free Edition are now supported on ARM64 platforms. You will have to provide the installation binaries of [Oracle Database 19c](https://www.oracle.com/database/technologies/oracle19c-linux-arm64-downloads.html) and put them into the `containerfiles/19.3.0` folder. The needed file is named *LINUX.ARM64_1919000_db_home.zip*. You also have to make sure to have internet connectivity for yum. Note that you must not uncompress the binaries. The script will handle that for you and fail if you uncompress them manually! -Before you build the image make sure that you have provided the installation binaries and put them into the right folder. Once you have chosen which edition and version you want to build an image of, go into the **dockerfiles** folder and run the **buildContainerImage.sh** script: +Before you build the image make sure that you have provided the installation binaries and put them into the right folder. Run the **buildContainerImage.sh** script from the `dockerfiles` directory; it selects the legacy `dockerfiles//Dockerfile` for versions before 19.3.0 and the modern `containerfiles//Containerfile` for 19.3.0 and later. [oracle@localhost dockerfiles]$ ./buildContainerImage.sh -h @@ -126,7 +126,7 @@ Option 2: Download from a web URL that does not require authentication: -t oracle/database:19.3.0-ee \ -o '--build-arg BACKUP_MODULE_URL=' -Option 3: Install from a local file system location. Place the RPM under the selected version directory and pass its relative path using `BACKUP_MODULE_LOCAL_FILE`. For example, if the RPM is stored as `dockerfiles/23.26.0/backup-modules/bck2cloud.rpm`: +Option 3: Install from a local file system location. Place the RPM under the selected version directory and pass its relative path using `BACKUP_MODULE_LOCAL_FILE`. For example, if the RPM is stored as `containerfiles/23.26.0/backup-modules/bck2cloud.rpm`: ./buildContainerImage.sh \ -v 23.26.0 \ @@ -149,15 +149,19 @@ Patched container images can now be built by specifying the parameter -p. Downlo #### Building the container images using Podman -Building Oracle Database container images using Podman is similar to Docker. Some additional environment variables are required to be set for proper functioning. The description is as follows: +Building Oracle Database container images using Podman is similar to Docker. The build scripts automatically use Docker image format for Podman builds so that the `HEALTHCHECK` metadata is preserved. For rootless Linux builds, set the following environment variable: -* `export BUILDAH_FORMAT=docker` (Required to support `HEALTHCHECK` specified in the Dockerfile) * `export BUILDAH_ISOLATION=chroot` (Required while building the container image in rootless mode) -After setting these environment variables, the container image can be built using `buildContainerImage.sh` script as follows: +After setting this environment variable, the container image can be built using `buildContainerImage.sh` script as follows: ./buildContainerImage.sh -e -v +RPM provenance is always recorded under `/usr/share/oracle/image-metadata/rpms`. +Inspect it with: + + podman run --rm --entrypoint /bin/sh IMAGE -c \ + 'ls -l /usr/share/oracle/image-metadata/rpms && cat /usr/share/oracle/image-metadata/rpms/*.txt' ### Running Oracle Database in a container #### Running Oracle Database Enterprise and Standard Edition 2 in a container @@ -180,6 +184,7 @@ To run your Oracle Database image use the `podman run` command as follows: -e ENABLE_FORCE_LOGGING=true \ -e ENABLE_TCPS=true \ -e TRUE_CACHE=true \ + -e TDE_ENABLED=true \ -e TDE_WALLET_PWD= \ -e PRIMARY_DB_PWD_FILE= \ -e PRIMARY_DB_TDE_WALLET= \ @@ -240,8 +245,11 @@ To run your Oracle Database image use the `podman run` command as follows: -e TRUE_CACHE: To configure Oracle True Cache instance. Supported from Oracle 26ai onwards. + -e TDE_ENABLED: + Set to 'true' to configure TDE during Enterprise/SE2 database creation. + Use together with TDE_WALLET_PWD or the tde_wallet_pwd Podman secret. -e TDE_WALLET_PWD: - Password for TDE wallet to configure TDE. + Password for the TDE wallet when TDE_ENABLED=true. -e PRIMARY_DB_PWD_FILE: (Required if TRUE_CACHE=true) -e PRIMARY_DB_TDE_WALLET: @@ -262,6 +270,9 @@ To run your Oracle Database image use the `podman run` command as follows: Optional: A volume with custom scripts to be run after database startup. For further details see the "Running scripts after setup and on startup" section below. +For rootless Podman volume permissions and storage configuration, see the +[SingleInstance FAQ](FAQ.md#rootless-podman-bind-mount-startup-failures). + Once the container has been started and the database created you can connect to it just like to any other database: sqlplus sys/@//localhost:1521/ as sysdba @@ -465,9 +476,9 @@ The ORACLE_SID for Oracle Database 26ai Free is always `FREE` and cannot be chan | `-p` | Map listener `1521`, OEM Express `5500`, and TCPS `2484` when TCPS is enabled | Map listener `1521`; OEM Express `5500` is exposed by the image | Maps host ports to container ports. | Optional, required for host access | | `--ulimit` | Recommended for Enterprise/SE2 database containers | Not shown in the Free example | Resource limits. Set according to Oracle Database documentation and host policy. | Recommended for Enterprise/SE2 | | `ORACLE_SID` | Supported; default is `ORCLCDB` | Do not set; Free always uses `FREE` | Oracle Database SID. | Optional for Enterprise/SE2, not used for Free | -| `ORACLE_PDB` | Supported; default is `ORCLPDB1` | Do not set; Free uses `FREEPDB1` | Oracle Database PDB name. | Optional for Enterprise/SE2, not used for Free | +| `ORACLE_PDB` | Supported; default is `ORCLPDB1` | Free uses `FREEPDB1`, including Free prebuilt images | Oracle Database PDB name. | Optional for Enterprise/SE2; not used for Free | | `ORACLE_PWD` | Supported; auto-generated if omitted | Supported; auto-generated if omitted | SYS, SYSTEM, and PDBADMIN password. Podman secrets can provide this through `oracle_pwd`. | Optional | -| `ORACLE_CHARACTERSET` | Supported; default is `AL32UTF8` | Supported; default is `AL32UTF8` | Character set used when creating the database. | Optional | +| `ORACLE_CHARACTERSET` | Supported; creation defaults to `AL32UTF8` | Creation defaults to `AL32UTF8`; Free prebuilt images retain the current character set if omitted | Character set used when creating the database or converting a Free prebuilt PDB. | Optional | | `INIT_SGA_SIZE` | Supported from 19.3 onward | Not shown in the Free example | Total SGA memory in MB used during first database creation. | Optional | | `INIT_PGA_SIZE` | Supported from 19.3 onward | Not shown in the Free example | Target aggregate PGA memory in MB used during first database creation. | Optional | | `INIT_CPU_COUNT` | Supported | Not shown in the Free example | Sets the `CPU_COUNT` initialization parameter. | Optional | @@ -478,9 +489,10 @@ The ORACLE_SID for Oracle Database 26ai Free is always `FREE` and cannot be chan | `ENABLE_FORCE_LOGGING` | Supported from 26ai onward | Not shown in the Free example | Enables force logging during first database creation. | Optional | | `ENABLE_TCPS` | Supported from 19.3 onward | Not shown in the Free example | Enables TCPS listener endpoint on container port `2484`. | Optional | | `TCPS_CERTS_LOCATION` | Supported from 19.3 onward | Not shown in the Free example | In-container location of user-provided `cert.crt` and `client.key` files for TCPS. | Optional | +| `TDE_ENABLED` | Supported for TDE wallet configuration | Not shown in the Free example | Enables TDE configuration during Enterprise/SE2 database creation. Set this to `true` together with `TDE_WALLET_PWD` (or the `tde_wallet_pwd` Podman secret). | Conditional for TDE | | `CONFIGURE_TDE` | Not shown in the Enterprise/SE2 example | Supported from 26ai onward | Enables TDE configuration for Free image database creation. | Optional | | `ENCRYPT_TABLESPACES` | Not shown in the Enterprise/SE2 example | Supported | Tablespace encryption list. Leave empty for user tablespace only, set `ALL`, or use entries such as `SYSTEM:true,SYSAUX:false`. | Optional | -| `TDE_WALLET_PWD` | Supported for TDE wallet configuration | Not shown in the Free example | Password for TDE wallet configuration. Can also be provided through the `tde_wallet_pwd` Podman secret. | Conditional for TDE | +| `TDE_WALLET_PWD` | Used when `TDE_ENABLED=true` | Not shown in the Free example | Password for TDE wallet configuration. Can also be provided through the `tde_wallet_pwd` Podman secret. | Conditional for TDE | | `TRUE_CACHE` | Supported from 26ai onward when running a True Cache container | Use the True Cache extension image flow for Free True Cache | Marks the container as a True Cache host. For complete primary plus True Cache Podman setup, use `extensions/truecache/README.md`. | Conditional for True Cache | | `PRIMARY_DB_CONN_STR` | Required when `TRUE_CACHE=true` | Required in Free True Cache extension flow | Primary database connection string in `:/` format. | Conditional for True Cache | | `PRIMARY_DB_NAME` | Optional when the primary DB_NAME differs from the service name | Optional when the primary DB_NAME differs from the service name | Primary source DB_NAME override. | Optional | @@ -565,7 +577,7 @@ To containerize an on-premise database, please follow the steps mentioned below: cd $ORACLE_HOME && ./runInstaller -silent -createGoldImage -destinationLocation '' -* The gold image created in the step above will have the name like `db_home_2022-03-25_12-43-21PM.zip`. Copy this gold image to the `OracleDatabase/SingleInstance/dockerfiles/` directory. The **version** would be the base version of the gold image, e.g. 19.3.0. +* The gold image created in the step above will have the name like `db_home_2022-03-25_12-43-21PM.zip`. Copy this gold image to `OracleDatabase/SingleInstance/containerfiles/` for 19.3.0 and later, or `dockerfiles/` for older releases. * Create the container image using this gold image by the following sample command: ./buildContainerImage.sh -i -e -v 19.3.0 -t oracle/database:19-onprem -o '--build-arg INSTALL_FILE_1=db_home_2022-03-25_12-43-21PM.zip' diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/Checksum.ee b/OracleDatabase/SingleInstance/containerfiles/19.3.0/Checksum.ee similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/Checksum.ee rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/Checksum.ee diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/Checksum.ee.arm64 b/OracleDatabase/SingleInstance/containerfiles/19.3.0/Checksum.ee.arm64 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/Checksum.ee.arm64 rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/Checksum.ee.arm64 diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/Checksum.se2 b/OracleDatabase/SingleInstance/containerfiles/19.3.0/Checksum.se2 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/Checksum.se2 rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/Checksum.se2 diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/Dockerfile b/OracleDatabase/SingleInstance/containerfiles/19.3.0/Containerfile similarity index 84% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/Dockerfile rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/Containerfile index 43eeb165d5..35472ed3fe 100644 --- a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/Dockerfile +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/Containerfile @@ -1,12 +1,13 @@ # syntax=docker/dockerfile:1.7 +# hadolint global ignore=DL4006 # LICENSE UPL 1.0 # # Copyright (c) 2018, 2026 Oracle and/or its affiliates. # -# ORACLE DOCKERFILES PROJECT +# ORACLE CONTAINERFILES PROJECT # -------------------------- -# This is the Dockerfile for Oracle Database 19c -# +# This is the Containerfile for Oracle Database 19c +# # REQUIRED FILES TO BUILD THIS IMAGE # ---------------------------------- # (1) db_home.zip @@ -15,15 +16,19 @@ # # HOW TO BUILD THIS IMAGE # ----------------------- -# Put all downloaded files in the same directory as this Dockerfile -# Run: -# $ docker build -t oracle/database:19.3.0-${EDITION} . +# Put all downloaded files in the same directory as this Containerfile +# Run: +# $ podman build -t oracle/database:19.3.0-${EDITION} . # # Pull base image # --------------- ARG BASE_IMAGE=oraclelinux:9 # hadolint ignore=DL3006 FROM ${BASE_IMAGE} as base +RUN \ + mkdir -p /usr/share/oracle/image-metadata/rpms && \ + rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /usr/share/oracle/image-metadata/rpms/base-image-rpms.txt && \ + rpm -qa --qf '%{NAME}\n' | sort -u > /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt; # Labels # ------ @@ -195,13 +200,28 @@ RUN chmod ug+x "$INSTALL_DIR"/*.sh && \ ############################################# FROM base +USER root + +RUN \ + rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /usr/share/oracle/image-metadata/rpms/image-rpms.txt && \ + rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /tmp/image-rpm-details && \ + if [ -f /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt ]; then \ + awk -F '\t' 'NR==FNR {base[$1]=1; next} !($1 in base) {print $1 "-" $2}' /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt /tmp/image-rpm-details > /usr/share/oracle/image-metadata/rpms/image-added-rpms.txt; \ + else \ + cp /usr/share/oracle/image-metadata/rpms/image-rpms.txt /usr/share/oracle/image-metadata/rpms/image-added-rpms.txt; \ + fi && \ + rm -f /tmp/image-rpm-details; USER oracle COPY --chown=oracle:dba --from=builder $ORACLE_BASE $ORACLE_BASE USER root RUN "$ORACLE_BASE"/oraInventory/orainstRoot.sh && \ - "$ORACLE_HOME"/root.sh + "$ORACLE_HOME"/root.sh && \ + setpriv --reuid=54321 --regid=54321 --init-groups env HOME=/home/oracle \ + "$ORACLE_HOME"/oui/bin/runInstaller -silent -ignoreSysPrereqs -attachHome \ + ORACLE_HOME="$ORACLE_HOME" ORACLE_HOME_NAME=OraDB19Home1 \ + -invPtrLoc /etc/oraInst.loc USER oracle WORKDIR /home/oracle @@ -213,5 +233,5 @@ RUN echo 'ORACLE_SID=${ORACLE_SID:-ORCLCDB}; export ORACLE_SID=${ORACLE_SID^^}' HEALTHCHECK --interval=1m --start-period=5m --timeout=30s \ CMD "$SCRIPT_BASE_DIR/$CHECK_DB_FILE" >/dev/null || exit 1 -# Define default command to start Oracle Database. +# Define default command to start Oracle Database. CMD [ "/bin/bash", "-c", "exec $SCRIPT_BASE_DIR/$RUN_FILE" ] diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/checkDBStatus.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/checkDBStatus.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/checkDBStatus.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/checkDBStatus.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/checkSpace.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/checkSpace.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/checkSpace.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/checkSpace.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/cloneDBObjBkup.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/cloneDBObjBkup.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/cloneDBObjBkup.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/cloneDBObjBkup.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/configDataguardPrereqs.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/configDataguardPrereqs.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/configDataguardPrereqs.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/configDataguardPrereqs.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/configTcps.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/configTcps.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/configTcps.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/configTcps.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/createDB.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/createDB.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/createDB.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/createDB.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/createObserver.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/createObserver.sh old mode 100644 new mode 100755 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/createObserver.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/createObserver.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/db_inst.rsp b/OracleDatabase/SingleInstance/containerfiles/19.3.0/db_inst.rsp similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/db_inst.rsp rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/db_inst.rsp diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/dbca.rsp.tmpl b/OracleDatabase/SingleInstance/containerfiles/19.3.0/dbca.rsp.tmpl similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/dbca.rsp.tmpl rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/dbca.rsp.tmpl diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/installDBBinaries.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/installDBBinaries.sh similarity index 98% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/installDBBinaries.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/installDBBinaries.sh index 42426f2424..efadcf41c7 100755 --- a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/installDBBinaries.sh +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/installDBBinaries.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2166,SC2164 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/license.txt b/OracleDatabase/SingleInstance/containerfiles/19.3.0/license.txt similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/license.txt rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/license.txt diff --git a/OracleDatabase/SingleInstance/containerfiles/19.3.0/managePDB.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/managePDB.sh new file mode 100755 index 0000000000..701b883a96 --- /dev/null +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/managePDB.sh @@ -0,0 +1,134 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 1982-2026 Oracle and/or its affiliates. All rights reserved. +# Since: Sep, 2026 +# Author: paramdeep.saini@oracle.com +# Description: Apply supported PDB-level database parameters. + +set -euo pipefail + +SQLPLUS_BIN="${SQLPLUS_BIN:-sqlplus}" +OPERATION="" +PDB_NAME="" +declare -a PARAMETERS=() + +function usage() { + cat <<'EOF' +Usage: + managePDB.sh --operation apply-parameters --pdb --parameter [--parameter ...] + +Options: + --operation PDB operation to execute. Currently: apply-parameters. + --pdb Target PDB name. + --parameter PDB parameter assignment. Repeat for multiple parameters. + --help Show this help. + +Environment: + SQLPLUS_BIN SQL*Plus executable (default: sqlplus). +EOF +} + +function die() { + echo "ERROR: $*" >&2 + exit 1 +} + +function require_option_value() { + [[ $# -ge 2 && -n "$2" ]] || die "Missing value for $1" +} + +function validate_pdb_name() { + [[ "$1" =~ ^[[:alpha:]][[:alnum:]_$#]*$ ]] || + die "Invalid PDB name: $1" +} + +function add_parameter() { + local assignment="$1" + local name value existing + + [[ "$assignment" == *=* ]] || die "Parameter must use NAME=VALUE syntax: $assignment" + name="${assignment%%=*}" + value="${assignment#*=}" + name="$(printf '%s' "$name" | tr '[:lower:]' '[:upper:]')" + value="$(printf '%s' "$value" | tr '[:lower:]' '[:upper:]')" + + [[ "$name" =~ ^[[:alpha:]_][[:alnum:]_$#]*$ ]] || + die "Invalid parameter name: $name" + [[ -n "$value" ]] || die "Parameter value cannot be empty: $name" + + for existing in "${PARAMETERS[@]}"; do + [[ "${existing%%=*}" != "$name" ]] || die "Parameter specified more than once: $name" + done + PARAMETERS+=("$name=$value") +} + +function apply_max_string_size() { + local value="$1" + + case "$value" in + STANDARD|EXTENDED) ;; + *) die "MAX_STRING_SIZE must be STANDARD or EXTENDED" ;; + esac + + "$SQLPLUS_BIN" -s "/ as sysdba" < 0 )) || die "At least one --parameter is required" + +for parameter in "${PARAMETERS[@]}"; do + apply_parameter "$parameter" +done diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/manageTnsAliases.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/manageTnsAliases.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/manageTnsAliases.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/manageTnsAliases.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/relinkOracleBinary.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/relinkOracleBinary.sh old mode 100644 new mode 100755 similarity index 98% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/relinkOracleBinary.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/relinkOracleBinary.sh index 15629d5d67..4c9b3271ee --- a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/relinkOracleBinary.sh +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/relinkOracleBinary.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2046 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/runOracle.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/runOracle.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/runOracle.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/runOracle.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/runUserScripts.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/runUserScripts.sh old mode 100644 new mode 100755 similarity index 97% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/runUserScripts.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/runUserScripts.sh index 240c1fa537..86a980ec55 --- a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/runUserScripts.sh +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/runUserScripts.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/setPassword.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/setPassword.sh similarity index 97% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/setPassword.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/setPassword.sh index 79ce7df2fc..358b239480 100755 --- a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/setPassword.sh +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/setPassword.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2010,SC2034 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. @@ -28,4 +29,3 @@ sqlplus / as sysdba << EOF ALTER USER PDBADMIN IDENTIFIED BY "$ORACLE_PWD"; exit; EOF - diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/setupLinuxEnv.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/setupLinuxEnv.sh similarity index 74% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/setupLinuxEnv.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/setupLinuxEnv.sh index b1257f97f9..c1a71b9656 100755 --- a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/setupLinuxEnv.sh +++ b/OracleDatabase/SingleInstance/containerfiles/19.3.0/setupLinuxEnv.sh @@ -10,14 +10,6 @@ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. # -## Use OCI yum repos on OCI instead of public yum -region=$(curl --noproxy '*' -sfm 3 -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/instance/ | sed -nE 's/^ *"regionIdentifier": "([^"]+)".*/\1/p') -if [ -n "$region" ]; then - echo "Detected OCI Region: $region" - for proxy in $(printenv | grep -i _proxy | cut -d= -f1); do unset $proxy; done - echo "-$region" > /etc/yum/vars/ociregion -fi - # Setup filesystem and oracle user # Adjust file permissions, go to /opt/oracle as user 'oracle' to proceed with Oracle installation # ------------------------------------------------------------ @@ -38,4 +30,4 @@ chown -R oracle:dba "$ORACLE_BASE" if [ ! -f '/usr/bin/python' ] && [ -f '/usr/bin/python3' ]; then alternatives --install /usr/bin/python python /usr/bin/python3 1; -fi \ No newline at end of file +fi diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/shutDown.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/shutDown.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/shutDown.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/shutDown.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/startDB.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/startDB.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/startDB.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/startDB.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/tdeSecretUtils.sh b/OracleDatabase/SingleInstance/containerfiles/19.3.0/tdeSecretUtils.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/tdeSecretUtils.sh rename to OracleDatabase/SingleInstance/containerfiles/19.3.0/tdeSecretUtils.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/Checksum.ee b/OracleDatabase/SingleInstance/containerfiles/21.3.0/Checksum.ee similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/Checksum.ee rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/Checksum.ee diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/Checksum.se2 b/OracleDatabase/SingleInstance/containerfiles/21.3.0/Checksum.se2 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/Checksum.se2 rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/Checksum.se2 diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile b/OracleDatabase/SingleInstance/containerfiles/21.3.0/Containerfile similarity index 81% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/Containerfile index ce6ee2c841..188bafab3f 100644 --- a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile +++ b/OracleDatabase/SingleInstance/containerfiles/21.3.0/Containerfile @@ -1,12 +1,12 @@ # LICENSE UPL 1.0 -# hadolint global ignore=SC2086,SC2016,DL3025 +# hadolint global ignore=SC2086,SC2016,DL3025,DL4006 # # Copyright (c) 2018, 2026 Oracle and/or its affiliates. # -# ORACLE DOCKERFILES PROJECT +# ORACLE CONTAINERFILES PROJECT # -------------------------- -# This is the Dockerfile for Oracle Database 21c -# +# This is the Containerfile for Oracle Database 21c +# # REQUIRED FILES TO BUILD THIS IMAGE # ---------------------------------- # (1) LINUX.X64_213000_db_home.zip @@ -15,15 +15,19 @@ # # HOW TO BUILD THIS IMAGE # ----------------------- -# Put all downloaded files in the same directory as this Dockerfile -# Run: -# $ docker build -t oracle/database:21.3.0-${EDITION} . +# Put all downloaded files in the same directory as this Containerfile +# Run: +# $ podman build -t oracle/database:21.3.0-${EDITION} . # # Pull base image # --------------- ARG BASE_IMAGE=oraclelinux:8 # hadolint ignore=DL3006 FROM ${BASE_IMAGE} as base +RUN \ + mkdir -p /usr/share/oracle/image-metadata/rpms && \ + rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /usr/share/oracle/image-metadata/rpms/base-image-rpms.txt && \ + rpm -qa --qf '%{NAME}\n' | sort -u > /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt; # Labels # ------ @@ -145,6 +149,17 @@ RUN chmod ug+x $INSTALL_DIR/*.sh && \ ############################################# FROM base +USER root + +RUN \ + rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /usr/share/oracle/image-metadata/rpms/image-rpms.txt && \ + rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /tmp/image-rpm-details && \ + if [ -f /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt ]; then \ + awk -F '\t' 'NR==FNR {base[$1]=1; next} !($1 in base) {print $1 "-" $2}' /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt /tmp/image-rpm-details > /usr/share/oracle/image-metadata/rpms/image-added-rpms.txt; \ + else \ + cp /usr/share/oracle/image-metadata/rpms/image-rpms.txt /usr/share/oracle/image-metadata/rpms/image-added-rpms.txt; \ + fi && \ + rm -f /tmp/image-rpm-details; USER oracle COPY --chown=oracle:dba --from=builder $ORACLE_BASE $ORACLE_BASE @@ -162,5 +177,5 @@ RUN echo 'ORACLE_SID=${ORACLE_SID:-ORCLCDB}; export ORACLE_SID=${ORACLE_SID^^}' HEALTHCHECK --interval=1m --start-period=5m --timeout=30s \ CMD "$SCRIPT_BASE_DIR/$CHECK_DB_FILE" >/dev/null || exit 1 -# Define default command to start Oracle Database. +# Define default command to start Oracle Database. CMD exec $SCRIPT_BASE_DIR/$RUN_FILE diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile.xe b/OracleDatabase/SingleInstance/containerfiles/21.3.0/Containerfile.xe similarity index 95% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile.xe rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/Containerfile.xe index d4ec6ca00a..009c53eda9 100644 --- a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/Dockerfile.xe +++ b/OracleDatabase/SingleInstance/containerfiles/21.3.0/Containerfile.xe @@ -2,18 +2,18 @@ # # Copyright (c) 2018, 2026 Oracle and/or its affiliates. # -# ORACLE DOCKERFILES PROJECT +# ORACLE CONTAINERFILES PROJECT # -------------------------- -# This is the Dockerfile for Oracle Database 21c Express Edition -# +# This is the Containerfile for Oracle Database 21c Express Edition +# # REQUIRED FILES TO BUILD THIS IMAGE # ---------------------------------- # None # # HOW TO BUILD THIS IMAGE # ----------------------- -# Run: -# $ docker build -t oracle/database:21.3.0-xe -f Dockerfile.xe . +# Run: +# $ podman build -t oracle/database:21.3.0-xe -f Containerfile.xe . # # # Pull base image diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/checkDBStatus.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/checkDBStatus.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/checkDBStatus.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/checkDBStatus.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/checkSpace.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/checkSpace.sh old mode 100644 new mode 100755 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/checkSpace.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/checkSpace.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/configTcps.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/configTcps.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/configTcps.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/configTcps.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/createDB.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/createDB.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/createDB.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/createDB.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/createObserver.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/createObserver.sh old mode 100644 new mode 100755 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/createObserver.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/createObserver.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/db_inst.rsp b/OracleDatabase/SingleInstance/containerfiles/21.3.0/db_inst.rsp similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/db_inst.rsp rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/db_inst.rsp diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/dbca.rsp.tmpl b/OracleDatabase/SingleInstance/containerfiles/21.3.0/dbca.rsp.tmpl similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/dbca.rsp.tmpl rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/dbca.rsp.tmpl diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/installDBBinaries.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/installDBBinaries.sh old mode 100644 new mode 100755 similarity index 98% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/installDBBinaries.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/installDBBinaries.sh index 415ee8455c..7e60eee779 --- a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/installDBBinaries.sh +++ b/OracleDatabase/SingleInstance/containerfiles/21.3.0/installDBBinaries.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2164 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/license.txt b/OracleDatabase/SingleInstance/containerfiles/21.3.0/license.txt similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/license.txt rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/license.txt diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/oracle-xe-21c.conf b/OracleDatabase/SingleInstance/containerfiles/21.3.0/oracle-xe-21c.conf similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/oracle-xe-21c.conf rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/oracle-xe-21c.conf diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/relinkOracleBinary.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/relinkOracleBinary.sh old mode 100644 new mode 100755 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/relinkOracleBinary.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/relinkOracleBinary.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/runOracle.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/runOracle.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/runOracle.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/runOracle.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/runUserScripts.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/runUserScripts.sh similarity index 96% rename from OracleDatabase/SingleInstance/dockerfiles/19.3.0/runUserScripts.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/runUserScripts.sh index edc2628e52..86a980ec55 100755 --- a/OracleDatabase/SingleInstance/dockerfiles/19.3.0/runUserScripts.sh +++ b/OracleDatabase/SingleInstance/containerfiles/21.3.0/runUserScripts.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. @@ -36,4 +37,4 @@ if [ -d "$SCRIPTS_ROOT" ] && [ -n "$(ls -A "$SCRIPTS_ROOT")" ]; then echo "DONE: Executing user defined scripts" echo ""; -fi; \ No newline at end of file +fi; diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/setPassword.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/setPassword.sh old mode 100644 new mode 100755 similarity index 97% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/setPassword.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/setPassword.sh index 5c0a6fc509..84e52a7db2 --- a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/setPassword.sh +++ b/OracleDatabase/SingleInstance/containerfiles/21.3.0/setPassword.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2010,SC2034 # LICENSE UPL 1.0 # # Copyright (c) 1982-2022 Oracle and/or its affiliates. All rights reserved. @@ -28,4 +29,3 @@ sqlplus / as sysdba << EOF ALTER USER PDBADMIN IDENTIFIED BY "$ORACLE_PWD"; exit; EOF - diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/setupLinuxEnv.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/setupLinuxEnv.sh similarity index 74% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/setupLinuxEnv.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/setupLinuxEnv.sh index 9f5827ad96..99b8cbaf77 100755 --- a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/setupLinuxEnv.sh +++ b/OracleDatabase/SingleInstance/containerfiles/21.3.0/setupLinuxEnv.sh @@ -10,14 +10,6 @@ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. # -## Use OCI yum repos on OCI instead of public yum -region=$(curl --noproxy '*' -sfm 3 -H "Authorization: Bearer Oracle" http://169.254.169.254/opc/v2/instance/ | sed -nE 's/^ *"regionIdentifier": "([^"]+)".*/\1/p') -if [ -n "$region" ]; then - echo "Detected OCI Region: $region" - for proxy in $(printenv | grep -i _proxy | cut -d= -f1); do unset $proxy; done - echo "-$region" > /etc/yum/vars/ociregion -fi - # Setup filesystem and oracle user # Adjust file permissions, go to /opt/oracle as user 'oracle' to proceed with Oracle installation # ------------------------------------------------------------ @@ -29,6 +21,7 @@ ln -s "$ORACLE_BASE"/scripts /docker-entrypoint-initdb.d && \ mkdir -p "$ORACLE_BASE"/oradata /home/oracle && \ mkdir -p "$ORACLE_HOME" && \ chmod ug+x "$ORACLE_BASE"/*.sh && \ +yum update -y && \ yum -y install oracle-database-preinstall-21c openssl expect file hostname && \ rm -rf /var/cache/yum && \ ln -s "$ORACLE_BASE"/"$PWD_FILE" /home/oracle/ && \ diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/shutDown.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/shutDown.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/shutDown.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/shutDown.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/21.3.0/startDB.sh b/OracleDatabase/SingleInstance/containerfiles/21.3.0/startDB.sh old mode 100644 new mode 100755 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/21.3.0/startDB.sh rename to OracleDatabase/SingleInstance/containerfiles/21.3.0/startDB.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/Checksum.ee b/OracleDatabase/SingleInstance/containerfiles/23.26.0/Checksum.ee similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/Checksum.ee rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/Checksum.ee diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/Checksum.se2 b/OracleDatabase/SingleInstance/containerfiles/23.26.0/Checksum.se2 similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/Checksum.se2 rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/Checksum.se2 diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/Containerfile b/OracleDatabase/SingleInstance/containerfiles/23.26.0/Containerfile similarity index 86% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/Containerfile rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/Containerfile index 09f76e2853..5b9d63d810 100644 --- a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/Containerfile +++ b/OracleDatabase/SingleInstance/containerfiles/23.26.0/Containerfile @@ -1,13 +1,13 @@ # syntax=docker/dockerfile:1.7 -# hadolint global ignore=SC2086,SC2016,DL3025 +# hadolint global ignore=SC2086,SC2016,DL3025,DL4006 # LICENSE UPL 1.0 # # Copyright (c) 2018, 2026 Oracle and/or its affiliates. # -# ORACLE DOCKERFILES PROJECT +# ORACLE CONTAINERFILES PROJECT # -------------------------- # This is the Containerfile for Oracle Database 26ai -# +# # REQUIRED FILES TO BUILD THIS IMAGE # ---------------------------------- # (1) LINUX.X64_2326000_db_home.zip @@ -17,12 +17,16 @@ # HOW TO BUILD THIS IMAGE # ----------------------- # Put all downloaded files in the same directory as this Containerfile -# Run: -# $ docker build -t oracle/database:23.26.0-${EDITION} . +# Run: +# $ podman build -t oracle/database:23.26.0-${EDITION} . # # Pull base image # --------------- FROM oraclelinux:8 as base +RUN \ + mkdir -p /usr/share/oracle/image-metadata/rpms && \ + rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /usr/share/oracle/image-metadata/rpms/base-image-rpms.txt && \ + rpm -qa --qf '%{NAME}\n' | sort -u > /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt; # Labels # ------ @@ -40,7 +44,7 @@ LABEL "provider"="Oracle" "volume.setup.location2"="/docker-entrypoint-initdb.d/setup" \ "volume.startup.location1"="/opt/oracle/scripts/startup" \ "volume.startup.location2"="/docker-entrypoint-initdb.d/startup" \ - "port.listener"="1521" + "port.listener"="1521" # Argument to control removal of components not needed after db software installation ARG SLIMMING=true @@ -73,6 +77,7 @@ ENV ORACLE_BASE=/opt/oracle \ MANAGE_TNS_ALIASES="manageTnsAliases.sh" \ CONFIG_TCPS_FILE="configTcps.sh" \ TDE_SECRET_UTILS_FILE="tdeSecretUtils.sh" \ + MANAGE_PDB="managePDB.sh" \ DECRYPT_PWD_FILE="decryptPassword.sh" \ SCRIPT_BASE_DIR="/opt/oracle/scripts/base" \ SLIMMING=$SLIMMING \ @@ -104,14 +109,14 @@ ENV PATH=$ORACLE_HOME/bin:$ORACLE_HOME/python/bin:$ORACLE_HOME/OPatch/:/usr/sbin # Copy files needed during both installation and runtime # ------------- COPY $SETUP_LINUX_FILE $CHECK_SPACE_FILE $INSTALL_DIR/ -COPY $RUN_FILE $START_FILE $SHUTDOWN_FILE $CREATE_DB_FILE $CREATE_OBSERVER_FILE $CONFIG_RSP $PWD_FILE $CHECK_DB_FILE $USER_SCRIPTS_FILE $RELINK_BINARY_FILE $CONFIG_DG_PREREQS_FILE $CONFIG_TCPS_FILE $TDE_SECRET_UTILS_FILE $DECRYPT_PWD_FILE $CLONEDB_OBJBACKUP $MANAGE_TNS_ALIASES ${SCRIPT_BASE_DIR}/ +COPY $RUN_FILE $START_FILE $SHUTDOWN_FILE $CREATE_DB_FILE $CREATE_OBSERVER_FILE $CONFIG_RSP $PWD_FILE $CHECK_DB_FILE $USER_SCRIPTS_FILE $RELINK_BINARY_FILE $CONFIG_DG_PREREQS_FILE $CONFIG_TCPS_FILE $TDE_SECRET_UTILS_FILE $DECRYPT_PWD_FILE $CLONEDB_OBJBACKUP $MANAGE_TNS_ALIASES $MANAGE_PDB ${SCRIPT_BASE_DIR}/ RUN chmod ug+x $INSTALL_DIR/*.sh && \ mkdir -p "${SCRIPT_BASE_DIR}" && \ chmod ug+x "${SCRIPT_BASE_DIR}"/*.sh && \ printf '#!/bin/bash\nexec "%s/%s" "$@"\n' "$SCRIPT_BASE_DIR" "$RUN_FILE" > "$ORACLE_BASE/$RUN_FILE" && \ chmod ug+x "$ORACLE_BASE/$RUN_FILE" && \ - for script in "$START_FILE" "$SHUTDOWN_FILE" "$CREATE_DB_FILE" "$CREATE_OBSERVER_FILE" "$PWD_FILE" "$CHECK_DB_FILE" "$USER_SCRIPTS_FILE" "$RELINK_BINARY_FILE" "$CONFIG_DG_PREREQS_FILE" "$CONFIG_TCPS_FILE" "$DECRYPT_PWD_FILE" "$CLONEDB_OBJBACKUP" "$MANAGE_TNS_ALIASES"; do \ + for script in "$START_FILE" "$SHUTDOWN_FILE" "$CREATE_DB_FILE" "$CREATE_OBSERVER_FILE" "$PWD_FILE" "$CHECK_DB_FILE" "$USER_SCRIPTS_FILE" "$RELINK_BINARY_FILE" "$CONFIG_DG_PREREQS_FILE" "$CONFIG_TCPS_FILE" "$DECRYPT_PWD_FILE" "$CLONEDB_OBJBACKUP" "$MANAGE_TNS_ALIASES" "$MANAGE_PDB"; do \ ln -sf "${SCRIPT_BASE_DIR}/$script" "$ORACLE_BASE/$script"; \ done && \ sync && \ @@ -193,6 +198,17 @@ RUN chmod ug+x $INSTALL_DIR/*.sh && \ ############################################# FROM base +USER root + +RUN \ + rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /usr/share/oracle/image-metadata/rpms/image-rpms.txt && \ + rpm -qa --qf '%{NAME} %{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /tmp/image-rpm-details && \ + if [ -f /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt ]; then \ + awk -F '\t' 'NR==FNR {base[$1]=1; next} !($1 in base) {print $1 "-" $2}' /usr/share/oracle/image-metadata/rpms/base-image-rpm-names.txt /tmp/image-rpm-details > /usr/share/oracle/image-metadata/rpms/image-added-rpms.txt; \ + else \ + cp /usr/share/oracle/image-metadata/rpms/image-rpms.txt /usr/share/oracle/image-metadata/rpms/image-added-rpms.txt; \ + fi && \ + rm -f /tmp/image-rpm-details; USER oracle COPY --chown=oracle:dba --from=builder $ORACLE_BASE $ORACLE_BASE @@ -210,5 +226,5 @@ RUN echo 'ORACLE_SID=${ORACLE_SID:-ORCLCDB}; export ORACLE_SID=${ORACLE_SID^^}' HEALTHCHECK --interval=1m --start-period=5m --timeout=30s \ CMD "$SCRIPT_BASE_DIR/$CHECK_DB_FILE" >/dev/null || exit 1 -# Define default command to start Oracle Database. +# Define default command to start Oracle Database. CMD exec $SCRIPT_BASE_DIR/$RUN_FILE diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/Containerfile.free b/OracleDatabase/SingleInstance/containerfiles/23.26.0/Containerfile.free similarity index 96% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/Containerfile.free rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/Containerfile.free index 191ad9f372..6ff5f72ca2 100644 --- a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/Containerfile.free +++ b/OracleDatabase/SingleInstance/containerfiles/23.26.0/Containerfile.free @@ -3,17 +3,17 @@ # # Copyright (c) 2022-2026 Oracle and/or its affiliates. # -# ORACLE DOCKERFILES PROJECT +# ORACLE CONTAINERFILES PROJECT # -------------------------- # This is the Containerfile for Oracle Database 26ai Free -# +# # REQUIRED FILES TO BUILD THIS IMAGE # ---------------------------------- # None # # HOW TO BUILD THIS IMAGE # ----------------------- -# Run: +# Run: # $ podman build -t oracle/database:23.26.0-free -f Containerfile.free . # # @@ -37,7 +37,7 @@ LABEL "provider"="Oracle" \ "volume.setup.location2"="/docker-entrypoint-initdb.d/setup" \ "volume.startup.location1"="/opt/oracle/scripts/startup" \ "volume.startup.location2"="/docker-entrypoint-initdb.d/startup" \ - "port.listener"="1521" + "port.listener"="1521" ARG INSTALL_FILE_1="https://download.oracle.com/otn-pub/otn_software/db-free/oracle-ai-database-free-26ai-23.26.2-1.el8.x86_64.rpm" ARG BACKUP_MODULE_URL="" @@ -62,6 +62,7 @@ ENV ORACLE_BASE=/opt/oracle \ CONFIG_DG_PREREQS_FILE="configDataguardPrereqs.sh" \ CONFIG_TCPS_FILE="configTcps.sh" \ TDE_SECRET_UTILS_FILE="tdeSecretUtils.sh" \ + MANAGE_PDB="managePDB.sh" \ SCRIPT_BASE_DIR="/opt/oracle/scripts/base" \ INSTALL_DIR="$HOME/install" \ ORACLE_DOCKER_INSTALL="true" \ @@ -73,18 +74,18 @@ ENV PATH=$ORACLE_HOME/bin:$PATH # Copy binaries # ------------- -COPY $CHECK_SPACE_FILE $CONF_FILE $SETUP_LINUX_FILE $RUN_FILE $SHUTDOWN_FILE $PWD_FILE $CHECK_DB_FILE $CREATE_DB_FILE $USER_SCRIPTS_FILE $CONFIG_DG_PREREQS_FILE $CONFIG_TCPS_FILE $TDE_SECRET_UTILS_FILE $DECRYPT_PWD_FILE $INSTALL_DIR/ +COPY $CHECK_SPACE_FILE $CONF_FILE $SETUP_LINUX_FILE $RUN_FILE $SHUTDOWN_FILE $PWD_FILE $CHECK_DB_FILE $CREATE_DB_FILE $USER_SCRIPTS_FILE $CONFIG_DG_PREREQS_FILE $CONFIG_TCPS_FILE $TDE_SECRET_UTILS_FILE $DECRYPT_PWD_FILE $MANAGE_PDB $INSTALL_DIR/ WORKDIR $INSTALL_DIR # hadolint ignore=DL3003,DL3033,SC2035 RUN mkdir -p "$ORACLE_BASE" && \ mkdir -p "${SCRIPT_BASE_DIR}" && \ - mv "$RUN_FILE" "$SHUTDOWN_FILE" "$PWD_FILE" "$CHECK_DB_FILE" "$CREATE_DB_FILE" "$USER_SCRIPTS_FILE" "$CONFIG_DG_PREREQS_FILE" "$CONFIG_TCPS_FILE" "$TDE_SECRET_UTILS_FILE" "$DECRYPT_PWD_FILE" "${SCRIPT_BASE_DIR}"/ && \ + mv "$RUN_FILE" "$SHUTDOWN_FILE" "$PWD_FILE" "$CHECK_DB_FILE" "$CREATE_DB_FILE" "$USER_SCRIPTS_FILE" "$CONFIG_DG_PREREQS_FILE" "$CONFIG_TCPS_FILE" "$TDE_SECRET_UTILS_FILE" "$DECRYPT_PWD_FILE" "$MANAGE_PDB" "${SCRIPT_BASE_DIR}"/ && \ chmod ug+x "${SCRIPT_BASE_DIR}"/*.sh && \ printf '#!/bin/bash\nexec "%s/%s" "$@"\n' "$SCRIPT_BASE_DIR" "$RUN_FILE" > "$ORACLE_BASE/$RUN_FILE" && \ chmod ug+x "$ORACLE_BASE/$RUN_FILE" && \ - for script in "$SHUTDOWN_FILE" "$PWD_FILE" "$CHECK_DB_FILE" "$CREATE_DB_FILE" "$USER_SCRIPTS_FILE" "$CONFIG_DG_PREREQS_FILE" "$CONFIG_TCPS_FILE" "$DECRYPT_PWD_FILE"; do \ + for script in "$SHUTDOWN_FILE" "$PWD_FILE" "$CHECK_DB_FILE" "$CREATE_DB_FILE" "$USER_SCRIPTS_FILE" "$CONFIG_DG_PREREQS_FILE" "$CONFIG_TCPS_FILE" "$DECRYPT_PWD_FILE" "$MANAGE_PDB"; do \ ln -sf "${SCRIPT_BASE_DIR}/$script" "$ORACLE_BASE/$script"; \ done && \ chmod ug+x *.sh && \ @@ -138,18 +139,18 @@ RUN --mount=type=bind,source=.,target=/build-context,readonly \ fi; \ rm -f "$backup_module_rpm"; \ fi - - + + ############################################# # ------------------------------------------- # Start new stage for installing the database # ------------------------------------------- ############################################# -FROM base AS builder +FROM base AS builder # Copy DB install file -ADD $INSTALL_FILE_1 $INSTALL_DIR/ +ADD $INSTALL_FILE_1 $INSTALL_DIR/ # Install DB software binaries RUN unbuffer yum -y localinstall "$INSTALL_DIR/$(basename $INSTALL_FILE_1)" diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/checkDBStatus.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/checkDBStatus.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/checkDBStatus.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/checkDBStatus.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/checkSpace.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/checkSpace.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/checkSpace.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/checkSpace.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/cloneDBObjBkup.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/cloneDBObjBkup.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/cloneDBObjBkup.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/cloneDBObjBkup.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/configDataguardPrereqs.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/configDataguardPrereqs.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/configDataguardPrereqs.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/configDataguardPrereqs.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/configTcps.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/configTcps.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/configTcps.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/configTcps.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/createDB.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/createDB.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/createDB.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/createDB.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/createObserver.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/createObserver.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/createObserver.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/createObserver.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/db_inst.rsp b/OracleDatabase/SingleInstance/containerfiles/23.26.0/db_inst.rsp similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/db_inst.rsp rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/db_inst.rsp diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/dbca.rsp.tmpl b/OracleDatabase/SingleInstance/containerfiles/23.26.0/dbca.rsp.tmpl similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/dbca.rsp.tmpl rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/dbca.rsp.tmpl diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/decryptPassword.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/decryptPassword.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/decryptPassword.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/decryptPassword.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/installDBBinaries.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/installDBBinaries.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/installDBBinaries.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/installDBBinaries.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/license.txt b/OracleDatabase/SingleInstance/containerfiles/23.26.0/license.txt similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/license.txt rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/license.txt diff --git a/OracleDatabase/SingleInstance/containerfiles/23.26.0/managePDB.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/managePDB.sh new file mode 100755 index 0000000000..7e738cb330 --- /dev/null +++ b/OracleDatabase/SingleInstance/containerfiles/23.26.0/managePDB.sh @@ -0,0 +1,301 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 1982-2026 Oracle and/or its affiliates. All rights reserved. +# Since: Sep, 2026 +# Author: paramdeep.saini@oracle.com +# Description: Apply and verify supported PDB-level database parameters. +# +# MAX_STRING_SIZE=EXTENDED requires the documented upgrade-mode bounce: +# OPEN UPGRADE -> SET SCOPE=SPFILE -> CLOSE -> OPEN UPGRADE -> utl32k.sql +# -> CLOSE -> OPEN -> utlrp.sql -> verify + +set -euo pipefail + +SQLPLUS_BIN="${SQLPLUS_BIN:-sqlplus}" +# 23.26 and 26ai Single Instance images install under product/26ai/dbhome_1. +ORACLE_HOME="${ORACLE_HOME:-/opt/oracle/product/26ai/dbhome_1}" +UTL32K_SQL="${UTL32K_SQL:-${ORACLE_HOME}/rdbms/admin/utl32k.sql}" +UTLRP_SQL="${UTLRP_SQL:-${ORACLE_HOME}/rdbms/admin/utlrp.sql}" +OPERATION="" +PDB_NAME="" +declare -a PARAMETERS=() + +function usage() { + cat <<'EOF' +Usage: + managePDB.sh --operation apply-parameters --pdb --parameter [--parameter ...] + +Options: + --operation PDB operation to execute. Currently: apply-parameters. + --pdb Target PDB name. + --parameter PDB parameter assignment. Repeat for multiple parameters. + --help Show this help. + +Environment: + SQLPLUS_BIN SQL*Plus executable (default: sqlplus). + UTL32K_SQL Oracle utl32k.sql path (default: ORACLE_HOME/rdbms/admin/utl32k.sql). + UTLRP_SQL Oracle utlrp.sql path (default: ORACLE_HOME/rdbms/admin/utlrp.sql). +EOF +} + +function die() { + echo "ERROR: $*" >&2 + exit 1 +} + +function require_option_value() { + [[ $# -ge 2 && -n "$2" ]] || die "Missing value for $1" +} + +function validate_pdb_name() { + [[ "$1" =~ ^[[:alpha:]][[:alnum:]_$#]*$ ]] || + die "Invalid PDB name: $1" +} + +function add_parameter() { + local assignment="$1" + local name value existing + + [[ "$assignment" == *=* ]] || die "Parameter must use NAME=VALUE syntax: $assignment" + name="${assignment%%=*}" + value="${assignment#*=}" + name="$(printf '%s' "$name" | tr '[:lower:]' '[:upper:]')" + value="$(printf '%s' "$value" | tr '[:lower:]' '[:upper:]')" + + [[ "$name" =~ ^[[:alpha:]_][[:alnum:]_$#]*$ ]] || + die "Invalid parameter name: $name" + [[ -n "$value" ]] || die "Parameter value cannot be empty: $name" + + for existing in "${PARAMETERS[@]}"; do + [[ "${existing%%=*}" != "$name" ]] || die "Parameter specified more than once: $name" + done + PARAMETERS+=("$name=$value") +} + +function run_sql() { + # Fail hard on SQL/OS errors; do not continue nested scripts after a failure. + "$SQLPLUS_BIN" -L -s "/ as sysdba" <= 12.0.0.0; PDB $PDB_NAME has ${compatible:-empty}" +} + +function verify_pdb_max_string_size() { + local expected="$1" + local actual + + actual="$(pdb_max_string_size)" + [[ "$actual" == "$expected" ]] || + die "MAX_STRING_SIZE verification failed for PDB $PDB_NAME: expected $expected, got ${actual:-empty}" + echo "PDB_PARAMETER_VERIFIED MAX_STRING_SIZE=$actual PDB=$PDB_NAME" +} + +function close_pdb_ignore_already_closed() { + run_sql " +ALTER SESSION SET CONTAINER = CDB\$ROOT; +BEGIN + EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE \"$PDB_NAME\" CLOSE IMMEDIATE'; +EXCEPTION + WHEN OTHERS THEN + -- ORA-65020: PDB already closed + IF SQLCODE != -65020 THEN + RAISE; + END IF; +END; +/ +" +} + +function open_pdb_upgrade() { + run_sql " +ALTER SESSION SET CONTAINER = CDB\$ROOT; +ALTER PLUGGABLE DATABASE \"$PDB_NAME\" OPEN UPGRADE; +" +} + +function open_pdb_normal() { + run_sql " +ALTER SESSION SET CONTAINER = CDB\$ROOT; +ALTER PLUGGABLE DATABASE \"$PDB_NAME\" OPEN; +" +} + +function migrate_max_string_size_to_extended() { + local pdb_value="$1" + local compatible + + [[ -f "$UTL32K_SQL" ]] || + die "Required Oracle migration script not found: $UTL32K_SQL" + [[ -f "$UTLRP_SQL" ]] || + die "Required Oracle recompilation script not found: $UTLRP_SQL" + + compatible="$(pdb_compatible)" + require_supported_compatible "$compatible" + + echo "MAX_STRING_SIZE migration required: PDB=${pdb_value:-empty} target=EXTENDED" + echo "Running the PDB upgrade-mode migration for $PDB_NAME with COMPATIBLE=$compatible" + + # Step 1: open upgrade and persist EXTENDED to the PDB SPFILE only. + close_pdb_ignore_already_closed + open_pdb_upgrade + run_sql " +ALTER SESSION SET CONTAINER = \"$PDB_NAME\"; +ALTER SYSTEM SET MAX_STRING_SIZE = EXTENDED SCOPE=SPFILE; +SELECT 'MAX_STRING_SIZE written to SPFILE for PDB=' || SYS_CONTEXT('USERENV', 'CON_NAME') FROM dual; +" + + # Step 2: bounce back into UPGRADE so EXTENDED is active in memory, then migrate. + close_pdb_ignore_already_closed + open_pdb_upgrade + run_sql " +ALTER SESSION SET CONTAINER = \"$PDB_NAME\"; +DECLARE + l_value VARCHAR2(30); +BEGIN + SELECT UPPER(TRIM(value)) INTO l_value FROM v\$parameter WHERE name = 'max_string_size'; + IF l_value <> 'EXTENDED' THEN + raise_application_error(-20001, + 'MAX_STRING_SIZE not EXTENDED in upgrade mode before utl32k.sql; actual=' || l_value); + END IF; +END; +/ +@$UTL32K_SQL +SELECT 'UTL32K completed for PDB=' || SYS_CONTEXT('USERENV', 'CON_NAME') FROM dual; +" + + # Step 3: open normally and recompile. + close_pdb_ignore_already_closed + open_pdb_normal + run_sql " +ALTER SESSION SET CONTAINER = \"$PDB_NAME\"; +@$UTLRP_SQL +DECLARE + l_value VARCHAR2(30); +BEGIN + SELECT UPPER(TRIM(value)) INTO l_value FROM v\$parameter WHERE name = 'max_string_size'; + IF l_value <> 'EXTENDED' THEN + raise_application_error(-20001, + 'MAX_STRING_SIZE verification failed after open; actual value is ' || l_value); + END IF; +END; +/ +SELECT 'PDB_PARAMETER_APPLIED MAX_STRING_SIZE=EXTENDED PDB=' || SYS_CONTEXT('USERENV', 'CON_NAME') FROM dual; +" + + verify_pdb_max_string_size EXTENDED +} + +function apply_max_string_size() { + local value="$1" + local current_pdb + + case "$value" in + STANDARD|EXTENDED) ;; + *) die "MAX_STRING_SIZE must be STANDARD or EXTENDED" ;; + esac + + current_pdb="$(pdb_max_string_size)" + + if [[ "$value" == "STANDARD" ]]; then + if [[ "$current_pdb" == "EXTENDED" ]]; then + die "MAX_STRING_SIZE cannot be changed from EXTENDED to STANDARD" + fi + [[ "$current_pdb" == "STANDARD" ]] || + die "MAX_STRING_SIZE verification failed for PDB $PDB_NAME: expected STANDARD, got ${current_pdb:-empty}" + echo "PDB_PARAMETER_ALREADY_APPLIED MAX_STRING_SIZE=STANDARD PDB=$PDB_NAME" + return 0 + fi + + if [[ "$current_pdb" == "EXTENDED" ]]; then + verify_pdb_max_string_size EXTENDED + return 0 + fi + + migrate_max_string_size_to_extended "$current_pdb" +} + +function apply_parameter() { + local assignment="$1" + local name="${assignment%%=*}" + local value="${assignment#*=}" + + case "$name" in + MAX_STRING_SIZE) + apply_max_string_size "$value" + ;; + *) + die "Unsupported PDB parameter: $name" + ;; + esac +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --operation) + require_option_value "$@" + OPERATION="$2" + shift 2 + ;; + --pdb) + require_option_value "$@" + PDB_NAME="$2" + shift 2 + ;; + --parameter) + require_option_value "$@" + add_parameter "$2" + shift 2 + ;; + --help|-h) + usage + exit 0 + ;; + *) + die "Unknown argument: $1" + ;; + esac +done + +[[ "$OPERATION" == "apply-parameters" ]] || + die "--operation must be apply-parameters" +[[ -n "$PDB_NAME" ]] || die "--pdb is required" +validate_pdb_name "$PDB_NAME" +(( ${#PARAMETERS[@]} > 0 )) || die "At least one --parameter is required" + +for parameter in "${PARAMETERS[@]}"; do + apply_parameter "$parameter" +done diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/manageTnsAliases.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/manageTnsAliases.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/manageTnsAliases.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/manageTnsAliases.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/oracle-free-26ai.conf b/OracleDatabase/SingleInstance/containerfiles/23.26.0/oracle-free-26ai.conf similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/oracle-free-26ai.conf rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/oracle-free-26ai.conf diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/relinkOracleBinary.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/relinkOracleBinary.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/relinkOracleBinary.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/relinkOracleBinary.sh diff --git a/OracleDatabase/SingleInstance/containerfiles/23.26.0/repairListenerConfig.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/repairListenerConfig.sh new file mode 100755 index 0000000000..5666a4f1ac --- /dev/null +++ b/OracleDatabase/SingleInstance/containerfiles/23.26.0/repairListenerConfig.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 1982-2026 Oracle and/or its affiliates. All rights reserved. +# Description: Repair persisted SIDB listener bind addresses after pod recreation. +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +set -euo pipefail + +ORACLE_BASE="${ORACLE_BASE:-/opt/oracle}" +ORACLE_HOME="${ORACLE_HOME:-/opt/oracle/product/26ai/dbhome_1}" +ORACLE_SID="${ORACLE_SID:-$(awk -F: -v oracle_home="${ORACLE_HOME}" '$2 == oracle_home { print $1; exit }' /etc/oratab 2>/dev/null || true)}" +ORACLE_SID="${ORACLE_SID^^}" +LISTENER_BIND_HOST="${LISTENER_BIND_HOST:-0.0.0.0}" + +if [ -z "${ORACLE_SID}" ]; then + exit 0 +fi + +LISTENER_FILE="${ORACLE_BASE}/oradata/dbconfig/${ORACLE_SID}/listener.ora" +if [ ! -f "${LISTENER_FILE}" ]; then + exit 0 +fi + +TMP_FILE="$(mktemp)" +trap 'rm -f "${TMP_FILE}"' EXIT +awk -v host="${LISTENER_BIND_HOST}" '{ gsub(/\(HOST[[:space:]]*=[[:space:]]*[^)[:space:]]+\)/, "(HOST=" host ")"); print }' "${LISTENER_FILE}" > "${TMP_FILE}" + +if cmp -s "${LISTENER_FILE}" "${TMP_FILE}"; then + exit 0 +fi + +mv "${TMP_FILE}" "${LISTENER_FILE}" +trap - EXIT +echo "INFO: repaired listener HOST entries to bind address ${LISTENER_BIND_HOST}" +# Startup may call this before the listener exists. Reconciliation may call it +# while the listener is running, so reload first and restart if reload fails. +if ! lsnrctl reload >/dev/null 2>&1; then + lsnrctl stop >/dev/null 2>&1 || true + lsnrctl start >/dev/null 2>&1 || echo "WARNING: listener restart deferred" +fi diff --git a/OracleDatabase/SingleInstance/containerfiles/23.26.0/repairLocalListenerRegistration.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/repairLocalListenerRegistration.sh new file mode 100755 index 0000000000..ce7da11e8c --- /dev/null +++ b/OracleDatabase/SingleInstance/containerfiles/23.26.0/repairLocalListenerRegistration.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 1982-2026 Oracle and/or its affiliates. All rights reserved. +# Description: Reconcile the database LOCAL_LISTENER with the current pod IP. +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + +set -u + +ORACLE_HOME="${ORACLE_HOME:-/opt/oracle/product/26ai/dbhome_1}" +export PATH="${ORACLE_HOME}/bin:${PATH}" + +is_ipv4() { + [[ "$1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] +} + +listener_host="${LOCAL_LISTENER_HOST:-}" +if ! is_ipv4 "${listener_host}"; then + listener_host="$(hostname -i 2>/dev/null | awk '{for (i = 1; i <= NF; i++) if ($i ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}$/) { print $i; exit }}')" +fi +if ! is_ipv4 "${listener_host}" && is_ipv4 "${ORACLE_HOSTNAME:-}"; then + listener_host="${ORACLE_HOSTNAME}" +fi + +if ! is_ipv4 "${listener_host}"; then + echo "WARNING: unable to determine an IPv4 address for LOCAL_LISTENER registration" + exit 0 +fi + +if ! sqlplus -s / as sysdba < /etc/yum/vars/ociregion -fi - # Setup filesystem and oracle user # Adjust file permissions, go to /opt/oracle as user 'oracle' to proceed with Oracle installation # ------------------------------------------------------------ diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/shutDown.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/shutDown.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/shutDown.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/shutDown.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/startDB.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/startDB.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/startDB.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/startDB.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/23.26.0/tdeSecretUtils.sh b/OracleDatabase/SingleInstance/containerfiles/23.26.0/tdeSecretUtils.sh similarity index 100% rename from OracleDatabase/SingleInstance/dockerfiles/23.26.0/tdeSecretUtils.sh rename to OracleDatabase/SingleInstance/containerfiles/23.26.0/tdeSecretUtils.sh diff --git a/OracleDatabase/SingleInstance/dockerfiles/buildContainerImage.sh b/OracleDatabase/SingleInstance/dockerfiles/buildContainerImage.sh index efa69e4568..e0f2cc129f 100755 --- a/OracleDatabase/SingleInstance/dockerfiles/buildContainerImage.sh +++ b/OracleDatabase/SingleInstance/dockerfiles/buildContainerImage.sh @@ -1,13 +1,13 @@ #!/bin/bash -e -# +# # Since: April, 2016 # Author: gerald.venzl@oracle.com # Description: Build script for building Oracle Database container images. -# +# # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. -# +# # Copyright (c) 2014,2026 Oracle and/or its affiliates. -# +# function usage() { cat << EOF @@ -22,7 +22,7 @@ Parameters: -e: creates image based on 'Enterprise Edition' -s: creates image based on 'Standard Edition 2' -x: creates image based on 'Express Edition' - -f: creates images based on Database 'Free' + -f: creates images based on Database 'Free' -i: ignores the MD5 checksums -p: creates and extends image using the patching extension -b: build base stage only (Used by extensions) @@ -41,7 +41,7 @@ EOF # Validate packages function checksumPackages() { if hash md5sum 2>/dev/null; then - echo "Checking if required packages are present and valid..." + echo "Checking if required packages are present and valid..." if ! md5sum -c "Checksum.${EDITION}${PLATFORM}"; then echo "MD5 for required packages to build this image did not match!" echo "Make sure to download missing files in folder ${VERSION}." @@ -54,8 +54,8 @@ function checksumPackages() { # Check container runtime function checkContainerRuntime() { - CONTAINER_RUNTIME=$(which docker 2>/dev/null) || - CONTAINER_RUNTIME=$(which podman 2>/dev/null) || + CONTAINER_RUNTIME=$(which podman 2>/dev/null) || + CONTAINER_RUNTIME=$(which docker 2>/dev/null) || { echo "No docker or podman executable found in your PATH" exit 1 @@ -105,8 +105,11 @@ function checkDockerVersion() { #### MAIN #### ############## -# Go into dockerfiles directory -cd "$(dirname "$0")" +# Resolve legacy and modern source roots. Versions before 19.3.0 retain the +# legacy Dockerfile layout; 19.3.0 and later use Containerfiles under containerfiles/. +SCRIPT_ROOT="$(cd "$(dirname "$0")" && pwd)" +MODERN_ROOT="$(dirname "$SCRIPT_ROOT")/containerfiles" +cd "$SCRIPT_ROOT" # Parameters ENTERPRISE=${ENTERPRISE:-0} @@ -116,12 +119,13 @@ FREE=${FREE:-0} PATCHING=0 BASE_ONLY=0 # Obtaining the latest version to build -VERSION="$(find -- *.*.* -type d | tail -n 1)" +VERSION="$(find "$SCRIPT_ROOT" "$MODERN_ROOT" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' 2>/dev/null | sort -V | tail -n 1)" SKIPMD5=0 declare -a BUILD_OPTS MIN_DOCKER_VERSION="17.09" MIN_PODMAN_VERSION="1.6.0" -DOCKERFILE="Dockerfile" +BUILD_FILE="Dockerfile" +BUILD_ROOT="$SCRIPT_ROOT" IMAGE_NAME="" if [ "$#" -eq 0 ]; then @@ -182,13 +186,13 @@ checkContainerRuntime # Only 19c (EE) and 26ai (Free and EE) are supported on ARM64 platform if [ "$(arch)" == "aarch64" ] || [ "$(arch)" == "arm64" ]; then PLATFORM=".arm64" - + if [ "${VERSION%%.*}" -lt 26 ]; then BUILD_OPTS=("--build-arg" "BASE_IMAGE=oraclelinux:8" "${BUILD_OPTS[@]}") else BUILD_OPTS=("--build-arg" "BASE_IMAGE=oraclelinux:9" "${BUILD_OPTS[@]}") fi - + if [ "${VERSION}" == "19.3.0" ] && { [ "${BASE_ONLY}" -eq 1 ] || [ "${ENTERPRISE}" -eq 1 ]; }; then BUILD_OPTS=("--build-arg" "INSTALL_FILE_1=LINUX.ARM64_1919000_db_home.zip" "${BUILD_OPTS[@]}") elif [ "${VERSION}" == "23.26.0" ] && [ "${FREE}" -eq 1 ]; then @@ -214,32 +218,33 @@ elif [ ${EXPRESS} -eq 1 ]; then echo "Version ${VERSION} does not have Express Edition available."; exit 1; fi; -elif [ ${FREE} -eq 1 ]; then - if [ "$(cut -f1 -d. <<< "$VERSION" )" -lt 23 ]; then +elif [ ${FREE} -eq 1 ]; then + if [ "$(cut -f1 -d. <<< "$VERSION" )" -lt 23 ]; then echo "Version ${VERSION} does not have Free Edition available."; exit 1; - else + else EDITION="free" SKIPMD5=1 fi; fi; # Go into version folder -cd "${VERSION}" || { +if [ "${VERSION%%.*}" -ge 19 ]; then + BUILD_FILE="Containerfile" + BUILD_ROOT="$MODERN_ROOT" +fi + +cd "${BUILD_ROOT}/${VERSION}" || { echo "Could not find version directory '${VERSION}'"; exit 1; } -if [ "${VERSION%%.*}" -ge 23 ]; then - DOCKERFILE="Containerfile" -fi; - -# Which Dockerfile should be used? +# Which build file should be used? if [ "${VERSION}" == "12.1.0.2" ] || { [ "${VERSION}" == "21.3.0" ] && [ "${EDITION}" == "xe" ]; } || { [ "${VERSION%%.*}" -ge 23 ] && [ "${EDITION}" == "free" ]; }; then - DOCKERFILE="${DOCKERFILE}.${EDITION}" + BUILD_FILE="${BUILD_FILE}.${EDITION}" fi; -echo "$DOCKERFILE" +echo "$BUILD_FILE" # Oracle Database image Name # If provided using -t build option then use it; Otherwise, create with version and edition @@ -291,8 +296,8 @@ if [ ${PATCHING} -eq 1 ]; then BUILD_OPTS=("${BUILD_OPTS[@]}" "--build-arg" "SLIMMING=false" ) fi -if [ ! -e "${DOCKERFILE}" ]; then - echo "ERROR: ${DOCKERFILE} doesn't exist" +if [ ! -e "${BUILD_FILE}" ]; then + echo "ERROR: ${BUILD_FILE} doesn't exist" exit 1 fi @@ -305,7 +310,7 @@ if [ ${BASE_ONLY} -eq 1 ]; then # BUILD THE BASE STAGE IMAGE (replace all environment variables) "${CONTAINER_RUNTIME}" build --force-rm=true \ "${BUILD_OPTS[@]}" "${PROXY_SETTINGS[@]}" --target base \ - -t "${IMAGE_NAME}" -f "${DOCKERFILE}" . || { + -t "${IMAGE_NAME}" -f "${BUILD_FILE}" . || { echo "" echo "ERROR: Base stage image was NOT successfully created." exit 1 @@ -324,7 +329,7 @@ echo "Building image '${IMAGE_NAME}' ..." BUILD_START=$(date '+%s') "${CONTAINER_RUNTIME}" build --force-rm=true --no-cache=true \ "${BUILD_OPTS[@]}" "${PROXY_SETTINGS[@]}" --build-arg DB_EDITION="${EDITION}" \ - -t "${IMAGE_NAME}" -f "${DOCKERFILE}" . || { + -t "${IMAGE_NAME}" -f "${BUILD_FILE}" . || { echo "" echo "ERROR: Oracle Database container image was NOT successfully created." echo "ERROR: Check the output and correct any reported problems with the build operation." @@ -341,12 +346,12 @@ echo "" echo "" cat << EOF - Oracle Database container image for '${EDITION}' version ${VERSION} is ready to be extended: - + Oracle Database container image for '${EDITION}' version ${VERSION} is ready to be extended: + --> ${IMAGE_NAME} Build completed in ${BUILD_ELAPSED} seconds. - + EOF # EXTEND THE BUILT IMAGE BY APPLYING PATCHING EXTENSION diff --git a/OracleDatabase/SingleInstance/extensions/README.md b/OracleDatabase/SingleInstance/extensions/README.md index 3e23875661..6df2fe9c52 100644 --- a/OracleDatabase/SingleInstance/extensions/README.md +++ b/OracleDatabase/SingleInstance/extensions/README.md @@ -12,7 +12,7 @@ Once you have created the base image, go into the **extensions** folder and run Parameters: -a: Build all extensions -x: Space separated extensions to build. Defaults to all - Choose from : patching + Choose from : k8s, patching, prebuiltdb, sharding, truecache -b: Base image to use -v: Base version to extend (example 21.3.0) -t: name:tag for the extended image diff --git a/OracleDatabase/SingleInstance/extensions/buildExtensions.sh b/OracleDatabase/SingleInstance/extensions/buildExtensions.sh index ee85e2ccb6..7b247127c1 100755 --- a/OracleDatabase/SingleInstance/extensions/buildExtensions.sh +++ b/OracleDatabase/SingleInstance/extensions/buildExtensions.sh @@ -1,4 +1,5 @@ #!/bin/bash -e +# shellcheck disable=SC2086,SC2154 # # Since: Mar, 2020 # Author: mohammed.qureshi@oracle.com @@ -43,6 +44,22 @@ checkContainerRuntime() { echo "No docker or podman executable found in your PATH" exit 1 } + + if "${CONTAINER_RUNTIME}" info | grep -i -q buildahversion; then + BUILD_FORMAT_OPTIONS=(--format=docker) + fi +} + +# Remove only base-stage tags created during this build, including on failure. +cleanupBaseImages() { + local base_image + for base_image in "${BASE_IMAGES_TO_CLEAN[@]}"; do + if "${CONTAINER_RUNTIME}" image inspect "$base_image" >/dev/null 2>&1; then + "${CONTAINER_RUNTIME}" rmi -f "$base_image" || + echo "WARNING: Could not remove temporary base image '$base_image'." >&2 + fi + done + BASE_IMAGES_TO_CLEAN=() } ############## @@ -52,9 +69,11 @@ checkContainerRuntime() { # Parameters DOCKEROPS="" DOCKERFILE="Dockerfile" -BASE_IMAGE="oracle/database:21.3.0-ee" +BASE_IMAGE="oracle/database:latest" IMAGE_NAME="oracle/database:ext" -VERSION="21.3.0" +VERSION="" +declare -a BUILD_FORMAT_OPTIONS +BASE_IMAGES_TO_CLEAN=() if [ "$#" -eq 0 ]; then usage; @@ -128,12 +147,66 @@ BUILD_START=$(date '+%s') cd "$SCRIPT_DIR" -if [[ "$EXTENSIONS" == *"patching"* ]]; then +BUILD_BASE_STAGE=false +FREE_PREBUILT=false +if [[ " $EXTENSIONS " == *" prebuiltdb "* ]]; then + if ! "${CONTAINER_RUNTIME}" image inspect "$BASE_IMAGE" >/dev/null 2>&1; then + "${CONTAINER_RUNTIME}" pull "$BASE_IMAGE" + fi + BASE_IMAGE_RELEASE=$("${CONTAINER_RUNTIME}" image inspect --format '{{ index .Config.Labels "release" }}' "$BASE_IMAGE") + if [ "$BASE_IMAGE_RELEASE" = "Free" ]; then + FREE_PREBUILT=true + for extension in $EXTENSIONS; do + if [ "$extension" != "prebuiltdb" ]; then + echo "ERROR: prebuiltdb must be the first extension for Free images because its final stage rebuilds from a clean base." + echo "Example: -x 'prebuiltdb truecache sharding'" + exit 1 + fi + break + done + fi +fi +if [[ "$EXTENSIONS" == *"patching"* ]]; then if [ "$( (ls patching/patches/one_offs && ls patching/patches/release_update) | wc -l)" -gt 0 ]; then - # BUILD THE LINUX BASE FOR REUSE - ../dockerfiles/buildContainerImage.sh -b -v "${VERSION}" -t "$BASE_IMAGE"-base + BUILD_BASE_STAGE=true fi fi +if [ "$FREE_PREBUILT" = true ]; then + BUILD_BASE_STAGE=true +fi + +if [ "$BUILD_BASE_STAGE" = true ]; then + if [ -z "$VERSION" ]; then + if ! "${CONTAINER_RUNTIME}" image inspect "$BASE_IMAGE" >/dev/null 2>&1; then + "${CONTAINER_RUNTIME}" pull "$BASE_IMAGE" + fi + VERSION=$("${CONTAINER_RUNTIME}" image inspect --format '{{ index .Config.Labels "version" }}' "$BASE_IMAGE") + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "ERROR: -v is required when the base image has no valid version label" + exit 1 + fi + fi + + # BUILD THE LINUX BASE FOR REUSE + BASE_BUILD_EDITION_ARGS=() + case "${BASE_IMAGE##*:}" in + *-free) + BASE_BUILD_EDITION_ARGS=("-f") + ;; + *-se2) + BASE_BUILD_EDITION_ARGS=("-s") + ;; + *-xe) + BASE_BUILD_EDITION_ARGS=("-x") + ;; + esac + if [ "$FREE_PREBUILT" = true ]; then + BASE_BUILD_EDITION_ARGS=("-f") + fi + trap cleanupBaseImages EXIT + ../dockerfiles/buildContainerImage.sh -b -v "${VERSION}" "${BASE_BUILD_EDITION_ARGS[@]}" -t "$BASE_IMAGE"-base + BASE_IMAGES_TO_CLEAN+=("${BASE_IMAGE}-base") +fi for x in $EXTENSIONS; do echo "Building extension $x..." @@ -143,22 +216,34 @@ for x in $EXTENSIONS; do exit 1; } + BUILD_CONTEXT_OPTIONS=() + EXTENSION_DOCKERFILE="$DOCKERFILE" + if [ "$x" = "prebuiltdb" ] && [ "$FREE_PREBUILT" = true ]; then + EXTENSION_DOCKERFILE="Dockerfile.free" + fi + if [ "$x" = "sharding" ]; then + BUILD_CONTEXT_OPTIONS=(--build-context "gdd-scripts=../../../GDD/containerfiles/scripts") + fi + # shellcheck disable=SC2086 - "${CONTAINER_RUNTIME}" build --force-rm=true --build-arg BASE_IMAGE="$BASE_IMAGE" \ - $DOCKEROPS $PROXY_SETTINGS -t $IMAGE_NAME -f $DOCKERFILE . || { + "${CONTAINER_RUNTIME}" build --force-rm=true "${BUILD_FORMAT_OPTIONS[@]}" --build-arg BASE_IMAGE="$BASE_IMAGE" \ + "${BUILD_CONTEXT_OPTIONS[@]}" $DOCKEROPS $PROXY_SETTINGS -t $IMAGE_NAME -f "$EXTENSION_DOCKERFILE" . || { echo "" echo "ERROR: Oracle Database Container Image was NOT successfully created." echo "ERROR: Check the output and correct any reported problems with the container build operation." exit 1 } - if "${CONTAINER_RUNTIME}" image inspect "${BASE_IMAGE}"-base >/dev/null 2>&1; then + if [ "$BASE_IMAGE" != "$IMAGE_NAME" ] && "${CONTAINER_RUNTIME}" image inspect "${BASE_IMAGE}"-base >/dev/null 2>&1; then "${CONTAINER_RUNTIME}" tag "$BASE_IMAGE"-base "$IMAGE_NAME"-base + if [ "$BUILD_BASE_STAGE" = true ]; then + BASE_IMAGES_TO_CLEAN+=("${IMAGE_NAME}-base") + fi fi BASE_IMAGE="$IMAGE_NAME" cd .. done -"${CONTAINER_RUNTIME}" rmi -f "$BASE_IMAGE"-base +cleanupBaseImages # Remove dangling images (intermitten images with tag ) "${CONTAINER_RUNTIME}" image prune -f > /dev/null diff --git a/OracleDatabase/SingleInstance/extensions/k8s/checkDBLockStatus.sh b/OracleDatabase/SingleInstance/extensions/k8s/checkDBLockStatus.sh index 5040899883..1e1e1c8a3c 100755 --- a/OracleDatabase/SingleInstance/extensions/k8s/checkDBLockStatus.sh +++ b/OracleDatabase/SingleInstance/extensions/k8s/checkDBLockStatus.sh @@ -15,6 +15,8 @@ EXTENSION_SCRIPT_DIR="${EXTENSION_SCRIPT_DIR:-/opt/oracle/scripts/extensions/k8s LOCKING_SCRIPT_PATH="${EXTENSION_SCRIPT_DIR}/${LOCKING_SCRIPT:-lock.py}" SCRIPT_BASE_DIR="${SCRIPT_BASE_DIR:-/opt/oracle/scripts/base}" CHECK_DB_FILE="${CHECK_DB_FILE:-checkDBStatus.sh}" +PMON_MISSING_FILE="/tmp/.${ORACLE_SID}.pmon_missing_since" +PMON_GRACE_SECONDS="${PMON_GRACE_SECONDS:-300}" if [ -x "${SCRIPT_BASE_DIR}/${CHECK_DB_FILE}" ]; then CHECK_DB_PATH="${SCRIPT_BASE_DIR}/${CHECK_DB_FILE}" @@ -35,14 +37,36 @@ elif ! "$LOCKING_SCRIPT_PATH" --check --file "$ORACLE_BASE/oradata/.${ORACLE_SID exit 1 # exist lock not held, DB is still initializing elif "$CHECK_DB_PATH"; then # DB health is good + rm -f "$PMON_MISSING_FILE" exit 0 elif test -f "$ORACLE_BASE/oradata/.${ORACLE_SID}.nochk"; then + rm -f "$PMON_MISSING_FILE" exit 1 # Skip health check -elif pgrep -f pmon > /dev/null; then +elif pgrep -f "[o]ra_pmon_${ORACLE_SID}" > /dev/null; then # DB procs detected + rm -f "$PMON_MISSING_FILE" exit 1 else # No DB procs detected + now=$(date +%s) + + if [ ! -f "$PMON_MISSING_FILE" ]; then + echo "$now" > "$PMON_MISSING_FILE" + echo "PMON is temporarily unavailable; starting ${PMON_GRACE_SECONDS}s grace period." + exit 1 + fi + + missing_since=$(cat "$PMON_MISSING_FILE" 2>/dev/null || echo "$now") + elapsed=$((now - missing_since)) + + if [ "$elapsed" -lt "$PMON_GRACE_SECONDS" ]; then + echo "PMON unavailable for ${elapsed}s; waiting for ${PMON_GRACE_SECONDS}s grace period." + exit 1 + fi + + echo "PMON unavailable for ${elapsed}s; restarting the container." + rm -f "$PMON_MISSING_FILE" + "$LOCKING_SCRIPT_PATH" --release --file "$ORACLE_BASE/oradata/.${ORACLE_SID}.exist_lck" # Kill the process that keeps the container alive pkill -9 -f "tail.*alert" diff --git a/OracleDatabase/SingleInstance/extensions/k8s/startDB.sh b/OracleDatabase/SingleInstance/extensions/k8s/startDB.sh index 6ccaa00f3b..4ab8ea5791 100755 --- a/OracleDatabase/SingleInstance/extensions/k8s/startDB.sh +++ b/OracleDatabase/SingleInstance/extensions/k8s/startDB.sh @@ -70,19 +70,68 @@ fi touch "$ORACLE_BASE/oradata/.${ORACLE_SID}.nochk" && sync for i in {1..10}; do - # Start database + # Mount database sqlplus / as sysdba << EOF $condn_sql alter database mount; - alter database open; - alter system register; exit; EOF + + # Get database role + DB_ROLE=$(sqlplus -s / as sysdba << EOF +set heading off; +set pagesize 0; +set feedback off; +select database_role from v\$database; +exit; +EOF +) + DB_ROLE=$(echo "$DB_ROLE" | xargs) + + # Check if database is a CDB + CDB_FLAG=$(sqlplus -s / as sysdba << EOF +set heading off; +set pagesize 0; +set feedback off; +select cdb from v\$database; +exit; +EOF +) + CDB_FLAG=$(echo "$CDB_FLAG" | xargs) + + # Open database based on database role + if [ "$DB_ROLE" = "PHYSICAL STANDBY" ]; then + + # Keep standby mounted when explicitly configured in MOUNTED mode + if [ "${STANDBY_OPEN_MODE:-READ_ONLY}" = "MOUNTED" ]; then + sqlplus / as sysdba << EOF + alter system register; + exit; +EOF + else + sqlplus / as sysdba << EOF + alter database open read only; + $(if [ "$CDB_FLAG" = "YES" ]; then echo "alter pluggable database all open read only;"; fi) + alter system register; + exit; +EOF + fi + + else + sqlplus / as sysdba << EOF + alter database open; + $(if [ "$CDB_FLAG" = "YES" ]; then echo "alter pluggable database all open;"; fi) + alter system register; + exit; +EOF + fi + if "$CHECK_DB_PATH"; then # DB health is good echo "DB is in good health on startup" break fi + # Sometimes DB locks of a dead container are not released immediately echo "Waiting for $i sec(s) before restarting Oracle processes and opening the database" sleep $i diff --git a/OracleDatabase/SingleInstance/extensions/prebuiltdb/Dockerfile.free b/OracleDatabase/SingleInstance/extensions/prebuiltdb/Dockerfile.free new file mode 100644 index 0000000000..f7309d7889 --- /dev/null +++ b/OracleDatabase/SingleInstance/extensions/prebuiltdb/Dockerfile.free @@ -0,0 +1,83 @@ +# LICENSE UPL 1.0 +# +# Copyright (c) 2020-2026 Oracle and/or its affiliates. All rights reserved. +# +# ORACLE DOCKERFILES PROJECT +# -------------------------- +# This Dockerfile extends the base container image with pre-created database, intending improved startup in CI/CD pipelines +# +# REQUIREMENTS FOR THIS IMAGE +# ---------------------------------- +# Oracle Single Instance Database container image Free version 23.26.0 onwards +# +# HOW TO BUILD THIS IMAGE +# ----------------------- +# +# Run: +# $ docker build -t . --build-arg BASE_IMAGE=oracle/database:23.26.0-free +# + +ARG BASE_IMAGE=oracle/database:23.26.0-free +# hadolint ignore=DL3006 +FROM ${BASE_IMAGE} AS prebuilt + +ARG ORACLE_SID +ARG ORACLE_PWD +ARG ENABLE_ARCHIVELOG +ARG ENABLE_FORCE_LOGGING +ARG AUTO_MEM_CALCULATION + +# Option to enable archivelog in pre-built database +ENV ENABLE_ARCHIVELOG=${ENABLE_ARCHIVELOG:-true} +ENV ENABLE_FORCE_LOGGING=${ENABLE_FORCE_LOGGING:-true} +ENV ORACLE_SID=${ORACLE_SID:-FREE} +ENV ORACLE_PWD=${ORACLE_PWD} +ENV AUTO_MEM_CALCULATION=${AUTO_MEM_CALCULATION:-false} + +COPY --chown=oracle:dba setup/* "$ORACLE_BASE"/scripts/extensions/setup/ +COPY --chown=oracle:dba configurePrebuiltPdb.sh "$SCRIPT_BASE_DIR"/configurePrebuiltPdb.sh +COPY --chown=oracle:dba startPrebuilt.sh "$ORACLE_BASE"/startPrebuilt.sh +COPY --chown=oracle:dba build/prepareFreeImage.sh /tmp/prepareFreeImage.sh +RUN chmod 755 "$ORACLE_BASE/startPrebuilt.sh" + +# Creating the database +RUN "$ORACLE_BASE/$RUN_FILE" --nowait \ + && "$SCRIPT_BASE_DIR/${SHUTDOWN_FILE:-shutDown.sh}" immediate \ + && /bin/bash /tmp/prepareFreeImage.sh \ + && rm -f /tmp/prepareFreeImage.sh + +# Rebuild the final image from the clean base stage so build-time database +# layers are not retained in the final image. +# hadolint ignore=DL3006 +FROM ${BASE_IMAGE}-base + +ARG ORACLE_SID +ARG ORACLE_PWD +ARG ENABLE_ARCHIVELOG +ARG ENABLE_FORCE_LOGGING +ARG AUTO_MEM_CALCULATION + +ENV ENABLE_ARCHIVELOG=${ENABLE_ARCHIVELOG:-true} +ENV ENABLE_FORCE_LOGGING=${ENABLE_FORCE_LOGGING:-true} +ENV ORACLE_SID=${ORACLE_SID:-FREE} +ENV ORACLE_PWD=${ORACLE_PWD} +ENV AUTO_MEM_CALCULATION=${AUTO_MEM_CALCULATION:-false} + +USER oracle +COPY --from=prebuilt $ORACLE_BASE $ORACLE_BASE +COPY --from=prebuilt /tmp/prebuilt-runtime /tmp/prebuilt-runtime + +USER root +COPY build/finalizeFreeImage.sh /tmp/finalizeFreeImage.sh +RUN /bin/bash /tmp/finalizeFreeImage.sh \ + && rm -f /tmp/finalizeFreeImage.sh + +USER oracle +WORKDIR /home/oracle + +HEALTHCHECK --interval=1m --start-period=1m --timeout=30s \ + CMD "$ORACLE_BASE/$CHECK_DB_FILE" >/dev/null || exit 1 + +EXPOSE 1521/tcp + +CMD [ "/bin/bash", "-c", "exec $ORACLE_BASE/startPrebuilt.sh" ] diff --git a/OracleDatabase/SingleInstance/extensions/prebuiltdb/README.md b/OracleDatabase/SingleInstance/extensions/prebuiltdb/README.md index bfaf1bd0cf..c18511fa3b 100644 --- a/OracleDatabase/SingleInstance/extensions/prebuiltdb/README.md +++ b/OracleDatabase/SingleInstance/extensions/prebuiltdb/README.md @@ -5,7 +5,7 @@ This extension extends [the base Oracle Single Instance Database image](../../RE The configurable parameters while building this extension are as follows: - ORACLE_SID -- ORACLE_PDB +- ORACLE_PDB (non-Free images) - ORACLE_PWD - ENABLE_ARCHIVELOG - ENABLE_FORCE_LOGGING @@ -19,6 +19,61 @@ Example command for building this extension is as: The detailed instructions for building extensions are [here](../README.md). +EE/SE2 and other non-Free images use the original `Dockerfile`: the database +and PDB remain in the image, without the slimming or extraction steps below. + +## Free image optimizations + +`buildExtensions.sh` selects `Dockerfile.free` when the base image has +`release=Free` in its labels. It reads the base version from the `version` +label unless `-v` is supplied, so custom image tags are supported. +For a direct build, select `-f Dockerfile.free` and provide the matching +clean `-base` image. + +For Free builds through `buildExtensions.sh`, a matching +`-base` stage is created automatically. The prebuilt database is +created in the first stage, while the final image is rebuilt from that clean +base stage so build-time database layers are not retained in the resulting +image. Build-time diagnostic output under `diag` and +`cfgtoollogs` is also removed after the database is shut down; Oracle +recreates the required diagnostic directories when the container starts. The +contents of `$ORACLE_HOME/assistants/dbca/templates` are removed as well, +since the prebuilt startup path does not run DBCA. + +Standard DBCA templates are removed from the Free prebuilt image because its +normal startup path does not run database creation with DBCA. True Cache's +DBCA operations do not require those standard database-creation templates. + +When combining extensions for Free images, `prebuiltdb` must come first, +for example `-x 'prebuiltdb truecache sharding'`. The build script rejects +other positions because the clean final stage would discard earlier +extensions' environment settings and files outside `ORACLE_BASE`. + +Free prebuilt images use `FREEPDB1`, the same as standard Free images. The +prebuilt PDB datafiles are retained in the compressed archive and opened +during startup. `ORACLE_PDB` is ignored for Free images. + +To reduce the unpacked image footprint, the final image stores the prebuilt +`oradata` directory as a compressed archive. The archive is expanded once by +`startPrebuilt.sh` before the normal Oracle entrypoint runs. This reduces the +image's on-disk footprint, but adds extraction time to the first +startup and requires writable storage for `oradata`; the database files still +occupy their normal runtime space after extraction. + +When `TRUE_CACHE=true`, archive extraction is skipped because True Cache +creates its own instance from the primary database. + +After successful extraction, stopping and starting the same container reuses +the database files. If extraction is interrupted, an in-progress marker causes +the next startup to retry extraction before starting Oracle. + +For Free prebuilt images, character-set conversion is attempted only when +`ORACLE_CHARACTERSET` is supplied. On each container start, the PDB's current +character set is compared with the supplied value. If they differ, the PDB +is converted after it is opened and before the database password is updated. +Conversion is skipped when the values match or `ORACLE_CHARACTERSET` is +omitted. New database creation continues to default to `AL32UTF8`. + This extended image can be run as follows: ``` @@ -35,14 +90,17 @@ helm install db21c --set image=,persistence=null oracle-db-1.0.0.tgz ## Advantages -This extended image includes an already setup database inside the image itself. Although the image size is larger, the startup time of the container includes only the database startup itself, which makes the container startup duration just a couple of seconds. +This extended image includes an already setup database inside the image itself. +Non-Free images start that database directly. Free images additionally extract +the database files and open the prebuilt PDB on startup. This extended image would be very useful in CI/CD scenarios, where database would be used for conducting tests, experiments and the workflow is simple. ## Limitations Some limitations are listed as follows: -- **External volume can not be used** for database persistence (as data files are inside the image itself). +- Non-Free images store the database files inside the image; mounting an empty external volume hides those files. +- Free images can extract into an empty, Oracle-writable `oradata` volume. An existing nonempty directory is left untouched unless an interrupted-extraction marker is present. - In Kubernetes environment, **the single replica mode** (i.e. replicas=1) can be used for database deployments. - The database created will not use more than 2GB of memory. - The amount of memory allocated for the database is calculated during creation of the database, which runs during the image build phase. By default, `AUTO_MEM_CALCULATION` is `false` so that the container built with this extension is portable, but it also means that the database inside of the containers deployed with this image will not use more than 2GB, even if more is available/allocated. diff --git a/OracleDatabase/SingleInstance/extensions/prebuiltdb/build/finalizeFreeImage.sh b/OracleDatabase/SingleInstance/extensions/prebuiltdb/build/finalizeFreeImage.sh new file mode 100755 index 0000000000..50047d955d --- /dev/null +++ b/OracleDatabase/SingleInstance/extensions/prebuiltdb/build/finalizeFreeImage.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 2026 Oracle and/or its affiliates. All rights reserved. +# +# Since: September, 2026 +# Author: mohammed.qureshi@oracle.com +# Description: Restore runtime files and complete the Free image root setup. +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# + +set -euo pipefail + +: "${ORACLE_BASE:?}" +: "${ORACLE_HOME:?}" + +if [ -f /tmp/prebuilt-runtime/oratab ]; then + cp /tmp/prebuilt-runtime/oratab /etc/oratab + chown oracle:oinstall /etc/oratab +fi +if [ -f /tmp/prebuilt-runtime/oracle-free-26ai ]; then + cp /tmp/prebuilt-runtime/oracle-free-26ai /etc/init.d/oracle-free-26ai +fi + +"${ORACLE_BASE}/oraInventory/orainstRoot.sh" +"${ORACLE_HOME}/root.sh" + +if [ -f /tmp/prebuilt-runtime/oracle-free-26ai.LICENSE ]; then + mkdir -p /usr/share/doc/oracle-free-26ai /licenses + cp /tmp/prebuilt-runtime/oracle-free-26ai.LICENSE /usr/share/doc/oracle-free-26ai/LICENSE + cp /tmp/prebuilt-runtime/oracle-free-26ai.LICENSE /licenses/license.txt + chmod 644 /usr/share/doc/oracle-free-26ai/LICENSE /licenses/license.txt +fi + +rm -rf /tmp/prebuilt-runtime diff --git a/OracleDatabase/SingleInstance/extensions/prebuiltdb/build/prepareFreeImage.sh b/OracleDatabase/SingleInstance/extensions/prebuiltdb/build/prepareFreeImage.sh new file mode 100755 index 0000000000..74e03248de --- /dev/null +++ b/OracleDatabase/SingleInstance/extensions/prebuiltdb/build/prepareFreeImage.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 2026 Oracle and/or its affiliates. All rights reserved. +# +# Since: September, 2026 +# Author: mohammed.qureshi@oracle.com +# Description: Clean and archive the Free prebuilt database for the final image. +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# + +set -euo pipefail + +: "${ORACLE_BASE:?}" +: "${ORACLE_HOME:?}" + +# The database must be shut down before cleanup and archiving. +rm -rf "${ORACLE_BASE}/diag" "${ORACLE_BASE}/cfgtoollogs" +if [ -d "${ORACLE_HOME}/assistants/dbca/templates" ]; then + find "${ORACLE_HOME}/assistants/dbca/templates" -mindepth 1 -delete +fi + +# Store only the archive in the final image. +tar --sparse --create \ + --gzip \ + --file="${ORACLE_BASE}/prebuilt-oradata.tar.gz" \ + -C "${ORACLE_BASE}" oradata +rm -rf "${ORACLE_BASE}/oradata" +mkdir -p "${ORACLE_BASE}/oradata" + +# Preserve OS files that are outside ORACLE_BASE for the final stage. +mkdir -p /tmp/prebuilt-runtime +if [ -f /etc/oratab ]; then + cp /etc/oratab /tmp/prebuilt-runtime/oratab +fi +if [ -f /etc/init.d/oracle-free-26ai ]; then + cp /etc/init.d/oracle-free-26ai /tmp/prebuilt-runtime/oracle-free-26ai +fi +if [ -f /usr/share/doc/oracle-free-26ai/LICENSE ]; then + cp /usr/share/doc/oracle-free-26ai/LICENSE /tmp/prebuilt-runtime/oracle-free-26ai.LICENSE +fi diff --git a/OracleDatabase/SingleInstance/extensions/prebuiltdb/configurePrebuiltPdb.sh b/OracleDatabase/SingleInstance/extensions/prebuiltdb/configurePrebuiltPdb.sh new file mode 100755 index 0000000000..a3bd14d28a --- /dev/null +++ b/OracleDatabase/SingleInstance/extensions/prebuiltdb/configurePrebuiltPdb.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# LICENSE UPL 1.0 +# +# Copyright (c) 2026 Oracle and/or its affiliates. All rights reserved. +# +# Since: September, 2026 +# Author: mohammed.qureshi@oracle.com +# Description: Configure the PDB for a Free prebuilt database. +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# + +set -euo pipefail + +PDB_NAME="FREEPDB1" + +REQUESTED_CHARACTERSET="${1:-}" + +if [ -n "$REQUESTED_CHARACTERSET" ]; then + REQUESTED_CHARACTERSET="${REQUESTED_CHARACTERSET^^}" +fi + +if [ -n "$REQUESTED_CHARACTERSET" ]; then + CHARACTERSET_PATTERN='^[A-Z][A-Z0-9_$#]*$' + + if [[ ! "$REQUESTED_CHARACTERSET" =~ $CHARACTERSET_PATTERN ]]; then + echo "ERROR: invalid ORACLE_CHARACTERSET value: $REQUESTED_CHARACTERSET" >&2 + exit 1 + fi +fi + +"${ORACLE_HOME}/bin/sqlplus" -s / as sysdba < 'READ WRITE' THEN + EXECUTE IMMEDIATE + 'ALTER PLUGGABLE DATABASE "${PDB_NAME}" OPEN READ WRITE FORCE'; + END IF; + + EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE "${PDB_NAME}" SAVE STATE'; +END; +/ + +ALTER SYSTEM REGISTER; +EXIT; +SQL + +if [ -n "$REQUESTED_CHARACTERSET" ]; then + CURRENT_CHARACTERSET="$(${ORACLE_HOME}/bin/sqlplus -s / as sysdba <> "${tns_file}" < ${host}:${port}/${service}." +} + +ensure_primary_tns_aliases() { + local primary_host="${ORACLE_HOSTNAME:-$(hostname)}" + local truecache_host="${TC_CONNECT_STR%%:*}" + local truecache_port="${TC_CONNECT_STR#*:}" + truecache_port="${truecache_port%%/*}" + ensure_tns_alias "${PRIMARY_SVCNAME}" "${primary_host}" "1521" "${PRIMARY_SVCNAME}" + ensure_tns_alias "${TC_SVCNAME}" "${truecache_host}" "${truecache_port:-1521}" "${TC_SVCNAME}" +} + log_debug_context() { local password_mode @@ -611,13 +637,16 @@ print_message "Sanitized PATH to keep only ORACLE_HOME runtime binaries first: $ print_message "Using ORACLE_SID ${ORACLE_SID} for local SYSDBA connectivity." print_message "Using sourceDB ${SOURCE_DB} for True Cache service configuration." if truecache_service_already_configured; then + ensure_primary_tns_aliases exit 0 fi if wait_for_existing_truecache_configuration; then + ensure_primary_tns_aliases exit 0 fi ensure_primary_service_ready if truecache_service_already_configured; then + ensure_primary_tns_aliases exit 0 fi @@ -652,3 +681,4 @@ else -serviceName "${PRIMARY_SVCNAME}" \ -pdbName "${PRIMARY_PDB_NAME}" fi +ensure_primary_tns_aliases diff --git a/OracleDatabase/SingleInstance/extensions/truecache/createBlob.sh b/OracleDatabase/SingleInstance/extensions/truecache/createBlob.sh index c04e9f5df0..86ef97819d 100755 --- a/OracleDatabase/SingleInstance/extensions/truecache/createBlob.sh +++ b/OracleDatabase/SingleInstance/extensions/truecache/createBlob.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2086 # LICENSE UPL 1.0 # # Copyright (c) 2024-2026 Oracle and/or its affiliates. All rights reserved. diff --git a/OracleDatabase/SingleInstance/extensions/truecache/createService.sh b/OracleDatabase/SingleInstance/extensions/truecache/createService.sh index 3e5c0cfe18..7208cd6767 100755 --- a/OracleDatabase/SingleInstance/extensions/truecache/createService.sh +++ b/OracleDatabase/SingleInstance/extensions/truecache/createService.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090 # LICENSE UPL 1.0 # # Copyright (c) 2024-2026 Oracle and/or its affiliates. All rights reserved. diff --git a/OracleDatabase/SingleInstance/extensions/truecache/registerService.sh b/OracleDatabase/SingleInstance/extensions/truecache/registerService.sh index 46b68b0bda..8916e153c4 100755 --- a/OracleDatabase/SingleInstance/extensions/truecache/registerService.sh +++ b/OracleDatabase/SingleInstance/extensions/truecache/registerService.sh @@ -1,5 +1,5 @@ #!/bin/bash -# shellcheck disable=SC2154,SC2155,SC2166 +# shellcheck disable=SC2001,SC2002,SC2006,SC2086,SC2154,SC2155,SC2162,SC2166,SC2236 # LICENSE UPL 1.0 # # Copyright (c) 2024-2026 Oracle and/or its affiliates. All rights reserved. @@ -82,6 +82,30 @@ function normalizeServiceName { printf '%s' "${value^^}" } +# Keep service aliases available even when DBCA does not write them. +function ensureTNSAlias { + local alias=$1 host=$2 port=$3 service=$4 + local tns_file="${TNS_ADMIN:-${ORACLE_HOME}/network/admin}/tnsnames.ora" + [ -n "${alias}" ] && [ -n "${host}" ] && [ -n "${port}" ] && [ -n "${service}" ] || return 1 + mkdir -p "$(dirname "${tns_file}")" && touch "${tns_file}" || return 1 + grep -qiE "^[[:space:]]*${alias}[[:space:]]*=" "${tns_file}" && return 0 + cat >> "${tns_file}" < ${host}:${port}/${service}." +} + +function ensureTrueCacheTNSAliases { + local local_host="${ORACLE_HOSTNAME:-$(hostname)}" + ensureTNSAlias "${PRIMARY_DB_APP_SVC}" "${PRIMARY_DB_HOST}" "${PRIMARY_DB_PORT:-1521}" "${PRIMARY_DB_APP_SVC}" + ensureTNSAlias "${TRUE_CACHE_DB_APP_SVC}" "${local_host}" "1521" "${TRUE_CACHE_DB_APP_SVC}" +} + function formatPendingAssociationValue { local value @@ -919,9 +943,11 @@ if [[ "${TRUE_CACHE}" == "true" ]]; then print_message "running primary-host registration helper for PRIMARY_SERVICE=${PRIMARY_DB_APP_SVC} TRUECACHE_SERVICE=${TRUE_CACHE_DB_APP_SVC}" createTCSvc startTrueCacheSvc + ensureTrueCacheTNSAliases checkTCSvc || return 1 else printManualPrimaryRegistrationReminder fi + ensureTrueCacheTNSAliases done fi diff --git a/OracleDatabase/SingleInstance/extensions/truecache/setup.sh b/OracleDatabase/SingleInstance/extensions/truecache/setup.sh index 6fd541b54c..ca507ee52f 100755 --- a/OracleDatabase/SingleInstance/extensions/truecache/setup.sh +++ b/OracleDatabase/SingleInstance/extensions/truecache/setup.sh @@ -1,5 +1,5 @@ #!/bin/bash -# shellcheck disable=SC2034,SC2120,SC2153,SC2155 +# shellcheck disable=SC2002,SC2034,SC2086,SC2119,SC2120,SC2153,SC2155,SC2162,SC2236 # LICENSE UPL 1.0 # # Copyright (c) 2024-2026 Oracle and/or its affiliates. All rights reserved.