From 055b8ad63e7ae27c2ca25ac26c527f377ce04ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=A5=E6=B5=A9?= Date: Tue, 23 Sep 2025 15:04:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(database-dump-via-docker-sock):=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8C=87=E5=AE=9A=E5=AE=B9=E5=99=A8=E5=86=85?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=91=BD=E4=BB=A4=E7=9A=84=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database-dump-via-docker-sock.sh | 34 ++++++++++++++++++++++++++++---- docker-exec-via-sock.sh | 24 +++++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/database-dump-via-docker-sock.sh b/database-dump-via-docker-sock.sh index cbc8431..0522953 100755 --- a/database-dump-via-docker-sock.sh +++ b/database-dump-via-docker-sock.sh @@ -12,7 +12,7 @@ print_usage() { cat <&2 Usage: $0 [--socket=PATH] [--api-version=VERSION] --container=NAME \\ [--type=postgres|mysql|kingbase] --backup-prefix=PREFIX [--backup-dir=DIR] \\ - [--mysql-user=USER] [--mysql-password=PASSWORD] + [--mysql-user=USER] [--mysql-password=PASSWORD] [--exec-user=NAME] Options: --socket=PATH Docker Engine unix socket path (default: /var/run/docker.sock) @@ -23,6 +23,7 @@ Options: --backup-prefix=PREFIX Backup filename prefix --mysql-user=USER MySQL user (default: root) --mysql-password=PASSWORD MySQL password (optional) + --exec-user=NAME Force a specific user when running commands inside the container --help Show this help message EOF_USAGE } @@ -36,6 +37,7 @@ BACKUP_PREFIX="" MYSQL_USER="root" MYSQL_PASSWORD="" MYSQL_PASSWORD_SET=0 +EXEC_USER_OVERRIDE="" detect_db_type_from_name() { name_lower=$(printf '%s' "$1" | tr 'A-Z' 'a-z') @@ -82,12 +84,19 @@ escape_for_double_quotes() { docker_exec() { exec_container_name=$1 exec_cmd=$2 + exec_user=${3:-} - curl -fsSL "https://Git.1-H.CC/Scripts/Linux/raw/branch/main/docker-exec-via-sock.sh" | sh -s -- \ + set -- \ --socket="$DOCKER_SOCKET" \ --api-version="$DOCKER_API_VERSION" \ --container="$exec_container_name" \ --cmd="$exec_cmd" + + if [ -n "$exec_user" ]; then + set -- "$@" --user="$exec_user" + fi + + curl -fsSL "https://Git.1-H.CC/Scripts/Linux/raw/branch/main/docker-exec-via-sock.sh" | sh -s -- "$@" } while [ "$#" -gt 0 ]; do @@ -158,6 +167,14 @@ while [ "$#" -gt 0 ]; do MYSQL_PASSWORD="$1" MYSQL_PASSWORD_SET=1 ;; + --exec-user=*) + EXEC_USER_OVERRIDE="${1#*=}" + ;; + --exec-user) + if [ "$#" -lt 2 ]; then missing_value '--exec-user'; fi + shift + EXEC_USER_OVERRIDE="$1" + ;; --help) print_usage exit 0 @@ -207,6 +224,8 @@ if [ -z "$DB_TYPE" ]; then fi fi +EXEC_USER_DEFAULT="" + case $DB_TYPE in postgres) BACKUP_EXTENSION=".sql.zst" @@ -227,6 +246,7 @@ case $DB_TYPE in BACKUP_EXTENSION=".sql.zst" DUMP_CMD="sys_dumpall --clean --username=\"\${DB_USER:-kingbase}\"" COMPRESS_CMD="zstd" + EXEC_USER_DEFAULT="root" ;; *) printf 'Unsupported database type: %s\n' "$DB_TYPE" >&2 @@ -234,6 +254,12 @@ case $DB_TYPE in ;; esac +if [ -n "$EXEC_USER_OVERRIDE" ]; then + EXEC_USER="$EXEC_USER_OVERRIDE" +else + EXEC_USER="$EXEC_USER_DEFAULT" +fi + timestamp=$(date +%Y-%m-%d_%H-%M-%S) backup_path="$BACKUP_DIR/${BACKUP_PREFIX}${timestamp}${BACKUP_EXTENSION}" @@ -244,7 +270,7 @@ cmd="mkdir -p \"${BACKUP_DIR}\" && set -o pipefail && ${DUMP_CMD} | ${COMPRESS_C log_border="----------------------------------------------------------------------" printf '%s\n' "$log_border" >&2 -if ! docker_exec "$CONTAINER_NAME" "$cmd"; then +if ! docker_exec "$CONTAINER_NAME" "$cmd" "${EXEC_USER:-}"; then printf '%s\n' "$log_border" >&2 log "backup command failed" exit 1 @@ -257,7 +283,7 @@ log "backup command finished, verifying file size inside container" verify_cmd="du -h \"${backup_path}\" 2>/dev/null | awk 'NR==1{print \$1}'" printf '%s\n' "$log_border" >&2 -size=$(docker_exec "$CONTAINER_NAME" "$verify_cmd" | tr -d '\r') +size=$(docker_exec "$CONTAINER_NAME" "$verify_cmd" "${EXEC_USER:-}" | tr -d '\r') printf '%s\n' "$log_border" >&2 printf '\n' >&2 diff --git a/docker-exec-via-sock.sh b/docker-exec-via-sock.sh index cda5c79..6a44b6d 100644 --- a/docker-exec-via-sock.sh +++ b/docker-exec-via-sock.sh @@ -21,13 +21,14 @@ log_stream() { print_usage() { cat <&2 -Usage: $0 [--socket=PATH] [--api-version=VERSION] --container=NAME --cmd=COMMAND +Usage: $0 [--socket=PATH] [--api-version=VERSION] --container=NAME --cmd=COMMAND [--user=NAME] Options: --socket=PATH Docker Engine unix socket path (default: /var/run/docker.sock) --api-version=VERSION Docker API version (default: v1.51) --container=NAME Container name to execute command in --cmd=COMMAND Command to execute in the container + --user=NAME Run command as the specified user (default: container default user) --shell=SHELL Shell to use (default: sh) 暂未实现 --help Show this help message EOF @@ -37,6 +38,7 @@ DOCKER_SOCKET="/var/run/docker.sock" DOCKER_API_VERSION="v1.51" CONTAINER_NAME="" CMD_TO_EXEC="" +EXEC_USER="" DOCKER_LAST_RESPONSE="" require_command() { @@ -55,13 +57,13 @@ missing_value() { docker_exec_create() { docker_exec_create_desc=$1 docker_exec_create_cmd=$2 - docker_exec_create_payload=$(jq -n --arg cmd "$docker_exec_create_cmd" '{ + docker_exec_create_payload=$(jq -n --arg cmd "$docker_exec_create_cmd" --arg user "$EXEC_USER" '{ AttachStdin: false, AttachStdout: true, AttachStderr: true, Tty: true, Cmd: ["sh", "-c", $cmd] - }') + } | if ($user | length) > 0 then .User = $user else . end) DOCKER_LAST_RESPONSE=$(curl --silent --show-error --unix-socket "$DOCKER_SOCKET" \ -X POST \ @@ -141,6 +143,14 @@ while [ "$#" -gt 0 ]; do shift CMD_TO_EXEC="$1" ;; + --user=*) + EXEC_USER="${1#*=}" + ;; + --user) + if [ "$#" -lt 2 ]; then missing_value '--user'; fi + shift + EXEC_USER="$1" + ;; --help) print_usage exit 0 @@ -180,7 +190,11 @@ fi docker_api_base="http://localhost/${DOCKER_API_VERSION}" exec_create_endpoint="${docker_api_base}/containers/${CONTAINER_NAME}/exec" -log "executing command in container '$CONTAINER_NAME': $CMD_TO_EXEC" +if [ -n "$EXEC_USER" ]; then + log "executing command in container '$CONTAINER_NAME' as '$EXEC_USER': $CMD_TO_EXEC" +else + log "executing command in container '$CONTAINER_NAME': $CMD_TO_EXEC" +fi exec_id=$(docker_exec_create "command" "$CMD_TO_EXEC") if [ -z "$exec_id" ]; then @@ -203,4 +217,4 @@ else # 将错误输出打印到 stderr echo "$output" >&2 exit "$exit_code" -fi \ No newline at end of file +fi