Skip to content

Commit 4a65c0d

Browse files
committedJul 10, 2021
ER #23: Support ORACLE_DATABASE
Signed-off-by: gvenzl <gerald.venzl@gmail.com>
1 parent c8b7105 commit 4a65c0d

5 files changed

+192
-12
lines changed
 

‎README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@ The 11gR2 (11.2.0.2) Oracle Database version stores the database data files unde
4646

4747
## Environment variables
4848

49+
Environment variables allow you to customize your container. Note that these variables will only be considered during the database initialization (first container startup).
50+
4951
### `ORACLE_PASSWORD`
5052
This variable is mandatory for the first container startup and specifies the password for the Oracle Database `SYS` and `SYSTEM` users.
5153

5254
### `ORACLE_RANDOM_PASSWORD`
5355
This is an optional variable. Set this variable to a non-empty value, like `yes`, to generate a random initial password for the `SYS` and `SYSTEM` users. The generated password will be printed to stdout (`ORACLE PASSWORD FOR SYS AND SYSTEM: ...`).
5456

57+
### `ORACLE_DATABASE`
58+
This is an optional variable. Set this variable to a non-empty string to create a new pluggable database with the name specified in this variable. **Note:** creating a new database can add several additional seconds to the initial container startup. If you do not want that additional startup time, use the already existing `XEPDB1` database instead.
59+
5560
### `APP_USER`
56-
This is an optional variable. Set this variable to a non-empty string to create a new database schema user with the name specified in this variable. This variable requires `APP_USER_PASSWORD` or `APP_USER_PASSWORD_FILE` to be specified as well.
61+
This is an optional variable. Set this variable to a non-empty string to create a new database schema user with the name specified in this variable. The user will be created in the default `XEPDB1` pluggable database. If `ORACLE_DATABASE` has been specified, the user will also be created in that pluggable database. This variable requires `APP_USER_PASSWORD` or `APP_USER_PASSWORD_FILE` to be specified as well.
5762

5863
### `APP_USER_PASSWORD`
5964
This is an optional variable. Set this variable to a non-empty string to define a password for the database schema user specified by `APP_USER`. This variable requires `APP_USER` to be specified as well.
@@ -100,6 +105,7 @@ This mechanism is supported for:
100105

101106
* `ORACLE_PASSWORD`
102107
* `APP_USER_PASSWORD`
108+
* `ORACLE_DATABASE`
103109

104110
## Initialization scripts
105111
If you would like to perform additional initialization of the database running in a container, you can add one or more `*.sql`, `*.sql.gz`, `*.sql.zip` or `*.sh` files under `/container-entrypoint-initdb.d` (creating the directory if necessary). After the database setup is completed, these files will be executed automatically in alphabetical order.

‎container-entrypoint.sh

+66-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,16 @@ function setup_env_vars() {
8484
if [ -d "${ORACLE_BASE}/oradata/dbconfig/${ORACLE_SID}" ]; then
8585
DATABASE_ALREADY_EXISTS="true";
8686
else
87-
# Allow for ORACLE_PASSWORD and/or ORACLE_PASSWORD_FILE
87+
88+
# Variable is only supported for >=18c
89+
if [[ "${ORACLE_VERSION}" = "11.2"* ]]; then
90+
unset "ORACLE_DATABASE"
91+
else
92+
# Allow for ORACLE_DATABASE or ORACLE_DATABASE_FILE
93+
file_env "ORACLE_DATABASE"
94+
fi;
95+
96+
# Allow for ORACLE_PASSWORD or ORACLE_PASSWORD_FILE
8897
file_env "ORACLE_PASSWORD"
8998

9099
# Password is mandatory for first container start
@@ -100,7 +109,7 @@ function setup_env_vars() {
100109
exit 1;
101110
fi;
102111

103-
# Allow for APP_USER_PASSWORD and/or APP_USER_PASSWORD_FILE
112+
# Allow for APP_USER_PASSWORD or APP_USER_PASSWORD_FILE
104113
file_env "APP_USER_PASSWORD"
105114

106115
# Check whether both variables have been specified.
@@ -240,6 +249,38 @@ function run_custom_scripts {
240249
fi;
241250
}
242251

252+
# Create pluggable database
253+
function create_database {
254+
255+
echo "CONTAINER: Creating pluggable database."
256+
257+
RANDOM_PDBADIN_PASSWORD=$(date +%s | sha256sum | base64 | head -c 8)
258+
259+
PDB_CREATE_START_TMS=$(date '+%s')
260+
261+
sqlplus -s / as sysdba <<EOF
262+
-- Exit on any errors
263+
WHENEVER SQLERROR EXIT SQL.SQLCODE
264+
265+
CREATE PLUGGABLE DATABASE ${ORACLE_DATABASE} \
266+
ADMIN USER PDBADMIN IDENTIFIED BY "${RANDOM_PDBADIN_PASSWORD}" \
267+
FILE_NAME_CONVERT=('pdbseed','${ORACLE_DATABASE}') \
268+
DEFAULT TABLESPACE USERS \
269+
DATAFILE '${ORACLE_BASE}/oradata/${ORACLE_SID}/${ORACLE_DATABASE}/users01.dbf' \
270+
SIZE 1m AUTOEXTEND ON NEXT 10m MAXSIZE UNLIMITED;
271+
272+
ALTER PLUGGABLE DATABASE ${ORACLE_DATABASE} OPEN READ WRITE;
273+
ALTER PLUGGABLE DATABASE ${ORACLE_DATABASE} SAVE STATE;
274+
exit;
275+
EOF
276+
277+
PDB_CREATE_END_TMS=$(date '+%s')
278+
PDB_CREATE_DURATION=$(( PDB_CREATE_END_TMS - PDB_CREATE_START_TMS ))
279+
echo "CONTAINER: DONE: Creating pluggable database, duration: ${PDB_CREATE_DURATION} seconds."
280+
281+
unset RANDOM_PDBADIN_PASSWORD
282+
}
283+
243284
# Create schema user for the application to use
244285
function create_app_user {
245286

@@ -250,6 +291,7 @@ function create_app_user {
250291
fi;
251292

252293
echo "CONTAINER: Creating database application user."
294+
253295
sqlplus -s / as sysdba <<EOF
254296
-- Exit on any errors
255297
WHENEVER SQLERROR EXIT SQL.SQLCODE
@@ -260,6 +302,21 @@ function create_app_user {
260302
GRANT CONNECT, RESOURCE, CREATE VIEW, CREATE MATERIALIZED VIEW TO ${APP_USER};
261303
exit;
262304
EOF
305+
306+
# If ORACLE_DATABASE is specified, create user also in app PDB (only applicable >=18c)
307+
if [ -n "${ORACLE_DATABASE:-}" ]; then
308+
sqlplus -s / as sysdba <<EOF
309+
-- Exit on any errors
310+
WHENEVER SQLERROR EXIT SQL.SQLCODE
311+
312+
ALTER SESSION SET CONTAINER=${ORACLE_DATABASE};
313+
314+
CREATE USER ${APP_USER} IDENTIFIED BY "${APP_USER_PASSWORD}" QUOTA UNLIMITED ON USERS;
315+
GRANT CONNECT, RESOURCE, CREATE VIEW, CREATE MATERIALIZED VIEW TO ${APP_USER};
316+
exit;
317+
EOF
318+
fi;
319+
263320
}
264321

265322
###########################
@@ -327,6 +384,12 @@ if healthcheck.sh; then
327384
exit 1;
328385
fi;
329386

387+
# Check whether user PDB should be created
388+
# setup_env_vars has already validated >=18c requirement
389+
if [ -n "${ORACLE_DATABASE:-}" ]; then
390+
create_database
391+
fi;
392+
330393
# Check whether app user should be created
331394
# setup_env_vars has already validated environment variables
332395
if [ -n "${APP_USER:-}" ]; then
@@ -338,6 +401,7 @@ if healthcheck.sh; then
338401
# For backwards compatibility
339402
run_custom_scripts /docker-entrypoint-initdb.d
340403

404+
# Database already initialized
341405
else
342406

343407
# Password was passed on for container start but DB is already initialized, ignoring.

‎tests/functions.sh

+6-1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ function runContainerTest {
7979
APP_USER_CMD=""
8080
APP_USER_PASSWORD_CMD=""
8181
ORA_PWD_CMD="${ORA_PWD_CMD:--e ORACLE_PASSWORD=LetsTest1}"
82+
ORACLE_DATABASE_CMD=""
8283

8384
if [ -n "${APP_USER:-}" ]; then
8485
APP_USER_CMD="-e APP_USER=${APP_USER}"
@@ -88,11 +89,15 @@ function runContainerTest {
8889
APP_USER_PASSWORD_CMD="-e APP_USER_PASSWORD=${APP_USER_PASSWORD}"
8990
fi;
9091

92+
if [ -n "${ORACLE_DATABASE:-}" ]; then
93+
ORACLE_DATABASE_CMD="-e ORACLE_DATABASE=${ORACLE_DATABASE}"
94+
fi;
95+
9196
echo "TEST ${TEST_NAME}: Started"
9297
echo ""
9398

9499
# Run and start container
95-
podman run -d --name ${CONTAINER_NAME} ${ORA_PWD_CMD} ${APP_USER_CMD} ${APP_USER_PASSWORD_CMD} ${IMAGE} >/dev/null
100+
podman run -d --name ${CONTAINER_NAME} ${ORA_PWD_CMD} ${APP_USER_CMD} ${APP_USER_PASSWORD_CMD} ${ORACLE_DATABASE_CMD} ${IMAGE} >/dev/null
96101

97102
# Check whether Oracle DB came up successfully
98103
if checkDB "${CONTAINER_NAME}"; then

‎tests/run_container_11202.sh ‎tests/test_container_11202.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
# Since: January, 2021
33
# Author: gvenzl
4-
# Name: run_container_11202.sh
4+
# Name: test_container_11202.sh
55
# Description: Run container test scripts for Oracle DB XE 11.2.0.2
66
#
77
# Copyright 2021 Gerald Venzl

‎tests/run_container_1840.sh ‎tests/test_container_1840.sh

+112-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
# Since: March, 2021
33
# Author: gvenzl
4-
# Name: run_container_1840.sh
4+
# Name: test_container_1840.sh
55
# Description: Run container test scripts for Oracle DB XE 18.4.0
66
#
77
# Copyright 2021 Gerald Venzl
@@ -70,9 +70,6 @@ result=$(podman exec -i ${CONTAINER_NAME} sqlplus -s system/"${ORA_PWD}" <<EOF
7070
EOF
7171
)
7272

73-
# Tear down the container, no longer needed
74-
tear_down_container "${CONTAINER_NAME}"
75-
7673
# See whether we got "OK" back from our test
7774
if [ "${result}" == "${EXPECTED_RESULT}" ]; then
7875
echo "TEST ${TEST_NAME}: OK";
@@ -82,6 +79,9 @@ else
8279
exit 1;
8380
fi;
8481

82+
# Tear down the container, no longer needed
83+
tear_down_container "${CONTAINER_NAME}"
84+
8585
# Clean up environment variables, all tests should remain self-contained
8686
unset CONTAINER_NAME
8787
unset NO_TEAR_DOWN
@@ -119,9 +119,6 @@ result=$(podman exec -i ${CONTAINER_NAME} sqlplus -s system/"${rand_pwd}"@//loca
119119
EOF
120120
)
121121

122-
# Tear down the container, no longer needed
123-
tear_down_container "${CONTAINER_NAME}"
124-
125122
# See whether we got "OK" back from our test
126123
if [ "${result}" == "${EXPECTED_RESULT}" ]; then
127124
echo "TEST ${TEST_NAME}: OK";
@@ -131,6 +128,9 @@ else
131128
exit 1;
132129
fi;
133130

131+
# Tear down the container, no longer needed
132+
tear_down_container "${CONTAINER_NAME}"
133+
134134
# Clean up environment variables, all tests should remain self-contained
135135
unset CONTAINER_NAME
136136
unset NO_TEAR_DOWN
@@ -167,9 +167,110 @@ result=$(podman exec -i ${CONTAINER_NAME} sqlplus -s "${APP_USER}"/"${APP_USER_P
167167
EOF
168168
)
169169

170+
# See whether we got "OK" back from our test
171+
if [ "${result}" == "${EXPECTED_RESULT}" ]; then
172+
echo "TEST ${TEST_NAME}: OK";
173+
echo "";
174+
else
175+
echo "TEST ${TEST_NAME}: FAILED!";
176+
exit 1;
177+
fi;
178+
179+
# Tear down the container, no longer needed
180+
tear_down_container "${CONTAINER_NAME}"
181+
182+
# Clean up environment variables, all tests should remain self-contained
183+
unset CONTAINER_NAME
184+
unset NO_TEAR_DOWN
185+
unset TEST_NAME
186+
unset EXPECTED_RESULT
187+
unset APP_USER
188+
unset APP_USER_PASSWORD
189+
190+
######################################
191+
##### Oracle Database (PDB) test #####
192+
######################################
193+
194+
# Tell test method not to tear down container
195+
NO_TEAR_DOWN="true"
196+
# Let's keep the container name in a var to keep it simple
197+
CONTAINER_NAME="18-oracle-db"
198+
# Let's keep the test name in a var to keep it simple too
199+
TEST_NAME="18.4.0 ORACLE_DATABASE"
200+
# This is what we want to have back from the SQL statement
201+
EXPECTED_RESULT="Hi from your Oracle PDB"
202+
# Oracle PDB
203+
ORACLE_DATABASE="GERALD_PDB"
204+
# Oracle password
205+
ORA_PWD="MyTestPassword"
206+
ORA_PWD_CMD="-e ORACLE_PASSWORD=${ORA_PWD}"
207+
208+
# Spin up container
209+
runContainerTest "${TEST_NAME}" "${CONTAINER_NAME}" "gvenzl/oracle-xe:18.4.0-slim"
210+
211+
# Test the random password, if it works we will get "OK" back from the SQL statement
212+
result=$(podman exec -i ${CONTAINER_NAME} sqlplus -s sys/"${ORA_PWD}"@//localhost/"${ORACLE_DATABASE}" as sysdba <<EOF
213+
set heading off;
214+
set echo off;
215+
set pagesize 0;
216+
SELECT '${EXPECTED_RESULT}' FROM dual;
217+
exit;
218+
EOF
219+
)
220+
221+
# See whether we got "OK" back from our test
222+
if [ "${result}" == "${EXPECTED_RESULT}" ]; then
223+
echo "TEST ${TEST_NAME}: OK";
224+
echo "";
225+
else
226+
echo "TEST ${TEST_NAME}: FAILED!";
227+
exit 1;
228+
fi;
229+
170230
# Tear down the container, no longer needed
171231
tear_down_container "${CONTAINER_NAME}"
172232

233+
# Clean up environment variables, all tests should remain self-contained
234+
unset CONTAINER_NAME
235+
unset NO_TEAR_DOWN
236+
unset TEST_NAME
237+
unset EXPECTED_RESULT
238+
unset ORACLE_DATABASE
239+
unset ORA_PWD
240+
unset ORA_PWD_CMD
241+
242+
#################################################
243+
##### Oracle Database (PDB) + APP_USER test #####
244+
#################################################
245+
246+
# Tell test method not to tear down container
247+
NO_TEAR_DOWN="true"
248+
# Let's keep the container name in a var to keep it simple
249+
CONTAINER_NAME="18-oracle-db"
250+
# Let's keep the test name in a var to keep it simple too
251+
TEST_NAME="18.4.0 ORACLE_DATABASE & APP_USER"
252+
# This is what we want to have back from the SQL statement
253+
EXPECTED_RESULT="Hi from your Oracle PDB"
254+
# App user
255+
APP_USER="other_app_user"
256+
# App user password
257+
APP_USER_PASSWORD="ThatAppUserPassword1"
258+
# Oracle PDB
259+
ORACLE_DATABASE="REGRESSION_TESTS"
260+
261+
# Spin up container
262+
runContainerTest "${TEST_NAME}" "${CONTAINER_NAME}" "gvenzl/oracle-xe:18.4.0"
263+
264+
# Test the random password, if it works we will get "OK" back from the SQL statement
265+
result=$(podman exec -i ${CONTAINER_NAME} sqlplus -s "${APP_USER}"/"${APP_USER_PASSWORD}"@//localhost/"${ORACLE_DATABASE}" <<EOF
266+
set heading off;
267+
set echo off;
268+
set pagesize 0;
269+
SELECT '${EXPECTED_RESULT}' FROM dual;
270+
exit;
271+
EOF
272+
)
273+
173274
# See whether we got "OK" back from our test
174275
if [ "${result}" == "${EXPECTED_RESULT}" ]; then
175276
echo "TEST ${TEST_NAME}: OK";
@@ -179,10 +280,14 @@ else
179280
exit 1;
180281
fi;
181282

283+
# Tear down the container, no longer needed
284+
tear_down_container "${CONTAINER_NAME}"
285+
182286
# Clean up environment variables, all tests should remain self-contained
183287
unset CONTAINER_NAME
184288
unset NO_TEAR_DOWN
185289
unset TEST_NAME
186290
unset EXPECTED_RESULT
187291
unset APP_USER
188292
unset APP_USER_PASSWORD
293+
unset ORACLE_DATABASE

0 commit comments

Comments
 (0)
Please sign in to comment.