#!/bin/sh # 公共函数库 # 总setenv文件权限 SETENV_MOD="550" # 总setenv文件可写状态权限 SETENV_WRITEABLE_MOD="600" # 默认特性配置 DEFAULT_FEATURE_PARAM="all n all" # 写日志 log() { local cur_date_="$(date +"%Y-%m-%d %H:%M:%S")" local log_type_="${1}" local msg_="${2}" local log_format_="[Common] [${cur_date_}] [${log_type_}]: ${msg_}" if [ "${log_type_}" = "INFO" ]; then echo "${log_format_}" elif [ "${log_type_}" = "WARNING" ]; then echo "${log_format_}" elif [ "${log_type_}" = "ERROR" ]; then echo "${log_format_}" elif [ "${log_type_}" = "DEBUG" ]; then echo "${log_format_}" 1> /dev/null fi } # 返回列表长度 __length_list() { local list="$1" local var="$2" local list_item local cnt=0 for list_item in ${list}; do cnt=$((cnt+1)) done eval "${var}=\"${cnt}\"" } # 获取列表索引值 __index_list() { local list="$1" shift local list_item local cnt=0 if [ $# -eq 0 ]; then return 0 fi for list_item in ${list}; do if [ ${1} -eq ${cnt} ]; then eval "${2}=\"${list_item}\"" shift 2 if [ $# -eq 0 ]; then return 0 fi fi cnt=$((cnt+1)) done return 0 } # 从列表中移除一项 __remove_item_in_list() { local to_removed="$1" shift local list="$*" local list_item local new_list for list_item in ${list}; do if [ "${to_removed}" != "${list_item}" ]; then if [ "${new_list}" = "" ]; then new_list="${list_item}" else new_list="${new_list} ${list_item}" fi fi done echo "${new_list}" } # 元素是否在列表中 __item_in_list() { local _outvar="$1" local _item="$2" shift 2 local _list_item local _matched="false" for _list_item in $*; do if [ "${_item}" = "${_list_item}" ]; then _matched="true" break fi done eval "${_outvar}=\"${_matched}\"" } # 反转列表 __reverse_list() { local _outvar="$1" local _list="$2" local _new_list="" local _list_item for _list_item in ${_list}; do if [ "${_new_list}" = "" ]; then _new_list="${_list_item}" else _new_list="${_list_item} ${_new_list}" fi done eval "${_outvar}=\"${_new_list}\"" } # 修改各文件及目录的属性 change_own() { local recursive="$3" local option="" local username="${USERNAME}" local usergroup="${USERGROUP}" if [ "$2" != "NA" ]; then if [ "${recursive}" = "true" ]; then option="-R" fi eval chown ${option} -h \"$2\" \"$1\" if [ $? -ne 0 ]; then log "ERROR" "$1 chown failed!" return 1 fi fi } # 修改各文件及目录的权限 change_mod() { local mod="$2" local install_for_all="$3" local recursive="$4" local option="" # 对于软连接,可能目标文件还没有拷贝进来,导致无法修改mod,这里过滤掉软连接 if [ -L "$1" ]; then return 0 fi if [ "$2" != "NA" ]; then if [ "${recursive}" = "true" ]; then option="-R" fi # 如果设置了install_for_all,则安装时other权限跟group权限对齐 if [ "${install_for_all}" = "y" ]; then local len_mod=${#mod} local new_mod="${mod%?}" local new_mod="${new_mod}${new_mod#${new_mod%?}}" chmod ${option} "${new_mod}" "$1" else chmod ${option} "$2" "$1" fi if [ $? -ne 0 ]; then log "ERROR" "$1 chmod failed!" return 1 fi fi return 0 } # 获取文件权限 get_file_mod() { local _outvar="$1" local _options="" _ret shift while true; do case "$1" in -L|--dereference) _options="${_options} $1" shift ;; *) break ;; esac done local _path="$1" local _result _result="$(stat ${_options} -c %a "${_path}")" _ret="$?" && [ $_ret -ne 0 ] && return $_ret eval "${_outvar}=\"${_result}\"" } # 检查路径是否为绝对路径 __check_abs_path() { local path="$1" if [ "${path#/}" != "${path}" ]; then is_abs_path="true" else is_abs_path="false" fi } __set_abs_path() { local install_path="$1" local path="$2" local varname="$3" local is_abs_path __check_abs_path "${path}" if [ "${is_abs_path}" != "true" ]; then eval "${varname}=\"${install_path}/${path}\"" else eval "${varname}=\"${path}\"" fi } # 创建目录 make_dir() { local path="$1" mkdir -p "${path}" if [ $? -ne 0 ]; then log "ERROR" "${path} mkdir failed!" exit 1 fi return 0 } # 检查install_path在docker_root之中 check_install_path_in_docker_root() { local install_path="$1" local docker_root="$2" echo "${install_path}" | grep "^${docker_root}" > /dev/null 2>&1 if [ $? -ne 0 ]; then log "ERROR" "check install path ${install_path} in docker root ${docker_root} failed!" return 1 fi return 0 } # 移除路径右侧斜线(/) rstrip_path() { local _outvar="$1" local _path="$2" _path="$(echo "${_path}" | sed "s/\/\+\$//g")" eval "${_outvar}=\"${_path}\"" } # 包是否在tools目录下 is_package_under_tools() { local _outvar="$1" local _package="$2" local _result_iput="false" if [ "${_package}" = "aoe" ] || [ "${_package}" = "nca" ] || [ "${_package}" = "amct_acl" ] || [ "${_package}" = "ncs" ]; then _result_iput="true" fi eval "${_outvar}=\"${_result_iput}\"" } # 获取包目录路径 get_package_dirpath() { local _outvar="$1" local _package="$2" local _is_under_tools _result is_package_under_tools "_is_under_tools" "${_package}" if [ "${_is_under_tools}" = "true" ]; then _result="tools/${_package}" else _result="${_package}" fi eval "${_outvar}=\"${_result}\"" } # 获取包ascend_install.info路径 get_package_install_info() { local _outvar="$1" local _install_path="$2" local _version_dir="$3" local _package="$4" local _package_dirpath="" eval "${_outvar}=\"\"" get_package_dirpath "_package_dirpath" "${_package}" eval "${_outvar}=\"${_install_path}/${_version_dir}/${_package_dirpath}/ascend_install.info\"" } # 获取包version.info路径 get_package_version_info() { local _outvar="$1" local _install_path="$2" local _version_dir="$3" local _package="$4" local _package_dirpath="" eval "${_outvar}=\"\"" get_package_dirpath "_package_dirpath" "${_package}" eval "${_outvar}=\"${_install_path}/${_version_dir}/${_package_dirpath}/version.info\"" } # 获取包filelist.csv路径 get_package_filelist() { local _outvar="$1" local _install_path="$2" local _version_dir="$3" local _package="$4" local _package_dirpath="" eval "${_outvar}=\"\"" get_package_dirpath "_package_dirpath" "${_package}" eval "${_outvar}=\"${_install_path}/${_version_dir}/${_package_dirpath}/script/filelist.csv\"" } # 获取包install_common_parser.sh路径 get_package_install_common_parser() { local _outvar="$1" local _install_path="$2" local _version_dir="$3" local _package="$4" local _package_dirpath="" eval "${_outvar}=\"\"" get_package_dirpath "_package_dirpath" "${_package}" eval "${_outvar}=\"${_install_path}/${_version_dir}/${_package_dirpath}/script/install_common_parser.sh\"" } # 获取包script目录路径 get_package_script_dirpath() { local _outvar="$1" local _install_path="$2" local _version_dir="$3" local _package="$4" local _package_dirpath="" eval "${_outvar}=\"\"" get_package_dirpath "_package_dirpath" "${_package}" eval "${_outvar}=\"${_install_path}/${_version_dir}/${_package_dirpath}/script\"" } # 检查参数不为空 check_param_not_empty() { local name="$1" local error_msg="$2" local value eval "value=\"\${${name}}\"" if [ "${value}" = "" ]; then comm_log "ERROR" "$2" return 1 fi return 0 } # 检查文件存在 check_file_exists() { local path="$1" local error_msg="$2" if [ ! -f "${path}" ]; then comm_log "ERROR" "$2" return 1 fi return 0 } # 检查返回值是否为0 check_ret_error() { local ret="$1" local msg="$2" if [ ${ret} -ne 0 ]; then comm_log "ERROR" "${msg}" return ${ret} fi return 0 } # 检查返回值是否为0 check_ret_warning() { local ret="$1" local msg="$2" if [ ${ret} -ne 0 ]; then comm_log "WARNING" "${msg}" return ${ret} fi return 0 } # 获取真实路径 get_realpath() { local _outvar="$1" local _path_gr="$2" _path_gr="$(readlink -f "${_path_gr}")" eval "${_outvar}=\"${_path_gr}\"" } # 检查返回值是否为0 cleanup_if_error() { local ret="$1" local cleanup="$2" if [ ${ret} -ne 0 ]; then eval "${cleanup}" return ${ret} fi return 0 } # 获取是否需要install_for_all get_install_for_all() { local _outvar="$1" eval "${_outvar}=\"n\"" if [ "$(id -u)" = "0" ]; then eval "${_outvar}=\"y\"" fi } # 获取临时目录 get_tmp_root() { local _outvar="$1" local _result_gtr if [ -d "${HOME}" ]; then _result_gtr="${HOME}" elif [ $(id -u) -eq 0 ] && [ -d "/root" ]; then _result_gtr="/root" else _result_gtr="${PWD}" fi eval "${_outvar}=\"${_result_gtr}\"" return 0 } # 获取临时文件 get_tmp_file() { local _outvar="$1" local _filename="$2" local _tmp_file_gtf _result get_tmp_root "_tmp_file_gtf" _result=$(mktemp "$_tmp_file_gtf/${_filename}_XXXXXX") check_ret_warning "$?" "mktemp $_tmp_file_gtf/${_filename}_XXXXXX failed." ret="$?" && [ $ret -ne 0 ] && return $ret eval "${_outvar}=\"${_result}\"" return 0 } # 获取包架构 get_scene_arch() { local _outvar="$1" local _scene_filepath="$2" local _result _result="$(grep "^arch=" "${_scene_filepath}" | cut -d= -f2-)" eval "${_outvar}=\"${_result}\"" } # 设置公共变量 set_global_vars() { local arch local scene_filepath="${curpath}/../scene.info" if [ -f "${scene_filepath}" ]; then get_scene_arch "arch" "${scene_filepath}" if [ "${arch}" != "" ]; then PKG_ARCH="${arch}" fi fi } # 打包feature参数 pack_feature_param() { local _outvar="$1" local _feature_type="$2" local _feature_exclude_all="$3" local _chip="$4" eval "${_outvar}=\"${_feature_type} ${_feature_exclude_all} ${_chip}\"" } # 解包feature参数 # 注意,调用解包时参数不可加引号 unpack_feature_param() { local _feature_type_var="$1" local _feature_exclude_all_var="$2" local _chip_var="$3" shift 3 eval "${_feature_type_var}=\"${1}\"" eval "${_feature_exclude_all_var}=\"${2}\"" eval "${_chip_var}=\"${3}\"" } # 展开version.info文件中参数 expand_version_file() { if [ "${VERSION_FILE}" = "" ]; then return 0 fi get_version "VERSION" "${VERSION_FILE}" get_version_dir "VERSION_DIR" "${VERSION_FILE}" } # 提取第一项 extract_1st() { local _outvar="$1" eval "${_outvar}=\"$2\"" } # 提取第二项 extract_2nd() { local _outvar="$1" eval "${_outvar}=\"$3\"" } # 获取并发进程数 get_thread_num() { local _outvar="$1" local _thread_num="$(cat /proc/cpuinfo | grep "^processor" | wc -l)" # 未取得CPU核数时,默认为1 if [ "$_thread_num" = "" ] || [ "$_thread_num" = "0" ]; then _thread_num="1" fi # CPU核数2倍 eval "${_outvar}=\"$((_thread_num*2))\"" } # 初始化fifo,用于并发控制 init_fifo() { local _outvar="$1" local _thread_num="$2" local _tmppath_if tmp local _skip_msg="skip init fifo" # 并发数为空时,默认为1 if [ "$_thread_num" = "" ]; then _thread_num="1" comm_log "WARNING" "thread number is empty, use ${_thread_num}." fi # 并发数<=0时,默认为1 if [ $_thread_num -le 0 ]; then comm_log "WARNING" "thread number is ${_thread_num}, use 1." _thread_num="1" fi get_tmp_file _tmppath_if "fifo" if [ -e "$_tmppath_if" ]; then rm -rf "$_tmppath_if" check_ret_warning "$?" "remove old file $_tmppath_if failed, ${_skip_msg}." ret="$?" && [ $ret -ne 0 ] && return $ret fi mkfifo "$_tmppath_if" check_ret_warning "$?" "make fifo $_tmppath_if failed, ${_skip_msg}." ret="$?" && [ $ret -ne 0 ] && return $ret # 使用文件描述符8作并发控制 # 实现方法参考: # exec 8<> "$_tmppath_if" # 创建文件描述符8 check_ret_warning "$?" "open fifo $_tmppath_if file descriptor failed, ${_skip_msg}." ret="$?" && [ $ret -ne 0 ] && return $ret rm -f "$_tmppath_if" check_ret_warning "$?" "remove fifo $_tmppath_if failed, ${_skip_msg}." ret="$?" && [ $ret -ne 0 ] && return $ret for tmp in $(seq $_thread_num); do echo >&8 check_ret_warning "$?" "echo fifo $_tmppath_if failed, ${_skip_msg}." ret="$?" && [ $ret -ne 0 ] && return $ret done eval "${_outvar}=\"${_tmppath_if}\"" } # 根据参数执行 exec_with_param() { local param="$1" shift 1 local exec_mode fifo_path="$PARALLEL_FIFO" tmp extract_1st "exec_mode" "$param" if [ "$exec_mode" = "concurrency" ]; then if [ "$fifo_path" = "none" ] || [ "$fifo_path" = "" ]; then "$@" & else read tmp <&8 { "$@" ret="$?" echo >&8 exit $ret } & fi else "$@" fi }