问题描述
我要使用maven docker插件启动postgres容器,然后在以后的步骤中使用数据库生成一些伪像。
<plugin>
…
<artifactId>docker-maven-plugin</artifactId>
…
<configuration>
<images>
<image>
...
<name>postgres:11</name>
...
</image>
</images>
</configuration>
<executions>
<execution>
<id>start-postgres-container</id>
<phase>generate-sources</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-postgres-container</id>
<phase>process-sources</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
我的问题是,当以上start
和stop
之间的任何操作出现错误时,maven会离开正在运行的容器,并且连续的构建尝试将失败,因此必须放下首先手动剩下的容器。
Maven中是否有一种方法/插件来指定一些finally
动作/阶段?这样一来,如果构建脚本失败,人们仍然可以释放一些可能已经保留的资源?
解决方法
将类似的解决方案应用于使用Ryuk的测试容器所做的工作可以实现目标:https://github.com/testcontainers/moby-ryuk
要标记的图像应加标签,例如为:
<autoRemove>true</autoRemove>
<labels>
<killme>true</killme>
</labels>
<wait>
<time>3000</time>
</wait>
上述延迟是为了给 Ryuk设置。由于这必须并行启动...
<image>
<alias>ryuk-summoned</alias>
<name>testcontainers/ryuk:0.3.0</name>
<run>
<ports>
<port>ryuk.port:8080</port>
</ports>
<volumes>
<bind>
<volume>/var/run/docker.sock:/var/run/docker.sock</volume>
</bind>
</volumes>
<autoRemove>true</autoRemove>
</run>
</image>
挑战是必须通过包含Deathnote的TCP套接字,至少每10秒钟向Ryuk容器发送一次节拍。像这样:printf "label=killme" | nc localhost 8080
。
使用下面的maven exec插件和简单的setup-ryuk.sh
脚本调用上述命令即可轻松实现。 (注意:这仅提供一个没有连续心跳的死亡笔记,因此Ryuk会在接下来的10秒钟内自行死亡-届时它将获得收到笔记的所有物品。)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>stop-postgres</id>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<target>
<exec executable="bash">
<arg value="setup-ryuk.sh"/>
<arg value="${ryuk.port}"/>
</exec>
</target>
</configuration>
</plugin>
要使该平台独立(如上所述,这对于Linux / Mac有效),并使Ryuk存活更长时间,最好的方法似乎是想出自己的maven插件向TCP套接字发送消息。