• Jenkins Job的Migrate之旅


    场景

    使用Jenkins 做为应用的定时任务处理, 在上面建立的800个左右的Job, 这个环境运行了很多年, 当初安装的最新版本是Jenkins 1.642.3, 现在因为OS需要升级等原因, 驻在上面的Jenkins 服务器也需要一并升级,在新的服务器上安装了新的Jenkins版本Jenkins 2.401.3。
    新版的Jenkins,界面更为清爽,Jenkins本身的升级很简单, 安装最新版本及相关插件就可以, 问题是对于旧的Job的迁移。
    这里迁移的场景相对比较简单,只需要迁移Job的配置就可以,对于构建的历史记录可以忽略。
    如果是在页面中进行配置的话, 一笔Job还好,几百笔时间上就是笔不小的开销,而且还要保证不出错,是否有什么快捷的方式呢?
    答案当然是肯定的。

    Job迁移的最简单方式-复制config.xml

    可以通过直接复制config.xml文件实现迁移旧的Job。

    config.xml文件包含了Jenkins Job的配置信息,包括源码配置、触发条件、构建步骤等等。迁移过程如下:

    1. 先停止新旧两个Jenkins实例,避免在迁移过程中进行任何更改。
    2. 导出旧Jenkins的Job配置文件,即config.xml,通常在${JENKINS_HOME}/jobs/[job_name]/目录下。
    3. 将config.xml文件复制到新Jenkins实例的相应位置,通常是${JENKINS_HOME}/jobs/[job_name]/。
    4. 重启新的Jenkins实例。
      需要注意的是,这种方法只能迁移Job的配置,不包括构建历史等数据。如果有需要迁移的插件,还需确保新的Jenkins实例有相应的插件。

    另外,Jenkins也提供了Job导入/导出插件,例如Jenkins Job Import Plugin,可以方便地实现Job迁移。

    快速导出 config.xml

    Jobs 的配置文件config.xml位于 ${JENKINS_HOME}/jobs的子目录中, 目录是Jenkins Job的名字,这些目录中除了Job配置文件之外,还有构建的记录等文件,可能内容比较多, 如果快速的将目录名和config.xml 提取出来呢?
    使用很多语言编写代码都可以实现这个功能, 比如Java , Python, Perl等, 考虑这台机器只有安装Java ,于是将以下代码复制到 ${JENKINS_HOME}/jobs 目录下:

    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.StandardCopyOption;
    
    public class MigrateJenkins {
    
        public static void main(String[] args) {
            File jobsDirectory = new File("jobs"); // 指定要遍历的jobs目录
            File targetDirectory = new File("jobsMigrate"); // 指定目标目录
    
            // 确保目标目录存在
            if (!targetDirectory.exists()) {
                targetDirectory.mkdirs();
            }
    
            // 获取所有一级子目录
            File[] subDirectories = jobsDirectory.listFiles(File::isDirectory);
    
            if (subDirectories == null || subDirectories.length == 0) {
                System.out.println("jobs目录中没有子目录");
                return;
            }
    
            for (File subDirectory : subDirectories) {
                File configFile = new File(subDirectory, "config.xml");
    
                if (configFile.exists() && configFile.isFile()) {
                    try {
                        // 复制子目录及其config.xml文件到目标目录
                        Files.copy(subDirectory.toPath(), new File(targetDirectory, subDirectory.getName()).toPath(),
                                StandardCopyOption.COPY_ATTRIBUTES);
    
                        Files.copy(configFile.toPath(),
                                new File(targetDirectory, subDirectory.getName() + "/config.xml").toPath(),
                                StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.out.println("子目录" + subDirectory.getName() + "中不存在config.xml文件");
                }
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    正常状况下执行以下两个命令行就可以完成代码的执行:

    javac MigrateJenkins.java
    java MigrateJenkins
    
    • 1
    • 2

    但是在这里的实际环境中使用javac编译类文件的时候, 出现了 error: unmappable character for encoding Cp1252 错误。

    ### error: unmappable character for encoding Cp1252 问题解决

    unmappable character for encoding Cp1252通常发生在Java源文件包含不支持的字符,并且正在尝试使用Cp1252编码进行编译。Cp1252编码不能映射所有Unicode字符,因此对于某些字符来说可能不适用。

    解决这个问题有两种方法:
    一种方式是将javac编译器的源代码文件编码设置为UTF-8,这个编码比Cp1252支持更多的字符。要实现这个,你需要在编译时添加"-encoding UTF-8"选项。比如:

    javac -encoding UTF-8 MigrateJenkins.java
    另一种方法是检查和编辑你的源代码文件,删除那些不被Cp1252编码支持的字符。

    也需要确保你的IDE(如Eclipse, IntelliJ等)的字符编码设置和Javac编译器的一致,以避免类似的错误。如果你在使用IDE,你可以在设置中查找encoding或character encoding,然后修改它为UTF-8。

    重新执行编译命令,错误信息是不一样了, 但是还是会报 javac error: illegal character: '\ufeff' 的错误。

    javac error: illegal character: '\ufeff' 错误解决

    这个错误涉及一个特殊的Unicode字符–‘\ufeff’,也被称为"字节顺序标记"(Byte Order Mark,简称BOM)。这经常发生在你的文件是在特定编辑器中保存为UTF-8带BOM的编码,并且当文件被读取时,读取器(在这里是javac)并不能正确处理BOM。

    虽然UTF-8编码本质上不需要BOM,一些编辑器(如Windows记事本)仍会在文本开头添加一个BOM。这就可能导致像javac这样的工具出现问题,因为它们并不期望看到BOM。

    解决方法有以下两种:

    • 使用能够删除BOM的文本编辑器。有的编辑器选项中可以直接设置保存为UTF-8无BOM编码。例如在PSPPSPad,Sublime Text,Notepadd++这样的编辑器中,都有"UTF-8无BOM"的保存选项。只需将文件以此方式保存,然后再次编译即可。

    • 使用命令行工具删除BOM。例如在Linux中,你可以使用sed工具:

    sed '1s/^\xEF\xBB\xBF//' originalFile > newFile
    以上的命令会将原文件复制到新文件,同时移除开头的BOM。然后你可以使用新文件进行编译。

    无论选择哪种方式,关键要点就是确保你的Java文件是以UTF-8无BOM格式进行保存的。

    到这里问题解决,几百个Jenkins Job的Migrate的时间也就10分钟。

    关于Jenkins Job Import Plugin

    Jenkins Job Import Plugin是Jenkins的一个插件,它允许用户从其它Jenkins实例或XML文件中导入作业配置。这个插件可以简化新的Jenkins实例的配置,使用户能够轻松地重复使用经过测试的作业配置,并快速构建Jenkins实例。它还可以帮助用户在不同的Jenkins实例之间共享和复制作业配置,提高团队的协作效率

    安装方式直接搜索Job Import 进行安装

    在这里插入图片描述



  • 相关阅读:
    Talk预告 | 新加坡Sea AI Lab庞天宇:(合理定义的)鲁棒性与准确率之间不存在矛盾
    日志采集/分析
    乾坤js隔离
    大数据高级开发工程师——Spark学习笔记(1)
    Linux家目录变成了-bash-4.2$
    Unity UGUI 绘制优雅的线段
    机器学习算法基础--聚类问题的评价指标
    https证书的常用版本有哪些
    深圳NPDP认证|如何做好一个B端产品经理?
    vue - Vue脚手架
  • 原文地址:https://blog.csdn.net/oscar999/article/details/133281732