有没有办法在Maven中指定某种最终动作构建-清理阶段?

问题描述

我要使用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>

我的问题是,当以上startstop间的任何操作出现错误时,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套接字发送消息。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...