Есть ли способ указать какое-то окончательное действие (этап сборки-очистки) в Maven?

Я запускаю контейнер postgres с плагином maven docker, а затем использую БД для создания некоторых артефактов на более поздних этапах.

<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? Чтобы в случае сбоя в сценариях сборки можно было освободить некоторые ресурсы, которые, возможно, уже были зарезервированы?


person alwi    schedule 12.11.2020    source источник
comment
Если вам нужно запустить док-контейнер с базой данных, это больше похоже на интеграционные тесты... Это должно быть сделано с помощью предварительного интеграционного теста, интеграционного теста и постинтеграционного теста... другой вариант - проверьте testcontainers, которые кажутся более подходящими для такого рода проблем, за исключением того, что я не понимаю, как использовать базу данных и создать код как-то здесь?...   -  person khmarbaise    schedule 12.11.2020
comment
Не обязательно. На самом деле это генерация кода, например. Классы Jooq основаны на схеме с применением самых последних миграций (см.: jooq-codegen-maven). На этапе проверки мы используем тестовые контейнеры для целей тестирования, в т.ч. Настройка БД. Но помимо того, как мы его используем, проблема, которую я описываю, будет общей проблемой для docker-maven-plugin, которая имеет цель выполнения stop, в то время как в MVN, похоже, нет возможности полагаться на нее в скрипте сборки.   -  person alwi    schedule 13.11.2020
comment
Docker обычно означает интеграционное тестирование, которое я описал (или использование тестовых контейнеров отличается)... любая другая область звучит для меня неправильно... решение может состоять в том, чтобы поместить генерацию в отдельный модуль, который отвечает только за генерацию, где это может быть сделано по-другому, что затем можно использовать в качестве зависимости в вашем проекте...   -  person khmarbaise    schedule 13.11.2020
comment
Вынос генерации кода в отдельный модуль просто переместит проблему в другое место и не решит ее (к тому же это уже отдельный небольшой модуль DAO в проекте). Мне нужно запустить БД для jooq.org/doc/latest/manual/code -генерация перед переходом к этапу компиляции модуля. Возможно, плагин docker mvn не лучший для этого, но тогда я открыт для любых предложений, как его можно заменить для генерации кода mvn, сохраняя при этом все полностью автоматизированным...   -  person alwi    schedule 16.11.2020


Ответы (1)


Цель может быть достигнута с помощью аналогичного решения для тестовых контейнеров с использованием 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>

Проблема заключается в том, что через TCP-сокет, содержащий ноту смерти, должна быть подача с сердцебиением в сторону контейнера Ryuk не менее 1 раза в 10 секунд, например. вот так: printf "label=killme" | nc localhost 8080.

Этого легко добиться с помощью приведенного ниже плагина maven exec и простого скрипта setup-ryuk.sh, вызывающего команду, упомянутую выше. (ПРИМЕЧАНИЕ: это дает только одну тетрадь смерти без последовательных ударов сердца, поэтому Рюк умирает сам в течение следующих 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.

person alwi    schedule 19.11.2020