Injecting Parameters into container image

An earlier port hard coded the IP address and port used for MariaDB connections. I want to pull these out so I can pass them in on the command line when I create the client.

First step: execute the refactoring of introduce a parameter…but into the shell script. This involves change both the calling and called programs. Here’s what that change looks like:

$ git diff
diff --git a/keystoneconfig/Dockerfile b/keystoneconfig/Dockerfile
index e9ea6a3..7b76558 100644
--- a/keystoneconfig/Dockerfile
+++ b/keystoneconfig/Dockerfile
@@ -8,4 +8,4 @@ RUN yum install -y centos-release-openstack-stein &&\
 
 COPY ./keystone-configure.sql /
 COPY ./configure_keystone.sh /
-CMD /configure_keystone.sh 
+CMD /configure_keystone.sh 10.89.0.4 3306
diff --git a/keystoneconfig/configure_keystone.sh b/keystoneconfig/configure_keystone.sh
index 0ae6410..7982813 100755
--- a/keystoneconfig/configure_keystone.sh
+++ b/keystoneconfig/configure_keystone.sh
@@ -1,7 +1,11 @@
 #!/bin/bash
- 
+
+MYSQL_HOST=$1
+MYSQL_PORT=$2
+
+
 echo -n Database 
-mysql -h 10.89.0.4  -P3306 -uroot --password=my-secret-pw < keystone-configure.sql
+mysql -h $MYSQL_HOST  -P$MYSQL_PORT -uroot --password=my-secret-pw < keystone-configure.sql
 echo " [COMPLETE]"
 
 echo -n "configuration "
-openstack-config  --set  /etc/keystone/keystone.conf database connection mysql+pymysql://keystone:keystone@172.17.0.2/keystone
+openstack-config  --set  /etc/keystone/keystone.conf database connection mysql+pymysql://keystone:keystone@$MYSQL_HOST/keystone
 DATABASE_CONN=`openstack-config  --get  /etc/keystone/keystone.conf database connection `
 echo $DATABASE_CONN

Note that I am also going to run this by changing the IP address to the currently active one in my Mariadb container. That way I can test it. First, grab the IP.

#  podman inspect $PODID | jq -r '.[] | .NetworkSettings | .IPAddress'
10.89.0.4

And run it:

podman run -it --network maria-bridge  localhost/keystoneconfig

Gives the output:

# podman run -it --network maria-bridge  localhost/keystoneconfig 
 [COMPLETE]
configuration mysql+pymysql://keystone:keystone@10.89.0.4/keystone
 [COMPLETE]
db-sync  [COMPLETE]
bootstrap /etc/keystone/fernet-keys/ does not exist
 [COMPLETE]

Lets run it again to see what happens:

DatabaseERROR 1007 (HY000) at line 2: Can’t create database ‘keystone’; database exists [COMPLETE] configuration mysql+pymysql://keystone:keystone@10.89.0.4/keystone [COMPLETE] db-sync [COMPLETE] bootstrap /etc/keystone/fernet-keys/ does not exist [COMPLETE]

Similar, but with the warning that the Database is already created. Lets look using the MySQL client:

# podman  run -it --network maria-bridge    -e MYSQL_ROOT_PASSWORD="my-secret-pw"    --rm mariadb sh    -c 'exec mysql -h10.89.0.4 -P3306 -uroot -p"$MYSQL_ROOT_PASSWORD"'
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 14
Server version: 10.4.10-MariaDB-1:10.4.10+maria~bionic mariadb.org binary distribution
 
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
MariaDB [(none)]&gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| keystone           |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.001 sec)
 
MariaDB [(none)]&gt; use keystone;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
MariaDB [keystone]&gt; show tables;
+------------------------------------+
| Tables_in_keystone                 |
+------------------------------------+
| access_rule                        |
.....
+------------------------------------+
46 rows in set (0.001 sec)

Now that the script is parameterized, the next step is to parameterize the container image itself. It turns out that there are two main ways to do this; to pass in environment variables or add to the command line. First, the env vars approach.

I made a slight change to the script above so that it used the env vars, but did not expect them to be passed in from outside:

diff --git a/keystoneconfig/configure_keystone.sh b/keystoneconfig/configure_keystone.sh
index 05c8ed8..094e30e 100755
--- a/keystoneconfig/configure_keystone.sh
+++ b/keystoneconfig/configure_keystone.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
-MYSQL_HOST=$1
-MYSQL_PORT=$2
+#MYSQL_HOST=$1
+#MYSQL_PORT=$2

To run the container:

podman run -it --network maria-bridge  -e MYSQL_HOST=10.89.0.4 -e MYSQL_PORT=3306 localhost/keystoneconfig

I like this from the calling side as it names the parameters explicitly. However, if I were re-using the script indie the container, I might want to have the parameters on the command line. They are also global parameters, which is an anti-pattern as well.

To run the script with the command line parameters passed in order, I revert the keystoneconfig/configure_keystone.sh aso that is pulls in the parameters on the command line, but leave the parameters off the CMD line in Dockerfile.

However, if I want to replace the command line parameters, I need to specify the executable as well. Which means that I have to execute the container like this:

# podman run -it --network maria-bridge  localhost/keystoneconfig    /configure_keystone.sh   10.89.0.4  3306

There is an alternative to using configuration values this way. We can mount the config file inside the docker container. But that is a tale for another day.

Leave a Reply

Your email address will not be published. Required fields are marked *

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