今天有同事编译Jenkins的相关Jobs的时候,出现了编译成功,可是输出产物失败的状况,以下图所示:
java
Caused by:java.io.IOException: No space left on device at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:345) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1793) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769) at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744) at hudson.util.IOUtils.copy(IOTuils.java:40) at hudson.FilePath.readFromTar(FilePath.java:2318) ....13 more Cause by:java.util.concurrent.ExecutionException:java.io.IOException:This archives contains unclosed entries. ...12 more Cause by:java.io.IOException:This archives contains unclosed entries. ...
看上面图的描述就是Jenkins服务器上的磁盘空间已经不足,致使输出产物失败的状况出现。python
好吧,我登陆Jenkins的服务器,去查看下磁盘空间,发现Jenkins存储的磁盘 /data 已经百分百使用完毕。
apache
oot@codesrv1:/data/.jenkins/jobs# pwd /data/.jenkins/jobs root@codesrv1:/data/.jenkins/jobs# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda3 48750348 44294000 2014928 96% / udev 3886836 4 3886832 1% /dev tmpfs 1558256 260 1557996 1% /run none 5120 0 5120 0% /run/lock none 3895636 0 3895636 0% /run/shm /dev/sda1 9738232 255456 8994536 3% /boot /dev/sda5 236267580 236267580 0 100% /data /dev/sdb1 314197776 5271856 293197332 2% /data1
查看了下 /data/.jenkins/jobs 目录下 全部的Jenkins jobs的占用状况api
root@codesrv1:/data/.jenkins/jobs# du -ah --max-depth=1
使用如上命令,查看全部的Jenkins jobs的磁盘占用状况。ruby
查看了大部分的Jenkins Jobs,发现IOS开发人员所拥有的IOS相关的Jenkins任务,随随便便都占用1G以上的磁盘。服务器
进入一个IOS的Jenkins任务,名为 iOS_Trunk 的Jenkins任务去查看磁盘占用状况微信
root@codesrv1:/data/.jenkins/jobs/iOS_Trunk/builds# pwd /data/.jenkins/jobs/iOS_Trunk/builds root@codesrv1:/data/.jenkins/jobs/iOS_Trunk/builds# du -ah --max-depth=1 46M ./802 1.5M ./826 0 ./lastFailedBuild 176M ./825 166M ./827 137M ./810 0 ./lastUnstableBuild 137M ./797 137M ./819 176M ./824 137M ./800 36K ./822 126M ./804 137M ./794 137M ./803 137M ./795 137M ./814 166M ./828 137M ./785 137M ./806 137M ./805 126M ./793 0 ./legacyIds 126M ./798 137M ./799 126M ./821 137M ./783 137M ./784 126M ./801 137M ./809 44K ./817 16K ./787 137M ./796 137M ./786 40K ./789 126M ./813 126M ./815 126M ./780 126M ./790 137M ./807 0 ./lastUnsuccessfulBuild 0 ./lastSuccessfulBuild 137M ./811 137M ./788 24M ./792 176M ./823 137M ./820 137M ./791 0 ./lastStableBuild 137M ./781 126M ./808 16K ./816 127M ./818 178M ./829 137M ./812 20K ./782 5.7G . root@codesrv1:/data/.jenkins/jobs/iOS_Trunk/builds#
发现这个iOS_Trunk的Jenkins任务,每一次编译的常务都有100多Mb,而后保留了大概50次的编译产物,因此关这一个Jenkins任务就占用了5.7G。可怕啊!markdown
去查看下 这个Jenkins的配置状况,以下图所示:架构
如上图所示,IOS的每一个任务都是 保持构建的最大个数 设置为了50,那就表明着每个IOS的任务理论上最多都占用5个多G的磁盘空间。测试
而其余的Android的Jenkins任务的配置以下图所示:
Android相关的Jenkins任务都是默认最多保留3天的构建产物,这样就能够节省磁盘。
把之前构建过的过期历史数据自动清除掉,保留最近更新的天数和个数。
修改策略为
- 保持构建的天数 3
- 保持构建的最大个数 20
固然这个策略能够根据本身的项目实际状况来定。
正常的删除Jenkins Job的流程是 先清理工做空间 而后再删除掉Jenkins Job
可是有不少同事之前直接就删除Jenkins Job,并无先清理工做空间,这样会致使有些被删除的Jenkins Job原来的工做空间一直存在占用的磁盘。
搜索了下,https://my.oschina.net/donhui/blog/677935 这篇文章中的Python脚本应该是能够解决这个问题的。
如下代码为转载内容,原文连接为 https://my.oschina.net/donhui/blog/677935
摘要: jenkins cleanup workspace after job removal
若是Jenkins使用的Master-Slave多节点架构,删除Jenkins JOB后,相应JOB的slave节点的workspace不会被删除
stackoverflow上有相关的问答:http://stackoverflow.com/questions/20532705/deleting-jenkins-jobs-through-gui-does-not-delete-their-workspaces-in-slaves
google groups上有相关的讨论:https://groups.google.com/forum/#!topic/jenkinsci-users/SiZ3DL-UJ-8
因此须要自行处理,因而用脚本实现该功能
具体思路是:
遍历jenkins节点的workspace,根据路径解析得到jenkins job name
若是该job不存在(经过python jenkinsapi实现),则删除相应的workspace
暂不考虑自定义的workspace
须要在jenkins每一个节点上进行处理(能够在jenkins上建立job,将job绑定到相应slave上;也能够在相应slave上直接运行脚本)
相关的Python脚本以下:
# -*- coding: utf-8 -*- import os import shutil import logging from jenkinsapi.jenkins import Jenkins logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__file__) def get_jenkins_instance(): jenkins_url = "http://jenkins.example.com" jenkins_username = "username" jenkins_password = "password" return Jenkins(jenkins_url, username=jenkins_username, password=jenkins_password) def clean_workspace(): jenkins_instance = get_jenkins_instance() jenkins_workspace_path = "/opt/JENKINS_HOME/workspace/" for dirpath, dirnames, filenames in os.walk(jenkins_workspace_path): if dirpath == jenkins_workspace_path: for dirname in dirnames: jenkins_job_name = dirname # 若是job被删除,则清理相应的workspace if not jenkins_instance.has_job(jenkins_job_name): logger.info("removing workspace dir of job:%s" % dirname) shutil.rmtree(os.path.join(dirpath, dirname)) if __name__ == "__main__": clean_workspace()
这个脚本暂时没有去运行,由于将IOS全部的Jenkins任务的丢弃旧的构建的策略修改以后,目前磁盘空间彻底足够使用!目前通过一轮清理,已经有84G的剩余能够可使用。
并且该脚本目前暂时不敢去使用,待我在测试的Jenkins服务器上测试以后再应用到正式的Jenkins服务器。
若是要使用,请读者将代码中的相关参数改成本身的Jenkins服务器配置的参数再运行。jenkins_url 、jenkins_username、jenkins_password 、jenkins_workspace_path这几个参数都得修改成真实的参数。
做者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/79225993若是以为本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行随意打赏。您的支持将鼓励我继续创做!