害你加班的bug就是我写的,记一次升级Jenkins插件引发的加班

主旨

本文主要记录了下Jenkins升级插件过程中出现的场景,一次加班经历,事发时没有截图,有兴趣可以看看。

起因

需求

最近有个需求:在Jenkins流水线中完成下载Git上的文件简单修改并提交的功能

起初找到了相关的插件用法,即使用 SSH Agent Plugin 来完成这个功能

插件不生效

经测试无法完成效果,分别怀疑了以下几点:

  • 凭据配置有误
  • 写错了脚本
  • 当前未安装此插件
  • 当前插件版本过低
  • 当前插件由于某种原因未生效

排查不生效原因

经排查,发现的确没有生效,原因是之前运维同事做迁移时做的一系列骚操作搞的:

  • 用最新的Jenkins war包部署 + 老版本Jenkins家目录
  • 由于新版本需要使用新版本的插件才能生效,升级了所有插件
  • 升级完重启,启动不起来了……
  • 回退老版本war包,继续使用当前升级过插件的Jenkins家目录
  • 在插件管理处,按提示降级了部分插件

预感

等我看到 Manage Jenkins 那一片红的时候,就有预感这次要不简单,当时也没多想,去检查了下 SSH Agent Plugin 的版本

升级插件

发现提示Warn 需要升级此插件到某版本及以后,插件方能生效,没多想,升级就是了

没想此举为我昨晚的加班,打开了潘多拉魔盒…… 升级完重启,启动不起来了!

Jenkins挂机

启动报错如下:(昨晚没心情截图,直接搜的错误)

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.<init>(Jenkins.java:904)
        at hudson.model.Hudson.<init>(Hudson.java:85)
        at hudson.model.Hudson.<init>(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 的相关问题解决办法

说是因为升级了 Role-based Authorization Strategy 插件会导致这个问题,What?? 我没升级它啊,这怎么回事!先看看外国老哥的解法:

简述解法:

  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包 https://mirrors.ustc.edu.cn/jenkins/war-stable/2.222.3/

部署到Tomcat的ROOT目录下

修改Tomcat conf/server.xml,修改 Tomcat 编码为UTF-8

修改 conf/context.xml,修改静态资源缓存最大值,需添加一行 <Resources cachingAllowed="true" cacheMaxSize="100000" />

启动Tomcat

访问测试Jenkins服务,查看插件错误警告

访问服务后,发现服务还可以登录,进来看到工程都还在!点开 Manage Jenkins 处,发现仍是大面积报红,检查发现是 Pipeline 依赖的组件不正确,按错误提示去 pluginManager updates处找到被依赖的插件,按提示升级,升级完重启(大部分插件需要重启以激活)

重启后,Pipeline相关的错误不在了,再去看其他的,直到所有的都解决了,插件也都正常了

除了之前插件上的报红,还有几处安全提示,我们的Jenkins不连外网,就一并关掉了

最后 Manage Jenkins 就变成了这样

备份,恢复服务

备份原服务家目录,将新版本部署到原 Tomcat,还原新版本家目录,重启服务

在恢复过程中,有提示某些数据 Unreadable,这些可以通过点击提示,管理这些旧数据,我这边因为主要的东西都在,就选了清除不可读数据了

后续工程修复,测试插件

所有失而复得的工程,其实只记录了内部的一些参数,但 SCM 如Git,这些流水线脚本信息都没记录,可能是因为 Git 插件升级所致

苦逼的一个一个加回来,好在工程不多,也就10来个,等所有工程修复好后,我测试了下之前失效的插件,插件可用了 :happy:

结尾

写这段文字主要记录一下这件挺坑的事,警示自己或大家,不要在没备份的情况下,去做一些不可逆的操作,比如升级 Jenkins,备份的作用同样适用于其他场景

posted @ 2020-05-27 12:26  东北小狐狸  阅读(3605)  评论(3编辑  收藏  举报