1. 程式人生 > >害你加班的bug就是我寫的,記一次升級Jenkins外掛引發的加班

害你加班的bug就是我寫的,記一次升級Jenkins外掛引發的加班

## 主旨 本文主要記錄了下Jenkins升級外掛過程中出現的場景,一次加班經歷,事發時沒有截圖,有興趣可以看看。 ## 起因 ### 需求 最近有個需求:在Jenkins流水線中完成下載Git上的檔案簡單修改並提交的功能 起初找到了相關的外掛用法,即使用 `SSH Agent Plugin` 來完成這個功能 ### 外掛不生效 經測試無法完成效果,分別懷疑了以下幾點: - 憑據配置有誤 - 寫錯了指令碼 - 當前未安裝此外掛 - 當前外掛版本過低 - 當前外掛由於某種原因未生效 ### 排查不生效原因 經排查,發現的確沒有生效,原因是之前運維同事做遷移時做的一系列騷操作搞的: - 用最新的Jenkins war包部署 + 老版本Jenkins家目錄 - 由於新版本需要使用新版本的外掛才能生效,升級了所有外掛 - 升級完重啟,啟動不起來了…… - 回退老版本war包,繼續使用當前升級過外掛的Jenkins家目錄 - 在外掛管理處,按提示降級了部分外掛 ### 預感 等我看到 `Manage Jenkins` 那一片紅的時候,就有預感這次要不簡單,當時也沒多想,去檢查了下 `SSH Agent Plugin` 的版本 ### 升級外掛 發現提示Warn 需要升級此外掛到某版本及以後,外掛方能生效,沒多想,升級就是了 沒想此舉為我昨晚的加班,打開了潘多拉魔盒…… **升級完重啟,啟動不起來了!** ### Jenkins掛機 啟動報錯如下:(昨晚沒心情截圖,直接搜的錯誤) ```bash com.thoughtworks.xstream.mapper.CannotResolveClassException: com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategyat com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:79)atcom.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at hudson.util.XStream2$CompatibilityMapper.realClass(XStream2.java:379) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at org.jenkinsci.jruby.JRubyMapper.realClass(JRubyMapper.java:34) at hudson.util.xstream.MapperDelegate.realClass(MapperDelegate.java:43) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:48) at hudson.util.RobustReflectionConverter.determineType(RobustReflectionConverter.java:461) at hudson.util.RobustReflectionConverter.doUnmarshal(RobustReflectionConverter.java:327) Caused: jenkins.util.xstream.CriticalXStreamException: com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy : com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy ---- Debugging information ---- message : com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException cause-message : com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy class : hudson.model.Hudson required-type : hudson.model.Hudson converter-type : hudson.util.RobustReflectionConverter path : /hudson/authorizationStrategy line number : 11 version : not available ------------------------------- at hudson.util.RobustReflectionConverter.doUnmarshal(RobustReflectionConverter.java:356) at hudson.util.RobustReflectionConverter.unmarshal(RobustReflectionConverter.java:270) at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1189) at hudson.util.XStream2.unmarshal(XStream2.java:161) at hudson.util.XStream2.unmarshal(XStream2.java:132) at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1173) at hudson.XmlFile.unmarshal(XmlFile.java:178) Caused: java.io.IOException: Unable to read /var/lib/jenkins/config.xml at hudson.XmlFile.unmarshal(XmlFile.java:181) at hudson.XmlFile.unmarshal(XmlFile.java:161) at jenkins.model.Jenkins.loadConfig(Jenkins.java:3005) at jenkins.model.Jenkins.access$1300(Jenkins.java:304) at jenkins.model.Jenkins$13.run(Jenkins.java:3104) at org.jvnet.hudson.reactor.TaskGraphBuilder$TaskImpl.run(TaskGraphBuilder.java:169) at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:296) at jenkins.model.Jenkins$5.runTask(Jenkins.java:1066) at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:214) at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:117) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused: org.jvnet.hudson.reactor.ReactorException at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:282) at jenkins.InitReactorRunner.run(InitReactorRunner.java:48) at jenkins.model.Jenkins.executeReactor(Jenkins.java:1100) at jenkins.model.Jenkins.(Jenkins.java:904) at hudson.model.Hudson.(Hudson.java:85) at hudson.model.Hudson.(Hudson.java:81) at hudson.WebAppMain$3.run(WebAppMain.java:233) Caused: hudson.util.HudsonFailedToLoad at hudson.WebAppMain$3.run(WebAppMain.java:250) ``` ## 經過 ### 按錯誤資訊排解問題 發現問題不可怕,一頓 Google Bing 發現了 [StackOverFlow 的相關問題解決辦法](https://stackoverflow.com/questions/55898685/after-updating-plugin-role-strategy-plugin-jenkins-is-not-working) 說是因為升級了 `Role-based Authorization Strategy` 外掛會導致這個問題,What?? 我沒升級它啊,這怎麼回事!先看看外國老哥的解法: ![](https://img2020.cnblogs.com/blog/1149398/202005/1149398-20200527110534081-238922932.png) 簡述解法: 1. 備份下 Jenkins 家目錄下的 config.xml 2. 修改原 config.xml,註釋掉 `authorizationStrategy` 塊,修改 `useSecurity` 為 true 3. 重啟服務,訪問成功再關閉服務 4. 恢復 config.xml 備份 替換 config.xml 5. 重啟服務 按這一套操作後,的確服務能起來了 ### 工程蒸發,引發的思考 接下來發現了另一個問題 ———— **所有工程都沒了!!** 先顧不上工程蒸發了的問題,手動建立了個測試流水線工程來測下 `SSH Agent Plugin` 是否生效,發現依舊無效 工程沒了問題其實不大,因為`使用者還在`、`許可權還在`、`構建工程的流水線指令碼在 GitLab 上`,大不了再配置一下就行了 我想了下,就算配置好工程後,`使 SSH Agent Plugin 外掛生效` 還沒完成啊,外掛版本還是亂成了一鍋粥,這不是定時炸彈麼 簡單瞭解了下,Jenkins 的外掛升級後,降級的版本是有一個預設值的,但這個值不一定是當前 Jenkins 版本預設或可用的值,最好的辦法是向上升級 思及此節,決定去升級下 Jenkins 及外掛,另闢了一處`實驗場`開搞 ### 備份Jenkins家目錄 Jenkins 家目錄裡最大的部分是 workspace 這個目錄,就是每個構建工程執行時的家目錄的父級,這個目錄裡的資料無需備份 將 Jenkins 家目錄備走後,手動建立 workspace 目錄,以防新工程無法構建 ### 下載新war包,部署Tomcat 在中科大的靜像站下載了2.222.3的war包
部署到Tomcat的ROOT目錄下 修改Tomcat conf/server.xml,修改 Tomcat 編碼為UTF-8 ![](https://img2020.cnblogs.com/blog/1149398/202005/1149398-20200527114101093-354532564.png) 修改 conf/context.xml,修改靜態資源快取最大值,需新增一行 `` ![](https://img2020.cnblogs.com/blog/1149398/202005/1149398-20200527114324765-1672399616.png) 啟動Tomcat ### 訪問測試Jenkins服務,檢視外掛錯誤警告 訪問服務後,發現服務還可以登入,進來看到工程都還在!點開 `Manage Jenkins` 處,發現仍是大面積報紅,檢查發現是 `Pipeline` 依賴的元件不正確,按錯誤提示去 pluginManager updates處找到被依賴的外掛,按提示升級,升級完重啟(大部分外掛需要重啟以啟用) 重啟後,Pipeline相關的錯誤不在了,再去看其他的,直到所有的都解決了,外掛也都正常了 除了之前外掛上的報紅,還有幾處安全提示,我們的Jenkins不連外網,就一併關掉了 ![](https://img2020.cnblogs.com/blog/1149398/202005/1149398-20200527115810952-1236600245.png) 最後 `Manage Jenkins` 就變成了這樣 ![](https://img2020.cnblogs.com/blog/1149398/202005/1149398-20200527115900799-1143298115.png) ### 備份,恢復服務 備份原服務家目錄,將新版本部署到原 Tomcat,還原新版本家目錄,重啟服務 >
在恢復過程中,有提示某些資料 Unreadable,這些可以通過點選提示,管理這些舊資料,我這邊因為主要的東西都在,就選了清除不可讀資料了 ### 後續工程修復,測試外掛 所有失而復得的工程,其實只記錄了內部的一些引數,但 SCM 如Git,這些流水線指令碼資訊都沒記錄,可能是因為 Git 外掛升級所致 苦逼的一個一個加回來,好在工程不多,也就10來個,等所有工程修復好後,我測試了下之前失效的外掛,外掛可用了 :happy: ## 結尾 寫這段文字主要記錄一下這件挺坑的事,警示自己或大家,**不要在沒備份的情況下,去做一些不可逆的操作**,比如升級 Jenkins,備份的作用同樣適用於其他場景