jenkins部署nodeJs前端工程至阿里OSS

在这里插入图片描述
在这里插入图片描述
执行shell

pwd
chmod -R 777 *
node -v #检测node版本(此条命令非必要)
npm -v #检测npm版本(此条命令非必要)
npm config set registry https://registry.npm.taobao.org #把npm源设置为淘宝源(这个你懂的)
npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass
npm install --unsafe-perm #安装项目中的依赖
npm run build:prod #打包

#!/bin/bash -e

export OSS_ACCESS_KEY_ID=
export OSS_ACCESS_KEY_SECRET=
export OSS_BUCKET=

_urlencode() {
  # urlencode <string>
  old_lc_collate=$LC_COLLATE
  LC_COLLATE=C
  length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
    *) printf '%%%02X' "'$c" ;;
    esac
  done
  LC_COLLATE=$old_lc_collate
}

_ali_nonce() {
    date +"%s%N"
}

_timestamp() {
    date -u +"%Y-%m-%dT%H%%3A%M%%3A%SZ"
}

_ali_urlencode() {
    _str="$1"
    _str_len=${#_str}
    _u_i=1
    while [ "$_u_i" -le "$_str_len" ]; do
        _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")"
        case $_str_c in [a-zA-Z0-9.~_-])
            printf "%s" "$_str_c"
            ;;
        *)
            printf "%%%02X" "'$_str_c"
            ;;
        esac
        _u_i="$(($_u_i + 1))"
    done
}

_ali_signature() {
    sorted_query=$(printf "%s" "${query}" | tr '&' '\n' | sort | paste -s -d '&')
    string_to_sign=$(printf "%s" "GET&%2F&$(_ali_urlencode "${sorted_query}")")
    signature=$(printf "%s" "${string_to_sign}" | openssl sha1 -binary -hmac "${ACCESS_KEY_SECRET}&" | base64)

    _ali_urlencode "${signature}"
}

aliyun_request_builder() {
    query="Format=json&AccessKeyId=${ACCESS_KEY_ID}&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&Version=${version}"
    query="${query}&SignatureNonce=$(_ali_nonce)&Timestamp=$(_timestamp)"

    for q in "$@"; do
        query="${query}&${q%%=*}=$(_ali_urlencode "${q#*=}")"
    done

    query="${query}&Signature=$(_ali_signature "${query}")"
    echo "${query}"
}

aliyun_rest() {
    query="${1}"
    curl -fs "${aliyun_endpoint}?${query}"
}

aliyun_cdn_refresh() {
    ACCESS_KEY_ID="${CDN_ACCESS_KEY_ID}"
    ACCESS_KEY_SECRET="${CDN_ACCESS_KEY_SECRET}"
    if [ -z "${ACCESS_KEY_ID}" ] && [ -z "${ACCESS_KEY_SECRTE}" ]; then
        echo "请设置CDN_ACCESS_KEY_ID,CDN_ACCESS_KEY_SECRET环境变量"
        exit 1
    fi

    aliyun_endpoint="https://cdn.aliyuncs.com/"
    version="2014-11-11"
    request_query="$(aliyun_request_builder \
        Action=RefreshObjectCaches \
        "ObjectPath=${1}" \
        ObjectType=File)"

    aliyun_rest "${request_query}"
}

_oss_upload_one_file() {
    file="${1}"
    if [ -z "${OSS_ACCESS_KEY_ID}" ] && [ -z "${OSS_ACCESS_KEY_SECRET}" ] && [ -z "${OSS_BUCKET}" ]; then
        echo "请设置OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, OSS_BUCKET三个环境变量"
        exit 1
    fi
    upload_path="${OSS_BASE_PATH:-/}"
    host="${OSS_BUCKET}.oss-cn-hangzhou.aliyuncs.com"
    Date="$(LC_ALL=C TZ=GMT date +'%a, %d %b %Y %T %Z')"
    Content_MD5=`openssl md5 -binary < "${file}" | base64`
    extension="${file##*.}"

    case "${extension,,}" in
        js)
            Content_Type=application/javascript
            ;;
        css)
            Content_Type=text/css
            ;;
        json)
            Content_Type=application/json
            ;;
        woff)
            Content_Type=font/woff
            ;;
        woff2)
            Content_Type=font/woff2
            ;;
        *)
            Content_Type=$(file -b --mime-type "${file}")
            ;;
    esac

    storage_path="${upload_path}${file}"
    CanonicalizedResource="/${OSS_BUCKET}${storage_path}"
    SignString="PUT\n${Content_MD5}\n${Content_Type}\n${Date}\n${CanonicalizedResource}"
    Signature=`echo -ne "$SignString" | openssl sha1 -binary -hmac "${OSS_ACCESS_KEY_SECRET}" | base64`
    Authorization="OSS ${OSS_ACCESS_KEY_ID}:${Signature}"

    echo "Uploading '${file}' to bucket: '${OSS_BUCKET}' path: '${storage_path}', content-type: '${Content_Type}'"
    curl -XPUT -sfLkT "${file}" \
        -H "Content-Type: ${Content_Type}" \
        -H "Date: ${Date}" -H "Content-Md5: ${Content_MD5}" \
        -H "Authorization: ${Authorization}" "https://${host}${storage_path}"
}

export -f _oss_upload_one_file

oss_upload() {
    src="${1}"
    cd "${src}"
    find -type f -printf "%P\0" | xargs -0 -I{} --no-run-if-empty -P10 bash -ec "_oss_upload_one_file {}"
}

main() {
    oss_upload "${1}"

    if [ -n "${CDN_URL}" ]; then
        echo "Refreshing CDN: '${CDN_URL}'"
        aliyun_cdn_refresh "${CDN_URL}"
    fi
}

pwd

main dist/

python2 /mnt/cdn/refreshCDN.py -i ${OSS_ACCESS_KEY_ID} -k ${OSS_ACCESS_KEY_SECRET} -r https://system.sharechef.com/ -t clear

refreshCDN.py

#!/usr/bin/env python
#coding=utf-8
# __author__ = 'hanli.zyb'

'''Check Package'''

try:
 import os, sys, getopt, time, json
 from aliyunsdkcore.client import AcsClient
 from aliyunsdkcore.acs_exception.exceptions import ClientException
 from aliyunsdkcore.acs_exception.exceptions import ServerException
 from aliyunsdkcdn.request.v20180510.RefreshObjectCachesRequest import RefreshObjectCachesRequest
 from aliyunsdkcdn.request.v20180510.PushObjectCacheRequest import PushObjectCacheRequest
 from aliyunsdkcdn.request.v20180510.DescribeRefreshTasksRequest import DescribeRefreshTasksRequest
 from aliyunsdkcdn.request.v20180510.DescribeRefreshQuotaRequest import DescribeRefreshQuotaRequest
except:
 sys.exit("[Error] Please pip install aliyun-python-sdk-cdn and aliyun-python-sdk-core ,please install now......")

class Refresh(object):

  '''init func'''

  def __init__(self):

   self.lists = []
   self.param = {}

  '''
  描述:调度的主函数
  resP:检测入参结果,如果类型不是 bool 说明有报错
  '''

  def main(self,argv):
    if len(argv) < 1 :
      sys.exit("\nusage: " + sys.argv[0] + " -h ")
    try:
      opts,args = getopt.getopt(argv,"hi:k:n:r:t:a:o:")
    except Exception as e :
      sys.exit("\nusage: " + sys.argv[0] + " -h ")
  
    for opt,arg in opts:
      if opt == '-h':
        self.helps()
        sys.exit()
      elif opt == '-i':
        self.param['-i'] = arg
      elif opt == '-k':
        self.param['-k'] = arg
      elif opt == '-r':
        self.param['-r'] = arg
      elif opt == '-t':
        self.param['-t'] = arg
      elif opt == '-a':
        self.param['-a'] = arg 
      elif opt == '-o':
        self.param['-o'] = arg
      elif opt == '-n':
        self.param['-n'] = arg
      else:
        sys.exit("\nusage: " + sys.argv[0] + " -h ")
  
    resP = self.doCheck(self.param)
    if not isinstance(resP,bool): sys.exit(resP)
    
    try:
      client = AcsClient(self.param['-i'], self.param['-k'], 'cn-hangzhou')
    except NameError:
      sys.exit("[Error]: SDK module not detected")

#     for g in self.doProd(self.param):
#       self.lists = []
#       self.doRefresh(''.join(g),self.param['-t'],client)
    self.doRefresh(self.param['-r'], self.param['-t'], client)

  '''
  描述:检测入参数
  '''
  def doCheck(self,param):

    try:
      for key1 in ('-i','-k','-r','-t'):
        if not key1 in param.keys():
          return "[Error]: {0} Must be by parameter".format(key1)

      try:
        if not param.has_key('-n'):
          self.param['-n'] = 50
        if not (abs(int(param['-n'])) <= 100 and abs(int(param['-n'])) > 0):
          return "[Error]: 0 < -n <= 100"
        else:
          self.param['-n'] = int(param['-n'])
      except ValueError as e:
        return "[Error]: -n Must be int Type ,{0}".format(str(e))

      if not param['-t'] in ("push","clear"): return "[Error]: taskType Error"
      if param.has_key('-a') and param.has_key('-o'): return "[Error]: -a and -o cannot exist at same time"

      if param.has_key('-a'):
          if not param['-a'] in ("domestic","overseas"): 
            return "[Error]: Area value Error"
          if param['-t'] == 'clear':
            return "[Error]: -t must be push and 'clear' -o use together"

      if param.has_key('-o'):
          if not param['-o'] in ("File","Directory"):
            return "[Error]: ObjectType value Error"
          if param['-t'] == 'push':
            return "[Error]: -t must be clear and 'push' -a use together"

    except KeyError as e:
       return "[Error]: Parameter {0} error".format(str(e))
    return True

  '''
  描述:生成器切分文件,对每行文件进行处理 '\n'
  gop:每次读取 URL 数量
  '''
  def doProd(self,params):
    gop = params['-n']
    mins = 1
    maxs = gop

    with open(params['-r'], "r") as f:
      for line in f.readlines():
        if mins != maxs:
         line = line.strip("\n") + "\n"
        else:
         line = line.strip("\n")
        self.lists.append(line)
        if mins >= maxs:
         yield self.lists
         mins = maxs
         maxs = gop + maxs -1
        else:
         mins += 1
      if len(self.lists) > 0: yield self.lists
       
  '''
  描述:刷新/预热任务
  '''
  def doRefresh(self,lists,types,client):
    try:
      if types == 'clear':
        taskID = 'RefreshTaskId'
        request = RefreshObjectCachesRequest()
        if self.param.has_key('-o'):
          request.set_ObjectType(self.param['-o'])
      elif types == 'push':
        taskID = 'PushTaskId'
        request = PushObjectCacheRequest()
        if self.param.has_key('-a'):
          request.set_Area(self.param['-a'])

      taskreq = DescribeRefreshTasksRequest()
      request.set_accept_format('json')
      request.set_ObjectPath(lists)
      response = json.loads(client.do_action_with_exception(request))
      print(response)
    
      while True:
        count = 0
        taskreq.set_accept_format('json')
        taskreq.set_TaskId(int(response[taskID]))
        taskresp = json.loads(client.do_action_with_exception(taskreq))
        print("[" + response[taskID] + "]" + "is doing refresh CDN ...")
        for t in taskresp['Tasks']['CDNTask']:
          if t['Status'] != 'Complete':
            count += 1
        if count == 0:
          break
        else:
          continue
        time.sleep(5)
    except Exception as e:
      sys.exit("[Error]" + str(e))

  '''
  描述:帮助信息
  '''
  def helps(self):
    print("\nscript options explain: \
            \n\t -i <AccessKey>                  访问阿里云凭证,访问控制台上可以获得; \
            \n\t -k <AccessKeySecret>            访问阿里云密钥,访问控制台上可以获得; \
            \n\t -r <filename>                   文件名称,每行一条 URL,有特殊字符先做 URLencode,以 http/https 开头; \
            \n\t -t <taskType>                   任务类型 clear 刷新,push 预热; \
            \n\t -n [int,[..100]]                可选项,每次操作文件数量,做多 100 条; \
            \n\t -a [String,<domestic|overseas>  可选项,预热范围,不传是默认是全球;\
            \n\t    domestic                     仅中国大陆; \
            \n\t    overseas                     全球(不包含中国大陆); \
            \n\t -o [String,<File|Directory>]    可选项,刷新的类型; \
            \n\t    File                         文件刷新(默认值); \
            \n\t    Directory                    目录刷新")
#TODO 入口

if __name__ == '__main__':
  fun = Refresh()
  fun.main(sys.argv[1:])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值