From 6a44fbf4fb533d603bfeb18868d0701ffa239726 Mon Sep 17 00:00:00 2001 From: David Sanchez Date: Tue, 30 Apr 2024 16:35:22 +0200 Subject: [PATCH] wip --- conan/cli/commands/create.py | 18 ++- conan/internal/runner/docker.py | 31 ++---- .../test/integration/command/runner_test.py | 104 ++++-------------- 3 files changed, 45 insertions(+), 108 deletions(-) diff --git a/conan/cli/commands/create.py b/conan/cli/commands/create.py index 81ffa5801d2..1cbf26bc350 100644 --- a/conan/cli/commands/create.py +++ b/conan/cli/commands/create.py @@ -67,11 +67,19 @@ def create(conan_api, parser, *args): print_profiles(profile_host, profile_build) if profile_host.runner and not os.environ.get("CONAN_RUNNER_ENVIRONMENT"): - return { - 'docker': DockerRunner, - 'ssh': SSHRunner, - 'wsl': WSLRunner, - }[profile_host.runner.get('type')](conan_api, 'create', profile_host, profile_build, args, raw_args).run() + try: + runner_type = profile_host.runner['type'] + except KeyError: + raise ConanException(f"Invalid runner configuration. 'type' must be defined") + try: + runner_instance = { + 'docker': DockerRunner, + 'ssh': SSHRunner, + 'wsl': WSLRunner, + }[runner_type] + except KeyError: + raise ConanException(f"Invalid runner type '{runner_type}'. Allowed values: 'docker' 'ssh' 'wsl'") + return runner_instance(conan_api, 'create', profile_host, profile_build, args, raw_args).run() if args.build is not None and args.build_test is None: args.build_test = args.build diff --git a/conan/internal/runner/docker.py b/conan/internal/runner/docker.py index 333a774b5c6..c6db6b4b003 100644 --- a/conan/internal/runner/docker.py +++ b/conan/internal/runner/docker.py @@ -51,7 +51,7 @@ def _instans_or_error(value, obj): ) -def docker_info(msg, error=False): +def _docker_info(msg, error=False): fg=Color.BRIGHT_MAGENTA if error: fg=Color.BRIGHT_RED @@ -60,15 +60,6 @@ def docker_info(msg, error=False): ConanOutput().status('└'+'─'*(2+len(msg))+'┘\n', fg=fg) -def list_patterns(cache_info): - _pattern = [] - for reference, info in cache_info.items(): - for revisions in info.get('revisions', {}).values(): - for package in revisions.get('packages').keys(): - _pattern.append(f'{reference}:{package}') - return _pattern - - class DockerRunner: def __init__(self, conan_api, command, host_profile, build_profile, args, raw_args): import docker @@ -80,7 +71,7 @@ def __init__(self, conan_api, command, host_profile, build_profile, args, raw_ar except: raise ConanException("Docker Client failed to initialize." "\n - Check if docker is installed and running" - "\n - Run 'pip install docker>=5.0.0, <=5.0.3'") + "\n - Run 'pip install pip install conan[runners]'") self.conan_api = conan_api self.build_profile = build_profile self.args = args @@ -125,13 +116,13 @@ def run(self): run conan inside a Docker continer """ if self.dockerfile: - docker_info(f'Building the Docker image: {self.image}') + _docker_info(f'Building the Docker image: {self.image}') self.build_image() volumes, environment = self.create_runner_environment() error = False try: if self.docker_client.containers.list(all=True, filters={'name': self.name}): - docker_info('Starting the docker container') + _docker_info('Starting the docker container') self.container = self.docker_client.containers.get(self.name) self.container.start() else: @@ -139,7 +130,7 @@ def run(self): environment.update(self.configfile.run.environment) if self.configfile.run.volumes: volumes.update(self.configfile.run.volumes) - docker_info('Creating the docker container') + _docker_info('Creating the docker container') self.container = self.docker_client.containers.run( self.image, "/bin/bash -c 'while true; do sleep 30; done;'", @@ -152,7 +143,7 @@ def run(self): security_opt=self.configfile.run.security_opt, detach=True, auto_remove=False) - docker_info(f'Container {self.name} running') + _docker_info(f'Container {self.name} running') except Exception as e: raise ConanException(f'Imposible to run the container "{self.name}" with image "{self.image}"' f'\n\n{str(e)}') @@ -170,10 +161,10 @@ def run(self): finally: if self.container: error_prefix = 'ERROR: ' if error else '' - docker_info(f'{error_prefix}Stopping container', error) + _docker_info(f'{error_prefix}Stopping container', error) self.container.stop() if self.remove: - docker_info(f'{error_prefix}Removing container', error) + _docker_info(f'{error_prefix}Removing container', error) self.container.remove() def build_image(self): @@ -200,7 +191,7 @@ def build_image(self): def run_command(self, command, log=True): if log: - docker_info(f'Running in container: "{command}"') + _docker_info(f'Running in container: "{command}"') exec_instance = self.docker_api.exec_create(self.container.id, f"/bin/bash -c '{command}'", tty=True) exec_output = self.docker_api.exec_start(exec_instance['Id'], tty=True, stream=True, demux=True,) stderr_log, stdout_log = '', '' @@ -248,7 +239,7 @@ def create_runner_environment(self): if self.cache == 'copy': tgz_path = os.path.join(self.abs_runner_home_path, 'local_cache_save.tgz') - docker_info(f'Save host cache in: {tgz_path}') + _docker_info(f'Save host cache in: {tgz_path}') self.conan_api.cache.save(self.conan_api.list.select(ListPattern("*:*")), tgz_path) return volumes, environment @@ -274,5 +265,5 @@ def update_local_cache(self): self.run_command('conan list --graph=create.json --graph-binaries=build --format=json > pkglist.json', log=False) self.run_command('conan cache save --list=pkglist.json --file "'+self.abs_docker_path+'"/.conanrunner/docker_cache_save.tgz') tgz_path = os.path.join(self.abs_runner_home_path, 'docker_cache_save.tgz') - docker_info(f'Restore host cache from: {tgz_path}') + _docker_info(f'Restore host cache from: {tgz_path}') package_list = self.conan_api.cache.restore(tgz_path) diff --git a/conans/test/integration/command/runner_test.py b/conans/test/integration/command/runner_test.py index 510fa4218e4..3371e10be92 100644 --- a/conans/test/integration/command/runner_test.py +++ b/conans/test/integration/command/runner_test.py @@ -87,36 +87,20 @@ def test_create_docker_runner_dockerfile_folder_path(): remove=True """) - conanfile = textwrap.dedent(""" - from conan import ConanFile - - class MyTest(ConanFile): - name = "pkg" - version = "0.2" - settings = "build_type", "compiler" - author = "John Doe" - license = "MIT" - url = "https://foo.bar.baz" - homepage = "https://foo.bar.site" - topics = "foo", "bar", "qux" - provides = "libjpeg", "libjpg" - deprecated = "other-pkg" - options = {"shared": [True, False], "fPIC": [True, False]} - default_options = {"shared": False, "fPIC": True} - """) - client.save({"conanfile.py": conanfile, "host_copy": profile_host_copy, "host_clean": profile_host_clean, "build": profile_build}) + client.save({"host_copy": profile_host_copy, "host_clean": profile_host_clean, "build": profile_build}) + client.run("new cmake_lib -d name=pkg -d version=0.2") client.run("create . -pr:h host_copy -pr:b build") assert "Restore: pkg/0.2" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307 metadata" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata" in client.out assert "Removing container" in client.out client.run("create . -pr:h host_clean -pr:b build") assert "Restore: pkg/0.2" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307 metadata" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata" in client.out assert "Removing container" in client.out @@ -154,29 +138,13 @@ def test_create_docker_runner_dockerfile_file_path(): cache=copy remove=True """) - conanfile = textwrap.dedent(""" - from conan import ConanFile - - class MyTest(ConanFile): - name = "pkg" - version = "0.2" - settings = "build_type", "compiler" - author = "John Doe" - license = "MIT" - url = "https://foo.bar.baz" - homepage = "https://foo.bar.site" - topics = "foo", "bar", "qux" - provides = "libjpeg", "libjpg" - deprecated = "other-pkg" - options = {"shared": [True, False], "fPIC": [True, False]} - default_options = {"shared": False, "fPIC": True} - """) - client.save({"conanfile.py": conanfile, "host": profile_host, "build": profile_build}) + client.save({"host": profile_host, "build": profile_build}) + client.run("new cmake_lib -d name=pkg -d version=0.2") client.run("create . -pr:h host -pr:b build") - + print(client.out) assert "Restore: pkg/0.2" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307 metadata" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata" in client.out assert "Removing container" in client.out @@ -280,29 +248,14 @@ def test_create_docker_runner_profile_abs_path(): cache=copy remove=True """) - conanfile = textwrap.dedent(""" - from conan import ConanFile - - class MyTest(ConanFile): - name = "pkg" - version = "0.2" - settings = "build_type", "compiler" - author = "John Doe" - license = "MIT" - url = "https://foo.bar.baz" - homepage = "https://foo.bar.site" - topics = "foo", "bar", "qux" - provides = "libjpeg", "libjpg" - deprecated = "other-pkg" - options = {"shared": [True, False], "fPIC": [True, False]} - default_options = {"shared": False, "fPIC": True} - """) - client.save({"conanfile.py": conanfile, "host": profile_host, "build": profile_build}) + + client.save({"host": profile_host, "build": profile_build}) + client.run("new cmake_lib -d name=pkg -d version=0.2") client.run(f"create . -pr:h '{os.path.join(client.current_folder, 'host')}' -pr:b '{os.path.join(client.current_folder, 'build')}'") assert "Restore: pkg/0.2" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307 metadata" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata" in client.out assert "Removing container" in client.out @@ -347,27 +300,12 @@ def test_create_docker_runner_profile_abs_path_from_configfile(): cache=copy remove=True """) - conanfile = textwrap.dedent(""" - from conan import ConanFile - - class MyTest(ConanFile): - name = "pkg" - version = "0.2" - settings = "build_type", "compiler" - author = "John Doe" - license = "MIT" - url = "https://foo.bar.baz" - homepage = "https://foo.bar.site" - topics = "foo", "bar", "qux" - provides = "libjpeg", "libjpg" - deprecated = "other-pkg" - options = {"shared": [True, False], "fPIC": [True, False]} - default_options = {"shared": False, "fPIC": True} - """) - client.save({"conanfile.py": conanfile, "host": profile_host, "build": profile_build}) + + client.save({"host": profile_host, "build": profile_build}) + client.run("new cmake_lib -d name=pkg -d version=0.2") client.run(f"create . -pr:h '{os.path.join(client.current_folder, 'host')}' -pr:b '{os.path.join(client.current_folder, 'build')}'") assert "Restore: pkg/0.2" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307" in client.out - assert "Restore: pkg/0.2:a0826e5ee3b340fcc7a8ccde40224e3562316307 metadata" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe" in client.out + assert "Restore: pkg/0.2:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata" in client.out assert "Removing container" in client.out \ No newline at end of file