| @ -0,0 +1,79 @@ | |||
| # 接口 | |||
| ```bash | |||
| IP: 192.168.100.50 | |||
| PORT: 8000 | |||
| HOST: baidu-link-submit-ms.juejin.im | |||
| ``` | |||
| ## 资源创建通知 | |||
| ### 请求 | |||
| `POST /v1/events/created` | |||
| ### 参数 | |||
| ```bash | |||
| # 格式 | |||
| Content-Type: application/json; charset=utf-8 | |||
| { | |||
| type, | |||
| id | |||
| } | |||
| ``` | |||
| ```bash | |||
| # 说明 | |||
| type := 'link' | 'column' | |||
| # type -> 资源类型,必需 | |||
| # link -> 链接 | |||
| # column -> 专栏 | |||
| id := <string> | |||
| # id -> 资源 ID,必需 | |||
| ``` | |||
| ### 响应 | |||
| ```bash | |||
| { | |||
| "s": 1, | |||
| "m": "success", | |||
| "d": [] | |||
| } | |||
| ``` | |||
| ### 示例 | |||
| ```bash | |||
| # 专栏文章创建后 | |||
| POST http://192.168.100.50:8000/v1/events/created HTTP/1.1 | |||
| Host: baidu-link-submit-ms.juejin.im | |||
| Content-Type: application/json | |||
| { | |||
| "type": "column", | |||
| "id": "5ac9dc9af265da23884d5543" | |||
| } | |||
| ``` | |||
| ## 资源更新通知 | |||
| ### 请求 | |||
| `POST /v1/events/updated` | |||
| 其余同上。 | |||
| ## 资源删除通知 | |||
| ### 请求 | |||
| `POST /v1/events/deleted` | |||
| 其余同上。 | |||
| @ -1,2 +1 @@ | |||
| # hi-guoqian-go-ms | |||
| guoqian Go->redis | |||
| @ -0,0 +1,58 @@ | |||
| # baidu_link_submit_ms.private.conf | |||
| # baidu_link_submit_ms nginx config file. | |||
| # | |||
| # This file auto generated by baidu_link_submit_ms/scripts/init_config.sh, | |||
| # [WARRING!] DO NOT change this manualy. | |||
| # | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| upstream baidu_link_submit_ms_private { | |||
| server 127.0.0.1:10100; | |||
| keepalive 64; | |||
| } | |||
| server { | |||
| listen 8000; | |||
| server_name baidu-link-submit-ms.juejin.im; | |||
| default_type 'text/plain'; # or browser will download page | |||
| include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||
| root /data/repo/baidu_link_submit_ms; | |||
| access_log /data/repo/baidu_link_submit_ms/logs/nginx-access.public.log logstash; | |||
| error_log /data/repo/baidu_link_submit_ms/logs/nginx-error.public.log; | |||
| client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||
| proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||
| # X-Juejin-Src for api src trace back | |||
| # X-Juejin-Uid for non-login user id | |||
| # X-Juejin-Token for api param hash check | |||
| add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||
| if ($request_method = OPTIONS ) { | |||
| return 200; | |||
| } | |||
| # global location settings | |||
| location /status { | |||
| return 200; | |||
| } | |||
| location / { | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Nginx-Proxy true; | |||
| proxy_pass http://baidu_link_submit_ms_private; | |||
| } | |||
| location ~ /\. { | |||
| deny all; | |||
| access_log off; | |||
| log_not_found off; | |||
| } | |||
| } | |||
| @ -0,0 +1,58 @@ | |||
| # baidu_link_submit_ms.public.conf | |||
| # baidu_link_submit_ms nginx config file. | |||
| # | |||
| # This file auto generated by baidu_link_submit_ms/scripts/init_config.sh, | |||
| # [WARRING!] DO NOT change this manualy. | |||
| # | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| upstream baidu_link_submit_ms_public { | |||
| server 127.0.0.1:10100; | |||
| keepalive 64; | |||
| } | |||
| server { | |||
| listen 80; | |||
| server_name baidu-link-submit-ms.juejin.im; | |||
| default_type 'text/plain'; # or browser will download page | |||
| include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||
| root /data/repo/baidu_link_submit_ms; | |||
| access_log /data/repo/baidu_link_submit_ms/logs/nginx-access.public.log logstash; | |||
| error_log /data/repo/baidu_link_submit_ms/logs/nginx-error.public.log; | |||
| client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||
| proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||
| # X-Juejin-Src for api src trace back | |||
| # X-Juejin-Uid for non-login user id | |||
| # X-Juejin-Token for api param hash check | |||
| add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||
| if ($request_method = OPTIONS ) { | |||
| return 200; | |||
| } | |||
| # global location settings | |||
| location /status { | |||
| return 200; | |||
| } | |||
| location / { | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Nginx-Proxy true; | |||
| proxy_pass http://baidu_link_submit_ms_public; | |||
| } | |||
| location ~ /\. { | |||
| deny all; | |||
| access_log off; | |||
| log_not_found off; | |||
| } | |||
| } | |||
| @ -0,0 +1 @@ | |||
| 1 | |||
| @ -0,0 +1,12 @@ | |||
| [Unit] | |||
| Description = Micro Service API | |||
| After = syslog.target network.target | |||
| [Service] | |||
| PIDFile = /data/repo/baidu_link_submit_ms/lock/baidu_link_submit_ms.pid | |||
| ExecStart = /data/repo/baidu_link_submit_ms/bin/baidu_link_submit_ms beta | |||
| ExecReload = /data/repo/baidu_link_submit_ms/bin/baidu_link_submit_ms beta reload | |||
| ExecStop = /data/repo/baidu_link_submit_ms/bin/baidu_link_submit_ms beta stop | |||
| [Install] | |||
| WantedBy=multi-user.target | |||
| @ -0,0 +1 @@ | |||
| 1 | |||
| @ -0,0 +1,82 @@ | |||
| #!/bin/sh | |||
| # ci.sh | |||
| # This script for build go projects. | |||
| # @version 170327:2 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # [ci] | |||
| echo "-[ci]-" | |||
| echo "start" | |||
| # ----------------------------[manual config here]------------------------------ | |||
| # base config | |||
| REPO_SRC=/data/repo/baidu_link_submit_ms | |||
| BUILD_TARGET=baidu_link_submit_ms | |||
| # fetch source config | |||
| go_packages=( | |||
| "github.com/astaxie/beego" | |||
| ) | |||
| http_proxy="" | |||
| # deploy config | |||
| DEPLOY_SRC=/data/repo | |||
| DEPLOY_LOG_SRC=/data/logs | |||
| ACTION=$1 | |||
| RELEASE_ENV=$2 | |||
| DEV_ENV_LOCATION=( | |||
| "root@192.168.0.203" | |||
| ) | |||
| BETA_ENV_LOCATION=( | |||
| "root@192.168.0.222" | |||
| ) | |||
| ONLINE_ENV_LOCATION=( | |||
| "root@192.168.100.42" # microservice03v | |||
| "root@192.168.100.44" # microservice04v | |||
| "root@192.168.100.46" # microservice04v | |||
| ) | |||
| # ------------------------------------------------------------------------------ | |||
| # check if release env fit repo src | |||
| NOW_PWD=`pwd` | |||
| if [ "$NOW_PWD" != "${REPO_SRC}/scripts" ] && [ "$NOW_PWD" != "${REPO_SRC}" ]; then | |||
| echo -e "\033[43m[WARRING!] PWD is ${NOW_PWD}, but REPO_SRC is ${REPO_SRC} \033[0m"; | |||
| echo -e "please check your REPO_SRC config to make sure that you config this file correctly."; | |||
| exit 1; | |||
| fi | |||
| # run scripts | |||
| SCRIPTS_SRC="${REPO_SRC}/scripts/ci" | |||
| if [ "${ACTION}" == "build" ]; then | |||
| . "${SCRIPTS_SRC}/fetch_source.sh" | |||
| . "${SCRIPTS_SRC}/build.sh" | |||
| elif [ "${ACTION}" == "release" ]; then | |||
| . "${SCRIPTS_SRC}/fetch_source.sh" | |||
| . "${SCRIPTS_SRC}/build.sh" | |||
| . "${SCRIPTS_SRC}/deploy.sh" | |||
| elif [ "${ACTION}" == "run_bee" ]; then | |||
| . "${SCRIPTS_SRC}/run_bee.sh" | |||
| else | |||
| echo "usage:" | |||
| echo "./ci.sh [action: build/release/run_bee] [beta/online/bee_path]" | |||
| echo "" | |||
| echo "e.g." | |||
| echo "./ci.sh release beta" | |||
| echo "" | |||
| fi | |||
| echo "end" | |||
| @ -0,0 +1,72 @@ | |||
| #!/bin/sh | |||
| # build.sh | |||
| # This script for build go projects. | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # [config] | |||
| echo "-[config]-" | |||
| # ----------------------------[manual config here]------------------------------ | |||
| # REPO_SRC=/data/repo/collection_set_api | |||
| # BUILD_TARGET=collection_set_api | |||
| # ------------------------------------------------------------------------------ | |||
| echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||
| echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||
| echo "" | |||
| sleep 1 | |||
| # [set env] | |||
| echo "-[set env]-" | |||
| # $GOBIN | |||
| export GOBIN="${REPO_SRC}/bin" | |||
| echo -e "\033[34mGOBIN set to: ${GOBIN}\033[0m" | |||
| # $GOPATH | |||
| export GOPATH="${REPO_SRC}" | |||
| echo -e "\033[34mGOPATH set to: ${GOPATH}\033[0m" | |||
| echo "" | |||
| sleep 1 | |||
| # [check old build target] | |||
| echo "-[check old build target]-" | |||
| if [ ! -d $GOBIN ]; then mkdir $GOBIN; fi | |||
| if [ -f "${GOBIN}/${BUILD_TARGET}" ]; then | |||
| echo -e "\033[43m[WARRING!] build target alerady exists, will remove it. \033[0m"; | |||
| echo "old build_target detail:" | |||
| ls -alh "${GOBIN}/${BUILD_TARGET}"; | |||
| oldShaSum=`shasum "${GOBIN}/${BUILD_TARGET}" | awk -F' ' '{print $1}'`; | |||
| echo "target sha: ${oldShaSum}"; | |||
| rm -rf "${GOBIN}/${BUILD_TARGET}"; | |||
| echo "old build target removed."; | |||
| fi | |||
| echo "done." | |||
| echo "" | |||
| sleep 1 | |||
| # [build] | |||
| echo "-[build]-" | |||
| echo "build start: " | |||
| echo "go build -o ${GOBIN}/${BUILD_TARGET}" | |||
| cd "${GOPATH}/src" | |||
| go build -o "${GOBIN}/${BUILD_TARGET}" | |||
| ls -alh "${GOBIN}/${BUILD_TARGET}" | |||
| newShaSum=`shasum "${GOBIN}/${BUILD_TARGET}" | awk -F' ' '{print $1}'`; | |||
| echo "target sha: ${newShaSum}"; | |||
| if [ "$oldShaSum" == "$newShaSum" ];then | |||
| echo -e "\033[43m[WARRING!] old build target shasum is equals to new build target. \033[0m" | |||
| fi | |||
| echo "done." | |||
| @ -0,0 +1,181 @@ | |||
| #!/bin/sh | |||
| # deploy.sh | |||
| # This script deploy repo to target env. | |||
| # @version 170322:2 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # [start deploy] | |||
| echo "-[start deploy]-" | |||
| # ----------------------------[manual config here]------------------------------ | |||
| # REPO_SRC=/data/repo/collection_set_api | |||
| # BUILD_TARGET=collection_set_api | |||
| # DEPLOY_SRC=/data/repo | |||
| # DEPLOY_LOG_SRC=/data/logs | |||
| # RELEASE_ENV=$1 | |||
| # | |||
| # DEV_ENV_LOCATION=( | |||
| # "root@192.168.0.203" | |||
| # ) | |||
| # BETA_ENV_LOCATION=( | |||
| # "root@192.168.0.204" | |||
| # ) | |||
| # ONLINE_ENV_LOCATION=( | |||
| # "root@192.168.100.32" # microservice03v | |||
| # "root@192.168.100.28" # microservice04v | |||
| # ) | |||
| # ------------------------------------------------------------------------------ | |||
| # final release location | |||
| RELEASE_ENV_LOCATION="" | |||
| # release file temp storage location | |||
| RELEASE_TEMP_DIR=/data/repo/release | |||
| # program system service name for systemctl | |||
| SERVICE_NAME="${BUILD_TARGET}.service" | |||
| # final deploy src | |||
| FINAL_DEPLOY_SRC="${DEPLOY_SRC}/${BUILD_TARGET}" | |||
| # nginx config | |||
| NGINX_BIN_LOCATION="/data/apps/nginx/sbin/nginx" | |||
| NGINX_CONFIG_LOCATION="/data/apps/nginx/conf/vhost/" | |||
| # deploy target machine error handler config | |||
| DEPLOY_ERROR_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_error.s" | |||
| DEPLOY_SUCCESS_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_success.s" | |||
| DEPLOY_LOG="${FINAL_DEPLOY_SRC}/logs/deploy.log" | |||
| # print config | |||
| echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||
| echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||
| echo -e "\033[34mRELEASE_TEMP_DIR set to: ${RELEASE_TEMP_DIR}\033[0m" | |||
| echo -e "\033[34mPROJECT WILL DEPLOY TO: ${FINAL_DEPLOY_SRC}\033[0m" | |||
| echo -e "\033[34mSERVICE_NAME set to: ${SERVICE_NAME}\033[0m" | |||
| echo "" | |||
| sleep 2 | |||
| # [check input] | |||
| if [ "$RELEASE_ENV" == "dev" ]; then | |||
| RELEASE_ENV_LOCATION=${DEV_ENV_LOCATION[*]} | |||
| elif [ "$RELEASE_ENV" == "beta" ]; then | |||
| RELEASE_ENV_LOCATION=${BETA_ENV_LOCATION[*]} | |||
| elif [ "$RELEASE_ENV" == "online" ]; then | |||
| RELEASE_ENV_LOCATION=${ONLINE_ENV_LOCATION[*]} | |||
| else | |||
| RELEASE_ENV_LOCATION="" | |||
| fi | |||
| if [ "$RELEASE_ENV_LOCATION" == "" ]; then | |||
| echo "please input an avaliable deploy environment [dev/beta/online]"; | |||
| echo "example: ./deploy.sh beta"; | |||
| exit 1; | |||
| fi | |||
| echo -e "\033[34mRELEASE_ENV set to: ${RELEASE_ENV} \033[0m" | |||
| echo -e "\033[34mRELEASE_ENV_LOCATION set to: \033[0m" | |||
| for releaseLocation in ${RELEASE_ENV_LOCATION[*]}; | |||
| do | |||
| echo -e "\033[34m ${releaseLocation} \033[0m" | |||
| done | |||
| echo "" | |||
| sleep 1 | |||
| # [check old release file] | |||
| echo "-[check old release target]-" | |||
| if [ ! -d $RELEASE_TEMP_DIR ]; then mkdir $RELEASE_TEMP_DIR; fi | |||
| if [ -f "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" ]; then | |||
| echo -e "\033[43m[WARRING!] release target alerady exists, will remove it. \033[0m"; | |||
| ls -alh "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz"; | |||
| oldShaSum=`shasum "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" | awk -F' ' '{print $1}'`; | |||
| echo "target sha: ${oldShaSum}"; | |||
| rm -f "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz"; | |||
| echo "old build target removed."; | |||
| fi | |||
| echo "" | |||
| sleep 1 | |||
| # [compress new release file] | |||
| echo "-[compress new release file]-" | |||
| cd $REPO_SRC; | |||
| tar -zcf "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" "./" | |||
| ls -alh "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz"; | |||
| newShaSum=`shasum "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" | awk -F' ' '{print $1}'`; | |||
| echo "target sha: ${newShaSum}"; | |||
| if [ "$oldShaSum" == "$newShaSum" ];then | |||
| echo -e "\033[43m[WARRING!] old release target shasum is equals to new release target. \033[0m" | |||
| fi | |||
| echo "" | |||
| sleep 1 | |||
| # [deploy] | |||
| echo "-[deploy]-" | |||
| echo "- coyp to target machine" | |||
| for releaseLocation in ${RELEASE_ENV_LOCATION[*]}; | |||
| do | |||
| echo -e "\033[34m deploy to ${releaseLocation} \033[0m"; | |||
| ssh -T $releaseLocation <<DEPLOY_INIT_SCRIPTS_1 | |||
| if [ ! -d $FINAL_DEPLOY_SRC ]; then mkdir $FINAL_DEPLOY_SRC; fi | |||
| if [ -f ${FINAL_DEPLOY_SRC}/${BUILD_TARGET}.tar.gz ]; then | |||
| rm -f ${FINAL_DEPLOY_SRC}/${BUILD_TARGET}.tar.gz; | |||
| fi | |||
| DEPLOY_INIT_SCRIPTS_1 | |||
| scp "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" "${releaseLocation}:${FINAL_DEPLOY_SRC}/"; | |||
| ssh -T $releaseLocation <<DEPLOY_INIT_SCRIPTS_2 | |||
| cd "${FINAL_DEPLOY_SRC}/"; | |||
| tar -zxvf "./${BUILD_TARGET}.tar.gz"; | |||
| DEPLOY_INIT_SCRIPTS_2 | |||
| done | |||
| echo "done." | |||
| echo "" | |||
| echo "-[configure & reactive service]-" | |||
| i=0 | |||
| for releaseLocation in ${RELEASE_ENV_LOCATION[*]}; | |||
| do | |||
| # sleep for online lvs reconnect nginx | |||
| if [ "$i" != "0" ]; then | |||
| echo "sleep 120 seconds for online lvs reconnect nginx."; | |||
| sleep 120; | |||
| fi | |||
| # deploy start | |||
| echo -e "\033[34mconfigure ${releaseLocation} \033[0m" | |||
| ssh -T $releaseLocation <<DEPLOY_SCRIPTS_1 | |||
| # exec reactive scripts | |||
| chmod +x "${FINAL_DEPLOY_SRC}/scripts/ci/reactive_service.sh"; | |||
| bash "${FINAL_DEPLOY_SRC}/scripts/ci/reactive_service.sh" ${REPO_SRC} ${BUILD_TARGET} ${DEPLOY_SRC} ${DEPLOY_LOG_SRC} ${RELEASE_ENV}; | |||
| DEPLOY_SCRIPTS_1 | |||
| #check deploy result | |||
| isDeploySuccess="" | |||
| isDeploySuccess=`ssh -T $releaseLocation <<DEPLOY_SCRIPTS_2 | |||
| cat $DEPLOY_SUCCESS_SIGNAL_FILE | |||
| DEPLOY_SCRIPTS_2` | |||
| if [ "${isDeploySuccess}" != "success" ]; then | |||
| echo -e "\033[43m[ERROR!] deploy failed detected. Failed at : ${releaseLocation}\033[0m"; | |||
| echo "please check release log at : ${releaseLocation}${DEPLOY_LOG}"; | |||
| echo "script exit."; | |||
| exit 1; | |||
| else | |||
| echo -e "\033[32m[OK] deploy success. deploy at : ${releaseLocation}\033[0m"; | |||
| fi | |||
| # counter | |||
| i=$(expr "$i" + "1"); | |||
| done | |||
| echo "done."; | |||
| exit 0; | |||
| @ -0,0 +1,71 @@ | |||
| #!/bin/sh | |||
| # fetch_source.sh | |||
| # This script for fetch source and packages. | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # [config] | |||
| echo "-[config]-" | |||
| # ----------------------------[manual config here]------------------------------ | |||
| # REPO_SRC=/data/repo/collection_set_api | |||
| go_packages=( | |||
| "github.com/astaxie/beego" | |||
| "github.com/garyburd/redigo/redis" | |||
| ) | |||
| # | |||
| # http_proxy="http://localhost:8123" | |||
| # ------------------------------------------------------------------------------ | |||
| # init env | |||
| # $GOBIN | |||
| export GOBIN="${REPO_SRC}/bin" | |||
| echo -e "\033[34mGOBIN set to: ${GOBIN}\033[0m" | |||
| # $GOPATH | |||
| export GOPATH="${REPO_SRC}" | |||
| echo -e "\033[34mGOPATH set to: ${GOPATH}\033[0m" | |||
| # print package list | |||
| echo "package list:" | |||
| for pkg in ${go_packages[*]}; | |||
| do | |||
| echo -e "\033[34m${pkg}\033[0m"; | |||
| done | |||
| echo "" | |||
| if [ "$http_proxy" != "" ]; then | |||
| echo "http_proxy set to:" | |||
| echo -e "\033[34m${http_proxy}\033[0m"; | |||
| echo "http_proxy location info:" | |||
| proxyLocation=`http_proxy=${http_proxy} curl -s ip.gs` | |||
| echo -e "\033[34m${proxyLocation}\033[0m"; | |||
| fi | |||
| echo "" | |||
| sleep 1 | |||
| # [fetch] | |||
| echo "-[fetch package]-" | |||
| for pkg in ${go_packages[*]}; | |||
| do | |||
| if [ "$http_proxy" == "" ]; then | |||
| echo "go get ${pkg}"; | |||
| go get $pkg; | |||
| else | |||
| echo "http_proxy=${http_proxy} go get ${pkg}"; | |||
| http_proxy=${http_proxy} go get $pkg; | |||
| fi | |||
| done | |||
| echo "done." | |||
| @ -0,0 +1,183 @@ | |||
| #!/bin/sh | |||
| # reactive_service.sh | |||
| # This script for reactive this projects. | |||
| # @version 170327:3 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # [config] | |||
| echo "-[config]-" | |||
| # ----------------------------[manual config here]------------------------------ | |||
| REPO_SRC=$1 | |||
| BUILD_TARGET=$2 | |||
| DEPLOY_SRC=$3 | |||
| DEPLOY_LOG_SRC=$4 | |||
| RELEASE_ENV=$5 | |||
| # ------------------------------------------------------------------------------ | |||
| # program system service name for systemctl | |||
| SERVICE_NAME="${BUILD_TARGET}.service" | |||
| # final deploy src | |||
| FINAL_DEPLOY_SRC="${DEPLOY_SRC}/${BUILD_TARGET}" | |||
| # nginx config | |||
| NGINX_BIN_LOCATION="/data/apps/nginx/sbin/nginx" | |||
| NGINX_CONFIG_LOCATION="/data/apps/nginx/conf/vhost/" | |||
| # deploy target machine error handler config | |||
| DEPLOY_ERROR_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_error.s" | |||
| DEPLOY_SUCCESS_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_success.s" | |||
| DEPLOY_LOG="${FINAL_DEPLOY_SRC}/logs/deploy.log" | |||
| # print config | |||
| echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||
| echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||
| echo -e "\033[34mPROJECT WILL DEPLOY TO: ${FINAL_DEPLOY_SRC}\033[0m" | |||
| echo -e "\033[34mSERVICE_NAME set to: ${SERVICE_NAME}\033[0m" | |||
| echo "" | |||
| sleep 2 | |||
| # [check input] | |||
| if [ "$RELEASE_ENV" == "dev" ]; then | |||
| echo "env ok"; | |||
| elif [ "$RELEASE_ENV" == "beta" ]; then | |||
| echo "env ok"; | |||
| elif [ "$RELEASE_ENV" == "online" ]; then | |||
| echo "env ok"; | |||
| else | |||
| echo "please input an avaliable deploy environment [dev/beta/online]"; | |||
| echo "example: ./deploy.sh beta"; | |||
| exit 1; | |||
| fi | |||
| echo -e "\033[34mRELEASE_ENV set to: ${RELEASE_ENV} \033[0m" | |||
| echo "" | |||
| sleep 1 | |||
| # configure log | |||
| if [ ! -d "${DEPLOY_LOG_SRC}/${BUILD_TARGET}" ]; then mkdir "${DEPLOY_LOG_SRC}/${BUILD_TARGET}"; fi | |||
| if [ ! -L "${FINAL_DEPLOY_SRC}/logs" ]; then ln -s "${DEPLOY_LOG_SRC}/${BUILD_TARGET}" "${FINAL_DEPLOY_SRC}/logs"; fi | |||
| # remove old deploy signal | |||
| if [ -f "${DEPLOY_ERROR_SIGNAL_FILE}" ]; then rm -f "${DEPLOY_ERROR_SIGNAL_FILE}"; fi | |||
| if [ -f "${DEPLOY_SUCCESS_SIGNAL_FILE}" ]; then rm -f "${DEPLOY_SUCCESS_SIGNAL_FILE}"; fi | |||
| # deploy start | |||
| echo "" | tee -a $DEPLOY_LOG; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "deploy start" | tee -a $DEPLOY_LOG; | |||
| # configure service | |||
| if [ ! -L "/etc/systemd/system/${SERVICE_NAME}" ]; then | |||
| cp "${FINAL_DEPLOY_SRC}/config/systemctl/${SERVICE_NAME}" "/etc/systemd/system/${SERVICE_NAME}"; | |||
| else | |||
| rm -f "/etc/systemd/system/${SERVICE_NAME}"; | |||
| cp "${FINAL_DEPLOY_SRC}/config/systemctl/${SERVICE_NAME}" "/etc/systemd/system/${SERVICE_NAME}"; | |||
| fi | |||
| # configure nginx | |||
| PUBLIC_NGINX_CONF="${FINAL_DEPLOY_SRC}/config/nginx/${BUILD_TARGET}.public.conf" | |||
| PRIVATE_NGINX_CONF="${FINAL_DEPLOY_SRC}/config/nginx/${BUILD_TARGET}.private.conf" | |||
| if [ -f "${PUBLIC_NGINX_CONF}" ]; then | |||
| ln -s "${PUBLIC_NGINX_CONF}" $NGINX_CONFIG_LOCATION; | |||
| fi | |||
| if [ -f "${PRIVATE_NGINX_CONF}" ]; then | |||
| ln -s "${PRIVATE_NGINX_CONF}" $NGINX_CONFIG_LOCATION; | |||
| fi | |||
| # test nginx config | |||
| $NGINX_BIN_LOCATION -t 2> "${FINAL_DEPLOY_SRC}/logs/nginx_test.log"; | |||
| isNginxOk=`grep 'test is successful' "${FINAL_DEPLOY_SRC}/logs/nginx_test.log" | wc -l `; | |||
| if [ "$isNginxOk" != "1" ]; then | |||
| touch $DEPLOY_ERROR_SIGNAL_FILE; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "[ERROR!] deploy error with nginx config error, nginx config error is : " | tee -a $DEPLOY_LOG; | |||
| cat "${FINAL_DEPLOY_SRC}/logs/nginx_test.log" | tee -a $DEPLOY_LOG; | |||
| exit 1; | |||
| else | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "nginx config is ok:" | tee -a $DEPLOY_LOG; | |||
| cat "${FINAL_DEPLOY_SRC}/logs/nginx_test.log" | tee -a $DEPLOY_LOG; | |||
| fi | |||
| # stop nginx | |||
| $NGINX_BIN_LOCATION -s stop | |||
| # check nginx is stoped | |||
| sleep 20; | |||
| nginxNum=`ps auxw | grep --color 'nginx' | grep -v grep | wc -l` | |||
| if [ "$nginxNum" != "0" ]; then | |||
| touch $DEPLOY_ERROR_SIGNAL_FILE; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "[ERROR!] deploy error with nginx stop failed, nginx process num is : ${nginxNum}" | tee -a $DEPLOY_LOG; | |||
| exit 1; | |||
| else | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "nginx stopped" | tee -a $DEPLOY_LOG; | |||
| fi | |||
| # restart service | |||
| /usr/bin/systemctl daemon-reload; | |||
| /usr/bin/systemctl enable ${SERVICE_NAME}; | |||
| /usr/bin/systemctl stop ${BUILD_TARGET}; # use start-stop for first time deploy | |||
| /usr/bin/systemctl start ${BUILD_TARGET}; | |||
| # check service | |||
| sleep 2; | |||
| /usr/bin/systemctl status "${BUILD_TARGET}" > "${FINAL_DEPLOY_SRC}/logs/service_status.log"; | |||
| serviceStatus=`grep "Active: active" "${FINAL_DEPLOY_SRC}/logs/service_status.log" | wc -l`; | |||
| if [ "$serviceStatus" == "0" ]; then | |||
| touch $DEPLOY_ERROR_SIGNAL_FILE; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "[ERROR!] deploy error with service start failed, systemctl status :" | tee -a $DEPLOY_LOG; | |||
| cat "${FINAL_DEPLOY_SRC}/logs/service_status.log" | tee -a $DEPLOY_LOG; | |||
| # restart nginx | |||
| $NGINX_BIN_LOCATION; | |||
| # check nginx num | |||
| nginxNum=`ps auxw | grep --color 'nginx' | grep -v grep | wc -l` | |||
| sleep 5; | |||
| if [ "$nginxNum" == "0" ]; then | |||
| touch $DEPLOY_ERROR_SIGNAL_FILE; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "[ERROR!] deploy error with nginx start failed, nginx process num is : ${nginxNum}" | tee -a $DEPLOY_LOG; | |||
| exit 1; | |||
| else | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "nginx started" | tee -a $DEPLOY_LOG; | |||
| fi | |||
| exit 1; | |||
| else | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "service started" | tee -a $DEPLOY_LOG; | |||
| cat "${FINAL_DEPLOY_SRC}/logs/service_status.log" | tee -a $DEPLOY_LOG; | |||
| fi | |||
| # start nginx | |||
| $NGINX_BIN_LOCATION | |||
| # check nginx num | |||
| nginxNum=`ps auxw | grep --color 'nginx' | grep -v grep | wc -l`; | |||
| sleep 5; | |||
| if [ "$nginxNum" == "0" ]; then | |||
| touch $DEPLOY_ERROR_SIGNAL_FILE; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "[ERROR!] deploy error with nginx start failed, nginx process num is : ${nginxNum}" | tee -a $DEPLOY_LOG; | |||
| exit 1; | |||
| else | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "nginx started" | tee -a $DEPLOY_LOG; | |||
| fi | |||
| # deploy success | |||
| echo "success" > $DEPLOY_SUCCESS_SIGNAL_FILE; | |||
| echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||
| echo "[OK] deploy success." | tee -a $DEPLOY_LOG; | |||
| exit 0; | |||
| @ -0,0 +1,51 @@ | |||
| #!/bin/sh | |||
| # run_bee.sh | |||
| # This script for run beego projects for dev. | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # [config] | |||
| echo "-[config]-" | |||
| # ----------------------------[manual config here]------------------------------ | |||
| # REPO_SRC=/data/repo/collection_set_api | |||
| # BUILD_TARGET=collection_set_api | |||
| BEE_PATH=$2 | |||
| # ------------------------------------------------------------------------------ | |||
| echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||
| echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||
| echo "" | |||
| sleep 1 | |||
| # [set env] | |||
| echo "-[set env]-" | |||
| # $GOBIN | |||
| export GOBIN="${REPO_SRC}/bin" | |||
| echo -e "\033[34mGOBIN set to: ${GOBIN}\033[0m" | |||
| # $GOPATH | |||
| export GOPATH="${REPO_SRC}" | |||
| echo -e "\033[34mGOPATH set to: ${GOPATH}\033[0m" | |||
| echo "" | |||
| # run | |||
| if [ "${BEE_PATH}" == "" ]; then | |||
| echo "please input bee executable file loacation to run this scripts, like :" | |||
| echo "./ci.sh run_bee /data/bin/bee" | |||
| exit 1; | |||
| fi | |||
| `${BEE_PATH} run ${REPO_SRC}/src` | |||
| echo "done." | |||
| @ -0,0 +1,58 @@ | |||
| # REPO_NAME.private.conf | |||
| # REPO_NAME nginx config file. | |||
| # | |||
| # This file auto generated by REPO_NAME/scripts/init_config.sh, | |||
| # [WARRING!] DO NOT change this manualy. | |||
| # | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| upstream REPO_NAME_private { | |||
| server UPSTREAM_ADDR; | |||
| keepalive 64; | |||
| } | |||
| server { | |||
| listen 8000; | |||
| server_name DOMAIN_NAME; | |||
| default_type 'text/plain'; # or browser will download page | |||
| include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||
| root /data/repo/REPO_NAME; | |||
| access_log /data/repo/REPO_NAME/logs/nginx-access.public.log logstash; | |||
| error_log /data/repo/REPO_NAME/logs/nginx-error.public.log; | |||
| client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||
| proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||
| # X-Juejin-Src for api src trace back | |||
| # X-Juejin-Uid for non-login user id | |||
| # X-Juejin-Token for api param hash check | |||
| add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||
| if ($request_method = OPTIONS ) { | |||
| return 200; | |||
| } | |||
| # global location settings | |||
| location /status { | |||
| return 200; | |||
| } | |||
| location / { | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Nginx-Proxy true; | |||
| proxy_pass http://REPO_NAME_private; | |||
| } | |||
| location ~ /\. { | |||
| deny all; | |||
| access_log off; | |||
| log_not_found off; | |||
| } | |||
| } | |||
| @ -0,0 +1,58 @@ | |||
| # REPO_NAME.public.conf | |||
| # REPO_NAME nginx config file. | |||
| # | |||
| # This file auto generated by REPO_NAME/scripts/init_config.sh, | |||
| # [WARRING!] DO NOT change this manualy. | |||
| # | |||
| # @version 170227:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| upstream REPO_NAME_public { | |||
| server UPSTREAM_ADDR; | |||
| keepalive 64; | |||
| } | |||
| server { | |||
| listen 80; | |||
| server_name DOMAIN_NAME; | |||
| default_type 'text/plain'; # or browser will download page | |||
| include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||
| root /data/repo/REPO_NAME; | |||
| access_log /data/repo/REPO_NAME/logs/nginx-access.public.log logstash; | |||
| error_log /data/repo/REPO_NAME/logs/nginx-error.public.log; | |||
| client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||
| proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||
| # X-Juejin-Src for api src trace back | |||
| # X-Juejin-Uid for non-login user id | |||
| # X-Juejin-Token for api param hash check | |||
| add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||
| if ($request_method = OPTIONS ) { | |||
| return 200; | |||
| } | |||
| # global location settings | |||
| location /status { | |||
| return 200; | |||
| } | |||
| location / { | |||
| proxy_set_header X-Real-IP $remote_addr; | |||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
| proxy_set_header Host $http_host; | |||
| proxy_set_header X-Nginx-Proxy true; | |||
| proxy_pass http://REPO_NAME_public; | |||
| } | |||
| location ~ /\. { | |||
| deny all; | |||
| access_log off; | |||
| log_not_found off; | |||
| } | |||
| } | |||
| @ -0,0 +1,12 @@ | |||
| [Unit] | |||
| Description = Micro Service API | |||
| After = syslog.target network.target | |||
| [Service] | |||
| PIDFile = /data/repo/REPO_NAME/lock/BUILD_TARGET.pid | |||
| ExecStart = /data/repo/REPO_NAME/bin/BUILD_TARGET beta | |||
| ExecReload = /data/repo/REPO_NAME/bin/BUILD_TARGET beta reload | |||
| ExecStop = /data/repo/REPO_NAME/bin/BUILD_TARGET beta stop | |||
| [Install] | |||
| WantedBy=multi-user.target | |||
| @ -0,0 +1,12 @@ | |||
| [Unit] | |||
| Description = Micro Service API | |||
| After = syslog.target network.target | |||
| [Service] | |||
| PIDFile = /data/repo/REPO_NAME/lock/BUILD_TARGET.pid | |||
| ExecStart = /data/repo/REPO_NAME/bin/BUILD_TARGET online | |||
| ExecReload = /data/repo/REPO_NAME/bin/BUILD_TARGET online reload | |||
| ExecStop = /data/repo/REPO_NAME/bin/BUILD_TARGET online stop | |||
| [Install] | |||
| WantedBy=multi-user.target | |||
| @ -0,0 +1,145 @@ | |||
| #!/bin/bash | |||
| # init_config.sh | |||
| # init enviroment config scripts. | |||
| # @version 170322:1 | |||
| # @author zhangxuhong <zhangxuhong@xitu.io> | |||
| # | |||
| # ----------------------------[manual config here]------------------------------ | |||
| # base config | |||
| REPO_SRC=/data/repo/baidu_link_submit_ms | |||
| REPO_NAME=baidu_link_submit_ms | |||
| BUILD_TARGET="${REPO_NAME}" | |||
| RELEASE_ENV=$1 # test, beta, online | |||
| # nginx config file type | |||
| DOMAIN_NAME="baidu-link-submit-ms.juejin.im" | |||
| PUBLIC_UPSTREAM_PORT=13100 | |||
| PRIVATE_UPSTREAM_PORT=13100 | |||
| # ------------------------------------------------------------------------------ | |||
| # default config | |||
| NGINX_CONF_TMPL_PUBLIC="REPO_NAME.public.conf" | |||
| NGINX_CONF_TMPL_PRIVATE="REPO_NAME.private.conf" | |||
| SYSTEMCTL_CONF_TMPL_BETA="REPO_NAME.beta.service" | |||
| SYSTEMCTL_CONF_TMPL_RELEASE="REPO_NAME.online.service" | |||
| # auto generated config | |||
| # nginx | |||
| NGINX_CONFIG_TMPL_FOLDER="${REPO_SRC}/scripts/config_template/nginx" | |||
| NGINX_CONFIG_DEPLOY_FOLDER="${REPO_SRC}/config/nginx" | |||
| NGINX_CONF_PUBLIC="${REPO_NAME}.public.conf" | |||
| NGINX_CONF_PRIVATE="${REPO_NAME}.private.conf" | |||
| NGINX_CONF_PUBLIC_ADDR="${NGINX_CONFIG_DEPLOY_FOLDER}/${NGINX_CONF_PUBLIC}" | |||
| NGINX_CONF_PRIVATE_ADDR="${NGINX_CONFIG_DEPLOY_FOLDER}/${NGINX_CONF_PRIVATE}" | |||
| if [ "${PUBLIC_UPSTREAM_PORT}" != "" ]; then | |||
| UPSTREAM_ADDR_PUBLIC="127.0.0.1:${PUBLIC_UPSTREAM_PORT}" | |||
| fi | |||
| if [ "${PRIVATE_UPSTREAM_PORT}" != "" ]; then | |||
| UPSTREAM_ADDR_PRIVATE="127.0.0.1:${PRIVATE_UPSTREAM_PORT}" | |||
| fi | |||
| # systemctl | |||
| SYSTEMCTL_CONFIG_TMPL_FOLDER="${REPO_SRC}/scripts/config_template/systemctl" | |||
| SYSTEMCTL_CONFIG_DEPLOY_FOLDER="${REPO_SRC}/config/systemctl" | |||
| SYSTEMCTL_CONF="${REPO_NAME}.service" | |||
| SYSTEMCTL_CONF_ADDR="${SYSTEMCTL_CONFIG_DEPLOY_FOLDER}/${SYSTEMCTL_CONF}" | |||
| # release env | |||
| if [ "$RELEASE_ENV" == "dev" ]; then | |||
| RELEASE_ENV_LOCATION="$RELEASE_ENV" | |||
| elif [ "$RELEASE_ENV" == "beta" ]; then | |||
| RELEASE_ENV_LOCATION="$RELEASE_ENV" | |||
| elif [ "$RELEASE_ENV" == "online" ]; then | |||
| RELEASE_ENV_LOCATION="$RELEASE_ENV" | |||
| else | |||
| RELEASE_ENV_LOCATION="" | |||
| fi | |||
| if [ "$RELEASE_ENV_LOCATION" == "" ]; then | |||
| echo "please input an avaliable deploy environment [dev/beta/online]"; | |||
| echo "example: ./init_config.sh.sh beta"; | |||
| exit 1; | |||
| fi | |||
| # ------------------------------------------------------------------------------ | |||
| # scripts start | |||
| # check env | |||
| NOW_PWD=`pwd` | |||
| if [ "$NOW_PWD" != "${REPO_SRC}/scripts" ] && [ "$NOW_PWD" != "${REPO_SRC}" ]; then | |||
| echo -e "\033[43m[WARRING!] PWD is ${NOW_PWD}, but REPO_SRC is ${REPO_SRC} \033[0m"; | |||
| echo -e "please check your REPO_SRC config to make sure that you config this file correctly."; | |||
| exit 1; | |||
| fi | |||
| # [init nginx config] | |||
| # deploy tmpl config to deploy folder | |||
| # for public config | |||
| if [ "${PUBLIC_UPSTREAM_PORT}" != "" ]; then | |||
| # deploy tmpl config to deploy folder | |||
| if [ -f "${NGINX_CONF_PUBLIC_ADDR}" ]; then | |||
| rm -f "${NGINX_CONF_PUBLIC_ADDR}"; | |||
| fi | |||
| cp "${NGINX_CONFIG_TMPL_FOLDER}/${NGINX_CONF_TMPL_PUBLIC}" "${NGINX_CONF_PUBLIC_ADDR}"; | |||
| # replace config param | |||
| sed -i "s/REPO_NAME/${REPO_NAME}/g" "${NGINX_CONF_PUBLIC_ADDR}"; | |||
| # replace domain name | |||
| sed -i "s/DOMAIN_NAME/${DOMAIN_NAME}/g" "${NGINX_CONF_PUBLIC_ADDR}"; | |||
| # replace upstream addr | |||
| sed -i "s/UPSTREAM_ADDR/${UPSTREAM_ADDR_PUBLIC}/g" "${NGINX_CONF_PUBLIC_ADDR}"; | |||
| fi | |||
| # for private config | |||
| if [ "${PRIVATE_UPSTREAM_PORT}" != "" ]; then | |||
| # deploy tmpl config to deploy folder | |||
| if [ -f "${NGINX_CONF_PRIVATE_ADDR}" ]; then | |||
| rm -f "${NGINX_CONF_PRIVATE_ADDR}"; | |||
| fi | |||
| cp "${NGINX_CONFIG_TMPL_FOLDER}/${NGINX_CONF_TMPL_PRIVATE}" "${NGINX_CONF_PRIVATE_ADDR}" | |||
| # replace config param | |||
| sed -i "s/REPO_NAME/${REPO_NAME}/g" "${NGINX_CONF_PRIVATE_ADDR}"; | |||
| # replace domain name | |||
| sed -i "s/DOMAIN_NAME/${DOMAIN_NAME}/g" "${NGINX_CONF_PRIVATE_ADDR}"; | |||
| # replace upstream addr | |||
| sed -i "s/UPSTREAM_ADDR/${UPSTREAM_ADDR_PRIVATE}/g" "${NGINX_CONF_PRIVATE_ADDR}"; | |||
| fi | |||
| # [init systemctl config] | |||
| # deploy tmpl config to deploy folder | |||
| # for beta service | |||
| if [ "${RELEASE_ENV_LOCATION}" == "beta" ]; then | |||
| if [ -f "${SYSTEMCTL_CONF_ADDR}" ]; then | |||
| rm -f "${SYSTEMCTL_CONF_ADDR}"; | |||
| fi | |||
| cp "${SYSTEMCTL_CONFIG_TMPL_FOLDER}/${SYSTEMCTL_CONF_TMPL_BETA}" "${SYSTEMCTL_CONF_ADDR}" | |||
| # replace repo name | |||
| sed -i "s/REPO_NAME/${REPO_NAME}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||
| # replace build target | |||
| sed -i "s/BUILD_TARGET/${BUILD_TARGET}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||
| fi | |||
| # for online service | |||
| if [ "${RELEASE_ENV_LOCATION}" == "online" ]; then | |||
| if [ -f "${SYSTEMCTL_CONF_ADDR}" ]; then | |||
| rm -f "${SYSTEMCTL_CONF_ADDR}"; | |||
| fi | |||
| cp "${SYSTEMCTL_CONFIG_TMPL_FOLDER}/${SYSTEMCTL_CONF_TMPL_RELEASE}" "${SYSTEMCTL_CONF_ADDR}" | |||
| # replace repo name | |||
| sed -i "s/REPO_NAME/${REPO_NAME}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||
| # replace build target | |||
| sed -i "s/BUILD_TARGET/${BUILD_TARGET}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||
| fi | |||
| exit 0; | |||
| @ -0,0 +1,11 @@ | |||
| package base | |||
| import ( | |||
| "github.com/astaxie/beego" | |||
| ) | |||
| const configFilePath = "/data/repo/baidu_link_submit_ms/src/config/app.conf" | |||
| func init() { | |||
| beego.LoadAppConfig("ini", configFilePath) | |||
| } | |||
| @ -0,0 +1,21 @@ | |||
| appname = hi_guoqian_go_ms | |||
| httpport = 13100 | |||
| runmode = dev | |||
| autorender = false | |||
| copyrequestbody = true | |||
| EnableDocs = false | |||
| [dev] | |||
| redisAddress = 192.168.0.204:6379 | |||
| redisDb = 0 | |||
| redisPassword= | |||
| [beta] | |||
| redisAddress = 192.168.0.204:6379 | |||
| redisDb = 0 | |||
| redisPassword= | |||
| [proc] | |||
| redisAddress = 192.168.100.15:6379 | |||
| redisDb = 1 | |||
| redisPassword=rcASeLT1NayQp59B4UiM | |||
| @ -0,0 +1,59 @@ | |||
| package controllers | |||
| import ( | |||
| . "errors" | |||
| "github.com/astaxie/beego" | |||
| . "middlewares" | |||
| . "models" | |||
| ) | |||
| var ( | |||
| baseUrl string = "https://juejin.im" | |||
| typePathMap map[string]string = map[string]string{ | |||
| "link": "/entry/", | |||
| "column": "/post/", | |||
| } | |||
| ) | |||
| type EventController struct { | |||
| beego.Controller | |||
| } | |||
| //start | |||
| func (this *EventController) Contribution() { | |||
| ret, err := IncrRedis("hi:guoqian") | |||
| controller := &BeegoController{Controller: this.Controller} | |||
| if err != nil { | |||
| if err.Error() == M_NO_RESULT { | |||
| controller.RenderOutput(EmptyErr(nil)) | |||
| return | |||
| } else { | |||
| controller.RenderOutput(ServerErr(err.Error())) | |||
| return | |||
| } | |||
| }else{ | |||
| controller.RenderOutput(Success(ret)) | |||
| return | |||
| } | |||
| } | |||
| func (this *EventController) Second() { | |||
| ret, err := GetRedis("hi:guoqian") | |||
| controller := &BeegoController{Controller: this.Controller} | |||
| if err != nil { | |||
| if err.Error() == M_NO_RESULT { | |||
| controller.RenderOutput(EmptyErr(nil)) | |||
| return | |||
| } else { | |||
| controller.RenderOutput(ServerErr(err.Error())) | |||
| return | |||
| } | |||
| }else{ | |||
| controller.RenderOutput(Success(ret)) | |||
| return | |||
| } | |||
| } | |||
| //end | |||
| @ -0,0 +1,25 @@ | |||
| package main | |||
| import ( | |||
| "github.com/astaxie/beego" | |||
| _ "base" | |||
| _ "models" | |||
| _ "routers" | |||
| ) | |||
| func main() { | |||
| initLog() | |||
| beego.Run() | |||
| } | |||
| func initLog() { | |||
| name := beego.AppConfig.String("appname") | |||
| logFilePath := "/data/repo/" + name + "/logs/" + name + ".log" | |||
| beego.SetLogger("file", `{"filename":"` + logFilePath + `","level":2,"daily":true,"maxdays":10}`) | |||
| if beego.AppConfig.String("runmode") != "dev" { | |||
| beego.BeeLogger.DelLogger("console") | |||
| } | |||
| beego.BeeLogger.EnableFuncCallDepth(true) | |||
| beego.SetLogFuncCall(true) | |||
| beego.BeeLogger.Async() | |||
| } | |||
| @ -0,0 +1,39 @@ | |||
| package middleware | |||
| import ( | |||
| "github.com/astaxie/beego" | |||
| ) | |||
| type BeegoController struct { | |||
| Controller beego.Controller | |||
| } | |||
| func (c *BeegoController) GetQuery(key string) string { | |||
| return c.Controller.Input().Get(key) | |||
| } | |||
| func (c *BeegoController) GetForm(key string) string { | |||
| return c.Controller.Input().Get(key) | |||
| } | |||
| func (c *BeegoController) GetHeader(key string) string { | |||
| return c.Controller.Ctx.Input.Header(key) | |||
| } | |||
| func (c *BeegoController) GetCookie(key string) string { | |||
| return c.Controller.Ctx.Input.Cookie(key) | |||
| } | |||
| func (c *BeegoController) GetBody() []byte { | |||
| return c.Controller.Ctx.Input.RequestBody | |||
| } | |||
| func (c *BeegoController) GetPath(key string) string { | |||
| return c.Controller.GetString(":" + key) | |||
| } | |||
| func (c *BeegoController) GetArray(key string) []string { | |||
| array := make([]string, 0) | |||
| c.Controller.Ctx.Input.Bind(&array, key) | |||
| return array | |||
| } | |||
| func (c *BeegoController) RenderOutput(ret *RenderStruct) { | |||
| c.Controller.Ctx.Output.Status = ret.Status | |||
| c.Controller.Data["json"] = ret | |||
| c.Controller.ServeJSON() | |||
| } | |||
| @ -0,0 +1,306 @@ | |||
| package middleware | |||
| import ( | |||
| "encoding/json" | |||
| "strconv" | |||
| "time" | |||
| ) | |||
| const ( | |||
| TYPE_STRING = iota | |||
| TYPE_INT | |||
| TYPE_FLOAT | |||
| TYPE_BOOLEAN | |||
| TYPE_TIME | |||
| TYPE_ARRAY | |||
| TYPE_JSON_OBJECT | |||
| ) | |||
| const ( | |||
| POS_QUERY = iota | |||
| POS_HEADER | |||
| POS_BODY_FORM | |||
| POS_BODY_JSON | |||
| POS_PATH | |||
| POS_COOKIE | |||
| ) | |||
| const ( | |||
| TIME_LAYOUT = "2006-01-02T15:04:05Z" | |||
| ) | |||
| type InputInterface interface { | |||
| GetQuery(key string) string | |||
| GetForm(key string) string | |||
| GetHeader(key string) string | |||
| GetCookie(key string) string | |||
| GetBody() []byte | |||
| GetPath(key string) string | |||
| GetArray(key string) []string | |||
| RenderOutput(r *RenderStruct) | |||
| } | |||
| type InputContainer struct { | |||
| simpleMap map[string]interface{} | |||
| objectMap map[string][]byte | |||
| arrayMap map[string][]string | |||
| } | |||
| type InputRule struct { | |||
| Name string | |||
| Description string | |||
| Position int | |||
| Type int | |||
| //此处有蹊跷 | |||
| Limit []string | |||
| Necessary bool | |||
| Max int | |||
| Min int | |||
| Default interface{} | |||
| } | |||
| type CheckError struct { | |||
| Missing string `json:"missing" xml:"missing"` | |||
| Illegal string `json:"illegal" xml:"illegal"` | |||
| } | |||
| func (c *CheckError) Error() string { | |||
| return "input error" | |||
| } | |||
| //must use this func to create a new container | |||
| func NewContainer() *InputContainer { | |||
| return &InputContainer{ | |||
| simpleMap: make(map[string]interface{}), | |||
| objectMap: make(map[string][]byte), | |||
| arrayMap: make(map[string][]string), | |||
| } | |||
| } | |||
| func (i *InputContainer) CheckInput(input InputInterface, rules []*InputRule) *CheckError { | |||
| for _, rule := range rules { | |||
| //check special input type | |||
| switch rule.Type { | |||
| case TYPE_ARRAY: | |||
| arr := input.GetArray(rule.Name) | |||
| if rule.Necessary && len(arr) <= 0 { | |||
| return &CheckError{ | |||
| Missing: rule.Name, | |||
| } | |||
| } | |||
| if rule.Max > 0 { | |||
| if len(arr) > rule.Max { | |||
| return &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| if rule.Min > 0 { | |||
| if len(arr) < rule.Min { | |||
| return &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| i.arrayMap[rule.Name] = arr | |||
| case TYPE_JSON_OBJECT: | |||
| var bytes []byte | |||
| switch rule.Position { | |||
| default: | |||
| fallthrough | |||
| case POS_BODY_JSON: | |||
| bytes = input.GetBody() | |||
| case POS_QUERY: | |||
| bytes = []byte(input.GetQuery(rule.Name)) | |||
| case POS_BODY_FORM: | |||
| bytes = []byte(input.GetForm(rule.Name)) | |||
| case POS_HEADER: | |||
| bytes = []byte(input.GetHeader(rule.Name)) | |||
| case POS_COOKIE: | |||
| bytes = []byte(input.GetCookie(rule.Name)) | |||
| } | |||
| if rule.Necessary && len(bytes) <= 0 { | |||
| return &CheckError{ | |||
| Missing: rule.Name, | |||
| } | |||
| } else if len(bytes) <= 0 { | |||
| continue | |||
| } | |||
| err := json.Unmarshal(bytes, &map[string]interface{}{}) | |||
| if err != nil { | |||
| return &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| i.objectMap[rule.Name] = bytes | |||
| default: | |||
| //check normal input type | |||
| var val string | |||
| switch rule.Position { | |||
| case POS_PATH: | |||
| val = input.GetPath(rule.Name) | |||
| default: | |||
| fallthrough | |||
| case POS_QUERY: | |||
| val = input.GetQuery(rule.Name) | |||
| case POS_BODY_FORM: | |||
| val = input.GetForm(rule.Name) | |||
| case POS_HEADER: | |||
| val = input.GetHeader(rule.Name) | |||
| case POS_COOKIE: | |||
| val = input.GetCookie(rule.Name) | |||
| } | |||
| if rule.Necessary && len(val) <= 0 { | |||
| return &CheckError{ | |||
| Missing: rule.Name, | |||
| } | |||
| } else if len(val) <= 0 { | |||
| i.simpleMap[rule.Name] = rule.Default | |||
| } else { | |||
| res, err := checkValue(rule, val) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| i.simpleMap[rule.Name] = res | |||
| } | |||
| } | |||
| } | |||
| return nil | |||
| } | |||
| func checkValue(rule *InputRule, val string) (interface{}, *CheckError) { | |||
| limit := len(rule.Limit) <= 0 | |||
| if !limit { | |||
| for _, i := range rule.Limit { | |||
| if val == i { | |||
| limit = true | |||
| break | |||
| } | |||
| } | |||
| if !limit { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| switch rule.Type { | |||
| default: | |||
| fallthrough | |||
| case TYPE_STRING: | |||
| if rule.Max > 0 { | |||
| if len(val) > rule.Max { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| if rule.Min > 0 { | |||
| if len(val) < rule.Min { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| return val, nil | |||
| case TYPE_INT: | |||
| intVal, err := strconv.Atoi(val) | |||
| if err != nil { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| if rule.Max > 0 { | |||
| if intVal > rule.Max { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| if rule.Min > 0 { | |||
| if intVal < rule.Min { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| return intVal, nil | |||
| case TYPE_FLOAT: | |||
| floatVal, err := strconv.ParseFloat(val, 64) | |||
| if err != nil { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| if rule.Max > 0 { | |||
| if floatVal > float64(rule.Max) { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| if rule.Min > 0 { | |||
| if floatVal < float64(rule.Min) { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| } | |||
| return floatVal, nil | |||
| case TYPE_BOOLEAN: | |||
| booleanVal, err := strconv.ParseBool(val) | |||
| if err != nil { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| return booleanVal, nil | |||
| case TYPE_TIME: | |||
| t, err := time.Parse(TIME_LAYOUT, val) | |||
| if err != nil { | |||
| return nil, &CheckError{ | |||
| Illegal: rule.Name, | |||
| } | |||
| } | |||
| return t, nil | |||
| } | |||
| } | |||
| func (i *InputContainer) GetInt(key string) int { | |||
| if res, ok := i.simpleMap[key].(int); ok { | |||
| return res | |||
| } | |||
| return 0 | |||
| } | |||
| func (i *InputContainer) GetBoolean(key string) bool { | |||
| if res, ok := i.simpleMap[key].(bool); ok { | |||
| return res | |||
| } | |||
| return false | |||
| } | |||
| func (i *InputContainer) GetFloat(key string) float64 { | |||
| if res, ok := i.simpleMap[key].(float64); ok { | |||
| return res | |||
| } | |||
| return 0 | |||
| } | |||
| func (i *InputContainer) GetString(key string) string { | |||
| if res, ok := i.simpleMap[key].(string); ok { | |||
| return res | |||
| } | |||
| return "" | |||
| } | |||
| func (i *InputContainer) GetArray(key string) []string { | |||
| return i.arrayMap[key] | |||
| } | |||
| func (i *InputContainer) GetObject(key string, obj interface{}) error { | |||
| bytes := i.objectMap[key] | |||
| return json.Unmarshal(bytes, obj) | |||
| } | |||
| func (i *InputContainer) GetTime(key string) time.Time { | |||
| if res, ok := i.simpleMap[key].(time.Time); ok { | |||
| return res | |||
| } | |||
| return time.Time{} | |||
| } | |||
| @ -0,0 +1,112 @@ | |||
| package middleware | |||
| import ( | |||
| "github.com/astaxie/beego" | |||
| "net/http" | |||
| ) | |||
| const ( | |||
| S_UNKNOWN_ERROR = iota | |||
| S_OK | |||
| S_NO_RESULT | |||
| S_ILLEGAL_TOKEN | |||
| S_WRONG_INPUT | |||
| S_WRONG_EXEC_RESULT | |||
| S_TOKEN_EXPIRE | |||
| ) | |||
| const ( | |||
| M_OK = "success" | |||
| M_NO_RESULT = "no result" | |||
| M_ILLEGAL_TOKEN = "illegal token" | |||
| M_TOKEN_EXPIRE = "token expired" | |||
| M_ILLEGAL_SESSION = "illegal session" | |||
| M_WRONG_INPUT = "wrong input" | |||
| M_WRONG_EXEC_RESULT = "exec error" | |||
| ) | |||
| type RenderStruct struct { | |||
| Status int `json:"-"` | |||
| S int `json:"s"` | |||
| M string `json:"m"` | |||
| D interface{} `json:"d"` | |||
| } | |||
| func Success(list interface{}) (r *RenderStruct) { | |||
| r = new(RenderStruct) | |||
| r.Status = http.StatusOK | |||
| r.S = S_OK | |||
| r.M = M_OK | |||
| if list == nil { | |||
| list = []interface{}{} | |||
| } | |||
| r.D = list | |||
| return | |||
| } | |||
| func EmptyErr(list interface{}) (r *RenderStruct) { | |||
| r = new(RenderStruct) | |||
| r.Status = http.StatusOK | |||
| r.S = S_NO_RESULT | |||
| r.M = M_NO_RESULT | |||
| if list == nil { | |||
| list = []interface{}{} | |||
| } | |||
| r.D = list | |||
| return | |||
| } | |||
| func InputErr(data interface{}) (r *RenderStruct) { | |||
| r = new(RenderStruct) | |||
| r.Status = http.StatusBadRequest | |||
| if data == nil { | |||
| data = []interface{}{} | |||
| } | |||
| r.S = S_WRONG_INPUT | |||
| r.M = M_WRONG_INPUT | |||
| r.D = data | |||
| if beego.BConfig.RunMode != "dev" { | |||
| r.D = []interface{}{} | |||
| } | |||
| return | |||
| } | |||
| func NormalErr(status int, s int, msg string, d interface{}) (r *RenderStruct) { | |||
| r = new(RenderStruct) | |||
| r.Status = status | |||
| r.S = s | |||
| r.M = msg | |||
| if d == nil { | |||
| d = []interface{}{} | |||
| } | |||
| r.D = d | |||
| return | |||
| } | |||
| func ServerErr(message string) (r *RenderStruct) { | |||
| r = new(RenderStruct) | |||
| r.Status = http.StatusInternalServerError | |||
| r.S = S_WRONG_EXEC_RESULT | |||
| r.M = message | |||
| if len(message) <= 0 { | |||
| r.M = M_WRONG_EXEC_RESULT | |||
| } | |||
| r.D = []interface{}{} | |||
| return | |||
| } | |||
| func TokenErr(errorType int) (r *RenderStruct) { | |||
| r = new(RenderStruct) | |||
| r.Status = http.StatusForbidden | |||
| switch errorType { | |||
| case S_TOKEN_EXPIRE: | |||
| r.S = S_TOKEN_EXPIRE | |||
| r.M = M_TOKEN_EXPIRE | |||
| default: | |||
| fallthrough | |||
| case S_ILLEGAL_TOKEN: | |||
| r.S = S_ILLEGAL_TOKEN | |||
| r.M = M_ILLEGAL_TOKEN | |||
| } | |||
| r.D = []interface{}{} | |||
| return | |||
| } | |||
| @ -0,0 +1,65 @@ | |||
| package models | |||
| import ( | |||
| "github.com/astaxie/beego" | |||
| "github.com/garyburd/redigo/redis" | |||
| "time" | |||
| ) | |||
| var RedisPool *redis.Pool | |||
| func init() { | |||
| address := beego.AppConfig.String("redisAddress") | |||
| password := beego.AppConfig.String("redisPassword") | |||
| dbNum := beego.AppConfig.String("redisDb") | |||
| dialFunc := func() (c redis.Conn, err error) { | |||
| // c, err = redis.Dial("tcp", address) | |||
| // func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) | |||
| c, err = redis.DialTimeout("tcp", address, 3*time.Second, 3*time.Second, 3*time.Second) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if beego.AppConfig.String("redisPassword") != "" { | |||
| if _, err := c.Do("AUTH", password); err != nil { | |||
| c.Close() | |||
| return nil, err | |||
| } | |||
| } | |||
| _, selecterr := c.Do("SELECT", dbNum) | |||
| if selecterr != nil { | |||
| c.Close() | |||
| return nil, selecterr | |||
| } | |||
| return | |||
| } | |||
| // initialize a new pool | |||
| RedisPool = &redis.Pool{ | |||
| MaxIdle: 100, | |||
| MaxActive: 50, | |||
| IdleTimeout: 180 * time.Second, | |||
| Dial: dialFunc, | |||
| } | |||
| } | |||
| func SetRedis(key string, value []byte) error { | |||
| conn := RedisPool.Get() | |||
| defer conn.Close() | |||
| conn.Send("SET", key, value) | |||
| return conn.Flush() | |||
| } | |||
| func GetRedis(key string) (int64, error) { | |||
| conn := RedisPool.Get() | |||
| defer conn.Close() | |||
| ret, err := redis.Int64(conn.Do("GET", key)) | |||
| return ret, err | |||
| } | |||
| func IncrRedis(key string) (int64, error) { | |||
| conn := RedisPool.Get() | |||
| defer conn.Close() | |||
| ret, err := redis.Int64(conn.Do("INCR", key)) | |||
| return ret, err | |||
| } | |||
| @ -0,0 +1,19 @@ | |||
| package routers | |||
| import ( | |||
| "net/http" | |||
| "github.com/astaxie/beego" | |||
| . "controllers" | |||
| ) | |||
| func init() { | |||
| eventController := EventController{} | |||
| namespace := beego.NewNamespace("/v1", | |||
| beego.NSRouter("/second", &eventController, "get:Second"), | |||
| beego.NSRouter("/contribution", &eventController, "post:Contribution"), | |||
| ) | |||
| beego.AddNamespace(namespace) | |||
| beego.ErrorHandler("404", func(w http.ResponseWriter, r *http.Request) { | |||
| w.WriteHeader(http.StatusNotFound) | |||
| }) | |||
| } | |||