Joyber 发布的文章

/usr不是user的缩写,其实usr是Unix Software Resource的缩写, 也就是Unix操作系统软件资源所放置的目录,而不是用户的数据;所有系统默认的软件都会放置到/usr, 系统安装完时,这个目录会占用最多的硬盘容量

/usr目录下的重要目录

  • /usr/X11R6/:为X Window System重要数据所放置的目录,之所以取名为X11R6是因为最后的X版本为第11版,且该版的第6次释出之意。
  • /usr/bin/:绝大部分的用户可使用指令都放在这里。请注意到他与/bin的不同之处。(是否与开机过程有关)
  • /usr/include/:c/c++等程序语言的档头(header)与包含档(include)放置处,当我们以tarball方式 (*.tar.gz 的方式安装软件)安装某些数据时,会使用到里头的许多包含档。
  • /usr/lib/:包含各应用软件的函式库、目标文件(object file),以及不被一般使用者惯用的执行档或脚本(script)。 某些软件会提供一些特殊的指令来进行服务器的设定,这些指令也不会经常被系统管理员操作, 那就会被摆放到这个目录下啦。要注意的是,如果你使用的是X86_64的Linux系统, 那可能会有/usr/lib64/目录产生
  • /usr/local/:统管理员在本机自行安装自己下载的软件(非distribution默认提供者),建议安装到此目录, 这样会比较便于管理。举例来说,你的distribution提供的软件较旧,你想安装较新的软件但又不想移除旧版, 此时你可以将新版软件安装于/usr/local/目录下,可与原先的旧版软件有分别啦。 你可以自行到/usr/local去看看,该目录下也是具有bin, etc, include, lib...的次目录
  • /usr/sbin/:非系统正常运作所需要的系统指令。最常见的就是某些网络服务器软件的服务指令(daemon)
  • /usr/share/:放置共享文件的地方,在这个目录下放置的数据几乎是不分硬件架构均可读取的数据, 因为几乎都是文本文件嘛。在此目录下常见的还有这些次目录:/usr/share/man:联机帮助文件
  • /usr/share/doc:软件杂项的文件说明
  • /usr/share/zoneinfo:与时区有关的时区文件
  • /usr/src/:一般原始码建议放置到这里,src有source的意思。至于核心原始码则建议放置到/usr/src/linux/目录下。

====================================   jenkins 配置新站步骤
ssh-copy-to root@172.19.0.x

vim /etc/ansible/hosts
servername(目标服务器名称) ansible_ssh_host=172.19.0.x ansible_ssh_port=22

cd /var/lib/jenkins/test

#测试是否能通过jenkins用户执行ansible执行连通到目标服务器
sudo -u jenkins ansible -m ping --become-user root -u root --private-key ./ssh4337360459752630127.key servername 

创建项目,可以从XX项目复制(填写项目名称,选择自由项目,最下面填写 从xxx项目复制来),修改以下地方:
----源码管理: 
--------git 地址; 
--------点击【高级】修改Refspec为:+refs/heads/分支名字:refs/remotes/origin/分支名字
--------指定分支(为空时代表any):*/分支名字
----构建:
--------ansible playbook:
------------Host subset: servername(目标服务器名称)
------------点击【高级】添加代码同步参数:Extra Variables
------------增加参数【srcdir】源码所在目录,填写代码空间变量:${WORKSPACE}/
------------增加参数【destdir】这个定义的值为目标发布的网站目录,注意后面要加/结尾:如 /www/wwwroot/xxxxxx/
------------增加参数【opts】文件同步参数,填写:--exclude-from=${PLAY_BOOK_EXCLUDE_FILE}
------------ Additional parameters 填写:--become-user root
----保存

#登录目标服务器,将项目代码备份,注意目录一定要以/结尾
rsync -r --exclude=.git --exclude=assets --exclude=attachments --exclude=protected/runtime --exclude=node_modules /www/wwwroot/xxxxxx/    ~/xxxxxxbak/

#发布测试是否成功,登录进去发布,选择项目:Build with Parameters -> deploy

语法检查别名

alias ansible-playbook-check='ansible-playbook --syntax-check'

查看模块帮助,例如查看file模块的帮助文档

ansible-doc file

查看可用模块:自动进入less模块,可/搜索

ansible-doc -l

你可能会遇到的问题:
使用ansible-playbook的时候,ssh无法链接前台服务器
点击【高级】,为命令增加附加参数,使用--become-user root 即使用root用户执行playbook命令
Additional parameters: --become-user root
另外,添加好ssh无密码访问后,还需要切换到jenkins用户连接一次服务器,因为第一次连接时会让用户输入yes后才能连接上,所以需要操作一次,成功连接后即可使用了
sudo -u jenkins ssh root@192.168.1.10

================= 本文开始 =============

创建自定义项目:
选择 This project is parameterized (这个项目是参数化的),参数如下:

####Choice Parameter
     名称    
Status
     选项    
Deploy
Rollback
     描述    
Deploy:发布
Rollback:回滚


####String Parameter
     名称    
Version
     默认值    
0
     描述    
发布版本序号

同步项目代码前备份:

case $Status  in
#    Deploy)
#        echo "Status:$Status"
#        path="${WORKSPACE}/../${JOB_NAME}_bak/${BUILD_NUMBER}"      #创建每次要备份的目录
#        if [ -d $path ];
#        then
#            echo "The files is already  exists "
#        else
#            mkdir -p  $path
#        fi
#        rsync -r --exclude=".git" ${WORKSPACE}/ $path/        #将构建工作空间文件备份到文件夹
#        echo "Copy code to ${path} Completing!"
#        ;;
    Rollback)
        echo "Status:$Status"
        echo "Version:$Version"

        if [ $Version -lt 1 ];then
            echo "Version val is error"
            exit 1
        fi

        path="${WORKSPACE}/../${JOB_NAME}_bak/$Version"            #备份目录
        if [ ! -d $path  ];then
            echo "Bak dir not exists: $path"
            exit 2
        fi


        #清除工作空间中除了.git文件夹的所有文件
                find ${WORKSPACE}/  ! -regex .*\.git.* -empty -delete

        rsync -r --exclude=".git" ${path}/ ${WORKSPACE}/       #将备份拷贝到构建工作空间
        echo "Copy bak code ${path} to ${WORKSPACE} Completing!"
        ;;
    *)
        exit
        ;;
esac

同步代码过程...
例子使用了ansible-playbook将代码同步到远程WEB服务器:
全局环境变量设置:

全局属性
Environment variables    
     键值对列表    
     键    PLAY_BOOK_EXCLUDE_FILE
     值    /etc/ansible/playbook/deploy.exclude

jenkins安装好ansible插件,配置一下ansible插件的命令路径: 配置好两个命令ansible(本例未使用)和ansible-playbook
构建设置:这里使用了一个自定义的环境变量(jenkins全局管理里面配置的PLAY_BOOK_EXCLUDE_FILE,项目同步时忽略的目录和文件可以写到这个文件里)

    Ansible installation    ansible-playbook    
     Playbook path    /etc/ansible/playbook/deploy.yml
     Inventory     Do not specify Inventory    
     Host subset    dev-web test    
     Number of parallel processes    5
     Extra Variables    
     Key    srcdir
     Value    ${WORKSPACE}/    
         
     Key    destdir
     Value    /www/wwwroot/houtai111/
         
     Key    opts
     Value    --exclude-from=${PLAY_BOOK_EXCLUDE_FILE}

同步代码以后备份本次代码

case $Status  in
    Deploy)
        echo "Status:$Status"
        path="${WORKSPACE}/../${JOB_NAME}_bak/${BUILD_NUMBER}"      #创建每次要备份的目录
        if [ -d $path ];
        then
            echo "The files is already  exists "
        else
            mkdir -p  $path
        fi

        rsync -r --exclude=".git" ${WORKSPACE}/ $path/        #将构建工作空间文件备份到文件夹
        echo "Copy code to ${path} Completing!"
        ;;
#    Rollback)
#        echo "Status:$Status"
#        echo "Version:$Version"
#
#        if [ $Version -lt 1 ];then
#            echo "Version val is error"
#            exit 1
#        fi
#
#        path="${WORKSPACE}/../${JOB_NAME}_bak/$Version"            #备份目录
#        if [ ! -d $path  ];then
#            echo "Bak dir not exists: $path"
#            exit 2
#        fi
#
#        rsync -r --exclude=".git" ${path}/ ${WORKSPACE}/       #将备份拷贝到构建工作空间
#       echo "Copy bak code ${path} to ${WORKSPACE} Completing!"
#        ;;
    *)
        exit
        ;;
esac

最后清理多余的备份,只保留最近的备份数量

ReservedNum=5  #保留文件数
FileDir="${WORKSPACE}/../${JOB_NAME}_bak"
date=$(date "+%Y%m%d-%H%M%S")

cd $FileDir   #进入备份目录
FileNum=$(ls -l | grep '^d' | wc -l)   #当前有几个文件夹,即几个备份

while(( $FileNum > $ReservedNum))
do
    OldFile=$(ls -rt | head -1)         #获取最旧的那个备份文件夹
    echo  $date "Delete File:"$OldFile
    rm -rf $FileDir/$OldFile
    let "FileNum--"
done 

构建项目的时候就会有选择:Deploy 还是 Rollback, 选择Rollback的话,version 填写 发布的序号即可使用相应的备份数据

playbook

- hosts: test,online
  remote_user: root
  tasks:
          - name: deploy code to remote server
            synchronize:
                    src: '{{ srcdir }}'
                    dest: '{{ destdir }}'
                    mode: push
                    dirs: yes
                    owner: no
                    group: no
                    copy_links: no
                    delete: no
                    rsync_opts: '{{opts}}'
          - name: copy files if not existing, and delete extraneous files
            synchronize:
                    src: '{{ srcdir }}/{{ item }}'
                    dest: '{{ destdir }}/{{ item }}'
                    mode: push
                    dirs: yes
                    owner: no
                    group: no
                    copy_links: no
                    delete: yes
                    rsync_opts: '--ignore-existing'
            with_items:
                    - common/coreCss/
                    - common/coreJs/
                    - common/css/
                    - common/js/
                    - pay/alipayMobile/alipay.config.php
                    - pay/alipayPC/alipay.config.php
                    - pay/singleTradeQuery/alipay.config.php
                    - wxpay/lib/WxPay.Config.php
                    
          - name: change files mode
            file:
                path: '{{ destdir }}/{{ item.0 }}'
                mode: '{{ item.1 }}'
            with_list:
                    - ['protected/yiic', '0755']

deploy.exclude

.git
.idea
.user.ini
lextab.py
yacctab.py
assets
attachments
node_modules
protected/runtime
pay/alipayMobile/alipay.config.php
pay/alipayPC/alipay.config.php
pay/singleTradeQuery/alipay.config.php
wxpay/lib/WxPay.Config.php

ansible hosts

[test]
192.168.1.100

[online]
web1 ansible_ssh_host=192.168.1.101 ansible_ssh_port=22
web2 ansible_ssh_host=192.168.1.102 ansible_ssh_port=22

总结:

  1. rebase 可以尽可能保持 master 分支干净整洁,并且易于识别 author
  2. squash 也可以保持 master 分支干净,但是 master 中 author 都是 maintainer,而不是原 owner
  3. merge 不能保持 master 分支干净,但是保持了所有的 commit history,大多数情况下都是不好的,个别情况挺好

squash 使用:squash merge
在使用 git 的过程中,可能你遇到过想要合并多个 commit 为一个,然后很多人会告诉你用 git commit --amend,然后你发现里面有你的多个 commit 历史,你可以通过 pick 选择,squash 合并等等。同样得,merge 的时候也可以这么干,你只需要这么简单的两步:

  • 切换到目标分支:git checkout master
  • 以 squash 的形式 merge:git merge --squash devel

你会发现,在 master 分支上居然有未提交的修改,然后你就需要在 master 上主动提交了修改,注意,这里是你 commit 的,也就是改变了 commit 的 author。

rebase 使用
但是,作为处女座的程序员肯定是不能忍受目前的情况的,因为我们既想合并 commits,又想保留作者的信息,那么有没有什么好办法呢?肯定是有的啦,这个时候我们可以尝试一下 rebase,操作步骤是这样的:

  • 先切换到 devel 分支(不一样咯):git checkout devel
  • 变基:git rebase -i master
  • 切换回目标分支:git checkout master
  • 合并: git merge devel

这里完成了第二步之后我想你应该大概知道发生了什么事了,我们在 devel 里面对照 master 进行了变基,所谓的变基其实就是找到两个分支共同的祖先,然后在当前分支上合并从共同祖先到现在的所有 commit,所以我们在第二步的时候会选择怎么处理这些 commit,然后我们就得到了一个从公共commit 到现在的单个 commit,这个时候别人讲我们这个 commit 合并到 master 也只会在 master 上留下一个 commit 记录,就像这样:

虽然这个 commit history 线看上去很不错,而且也比较符合实际情况,但是我们需要注意到的有点就是分支上的开发者需要自己执行变基操作,从而导致他的原始 commit history 变化了(可以理解成被合并了)。

原文:
https://www.jianshu.com/p/684a8ae9dcf1