You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

create_docker.sh 7.1 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #!/usr/bin/env bash
  2. #
  3. # Create a new docker file and build docker according to the options.
  4. #
  5. # Author: donkey <anjingyu_ws@foxmail.com>
  6. # Stop script on NZEC
  7. set -e
  8. # Stop script if unbound variable found (use ${var:-} if intentional)
  9. set -u
  10. # By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
  11. # This is causing it to fail
  12. set -o pipefail
  13. # standard output may be used as a return value in the functions
  14. # we need a way to write text on the screen in the functions so that
  15. # it won't interfere with the return value.
  16. # Exposing stream 3 as a pipe to standard output of the script itself
  17. exec 3>&1
  18. function errtrap()
  19. {
  20. error "[EXCEPTION:$1] Error: Command or function exited with status $?"
  21. }
  22. # Catch the exception
  23. if command -v "trap" >/dev/null 2>&1; then
  24. # Get the exception information when program was breaked
  25. trap 'errtrap $LINENO' ERR
  26. fi
  27. # Prepare the color variables for your terminal
  28. if test -t 1; then # if terminal
  29. ncolors=$(which tput > /dev/null && tput colors) # supports color
  30. if test -n "$ncolors" && test $ncolors -ge 8; then
  31. termcols=$(tput cols)
  32. bold="$(tput bold)"
  33. underline="$(tput smul)"
  34. standout="$(tput smso)"
  35. normal="$(tput sgr0)"
  36. black="$(tput setaf 0)"
  37. red="$(tput setaf 1)"
  38. green="$(tput setaf 2)"
  39. yellow="$(tput setaf 3)"
  40. blue="$(tput setaf 4)"
  41. magenta="$(tput setaf 5)"
  42. cyan="$(tput setaf 6)"
  43. white="$(tput setaf 7)"
  44. fi
  45. fi
  46. readonly VERBOSE=${VERBOSE:-false}
  47. readonly CUR_DIR=$(cd `dirname $0`; pwd)
  48. readonly PROJ_DIR=`dirname $CUR_DIR`
  49. readonly DOCKER_DIR="$PROJ_DIR/docker"
  50. readonly DEFAULT_LTS_VERSION="22.04"
  51. declare -A readonly UBUNTU_LTS_DICT=(["22.04"]="jammy" ["20.04"]="focal" ["18.04"]="bionic")
  52. ### Helper log functions ###
  53. function error()
  54. {
  55. if [ "$VERBOSE" = true ]; then
  56. printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
  57. fi
  58. printf "%b\n" "[ ${red}ERROR${normal} ]: $@" >&2
  59. }
  60. function warning()
  61. {
  62. if [ "$VERBOSE" = true ]; then
  63. printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
  64. fi
  65. printf "%b\n" "[${yellow}WARNING${normal}]: $@" >&3
  66. }
  67. function info()
  68. {
  69. if [ "$VERBOSE" = true ]; then
  70. printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
  71. fi
  72. printf "%b\n" "[ ${cyan}INFOM${normal} ]: $@" >&3
  73. }
  74. function debug()
  75. {
  76. if [ "$VERBOSE" = true ]; then
  77. printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
  78. fi
  79. printf "%b\n" "[ ${magenta}DEBUG${normal} ]: $@" >&3
  80. }
  81. function verbose()
  82. {
  83. if [ "$VERBOSE" = true ]; then
  84. printf "%b\n" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}][${green}VERBOSE${normal}]: $@" >&3
  85. fi
  86. }
  87. #######################################
  88. # Join array by a char
  89. # Globals:
  90. # None
  91. # Arguments:
  92. # $1 -- Delimiter char
  93. # $2 -- Element array
  94. # Returns:
  95. # Spliced string
  96. # Eamples:
  97. # join_by_char , 1 2 3 -> 1,2,3
  98. # eles=(1 2 3); join_by_char '|' "${eles[@]}" -> 1,2,3
  99. #######################################
  100. function join_by_char()
  101. {
  102. local IFS="$1"
  103. shift
  104. echo "$*"
  105. }
  106. #######################################
  107. # Check element is in a set or not
  108. # Globals:
  109. # None
  110. # Arguments:
  111. # $1 -- String whould be checked
  112. # $2 -- Element array
  113. # Examples:
  114. # arr=("Linux" "WebGL" "Windows")
  115. # if ele_in "Linux" "${arr[@]}"; then; echo "in"; fi
  116. #######################################
  117. function ele_in()
  118. {
  119. local _PATTERN="$1"
  120. shift
  121. local _SS=`join_by_char '|' "$@"`
  122. if [[ "$_PATTERN" =~ ^(${_SS})$ ]]; then
  123. return 0
  124. fi
  125. return 1
  126. }
  127. #######################################
  128. # Check the key exists in dict or not
  129. # Globals:
  130. # None
  131. # Arguments:
  132. # $1 -- String whould be checked
  133. # $2 -- A helper string, 'in'
  134. # $3 -- Element array
  135. # Examples:
  136. # declare -A dict=(["Linux"]="linux" ["Darwin"]="macos" ["Windows"]="windows")
  137. # if ! key_exists "FreeBSD" in dict; then echo "No such key"; fi
  138. #######################################
  139. function key_exists()
  140. {
  141. if [ "$2" != in ]; then
  142. error "Incorrect usage."
  143. error "Correct usage: key_exists {key} in {array}"
  144. return
  145. fi
  146. eval '[ ${'$3'[$1]+exists} ]'
  147. }
  148. function usage()
  149. {
  150. printf "%b\n" "Generate ${green}Dockerfile${normal} and do ${cyan}docker build${normal} for a specific ${magenta}Ubuntu LTS${normal} image as the ${blue}GitLab Runner${normal}" >&3
  151. printf "%b\n" " ${green}-t, --target${normal} The target Ubuntu LTS version, default: ${yellow}${DEFAULT_LTS_VERSION}${normal}." >&3
  152. printf "%b\n" " ${green}-n, --name${normal} The tag name of the image, default: ${yellow}builder-ubuntu-$(uname -m):${DEFAULT_LTS_VERSION}${normal}." >&3
  153. printf "%b\n" " ${green}-a, --arch${normal} The architecture for cross compiling: ${yellow}$(uname -m)${normal}." >&3
  154. }
  155. function main()
  156. {
  157. local _ARCH=`uname -m`
  158. local _CODE=$DEFAULT_LTS_VERSION
  159. local _NAME=""
  160. # Parse the options
  161. while [ $# -gt 0 ];
  162. do
  163. case $1 in
  164. -t | --target )
  165. shift
  166. if [ $# -gt 0 ]; then
  167. _CODE=$1
  168. fi
  169. ;;
  170. -n | --name )
  171. shift
  172. if [ $# -gt 0 ]; then
  173. _NAME=$1
  174. fi
  175. ;;
  176. -a | --arch )
  177. shift
  178. if [ $# -gt 0 ]; then
  179. _ARCH=$1
  180. fi
  181. ;;
  182. -h | --help )
  183. usage
  184. exit
  185. ;;
  186. * )
  187. warning "Unknown options: $1"
  188. ;;
  189. esac
  190. shift
  191. done
  192. if ! key_exists "$_CODE" in UBUNTU_LTS_DICT; then
  193. error "The version ${red}${_CODE}${normal} is not supported."
  194. exit -1
  195. fi
  196. if [ -z "$_NAME" ]; then
  197. _NAME="builder-ubuntu-${_ARCH}:${_CODE}"
  198. fi
  199. local _DF_NAME="Dockerfile.ubuntu.${_ARCH}.${_CODE}"
  200. info "Generating ${green}${_DF_NAME}${normal} ..."
  201. cp $DOCKER_DIR/Dockerfile.ubuntu.template $CUR_DIR/${_DF_NAME}
  202. sed -i'.bak' "s|__UBUNTU_TAG__|${_CODE}|g" $CUR_DIR/${_DF_NAME}
  203. sed -i'.bak' "s|__UBUNTU_BRANCH_NAME__|${UBUNTU_LTS_DICT[$_CODE]}|g" $CUR_DIR/${_DF_NAME}
  204. # Cross compile env
  205. if [ ${_ARCH} == "$(uname -m)" ]; then
  206. sed -i'.bak' "s|__UBUNTU_CROSS__||g" $CUR_DIR/${_DF_NAME}
  207. else
  208. local _EMBEDDED_REPO="deb [arch=${_ARCH}] \${EMBEDDED_BASE_URL} \${BRANCH} \${CATATORIES}\\\\ndeb [arch=${_ARCH}] \${EMBEDDED_BASE_URL} \${BRANCH}-updates \${CATATORIES}\\\\ndeb [arch=${_ARCH}] \${EMBEDDED_BASE_URL} \${BRANCH}-backports \${CATATORIES}\\\\ndeb [arch=${_ARCH}] \${EMBEDDED_BASE_URL} \${BRANCH}-security \${CATATORIES}"
  209. sed -i'.bak' "s|__UBUNTU_CROSS__|${_EMBEDDED_REPO}|g" $CUR_DIR/${_DF_NAME}
  210. fi
  211. if [ -f "$CUR_DIR/${_DF_NAME}.bak" ]; then
  212. rm -rf "$CUR_DIR/${_DF_NAME}.bak"
  213. fi
  214. info "Building ${green}${_NAME}${normal} ..."
  215. docker build -f $CUR_DIR/${_DF_NAME} -t ${_NAME} .
  216. }
  217. main $@