需要一个工作策略来在Jenkins管道脚本中执行SQL脚本 [英] Need a working strategy to execute SQL scripts in Jenkins pipeline script

查看:1870
本文介绍了需要一个工作策略来在Jenkins管道脚本中执行SQL脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为Jenkins管道脚本的一部分,我需要执行一些SQL脚本来初始化一个数据库(mariadb)。这项工作在我拥有的詹金斯奴隶上运行。我维护Jenkins主实例,但不是它运行的主机。



我的第一个尝试是在脚本中调用内联代码Sql.newInstance(.. 。)和sql.execute(...)。因为mariadb jar不在classpath中。



然后我尝试设置从属的CLASSPATH env var,将mariadb客户端jar添加到它,然后断开连接并重新连接从机。这似乎没有效果。

然后我尝试了@ GrapeConfig / @ Grab方法。我使用@GrapeConfig来设置systemClassLoader = true。这会因无法找到合适的类加载器而失败。所以,我尝试删除@GrapeConfig,并且这个失败的结果是RuntimeException:无法创建类javax.xml.parsers.SAXParserFactory的提供程序。

接下来,我我猜想我会尝试从sh命令直接运行mysql,并在我的sql脚本的内容中使用管道。这看起来似乎是合理的,但我不确定这是否会奏效。



我已经看过有关各种尝试这样做的笔记,但我从未听说过有人成功地做到了这一点。

解决方案

虽然用java方式实现这个看起来很合理,但我发现它更多直接简单地运行' sh(mysql ...< file.sql)'。它避免了所有粗糙的类路径问题。它确实要求将数据库客户端安装在从属机器上,并且它不允许数据库独立性(不是那么重要)。实际上,我实际上做的是在容器中运行mariadb,所以最终的命令行更像 docker exec -i容器mysql ...< file.sql (注意-i,而不是通常的-it,因为如果在文件中管道的话,这将不起作用)。

更新

从macg33zr的手肘中,我发现将任务添加到现有的Gradle构建脚本来操作数据库非常简单。我没有完全实现我需要的东西,我只是验证它可以使用简单的select语句。



我已经有了JDBC驱动程序的jars在一个单独的Gradle配置中,因为我需要将这些工件存储在容器的lib目录中。



以下是所需部分的完整摘要: https://discuss.gradle.org/t/jdbc-driver-class-cannot-be-loaded-with-gradle-2-0-but-worked-with-1-12/2277 。关键的微妙之处是将JDBC驱动程序jar添加到类加载器。


As part of a Jenkins pipeline script, I need to execute some SQL scripts to initialize a database (mariadb). This job runs on a Jenkins slave that I own. I maintain the Jenkins master instance, but not the host it runs on.

My first try was simply having inline code in the script to call "Sql.newInstance(...)" and "sql.execute(...)". This fails because the mariadb jar is not in the classpath.

I then tried setting the CLASSPATH env var for the slave, to add the mariadb client jar to it, then disconnecting and reconnecting the slave. This appeared to have no effect.

I then tried the @GrapeConfig/@Grab approach. I used @GrapeConfig to set "systemClassLoader=true". This fails with "Unable to find suitable classloader". So, I then tried removing the @GrapeConfig, and this fails with "RuntimeException: Provider for class javax.xml.parsers.SAXParserFactory cannot be created".

Next, I guess I'm going to try to directly run "mysql" from a "sh" command and pipe in the contents of my sql scripts. This seems plausible, but I'm not sure if this will work.

I've seen notes talking about various attempts to do this, but I've never heard of someone successfully doing this.

解决方案

Although it seems logical to implement this in a "java way", I found that it was more straightforward to simply run 'sh("mysql ... < file.sql")'. It avoids all the gnarly classpath problems. It does require that the database client be installed on the slave box, and it doesn't allow for database independence (not really that important). In reality, what I actually did was run mariadb in a container, so the resulting command line was more like "docker exec -i container mysql ... < file.sql" (notice the "-i", not the usual "-it", as that won't work if piping in a file).

Update:

From the elbow from macg33zr, I found it was pretty easy to add tasks to my existing Gradle build script to manipulate the database. I haven't fully implemented what I need to with it, I just verified that it could work with a simple "select" statement.

I already had the JDBC driver jars in a separate Gradle configuration, as I needed to store those artifacts in the container's lib directory.

The following is a good summary of the required pieces: https://discuss.gradle.org/t/jdbc-driver-class-cannot-be-loaded-with-gradle-2-0-but-worked-with-1-12/2277 . The key subtle thing is adding the JDBC driver jars to the classloader.

这篇关于需要一个工作策略来在Jenkins管道脚本中执行SQL脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆