1.一个真实的代码泄露故事2.Jenkins的基本使用3.gitsubmodule的基本使用4.在Jenkins中使用gitmodule编译所有模块5.概要六、资源下载1、一个真实的故事发生在功能机时代。我们项目组开发一款手机,软件开发成员大概有20人。结果在手机发布一周后,又有一家小厂推出了一款软件界面和功能几乎一样的手机,除了开机界面。因为在那个年代,几乎所有人都使用MTK和高通提供的解决方案,而且都是统一的菜单式功能。你无法拿出有力的证据来证明别人窃取了你的代码。后来内部发现确实是开发者泄露了代码,所以所有电脑的USB接口都被禁用了。这是我亲身经历的真实故事,当时每个人负责一个模块,例如:A负责通话管理和电话本,B负责系统设置,C负责短信和彩信。..编译的时候需要把所有的代码放在一起统一编译,这就意味着所有的软件人员都可以获得所有的源代码,这也造成了代码泄露的隐患。严重的事件,毕竟人为财死,鸟为食亡!那么,有没有代码控制的方法来解决这个权限问题呢?在目前的项目中,强调分层,划分模块。这是从软件工程的角度来考虑的。如果更进一步,将这些模块划分成一个小的子系统,每个开发者只对自己的模块负责,只能有拉取自己代码的权限,无法得到一个项目中的所有模块。码起来。只有项目集成商(管理员)才有全权拉取所有源代码来构建整个系统。这样,他们可以更好地控制代码安全问题。要实现这样的代码控制,可以使用git工具中的submodule。在本文中,我们将详细讲解gitsubmodule的使用。这篇文章是面向工具的,可能比较长。为了提供一站式服务,我会记录相关资源、步骤、遇到的错误信息等细节,以供日后参考。不管怎样,通过本文,你可以学习和了解以下知识点:Jenkins的基本用法;git子模块的基本命令用法;通过三个demo工程,一步步实现代码安全控制;使用Jenkins+gitsubmodule实现自动编译;git子树和子模块的区别;如果你需要文中提到的软件和代码资源,可以在文末找到下载方法。二、Jenkins的基本使用1、Jenkins是什么?Jenkins是一个用Java编写的开源持续集成工具,这意味着它可以帮助我们自动构建各种项目。Jenkins运行在Servlet容器中(如ApacheTomcat),在Ubuntu系统中使用apt-get即可一键安装。Jenkins有以下特点:嵌入在web服务器中,通过浏览器操作,非常方便;它可以执行基于ApacheAnt和ApacheMaven的项目,以及任意Shell脚本和Windows批处理命令;它可以通过各种方式触发Construct。比如提交到版本控制系统时触发,通过类似Cron的机制进行调度。当其他构建完成后,也可以通过特定的URL请求;Jenkins强大的插件让Jenkins可以集成很多软件,这可能有助于我们不断地集成我们的工程项目;为用户提供强大的功能和灵活性来自动化发布、部署等。其他的我就不说了,我觉得很有用,有机会也可以试试。另外,我用来测试的虚拟机是新安装的Ubuntu16.04-64。请按照以下步骤确保它可以顺利运行。关于JDK和Jenkins的安装方法,网上有很多资料。有些流程有问题,或者有些关键步骤没有写清楚。为了方便大家操作成功一次,我还是记录在这里。如果您已经熟悉安装过程,可以直接滑到下一个主题。2、安装JDK8(一)下载解压下载jdk-8u221-linux-x64.tar.gz,(文末提供下载地址),解压到目录/home/sewain/OpenSource,解压命令:sudotar-zxvfjdk-8u221-linux-x64.tar.gz-C/opt(2)设置环境变量执行命令:vim~/.bashrc,在末尾添加如下内容:exportJAVA_HOME=/opt/jdk1.8.0_221exportPATH=$JAVA_HOME/bin:$PATHexportCLASSPATH=./$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jart我建议你也使用这个环境变量。如果以后升级JDK版本,只需要修改JAVA_HOME即可。(3))重新加载环境变量,执行命令:source~/.bashrc,此时环境变量生效。验证:java-version,如果出现如下信息,说明OK:javaversion"1.8.0_221"Java(TM)SERuntimeEnvironment(build1.8.0_221-b11)JavaHotSpot(TM)64-BitServerVM(build25.221-b11,mixedmode)3.安装Jenkins(1)导入Jenkins仓库的GPGkeysudowget-q-O-https://pkg.jenkins.io/debian/jenkins.io.key|sudoapt-keyadd-(2)添加Jenkins仓库到系统sudosh-c'echodebhttp://pkg.jenkins.io/debian-stablebinary/>/etc/apt/sources.list.d/jenkins.list'(3)使用aptinstallsudoaptupdatesudoaptinstalljenkinsJenkins服务后会自动安装过程完成可以通过命令systemctlstatusjenkins来验证。systemctlstatusjenkins(4)配置端口Jenkins是内嵌在tomcat服务器中,默认使用8080端口,容易和其他服务冲突,需要修改。涉及两个文件:文件一:在/etc/init.d/jenkins第一行的PATH变量中,加入自己的JDK地址:PATH=/bin:/usr/bin:/sbin:/usr/sbin:/opt/jdk1.8.0_221/binfile2:/etc/default/jenkins修改HTTP_PORT的值为新的端口号,例如:HTTP_PORT=9090。(5)Jenkins启动和停止指令sudoservicejenkinsstartsudoservicejenkinsstop如果不幸遇到错误,可以反复使用这两条指令来消除错误。4.在浏览器中配置Jenkins在浏览器中输入:htpp://localhost:9090,稍等片刻,出现界面:按照界面提示,从/var/lib/jenkins/secrets/initialAdminPassword中复制安全密码文件(需要root权限),在浏览器窗口填写。此时出现安装插件窗口。一般只需要安装推荐的插件即可:插件安装完成后,进入管理员配置界面:至此,Jenkins的安装已经成功完成!五、在Jenkins中配置一个小项目(1)准备测试代码Test1Jenkins只是一个组件框架,具体的编译过程由用户自行决定。Jenkins首先通过git工具获取远程仓库中的代码,然后执行用户指定的编译指令。因此,我们需要提前准备一份测试代码,放在Jenkins可以访问的远程仓库中。当然,你也可以在你本地的Ubuntu系统中部署一个git仓库。为了方便,我测试的代码Test1放在了gitee中。(2)新建一个项目(3)输入项目名称,选择第一个自由样式(Freeproject)(4)在第一个选项卡General下,输入项目的描述信息(Description),随便写什么想。(5)源码管理在Jenkins的构建(编译)过程中,需要获取源码,因此需要配置git仓库的地址和账号信息(用户名和密码)。首先在Add下拉按钮下,选择Jenkins:EnterUsernameandPassword:账号添加完成后,在Credentials下拉框中,选择刚刚添加的gitee账号,可以看到红色的权限错误提示消失了,表示可以拉取到远程仓??库中的源码。(6)BuildTriggers根据需要选择构建触发器以不同的方式触发,如:定时触发、另一个项目构建成功时触发等。我们这里不选择任何item,手动点击主界面的按钮触发。(7)BuildEnvironment编译环境这部分我用的比较少,使用其他工具来辅助Jenkins的功能。(8)BuildCompilation是告诉Jenkins如何构建系统,也就是说:Jenkins只是一个自动化构建系统。具体编译过程可由用户自行决定。有以下选项:这里我们选择直接执行脚本(ExecuteShell),输入如下命令:(9)Post-buildActions编译后操作告诉Jenkins:编译一个项目后,需要做什么?例如:发送邮件,触发下一个项目自动编译等,可以添加多个action。选项如下:以上步骤配置完成后,点击Save保存。此时在主界面可以看到项目的全貌,如下图所示:在Jenkins后台,该项目的保存路径为:/var/lib/jenkins/jobs/Test1。6.手动触发一次编译由于在上面的第(6)步中我们没有选择任何触发条件,所以我们需要手动点击项目Test1主界面左侧的BuildNow按钮来触发。此时,在左侧的BuildHistory中,可以看到编译历史,点击某个编译记录号,可以看到本次编译的详细信息。在编译详情中,点击左侧ConsoleOutput按钮,可以看到编译的输出信息:编译成功后得到可执行文件。我们在Jenkins后台可以看到源码已经拉取到/var/lib/jenkins/jobs/Test1/workspace目录下:到这里,你已经学会了Jenkins最基本的操作!下面继续说gitsubmodule的使用,这部分是核心内容!三、gitsubmodule的基本使用1、什么是gitsubmodule?gitsubmodule是一个多模块管理的工具。它允许一个项目成为一个存储库,而其他项目作为子模块存在于父项目中。父项目和子项目的提交是分开的,也就是说父项目提交的信息只包含子项目的信息,不包含子项目的代码;子项目有自己独立的提交、推送和拉取操作。gitsubmodule一般用在比较大的项目中。为了便于复用或者代码安全,往往需要分成若干??个子项目进行代码管理。常用指令包括:添加子模块:gitsubmoduleadd更新子模块:gitsubmoduleupdate初始化子模块:gitsubmoduleinit递归克隆整个项目:gitclone--recursive拉取所有子模块:gitsubmoduleforeachgitpull2。使用三个小项目来测试子模块的使用。为了演示,我们创建三个项目,并推送到远程仓库。这里我们使用gitee。Test1:编译得到一个动态库:libtest1.so;Test2:编译得到动态库:libtest2.so;Test3:编译得到一个可执行程序,加载并调用上面两个动态库中的函数。为什么要这样设计模块:安全!开发人员A:负责Test1,不能访问其他模块的代码;开发人员B:负责Test2,不能访问其他模块的代码;项目经理:负责Test3和代码的集成,可以获取所有的代码;项目经理需要将Test1和Test2作为子模块添加到Test3中,执行如下指令:1.gitsubmoduleaddhttps://gitee.com/[youraccount]/test1.gittest12.gitsubmoduleaddhttps://gitee.com/[youraccount]/test2.gittest2将Test1和Test2作为子模块添加到Test3后,查看文件变化:也可以查看.gitmodules文件可以看出git工具管理通过这个配置文件的子模块。管理员需要对所有模块进行集成编译。因此,我们在Test3目录下添加一个脚本build.sh。所有的编译指令都写在这个脚本中。内容如下:内容是最基本的,直接调用make命令,执行即可,输出:至此,我们完成了添加子模块的功能。3.在空目录下编译验证可行性。在另一个空目录下,克隆Test3项目,可以发现克隆出来的test1和test2文件夹是空的,如下图:手动获取所有子模块,执行命令:gitsubmoduleupdate--init--recursive此时,使用tree命令查看文件变化,可以看到test1和test2的文件已经拉下来了。这里有一个问题需要注意:子模块的代码虽然拉下来了,但是它的head并没有指向master分支,需要手动处理,如图:这时候我们执行脚本build.sh再次在test3目录中。您可以成功编译所有子模块。在以上步骤中,我们在本地临时目录中手动测试了子模块的编译过程。下一章我们会将这个过程部署到Jenkins系统中,所以刚才执行的指令需要写在build.sh脚本中。build.sh的内容变为:4.使用Jenkins中的git模块编译所有模块以下操作均在浏览器的Jenkins面板中进行。1、重新配置项目因为我们是在Test3中编译整个项目(Test1和Test2作为子模块包含在内),所以先删除之前添加的Test1项目,如图:然后重新添加项目Test3进行审核步骤:输入描述信息,选择自由风格项目;输入git仓库地址和账户信息,选择master分支;不要设置触发器;不设置编译环境;编译:选择Executeshell执行脚本,输入编译命令:./build.sh。(刚才说了,Jenkins是一个自动化构建框架,具体的编译过程由用户自己决定,所以我们这里的编译过程是执行Test3下的脚本build.sh);编译后,没有设置动作;当然,也可以直接在之前的Test1项目的基础上进行修改。此时,我们直接点击Jenkins中的BuildNow按钮。如果不出意外,会提示编译错误(左边BuildHistory下会出现一个红色的错误圆圈)。点进去,看输出信息(ConsoleOutput按钮),提示错误:原因如前所述,子模块获取后,head没有指向master分支,需要我们手动修改第一次编译的时候(没找到其他的如果知道方法请告诉我!)手动解决:在命令行窗口,进入Test3目录/var/lib/jenkins/jobs/Test3/workspaceJenkins系统,执行如下指令:gitsubmoduleupdate--init--recursivecdtest1/gitcheckoutmastercd-cdtest2/gitcheckoutmastercd-此时,重新触发一次编译,即可成功!5.总结本文属于工具类。部署完成后,每次编译只需在浏览器中点击一个按钮即可,无需ssh登录远程电脑手动操作。如果还想深入,可以研究以下几点:1.Jenkins是如何保存编译历史的?在/var/lib/jenkins/jobs/Test3/builds目录下,可以看到很多以数字命名的文件夹,里面记录了每次的编译信息。2、编译后的动作在我们的编译脚本build.sh文件中,只生成了可执行文件,可以继续扩展功能,比如自动部署。或者在项目配置的【Post-buildActions】中,重写一个专门用于自动部署的脚本文件。3、gitsubtree的作用和gitsubmodule很相似,但本质不同。Subtree直接将子模块代码复制到主模块,命令简单;submodule使用一个“指针”指向子模块,命令相对复杂,功能更强大;4.继续研究Jenkins中的插件功能6.资源下载文中用到的资源,放在网盘中。如有需要,请在留言区发送号码:030公众号,您将收到下载地址。本文转载自微信公众号“IOT物联网小镇”,可通过以下二维码关注。转载本文请联系物联小镇公众号。
