Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy goal for copying files from container to host #1405

Merged
merged 5 commits into from Apr 2, 2021

Conversation

mabrarov
Copy link
Contributor

@mabrarov mabrarov commented Nov 13, 2020

Copy goal for copying files & directories from container to host. Refer to issue #752.

Things which are missing due to I have few time to work on them:

  • Unit tests for CopyMojo class.
  • Example different than implementation of docker builder pattern and / or example copying directory (i.e. not just a single file).
  • Documentation for the copy goal.

I appreciate any help with making this pull request complete.

Fixes #752

@codecov
Copy link

codecov bot commented Nov 13, 2020

Codecov Report

Merging #1405 (90ab423) into master (5b91720) will increase coverage by 0.88%.
The diff coverage is 81.56%.

@@             Coverage Diff              @@
##             master    #1405      +/-   ##
============================================
+ Coverage     59.25%   60.14%   +0.88%     
- Complexity     2004     2068      +64     
============================================
  Files           163      165       +2     
  Lines          9047     9358     +311     
  Branches       1366     1414      +48     
============================================
+ Hits           5361     5628     +267     
- Misses         3198     3236      +38     
- Partials        488      494       +6     
Impacted Files Coverage Δ Complexity Δ
...rc/main/java/io/fabric8/maven/docker/LogsMojo.java 0.00% <0.00%> (ø) 0.00 <0.00> (ø)
...c/main/java/io/fabric8/maven/docker/StartMojo.java 0.00% <0.00%> (ø) 0.00 <0.00> (ø)
...8/maven/docker/assembly/DockerAssemblyManager.java 16.41% <0.00%> (-0.71%) 11.00 <0.00> (ø)
...o/fabric8/maven/docker/service/ArchiveService.java 23.52% <0.00%> (-3.14%) 1.00 <0.00> (ø)
.../io/fabric8/maven/docker/service/QueryService.java 21.21% <0.00%> (-0.67%) 4.00 <0.00> (ø)
.../io/fabric8/maven/docker/service/WatchService.java 3.79% <0.00%> (ø) 1.00 <0.00> (ø)
...ven/docker/access/hc/DockerAccessWithHcClient.java 24.25% <3.33%> (-0.97%) 26.00 <0.00> (ø)
.../docker/config/handler/property/ValueProvider.java 83.17% <44.44%> (-3.56%) 12.00 <1.00> (+1.00) ⬇️
...rc/main/java/io/fabric8/maven/docker/SaveMojo.java 83.33% <50.00%> (-3.51%) 37.00 <1.00> (-1.00)
...rc/main/java/io/fabric8/maven/docker/StopMojo.java 50.52% <75.00%> (-9.96%) 21.00 <5.00> (-12.00)
... and 15 more

@sonarcloud
Copy link

sonarcloud bot commented Dec 17, 2020

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 4 Code Smells

84.7% 84.7% Coverage
0.0% 0.0% Duplication

@mabrarov
Copy link
Contributor Author

mabrarov commented Dec 17, 2020

I squashed commits related to the code changes for copy goal. Documentation and additional examples are the only things which are still pending. Though... I feel that unit tests for CopyMojo class could be enhanced too.

@rohanKanojia
Copy link
Member

@mabrarov : polite ping, Could you please rebase your branch against master? Is this PR ready? Do you have some time to add examples / docs ?

@mabrarov
Copy link
Contributor Author

mabrarov commented Mar 7, 2021

@rohanKanojia,

Could you please rebase your branch against master?

Done.

Is this PR ready?

Documentation is missing. It is in progress (was on hold due to the lack of time to work on it). Give me a week to complete this part of the work.

Do you have some time to add examples

This pull request includes it/builder test which itself is a good example. I'm looking to add an example which is different than docker builder pattern, e.g. running tests in container and copying results of tests from container to host (refer to #752). Unfortunately, I cannot promise that I'll be able to add this part of the work soon, i.e. help is appreciated.

@rohanKanojia rohanKanojia added this to the 0.35.0 milestone Mar 7, 2021
@rhuss rhuss added the WIP Work in Progress label Mar 7, 2021
@rhuss
Copy link
Collaborator

rhuss commented Mar 7, 2021

Thanks for the PR ! Unfortunately I don't have much time anymore to help except some sporadic reviews (on a month-based scale), but happy to help to integrate it as I think this covers a potential useful use case.

for (ImageConfiguration imageConfiguration : imageConfigurations) {
CopyConfiguration copyConfiguration = imageConfiguration.getCopyConfiguration();
if (isEmpty(copyConfiguration)) {
continue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should log here too so that user can find out that he/she is not providing CopyConfiguration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added debug log in 1b775a7. It's assumed that it's OK if copy configuration is missing, because user may have multiple images configured but wants to copy just from one of them. Please, let me know if you disagree and want to have info or warn log for this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot. Looks good. I noticed this when I was trying out your PR and didn't configure any copyConfiguration. I was assuming that you implemented it like this:

mvn docker:copy -Ddocker.copy.containerPath=/src -Ddocker.copy.hostDir=/target

But I noticed later that we need to specify copy related configuration in <image>

Copy link
Contributor Author

@mabrarov mabrarov Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still possible with external configuration (check "Activating property configuration externally" section specifically). Here is example for the integration test from this pull request:

mvn -q clean install -DskipTests \
&& mvn -q -f it/builder/builder-image/pom.xml package \
&& mvn -f it/builder/builder-image/pom.xml docker:copy \
     -Ddocker.imagePropertyConfiguration=override \
     -Ddocker.createContainers \
     -Ddocker.copy.entries.1.containerPath=//dmp-it-builder-app.tar.gz \
     -Ddocker.copy.entries.1.hostDirectory=target \
&& tar -tvf it/builder/builder-image/target/dmp-it-builder-app.tar.gz

Expected output looks like:

[INFO] Scanning for projects...
[INFO]
[INFO] ---------< io.fabric8.dmp.itests:dmp-it-builder-builder-image >---------
[INFO] Building dmp-it-builder-builder-image 0.34-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- docker-maven-plugin:0.34-SNAPSHOT:copy (default-cli) @ dmp-it-builder-builder-image ---
[INFO] DOCKER> Global docker.imagePropertyConfiguration=override property activates property configuration for image
[INFO] DOCKER> Copying /dmp-it-builder-app.tar.gz from 050943faf3b8 container into D:\Users\Marat\Documents\work\java\docker-maven-plugin\it\builder\builder-image\target host directory
[INFO] Expanding: C:\Users\Marat\AppData\Local\Temp\docker-copy-7878239238909315602.tar into D:\Users\Marat\Documents\work\java\docker-maven-plugin\it\builder\builder-image\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.996 s
[INFO] Finished at: 2021-03-23T20:42:59+03:00
[INFO] ------------------------------------------------------------------------
-rwxr-xr-x root/root     88976 1970-01-01 03:00 hello

This command:

mvn -f it/builder/builder-image/pom.xml docker:copy \
  -Ddocker.imagePropertyConfiguration=override \
  -Ddocker.createContainers \
  -Ddocker.copy.entries.1.containerPath=//dmp-it-builder-app.tar.gz \
  -Ddocker.copy.entries.1.hostDirectory=target

can be simplified till:

mvn -f it/builder/builder-image/pom.xml docker:copy \
  -Ddocker.imagePropertyConfiguration=override \
  -Ddocker.createContainers \
  -Ddocker.copy.entries..containerPath=//dmp-it-builder-app.tar.gz \
  -Ddocker.copy.entries..hostDirectory=target

Note that I use //dmp-it-builder-app.tar.gz instead of /dmp-it-builder-app.tar.gz, because I use Git Bash on Windows. On Linux you can use /dmp-it-builder-app.tar.gz.

Building of docker image and copying from the built image (from a temporary container created from the built image) can be combined into a single maven run:

mvn -f it/builder/builder-image/pom.xml clean package docker:copy \
  -Ddocker.imagePropertyConfiguration=override \
  -Ddocker.createContainers \
  -Ddocker.copy.entries.1.containerPath=//dmp-it-builder-app.tar.gz \
  -Ddocker.copy.entries.1.hostDirectory=target

You can copy from arbitrary image as well:

$ mvn -f it/builder/builder-image/pom.xml docker:copy \
  -Ddocker.imagePropertyConfiguration=only \
  -Ddocker.name=alpine \
  -Ddocker.createContainers \
  -Ddocker.copy.entries.1.containerPath=//etc/os-release \
  -Ddocker.copy.entries.1.hostDirectory=target \
&& cat it/builder/builder-image/target/os-release
...
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.1
PRETTY_NAME="Alpine Linux v3.12"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, Thanks a lot for your comment. I think it would be nice if we could add all these configuration modes as documentation about docker:copy goal in https://github.com/fabric8io/docker-maven-plugin/tree/master/src/main/asciidoc/inc

Copy link
Contributor Author

@mabrarov mabrarov Mar 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that you still need a POM with configuration of d-m-p having at least one image, because d-m-p external configuration feature can only extend / override that image configuration, but cannot create a new image configuration.
For example, this command doesn't work (doesn't do anything):

$ mvn -f it/builder/pom.xml docker:copy \
  -Ddocker.imagePropertyConfiguration=only \
  -Ddocker.name=alpine \
  -Ddocker.createContainers \
  -Ddocker.copy.entries.1.containerPath=//etc/os-release \
  -Ddocker.copy.entries.1.hostDirectory=target

because the referenced POM - it/builder/pom.xml - has no image configuration for d-m-p.

it/builder/builder-image/.gitignore Show resolved Hide resolved
it/builder/builder-image/CMakeLists.txt Show resolved Hide resolved
@rohanKanojia
Copy link
Member

Hi, I was trying to test copy goal. But somehow I'm not able to get it working. I'm trying with a configuration like this(I copied it from your integration test):

                        <plugin>
                          <groupId>io.fabric8</groupId>
                          <artifactId>docker-maven-plugin</artifactId>
                          <version>0.34-SNAPSHOT</version>
                          <executions>
                            <execution>
                              <id>copy-from-builder</id>
                              <phase>generate-resources</phase>
                              <goals>
                                <goal>start</goal>
                                <goal>copy</goal>
                                <goal>stop</goal>
                              </goals>
                              <configuration>
                                <images>
                                  <image>
                                    <name>busybox:latest</name>
                                    <copy>
                                      <entries>
                                        <entry>
                                          <containerPath>/etc/hostname</containerPath>
                                          <hostDirectory>/home/rohaan/Downloads/</hostDirectory>
                                        </entry>
                                      </entries>
                                    </copy>
                                  </image>
                                </images>
                                <createContainers>true</createContainers>
                              </configuration>
                            </execution>
                          </executions>  
                        </plugin>

I'm trying to copy /etc/hostname file from container to my Downloads folder:

meetup-app : $ docker run -it busybox:latest  /bin/sh
/ # cat /etc/hostname 
53369ce74e83

When I run mvn clean install I can see copy goal being executed. I can also see the file getting created, but the file is empty:

meetup-app : $ ls ~/Downloads/hostname 
/home/rohaan/Downloads/hostname
meetup-app : $ cat ~/Downloads/hostname 

Could you please review and check what I'm doing wrong?

@mabrarov
Copy link
Contributor Author

mabrarov commented Mar 21, 2021

@rohanKanojia,

Regarding your test - there is a chance that /etc/hostname file is empty at the time copy goal is executed, because Docker may modify /etc/hostname file after container start. Could you please provide the full maven project to reproduce the issue you faced? Is it possible to implement some pause after start of container and before invocation of copy goal (like wait option with some timeout)?

<createContainers>true</createContainers>

is definitely wrong (should be removed) because it leads to copy goal creating container before copying from it, instead of using container created by start goal.

@rohanKanojia
Copy link
Member

ohk, It seems to be working after removing <createContainers>true</createContainers> from plugin configuration. Thanks a lot

@rohanKanojia
Copy link
Member

@mabrarov : polite ping, Do you have some time to add docs/sample? If not, I can try submitting a PR to your fork.

@rohanKanojia
Copy link
Member

@mabrarov : I've created a PR for docs+sample: mabrarov#1 . Would appreciate if you could review it. I think we can then proceed with merge.

@mabrarov mabrarov force-pushed the copy_mojo branch 4 times, most recently from 894ac7e to 2cae86d Compare March 31, 2021 00:14
@mabrarov
Copy link
Contributor Author

mabrarov commented Mar 31, 2021

Thanks to @rohanKanojia I was able to complete this PR - documentation and examples are in place now and I consider this PR ready for review and merging. Please note that when I was writing documentation, then I fixed one error and implemented pulling of images when createContainers=true and imagePullPolicy allows (and image is missing) or requires pulling image.

@rohanKanojia
Copy link
Member

@mabrarov: Thanks a lot for your work! Could you please add a line to doc/changelog.md regarding this change? I think we can proceed with merge after that

I'm planning to cut 0.35.0 this week and it would be awesome if this change could make into it.

@mabrarov
Copy link
Contributor Author

Added new copy goal into "doc/changelog.md". Waiting for 0.35.0 release.

@mabrarov
Copy link
Contributor Author

mabrarov commented Mar 31, 2021

@rohanKanojia,

I'm new to GitHub Actions and CircleCI, but it feels like we need to add Windows and Linux tests for (builds with) Maven Wrapper, where mvnw.cmd (Windows) and ./mvnw (Linux) are used instead of mvn, because I found that Maven Wrapper files were broken in this repository.

@rohanKanojia
Copy link
Member

@mabrarov : Hello, sorry for naive question. What's the difference in running maven goals using mvn as compared to these wrappers?

@mabrarov
Copy link
Contributor Author

@rohanKanojia,

There is no difference b/w Maven and Maven Wrapper in terms of execution of goals.

My idea is like this: if we have Maven Wrapper (and we already have it, even without this PR), then it should work. Unfortunately, Maven Wrapper files were broken, which means that either nobody uses Maven Wrapper in this repository or nobody tests Maven Wrapper. Thus we need to either remove (probably unused) Maven Wrapper (which I personally like, because it helps with quick build where you don't need to install anything except JDK) or implement tests for Maven Wrapper. The simplest test for Maven Wrapper is building the project with it :)

@rohanKanojia
Copy link
Member

@mabrarov : I see. I don't have any problem in adding additional Github/CircleCI workflows for fixed maven wrapper. You can go ahead and create a PR for this if you have time. If not, you can create an issue and I'll try to pick it up in the coming holidays.

@mabrarov
Copy link
Contributor Author

mabrarov commented Apr 1, 2021

@rohanKanojia,

Here is the new feature request about Maven Wrapper: #1450

@rohanKanojia
Copy link
Member

@mabrarov : I've created #1451 for adding github action workflows for maven wrappers. Would appreciate if you could review it..

@rohanKanojia
Copy link
Member

@mabrarov : Thanks a lot for your PR! Could you please resolve this minor conflict? I think we can proceed with merge then

mabrarov and others added 4 commits April 2, 2021 01:04
Signed-off-by: Marat Abrarov <abrarov@gmail.com>
Signed-off-by: Marat Abrarov <abrarov@gmail.com>
+ Added Docs for `docker:copy`
+ Added a `copy-from-container` sample which contains profiles for
  copying file and directory to localhost from container

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
…l documentation

Signed-off-by: Marat Abrarov <abrarov@gmail.com>
@mabrarov mabrarov force-pushed the copy_mojo branch 3 times, most recently from 1730cf5 to 78fe4c9 Compare April 1, 2021 22:33
Signed-off-by: Marat Abrarov <abrarov@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Need capability to copy files from running container to host
3 participants