Как очистить временные файлы после выполнения внутри скрипта точки входа? - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь написать свой собственный образ док-станции mariadb. Я хотел выполнить некоторые операторы sql сразу после запуска контейнера (после exec mysqld). Однако я нашел вариант mysqld --init-file полезным для моего случая. Итак, мой сценарий входа выглядит примерно так:

Dockerfile

FROM alpine:edge

RUN set -ex \
    && apk add mariadb mariadb-client \
    && mkdir -p /run/mysqld \
    && chown -R mysql:mysql /run/mysqld \
    && ln -snf /usr/lib/mariadb /usr/lib/mysql \
    && mysql_install_db --user=mysql --skip-name-resolve --auth-root-authentication-method=socket --auth-root-socket-user=root --force --rpm --skip-test-db

   COPY entrypoint.sh /
   ENTRYPOINT ["/entrypoint.sh"]
   EXPOSE 3306

   CMD ["mysqld"]

entrypoint.sh

#!/bin/sh

set -ex
{
    echo  "CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
    echo  "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE};"
    echo  "GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%';"
} > /tmp/mysqld-init.sql


exec $@ --init-file="/tmp/mysqld-init.sql"

Как видите, временный файл инициализации содержит некоторую конфиденциальную информацию. Я хотел почистить его после исполнения exec $@ --init-file="/tmp/mysqld-init.sql".

Теперь две мысли пришли мне в голову. Один из них - создать файл именованного канала (FIFO) для временной команды sql или использовать команду trap.

Идея-1

Но проблема здесь в том, что ненужный дочерний фоновый процесс продолжает работать на контейнере, поскольку я использовал оператор управления процессом &. Но я напрасно, как я могу выйти из этого процесса.

if [ ! -p "/tmp/mysqld.init" ]; then
    mkfifo /tmp/mysqld.init
fi

{
    echo  "CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
    echo  "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE};"
    echo  "GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%';"
} > /tmp/mysqld.init &

exec $@ --init-file="/tmp/mysqld.init"

Идея-2

Используйте команду trap и очистите временный файл при выполнении команды exec. Но я не знаю, как поймать сигнал exec.

trap cleanup "the exec signal"

cleanup()
{
  echo "Caught Signal ... cleaning up."
  rm -rf /tmp/mysqld-init.sql
  echo "Done cleanup ... quitting."
  exit 1
}
  set -ex
{
    echo  "CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
    echo  "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE};"
    echo  "GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%';"
} > /tmp/mysqld-init.sql

exec $@ --init-file="/tmp/mysqld.init"

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Используйте tini для решения этой проблемы с сигналом и процессом зомби.

FROM alpine:edge

RUN set -ex \
    && apk add --no-cache mariadb mariadb-client tini \
    && mkdir -p /run/mysqld \
    && chown -R mysql:mysql /run/mysqld \
    && ln -snf /usr/lib/mariadb /usr/lib/mysql \
    && mysql_install_db --user=mysql --skip-name-resolve --auth-root-authentication-method=socket --auth-root-socket-user=root --force --rpm --skip-test-db

COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 3306

CMD ["mysqld"]

entrypoint.sh

if [ ! -p "/tmp/mysqld.init" ]; then
    mkfifo /tmp/mysqld.init
fi

{
    echo  "CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
    echo  "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE};"
    echo  "GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%';"
} > /tmp/mysqld.init &

    exec tini -g -- "$@" --init-file="/tmp/mysqld.init"
0 голосов
/ 19 января 2019

Я думаю trap - лучшее решение для этого

function interrupt(){

    local dir=$1
    [ -e ${dir} ] && rm -rf ${dir}
    exit 128
}
TMP_DIR=$(mktemp -d /tmp/entrypoint.XXXX)
trap "interrupt ${TMP_DIR}" SIGINT SIGTERM
trap "rm -rf ${TMP_DIR}" EXIT

set -ex
{
    echo  "CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}';"
    echo  "CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE};"
    echo  "GRANT ALL ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%';"
} > ${TMP_DIR}/mysqld-init.sql

exec $@ --init-file="${TMP_DIR}/mysqld-init.sql"
...