PHP 基於 Jenkins ansible 動態選擇版本進行自動化部署與回滾(第二版)


PHP 基於 Jenkins ansible 動態選擇版本進行自動化部署與回滾(第二版)

先看流程圖:

流程圖

大概介紹一下:

  • 版本選擇使用jenkins 中的 git parameter 插件實現
  • 回滾方式比較low,直接使用代碼庫目錄方式實現

其中gitlab、ansible、jenkins安裝不在本文討論范圍之內。

效果

先看下效果圖:
jpg

jenkins 發布配置

PHP 代碼不需要 Ant 或者 meaven 編譯,所以可以直接使用。

新建一個項目,比較重要的是:選擇參數化構建

  1. 選擇git parameter,需要給參數定義個變量名稱。部署發布作用區
  2. 選擇dynamic chocie parameter , 選擇回滾版本號,默認 none 的話就是部署發布

下圖為配置詳情:

jpg1

dynamic 參數配置代碼:

def ver_keys = ['bash', '-c','cd /home/www/Repositories/HaifaxOnline/rollback  ;  echo none; ls | sort -rn ' ]
ver_keys.execute().text.tokenize('\n')

git 庫配置

然后選擇git倉庫的配置,網上很多。

回滾和發布配置

然后在構建時選擇插件:excute shell,執行shell 命令:

jp

具體代碼在這:

echo $branch_and_tags
echo "build_id:"$BUILD_NUMBER
echo "項目名稱:" $JOB_NAME
echo "work_sapce" $JENKINS_HOME
echo "choice:" $choice
id

echo "==============================="
if [ $choice = "none" ];then
   echo "choice:部署"
   
   python3 /home/www/deploy.py -build_id=$BUILD_NUMBER -jenkins_home=$JENKINS_HOME -job_name=$JOB_NAME -repo_path=/home/www/Repositories

   sudo ansible-playbook /etc/ansible/$JOB_NAME.yml -e "job_name=$JOB_NAME code_src=/home/www/Repositories/$JOB_NAME/code/ code_dest=/alidata/www/"
   
else
   echo "choice:回滾"
   HIS_ID=$choice
   echo "回滾版本:$HIS_ID"
   sudo ansible-playbook /etc/ansible/$JOB_NAME.yml -e "job_name=$JOB_NAME code_src=/home/www/Repositories/$JOB_NAME/rollback/$HIS_ID/ code_dest=/alidata/www/"
fi

需要注意的是,如果ansible需要使用root用戶執行時,需要對jenkins的帳號授權sodu權限處理。

一些參數的解釋:

  • code_dest: 線上服務器的代碼目錄位置,需要手動配置
  • code_src: jenkins本地服務器的代碼存儲位置,需手動配置
  • job_name: 這個參數為了好套用,所以設計成job_name的方式,傳遞給ansible,ansible的yml文件一定要使用job_name.yml命名,否則會報錯

代碼庫存儲目錄處理:

deploy.py中代碼如下,主要是對jenkins服務器中的本地代碼庫,進行目錄處理:

#!/usr/bin/env python
# -*-coding=utf-8-*-
# __author__ = 'ccorz'

import argparse, os, shutil


class Deploye:
    def __init__(self):
        parse = argparse.ArgumentParser()
        parse.add_argument('-job_name', type=str, required=True)
        parse.add_argument('-build_id', type=str)
        parse.add_argument('-repo_path', type=str)
        parse.add_argument('-jenkins_home', type=str)
        self.args = parse.parse_args()
        self.job_repo = '%s/%s' % (self.args.repo_path, self.args.job_name)
        self.job_git = '%s/workspace/%s/' % (self.args.jenkins_home, self.args.job_name)
        self.job_code = '%s/code' % self.job_repo
        self.job_rollback = '%s/rollback' % self.job_repo

    def path_handler(self):
        """判斷代碼庫目錄是否存在,不存在則創建"""
        # print(self.args.repo_path)
        if not os.path.exists(self.args.repo_path):
            os.mkdir(self.args.repo_path)
        if not os.path.exists(self.job_repo):
            os.makedirs(self.job_rollback,exist_ok=True)
        else:
            shutil.rmtree(self.job_code)

    def copy_code(self):
        shutil.copytree(self.job_git, self.job_code,symlinks=False,ignore=shutil.ignore_patterns('.git'))
        os.system('find %s -ctime +2 -exec rm -rf {} \;' % self.job_rollback)
        shutil.copytree(self.job_git, "%s/%s"%(self.job_rollback,self.args.build_id),
                        symlinks=False,ignore=shutil.ignore_patterns('.git'))

if __name__ == '__main__':
    obj = Deploye()
    obj.path_handler()
    obj.copy_code()

ansbile中的設置

這一部分其實實現方式很多,為了方便套用,基本實現了參數化方式,先看下目錄結構:

chengchendeiMac:ansible shane$ tree
.
|____.DS_Store
|____ansible.cfg
|____google.yml
|____XXXXXnline.yml
|____hosts
|____mysqlbak.yml
|____roles
| |____google
| | |____tasks
| | | |____main.yml
| | |____templates
| | | |____common.inc.php.j2
| | | |____config.common.inc.php.j2
| | |____vars
| | | |____main.yml
| |____XXXXXnline
| | |____tasks
| | | |____main.yml
| | |____templates
| | | |____common.inc.php.j2
| | | |____config.common.inc.php.j2
| | |____vars
| | | |____main.yml
| |____test_job
| | |____tasks
| | | |____main.yml
| | |____templates
| | | |____common.inc.php.j2
| | | |____config.common.inc.php.j2
| | |____vars
| | | |____main.yml

再看下ansible的入口yml文件:

chengchendeiMac:ansible shane$ cat google.yml 
---

- hosts: google
  user: root
  gather_facts: no
  roles:
    - "{{job_name}}"

然后在看下角色配置:

chengchendeiMac:ansible shane$ cat roles/google/tasks/main.yml   
---

- name: sync "{{job_name}}" statics code
  synchronize:
    src: "{{code_src}}/statics/"
    dest: "{{code_dest}}/statics/"
    delete: yes
    rsync_opts: --exclude=upload

- name: sync "{{job_name}}" web code
  synchronize:
    src: "{{code_src}}/web/"
    dest: "{{code_dest}}/p2p/"
    delete: yes
    rsync_opts: '--exclude=data/pay_cache/* --exclude=data/*'

- name: "configure conf files: common.inc.php"
  template:
    src: common.inc.php.j2
    dest: "{{code_dest}}/xxx/common.inc.php"

- name: "configure conf files: config.common.inc.php"
  template:
    src: config.common.inc.php.j2
    dest: "{{code_dest}}/xxx/config.common.inc.php"

因為我這邊的代碼中有兩個目錄,做了動靜分離,寫了兩個,這一塊自由發揮吧。然后使用模板的方式,將固定的配置文件覆蓋即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM