From f417a91a57118d80113983cea9e8a299d617f776 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sat, 8 Sep 2018 23:51:39 +0200 Subject: [PATCH 1/6] First try at getting rid of timeout logic in Linux docker handling, by swapping splitting docker run into create and start --- cibuildwheel/linux.py | 81 ++++++++++--------------------------------- 1 file changed, 18 insertions(+), 63 deletions(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 662d552d..ed81d5f8 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -1,20 +1,14 @@ from __future__ import print_function -import os, subprocess, sys, time, uuid +import os, subprocess, sys, uuid from collections import namedtuple from .util import prepare_command, get_build_verbosity_extra_flags -import monotonic - try: from shlex import quote as shlex_quote except ImportError: from pipes import quote as shlex_quote -class DockerRunTimeoutError(Exception): - pass - - def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment, manylinux1_images): try: subprocess.check_call(['docker', '--version']) @@ -129,72 +123,33 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be gid=os.getgid(), ) + def run_docker(*args): + print('docker command: docker {}'.format(' '.join(map(shlex_quote, args)))) + return subprocess.check_call(['docker'] + list(args)) + container_name = 'cibuildwheel-{}'.format(uuid.uuid4()) + run_docker('create', + '--env', 'CIBUILDWHEEL', + '--name', container_name, + '-i', + '-v', '/:/host', # ignored on Circle + docker_image, '/bin/bash') - command = [ - 'docker', - 'run', - '--env', - 'CIBUILDWHEEL', - '--name', container_name, - '-i', - '-v', '/:/host', # ignored on Circle - docker_image, - '/bin/bash', - ] - print('docker command: {}'.format(command)) - docker_process = subprocess.Popen( - command, - stdin=subprocess.PIPE, - universal_newlines=True, - ) - - # It will take a bit for docker to get the container up and - # running. Keep trying to copy in the project directory until - # it succeeds. There is a timeout to avoid spinning forever. - - timeout = 180 - start = monotonic.monotonic() - while True: - time.sleep(1) - command = [ - 'docker', - 'cp', - '{}/.'.format(os.path.abspath(project_dir)), - '{}:/project'.format(container_name), - ] - print('docker command: {}'.format(command)) - if subprocess.call(command) == 0: - break - - if monotonic.monotonic() - start > timeout: - raise DockerRunTimeoutError( - 'Unable to successfully copy project directory' - ' within {} seconds'.format(timeout) - ) + abs_project_dir = os.path.abspath(project_dir) + run_docker('cp', abs_project_dir + '/.', container_name + ':/project') + docker_process = subprocess.Popen(['docker', 'start', '-i', '-a', container_name], + stdin=subprocess.PIPE, universal_newlines=True) try: docker_process.communicate(bash_script) except KeyboardInterrupt: docker_process.kill() docker_process.wait() - command = [ - 'docker', - 'cp', - '{}:/output/.'.format(container_name), - os.path.abspath(output_dir), - ] - print('docker command: {}'.format(command)) - subprocess.check_call(command) + abs_output_dir = os.path.abspath(output_dir) + run_docker('cp', container_name + ':/output/.', abs_output_dir) - command = [ - 'docker', - 'rm', - '-v', container_name, - ] - print('docker command: {}'.format(command)) - subprocess.check_call(command) + run_docker('rm', '-v', container_name) if docker_process.returncode != 0: exit(1) From fcf1e9cd84959f33b348ef8345e7c8d8ae926b1c Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 9 Sep 2018 01:13:13 +0200 Subject: [PATCH 2/6] Moving stdin communication with docker to run_docker function --- cibuildwheel/linux.py | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index ed81d5f8..2978ff50 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -123,9 +123,19 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be gid=os.getgid(), ) - def run_docker(*args): + def run_docker(*args, stdin_str=None): print('docker command: docker {}'.format(' '.join(map(shlex_quote, args)))) - return subprocess.check_call(['docker'] + list(args)) + if stdin_str is None: + return subprocess.check_call(['docker'] + list(args)) + else: + process = subprocess.Popen(['docker'] + list(args), + stdin=subprocess.PIPE, universal_newlines=True) + try: + process.communicate(stdin_str) + except KeyboardInterrupt: + process.kill() + process.wait() + return process.returncode container_name = 'cibuildwheel-{}'.format(uuid.uuid4()) run_docker('create', @@ -134,22 +144,10 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be '-i', '-v', '/:/host', # ignored on Circle docker_image, '/bin/bash') - - abs_project_dir = os.path.abspath(project_dir) - run_docker('cp', abs_project_dir + '/.', container_name + ':/project') - - docker_process = subprocess.Popen(['docker', 'start', '-i', '-a', container_name], - stdin=subprocess.PIPE, universal_newlines=True) - try: - docker_process.communicate(bash_script) - except KeyboardInterrupt: - docker_process.kill() - docker_process.wait() - - abs_output_dir = os.path.abspath(output_dir) - run_docker('cp', container_name + ':/output/.', abs_output_dir) - + run_docker('cp', os.path.abspath(project_dir) + '/.', container_name + ':/project') + script_returncode = run_docker('start', '-i', '-a', container_name, stdin_str=bash_script) + run_docker('cp', container_name + ':/output/.', os.path.abspath(output_dir)) run_docker('rm', '-v', container_name) - if docker_process.returncode != 0: + if script_returncode != 0: exit(1) From d4885fe44a4b7419196d00b99c6adaf936869b07 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 9 Sep 2018 01:18:59 +0200 Subject: [PATCH 3/6] Fixing outdated Python 2 syntax error --- cibuildwheel/linux.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 2978ff50..387554e9 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -123,12 +123,12 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be gid=os.getgid(), ) - def run_docker(*args, stdin_str=None): - print('docker command: docker {}'.format(' '.join(map(shlex_quote, args)))) + def run_docker(command, stdin_str=None): + print('docker command: docker {}'.format(' '.join(map(shlex_quote, command)))) if stdin_str is None: - return subprocess.check_call(['docker'] + list(args)) + return subprocess.check_call(['docker'] + command) else: - process = subprocess.Popen(['docker'] + list(args), + process = subprocess.Popen(['docker'] + command, stdin=subprocess.PIPE, universal_newlines=True) try: process.communicate(stdin_str) @@ -138,16 +138,16 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be return process.returncode container_name = 'cibuildwheel-{}'.format(uuid.uuid4()) - run_docker('create', - '--env', 'CIBUILDWHEEL', - '--name', container_name, - '-i', - '-v', '/:/host', # ignored on Circle - docker_image, '/bin/bash') - run_docker('cp', os.path.abspath(project_dir) + '/.', container_name + ':/project') - script_returncode = run_docker('start', '-i', '-a', container_name, stdin_str=bash_script) - run_docker('cp', container_name + ':/output/.', os.path.abspath(output_dir)) - run_docker('rm', '-v', container_name) + run_docker(['create', + '--env', 'CIBUILDWHEEL', + '--name', container_name, + '-i', + '-v', '/:/host', # ignored on Circle + docker_image, '/bin/bash']) + run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project']) + script_returncode = run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script) + run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)]) + run_docker(['rm', '-v', container_name]) if script_returncode != 0: exit(1) From 4cc09a35b48bd5bdc541868db378f3ef68bd5aba Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 9 Sep 2018 01:20:31 +0200 Subject: [PATCH 4/6] Removing monotonic from dependencies (until necessary again) --- setup.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/setup.py b/setup.py index d906564e..11002a93 100644 --- a/setup.py +++ b/setup.py @@ -9,10 +9,7 @@ except ImportError: setup( name='cibuildwheel', version='0.9.4', - install_requires=[ - 'bashlex', - 'monotonic', - ], + install_requires=['bashlex'], description="Build Python wheels on CI with minimal configuration.", long_description='For readme please see http://github.com/joerick/cibuildwheel', author="Joe Rickerby", From b64770a56075719aee09924b02d57c6100992066 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 9 Sep 2018 16:11:42 +0200 Subject: [PATCH 5/6] Cleaning up use of run_docker and removing some debug output --- cibuildwheel/linux.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 387554e9..a6f5bc98 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -67,12 +67,6 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be PATH="$PYBIN:$PATH" sh -c {before_build} fi - pwd - ls -l . - ls -l /project - ls -l /output - ls -l /host - # Build that wheel PATH="$PYBIN:$PATH" "$PYBIN/pip" wheel . -w /tmp/built_wheel --no-deps {build_verbosity_flag} built_wheel=(/tmp/built_wheel/*.whl) @@ -126,7 +120,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be def run_docker(command, stdin_str=None): print('docker command: docker {}'.format(' '.join(map(shlex_quote, command)))) if stdin_str is None: - return subprocess.check_call(['docker'] + command) + subprocess.check_call(['docker'] + command) else: process = subprocess.Popen(['docker'] + command, stdin=subprocess.PIPE, universal_newlines=True) @@ -135,19 +129,22 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be except KeyboardInterrupt: process.kill() process.wait() - return process.returncode + if process.returncode != 0: + raise subprocess.CalledProcessError(process.returncode, process.args) container_name = 'cibuildwheel-{}'.format(uuid.uuid4()) - run_docker(['create', - '--env', 'CIBUILDWHEEL', - '--name', container_name, - '-i', - '-v', '/:/host', # ignored on Circle - docker_image, '/bin/bash']) - run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project']) - script_returncode = run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script) - run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)]) - run_docker(['rm', '-v', container_name]) - - if script_returncode != 0: + try: + run_docker(['create', + '--env', 'CIBUILDWHEEL', + '--name', container_name, + '-i', + '-v', '/:/host', # ignored on Circle + docker_image, '/bin/bash']) + run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project']) + run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script) + run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)]) + except subprocess.CalledProcessError: exit(1) + finally: + # Still gets executed, even when 'exit(1)' gets called + run_docker(['rm', '-v', container_name]) From 1dbda7af7eed7f12d124fdc07e2cdafa0b8f85b0 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Wed, 12 Sep 2018 11:52:41 +0200 Subject: [PATCH 6/6] Add '--force' to 'docker rm' command in Linux builds --- cibuildwheel/linux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index a6f5bc98..a3eb19f9 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -147,4 +147,4 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be exit(1) finally: # Still gets executed, even when 'exit(1)' gets called - run_docker(['rm', '-v', container_name]) + run_docker(['rm', '--force', '-v', container_name])