鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

脚本打包方式

由于Nginx实际迁移场景中,部分配置文件、静态文件等存放在Nginx安装路径外,为方便打包源成分,我们提供了一个打包脚本示例。脚本会将Nginx安装路径外源成分按照其原目录结构打包在“/打包路径/Nginx安装路径/sbin/source_related”目录下。

  • 该脚本只是一个打包示例,不存在危险操作、源码泄露,请您根据实际情况部分或全部复制后使用。
  • 仅支持源码编译的Nginx,且二进制在“Nginx安装路径/sbin”目录下。
  • 手动添加迁移场景不支持通过RPM包安装的Nginx迁移。如需迁移,请使用虚拟机镜像迁移场景或手动进行迁移。
  1. 请在源虚拟机的任意位置创建一个.sh脚本文件(例如pack_nginx_sources.sh),并将pack_nginx_sources.sh添加到该文件中(该脚本为一个可用的示例,可根据需求进行相应修改)。
  2. 执行该脚本以完成打包过程。打包后的tar包位于“/home”目录下。
    1
    bash /path/to/pack_nginx_sources.sh /usr/local/nginx
    

    请根据提示信息输入Nginx二进制路径:

    1
    Enter nginx binary path:
    
    • /path/to:脚本实际存放路径。
    • /usr/local/nginx:源Nginx安装目录的绝对路径,请根据实际路径进行修改。
  3. 如果执行脚本过程中出现以下报错,请按照如下步骤进行操作。
    -bash: ./autoBuild.sh: /bin/bash^M: bad interpreter: No such file or directory
    1. 安装dos2unix。
      1
      yum install dos2unix
      
    2. 安装成功后执行以下命令。
      1
      dos2unix pack_nginx_sources.sh
      
    3. 执行完成后请重新启动脚本。
    若您无可用Yum源安装失败,请执行以下命令,执行完成后请重新启动脚本。
    sed -i 's/\r//g' pack_nginx_sources.sh
  4. 打包完成后请手动删除生成的“/home/nginx_mig_tmp”目录。

pack_nginx_sources.sh

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/bash

# 检查命令行参数,确保提供了源Nginx安装目录的绝对路径
if [ $# -ne 1 ]; then
     echo "Usage: $0 <source_nginx_install_dir>"
     exit 1
fi

source_nginx_dir="$1"
source_nginx_binary="$source_nginx_dir/sbin/nginx"
temp_dir="/home/nginx_mig_tmp"
source_nginx_tmp="$temp_dir/$(basename "$source_nginx_dir")"
migration_tar="nginx_migration.tar"

if [ ! -d "$source_nginx_dir" ]; then
     echo "The parameter entered is not a valid directory."
     echo "Usage: $0 <source_nginx_install_dir>"
     exit 1
fi

if [ ! -d "$source_nginx_dir/sbin" ]; then
    echo "The source Nginx installation path does not contain the sbin directory."
    echo "Usage: $0 <source_nginx_install_dir>"
    echo "Notice: This script only supports the source Nginx binary stored in \"<source_nginx_install_dir>/sbin\"."
    exit 1
fi

if [ ! -f "$source_nginx_binary" ]; then
    echo "The source Nginx binary file is not in $source_nginx_dir/sbin."
    echo "Usage: $0 <source_nginx_install_dir>"
    echo "Notice: This script only supports the source Nginx binary stored in \"<source_nginx_install_dir>/sbin\"."
    exit 1
fi

# 步骤一:创建临时目录并复制Nginx安装目录
target_nginx_dir="$(dirname "$source_nginx_tmp")"
mkdir -p "$target_nginx_dir"
echo "Copying $source_nginx_dir to $target_nginx_dir ..."
if ! cp -rp "$source_nginx_dir" "$target_nginx_dir"; then
     echo "Failed to copy the Nginx installation directory"
     exit 1
fi
# 创建指定目录打包包外的成分
source_related_dir="$source_nginx_tmp/sbin/source_related"
mkdir -p "$source_related_dir"
mkdir -p "$source_related_dir/external_confs"
external_confs_record="$source_related_dir/external_confs/external_conf_record.txt"
touch "${external_confs_record}"
chmod 600 "${external_confs_record}"

# 步骤二:获取编译选项指定的依赖文件并复制
echo -e "\e[1;32m Getting installation configure command paths...\e[0m"
keywords="sbin-path|conf-path|error-log-path|http-log-path|http-client-body-temp-path|http-fastcgi-temp-path|http-proxy-temp-path|http-scgi-temp-path|http-uwsgi-temp-path|pid-path|lock-path"
cd "$source_nginx_dir"
strings "$source_nginx_binary" | grep "configure arguments"
strings "$source_nginx_binary" | grep "configure arguments" | grep -Eo "($keywords)=[^[:space:]]+" | awk -F '=' '{print $2}' | while read -r path; do
     # 如果依赖文件已在包内,则跳过复制步骤
     if [[ "$path" == "$source_nginx_dir"* ]]; then
         echo "Skip copying $path because it is in the source Nginx directory."
         continue
     fi

     source_path="$path"

     # 获取相对路径的真实路径
     if [[ "$path" == ../* ]]; then
         source_path=$(realpath --relative-base="$source_nginx_dir" -m "$path")
     fi

     # 如果是nginx的conf和log文件,拷贝所在目录
     if [[ "$source_path" =~ \.conf$ ]] || [[ "$source_path" =~ \.log$ ]]; then
         source_path=$(dirname "$source_path")
     fi

     target_dir="$source_related_dir/$(dirname "$source_path")"
     if [ ! -d "$target_dir" ]; then
         mkdir -p "$target_dir"
     fi
     echo "Copying $source_path to $target_dir ..."
     if ! cp -rp "$source_path" "$target_dir"; then
         echo "Failed to copy file/directory: $source_path"
     fi
 done

# 步骤三:获取启动配置文件并复制
echo " "
echo -e "\e[1;32m Getting startup config file...\n \e[0m"
ps -ef | grep nginx
echo " "
echo "Please refer to the process information of 'ps -ef | grep nginx' above, check whether the source Nginx to be migrated is started with a specified configuration file."
echo "e.g., nginx: master process {path to the Nginx binary to be migrated} -c {configuration file path}"
echo "If it is not specified directly, press Enter to skip this step; otherwise, please enter the configuration file path."
echo "Enter Nginx binary path: "
read -r nginx_binary_path
 keywords="$nginx_binary_path"
ps -ef | grep nginx | grep -oE "nginx: master process $keywords \-c ([^ ]+)" | while read -r line; do
     CONF_FILE=$(echo "$line" | grep -oE 'c ([^ ]+)' | cut -d ' ' -f2)
     echo "[Startup config file]: $CONF_FILE"
     if [ ! -f "$CONF_FILE" ]; then
         continue
     fi
     conf_dir=$(dirname "$CONF_FILE")
     # 包内的跳过
     if [[ "$conf_dir" == "$source_nginx_dir"* ]]; then
         continue
     fi

     echo "$CONF_FILE" >> "$external_confs_record"

     target_dir=$(dirname "$source_related_dir$conf_dir")
     if [ ! -d "$target_dir" ]; then
         mkdir -p "$target_dir"
     fi
     echo "Copying $conf_dir to $target_dir ..."
     if ! cp -rp "$conf_dir" "$target_dir"; then
         echo "Failed to copy confs dir: $conf_dir"
     fi
 done

# 步骤四:扫描配置文件中引用的外部文件/目录并复制
echo " "
echo -e "\e[1;32m Scanning included sources in config file...\e[0m"
conf_file_list=()
while IFS= read -r -d '' file; do
     conf_file_list+=("$file")
done < <(find "$source_nginx_tmp" -type f -name "*.conf" -print0)

# 入参:[line][relative_base_path]
function handle_included() {
     line="$1"
     relative_base_path="$2"
     path=$(echo "$line" | awk '{print $2}' | sed 's/[";]//g')

     if [[ "$path" == /* ]]; then
         source_path="$path"
         target_path="$source_related_dir$source_path"
     elif [[ "$path" == ../* ]]; then
         source_path=$(realpath --relative-base="$relative_base_path" -m "$path")
         target_path="$source_related_dir$source_path"
     else
         return
     fi

     if [[ "${path##*/}" == \** ]]; then
         source_path=$(dirname "$source_path")
         target_path=$(dirname "$target_path")
     fi

     target_dir=$(dirname "$target_path")
     mkdir -p "$target_dir"
     echo "Copying $source_path to $target_dir ..."
     if ! cp -rp "$source_path" "$target_dir"; then
         echo "Failed to copy file/directory: $path"
     fi
}

for file in "${conf_file_list[@]}"; do
     echo "[conf file]: $file"
     file_dir=$(dirname "$file")
     if [ ! -f "$file" ]; then
         continue
     fi
     # 获取源conf的dir
     if echo "$file" | grep -q "source_related"; then
         source_conf_dir=$(echo "$file_dir" | awk -F 'source_related' '{print $2}')
     else
         source_conf_dir="$source_nginx_dir/conf"
     fi
     # 相对于conf路径
     keywords="include|ssl_certificate|ssl_certificate_key|ssl_dhparam"
     cd "$source_conf_dir"
     grep -wE "^[[:space:]]*($keywords)" "$file" | while read -r line; do
         handle_included "$line" "$source_conf_dir"
     done
     # 相对安装路径
     keywords="error_log|access_log|root|alias|client_body_temp_path|fastcgi_temp_path|proxy_temp_path|proxy_cache_path|scgi_temp_path|uwsgi_temp_path"
     cd "$source_nginx_dir"
     grep -wE "^[[:space:]]*($keywords)" "$file" | while read -r line; do
         handle_included "$line" "$source_nginx_dir"
     done
 done

# 步骤五:清理source_related内,步骤三扫描配置文件时,二次拷贝的源Nginx安装目录
echo " "
cd "$(dirname "$temp_dir")"
source_related_nginx="$source_related_dir$source_nginx_dir"
if [ -d "$source_related_nginx" ]; then
     echo "[remove]: $source_related_nginx"
     rm -rf "${source_related_nginx}"
fi

# 步骤六:打包源成分目录
echo " "
echo -e "\e[1;32m Packing tar...\e[0m"
tar cvf "$migration_tar" "$(basename "$temp_dir")" >/dev/null
if [[ "$?" -ne "${SUCCESS}" ]]; then
     echo "Failed to create tar."
     exit 1
fi

echo "Nginx related components are packaged into $migration_tar."
echo "Note: Please manually check and remove unrelated files/dirs if needed."
echo "Please manually upload it to the node server and extract it using the command: tar xvf $migration_tar -C /custom_path"