Jenkins:批次自動將 Maven 型別 Job 遷移到自由風格型別
為什麼要遷移?
近期進行 Jenkins 從1.X到2.X的升級演練
Jenkins2 最新版本只能在 JDK8 或 JDK11 版本下執行,我所使用的 JDK 版本為 JDK8
在構建 Maven Job,Job 配置的 JDK 版本為 JDK7時,構建報錯
$ /usr/local/java/bin/java -cp /data/jenkins/maven31-agent.jar:/usr/local/maven/boot/plexus-classworlds-2.5.2.jar:/usr/local/maven/conf/logging jenkins.maven3.agent.Maven31Main /usr/local/maven /data/jenkins/slave.jar /data/jenkins/maven31-interceptor.jar /data/jenkins/maven3-interceptor-commons.jar 45631Exception in thread "main" java.lang.UnsupportedClassVersionError: hudson/remoting/Launcher : Unsupported major.minor version 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClassFromSelf(ClassRealm.java:401) at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:42) at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247) at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239) at jenkins.maven3.agent.Maven31Main.main(Maven31Main.java:138) at jenkins.maven3.agent.Maven31Main.main(Maven31Main.java:67)
經定位,原來 Maven 型別 Job 與 JDK 版本有一定相容性,部分說明如下:
Maven jobs and Java versions compatibility : Because java serialized classes are exchanged between Jenkins master and Maven Jobs it is required that the JVM used to launch Maven is superior or equal to the version of Java for which Jenkins Master is built for.
Jenkins >= 1.520 requires Java 6 thus Maven jobs must be launched with Java >= 6.
Jenkins >= 1.612 requires Java 7 thus Maven jobs must be launched with Java >= 7.
Jenkins >= 2.54 requires Java 8 thus Maven jobs must be launched with Java >= 8.
詳見:
而我們的這些 Job 必須使用指定 JDK 版本構建,不能隨意修改 JDK 版本
而自由風格型別的 Job,不會出現這個問題
所以,計劃將 Maven 型別 Job 遷移到自由風格型別
如何遷移?
那麼如何遷移呢?
統計了下 Maven 型別的 Job,有數百個,手動遷移不現實的
透過 google 發現有前人寫的 grovvy 指令碼:
嘗試執行該指令碼,可能與環境有關,它會報錯
由於對 groovy 不太熟悉,解決起來比較麻煩
所以參考它的邏輯,使用 python 指令碼實現了遷移的功能
python 指令碼如下所示,有需要的可以自行修改:
# -*- coding:utf-8 -*-import xml.etree.ElementTree as ETimport sysfrom jenkinsapi.jenkins import Jenkins reload(sys) sys.setdefaultencoding('utf8')def get_jenkins_server(): JENKINS_URL = " JENKINS_USERNAME = "jenkins" JENKINS_PASSWORD = "jenkins" return Jenkins(JENKINS_URL, username=JENKINS_USERNAME, password=JENKINS_PASSWORD, timeout=30)def get_modified_xml(job_config_xml_tree): # create builders node builders_element = ET.Element("builders") job_config_xml_tree.append(builders_element) # Move prebuilders to builders prebuilders_node = job_config_xml_tree.find("prebuilders") if prebuilders_node is not None and prebuilders_node.getchildren() is not None: for pre_builder in prebuilders_node.getchildren(): builders_element.append(pre_builder) job_config_xml_tree.remove(prebuilders_node) # Create a maven block maven_node = ET.Element("hudson.tasks.Maven") builders_element.append(maven_node) move(job_config_xml_tree.find("goals"), job_config_xml_tree, maven_node, "targets") maven_name_node = job_config_xml_tree.find("mavenName") if maven_name_node: move(maven_name_node, job_config_xml_tree, maven_node) else: maven_name_node = ET.Element("mavenName") maven_name_node.text = "Maven" maven_node.append(maven_name_node) move(job_config_xml_tree.find("rootPOM"), job_config_xml_tree, maven_node) move(job_config_xml_tree.find("mavenOpts"), job_config_xml_tree, maven_node) move(job_config_xml_tree.find("settings"), job_config_xml_tree, maven_node) move(job_config_xml_tree.find("globalSettings"), job_config_xml_tree, maven_node) # items that don't exist in maven step: remove(job_config_xml_tree, [ 'resolveDependencies', 'processPlugins', 'siteArchivingDisabled', 'archivingDisabled', 'mavenValidationLevel', 'disableTriggerDownstreamProjects', 'blockTriggerWhenBuilding', 'fingerprintingDisabled', 'incrementalBuild', 'processPlugins', 'siteArchivingDisabled', 'ignoreUpstremChanges', 'rootModule' ]) # Move postbuilders to builders postbuilders_node = job_config_xml_tree.find("postbuilders") if postbuilders_node is not None and postbuilders_node.getchildren() is not None: for post_builder in postbuilders_node.getchildren(): builders_element.append(post_builder) job_config_xml_tree.remove(postbuilders_node) # rename top-level element # new parent node new_job_config_xml_tree = ET.Element("project") for child_node in job_config_xml_tree.getchildren(): new_job_config_xml_tree.append(child_node) return new_job_config_xml_treedef move(from_node, from_parent_node, to_node, to_name=None): if from_node is not None: if to_name: tmp_element_node = ET.Element(to_name) tmp_element_node.text = from_node.text tmp_element_node.attrib = from_node.attrib to_node.append(tmp_element_node) from_parent_node.remove(from_node) else: to_node.append(from_node) from_parent_node.remove(from_node)def remove(from_node, name_list): for name in name_list: tmp_node = from_node.find(name) if tmp_node is not None: from_node.remove(tmp_node)def main(): jenkins_server = get_jenkins_server() job_list = jenkins_server.get_jobs_list() for job_name in job_list: if not job_name.endswith("-DEPRECATED"): job_obj = jenkins_server.get_job(job_name) config_text = job_obj.get_config() config_xml_tree = ET.fromstring(config_text) if config_xml_tree.tag == "maven2-moduleset": new_config_xml_tree = get_modified_xml(config_xml_tree) new_config_xml = ET.tostring(new_config_xml_tree) jenkins_server.rename_job(job_name, job_name + "-DEPRECATED") jenkins_server.create_job(job_name, new_config_xml) print("migrate job from Maven Type to FreeStyle Type: " + job_name)if __name__ == "__main__": main()
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557424/viewspace-2663750/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- jsp頁面number型別自動轉為String型別JS型別
- Jenkins Job遷移Jenkins
- 中介軟體的型別:不同的風格型別
- 淺談程式語言型別的強型別,弱型別,動態型別,靜態型別型別
- PostgreSQL批次改資料型別SQL資料型別
- 將maven、gradle倉庫遷移到d盤MavenGradle
- Java資料型別自動轉換(++ ,+=)Java資料型別
- 遊戲自動化型別和方向遊戲型別
- TS資料型別:型別別名/聯合型別/字面量型別/型別推論等綱要資料型別
- 我如何將部落格遷移到 Kubernetes(上)
- 我如何將部落格遷移到 Kubernetes(下)
- 第11章 使用類——型別轉換(二)將自定義型別轉換為內建型別型別
- JavaScript引用型別-Object型別JavaScript型別Object
- 值型別和引用型別型別
- route.query型別報錯,不能將LocationQueryValue...... 分配給型別.....型別
- JSON序列化時將BigDecimal型別轉換成String型別JSONDecimal型別
- Java™ 教程(將介面用作型別)Java型別
- js基本型別和引用型別區別JS型別
- 值型別與引用型別的區別型別
- typeScript 型別斷言、聯合型別和交叉型別(七)TypeScript型別
- 概念區別 【編譯型語言與解釋型語言、動態型別語言與靜態型別語言、強型別語言與弱型別語言】編譯型別
- python自學——資料型別Python資料型別
- JavaScript值型別和引用型別JavaScript型別
- ECMAScript 原始型別與引用型別型別
- 資料型別,型別轉換資料型別
- c#:值型別&引用型別C#型別
- 型別預設和any型別型別
- java基本資料型別與自動轉換Java資料型別
- JS指令碼批次處理TS資料型別JS指令碼資料型別
- TypeScript 泛型型別TypeScript泛型型別
- 型別 VS 泛型型別泛型
- JavaScript - 基本型別與引用型別值JavaScript型別
- BigDecimal轉為String型別、int型別Decimal型別
- 基本資料型別與字串型別資料型別字串
- Java的基本型別和引用型別Java型別
- js基本語法之 值型別(資料型別)(變數型別)JS資料型別變數
- c#中值型別和引用型別的區別C#型別
- Mysql BLOB、BLOB與TEXT區別及效能影響、將BLOB型別轉換成VARCHAR型別MySql型別