github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/hack/lib/golang.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  # Copyright 2014 The Kubernetes Authors.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  # -----------------------------------------------------------------------------
    18  # CHANGELOG
    19  # KubeEdge Authors:
    20  # To Get Detail Version Info for KubeEdge Project
    21  
    22  #set -x
    23  set -o errexit
    24  set -o nounset
    25  set -o pipefail
    26  
    27  YES="y"
    28  NO="n"
    29  
    30  kubeedge::version::get_version_info() {
    31  
    32    GIT_COMMIT=$(git rev-parse "HEAD^{commit}" 2>/dev/null)
    33  
    34    if git_status=$(git status --porcelain 2>/dev/null) && [[ -z ${git_status} ]]; then
    35      GIT_TREE_STATE="clean"
    36    else
    37      GIT_TREE_STATE="dirty"
    38    fi
    39  
    40    GIT_VERSION=$(git describe --tags --abbrev=14 "${GIT_COMMIT}^{commit}" 2>/dev/null)
    41  
    42    # This translates the "git describe" to an actual semver.org
    43    # compatible semantic version that looks something like this:
    44    #   v1.1.0-alpha.0.6+84c76d1142ea4d
    45    #
    46    # TODO: We continue calling this "git version" because so many
    47    # downstream consumers are expecting it there.
    48    #
    49    # These regexes are painful enough in sed...
    50    # We don't want to do them in pure shell, so disable SC2001
    51    # shellcheck disable=SC2001
    52    DASHES_IN_VERSION=$(echo "${GIT_VERSION}" | sed "s/[^-]//g")
    53    if [[ "${DASHES_IN_VERSION}" == "---" ]] ; then
    54      # shellcheck disable=SC2001
    55      # We have distance to subversion (v1.1.0-subversion-1-gCommitHash)
    56      GIT_VERSION=$(echo "${GIT_VERSION}" | sed "s/-\([0-9]\{1,\}\)-g\([0-9a-f]\{14\}\)$/.\1\+\2/")
    57    elif [[ "${DASHES_IN_VERSION}" == "--" ]] ; then
    58        # shellcheck disable=SC2001
    59        # We have distance to base tag (v1.1.0-1-gCommitHash)
    60        GIT_VERSION=$(echo "${GIT_VERSION}" | sed "s/-g\([0-9a-f]\{14\}\)$/+\1/")
    61    fi
    62  
    63    if [[ "${GIT_TREE_STATE}" == "dirty" ]]; then
    64      # git describe --dirty only considers changes to existing files, but
    65      # that is problematic since new untracked .go files affect the build,
    66      # so use our idea of "dirty" from git status instead.
    67      GIT_VERSION+="-dirty"
    68    fi
    69  
    70  
    71    # Try to match the "git describe" output to a regex to try to extract
    72    # the "major" and "minor" versions and whether this is the exact tagged
    73    # version or whether the tree is between two tagged versions.
    74    if [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?([-].*)?([+].*)?$ ]]; then
    75      GIT_MAJOR=${BASH_REMATCH[1]}
    76      GIT_MINOR=${BASH_REMATCH[2]}
    77      if [[ -n "${BASH_REMATCH[4]}" ]]; then
    78        GIT_MINOR+="+"
    79      fi
    80    fi
    81  
    82    # If GIT_VERSION is not a valid Semantic Version, then refuse to build.
    83    if ! [[ "${GIT_VERSION}" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
    84        echo "GIT_VERSION should be a valid Semantic Version. Current value: ${GIT_VERSION}"
    85        echo "Please see more details here: https://semver.org"
    86        exit 1
    87    fi
    88  }
    89  
    90  # Get the value that needs to be passed to the -ldflags parameter of go build
    91  kubeedge::version::ldflags() {
    92    kubeedge::version::get_version_info
    93  
    94    local -a ldflags
    95    function add_ldflag() {
    96      local key=${1}
    97      local val=${2}
    98      # If you update these, also update the list pkg/version/def.bzl.
    99      ldflags+=(
   100        "-X ${KUBEEDGE_GO_PACKAGE}/pkg/version.${key}=${val}"
   101      )
   102    }
   103  
   104    add_ldflag "buildDate" "$(date ${SOURCE_DATE_EPOCH:+"--date=@${SOURCE_DATE_EPOCH}"} -u +'%Y-%m-%dT%H:%M:%SZ')"
   105    if [[ -n ${GIT_COMMIT-} ]]; then
   106      add_ldflag "gitCommit" "${GIT_COMMIT}"
   107      add_ldflag "gitTreeState" "${GIT_TREE_STATE}"
   108    fi
   109  
   110    if [[ -n ${GIT_VERSION-} ]]; then
   111      add_ldflag "gitVersion" "${GIT_VERSION}"
   112    fi
   113  
   114    if [[ -n ${GIT_MAJOR-} && -n ${GIT_MINOR-} ]]; then
   115      add_ldflag "gitMajor" "${GIT_MAJOR}"
   116      add_ldflag "gitMinor" "${GIT_MINOR}"
   117    fi
   118  
   119    # The -ldflags parameter takes a single string, so join the output.
   120    echo "${ldflags[*]-}"
   121  }
   122  
   123  
   124  # kubeedge::binaries_from_targets take a list of build targets and return the
   125  # full go package to be built
   126  kubeedge::golang::binaries_from_targets() {
   127    local target
   128    for target in "$@"; do
   129      echo "${KUBEEDGE_GO_PACKAGE}/${target}"
   130    done
   131  }
   132  
   133  kubeedge::check::env() {
   134    errors=()
   135    if [ -z $GOPATH ]; then
   136      errors+="GOPATH environment value not set"
   137    fi
   138  
   139    # check other env 
   140  
   141    # check lenth of errors
   142    if [[ ${#errors[@]} -ne 0 ]] ; then
   143      local error
   144      for error in ${errors[@]}; do
   145        echo "Error: "$error
   146      done
   147      exit 1
   148    fi
   149  }
   150  
   151  ALL_BINARIES_AND_TARGETS=(
   152    cloudcore:cloud/cmd/cloudcore
   153    admission:cloud/cmd/admission
   154    keadm:keadm/cmd/keadm
   155    edgecore:edge/cmd/edgecore
   156    edgesite:edgesite/cmd/edgesite
   157  )
   158  
   159  kubeedge::golang::get_target_by_binary() {
   160    local key=$1
   161    for bt in "${ALL_BINARIES_AND_TARGETS[@]}" ; do
   162      local binary="${bt%%:*}"
   163      if [ "${binary}" == "${key}" ]; then
   164        echo "${bt##*:}"
   165        return
   166      fi
   167    done
   168    echo "can not find binary: $key"
   169    exit 1
   170  }
   171  
   172  kubeedge::golang::get_all_targets() {
   173    local -a targets
   174    for bt in "${ALL_BINARIES_AND_TARGETS[@]}" ; do
   175      targets+=("${bt##*:}")
   176    done
   177    echo ${targets[@]}
   178  }
   179  
   180  kubeedge::golang::get_all_binares() {
   181    local -a binares 
   182    for bt in "${ALL_BINARIES_AND_TARGETS[@]}" ; do
   183      binares+=("${bt%%:*}")
   184    done
   185    echo ${binares[@]}
   186  }
   187  
   188  IFS=" " read -ra KUBEEDGE_ALL_TARGETS <<< "$(kubeedge::golang::get_all_targets)"
   189  IFS=" " read -ra KUBEEDGE_ALL_BINARIES<<< "$(kubeedge::golang::get_all_binares)"
   190  
   191  kubeedge::golang::build_binaries() {
   192    kubeedge::check::env
   193    local -a targets=()
   194    local binArg
   195    for binArg in "$@"; do
   196      targets+=("$(kubeedge::golang::get_target_by_binary $binArg)")
   197    done
   198    
   199    if [[ ${#targets[@]} -eq 0 ]]; then
   200      targets=("${KUBEEDGE_ALL_TARGETS[@]}")
   201    fi
   202      
   203    local -a binaries
   204    while IFS="" read -r binary; do binaries+=("$binary"); done < <(kubeedge::golang::binaries_from_targets "${targets[@]}")
   205  
   206    local ldflags
   207    read -r ldflags <<< "$(kubeedge::version::ldflags)"
   208  
   209    mkdir -p ${KUBEEDGE_OUTPUT_BINPATH}
   210    for bin in ${binaries[@]}; do
   211      echo "building $bin"
   212      local name="${bin##*/}"
   213      set -x
   214      go build -o ${KUBEEDGE_OUTPUT_BINPATH}/${name} -ldflags "$ldflags" $bin
   215      set +x
   216    done
   217  
   218  }
   219  
   220  
   221  KUBEEDGE_ALL_CROSS_BINARIES=(
   222  edgecore
   223  edgesite
   224  )
   225  
   226  kubeedge::golang::is_cross_build_binary() {
   227    local key=$1
   228    for bin in "${KUBEEDGE_ALL_CROSS_BINARIES[@]}" ; do
   229      if [ "${bin}" == "${key}" ]; then
   230        echo ${YES} 
   231        return
   232      fi
   233    done
   234    echo ${NO} 
   235  }
   236  
   237  KUBEEDGE_ALL_CROSS_GOARMS=(
   238  8
   239  7
   240  )
   241  
   242  kubeedge::golang::is_supported_goarm() {
   243    local key=$1
   244    for value in ${KUBEEDGE_ALL_CROSS_GOARMS[@]} ; do
   245      if [ "${value}" == "${key}" ]; then
   246        echo ${YES} 
   247        return
   248      fi
   249    done
   250    echo ${NO} 
   251  }
   252  
   253  kubeedge::golang::cross_build_place_binaries() {
   254    kubeedge::check::env
   255    
   256    local -a targets=()
   257    local goarm=${goarm:-${KUBEEDGE_ALL_CROSS_GOARMS[0]}}
   258  
   259    for arg in "$@"; do
   260        if [[ "${arg}" == GOARM* ]]; then
   261          # Assume arguments starting with a dash are flags to pass to go.
   262          goarm="${arg##*GOARM}"
   263        else
   264          if [ "$(kubeedge::golang::is_cross_build_binary ${arg})" == "${NO}" ]; then
   265            echo "${arg} does not support cross build"
   266            exit 1
   267          fi
   268          targets+=("$(kubeedge::golang::get_target_by_binary $arg)")
   269        fi
   270    done
   271  
   272    if [[ ${#targets[@]} -eq 0 ]]; then
   273      for bin in ${KUBEEDGE_ALL_CROSS_BINARIES[@]}; do
   274          targets+=("$(kubeedge::golang::get_target_by_binary $bin)")
   275      done
   276    fi
   277    
   278    if [ "$(kubeedge::golang::is_supported_goarm ${goarm})" == "${NO}" ]; then
   279      echo "GOARM${goarm} does not support cross build"
   280      exit 1 
   281    fi
   282  
   283    local -a binaries
   284    while IFS="" read -r binary; do binaries+=("$binary"); done < <(kubeedge::golang::binaries_from_targets "${targets[@]}")
   285  
   286    local ldflags
   287    read -r ldflags <<< "$(kubeedge::version::ldflags)"
   288  
   289    mkdir -p ${KUBEEDGE_OUTPUT_BINPATH}
   290    for bin in ${binaries[@]}; do
   291      echo "cross buildding $bin GOARM${goarm}"
   292      local name="${bin##*/}"
   293      if [ "${goarm}" == "8" ]; then
   294        set -x
   295        GOARCH=arm64 GOOS="linux" CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc go build -o ${KUBEEDGE_OUTPUT_BINPATH}/${name} -ldflags "$ldflags" $bin
   296        set +x
   297      elif [ "${goarm}" == "7" ]; then
   298        set -x
   299        GOARCH=arm GOOS="linux" GOARM=${goarm} CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc go build -o ${KUBEEDGE_OUTPUT_BINPATH}/${name} -ldflags "$ldflags" $bin
   300        set +x
   301      fi
   302    done
   303  }
   304  
   305  KUBEEDGE_ALL_SMALL_BINARIES=(
   306  edgecore
   307  edgesite
   308  )
   309  
   310  kubeedge::golang::is_small_build_binary() {
   311    local key=$1
   312    for bin in "${KUBEEDGE_ALL_SMALL_BINARIES[@]}" ; do
   313      if [ "${bin}" == "${key}" ]; then
   314        echo ${YES} 
   315        return
   316      fi
   317    done
   318    echo ${NO} 
   319  }
   320  
   321  kubeedge::golang::small_build_place_binaries() {
   322    kubeedge::check::env
   323    local -a targets=()
   324  
   325    for arg in "$@"; do
   326      if [ "$(kubeedge::golang::is_small_build_binary ${arg})" == "${NO}" ]; then
   327        echo "${arg} does not support small build"
   328        exit 1
   329      fi
   330      targets+=("$(kubeedge::golang::get_target_by_binary $arg)")
   331    done
   332  
   333    if [[ ${#targets[@]} -eq 0 ]]; then
   334      for bin in ${KUBEEDGE_ALL_SMALL_BINARIES[@]}; do
   335          targets+=("$(kubeedge::golang::get_target_by_binary $bin)")
   336      done
   337    fi
   338    
   339    local -a binaries
   340    while IFS="" read -r binary; do binaries+=("$binary"); done < <(kubeedge::golang::binaries_from_targets "${targets[@]}")
   341  
   342    local ldflags
   343    read -r ldflags <<< "$(kubeedge::version::ldflags)"
   344  
   345    mkdir -p ${KUBEEDGE_OUTPUT_BINPATH}
   346    for bin in ${binaries[@]}; do
   347      echo "small building $bin"
   348      local name="${bin##*/}"
   349      set -x
   350      go build -o ${KUBEEDGE_OUTPUT_BINPATH}/${name} -ldflags "-w -s -extldflags -static $ldflags" $bin
   351      upx-ucl -9 ${KUBEEDGE_OUTPUT_BINPATH}/${name}
   352      set +x
   353    done
   354  }
   355  
   356  
   357  kubeedge::golang::get_cloud_test_dirs() {
   358    (
   359      local findDirs
   360      local -a dirArray
   361      cd ${KUBEEDGE_ROOT}
   362      findDirs=$(find -L ./cloud -not \( \
   363          \( \
   364            -path './cloud/test/integration/*' \
   365          \) -prune \
   366        \) -name '*_test.go' -print0 | xargs -0n1 dirname | LC_ALL=C sort -u)
   367      dirArray=(${findDirs// /})
   368      echo "${dirArray[@]}"
   369    )
   370  }
   371  
   372  kubeedge::golang::get_keadm_test_dirs() {
   373      cd ${KUBEEDGE_ROOT}
   374      findDirs=$(find -L ./keadm \
   375  	    -name '*_test.go' -print | xargs -0n1 dirname | uniq)
   376      echo "${findDirs}"
   377  }
   378  
   379  kubeedge::golang::get_edge_test_dirs() {
   380    (
   381      local findDirs
   382      local -a dirArray=()
   383      cd ${KUBEEDGE_ROOT}
   384      findDirs=$(find "./edge/pkg" -name "*_test.go"| xargs -I{} dirname {} | uniq)
   385      dirArray=(${findDirs// /})
   386      echo "${dirArray[@]}"
   387    )
   388  }
   389  
   390  read -ra KUBEEDGE_CLOUD_TESTCASES <<< "$(kubeedge::golang::get_cloud_test_dirs)"
   391  read -ra KUBEEDGE_EDGE_TESTCASES <<< "$(kubeedge::golang::get_edge_test_dirs)"
   392  read -ra KUBEEDGE_KEADM_TESTCASES <<< "$(kubeedge::golang::get_keadm_test_dirs)"
   393  
   394  readonly KUBEEDGE_ALL_TESTCASES=(
   395    ${KUBEEDGE_CLOUD_TESTCASES[@]}
   396    ${KUBEEDGE_EDGE_TESTCASES[@]}
   397    ${KUBEEDGE_KEADM_TESTCASES[@]}
   398  )
   399  
   400  ALL_COMPONENTS_AND_GETTESTDIRS_FUNCTIONS=(
   401    cloud::::kubeedge::golang::get_cloud_test_dirs
   402    edge::::kubeedge::golang::get_edge_test_dirs
   403    keadm::::kubeedge::golang::get_keadm_test_dirs
   404  )
   405  
   406  kubeedge::golang::get_testdirs_by_component() {
   407    local key=$1
   408    for ct in "${ALL_COMPONENTS_AND_GETTESTDIRS_FUNCTIONS[@]}" ; do
   409      local component="${ct%%::::*}"
   410      if [ "${component}" == "${key}" ]; then
   411        local testcases="${ct##*::::}"
   412        echo $(eval $testcases)
   413        return
   414      fi
   415    done
   416    echo "can not find component: $key"
   417    exit 1
   418  }
   419  
   420  kubeedge::golang::run_test() {
   421    echo "running tests cases $@"
   422  
   423    cd ${KUBEEDGE_ROOT}
   424  
   425    local -a testdirs=()
   426    local binArg
   427    for binArg in "$@"; do
   428      testdirs+=("$(kubeedge::golang::get_testdirs_by_component $binArg)")
   429    done
   430  
   431    if [[ ${#testdirs[@]} -eq 0 ]]; then
   432      testdirs+=("${KUBEEDGE_ALL_TESTCASES[@]}")
   433    fi
   434  
   435    go test ${testdirs[@]}
   436  }