首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何清除内部入口点脚本执行后的临时文件?

如何清除内部入口点脚本执行后的临时文件?
EN

Stack Overflow用户
提问于 2019-01-18 23:57:56
回答 2查看 466关注 0票数 0

我正在尝试写我自己的mariadb码头形象。我想在容器启动后(在exec mysqld之后)执行一些sql语句。但是,我发现mysqld --init-file选项对我的情况很有用。所以我的入口点脚本如下所示。

Dockerfile

代码语言:javascript
复制
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

代码语言:javascript
复制
#!/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"

如您所见,临时init文件包含一些敏感信息。我想在执行exec $@ --init-file="/tmp/mysqld-init.sql"之后清理它。

现在我想到了两个想法。一种是为临时sql命令创建一个命名管道(FIFO)文件,或者使用trap命令。

Idea-1

但是这里的问题是一个不必要的子后台进程是在容器上继续运行,因为我使用了进程控制操作符&。但我是徒劳的,我如何才能退出这一进程。

代码语言:javascript
复制
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"

Idea-2

使用trap命令,并在执行exec命令时清除临时文件。但我不知道怎么才能捕捉到上级的信号。

代码语言:javascript
复制
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"
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-01 15:43:16

使用蒂尼解决这个信号和僵尸进程问题。

代码语言:javascript
复制
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

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2019-01-19 00:50:06

我认为trap是解决这个问题的最佳方法。

代码语言:javascript
复制
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"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54262883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档