今天有同事編譯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若是以爲本文對您有所幫助,歡迎您掃碼下圖所示的支付寶和微信支付二維碼對本文進行隨意打賞。您的支持將鼓勵我繼續創做!