Skip to content

Fix windows path handling in podman cp #25701

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

Merged

Conversation

danegsta
Copy link
Contributor

@danegsta danegsta commented Mar 27, 2025

This PR fixes a handful of Windows path bugs in podman container cp that prevented copying files from (or to) a Windows host.

  • The Windows drive letter was being treated as a container ID/name, which is fixed by using filepath.IsAbs to determine if a given path is an absolute path on the system (on Windows, this is true for paths starting with a single drive letter and a colon).
  • The code used / as the root folder path, even on Windows (should be <drive letter>:\ (i.e. C:\), which caused copier to reject the given path. This was fixed by depending on the behavior of filepath.VolumeName and os.PathSeparator to build the correct root path for a given OS.
  • There was logic that was hardcoded to use / as the path separator rather than os.PathSeparator which caused path normalization to fail. Fixed by using the os specific separator.
  • There was a bug (now fixed) in the copier package in containers/buildah that would cause an infinite loop when trying to process files from a Windows path. I updated the vendored dependency to the latest version of buildah.
  • Some methods in cp.go used filepath for parsing paths within containers, which causes issues on Windows. Switched to using path for processing paths within containers to force Linux style conventions.

I also refactored the e2e test coverage that was added for podman container cp (moved the existing test from basic_test.go to cp_test.go alongside the podman machine cp test coverage) and added a few new test cases.

Does this PR introduce a user-facing change?

None

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from 6a95cf4 to a75e784 Compare March 27, 2025 01:25
@danegsta danegsta changed the title Fix windows path handling in docker cp Fix windows path handling in podman cp Mar 27, 2025
Copy link

[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore.

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from a75e784 to d4bd413 Compare March 27, 2025 01:36
@danegsta
Copy link
Contributor Author

[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore.

I’d accidentally downgraded github.com/containers/common when rebasing my work on main; fixed the issue in my latest push.

@l0rd
Copy link
Member

l0rd commented Mar 27, 2025

@danegsta thank you! I believe changes to go.mod and the vendor folder should not be part of this PR.

@Luap99
Copy link
Member

Luap99 commented Mar 27, 2025

@flouthoc new buildah tests seems broken when run with podman build, can you take a look?

@Luap99
Copy link
Member

Luap99 commented Mar 27, 2025

@danegsta thank you! I believe changes to go.mod and the vendor folder should not be part of this PR.

AFAICT this depends on the buildah bump due the bug fix in the copier package so the bump here should be fine.
That said generally I prefer if the vendor bump is a separate commit to make the actual podman changes easier to review.

@danegsta
Copy link
Contributor Author

@danegsta thank you! I believe changes to go.mod and the vendor folder should not be part of this PR.

AFAICT this depends on the buildah bump due the bug fix in the copier package so the bump here should be fine. That said generally I prefer if the vendor bump is a separate commit to make the actual podman changes easier to review.

Yes, the bug fix in the copier package needs to be picked up via upgraded buildah version before the fixes to the cp command can be made (otherwise with the original version of buildah the command will get stuck in an infinite loop while trying to resolve the files to be copied).

Would you prefer an entirely separate PR for the buildah version update or should I restructure this PR into two separate commits?

@flouthoc
Copy link
Collaborator

@Luap99 The new test which I added at buildah containers/buildah#6087 expects 128 to be the exit code but it seems buildah-tests.diff overrides it with 125 here https://github.com/containers/podman/blob/main/test/buildah-bud/buildah-tests.diff#L118

I can add another hack in buildah-tests.diff for this test or I can fix in buildah to return 125 in case of error, fixing this at buildah end is more suitable i guess. WDYT ?

@Luap99
Copy link
Member

Luap99 commented Mar 27, 2025

I can add another hack in buildah-tests.diff for this test or I can fix in buildah to return 125 in case of error, fixing this at buildah end is more suitable i guess. WDYT ?

I don't think 128 is a particular great exit code. 125 seems to better for consistency with other errors so I would think this in buildah if that is easy.

@Luap99
Copy link
Member

Luap99 commented Mar 27, 2025

@flouthoc Note there is also a second issue:

[+0848s] not ok 426 build-with-timestamp-applies-to-oci-archive
[+0848s] # (from function `die' in file tests/helpers.bash, line 523,
[+0848s] #  from function `run_buildah' in file tests/helpers.bash, line 510,
[+0848s] #  in test file tests/bud.bats, line 7494)
[+0848s] #   `run_buildah build -f <(echo 'FROM scratch') --tag=oci-archive:${outpath}.a --timestamp 0' failed
[+0848s] # /var/tmp/go/src/github.com/containers/podman/test-buildah-v1.39.1-0.20250326204000-898fbb2d25c6/tests /var/tmp/go/src/github.com/containers/podman/test-buildah-v1.39.1-0.20250326204000-898fbb2d25c6
[+0848s] # # /var/tmp/go/src/github.com/containers/podman/bin/podman --root /var/tmp/buildah_tests.gseiis/root --runroot /var/tmp/buildah_tests.gseiis/runroot --storage-driver vfs --registries-conf /var/tmp/go/src/github.com/containers/podman/test-buildah-v1.39.1-0.20250326204000-898fbb2d25c6/tests/registries.conf system service [...] unix:///run/podman/podman-426.sock
[+0848s] # # podman-remote build --force-rm=false --layers=false -f /dev/fd/63 --tag=oci-archive:/var/tmp/buildah_tests.gseiis/timestamp-oci.tar.a --timestamp 0
[+0848s] # time="2025-03-27T04:59:20-05:00" level=error msg="1 error occurred:\n\t* readlink /proc/180077/fd/8: no such file or directory\n\n\n"
[+0848s] # Error: Post "http://d/v5.5.0/libpod/build?compatvolumes=0&dockerfile=%5B%2263%22%5D&httpproxy=1&identitylabel=1&idmappingoptions=%7B%22HostUIDMapping%22%3Atrue%2C%22HostGIDMapping%22%3Atrue%2C%22UIDMap%22%3A%5B%5D%2C%22GIDMap%22%3A%5B%5D%2C%22AutoUserNs%22%3Afalse%2C%22AutoUserNsOpts%22%3A%7B%22Size%22%3A0%2C%22InitialSize%22%3A0%2C%22PasswdFile%22%3A%22%22%2C%22GroupFile%22%3A%22%22%2C%22AdditionalUIDMappings%22%3Anull%2C%22AdditionalGIDMappings%22%3Anull%7D%7D&isolation=0&jobs=1&networkmode=0&nsoptions=%5B%7B%22Name%22%3A%22user%22%2C%22Host%22%3Atrue%2C%22Path%22%3A%22%22%7D%5D&omithistory=0&output=oci-archive%3A%2Fvar%2Ftmp%2Fbuildah_tests.gseiis%2Ftimestamp-oci.tar.a&outputformat=application%2Fvnd.oci.image.manifest.v1%2Bjson&pullpolicy=missing&retry=3&retry-delay=2s&rm=1&seccomp=%2Fusr%2Fshare%2Fcontainers%2Fseccomp.json&shmsize=204800&t=oci-archive%3A%2Fvar%2Ftmp%2Fbuildah_tests.gseiis%2Ftimestamp-oci.tar.a&timestamp=0": io: read/write on closed pipe
[+0848s] # [ rc=125 (** EXPECTED 0 **) ]
[+0848s] # #/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
[+0848s] # #| FAIL: exit code is 125; expected 0
[+0848s] # #\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[+0848s] # teardown: stopping podman server 180008

@danegsta
Copy link
Contributor Author

@Luap99 it sounds like additional changes need to make it into buildah before it can be updated. Seems like it probably makes more sense to have a separate PR for updating buildah.

I’ll break this PR up into separate commits for the podman and buildah changes (so that it can be reviewed in the meantime), but once buildah is updated independently I’ll undo my go.mod and vendor changes and rebase off of main.

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from d4bd413 to e22eb88 Compare March 27, 2025 17:21
@Luap99
Copy link
Member

Luap99 commented Mar 27, 2025

but once buildah is updated independently I’ll undo my go.mod and vendor changes and rebase off of main.

Sounds good.

@flouthoc
Copy link
Collaborator

@flouthoc new buildah tests seems broken when run with podman build, can you take a look?

Created a PR for first one containers/buildah#6092

and for second test build-with-timestamp-applies-to-oci-archive needs to be skipped at remote because compat API does not support tags to oci-archive , infact API does not knows yet how to handle cases where no tags is produced.

@danegsta
Copy link
Contributor Author

Looks like #14862 should be fixed by this PR.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 1, 2025
@danegsta
Copy link
Contributor Author

danegsta commented Apr 1, 2025

@flouthoc looks like containers/buildah#6092 was merged; I've opened #25756 to bump the vendored buildah version to the latest commit from main.

I'll rebase this PR with only the cp command changes once that PR gets merged.

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from c2e009d to 30459f5 Compare April 2, 2025 00:32
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 2, 2025
@danegsta
Copy link
Contributor Author

danegsta commented Apr 2, 2025

Rebased on main with just the podman cp fixes now that buildah has been updated.

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from 30459f5 to 9db4139 Compare April 2, 2025 19:09
@danegsta danegsta force-pushed the danegsta/windowsCpPath branch 2 times, most recently from 9216c7f to da81e28 Compare April 7, 2025 17:20
@danegsta
Copy link
Contributor Author

danegsta commented Apr 7, 2025

Rebased on latest main

@danegsta
Copy link
Contributor Author

danegsta commented Apr 7, 2025

/retest

Copy link
Contributor

openshift-ci bot commented Apr 7, 2025

@danegsta: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@danegsta
Copy link
Contributor Author

danegsta commented Apr 8, 2025

@Luap99 did you have any other concerns with the PR? I wanted to make sure this doesn't fall off the radar.

There's one failing test, but it seems like it should be a flaky test as I've rebased a couple times and it seems that a different random test fails each time the tests restart (also the current failing test doesn't look like it should be hitting any of the code changed in this PR).

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

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

Some comments on the test, sorry I should have looked closer before.

Overall I don't use windows so I am not the best person to review/understand the code but it makes sense to me at least. @l0rd Can you do a review here?

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from da81e28 to 24d7eaf Compare April 8, 2025 18:17
Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

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

LGTM, thank you
@l0rd PTAL

Copy link
Contributor

openshift-ci bot commented Apr 8, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: danegsta, Luap99

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 8, 2025
@l0rd
Copy link
Member

l0rd commented Apr 8, 2025

@danegsta one test is failing on both WSL and Hyper-V:

STEP: copy from host to container by name - C:/Users/Administrator/AppData/Local/cirrus-ci-build/repo[/pkg/machine/e2e/cp_test.go:110](https://github.com/containers/podman/blob/24d7eaf6879059239b17ee593015ee1e3cb4aea9/pkg/machine/e2e/cp_test.go#L110) @ 04/08/25 18:32:23.41
  C> podman.exe -r cp Z:\ginkgo1275841403\foo.txt podman-cp-test:/tmp/rename.txt
  Error: "/tmp/rename.txt" could not be found on container podman-cp-test: no such file or directory

  [FAILED] Expected
      <int>: 125
  to match exit code:
      <int>: 0
  In [It] at: C:/Users/Administrator/AppData/Local/cirrus-ci-build/repo[/pkg/machine/e2e/cp_test.go:114](https://github.com/containers/podman/blob/24d7eaf6879059239b17ee593015ee1e3cb4aea9/pkg/machine/e2e/cp_test.go#L114) @ 04/08/25 18:32:23.691

  Full Stack Trace
    github.com/containers/podman/v5/pkg/machine/e2e_test.init.func8.1()
    	C:/Users/Administrator/AppData/Local/cirrus-ci-build/repo[/pkg/machine/e2e/cp_test.go:114](https://github.com/containers/podman/blob/24d7eaf6879059239b17ee593015ee1e3cb4aea9/pkg/machine/e2e/cp_test.go#L114) +0x1f22

I don't think this is a bug introduced by this PR though. You can either file a new issue and update this PR to skip that particular test on Windows or try to fix it in this PR.

You can reproduce the error running the tests locally on Windows:

./winmake localmachine "cp_test.go"

@l0rd
Copy link
Member

l0rd commented Apr 8, 2025

There's one failing test, but it seems like it should be a flaky test as I've rebased a couple times and it seems that a different random test fails each time the tests restart (also the current failing test doesn't look like it should be hitting any of the code changed in this PR).

Yes this is annoying. I have been there too. Don't hesitate to ask us to re-run a specific test when it happens again.

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from 24d7eaf to 313f5bb Compare April 8, 2025 21:51
@danegsta
Copy link
Contributor Author

danegsta commented Apr 8, 2025

I don't think this is a bug introduced by this PR though. You can either file a new issue and update this PR to skip that particular test on Windows or try to fix it in this PR.

This is what I get for updating my test cases for a Windows focused PR on a Mac. The new failing test was a pretty easy fix; containerParentDir was using filepath to parse container specific paths when it should probably be using path to force Linux style path handling.

Edit: just took a closer look and this seems to be a problem in a few other places in cp.go. I'm going to try and fix them and add additional test coverage for container to container copy.

@danegsta danegsta force-pushed the danegsta/windowsCpPath branch from 313f5bb to 9a723ff Compare April 8, 2025 22:23
@l0rd
Copy link
Member

l0rd commented Apr 9, 2025

Tests are green. Great job, @danegsta.

About your last change: it's usually preferable to use path/filepath rather than path for manipulating file paths. However container paths must be consistent across OSes (using forward slashes, even when the code is run on Windows) and using path should be okay in this case. cc @Luap99

/lgtm
/hold

@openshift-ci openshift-ci bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 9, 2025
@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Apr 9, 2025
@l0rd
Copy link
Member

l0rd commented Apr 10, 2025

/unhold

@openshift-ci openshift-ci bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 10, 2025
@openshift-merge-bot openshift-merge-bot bot merged commit 48423a6 into containers:main Apr 10, 2025
81 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. machine release-note-none
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants