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

Fix cwd in Linux docker images #410

Merged
merged 6 commits into from
Jul 22, 2020

Conversation

YannickJadoul
Copy link
Member

Closes #409

@YannickJadoul YannickJadoul force-pushed the fix-pwd-linux-docker branch 3 times, most recently from b945b54 to a400aa3 Compare July 19, 2020 23:26
@YannickJadoul
Copy link
Member Author

YannickJadoul commented Jul 19, 2020

Think we're almost there. Questions left:

  • Is this fine, adding cwd to the constructor, or should we add cwd to each docker.call?
  • More tests? Maybe CIBW_BEFORE_ALL as well? And anything else to test?
  • Is there a better way of adding this test? We could just add another test function to test_before_build and not go through Python? Also, can we compare stored_cwd to something else for Windows/macOS?

@YannickJadoul
Copy link
Member Author

Broken because this issue is fixed, but #411 isn't.

test_overridden_path's 'CIBW_BEFORE_ALL': 'mkdir new_path && touch new_path/python && chmod +x new_path/python' is now also evaluated from /project, but $(pwd) in ``'CIBW_ENVIRONMENT': '''PATH="$(pwd)/new_path:$PATH"'''is not interpolated correctly, so/new_path` does not contain `python`, so the Python executable on `PATH` is not overwritten.

I'll rebase onto #411.

@YannickJadoul
Copy link
Member Author

(rebased after merge of #411)

Copy link
Contributor

@joerick joerick left a comment

Choose a reason for hiding this comment

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

Thanks again for looking at these fixes, as I don't have time just at the moment!

Comment on lines +113 to +114
with DockerContainer(docker_image, simulate_32_bit=platform_tag.endswith('i686'), cwd='/project') as docker:
docker.copy_into(Path.cwd(), PurePath('/project'))
Copy link
Contributor

Choose a reason for hiding this comment

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

Setting cwd to /project in the constructor feels a little strange, because I don't think /project has been created yet. I suppose Docker must create it if it's not there. But doesn't feel right to me. I think a more familar approach might be to have docker.chdir(PurePath('/project')) after the project is copied over.

The cwd can be stored in DockerContainer as an ivar, and used whenever call() is called without a cwd. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

Docker does document that passing -w will create the directory: https://docs.docker.com/engine/reference/commandline/create/#options

For the DockerContainer, I thought of it as just setting the "default directory" during the with-statement, and just adding an exception if necessary. And also that we then couldn't forget it, later.

But yes, chdir would also work, if you prefer that. I hadn't thought of that option. I guess we don't even need to store it, but could just cd, rather than storing it as an attribute?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, that's good that's it's documented. Then I think either approach is valid, actually. Happy to leave it as-is.

Copy link
Member Author

Choose a reason for hiding this comment

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

Given that we don't have a os.chdir for macOS or Windows (and just use the working directory that's there at the start of cibuildwheel/build), I think the current approach might match better. But I'm happy changing it as well, if you prefer. I like the suggested chdir method as well (and we might end up needing it at some later point?). Your call!

@Czaki, any input on this? Do you prefer with DockerContainer(..., cwd='/project'): or with DockerContainer(...) as docker: docker.chdir('/project')?

Copy link
Contributor

@Czaki Czaki Jul 21, 2020

Choose a reason for hiding this comment

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

I prefer with DockerContainer(..., cwd='/project'): and change second argument of

def copy_into(self, from_path: Path, to_path: Optional[PurePath]=none)
    if to_path is None:
        to_path = self.cwd
    ...

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, that's an interesting suggestion. I'll add that a as extra commit. If @joerick doesn't like it, it can just be removed before merging!

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, that's not possible, @Czaki, because self.cwd can also be None. Do you suggest any way to fix it, or should we just keep to_path in copy_into mandatory?

Copy link
Contributor

Choose a reason for hiding this comment

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

Raise exception with information that cwd should be set or to_path.
I suggest this to reduce number of places where path is provided as literal.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, possible, but ... it's still used in a lot of places, like format(..., project='/project', ...), so doing this won't solve that all?

Comment on lines 27 to 32

if sys.platform == 'linux':
cwd_file = '/tmp/cwd.txt'
with open(cwd_file) as f:
stored_cwd = f.read()
assert stored_cwd == '/project'
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this is missing a mac and windows test. Also, it might be a bit Rube Goldberg - could you instead assert os.getcwd() == '/project'? And in BEFORE_ALL, do the same?

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like this is missing a mac and windows test.

Well, yes, but I didn't know what directory they're supposed to be executed from? As far as I know, it will depend on the CI; probably somewhere in the home directory or a subdirectory?

Also, it might be a bit Rube Goldberg - could you instead assert os.getcwd() == '/project'?

Nope, that's not working. The tests are actually executed from a different directory, and we want to test CIBW_BEFORE_BUILD is executed from the right directory. Or do you mean to python -c "import os; os.getcwd() == '/project'" in CIBW_BEFORE_BUILD?

And in BEFORE_ALL, do the same?

Yes, will do. But I'll wait until the above gets settled.

Copy link
Contributor

Choose a reason for hiding this comment

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

Or do you mean to python -c "import os; os.getcwd() == '/project'" in CIBW_BEFORE_BUILD?

Yeah, that's what I was thinking, I suppose it'd be something like...

{
   'CIBW_BEFORE_BUILD': f'''python -c "import os; assert os.getcwd() == {os.getcwd()!r}"''',
   'CIBW_BEFORE_ALL': f'''python -c "import os; assert os.getcwd() == {os.getcwd()!r}"''',
   'CIBW_BEFORE_BUILD_LINUX': '''python -c "import os; assert os.getcwd() == '/project'"''',
   'CIBW_BEFORE_ALL_LINUX': '''python -c "import os; assert os.getcwd() == '/project'"''',
}

Choose a reason for hiding this comment

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

Windows on GH Actions uses /d/a/bls-signatures/bls-signatures which is the repo name twice: https://github.com/Chia-Network/bls-signatures/runs/887873992?check_suite_focus=true#step:10:60

Mac is /Users/runner/work/bls-signatures/bls-signatures/ see: https://github.com/Chia-Network/bls-signatures/runs/887873983?check_suite_focus=true#step:11:535

Copy link
Member Author

Choose a reason for hiding this comment

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

Windows on GH Actions uses /d/a/bls-signatures/bls-signatures which is the repo name twice: https://github.com/Chia-Network/bls-signatures/runs/887873992?check_suite_focus=true#step:10:60

Mac is /Users/runner/work/bls-signatures/bls-signatures/ see: https://github.com/Chia-Network/bls-signatures/runs/887873983?check_suite_focus=true#step:11:535

Thanks, but that's different from every CI and every project, even (since it contains the project name), so that doesn't seem feasible to distinguish. Let me try @joerick's plan (maybe with __file__ rather than getcwd?) :-)

Copy link
Member Author

@YannickJadoul YannickJadoul Jul 21, 2020

Choose a reason for hiding this comment

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

OK, like this?

I added a test that checks whether a failing CIBW_BEFORE_BUILD and CIBW_BEFORE_ALL also fail the whole run.

@YannickJadoul YannickJadoul force-pushed the fix-pwd-linux-docker branch 6 times, most recently from 26608a5 to f4578eb Compare July 21, 2020 17:55
@YannickJadoul
Copy link
Member Author

Alright. Next round of review! :-)

Slightly worrying note: we're now at 58 and 59 minutes on Azure Pipelines, for the tests on Windows (one of the two jobs actually timed out before I restarted it) :-/ Not sure why Windows (or the Windows infrastructure at Azure) is twice as slow as Linux...

@Czaki
Copy link
Contributor

Czaki commented Jul 21, 2020

Slightly worrying note: we're now at 58 and 59 minutes on Azure Pipelines, for the tests on Windows (one of the two jobs actually timed out before I restarted it) :-/ Not sure why Windows (or the Windows infrastructure at Azure) is twice as slow as Linux...

Maybe use timeoutInMinutes: 180 ?

I also observe in my projects that windows is much slower.

@YannickJadoul
Copy link
Member Author

Maybe use timeoutInMinutes: 180 ?

I also observe in my projects that windows is much slower.

Alright, thanks! But it's still a bit worrying and very slow to wait for, so ... maybe only a temporary solution :-/

@Czaki
Copy link
Contributor

Czaki commented Jul 21, 2020

on github acrions and in azure pipelines there is big amount of available workers. Cannot we split tests on two workers?

@YannickJadoul
Copy link
Member Author

Yes, maybe. But that feels like a huge mess, as well :-(

@Czaki
Copy link
Contributor

Czaki commented Jul 21, 2020

How it looks in my project:
obraz

https://stackoverflow.com/questions/10150881/why-is-python-so-much-slower-on-windows

Looks like problems with creating multiple process, antivirus, etc, which create bad performance in this case because of multiple spawning of new python using subprocess.

Maybe pytest-xdist?

@YannickJadoul
Copy link
Member Author

Maybe pytest-xdist?

I don't know anything about that, but let's discuss in #412 :-)

Copy link
Contributor

@joerick joerick left a comment

Choose a reason for hiding this comment

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

Looks good to me! Weird about the Windows test times, but it can't be related to this PR.

@YannickJadoul YannickJadoul merged commit 3cd3a9d into pypa:master Jul 22, 2020
@YannickJadoul YannickJadoul deleted the fix-pwd-linux-docker branch July 22, 2020 12:41
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.

The "/project/" path isn't there anymore for Linux in version 1.5.3
4 participants