Oracle Database 21c XE, setting up a demo environment using Vagrant and Oracle VirtualBox (part 2)

Marc Lameriks

I wanted to set up a demo environment with Apache Kafka (an open-source distributed event streaming platform) and an Oracle Database, all within containers. For my purpose I opted for Oracle Database XE.
[https://kafka.apache.org/]

As I did before, on my Windows laptop, I wanted to use a demo environment within an Oracle VirtualBox appliance, with the help of Vagrant.

I am going to use Linux, and at the time I wrote this article, the general availability of Oracle Database 21c Express Edition (XE) on Linux was announced!
[https://blogs.oracle.com/database/post/oracle-database-21c-xe-generally-available]

In a series of articles, I will take you with me on my path to set everything up.

In this article I will share with you the steps I took, to set up a demo environment with an Oracle Database XE. The focus in this article will be on Oracle Database 21c XE and the problems I encountered.

Stop the running machine

I continue where I left off in the previous article, where I created an Oracle VirtualBox appliance with
Oracle Database 18.4.0 XE, with the help of Vagrant.
[Oracle Database 21c XE, setting up a demo environment using Vagrant and Oracle VirtualBox (part 1)]

I wanted to start more or less from scratch, and with Vagrant that’s no problem.

From the subdirectory named env on my Windows laptop, I opened a Windows Command Prompt (cmd) and typed:

vagrant destroy

With the following output:

    ubuntu_docker: Are you sure you want to destroy the 'ubuntu_docker' VM? [y/N] y
==> ubuntu_docker: Destroying VM and associated drives...

Next, I typed:

vagrant up

With the following output (only showing certain parts):

Bringing machine 'ubuntu_docker' up with 'virtualbox' provider...
==> ubuntu_docker: Box 'ubuntu/focal64' could not be found. Attempting to find and install...
    ubuntu_docker: Box Provider: virtualbox
    ubuntu_docker: Box Version: >= 0
==> ubuntu_docker: Loading metadata for box 'ubuntu/focal64'
    ubuntu_docker: URL: https://vagrantcloud.com/ubuntu/focal64
==> ubuntu_docker: Adding box 'ubuntu/focal64' (v20211026.0.0) for provider: virtualbox
    ubuntu_docker: Downloading: https://vagrantcloud.com/ubuntu/boxes/focal64/versions/20211026.0.0/providers/virtualbox.box
Download redirected to host: cloud-images.ubuntu.com
    ubuntu_docker:
==> ubuntu_docker: Successfully added box 'ubuntu/focal64' (v20211026.0.0) for 'virtualbox'!
==> ubuntu_docker: Importing base box 'ubuntu/focal64'...
…
==> ubuntu_docker: Mounting shared folders...
    ubuntu_docker: /vagrant => C:/My/AMIS/env
…
    ubuntu_docker: **** Begin installing Docker Engine
…
    ubuntu_docker: Unable to find image 'hello-world:latest' locally
    ubuntu_docker: latest: Pulling from library/hello-world
    ubuntu_docker: 2db29710123e: Pulling fs layer
    ubuntu_docker: 2db29710123e: Verifying Checksum
    ubuntu_docker: 2db29710123e: Download complete
    ubuntu_docker: 2db29710123e: Pull complete
    ubuntu_docker: Digest: sha256:37a0b92b08d4919615c3ee023f7ddb068d12b8387475d64c622ac30f45c29c51
    ubuntu_docker: Status: Downloaded newer image for hello-world:latest
    ubuntu_docker:
    ubuntu_docker: Hello from Docker!
    ubuntu_docker: This message shows that your installation appears to be working correctly.
    ubuntu_docker:
    ubuntu_docker: To generate this message, Docker took the following steps:
    ubuntu_docker:  1. The Docker client contacted the Docker daemon.
    ubuntu_docker:  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    ubuntu_docker:     (amd64)
    ubuntu_docker:  3. The Docker daemon created a new container from that image which runs the
    ubuntu_docker:     executable that produces the output you are currently reading.
    ubuntu_docker:  4. The Docker daemon streamed that output to the Docker client, which sent it
    ubuntu_docker:     to your terminal.
    ubuntu_docker:
    ubuntu_docker: To try something more ambitious, you can run an Ubuntu container with:
    ubuntu_docker:  &docker run -it ubuntu bash
    ubuntu_docker:
    ubuntu_docker: Share images, automate workflows, and more with a free Docker ID:
    ubuntu_docker:  https://hub.docker.com/
    ubuntu_docker:
    ubuntu_docker: For more examples and ideas, visit:
    ubuntu_docker:  https://docs.docker.com/get-started/
    ubuntu_docker:
    ubuntu_docker: **** End installing Docker Engine

Creating dockerfiles for Oracle Database 21c XE

As I mentioned in my previous article, for setting up my demo environment, I opted for setting up a Linux VirtualBox VM myself, by using Vagrant scripts (as I did many times before), and installing the Oracle Database XE by using the Linux Docker image, which can be built using the Dockerfile, provided on github.

Looking at the README.md, the most recent container image for XE was: Oracle Database 18c (18.4.0) Express Edition (XE). As I mentioned in my previous article, from the docker-images-main.zip, I downloaded earlier from github, I extracted directory OracleDatabase\SingleInstance\dockerfiles\18.4.0 to directory C:\My\AMIS\env\oraclexedatabase\dockerfiles\18.4.0 on my Windows laptop.
[https://github.com/oracle/docker-images/blob/main/OracleDatabase/SingleInstance/README.md]

I reckoned that perhaps I could change the existing 18.4.0 scripts so they would work for 21c.

So, I made a copy of the 18.4.0 directory and named it 21.0.0 (not being sure what the exact version would be, I left it at this for the time being).
Then I had to change the content of a number of files.

Content of file Dockerfile.xe:
[in bold, I highlighted the changes]

# LICENSE UPL 1.0
#
# Copyright (c) 2018, 2020 Oracle and/or its affiliates.
#
# ORACLE DOCKERFILES PROJECT
# --------------------------
# This is the Dockerfile 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.0.0-xe -f Dockerfile.xe .
#
#
# Pull base image
# ---------------
FROM oraclelinux:7-slim

# Labels
# ------
LABEL "provider"="Oracle"                                               \
      "issues"="https://github.com/oracle/docker-images/issues"         \
      "volume.data"="/opt/oracle/oradata"                               \
      "volume.setup.location1"="/opt/oracle/scripts/setup"              \
      "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.oemexpress"="5500"                                          \
      "port.apex"="8080"

# Environment variables required for this build (do NOT change)
# -------------------------------------------------------------
ENV ORACLE_BASE=/opt/oracle \
    ORACLE_HOME=/opt/oracle/product/21c/dbhomeXE \
    ORACLE_SID=XE \
    INSTALL_FILE_1="https://download.oracle.com/otn-pub/otn_software/db-express/oracle-database-xe-21c-1.0-1.ol8.x86_64.rpm" \
    RUN_FILE="runOracle.sh" \
    PWD_FILE="setPassword.sh" \
    CONF_FILE="oracle-xe-21c.conf" \
    CHECK_SPACE_FILE="checkSpace.sh" \
    CHECK_DB_FILE="checkDBStatus.sh" \
    INSTALL_DIR="$HOME/install" \
    ORACLE_DOCKER_INSTALL="true"

# Use second ENV so that variable get substituted
ENV PATH=$ORACLE_HOME/bin:$PATH

# Copy binaries
# -------------
COPY $CHECK_SPACE_FILE $RUN_FILE $PWD_FILE $CHECK_DB_FILE $CONF_FILE $INSTALL_DIR/

RUN chmod ug+x $INSTALL_DIR/*.sh && \
    sync && \
    $INSTALL_DIR/$CHECK_SPACE_FILE && \
    cd $INSTALL_DIR && \
    yum -y install openssl oracle-database-preinstall-21c && \
    sed -i -e 's/\(oracle\s\+hard\s\+nofile\)/# \1/' /etc/security/limits.d/oracle-database-preinstall-21c.conf && \
    yum -y localinstall $INSTALL_FILE_1 && \
    rm -rf /var/cache/yum && \
    rm -rf /var/tmp/yum-* && \
    mkdir -p $ORACLE_BASE/scripts/setup && \
    mkdir $ORACLE_BASE/scripts/startup && \
    ln -s $ORACLE_BASE/scripts /docker-entrypoint-initdb.d && \
    mkdir -p $ORACLE_BASE/oradata /home/oracle && \
    chown -R oracle:oinstall $ORACLE_BASE /home/oracle && \
    mv $INSTALL_DIR/$RUN_FILE $ORACLE_BASE/ && \
    mv $INSTALL_DIR/$PWD_FILE $ORACLE_BASE/ && \
    mv $INSTALL_DIR/$CHECK_DB_FILE $ORACLE_BASE/ && \
    mv $INSTALL_DIR/$CONF_FILE /etc/sysconfig/ && \
    ln -s $ORACLE_BASE/$PWD_FILE / && \
    cd $HOME && \
    rm -rf $INSTALL_DIR && \
    chmod ug+x $ORACLE_BASE/*.sh

HEALTHCHECK --interval=1m --start-period=5m \
   CMD "$ORACLE_BASE/$CHECK_DB_FILE" >/dev/null || exit 1

CMD exec $ORACLE_BASE/$RUN_FILE

I renamed file oracle-xe-18c.conf to oracle-xe-21c.conf, with content:
[in bold, I highlighted the changes]

# This is a configuration file to setup the Oracle Database. 
# It is used when running '/etc/init.d/oracle-xe-21c configure'.

# LISTENER PORT used Database listener, Leave empty for automatic port assignment
LISTENER_PORT=1521

# EM_EXPRESS_PORT Oracle EM Express URL port
EM_EXPRESS_PORT=5500

# Character set of the database
CHARSET=###ORACLE_CHARACTERSET###

# Database file directory
# If not specified, database files are stored under Oracle base/oradata
DBFILE_DEST=

# SKIP Validations, memory, space
SKIP_VALIDATIONS=false

Content of file runOracle.sh:
[in bold, I highlighted the changes]

#!/bin/bash

############# Execute custom scripts ##############
function runUserScripts {

  SCRIPTS_ROOT="$1";

  # Check whether parameter has been passed on
  if [ -z "$SCRIPTS_ROOT" ]; then
    echo "$0: No SCRIPTS_ROOT passed on, no scripts will be run";
    exit 1;
  fi;
  
  # Execute custom provided files (only if directory exists and has files in it)
  if [ -d "$SCRIPTS_ROOT" ] && [ -n "$(ls -A $SCRIPTS_ROOT)" ]; then
      
    echo "";
    echo "Executing user defined scripts"
  
    for f in $SCRIPTS_ROOT/*; do
        case "$f" in
            *.sh)     echo "$0: running $f"; . "$f" ;;
            *.sql)    echo "$0: running $f"; echo "exit" | su -p oracle -c "$ORACLE_HOME/bin/sqlplus / as sysdba @$f"; echo ;;
            *)        echo "$0: ignoring $f" ;;
        esac
        echo "";
    done
    
    echo "DONE: Executing user defined scripts"
    echo "";
  
  fi;
  
}

########### Move DB files ############
function moveFiles {
   if [ ! -d $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID ]; then
      su -p oracle -c "mkdir -p $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/"
   fi;
   
   su -p oracle -c "mv $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/"
   su -p oracle -c "mv $ORACLE_HOME/dbs/orapw$ORACLE_SID $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/"
   su -p oracle -c "mv $ORACLE_HOME/network/admin/listener.ora $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/"
   su -p oracle -c "mv $ORACLE_HOME/network/admin/tnsnames.ora $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/"

   cp /etc/oratab $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/
      
   symLinkFiles;
}

########### Symbolic link DB files ############
function symLinkFiles {

   if [ ! -L $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora ]; then
      ln -s $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/spfile$ORACLE_SID.ora $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora
   fi;
   
   if [ ! -L $ORACLE_HOME/dbs/orapw$ORACLE_SID ]; then
      ln -s $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/orapw$ORACLE_SID $ORACLE_HOME/dbs/orapw$ORACLE_SID
   fi;
   
   if [ ! -L $ORACLE_HOME/network/admin/listener.ora ]; then
      ln -sf $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/listener.ora $ORACLE_HOME/network/admin/listener.ora
   fi;
   
   if [ ! -L $ORACLE_HOME/network/admin/tnsnames.ora ]; then
      ln -sf $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/tnsnames.ora $ORACLE_HOME/network/admin/tnsnames.ora
   fi;
   
   cp $ORACLE_BASE/oradata/dbconfig/$ORACLE_SID/oratab /etc/oratab
}

########### Opposite of the above ############
function undoSymLinkFiles {

   if [ -L $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora ]; then
      rm $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora
   fi;

   if [ -L $ORACLE_HOME/dbs/orapw$ORACLE_SID ]; then
      rm $ORACLE_HOME/dbs/orapw$ORACLE_SID
   fi;

   if [ -L $ORACLE_HOME/network/admin/listener.ora ]; then
      rm $ORACLE_HOME/network/admin/listener.ora
   fi;

   if [ -L $ORACLE_HOME/network/admin/tnsnames.ora ]; then
      rm $ORACLE_HOME/network/admin/tnsnames.ora
   fi;

   sed -i "\|${ORACLE_SID}:${ORACLE_HOME}|d" /etc/oratab
}
########### SIGTERM handler ############
function _term() {
   echo "Stopping container."
   echo "SIGTERM received, shutting down database!"
  /etc/init.d/oracle-xe-21c stop
}

############# Create DB ################
function createDB {
   # Auto generate ORACLE PWD if not passed on
   export ORACLE_PWD=${ORACLE_PWD:-"`openssl rand -hex 8`"}
   echo "ORACLE PASSWORD FOR SYS AND SYSTEM: $ORACLE_PWD";
   
   # Set character set
   export ORACLE_CHARACTERSET=${ORACLE_CHARACTERSET:-AL32UTF8}
   sed -i -e "s|###ORACLE_CHARACTERSET###|$ORACLE_CHARACTERSET|g" /etc/sysconfig/$CONF_FILE

   (echo "$ORACLE_PWD"; echo "$ORACLE_PWD";) | /etc/init.d/oracle-xe-21c configure

   # Listener 
   echo "# listener.ora Network Configuration File:
         
         SID_LIST_LISTENER = 
           (SID_LIST =
             (SID_DESC =
               (SID_NAME = PLSExtProc)
               (ORACLE_HOME = $ORACLE_HOME)
               (PROGRAM = extproc)
             )
           )
         
         LISTENER =
           (DESCRIPTION_LIST =
             (DESCRIPTION =
               (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
               (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
             )
           )
         
         DEFAULT_SERVICE_LISTENER = (XE)" > $ORACLE_HOME/network/admin/listener.ora

# TNS Names.ora
   echo "# tnsnames.ora Network Configuration File:

XE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE)
    )
  )

LISTENER_XE =
  (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))

XEPDB1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XEPDB1)
    )
  )

EXTPROC_CONNECTION_DATA =	
  (DESCRIPTION =
     (ADDRESS_LIST =
       (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE))
     )
     (CONNECT_DATA =
       (SID = PLSExtProc)
       (PRESENTATION = RO)
     )
  )
" > $ORACLE_HOME/network/admin/tnsnames.ora

  # Move database operational files to oradata
  moveFiles;
}

############# MAIN ################

# Set SIGTERM handler
trap _term SIGTERM

# Check whether database already exists
if [ -d $ORACLE_BASE/oradata/$ORACLE_SID ]; then
   symLinkFiles;
   # Make sure audit file destination exists
   if [ ! -d $ORACLE_BASE/admin/$ORACLE_SID/adump ]; then
      su -p oracle -c "mkdir -p $ORACLE_BASE/admin/$ORACLE_SID/adump"
   fi;
else
    # If the oradata folder is missing/empty, but db was previously set up,
    # allow a new db to be set up in its place
    undoSymLinkFiles;
fi;

/etc/init.d/oracle-xe-21c start | grep -qc "Oracle Database is not configured"
if [ "$?" == "0" ]; then
   # Create database
   createDB;
   
   # Execute custom provided setup scripts
   runUserScripts $ORACLE_BASE/scripts/setup
fi;

# Check whether database is up and running
$ORACLE_BASE/$CHECK_DB_FILE
if [ $? -eq 0 ]; then
  echo "#########################"
  echo "DATABASE IS READY TO USE!"
  echo "#########################"

  # Execute custom provided startup scripts
  runUserScripts $ORACLE_BASE/scripts/startup

else
  echo "#####################################"
  echo "########### E R R O R ###############"
  echo "DATABASE SETUP WAS NOT SUCCESSFUL!"
  echo "Please check output for further info!"
  echo "########### E R R O R ###############"
  echo "#####################################"
fi;

echo "The following output is now a tail of the alert.log:"
tail -f $ORACLE_BASE/diag/rdbms/*/*/trace/alert*.log &
childPID=$!
wait $childPID

Next, I had a looked at file buildContainerImage.sh and search for 18.4.0 in the file. Then, I changed the content of the file:
[in bold, I highlighted the changes]

#!/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,2021 Oracle and/or its affiliates.
# 

usage() {
  cat << EOF

Usage: buildContainerImage.sh -v [version] -t [image_name:tag] [-e | -s | -x] [-i] [-o] [container build option]
Builds a container image for Oracle Database.

Parameters:
   -v: version to build
       Choose one of: $(for i in */; do echo -n "${i%%/}  "; done)
   -t: image_name:tag for the generated docker image
   -e: creates image based on 'Enterprise Edition'
   -s: creates image based on 'Standard Edition 2'
   -x: creates image based on 'Express Edition'
   -i: ignores the MD5 checksums
   -o: passes on container build option

* select one edition only: -e, -s, or -x

LICENSE UPL 1.0

Copyright (c) 2014,2021 Oracle and/or its affiliates.

EOF

}

# Validate packages
checksumPackages() {
  if hash md5sum 2>/dev/null; then
    echo "Checking if required packages are present and valid..."   
    if ! md5sum -c "Checksum.${EDITION}"; then
      echo "MD5 for required packages to build this image did not match!"
      echo "Make sure to download missing files in folder ${VERSION}."
      exit 1;
    fi
  else
    echo "Ignored MD5 sum, 'md5sum' command not available.";
  fi
}

# Check container runtime
checkContainerRuntime() {
  CONTAINER_RUNTIME=$(which docker 2>/dev/null) ||
    CONTAINER_RUNTIME=$(which podman 2>/dev/null) ||
    {
      echo "No docker or podman executable found in your PATH"
      exit 1
    }

  if "${CONTAINER_RUNTIME}" info | grep -i -q buildahversion; then
    checkPodmanVersion
  else
    checkDockerVersion
  fi
}

# Check Podman version
checkPodmanVersion() {
  # Get Podman version
  echo "Checking Podman version."
  PODMAN_VERSION=$("${CONTAINER_RUNTIME}" info --format '{{.host.BuildahVersion}}' 2>/dev/null ||
                   "${CONTAINER_RUNTIME}" info --format '{{.Host.BuildahVersion}}')
  # Remove dot in Podman version
  PODMAN_VERSION=${PODMAN_VERSION//./}

  if [ -z "${PODMAN_VERSION}" ]; then
    exit 1;
  elif [ "${PODMAN_VERSION}" -lt "${MIN_PODMAN_VERSION//./}" ]; then
    echo "Podman version is below the minimum required version ${MIN_PODMAN_VERSION}"
    echo "Please upgrade your Podman installation to proceed."
    exit 1;
  fi
}

# Check Docker version
checkDockerVersion() {
  # Get Docker Server version
  echo "Checking Docker version."
  DOCKER_VERSION=$("${CONTAINER_RUNTIME}" version --format '{{.Server.Version | printf "%.5s" }}'|| exit 0)
  # Remove dot in Docker version
  DOCKER_VERSION=${DOCKER_VERSION//./}

  if [ "${DOCKER_VERSION}" -lt "${MIN_DOCKER_VERSION//./}" ]; then
    echo "Docker version is below the minimum required version ${MIN_DOCKER_VERSION}"
    echo "Please upgrade your Docker installation to proceed."
    exit 1;
  fi;
}

##############
#### MAIN ####
##############

# Go into dockerfiles directory
cd $(dirname $0)

# Parameters
ENTERPRISE=0
STANDARD=0
EXPRESS=0
# Obtaining the latest version to build
VERSION="$(ls -1rd *.*.* | sed -n 1p)"
SKIPMD5=0
declare -a BUILD_OPTS
MIN_DOCKER_VERSION="17.09"
MIN_PODMAN_VERSION="1.6.0"
DOCKERFILE="Dockerfile"
IMAGE_NAME=""

if [ "$#" -eq 0 ]; then
  usage;
  exit 1;
fi

while getopts "hesxiv:t:o:" optname; do
  case "${optname}" in
    "h")
      usage
      exit 0;
      ;;
    "i")
      SKIPMD5=1
      ;;
    "e")
      ENTERPRISE=1
      ;;
    "s")
      STANDARD=1
      ;;
    "x")
      EXPRESS=1
      ;;
    "v")
      VERSION="${OPTARG}"
      ;;
    "t")
      IMAGE_NAME="${OPTARG}"
      ;;
    "o")
      eval "BUILD_OPTS=(${OPTARG})"
      ;;
    "?")
      usage;
      exit 1;
      ;;
    *)
    # Should not occur
      echo "Unknown error while processing options inside buildContainerImage.sh"
      ;;
  esac
done

# Check that we have a container runtime installed
checkContainerRuntime

# Which Edition should be used?
if [ $((ENTERPRISE + STANDARD + EXPRESS)) -gt 1 ]; then
  usage
elif [ ${ENTERPRISE} -eq 1 ]; then
  EDITION="ee"
elif [ ${STANDARD} -eq 1 ]; then
  EDITION="se2"
elif [ ${EXPRESS} -eq 1 ]; then
  if [ "${VERSION}" == "21.0.0" ]; then
    EDITION="xe"
    SKIPMD5=1
  elif [ "${VERSION}" == "18.4.0" ]; then
    EDITION="xe"
    SKIPMD5=1
  elif [ "${VERSION}" == "11.2.0.2" ]; then
    EDITION="xe"
    BUILD_OPTS=("--shm-size=1G" "${BUILD_OPTS[@]}")
  else
    echo "Version ${VERSION} does not have Express Edition available.";
    exit 1;
  fi;
fi;

# Which Dockerfile should be used?
if [ "${VERSION}" == "12.1.0.2" ] || [ "${VERSION}" == "11.2.0.2" ] || [ "${VERSION}" == "21.0.0" ] || [ "${VERSION}" == "18.4.0" ]; then
  DOCKERFILE="${DOCKERFILE}.${EDITION}"
fi;

# Oracle Database image Name
# If provided using -t build option then use it; Otherwise, create with version and edition
if [ -z "${IMAGE_NAME}" ]; then
  IMAGE_NAME="oracle/database:${VERSION}-${EDITION}"
fi;

# Go into version folder
cd "${VERSION}" || {
  echo "Could not find version directory '${VERSION}'";
  exit 1;
}

if [ ! "${SKIPMD5}" -eq 1 ]; then
  checksumPackages
else
  echo "Ignored MD5 checksum."
fi
echo "=========================="
echo "Container runtime info:"
"${CONTAINER_RUNTIME}" info
echo "=========================="

# Proxy settings
declare -a PROXY_SETTINGS
# shellcheck disable=SC2154
if [ "${http_proxy}" != "" ]; then
  PROXY_SETTINGS=("${PROXY_SETTINGS[@]}" "--build-arg" "http_proxy=${http_proxy}")
fi

# shellcheck disable=SC2154
if [ "${https_proxy}" != "" ]; then
  PROXY_SETTINGS=("${PROXY_SETTINGS[@]}" "--build-arg" "https_proxy=${https_proxy}")
fi

# shellcheck disable=SC2154
if [ "${ftp_proxy}" != "" ]; then
  PROXY_SETTINGS=("${PROXY_SETTINGS[@]}" "--build-arg" "ftp_proxy=${ftp_proxy}")
fi

# shellcheck disable=SC2154
if [ "${no_proxy}" != "" ]; then
  PROXY_SETTINGS=("${PROXY_SETTINGS[@]}" "--build-arg" "no_proxy=${no_proxy}")
fi

if [ ${#PROXY_SETTINGS[@]} -gt 0 ]; then
  echo "Proxy settings were found and will be used during the build."
fi

# ################## #
# BUILDING THE IMAGE #
# ################## #
echo "Building image '${IMAGE_NAME}' ..."

# BUILD THE IMAGE (replace all environment variables)
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}" . || {
  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."
  exit 1
}

# Remove dangling images (intermitten images with tag <none>)
yes | "${CONTAINER_RUNTIME}" image prune > /dev/null

BUILD_END=$(date '+%s')
BUILD_ELAPSED=$(( BUILD_END - BUILD_START ))

echo ""
echo ""

cat << EOF
  Oracle Database container image for '${EDITION}' version ${VERSION} is ready to be extended: 
    
    --> ${IMAGE_NAME}

  Build completed in ${BUILD_ELAPSED} seconds.
  
EOF

Remark about shared folder:

Mounting shared folders...
    ubuntu_docker: /vagrant => C:/My/AMIS/env

As you can see in the output from vagrant up via the shared folder, the copied files are now also available from within the Oracle VirtualBox appliance.

Building Oracle Database container image for Oracle Database 12c XE

I used vagrant ssh to connect into the running VM. Next, in order to build the image for Oracle Database 21c XE, I used the following commands on the Linux Command Prompt (similar with what I did for version 18.4.0):

cd /vagrant/oraclexedatabase/dockerfiles
./buildContainerImage.sh -v 21.0.0 -x

Remark:
There are some steps in the process that take a long time, it seems like the process is hanging, but you have to be patience. The whole process can take more than 5 minutes.

With the following output:

WARNING: No swap limit support
Checking Docker version.
Ignored MD5 checksum.
...
Building image 'oracle/database:21.0.0-xe' ...
Sending build context to Docker daemon  19.46kB
Step 1/8 : FROM oraclelinux:7-slim
7-slim: Pulling from library/oraclelinux
4ade2748332d: Pull complete
...
Complete!
Loaded plugins: ovl
...
Transaction test succeeded
Running transaction
  Installing : file-5.11-37.el7.x86_64                                      1/2
  Installing : oracle-database-xe-21c-1.0-1.x86_64                          2/2
[INFO] Executing post installation scripts...
...
Successfully built aa73bfbb6c60
Successfully tagged oracle/database:21.0.0-xe


  Oracle Database container image for 'xe' version 21.0.0 is ready to be extended:

    --> oracle/database:21.0.0-xe

  Build completed in 713 seconds.
vagrant@ubuntu-focal:/vagrant/oraclexedatabase/dockerfiles$

In order to get a list of all the docker images, I used the following command on the Linux Command Prompt:

docker image ls

With the following output:

REPOSITORY        TAG         IMAGE ID       CREATED         SIZE
oracle/database   21.0.0-xe   aa73bfbb6c60   8 seconds ago   6.53GB
oraclelinux       7-slim      1af2d7d8be2c   10 hours ago    132MB
hello-world       latest      feb5d9fea6a5   2 months ago    13.3kB

So, here we can see the image was successfully created.

Running Oracle Database 21c XE in a container

In order to create the container, I used the following command on the Linux Command Prompt (similar with what I did for version 18.4.0):

sudo docker run --name oracle_database_21.0.0-xe \
-p 1521:1521 -p 5500:5500 \
-e ORACLE_PWD=manager \
-e ORACLE_CHARACTERSET=AL32UTF8 \
-v /opt/oracle/oradata:/opt/oracle/oradata \
oracle/database:21.0.0-xe

With the following output:

ORACLE PASSWORD FOR SYS AND SYSTEM: manager
Specify a password to be used for database accounts. Oracle recommends that the password entered should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case character and 1 digit [0-9]. Note that the same password will be used for SYS, SYSTEM and PDBADMIN accounts:
Confirm the password:
Configuring Oracle Listener.
Listener configuration succeeded.
Configuring Oracle Database XE.
Enter SYS user password:
*******
Enter SYSTEM user password:
*******
Enter PDBADMIN User Password:
***********
[FATAL] [DBT-10011] Incorrect ownership/permissions detected for the file (/opt/oracle/product/21c/dbhomeXE/bin/oradism).
   CAUSE: Following nodes does not have required file ownership/permissions: Node :9a4154bb1e13
PRVG-11960 : Set user ID bit is not set for file "/opt/oracle/product/21c/dbhomeXE/bin/oradism" on node "9a4154bb1e13".
PRVG-2031 : Owner of file "/opt/oracle/product/21c/dbhomeXE/bin/oradism" did not match the expected value on node "9a4154bb1e13". [Expected = "root(0)" ; Found = "oracle(54321)"]

   ACTION: Run the Oracle Home root script as the "root" user to fix the permissions.

Database configuration failed. Check logs under '/opt/oracle/cfgtoollogs/dbca'.
mkdir: cannot create directory '/opt/oracle/oradata/dbconfig': Permission denied
mv: cannot stat '/opt/oracle/product/21c/dbhomeXE/dbs/spfileXE.ora': No such file or directory
mv: cannot stat '/opt/oracle/product/21c/dbhomeXE/dbs/orapwXE': No such file or directory
mv: cannot move '/opt/oracle/product/21c/dbhomeXE/network/admin/listener.ora' to '/opt/oracle/oradata/dbconfig/XE/': No such file or directory
mv: cannot move '/opt/oracle/product/21c/dbhomeXE/network/admin/tnsnames.ora' to '/opt/oracle/oradata/dbconfig/XE/': No such file or directory
cp: cannot create regular file '/opt/oracle/oradata/dbconfig/XE/': No such file or directory
cp: cannot stat '/opt/oracle/oradata/dbconfig/XE/oratab': No such file or directory
ORACLE_HOME = [/home/oracle] ? ORACLE_BASE environment variable is not being set since this
information is not available for the current user ID .
You can set ORACLE_BASE manually if it is required.
Resetting ORACLE_BASE to its previous value or ORACLE_HOME
The Oracle base remains unchanged with value /opt/oracle
#####################################
########### E R R O R ###############
DATABASE SETUP WAS NOT SUCCESSFUL!
Please check output for further info!
########### E R R O R ###############
#####################################
The following output is now a tail of the alert.log:
tail: cannot open '/opt/oracle/diag/rdbms/*/*/trace/alert*.log' for reading: No such file or directory
tail: no files remaining
vagrant@ubuntu-focal:/vagrant/oraclexedatabase/dockerfiles$

Remember from my previous article, with Oracle 18.4.0 XE I got the error:

Cannot create directory "/opt/oracle/oradata/XE".

To fix that error, I had to change some write permissions for that directory on the guests operating system in the appliance.

Remember the parameter, I also described in my previous article:

-v/opt/oracle/oradata
The data volume to use for the database.
Has to be writable by the Unix “oracle” (uid: 54321) user inside the container!
If omitted the database will not be persisted over container recreation.

See also (“Cannot create directory” error when using volumes):
This is a Unix filesystem permission issue. Docker by default will map the uid inside the container to the outside world. The uid for the oracle user inside the container is 54321 and therefore all files are created with this uid. If you happen to have your volume pointed at a location outside there container where this uid doesn’t have any permissions for, the container can’t write to it and therefore the database files creation fails.
[https://github.com/oracle/docker-images/blob/main/OracleDatabase/SingleInstance/FAQ.md#cannot-create-directory-error-when-using-volumes]

But this time, with 21c, I got another kind of error!

Investigating the error by looking at the Oracle documentation for version 18.4.0 and 21c

First, I had a look at the Oracle documentation for version 18.4.0 and 21c with regard to configuration, database files and log’s location.

Oracle Database 18.4.0 XE:

[https://docs.oracle.com/en/database/oracle/oracle-database/18/xeinl/procedure-installing-oracle-database-xe.html]

Oracle Database 21c XE:

[https://docs.oracle.com/en/database/oracle/oracle-database/21/xeinl/installing-oracle-database-xe.html]

So, no big differences there between the two versions.

Next step, was to have a look at the Oracle documentation for version 18.4.0 and 21c with regard to installing Oracle Database XE using RPM packages.

Oracle Database 18.4.0 XE:
For installing Oracle Database XE RPM and creating and configuring an Oracle Database these are the steps, described in the installation guide:

  • Execute as user root using sudo.
 sudo -s
  • Install the Database Preinstallation RPM
yum -y localinstall oracle-database-preinstall-18c-1.0-1.el7.x86_64.rpm
  • Install the database software
yum -y localinstall oracle-database-xe-18c-1.0-1.x86_64.rpm

The Database Preinstallation RPM automatically creates Oracle installation owner and groups and sets up other kernel configuration settings as required for Oracle installations.

  • Run the service configuration script
/etc/init.d/oracle-xe-18c configure

[https://docs.oracle.com/en/database/oracle/oracle-database/18/xeinl/procedure-installing-oracle-database-xe.html]

Oracle Database 21c XE:
For installing Oracle Database XE RPM and creating and configuring an Oracle Database these are the steps, described in the installation guide:

  • Execute as user root using sudo.
 sudo -s
  • Install the Database Preinstallation RPM
yum -y localinstall oracle-database-preinstall-21c-1.0-1.el7.x86_64.rpm
  • Install the database software
yum -y localinstall oracle-database-xe-21c-1.0-1.ol7.x86_64.rpm

The Database Preinstallation RPM automatically creates Oracle installation owner and groups and sets up other kernel configuration settings as required for Oracle installations.

  • Run the service configuration script
/etc/init.d/oracle-xe-21c configure

[https://docs.oracle.com/en/database/oracle/oracle-database/21/xeinl/installing-oracle-database-xe.html]

So again, no big differences there between the two versions.

Then I compared these installation instructions, with the instructions in the file Dockerfile.xe (only showing the last part):

…
# Environment variables required for this build (do NOT change)
# -------------------------------------------------------------
ENV ORACLE_BASE=/opt/oracle \
    ORACLE_HOME=/opt/oracle/product/18c/dbhomeXE \
    ORACLE_SID=XE \
    INSTALL_FILE_1="https://download.oracle.com/otn-pub/otn_software/db-express/oracle-database-xe-18c-1.0-1.x86_64.rpm" \
    RUN_FILE="runOracle.sh" \
    PWD_FILE="setPassword.sh" \
    CONF_FILE="oracle-xe-18c.conf" \
    CHECK_SPACE_FILE="checkSpace.sh" \
    CHECK_DB_FILE="checkDBStatus.sh" \
    INSTALL_DIR="$HOME/install" \
    ORACLE_DOCKER_INSTALL="true"

# Use second ENV so that variable get substituted
ENV PATH=$ORACLE_HOME/bin:$PATH

# Copy binaries
# -------------
COPY $CHECK_SPACE_FILE $RUN_FILE $PWD_FILE $CHECK_DB_FILE $CONF_FILE $INSTALL_DIR/

RUN chmod ug+x $INSTALL_DIR/*.sh && \
    sync && \
    $INSTALL_DIR/$CHECK_SPACE_FILE && \
    cd $INSTALL_DIR && \
    yum -y install openssl oracle-database-preinstall-18c && \
    sed -i -e 's/\(oracle\s\+hard\s\+nofile\)/# \1/' /etc/security/limits.d/oracle-database-preinstall-18c.conf && \
    yum -y localinstall $INSTALL_FILE_1 && \
    rm -rf /var/cache/yum && \
    rm -rf /var/tmp/yum-* && \
    mkdir -p $ORACLE_BASE/scripts/setup && \
    mkdir $ORACLE_BASE/scripts/startup && \
    ln -s $ORACLE_BASE/scripts /docker-entrypoint-initdb.d && \
    mkdir -p $ORACLE_BASE/oradata /home/oracle && \
    chown -R oracle:oinstall $ORACLE_BASE /home/oracle && \
    mv $INSTALL_DIR/$RUN_FILE $ORACLE_BASE/ && \
    mv $INSTALL_DIR/$PWD_FILE $ORACLE_BASE/ && \
    mv $INSTALL_DIR/$CHECK_DB_FILE $ORACLE_BASE/ && \
    mv $INSTALL_DIR/$CONF_FILE /etc/sysconfig/ && \
    ln -s $ORACLE_BASE/$PWD_FILE / && \
    cd $HOME && \
    rm -rf $INSTALL_DIR && \
    chmod ug+x $ORACLE_BASE/*.sh

HEALTHCHECK --interval=1m --start-period=5m \
   CMD "$ORACLE_BASE/$CHECK_DB_FILE" >/dev/null || exit 1

CMD exec $ORACLE_BASE/$RUN_FILE

For my own convenience, I repeat here the RUN part from file Dockerfile.xe , with the actual values:

RUN chmod ug+x $HOME/install/*.sh && \
    sync && \
    $HOME/install/checkSpace.sh && \
    cd $HOME/install && \
    yum -y install openssl oracle-database-preinstall-18c && \
    sed -i -e 's/\(oracle\s\+hard\s\+nofile\)/# \1/' /etc/security/limits.d/oracle-database-preinstall-18c.conf && \
    yum -y localinstall https://download.oracle.com/otn-pub/otn_software/db-express/oracle-database-xe-18c-1.0-1.x86_64.rpm && \
    rm -rf /var/cache/yum && \
    rm -rf /var/tmp/yum-* && \
    mkdir -p /opt/oracle/scripts/setup && \
    mkdir /opt/oracle/scripts/startup && \
    ln -s /opt/oracle/scripts /docker-entrypoint-initdb.d && \
    mkdir -p /opt/oracle/oradata /home/oracle && \
    chown -R oracle:oinstall /opt/oracle /home/oracle && \
    mv $HOME/install/runOracle.sh /opt/oracle/ && \
    mv $HOME/install/setPassword.sh /opt/oracle/ && \
    mv $HOME/install/checkDBStatus.sh /opt/oracle/ && \
    mv $HOME/install/oracle-xe-18c.conf /etc/sysconfig/ && \
    ln -s /opt/oracle/setPassword.sh / && \
    cd $HOME && \
    rm -rf $HOME/install && \
    chmod ug+x /opt/oracle/*.sh

HEALTHCHECK --interval=1m --start-period=5m \
   CMD "/opt/oracle/checkDBStatus.sh" >/dev/null || exit 1

CMD exec /opt/oracle/runOracle.sh

I also had a look at the content of file runOracle.sh:

/etc/init.d/oracle-xe-18c start | grep -qc "Oracle Database is not configured"
if [ "$?" == "0" ]; then
   # Create database
   createDB;
   
   # Execute custom provided setup scripts
   runUserScripts $ORACLE_BASE/scripts/setup
fi;
…

As you can see, the installation instructions can be found in the file Dockerfile.xe and of file runOracle.sh (see the different colors I used). This gave me some insight in how the image is set up.

Getting a list of files and directories from the running docker container

Because the image for Oracle Database 18.4.0 XE did work successfully, I was curious about its content. In particular the ownership/permissions settings of certain files and directories.

This of course in relation to the error I got, remember:

[FATAL] [DBT-10011] Incorrect ownership/permissions detected for the file (/opt/oracle/product/21c/dbhomeXE/bin/oradism).
   CAUSE: Following nodes does not have required file ownership/permissions: Node :9a4154bb1e13
PRVG-11960 : Set user ID bit is not set for file "/opt/oracle/product/21c/dbhomeXE/bin/oradism" on node "9a4154bb1e13".
PRVG-2031 : Owner of file "/opt/oracle/product/21c/dbhomeXE/bin/oradism" did not match the expected value on node "9a4154bb1e13". [Expected = "root(0)" ; Found = "oracle(54321)"]

For my own convenience, I sum up here, a list of files and directories from the running docker container for the Oracle Database 18.4.0 XE version. I got these previously, by opening a shell into the running docker container:

docker exec -it oracle_database_18.4.0-xe sh

I used the following command on the shell Command Prompt:

sh-4.2# pwd

With the following output:

/

Next, I used the following command on the shell Command Prompt:

sh-4.2# ls -latr

With the following output:

total 76
drwxr-xr-x   2 root root 4096 Apr 11  2018 srv
drwxr-xr-x   2 root root 4096 Apr 11  2018 mnt
drwxr-xr-x   2 root root 4096 Apr 11  2018 media
dr-xr-xr-x   2 root root 4096 Apr 11  2018 boot
drwxr-xr-x   1 root root 4096 Nov 24 03:56 usr
lrwxrwxrwx   1 root root    8 Nov 24 03:56 sbin -> usr/sbin
lrwxrwxrwx   1 root root    9 Nov 24 03:56 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    7 Nov 24 03:56 lib -> usr/lib
lrwxrwxrwx   1 root root    7 Nov 24 03:56 bin -> usr/bin
drwxr-xr-x   1 root root 4096 Nov 24 03:56 var
dr-xr-x---   1 root root 4096 Nov 28 10:49 root
drwxr-xr-x   1 root root 4096 Nov 28 10:50 home
drwxr-xr-x   1 root root 4096 Nov 28 10:58 run
drwxr-xr-x   1 root root 4096 Nov 28 10:58 opt
lrwxrwxrwx   1 root root   26 Nov 28 10:58 setPassword.sh -> /opt/oracle/setPassword.sh
lrwxrwxrwx   1 root root   19 Nov 28 10:58 docker-entrypoint-initdb.d -> /opt/oracle/scripts
-rwxr-xr-x   1 root root    0 Nov 28 11:17 .dockerenv
drwxr-xr-x   1 root root 4096 Nov 28 11:17 ..

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd home
sh-4.2# ls -latr

With the following output:

total 20
drwxr-xr-x 1 root   root     4096 Nov 28 10:50 .
drwx------ 1 oracle oinstall 4096 Nov 28 10:58 oracle
drwxr-xr-x 1 root   root     4096 Nov 28 11:17 ..

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd oracle
sh-4.2# ls -latr

With the following output:

total 40
-rw-r--r-- 1 oracle oinstall  172 Nov 23 17:31 .kshrc
-rw-r--r-- 1 oracle oinstall  231 Nov 23 17:44 .bashrc
-rw-r--r-- 1 oracle oinstall  193 Nov 23 17:44 .bash_profile
-rw-r--r-- 1 oracle oinstall   18 Nov 23 17:44 .bash_logout
drwxr-xr-x 1 root   root     4096 Nov 28 10:50 ..
drwxrwx--- 1 oracle oinstall 4096 Nov 28 10:58 .oracle_jre_usage
drwx------ 1 oracle oinstall 4096 Nov 28 10:58 .

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd /opt
sh-4.2# ls -latr

With the following output:

total 24
drwxr-xr-x 3 root   root     4096 Nov 28 10:58 ORCLfmap
drwxr-xr-x 1 root   root     4096 Nov 28 10:58 .
drwxr-xr-x 1 root   root     4096 Nov 28 11:17 ..
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 11:18 oracle

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd oracle
sh-4.2# ls -latr

With the following output:

total 76
-rwxrwxrwx 1 root   root      781 Nov  7 13:44 setPassword.sh
-rwxrwxrwx 1 root   root     6676 Nov  7 13:44 runOracle.sh
-rwxrwxrwx 1 root   root     1137 Nov  7 13:44 checkDBStatus.sh
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 10:55 product
drwxrwx--- 4 oracle oinstall 4096 Nov 28 10:58 oraInventory
drwxrwxr-x 1 oracle oinstall 4096 Nov 28 10:58 diag
drwxrwx--- 2 oracle oinstall 4096 Nov 28 10:58 checkpoints
drwxr-xr-x 1 root   root     4096 Nov 28 10:58 ..
drwxr-xr-x 4 oracle oinstall 4096 Nov 28 10:58 scripts
drwxr-x--- 3 oracle oinstall 4096 Nov 28 11:18 admin
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 11:18 .
drwxr-x--- 3 oracle oinstall 4096 Nov 28 11:20 audit
drwxr-xr-x 5 oracle oinstall 4096 Nov 28 11:20 cfgtoollogs
drwxr-xrwx 4 root   root     4096 Nov 28 11:26 oradata

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd cfgtoollogs
sh-4.2# ls -latr

With the following output:

total 24
drwxr-xr-x 2 oracle oinstall 4096 Nov 28 11:17 netca
drwxr-x--- 3 oracle oinstall 4096 Nov 28 11:18 dbca
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 11:18 ..
drwxr-xr-x 5 oracle oinstall 4096 Nov 28 11:20 .
drwxr-x--- 4 oracle oinstall 4096 Nov 28 11:23 sqlpatch

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd /opt/oracle/product
sh-4.2# ls -latr

With the following output:

total 24
drwxrwxr-x 1 oracle oinstall 4096 Nov 28 10:55 18c
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 10:55 .
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 11:18 ..

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd 18c
sh-4.2# ls -latr

With the following output:

total 24
drwxr-xr-x 1 oracle oinstall 4096 Nov 28 10:55 ..
drwxrwxr-x 1 oracle oinstall 4096 Nov 28 10:55 .
drwxrwxr-x 1 oracle oinstall 4096 Nov 28 11:30 dbhomeXE

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd dbhomeXE
sh-4.2# ls -latr

With the following output:

total 316
-rw-r--r--  1 oracle oinstall   852 Aug 18  2015 env.ora
-rw-r--r--  1 oracle oinstall  2927 Oct 14  2016 schagent.conf
-rwxr-x---  1 oracle oinstall  1783 Mar  8  2017 runInstaller
-rwx------  1 oracle oinstall   589 Oct 18  2018 root.sh
-r-xr-xr-x  1 oracle oinstall  5780 Nov 21  2019 LICENSE
drwxrwxr-x  1 oracle oinstall  4096 Nov 28 10:55 ..
drwxr-xr-x  2 oracle oinstall  4096 Nov 28 10:55 QOpatch
drwxr-xr-x 12 oracle oinstall  4096 Nov 28 10:55 OPatch
drwxr-xr-x  2 oracle oinstall  4096 Nov 28 10:55 addnode
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:55 R
drwxr-xr-x  1 oracle oinstall  4096 Nov 28 10:55 assistants
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 css
drwxr-xr-x  6 oracle oinstall  4096 Nov 28 10:56 crs
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:56 clone
drwxr-xr-x  2 oracle oinstall  4096 Nov 28 10:56 bin
drwxr-xr-x 11 oracle oinstall  4096 Nov 28 10:56 ctx
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 diagnostics
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 demo
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:56 deinstall
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 dbjava
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 data
drwxr-xr-x  7 oracle oinstall  4096 Nov 28 10:56 cv
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:56 hs
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 has
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:56 dv
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:56 drdaas
drwxr-xr-x 13 oracle oinstall  4096 Nov 28 10:56 dmu
drwxr-xr-x  2 oracle oinstall  4096 Nov 28 10:56 instantclient
drwxr-x--- 12 oracle oinstall  4096 Nov 28 10:56 inventory
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:57 jdbc
drwxr-xr-x  8 oracle oinstall  4096 Nov 28 10:57 javavm
drwxr-xr-x  7 oracle oinstall  4096 Nov 28 10:57 jdk
drwxr-xr-x 10 oracle oinstall  4096 Nov 28 10:57 ldap
drwxr-xr-x  2 oracle oinstall  4096 Nov 28 10:57 jlib
drwxr-xr-x  3 oracle oinstall 12288 Nov 28 10:58 lib
drwxr-xr-x  9 oracle oinstall  4096 Nov 28 10:58 md
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:58 mgw
drwxr-xr-x  1 oracle oinstall  4096 Nov 28 10:58 network
drwxr-xr-x  8 oracle oinstall  4096 Nov 28 10:58 odbc
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:58 nls
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:58 oracore
drwxr-xr-x  7 oracle oinstall  4096 Nov 28 10:58 opmn
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:58 olap
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 oss
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 ordim
drwxr-xr-x  7 oracle oinstall  4096 Nov 28 10:58 ord
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:58 owm
drwxr-xr-x  8 oracle oinstall  4096 Nov 28 10:58 oui
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:58 racg
drwxr-xr-x  6 oracle oinstall  4096 Nov 28 10:58 precomp
drwxr-xr-x  6 oracle oinstall  4096 Nov 28 10:58 plsql
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:58 perl
drwxr-xr-x  1 oracle oinstall  4096 Nov 28 10:58 rdbms
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 relnotes
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 ucp
drwxr-xr-x  6 oracle oinstall  4096 Nov 28 10:58 srvm
drwxr-xr-x  6 oracle oinstall  4096 Nov 28 10:58 sqlplus
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 sqlpatch
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 sqlj
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 slax
drwxr-xr-x  5 oracle oinstall  4096 Nov 28 10:58 sdk
drwxr-x---  7 oracle oinstall  4096 Nov 28 10:58 xdk
drwxr-xr-x  3 oracle oinstall  4096 Nov 28 10:58 wwg
drwxr-xr-x  2 oracle oinstall  4096 Nov 28 10:58 utl
drwxr-xr-x  4 oracle oinstall  4096 Nov 28 10:58 usm
-rw-r-----  1 oracle oinstall   130 Nov 28 10:58 oraInst.loc
drwxrwxr-x  9 oracle oinstall  4096 Nov 28 10:58 install
drwxrwx---  3 oracle oinstall  4096 Nov 28 10:58 cfgtoollogs
drwxr-xr-x  1 oracle oinstall  4096 Nov 28 11:18 log
drwxr-xr-x  1 oracle oinstall  4096 Nov 28 11:30 dbs
drwxrwxr-x  1 oracle oinstall  4096 Nov 28 11:30 .

Next, I used the following commands on the shell Command Prompt:

sh-4.2# cd bin
sh-4.2# ls -latr

With the following output:

total 644220
-rwxr-xr-x 1 oracle oinstall       153 Nov  7  1997 echodo
-rwxr-xr-x 1 oracle oinstall      2790 Jan  1  2000 orald
-rwxr-xr-x 1 oracle oinstall      6823 Jan  1  2000 oraenv
-rw-r--r-- 1 oracle oinstall      5003 Jan  1  2000 oerr.pl
-rwxr-xr-x 1 oracle oinstall       703 Jan  1  2000 oerr
-rwxr-xr-x 1 oracle oinstall      2396 Jan  1  2000 gensyslib
-rwxr-x--- 1 oracle oinstall     15732 Jan  1  2000 dbstart
-rwxr-x--- 1 oracle oinstall      8142 Jan  1  2000 dbshut
-rwxr-xr-x 1 oracle oinstall      2445 Jan  1  2000 dbhome
-rwxr-xr-x 1 oracle oinstall      6404 Jan  1  2000 coraenv
-rwxr-xr-x 1 oracle oinstall      3261 May  4  2000 symfind
-rwxr-x--- 1 oracle oinstall        48 Sep 25  2000 oraxml
-rwxr-x--- 1 oracle oinstall        48 Sep 25  2000 oraxsl
-rwxr-x--- 1 oracle oinstall        46 Nov  7  2000 oracg
-rwxr-x--- 1 oracle oinstall        45 Sep 26  2001 transx
-rwxr-x--- 1 oracle oinstall        59 Nov 25  2002 orapipe
-rwxr-x--- 1 oracle oinstall        44 Dec  5  2002 orajaxb
-rwxr-xr-x 1 oracle oinstall      2989 Aug 20  2012 crsdiag.pl
-rwxr-xr-x 1 oracle oinstall      1398 Sep 13  2012 cluvfyrac.sh
-rwxr-xr-x 1 oracle oinstall      1398 Sep 13  2012 cluvfy
-rwxr-x--- 1 oracle oinstall      6537 Sep 28  2012 emdwgrd
-rwxr-xr-x 1 oracle oinstall         0 Aug 13  2014 tnnfg
-rwxr-xr-x 1 oracle oinstall      1635 Dec  5  2014 linkshlib
-rwxr-xr-x 1 oracle oinstall    230027 Jun 15  2016 zip
-rwxr-xr-x 1 oracle oinstall       945 Jun 20  2016 acfsroot
-rwxr-xr-x 1 oracle oinstall       940 Jun 20  2016 okaroot
-rwxr-xr-x 1 oracle oinstall      1000 Jun 20  2016 afdroot
-rwxr-xr-x 1 oracle oinstall      1007 Jun 20  2016 olfsroot
-rwxr-xr-x 1 oracle oinstall      1001 Jun 20  2016 olfscmd
-rwxr-xr-x 1 oracle oinstall       727 Sep  8  2016 acfsremote
-rwxr-xr-x 1 oracle oinstall      7000 Nov 18  2016 okcreate
-rwxr-xr-x 1 oracle oinstall      3078 Mar 28  2017 afddriverstate
-rwxr-xr-x 1 oracle oinstall      2854 Mar 28  2017 afdtool
-rw-r--r-- 1 oracle oinstall      5978 Jun 21  2017 ore_srcexport.pl
-rw-r--r-- 1 oracle oinstall      4331 Jun 21  2017 ore_dsiimport.pl
-rw-r--r-- 1 oracle oinstall      4799 Jun 21  2017 ore_dsiexport.pl
-rw-r--r-- 1 oracle oinstall      7472 Jun 21  2017 ore_destimport.pl
-rwxr-x--- 1 oracle oinstall      3120 Jul  7  2017 commonSetup.sh
-rw-r----- 1 oracle oinstall       999 Aug 23  2017 dbSetup.pl
-rwxr-x--- 1 oracle oinstall     65179 Aug 24  2017 emdwgrd.pl
-rw-r--r-- 1 oracle oinstall      9125 Aug 26  2017 aqxmlctl.pl
-rwxr-x--- 1 oracle oinstall       768 Aug 26  2017 xsql
-rwx------ 1 oracle oinstall     64008 Sep  7  2017 xmlwf
-rwxr-xr-x 1 oracle oinstall     10074 Sep 13  2017 genorasdksh
-rwxr-xr-x 1 oracle oinstall      6149 Sep 13  2017 genclntst
-rwxr-xr-x 1 oracle oinstall     14605 Sep 13  2017 genclntsh
-rwxr-xr-x 1 oracle oinstall      5914 Sep 13  2017 genagtsh
-rwx------ 1 oracle oinstall      2139 Sep 19  2017 rootPreRequired.sh
-rwxr-xr-x 1 oracle oinstall      6534 Sep 27  2017 relink
-rwxr-x--- 1 oracle oinstall      5385 Oct  2  2017 patchgen
-rwxr-xr-x 1 oracle oinstall      4764 Oct 10  2017 genoccish
-rwxr-xr-x 1 oracle oinstall   2297591 Nov 30  2017 lxegen
-rwxr-xr-x 1 oracle oinstall   1840940 Nov 30  2017 lmsgen
-rwxr-xr-x 1 oracle oinstall   7828022 Nov 30  2017 lxinst
-rwxr-xr-x 1 oracle oinstall   1776251 Nov 30  2017 lxchknlb
-rwxr-xr-x 1 oracle oinstall   3104400 Nov 30  2017 lcsscan
-rwxr-xr-x 1 oracle oinstall      6093 Dec  1  2017 owm
-rwxr-xr-x 1 oracle oinstall      4619 Dec  1  2017 orapki
-rwxr-xr-x 1 oracle oinstall      4587 Dec  1  2017 mkstore
-rwxr-x--- 1 oracle oinstall      6789 Dec  1  2017 asmcmd
-rwxr-xr-x 1 oracle oinstall      5670 May  2  2018 rhpctl
-rwxr-xr-x 1 oracle oinstall     76759 Jul 13  2018 asmcmdcore
-rwxr-xr-x 1 oracle oinstall      7605 Aug  9  2018 gennttab
-rwxr-xr-x 1 oracle oinstall      4852 Aug  9  2018 gennfgt
-rwxr-xr-x 1 oracle oinstall     13488 Aug  9  2018 adapters
-rw------- 1 oracle oinstall     95502 Aug  9  2018 oklist0
-rw------- 1 oracle oinstall     84092 Aug  9  2018 okinit0
-rw------- 1 oracle oinstall     81017 Aug  9  2018 okdstry0
-rwxr-x--- 1 oracle oinstall    138707 Aug 21  2018 xml
-rwxr-x--- 1 oracle oinstall    185969 Aug 21  2018 xmlcg
-rwxr-x--- 1 oracle oinstall     32972 Aug 21  2018 schema
-rwxr-x--- 1 oracle oinstall     38586 Aug 21  2018 xvm
-rwxr-x--- 1 oracle oinstall     52099 Aug 21  2018 xsl
-rwxr-x--- 1 oracle oinstall     27619 Aug 21  2018 xmlpatch
-rwxr-x--- 1 oracle oinstall     27744 Aug 21  2018 xmldiff
-rwxr-xr-x 1 oracle oinstall     58238 Sep  5  2018 lsnodes
-rwxr-xr-x 1 oracle oinstall  88939994 Sep 12  2018 afdboot
-rwxr-xr-x 1 oracle oinstall    278282 Sep 12  2018 afdtool.bin
-rwxr-xr-x 1 oracle oinstall     33548 Sep 12  2018 olfsctl
-rwxr-xr-x 1 oracle oinstall     29760 Oct 18  2018 rtsora
-rwxr-x--x 1 oracle oinstall     25110 Oct 18  2018 osh
-rwxr-x--x 1 oracle oinstall     24536 Oct 18  2018 oraversion
-rwxr-x--- 1 oracle oinstall     53394 Oct 18  2018 oraping
-rwxr-xr-x 1 oracle oinstall    181040 Oct 18  2018 oradnfs
-rwxr-x--- 1 oracle oinstall     98250 Oct 18  2018 oradism
-rwxr-x--- 1 oracle oinstall   1875437 Oct 18  2018 orabasehome
-rwxr-x--- 1 oracle oinstall   1875447 Oct 18  2018 orabaseconfig
-rw-r--r-- 1 oracle oinstall    187392 Oct 18  2018 opwdintg.exe
-rwxr-x--- 1 oracle oinstall     35759 Oct 18  2018 mtactl
-rwxr-xr-x 1 oracle oinstall   1177288 Oct 18  2018 genksms
-rwxr-x--- 1 oracle oinstall   1748888 Oct 18  2018 fmputlhp
-rwxr-x--- 1 oracle oinstall   2020196 Oct 18  2018 fmputl
-rwxr-xr-x 1 oracle oinstall   2115753 Oct 18  2018 diskmon.bin
-rwxr-x--- 1 oracle oinstall      3136 Oct 18  2018 dbupgrade
-rw-r--r-- 1 oracle oinstall      5297 Oct 18  2018 dbgeu_run_action.pl
-rwxr-x--x 1 oracle oinstall   1388939 Oct 18  2018 dbfs_client
-rw-r--r-- 1 oracle oinstall    128588 Oct 18  2018 bdschecksw
-rw-r--r-- 1 oracle oinstall     43394 Oct 18  2018 CommonSetup.pm
-rwxr-xr-x 1 oracle oinstall   6569249 Oct 18  2018 orabase
-rwxr-xr-x 1 oracle oinstall      1573 Oct 18  2018 olsoidsync
-rwxr-xr-x 1 oracle oinstall      1176 Oct 18  2018 olsadmintool
-rw-r--r-- 1 oracle oinstall       909 Oct 18  2018 ORE
-rwxr-xr-x 1 oracle oinstall      4098 Oct 18  2018 umu
-rwxr-xr-x 1 oracle oinstall      1352 Oct 18  2018 statusnc
-rwxr-xr-x 1 oracle oinstall       943 Oct 18  2018 ott
-rwxr-xr-x 1 oracle oinstall      1320 Oct 18  2018 ojvmtc
-rwxr-xr-x 1 oracle oinstall      1436 Oct 18  2018 ojvmjava
-rwxr-xr-x 1 oracle oinstall      1351 Oct 18  2018 ncomp
-rwxr-xr-x 1 oracle oinstall      2460 Oct 18  2018 loadjava
-rwxr-xr-x 1 oracle oinstall      2351 Oct 18  2018 eusm
-rwxr-xr-x 1 oracle oinstall      1466 Oct 18  2018 dropjava
-rwxr-xr-x 1 oracle oinstall      1516 Oct 18  2018 deploync
-rwxr-xr-x 1 oracle oinstall      3007 Oct 18  2018 trcasst
-rwxr-xr-x 1 oracle oinstall     11446 Oct 18  2018 srvctl
-rwxr-x--- 1 oracle oinstall      4624 Oct 18  2018 roohctl
-rwxr-x--- 1 oracle oinstall      7074 Oct 18  2018 rconfig
-rw-r----- 1 oracle oinstall      3890 Oct 18  2018 platform_common
-rwxr-xr-x 1 oracle oinstall      3145 Oct 18  2018 oidprovtool
-rwxr-xr-x 1 oracle oinstall      7705 Oct 18  2018 netmgr
-rwxr-xr-x 1 oracle oinstall      2910 Oct 18  2018 ldifmigrator
-rwxr-xr-x 1 oracle oinstall      7472 Oct 18  2018 diagsetup
-rwxr-xr-x 1 oracle oinstall      2957 Oct 18  2018 bndlchk
-rwxr-x--x 1 oracle oinstall      1557 Oct 18  2018 aqxmlctl
-rwxr-x--- 1 oracle oinstall       107 Oct 18  2018 netca_deinst.sh
-rwxr-x--- 1 oracle oinstall      6924 Oct 18  2018 netca
-rwxr-x--- 1 oracle oinstall     10508 Oct 18  2018 dbua
-rwxr-xr-x 1 oracle oinstall      2080 Oct 18  2018 trcsess
-rwxr-xr-x 1 oracle oinstall      4749 Oct 18  2018 srvconfig
-rwxr-xr-x 1 oracle oinstall      2847 Oct 18  2018 schemasync
-rwxr-xr-x 1 oracle oinstall      1781 Oct 18  2018 schagent
-rwxr-xr-x 1 oracle oinstall      2411 Oct 18  2018 oradnfs_run.sh
-rwxr-xr-x 1 oracle oinstall      2173 Oct 18  2018 oidca
-rwxr-xr-x 1 oracle oinstall      1304 Oct 18  2018 odisrvreg
-rwxr-xr-x 1 oracle oinstall       484 Oct 18  2018 kfod
-rwxr-x--- 1 oracle oinstall       340 Oct 18  2018 extusrupgrade
-rw-r----- 1 oracle oinstall      7140 Oct 18  2018 chopt.pl
-rw-r----- 1 oracle oinstall      2293 Oct 18  2018 chopt.ini
-rwxr-x--- 1 oracle oinstall       284 Oct 18  2018 chopt
-rwxr-xr-x 1 oracle oinstall  10847196 Oct 18  2018 proc
-rwxr-xr-x 1 oracle oinstall  10495520 Oct 18  2018 procob
-rwxr-x--x 1 oracle oinstall    763051 Oct 18  2018 dg4odbc
-rwxr-x--x 1 oracle oinstall    374426 Oct 18  2018 ctxload
-rwxr-x--x 1 oracle oinstall    784787 Oct 18  2018 ctxlc
-rwxr-x--x 1 oracle oinstall   9813247 Oct 18  2018 wrap
-rwxr-x--x 1 oracle oinstall    104939 Oct 18  2018 dbv
-rwxr-x--x 1 oracle oinstall    879453 Oct 18  2018 ctxkbtc
-rwxr-x--x 1 oracle oinstall     35328 Oct 18  2018 tstshm
-rwxr-x--x 1 oracle oinstall    109163 Oct 18  2018 orapwd
-rwxr-x--x 1 oracle oinstall     25537 Oct 18  2018 maxmem
-rwxr-x--x 1 oracle oinstall     25129 Oct 18  2018 dbfsize
-rwxr-x--x 1 oracle oinstall   1125104 Oct 18  2018 mapsga
-rwxr-x--x 1 oracle oinstall   1125569 Oct 18  2018 dumpsga
-rwxr-x--x 1 oracle oinstall     24843 Oct 18  2018 cursize
-rwxr-x--x 1 oracle oinstall    234706 Oct 18  2018 agtctl
-rwxr-x--x 1 oracle oinstall    149361 Oct 18  2018 sbttest
-rwxr-x--x 1 oracle oinstall    221644 Oct 18  2018 hsots
-rwxr-x--x 1 oracle oinstall    221481 Oct 18  2018 hsdepxa
-rwxr-x--x 1 oracle oinstall    352041 Oct 18  2018 hsalloci
-rwxr-x--x 1 oracle oinstall    103141 Oct 18  2018 nid
-rwxr-x--x 1 oracle oinstall    145012 Oct 18  2018 kfod.bin
-rwxr-x--- 1 oracle oinstall   2378078 Oct 18  2018 jssu
-rwx------ 1 oracle oinstall   2592744 Oct 18  2018 extjobo
-rwxr-x--- 1 oracle oinstall   2592744 Oct 18  2018 extjob
-rwxr-x--x 1 oracle oinstall     36065 Oct 18  2018 amdu
-rwxr-x--x 1 oracle oinstall     90280 Oct 18  2018 mkpatch
-rwxr-x--x 1 oracle oinstall     98474 Oct 18  2018 kfed
-rwxr-x--x 1 oracle oinstall     78032 Oct 18  2018 renamedg
-rwxr-x--x 1 oracle oinstall   3811236 Oct 18  2018 setasmgid
-rwxr-xr-x 1 oracle oinstall     27334 Oct 18  2018 osdbagrp
-rwxr-x--x 1 oracle oinstall   7960085 Oct 18  2018 orion
-rwxr-x--x 1 oracle oinstall    130180 Oct 18  2018 trcldr
-rwxr-x--x 1 oracle oinstall     25347 Oct 18  2018 skgxpinfo
-rwxr-x--x 1 oracle oinstall     87903 Oct 18  2018 oputil
-rwxr-x--x 1 oracle oinstall     36201 Oct 18  2018 tnsping
-rwxr-xr-x 1 oracle oinstall     22891 Oct 18  2018 sqlplus
-rwxr-xr-x 1 oracle oinstall   1182513 Oct 18  2018 ldapadd
-rwxr-xr-x 1 oracle oinstall   1113412 Oct 18  2018 ldapsearch
-rwxr-xr-x 1 oracle oinstall   1182513 Oct 18  2018 ldapmodify
-rwxr-xr-x 1 oracle oinstall   1079983 Oct 18  2018 ldapmoddn
-rwxr-xr-x 1 oracle oinstall   1080327 Oct 18  2018 ldapdelete
-rwxr-xr-x 1 oracle oinstall   1080082 Oct 18  2018 ldapcompare
-rwxr-xr-x 1 oracle oinstall   1200543 Oct 18  2018 ldapmodifymt
-rwxr-xr-x 1 oracle oinstall   1200543 Oct 18  2018 ldapaddmt
-rwxr-xr-x 1 oracle oinstall   1160971 Oct 18  2018 dsml2ldif
-rwxr-xr-x 1 oracle oinstall     28102 Oct 18  2018 rawutl
-rwxr-xr-x 1 oracle oinstall     95502 Oct 18  2018 oklist
-rwxr-x--x 1 oracle oinstall    532199 Oct 18  2018 imp
-rwxr-x--x 1 oracle oinstall    137458 Oct 18  2018 tkprof
-rwxr-x--x 1 oracle oinstall   1706676 Oct 18  2018 sqlldr
-rwxr-x--x 1 oracle oinstall    144639 Oct 18  2018 plshprof
-rwxr-x--x 1 oracle oinstall   1066166 Oct 18  2018 exp
-rwxr-x--x 1 oracle oinstall     38944 Oct 18  2018 loadpsp
-rwxr-x--x 1 oracle oinstall     72289 Oct 18  2018 kgmgr
-rwxr-x--x 1 oracle oinstall    240726 Oct 18  2018 impdp
-rwxr-x--x 1 oracle oinstall    228704 Oct 18  2018 expdp
-rwxr-x--x 1 oracle oinstall    787677 Oct 18  2018 wrc
-rwxr-x--x 1 oracle oinstall     57556 Oct 18  2018 genezi
-rwxr-x--x 1 oracle oinstall    966520 Oct 18  2018 dgmgrl
-rwxr-x--x 1 oracle oinstall     42873 Oct 18  2018 dg4pwd
-rwxr-x--x 1 oracle oinstall    242041 Oct 18  2018 uidrvci
-rwxr-x--x 1 oracle oinstall     35373 Oct 18  2018 sysresv
-rwxr-x--x 1 oracle oinstall    206751 Oct 18  2018 extproc
-rwxr-x--x 1 oracle oinstall     40617 Oct 18  2018 adrci
-rwxr-x--x 1 oracle oinstall   1093198 Oct 18  2018 tnslsnr
-rwxr-xr-x 1 oracle oinstall     84124 Oct 18  2018 okinit
-rwxr-xr-x 1 oracle oinstall     81049 Oct 18  2018 okdstry
-rwxr-x--x 1 oracle oinstall    178299 Oct 18  2018 lsnrctl
-rwxr-x--x 1 oracle oinstall     50154 Oct 18  2018 trcroute
-rwxr-x--x 1 oracle oinstall  13882067 Oct 18  2018 rman
-rwxr-x--x 1 oracle oinstall    324252 Oct 18  2018 drdalsnr
-rwxr-x--x 1 oracle oinstall    254988 Oct 18  2018 drdactl
-rwxr-x--x 1 oracle oinstall   2213143 Oct 18  2018 drdaproc
-rwxr-xr-x 1 oracle oinstall     14544 Oct 18  2018 onsctl
-rwxr-xr-x 1 oracle oinstall   1080090 Oct 18  2018 ldapbind
-rwxr-x--- 1 oracle oinstall      5555 Oct 18  2018 emca
-rwxr-x--- 1 oracle oinstall      7479 Oct 18  2018 dbca
-rwxr-x--x 1 oracle oinstall 437755981 Oct 18  2018 oracle
lrwxrwxrwx 1 oracle oinstall        24 Nov 28 10:55 lbuilder -> ../nls/lbuilder/lbuilder
drwxr-xr-x 2 oracle oinstall      4096 Nov 28 10:56 .
drwxrwxr-x 1 oracle oinstall      4096 Nov 28 11:30 ..

As you can see here oradism is owned by user oracle (like in version 21c, according to the error):

-rwxr-x--- 1 oracle oinstall     98250 Oct 18  2018 oradism

So, in version 18.4.0 this was apparently not a problem.

Investigating the error further

So, let’s have a look at the error again:

[FATAL] [DBT-10011] Incorrect ownership/permissions detected for the file (/opt/oracle/product/21c/dbhomeXE/bin/oradism).
   CAUSE: Following nodes does not have required file ownership/permissions: Node :9a4154bb1e13
PRVG-11960 : Set user ID bit is not set for file "/opt/oracle/product/21c/dbhomeXE/bin/oradism" on node "9a4154bb1e13".
PRVG-2031 : Owner of file "/opt/oracle/product/21c/dbhomeXE/bin/oradism" did not match the expected value on node "9a4154bb1e13". [Expected = "root(0)" ; Found = "oracle(54321)"]

There is a problem with the file:

/opt/oracle/product/21c/dbhomeXE/bin/oradism

with regard to file ownership/permissions.
Apparently, root(0) was expected, but oracle(54321) was found.

I remembered reading about the Database Preinstallation RPM which automatically creates Oracle installation owner and groups (see further above). So, I focused on that aspect.

When installed, the Oracle Database Preinstallation RPM does the following:
Creates an oracle user, and creates the oraInventory (oinstall) and OSDBA (dba) groups for that user
[https://docs.oracle.com/en/database/oracle/oracle-database/21/ladbi/about-the-oracle-preinstallation-rpm.html]

The RUN part from file Dockerfile.xe , contains this line:

chown -R oracle:oinstall /opt/oracle /home/oracle && \

Remark about chown:

chown [OPTION]... [OWNER][:[GROUP]] FILE...

Change the owner and/or group of each FILE to OWNER and/or GROUP.

OPTIONS:
-R, –recursive
operate on files and directories recursively
[man chown]

So, what we see here is that via the command above, the directories /opt/oracle and /home/oracle are owned by oracle and belong to group oinstall.

The RUN part from file Dockerfile.xe , contains this line:

    chmod ug+x /opt/oracle/*.sh

Remark about chmod:

chmod [OPTION]... MODE[,MODE]... FILE...

Change file mode bits

Chmod changes the file mode bits of each given file according to mode, which can be either a symbolic representation of changes to make, or an octal number representing the bit pattern for the new mode bits.

The format of a symbolic mode is [ugoa…][[-+=][perms…]…], where perms is either zero or more letters from the set rwxXst, or a single letter from the set ugo. Multiple symbolic modes can be given, separated by commas.

A combination of the letters ugoa controls which users’ access to the file will be changed: the user who owns it (u), other users in the file’s group (g), other users not in the file’s group (o), or all users (a). If none of these are given, the effect is as if (a) were given, but bits that are set in the umask are not affected.

The operator + causes the selected file mode bits to be added to the existing file mode bits of each file; causes them to be removed; and = causes them to be added and causes unmentioned bits to be removed except that a directory’s unmentioned set user and group ID bits are not affected.

The letters rwxXst select file mode bits for the affected users: read (r), write (w), execute (or search for directories) (x), execute/search only if the file is a directory or already has execute permission for some user (X), set user or group ID on execution (s), restricted deletion flag or sticky bit (t). Instead of one or more of these letters, you can specify exactly one of the letters ugo: the permissions granted to the user who owns the file (u), the permissions granted to other users who are members of the file’s group (g), and the permissions granted to users that are in neither of the two preceding categories (o).

So, what we see here is that via the command above, for every shell script (*.sh) in the directory /opt/oracle the user who owns it (u), and other users in the file’s group (g) can execute (x) that script.

So, this accounts for:
Incorrect ownership/permissions detected for the file /opt/oracle/product/21c/dbhomeXE/bin/oradism

Again, as mentioned above, root(0) was expected, but oracle(54321) was found.

So, what to do now?

More about the way forward, you can read in my next article. But I can already say that I got it working.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Next Post

OCI DevOps Composite–creating Build & Deploy Pipeline resources using Terraform plans

I recently started a GitHub repo with Terraform plans for the creation of what I call OCI Composites – combinations of resources that will frequently be used together and that will have to be created through Infrastructure as Code. My first entry in this repository was the composite of Function, […]
%d bloggers like this: