How to configure imagePullPolicy from fabric8-maven-plugin - fabric8

Context:
I'm using fabric8-maven-plugin to generate the docker image and deploy it to a Kubernetes cluster.
Question:
It's possible to configure the imagePullPolicy parameter whose default value is IfNotPresent?
Current configuration in pom.xml
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>3.5.25</version>
<configuration>
<images>
<image>
<name>my-service</name>
<alias>service</alias>
<build>
<from>java:8</from>
<tags>
<tag>latest</tag>
<tag>${project.version}</tag>
</tags>
<!--
The entry point path used is "maven/" since this is the default folder: https://dmp.fabric8.io/#building-images,
"launch.sh" is copied to the container based in the assembly.xml descriptor file.
-->
<entryPoint>
<exec>
<arg>maven/launch.sh</arg>
</exec>
</entryPoint>
<assembly>
<descriptor>assembly.xml</descriptor>
</assembly>
</build>
</image>
</images>
<generator>
<includes>
<include>java-exec</include>
</includes>
<config>
<java-exec>
<webPort>8080</webPort>
</java-exec>
</config>
</generator>
</configuration>
</plugin>
</plugins>
</build>
What I got is:
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: 394148814603.dkr.ecr.us-east-1.amazonaws.com/dkrecr-nafiux-ncp/kcluster-ncp-myservice
imagePullPolicy: IfNotPresent <---- I want to personalize this value to Always, for instance.
name: service
securityContext:
privileged: false
Why I want to change the value to Always? Mainly because I'm doing a lot of tests with the cluster, and I don't want to assign a new version to the docker image for each test that I do, at this point.
I appreciate your support.

Finally I found the parameter that I was looking for:
1) Add latest to the docker image:
<name>myservice:latest</name>
2) Add pullPolicy in the enricher configuration.
<enricher>
<config>
<fmp-controller>
<pullPolicy>Always</pullPolicy>
</fmp-controller>
</config>
</enricher>
Full example:
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>3.5.25</version>
<configuration>
<images>
<image>
<alias>service</alias>
<name>myservice:latest</name>
<build>
<from>java:8</from>
<tags>
<tag>latest</tag>
<tag>${project.version}</tag>
</tags>
<!--
The entry point path used is "maven/" since this is the default folder: https://dmp.fabric8.io/#building-images,
"launch.sh" is copied to the container based in the assembly.xml descriptor file.
-->
<entryPoint>
<exec>
<arg>maven/launch.sh</arg>
</exec>
</entryPoint>
<assembly>
<descriptor>assembly.xml</descriptor>
</assembly>
</build>
</image>
</images>
<generator>
<includes>
<include>java-exec</include>
</includes>
<config>
<java-exec>
<webPort>8080</webPort>
</java-exec>
</config>
</generator>
<enricher>
<config>
<fmp-controller>
<pullPolicy>Always</pullPolicy>
</fmp-controller>
</config>
</enricher>
</configuration>
</plugin>
</plugins>
</build>

Add following enricher config to pom.xml along with generator, images.
<configuration>
<enricher>
<config>
<fmp-controller>
<pullPolicy>Always</pullPolicy>
</fmp-controller>
</config>
</enricher>
</configuration>
Though this is not ideal way, but will work for the time being.

Related

volumes in docker-maven-plugin not binding

I am using docker-maven-plugin to run an image from a remote repository.
The image is running using docker:start but it seems like the volumes not working.
I run the command using groovy (jenkins):
sh(script:"mvn -B -gs ${cfg} -f lib/pom.xml docker:start", returnStatus: true)
my pom.xml code is:
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.31.0</version>
<configuration>
<images>
<image>
<name>imageName:latest</name>
<run>
<volumes>
<bind>
<volume>/inputs:/inputs</volume>
<volume>/out:/out</volume>
<volume>/env:/env</volume>
</bind>
</volumes>
</run>
</image>
</images>
</configuration>
</plugin>
any idea what is going wrong?

Passing placeholders to docker image built from docker-maven-plugin (io.fabric8)

Im building a docker image from maven using io.fabric8:docker-maven-plugin.
i want the container to run like :
java -jar -Dspring.profiles.active=prod /maven/myapp-1.4.3.jar
java -jar -Dspring.profiles.active=dev /maven/myapp-1.4.3.jar
so i actually want the image to pass -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE and that variable will be passed in via docker run when starting a container:
docker run --env SPRING_PROFILES_ACTIVE=prod
however, it looks like the container run this command:
java -jar -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE /maven/myapp-1.4.3.jar
and the $SPRING_PROFILES_ACTIVE is not replaced with the env var.
pom.xml:
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.31.0</version>
<extensions>true</extensions>
<configuration>
<verbose>true</verbose>
<images>
<image>
<name>${docker.registry}/${project.artifactId}</name>
<build>
<from>java:8-jdk-alpine</from>
<tags>
<tag>${project.version}</tag>
<tag>latest</tag>
</tags>
<entryPoint>
<exec>
<args>java</args>
<args>-jar</args>
<!--<args>-Dspring.profiles.active=$SPRING_PROFILES_ACTIVE</args>-->
<args>/maven/${project.artifactId}-${project.version}.jar</args>
</exec>
</entryPoint>
<assembly>
<descriptorRef>artifact</descriptorRef>
</assembly>
</build>
</image>
</images>

Tomcat deploys older version of webapp

This might be a duplicate, cause I can't image that we're the first to encounter this, but I can't seem to find it.
So, we are deploying WAR files to a tomcat 8.5 server with gitlab ci using maven. Issue is that tomcat messes up the versions when we moved from 0.2.9 to 0.2.10. Apparendly the server deploys the WARs in alphabetical order and 0.2.10 lies between 0.2.1 and 0.2.2 and the running version is still 0.2.9 even while 0.2.10 was correctly deployed to the server.
Full webapp name looks like: WebappName##0.2.10-SNAPSHOT_201901010000.war
We thought about renaming our versions to 0.2.009 and 0.2.010 but that seems like a rather dirty work-around. Of cause older versions will be deleted from time to time so it's not a permanent problem, but it's just somewhat annoying and any hints on how to solve this would be great.
From the pom.xml
<version>0.2.10-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.install.skip>true</maven.install.skip>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>
[..]
<profile>
<id>deploy-stage</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<war.name>WebappName##${project.version}_${timestamp}</war.name>
<tomcat.url>http://[..]/manager/text</tomcat.url>
<tomcat.server>[..]</tomcat.server>
<tomcat.webpath>/${war.name}</tomcat.webpath>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>default-war</id>
<goals>
<goal>manifest</goal>
<goal>war</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<warName>${war.name}</warName>
<failOnMissingWebXml>true</failOnMissingWebXml>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<forced>true</forced>
<manifest>
<addClasspath>true</addClasspath>
<packageName>true</packageName>
<useUniqueVersions>true</useUniqueVersions>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Archetype>${archetypeArtifactId}</Archetype>
<Archetype-Version>${archetypeVersion}</Archetype-Version>
</manifestEntries>
</archive>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<warFile>${project.build.directory}/${war.name}.war</warFile>
<url>${tomcat.url}</url>
<server>${tomcat.server}</server>
<path>${tomcat.webpath}</path>
</configuration>
<executions>
<execution>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
From gitlab-ci.yml
variables:
MAVEN_OPTS: "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
# Cache downloaded dependencies and plugins between builds.
cache:
paths:
- /root/.m2/repository/
stages:
- build
- deploy
# Run deploy
deploy:staging:
stage: deploy
script:
- 'mvn $MAVEN_CLI_OPTS -Dsonar.branch=$CI_COMMIT_REF_NAME deploy -am -P deploy-stage'
only:
- staging
image: maven:3.3.9-jdk-8
As the Apache Tomcat documentation says:
String comparisons are used to determine version order.
This is simply not the same as comparison of Maven artifact versions. A version of 2.0.2 is always larger by String comparison than 2.0.10 or even 2.0.15000 etc.
I guess you have something like this in your pom.xml:
<properties>
<buildTimestamp>${maven.build.timestamp}</buildTimestamp>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>
<build>
<finalName>${project.artifactId}##${project.version}_${maven.build.timestamp}</finalName>
</build>
You can change that to:
<finalName>${project.artifactId}##${maven.build.timestamp}_${project.version}</finalName>
which yields a file name like WebappName##201901010000_0.2.10-SNAPSHOT.war.
This way the most current build by timestamp will be deployed as currently active application version.
Alternatively you can keep your version schema of the .war file name and instead have your app deployed using a versioned file name for your context.xml:
apache-tomcat/conf/Catalina/localhost/WebappName##201901010000.xml
with the content:
<Context docBase="/path/to/WebappName##0.2.10-SNAPSHOT_201901010000.war" path="/WebappName"/>
In Apache Tomcat Manager this will show up as version 201901010000 in application version column. Again the most current build by timestamp will be deployed as currently active application version independent of the Maven artifact version as the deployment version String is taken from the .xml file name instead of the .war file name.

docker-maven-plugin: how do I pass environment variable from `docker run ... -e <value>` to build or run step?

I have a .jar that contains multiple public static void main(psvm)'s that I want to be able to call when I do docker run ... -e <class.path.from.env> on the image and pass an environment variable to specify the class path. Something like this:
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<images>
<image>
<name>${project.artifactId}</name>
<build>
<from>java:8-jre</from>
<tags>
<tag>${build.environment}-latest</tag>
<tag>${build.environment}-${build.number}</tag>
</tags>
<entryPoint>
<exec>
<arg>java</arg>
<arg>-Duser.timezone=UTC</arg>
<arg>-cp</arg>
<arg>/opt/${project.artifactId}-${project.version}.jar</arg>
<arg>${class.path.from.env}</arg>
</exec>
</entryPoint>
<assembly>
<basedir>/opt</basedir>
<inline>
<files>
<file>
<source>target/${project.artifactId}-${project.version}.jar</source>
</file>
</files>
</inline>
</assembly>
</build>
</image>
</images>
</configuration>
</plugin>
Although I read the whole documentation for docker-maven-plugin, I'm not sure how I can make this work. Basically where do I declare the environment variable class.path.from.env and how can I make sure it gets the one I pass through -e in docker run ...?
I think you need to declare a <run> section next to your <build> section, and add your env variable to <env>, as described here: https://dmp.fabric8.io/#misc-env
<run>
<env>
<CATALINA_OPTS>-Xmx32m</CATALINA_OPTS>
<JOLOKIA_OFF/>
</env>

How can I use properties exactly as they are provided by the io.fabric8 docker-maven-plugin?

Maven properties filled in by io.fabric8 docker-maven-plugin seem not to be interpolated when used as is.
The docker-maven-plugin fills in some maven properties (some.host and some.port) which I try to resolve.
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.15.5</version>
<configuration>
<images>
<image>
<alias>...</alias>
<name>...</name>
<run>
<ports>
<port>+some.host:some.port:5432</port>
</ports>
<namingStrategy>alias</namingStrategy>
</run>
</image>
</images>
</configuration>
</plugin>
They are used like this:
<properties>
<docker.host>${some.host}</docker.host>
<docker.port>${some.port}</docker.port>
</properties>
which leads to two empty values. They contain nothing while they should contain e.g. 127.0.0.1 and 5555.
If I add some characters, suddenly the values are interpolated correctly (but of course the values are useless then)
<properties>
<docker.host>${some.host}+abc</docker.host>
<docker.port>${some.port}+123</docker.port>
</properties>
which leads to 127.0.0.1+abc and 5555+123
Some things I tried don't work either:
<properties>
<dollar>$</dollar>
<docker.host>${dollar}{some.host}</docker.host>
<docker.port>${some.port}${}</docker.port>
</properties>
which leads to an empty value and 5555null
Roland Huß noted that the problem could be avoided by using dockers fixed ports. And that should be the first choice.
But for completion, I'll add a solution that also works:
Trick maven into creating an empty property (e.g., using the groovy-maven-plugin)
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>set empty property</id>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
<![CDATA[
project.properties.setProperty('empty', '');
]]>
</source>
</configuration>
</execution>
</executions>
</plugin>
Use the empty property to make maven interpolate the properties exposed by the docker-maven-plugin
<docker.host>${some.host}${empty}</docker.host>
<docker.port>${some.port}${empty}</docker.port>

Resources