|
- #!/usr/bin/env bash
- #
- # Create a new docker file and build docker according to the options.
- #
- # Author: donkey <anjingyu_ws@foxmail.com>
-
- # Stop script on NZEC
- set -e
- # Stop script if unbound variable found (use ${var:-} if intentional)
- set -u
- # By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
- # This is causing it to fail
- set -o pipefail
-
- # standard output may be used as a return value in the functions
- # we need a way to write text on the screen in the functions so that
- # it won't interfere with the return value.
- # Exposing stream 3 as a pipe to standard output of the script itself
- exec 3>&1
-
- function errtrap()
- {
- error "[EXCEPTION:$1] Error: Command or function exited with status $?"
- }
-
- # Catch the exception
- if command -v "trap" >/dev/null 2>&1; then
- # Get the exception information when program was breaked
- trap 'errtrap $LINENO' ERR
- fi
-
- # Prepare the color variables for your terminal
- if test -t 1; then # if terminal
- ncolors=$(which tput > /dev/null && tput colors) # supports color
- if test -n "$ncolors" && test $ncolors -ge 8; then
- termcols=$(tput cols)
- bold="$(tput bold)"
- underline="$(tput smul)"
- standout="$(tput smso)"
- normal="$(tput sgr0)"
- black="$(tput setaf 0)"
- red="$(tput setaf 1)"
- green="$(tput setaf 2)"
- yellow="$(tput setaf 3)"
- blue="$(tput setaf 4)"
- magenta="$(tput setaf 5)"
- cyan="$(tput setaf 6)"
- white="$(tput setaf 7)"
- fi
- fi
-
- readonly VERBOSE=${VERBOSE:-false}
- readonly CUR_DIR=$(cd `dirname $0`; pwd)
- readonly PROJ_DIR=`dirname $CUR_DIR`
- readonly DOCKER_DIR="$PROJ_DIR/docker"
-
- readonly DEFAULT_LTS_VERSION="22.04"
- declare -A readonly UBUNTU_LTS_DICT=(["22.04"]="jammy" ["20.04"]="focal" ["18.04"]="bionic")
-
- ### Helper log functions ###
- function error()
- {
- if [ "$VERBOSE" = true ]; then
- printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
- fi
- printf "%b\n" "[ ${red}ERROR${normal} ]: $@" >&2
- }
-
- function warning()
- {
- if [ "$VERBOSE" = true ]; then
- printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
- fi
- printf "%b\n" "[${yellow}WARNING${normal}]: $@" >&3
- }
-
- function info()
- {
- if [ "$VERBOSE" = true ]; then
- printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
- fi
- printf "%b\n" "[ ${cyan}INFOM${normal} ]: $@" >&3
- }
-
- function debug()
- {
- if [ "$VERBOSE" = true ]; then
- printf "%b" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}]" >&2
- fi
- printf "%b\n" "[ ${magenta}DEBUG${normal} ]: $@" >&3
- }
-
- function verbose()
- {
- if [ "$VERBOSE" = true ]; then
- printf "%b\n" "[${yellow}$(date +'%Y-%m-%dT%H:%M:%S%z')${normal}][${green}VERBOSE${normal}]: $@" >&3
- fi
- }
-
- #######################################
- # Join array by a char
- # Globals:
- # None
- # Arguments:
- # $1 -- Delimiter char
- # $2 -- Element array
- # Returns:
- # Spliced string
- # Eamples:
- # join_by_char , 1 2 3 -> 1,2,3
- # eles=(1 2 3); join_by_char '|' "${eles[@]}" -> 1,2,3
- #######################################
- function join_by_char()
- {
- local IFS="$1"
- shift
- echo "$*"
- }
-
- #######################################
- # Check element is in a set or not
- # Globals:
- # None
- # Arguments:
- # $1 -- String whould be checked
- # $2 -- Element array
- # Examples:
- # arr=("Linux" "WebGL" "Windows")
- # if ele_in "Linux" "${arr[@]}"; then; echo "in"; fi
- #######################################
- function ele_in()
- {
- local _PATTERN="$1"
- shift
-
- local _SS=`join_by_char '|' "$@"`
-
- if [[ "$_PATTERN" =~ ^(${_SS})$ ]]; then
- return 0
- fi
-
- return 1
- }
-
- #######################################
- # Check the key exists in dict or not
- # Globals:
- # None
- # Arguments:
- # $1 -- String whould be checked
- # $2 -- A helper string, 'in'
- # $3 -- Element array
- # Examples:
- # declare -A dict=(["Linux"]="linux" ["Darwin"]="macos" ["Windows"]="windows")
- # if ! key_exists "FreeBSD" in dict; then echo "No such key"; fi
- #######################################
- function key_exists()
- {
- if [ "$2" != in ]; then
- error "Incorrect usage."
- error "Correct usage: key_exists {key} in {array}"
- return
- fi
-
- eval '[ ${'$3'[$1]+exists} ]'
- }
-
- function usage()
- {
- 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
-
- printf "%b\n" " ${green}-t, --target${normal} The target Ubuntu LTS version, default: ${yellow}${DEFAULT_LTS_VERSION}${normal}." >&3
- printf "%b\n" " ${green}-n, --name${normal} The tag name of the image, default: ${yellow}builder-ubuntu-$(uname -m):${DEFAULT_LTS_VERSION}${normal}." >&3
- printf "%b\n" " ${green}-a, --arch${normal} The architecture for cross compiling: ${yellow}$(uname -m)${normal}." >&3
- }
-
- function main()
- {
- local _ARCH=`uname -m`
- local _CODE=$DEFAULT_LTS_VERSION
- local _NAME=""
-
- # Parse the options
- while [ $# -gt 0 ];
- do
- case $1 in
- -t | --target )
- shift
- if [ $# -gt 0 ]; then
- _CODE=$1
- fi
- ;;
- -n | --name )
- shift
- if [ $# -gt 0 ]; then
- _NAME=$1
- fi
- ;;
- -a | --arch )
- shift
- if [ $# -gt 0 ]; then
- _ARCH=$1
- fi
- ;;
- -h | --help )
- usage
- exit
- ;;
- * )
- warning "Unknown options: $1"
- ;;
- esac
- shift
- done
-
- if ! key_exists "$_CODE" in UBUNTU_LTS_DICT; then
- error "The version ${red}${_CODE}${normal} is not supported."
- exit -1
- fi
-
- if [ -z "$_NAME" ]; then
- _NAME="builder-ubuntu-${_ARCH}:${_CODE}"
- fi
-
- local _DF_NAME="Dockerfile.ubuntu.${_ARCH}.${_CODE}"
-
- info "Generating ${green}${_DF_NAME}${normal} ..."
-
- cp $DOCKER_DIR/Dockerfile.ubuntu.template $CUR_DIR/${_DF_NAME}
- sed -i'.bak' "s|__UBUNTU_TAG__|${_CODE}|g" $CUR_DIR/${_DF_NAME}
- sed -i'.bak' "s|__UBUNTU_BRANCH_NAME__|${UBUNTU_LTS_DICT[$_CODE]}|g" $CUR_DIR/${_DF_NAME}
-
- # Cross compile env
- if [ ${_ARCH} == "$(uname -m)" ]; then
- sed -i'.bak' "s|__UBUNTU_CROSS__||g" $CUR_DIR/${_DF_NAME}
- else
- 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}"
-
- sed -i'.bak' "s|__UBUNTU_CROSS__|${_EMBEDDED_REPO}|g" $CUR_DIR/${_DF_NAME}
- fi
-
- if [ -f "$CUR_DIR/${_DF_NAME}.bak" ]; then
- rm -rf "$CUR_DIR/${_DF_NAME}.bak"
- fi
-
- info "Building ${green}${_NAME}${normal} ..."
- docker build -f $CUR_DIR/${_DF_NAME} -t ${_NAME} .
- }
-
- main $@
|