2017-03-15 126 views
1

作爲Jenkins管道腳本的一部分,我需要執行一些SQL腳本來初始化數據庫(mariadb)。這項工作在我擁有的詹金斯奴隸上運行。我維護Jenkins主實例,但不是它運行的主機。需要在Jenkins管道腳本中執行SQL腳本的工作策略

我的第一次嘗試是在腳本中調用「Sql.newInstance(...)」和「sql.execute(...)」。由於mariadb jar不在類路徑中,因此失敗。

然後我嘗試設置從屬的CLASSPATH env var,將mariadb客戶端jar添加到它,然後斷開連接並重新連接從屬設備。這似乎沒有效果。

然後我嘗試了@ GrapeConfig/@ Grab方法。我使用@GrapeConfig來設置「systemClassLoader = true」。這會因「無法找到合適的類加載器」而失敗。於是,我嘗試刪除@GrapeConfig,並且失敗,出現「RuntimeException:無法創建類javax.xml.parsers.SAXParserFactory的提供程序」。

接下來,我想我會嘗試從「sh」命令直接運行「mysql」,並在我的sql腳本的內容中管道。這似乎是合理的,但我不確定這是否會起作用。

我已經看過筆記談論各種嘗試這樣做,但我從來沒有聽說過某人成功地做到這一點。

+0

你可以把mariadb jar放在Jenkins JDK/jre/lib/ext中,試試用Sql.newInstance(...) –

+0

你可以把Groovy代碼放到Gradle項目中運行SQL腳本,然後使用Jenkins在管道中使用Gradle構建步驟運行所需的Gradle任務。這是我之前完成的設置數據庫以在項目CI構建上運行測試的事情。然後你可以在Jenkins之外離線工作。 – macg33zr

+0

有趣的想法,特別是在我運行這些sql腳本之前,我已經使用Gradle構建腳本構建了自己的代碼。當然,您應該添加這個答案作爲答案,並加以闡述。 –

回答

1

雖然用「java方式」實現它似乎是合乎邏輯的,但我發現僅僅運行'sh("mysql ... < file.sql")'會更直接。它避免了所有粗糙的類路徑問題。它確實要求數據庫客戶機安裝在從機盒上,並且不允許數據庫獨立性(不是那麼重要)。實際上,我實際上做的是在容器中運行mariadb,因此最終的命令行更像是「docker exec -i container mysql ... < file.sql」(注意「-i」,而不是通常的「-it」),因爲如果管道在一份文件)。

更新

從從macg33zr肘,我發現這是很容易的任務添加到我現有的搖籃構建腳本來操作數據庫。我沒有完全實現我需要的東西,我只是驗證它可以用簡單的「select」語句來工作。

我已經有了一個單獨的Gradle配置中的JDBC驅動程序jars,因爲我需要將這些工件存儲在容器的lib目錄中。

以下是所需部件的一個很好的總結:https://discuss.gradle.org/t/jdbc-driver-class-cannot-be-loaded-with-gradle-2-0-but-worked-with-1-12/2277。關鍵的微妙之處在於將JDBC驅動程序jar添加到類加載器中。

+0

我在這裏的答案中添加了類似於我的Gradle構建中的東西:http://stackoverflow.com/questions/6329872/how-to-add-external-jar-files-to-gradle-build-script。另一種方法是使用Liquibase變更集實現數據庫更新 - 請參閱http://www.liquibase.org/。 Liquibase是一個Java工具,我爲Gradle編寫了一個包裝類。這是從運行.SQL腳本開始的更高層次,因爲您正在對數據庫模式/數據進行細粒度的更改控制。請注意,現在有一個Gradle插件:https://github.com/liquibase/liquibase-gradle-plugin – macg33zr