fabric8io / docker-maven-plugin

Maven plugin for running and creating Docker images
https://dmp.fabric8.io
Apache License 2.0
1.88k stars 643 forks source link

Add build meta data from an assembly to the container #312

Open jstrachan opened 9 years ago

jstrachan commented 9 years ago

it would be nice if the docker maven plugin generated a 'dependencies' file (xml/json/yaml) which contains all the mvn coordinates of the transitive dependencies put into the docker image

its going to be increasingly useful to be able to query all docker images which are using a given dependency.

when patching libraries for security; its going to be useful to have a canonical list of the maven coordinates of all transitive dependencies put inside a docker image.

it'd be nice to also be able to include this dependency file inside the docker image in a canonical place. /dependencies.yaml or whatever?

jgangemi commented 9 years ago

why not use the dependency:build-classpath goal to achieve this?

jstrachan commented 9 years ago

its more something I'd like to happen OOTB than manually getting users to hack their poms to add a dependency:build-classpath goal and then another build-helper:attach-artifact goal to add it to the repo

jgangemi commented 9 years ago

so this is something you want to dump into nexus (or similar maven repository) and not the container itself?

jstrachan commented 9 years ago

both ;)

So I'd like a way to easily audit - by looking at a docker image - or by querying nexus - what docker images have what versions of what maven dependencies inside them.

e.g. to be able to do nice patching of a jar "foo-1.2.3" to be able to query docker images or maven repos to find what projects need fixing

jgangemi commented 9 years ago

just to continue playing devil's advocate...

don't you already know this just based on the container's version or are you not tying the container version to the artifact version?

jstrachan commented 9 years ago

how from the container image's version do we know the transitive dependency tree of all the versions of all the jars used inside it? If that was immediately obvious today from docker images I'd not have raised this issue ;).

Note for fat jars where there's only 1 jar dependency going into the docker image this is not an issue; as usually the version of the image will be the fatjar version. This issue is more related to the use case of flat classpaths (multiple transitive dependent jars copied into the /deployments folder) or for multiple WARs per servlet engine - where the transitive dependency tree should, by default, be put in a canonical place in docker and the maven repo to aid patching/upgrading

jgangemi commented 9 years ago

if the container version is tied to the maven/pom version, then can't you just go back to the pom for the app, run a dependency:tree and get your versions?

jstrachan commented 9 years ago

Possibly - if you knew how to find the source code & knew the right version of maven to use & knew the environment/settings used to run the release build.

Though profiles and system properties can break knowing the real dependencies that were used at the time of a build (versus the default dependencies).

Then knowing the maven dependencies isn't really enough; its the assembly that the docker maven plugin chooses for each image thats the important information (which can include/exclude dependencies and so forth).

In general its much simpler and safer to just generate this at build time; then you know its exactly what docker maven plugin put into the image; rather than some guestimate thats right 9 times out of 10

rhuss commented 9 years ago

I agree with @jstrachan that adding meta data for how the assembly is created (like the deps maven coords and/or even the classpath as a flat file). This could be used e.g by a base image's startup script or other tools for adding value.

For the classpath I've implemented a solution based on the dependency plugin in only, but this is quite involved (you need to take care to use the right, fixed path separators ":" even on windows etc. which adds quite some extra lines). So direct d-m-p support might really help for this occasions.

Maybe we should also put an option to put the pom itself into the image but as already said, a pom.xml is often only the half truth since it depends on (then external) parent poms and boms.

jgangemi commented 9 years ago

like i said, just playing devil's advocate, i think this would be useful. :)

can you force maven to generate an 'effective' pom? that would handle it only being a 1/2 truth.

rhuss commented 9 years ago

@jgangemi yeah, you know it, it's always important to ask the hard questions about the use case :) You are right, many of the things could be done by some magic combinations of various Maven plugins playing together, but that's gets very complex quite fast.

E.g. here's the maven-dependency-plugin together with d-m-p for getting the classpath into the image (descriptor ref 'artifact-with-dependencies` includes the classpath file if present)

     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.10</version>
        <executions>
          <execution>
            <id>add-classpath</id>
            <phase>package</phase>
            <goals>
              <!--  create target/classpath for docker-maven-plugin's assembly to pick up  -->
              <goal>build-classpath</goal>
            </goals>
            <configuration>
              <prefix>.</prefix>
              <pathSeparator>:</pathSeparator>
              <includeScope>runtime</includeScope>
              <outputFile>${project.build.directory}/classpath</outputFile>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.jolokia</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <version>${docker.maven.plugin.version}</version>
        <configuration>
          <images>
            <image>
              <name>${docker.image}</name>
              <build>
                <from>${docker.from}</from>
                <assembly>
                  <basedir>/app</basedir>
                  <descriptorRef>artifact-with-dependencies</descriptorRef>
                </assembly>
                <env>
                  <JAVA_APP_JAR>${project.build.finalName}.jar</JAVA_APP_JAR>
                  <JAVA_MAIN_CLASS>io.fabric8.quickstarts.java.simple.Main</JAVA_MAIN_CLASS>
                </env>
              </build>
            </image>
          </images>
        </configuration>
      </plugin>
rhuss commented 9 years ago

Calling another plugin (like help:effective-pom) is always hard from within another plugin, so I'm not sure whether getting the fully resolved pom is easy but it would be a good addition for sure.

A plain dependency list with only maven coordinates line-by-line would be cool insofar it can be easily used by other tools than maven too make use of it.