文章目录
1.git
1.1 常用指令
git branch查看本地分支, -r查看远程分支, -a查看本地和远程,-v查看各分支最后一次提交, -D删除分支
git fetch origin arch(远程):arch(本地)
git lfs clone #Large File Storage,在Git仓库中用一个1KB不到的文本指针来代替文件的存在,通过把大文件存储在Git仓库外,可减小Git仓库本身的体积,使克隆Git仓库的速度加快且不会损失性能
git add -A # 全部,这样新增的文件也能stash save
git commit -m '提交信息' --no-verify # 可以跳过代码检查
git commit --amend -m '提交信息' --no-verify # 对上一次的提交进行修改
git log --oneline --graph # 查看commit第一行
git status # 查看工作区变更是红色(缓存区是绿色),新版本
git push origin dev(本地) :dev(远程) -f # 覆盖commit
git reset --hard commithash # 慎用,一般不带hard
git remote add/remove # 添加/删除一个远端仓库,origin名字可代替后面github仓库(这github仓库是https版本,换成ssh版本并配置key免密登录)
git remote -v:显示所有远程仓库
git stash save a # 先git add -A再执行这一步后再git pull origin ,因为有冲突也能pull成功
git stash list # 可到新分支pop此分支改动
git stash pop stash@{0} #有冲突也pop出来了,解决冲突(updated是远程)后保存并git add这文件即标记已解决,可用git reset HEAD 文件将绿变红,最后git stash drop stash@{0}
git checkout a.html # 还原a.html文件改动, 红色变没
git checkout -b dev # 创建并切换到dev分支,不加-b只是切换
git pull = git fetch + git merge # 一般不单独用merge
git push <远程主机名> <本地分支名>:<远程分支名> # git push origin dev:dev 和 git push origin dev 等效,因为本地分支和远程分支同名可以省略冒号部分
git diff > a.patch
git apply --reject a.patch # 尝试应用补丁(允许部分失败)
ls *.rej,rm *.rej # 手动解决冲突后,删除 .rej 文件
git add, git commit -m "" , git format-patch -n1
git cherry-pick 另一分支commitid, 出现冲突,git status查看解决后git add冲突文件后git cherry-pick --continue (先git pull -p 拉取分支和tag,git remote update -p)
# 在Windows下,标准的行结尾格式是CRLF(回车符和换行符),它由一个回车符(CR)和一个换行符(LF)组成,即\r\n。
# 在Unix和类Unix系统(如Linux和macOS)中,标准的行结尾格式只使用换行符(LF),即\n。
# git 提交出现dos格式的解决方法,关闭 git 的自动换行符转换。
git config --global core.autocrlf false
内部:
git tag -a NS730-v0.01.00 -m "NS730-v0.01.00-release" # 创建tag
git push origin NS730-v0.01.00 # 同commitid自动会有tag标志
外部:commitid关联内部
git add meta-alibaba/meta-obmc-h # git commit/push/网页merge:[tag]模板, 合并后重复上面内部中2行
验证:
git clone -b 外部
./sync_yocto.sh 或 cp -r其他项目yocto文件夹
git submodule init
git submodule update
进入内部,git fetch origin q:q ; git checkout q ; 一定要git status检查内外部,不然dirty
source openbmc-init-build-env meta-alibaba/meta-obmc-h , bitbake
openbmc$ git remote -v
origin https://github.com/AspeedTech-BMC/openbmc.git (fetch)
origin https://github.com/AspeedTech-BMC/openbmc.git (push)
openbmc$ git remote rename origin old-origin
openbmc$ git remote add origin https://172.16.11.16/ta/aspeed_2700evb.git
openbmc$ git config --global user.name "ta"
git config --global user.email "ta@m.com"
openbmc$ cat .gitignore
build*/*
customrc
*.sw?
.repo/
.vscode/
openbmc$ git branch
* v09.06
openbmc$ git push origin v09.06:main -f
error: src refspec v09.06 matches more than one
error: failed to push some refs to 'https://172.16.11.16/ta/aspeed_2700evb.git'
openbmc$ git show-ref | grep v09.06
cf5f451d8ffcb8eefc288ba305707f953874baf9 refs/heads/v09.06
1ae1969ea30a13640f8f4a337500da1841419325 refs/tags/v09.06
openbmc$ git -c http.sslVerify=false push origin refs/tags/v09.06:master -f
openbmc$ git -c http.sslVerify=false push --set-upstream origin --all
出现:server certificate verification failed. CAfile: none CRLfile: none ,则 git config --global http.sslVerify false 改变.gitconfig的[http]字段
1.2 commit规范
# .commit_template.txt隐藏文件:git commit进入vi界面(进入前要git config core.editor vim设一下vi模式)
[Project/Common][Feature/Bug/Enhancement/Porting/Debug/Style/Build/Docs/Refactor/Revert]: Brief oneline Summary(Less than 50 characters)
# .commit-msg-hooks.sh隐藏文件:
#!/bin/sh
str=$(cat $1) # $1就是git commit进入里的信息即ommit_template.txt内容
python .git/hooks/commit-msg-check.py "$str"
# .commit-msg-check.py隐藏文件:
#!/usr/bin/python
import sys
support_plat = ["Common", "SR", "Lin"]
support_type = ["Feature", "Bug", "Enhancement", "Porting",
"Debug", "Style", "Build", "Docs", "Refactor", "Revert"]
format_dict = {"Description": False, "Root Cause": False,
"Solution": False, "JIRA": False, "Test": False}
line = sys.argv[1]
if line.startswith("Merge branch"):
exit(0)
commit = line.splitlines()
if len(commit[0]) == 0:
print("Reject!!!! \nFirst line of commit message must not empty! !")
exit(1)
platform = commit[0].lstrip()[1:-1].split("]")[0]
types = commit[0].lstrip()[1:-1].split("]")[1].lstrip()[1:]
if types not in support_type:
print("Reject!!!! \nPlease select type in {} !".format(support_type))
exit(1)
if platform not in support_plat:
print("Reject!!!! \nPlease select platform in {} !".format(support_plat))
exit(1)
for index in range(1, len(commit)):
commit_line = commit[index]
if commit_line.startswith("[Description"):
format_dict["Description"] = True
if commit_line.startswith("[Root"):
format_dict["Root Cause"] = True
if commit_line.startswith("[Solution"):
format_dict["Solution"] = True
if commit_line.startswith("[JIRA"):
format_dict["JIRA"] = True
if commit_line.startswith("[Test"):
format_dict["Test"] = True
for key, value in format_dict.items():
if not value:
print("Reject!!!! \nLost \"{}\" field in commit!".format(key))
exit(1)
exit(0)
# openbmc-init-build-env文件(fb)或setup文件(ocp):拷贝安装上面文件
title_num=$(sed -n '/\[commit\]/p' .git/config | wc | awk -F' ' '{print $1}')
file_num=$(sed -n '/template = \.git\/commit_template.txt/p' .git/config | wc | awk -F' ' '{print $1}')
if ! ([ "$title_num" -gt 0 ] && [ "$file_num" -gt 0 ]) ; then
echo "[commit]" >> .git/config
echo " template = .git/commit_template.txt" >> .git/config
fi
if [ -f ".commit_template.txt" ];then
cp .commit_template.txt .git/commit_template.txt
fi
if [ -f ".commit-msg-hooks.sh" ];then
chmod 777 .commit-msg-hooks.sh
cp .commit-msg-hooks.sh .git/hooks/commit-msg ###### git commit回车触发
fi
if [ -f ".commit-msg-check.py" ];then
chmod 777 .commit-msg-check.py
cp .commit-msg-check.py .git/hooks/commit-msg-check.py
fi
#如下在项目目录:
#source openbmc-init-build-env meta-hua/meta-whitebox
#cat .git/config
#[commit]
# template = .git/commit_template.txt
ssh可免密码(git@),但要配置公钥到github上。https免密:git config --global credential.helper store (除第一次,后面缓存,git config --global --list查看)
如下一行(linux中没有.exe)是在.ssh文件夹中(原来只有known_hosts文件)生成两个id文件。
如下配置输入ssh localhost就不要登录密码,-t
参数指定要生成的密钥类型,-P
密码"表示没有,-f
是密钥的生成后的保存文件位置。
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 生成如下两个文件
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 0600 ~/.ssh/authorized_keys
2.docker
2.1 pull/image,run/ps(进程),exec/commit
docker和vmware虚拟机一样由三部分构成:镜像(image)
是像ubuntu镜像文件(iso,img文件),容器(ps)
是一个正在运行的虚拟机,仓库
是存放镜像文件场所(dockerhub)。tar文件
类似于vm使用时的vmdk文件,可将一个镜像直接保存成一个tar文件,别人load重新加载成一个镜像,run起来成了一个虚拟机。Dockfile
是一个很短的配置文件,通过写"如何构建"的步骤来指定一个镜像如何构建的,通过docker build指令可将Dockfile构建成一个镜像。仓库保存了一些公有镜像如ubuntu/nginx/mysql/tomcat镜像等。
ubuntu安装命令:sudo apt install docker.io,网站:play with docker。docker run -d -p 81:80 nginx
指定外部81端口同理点击81跳转到nginx网页首页(nginx的默认端口是80)。
如下再次点击外部80端口。
如下暂时用不到81,容器里内容修改后要commit成新镜像m1
,和pull下来的nginx镜像
并列。
当前目录自己新增index.html(里面写着wai bu de wen jian)和Dockerfile两文件,将原来nginx里面index.html替换了,如下vi Dockerfile。
点击外部100号端口如下:上面为dockerfile build成一镜像run成为一容器。
2.2 save/load
docker rm m2将m2镜像直接删除,提示有个容器基于这镜像无法删除,那将容器(container id)也删了。docker save + 镜像id,不是容器id。
删了容器还要删除镜像m2,docker load使m2镜像又从tar文件重新拿过来了。文件映射-v
就是将一些静态文件放外面,在外面(pwd)修改文件(因为是映射的)里面文件也会跟着变化。
2.3 Dockerfile
FROM
:指定当前镜像基于哪个镜像,必填,一行就可以构建一个镜像。镜像像程序,容器像进程。
WORKDIR
:指定接下来shell语句运行在哪个路径下,如下alpine镜像下肯定没有/app这个目录,自动创建。
COPY
:将当前宿主机文件
拷贝到镜像中去。
RUN
:构建容器时运行这脚本,当前工作目录就是/app,所以如下321写入/app/1.txt
CMD
:指定整个容器启动起来运行脚本,运行完后整个容器生命周期结束(tail -f 阻塞式)。
如下必须命名为Dockerfile,1.txt里面原本内容有123。
如下指定输出镜像名test,最后的点表示dockfile文件位于当前目录下。
进入docker默认是root用户,增加自己的同名目录并切换再编译。
编译实例
如果出现source not found,如上vim后面加入bash,并添加如下,加入默认/bin/sh指向bash。
sudo docker build -t amdturin
sudo docker run -it -u 1003:1003 -v /home_a/si:/home/si amdturin (docker images查看,因为是latest不用指定版本号) /bin/bash
在docker内ls -l,如下1003就是用户名和group名。
如下在容器中切换到了username用户,第3/4行分别是gitlab/github。. setup sp7。
x.bbappend找不到bb,find后没有,注释为x.bbappend.bk。
3.jenkins
3.1 jenkins-docker配置
jenkins镜像和nginx一样,code push到git上,git通过hook触发构建/测试/部署就是CI(持续集成)CD(持续交付)工具即jenkins(需提供一台运行jenkins的机器)。官网https://www.jenkins.io/下载jenkins,可选择适合你自己系统的版本,也可选择不依赖于系统的docker(前提本机安装了docker)或war包(本机安装了java),如下开启服务端
。
执行如上命令出现密码,复制这串密码,浏览器打开http://localhost:8080(客户端
),粘贴到管理员密码里。点击安装推荐插件,创建管理员用户y,密码123,到这里jenkins已经安装完成了(装在win上),主要用来配合git服务器。
在指定服务器上安装docker,使用docker命令进行下载jenkins-docker版本如下:
docker pull jenkins/jenkins:2.54 (docker images查看, 不指定版本就是最新的版本)
-name
指定image名字。-p
内部container和外部对应关系。-v
外部地址和container内部地址对应关系,在container内部修改jenkins的话,外部也会更新。/etc/localtime
时间同步。
docker run --privileged=true -d --name jenkins -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock -v /home/y/jenkins_home:/var/jenkins_home/ -v /etc/localtime:/etc/localtime jenkins/jenkins:2.54 (或v4)
docker exec -u 0 -it jenkins bash # 进入docker container内部,需安装cppcheck等命令
docker save –o jenkins_v4.tar jenkins/jenkins:v4 # 保存docker images为tar包命令
docker load -input jenkins_v4.tar # 加载tar包为docker images命令
3.2 jenkins与gitlab配置
gitlab与jenkins的access token配置
GitLab配置Access Token,用于jenkins连接GitLab获取GitLab API接口:点击右上角用户头像Edit profile,再点击左侧Access Tokens ,命名为gitlab_jenkins,Select scopes全部勾选上,点击创建产生如下字符串。
如下Manage Jenkins需要admin admin用户。如下Add是一个按钮。
新建jenkins job和配置job
jenkins的Dashboard仪表盘界面点击New Item(要登陆),可新建job或者复制已有job,直接复制已有job,拷贝后的job不要运行build,避免回填错误数据到GitLab。
http://10.75.13.34:8084/job/example/,点击Advanced。
如下gitlab查看成员,只有Maintainer才有Settings。
jenkins pipeline script配置
// 环境模块导入, 清空工作空间,groovy语言
import hudson.*
node(""){
stage("clear workspace"){
cleanWs()
}
}
// 下载源码
node(""){
stage("download code"){
echo "download code"
if (env.gitlabSourceBranch == null){ //当gitlab过来触发的job的话,环境变量上就会有gitlabSourceBranch字串
git branch: "sw61", credentialsId: '18f53bc3-dc50-4178-acde-d628264ee453', url: 'https://gitlab-dbd...com/bsp_diag/prj_bsp.git' // null说明不是gitlab触发
}else{ //gitlab做了push或merge操作时触发,credentialsId就是Access Tokens
git branch: env.gitlabSourceBranch, credentialsId: '18f53bc3-dc50-4178-acde-d628264ee453', url: env.gitlabSourceRepoHttpUrl
}
}
}
// 源码cppcheck扫描
try{
node(""){
stage("cppcheck"){
echo "cppcheck starting"
pwd()
sh "/home/cppcheck-1.75/cppcheck 4 --enable=all --inconclusive --xml --xml-version=2 "+env.WORKSPACE+" 2> cppcheck.xml"
publishCppcheck ignoreBlankFiles: true, pattern: 'cppcheck.xml'
def cppcheck_file_obj = new File(env.WORKSPACE+"/cppcheck.xml")
if (cppcheck_file_obj.isFile()){
echo "cppcheck.xml file exist"
result = sh returnStdout: true ,script: "cat "+env.WORKSPACE+"/cppcheck.xml"
if (result == ""){
echo "analyse cppcheck.xml failure,cppcheck.xml is empty"
currentBuild.result="FAILURE"
}else{
echo "analyse cppcheck.xml"
cppcheck_result = sh returnStdout: true ,script: "cat "+env.WORKSPACE+"/cppcheck.xml | grep 'cppcheck version'"
if(cppcheck_result == ""){
echo "analyse cppcheck.xml failure,cppcheck.xml format error"
currentBuild.result="FAILURE"
}else{
final_result = sh returnStdout: true ,script: '''cat '''+env.WORKSPACE+'''/cppcheck.xml | grep severity=\\"error\\"'''
if(final_result == ""){
echo "analyse cppcheck.xml pass"
}else{
echo "analyse cppcheck.xml failure,cppcheck.xml has error"
currentBuild.result="FAILURE"
}
}
}
}else{
echo "cppcheck.xml file not exist"
currentBuild.result="FAILURE"
}
}
}
}catch(e) {
echo "cppcheck failure"
currentBuild.result="FAILURE"
}
// 源码编译
try{
node(""){
stage("compile code"){
echo "compile code"
sh "make" //在docker里编译
}
}
}catch(e) {
echo "compile code failure"
currentBuild.result="FAILURE"
}
// 验证扫描与编译结果,成功后归档相关文件
node(""){
stage("archive"){
echo "archive"
if(currentBuild.result == 'FAILURE') {
echo "Something unexpected happened. Please inspect Jenkins logs. Skip archive."
}else{
sh '''
mkdir build
cp cppcheck.xml build/
cp *.ko build/
tar -zcf archive.tar.gz build/
'''
archiveArtifacts artifacts: '*.tar.gz', followSymlinks: false
}
}
}
// 根据扫描和编译结果,回填数据到GitLab
stage("commit gitlab"){
echo "commit gitlab"
if(currentBuild.result == 'FAILURE') {
updateGitlabCommitStatus(name: 'sw61_bsp_build', state: 'failed')
}else{
updateGitlabCommitStatus(name: 'sw61_bsp_build', state: 'success')
}
}
jenkins&gitLab集成环境验证
GitLab推送修改至仓库新分支,验证push event可触发jenkins job,jenkins回填数据至GitLab。
gitlab触发docker_jekins(部署在34服务器上),34 ssh到33编译服务器进行编译回传img到34,34将img传到测试的机器上(测试机器上有测试用例代码文件),34拷完img后触发40测试平台服务器(40是大docker前后端,小docker测试环境 【 ssh/串口/PDU到测试机器上 ,python3 测试用例 】 ,34传来的是选择哪一个小docker ),40将执行pass显示结果传给34,34传给gitlab。
4.gerrit
用github账户登录https://gerrit.openbmc.org,gerrit页面Setting - Contact Information,Profile下填Full Name,Email Address填New Email Addr,SEND VERIFICATION确认。Setting - New SSH Keys参考上面gitlab免密。
BROWSE按钮选择Repositories选择项目如openbmc/bmcweb,ANONYMOUS HTTP进行git clone。gerrit进行commit时必须生成一个Change-Id,否则push到gerrit服务器时会收到错误提醒,对于仓库没有.git/hooks/commit-msg文件时,需要如下下载:
git add,git commit -s ( -s让commit信息里自动生成 signed-off-by,commit-msg自动生成Change-Id) -m " aaa" 。不能把代码提交到远程master或其他分支(这样就越过gerrit了),gerrit必须依赖refs/for/*的分支如git push origin HEAD:refs/for/master,CHANGES -> Open 查看提交是否成功,点击Reviewers, 添加审核人员 (可以添加多个),如果该项目自己也有权限,可自己打分,同时Code-Review必须是2分才能进行merge(分数不可以累加)。
当review人员收到review请求后,进入项目点击REPLY,进行Code-Review打分,Submit提交打分,代码查看:BROWSE - Repositories - 项目名 - BROWSE - 分支。