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

Is there a way to specify some kind finally action (build-cleanup phase) in 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中有没有way/plugin指定一些finallyaction/phase?这样一来,如果构建脚本失败,仍然可以释放一些可能已经保留的资源?

使用 Ryuk 将类似的解决方案应用于测试容器正在做的事情可以实现目标:https://github.com/testcontainers/moby-ryuk

要获取的图像应该被标记,例如如:

<autoRemove>true</autoRemove>
<labels>
   <killme>true</killme>
</labels>
<wait>
   <time>3000</time>
</wait>

以上延迟是为了给一些时间 琉克设置。因为这个必须并行启动...

                        <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 套接字向 Ryuk 容器至少每 10 秒发送一次 hartbeat,例如。像这样: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 套接字。