Skip to content

Commit

Permalink
profile runner bug fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
davidsanfal committed Mar 22, 2024
1 parent 72e6164 commit 2c50c14
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 17 deletions.
44 changes: 30 additions & 14 deletions conan/internal/runner/docker.py
Expand Up @@ -2,6 +2,7 @@
import json
import platform
import shutil
import itertools
from conan.api.model import ListPattern
from conan.api.output import Color, ConanOutput
from conan.api.conan_api import ConfigAPI
Expand Down Expand Up @@ -47,10 +48,26 @@ def __init__(self, conan_api, command, profile, args, raw_args):
self.abs_host_path = make_abs_path(args.path)
if args.format:
raise ConanException("format argument is forbidden if running in a docker runner")

# Runner config
self.abs_runner_home_path = os.path.join(self.abs_host_path, '.conanrunner')
self.abs_docker_path = os.path.join('/root/conanrunner', os.path.basename(self.abs_host_path)).replace("\\","/")
raw_args[raw_args.index(args.path)] = f'"{self.abs_docker_path}"'
self.command = ' '.join([f'conan {command}'] + raw_args + ['-f json > create.json'])

# Update conan command and some paths to run inside the container
raw_args[raw_args.index(args.path)] = self.abs_docker_path
self.profiles = []
profile_list = set(self.args.profile_build + self.args.profile_host)
# Update the profile paths
for i, raw_arg in enumerate(raw_args):
for i, raw_profile in enumerate(profile_list):
_profile = ProfileLoader.get_profile_path(os.path.join(ConfigAPI(self.conan_api).home(), 'profiles'), raw_profile, os.getcwd())
_name = f'{os.path.basename(_profile)}_{i}'
if raw_profile in raw_arg:
raw_args[raw_args.index(raw_arg)] = raw_arg.replace(raw_profile, os.path.join(self.abs_docker_path, '.conanrunner/profiles', _name))
self.profiles.append([_profile, os.path.join(self.abs_runner_home_path, 'profiles', _name)])
self.command = ' '.join([f'conan {command}'] + [f'"{raw_arg}"' if ' ' in raw_arg else raw_arg for raw_arg in raw_args] + ['-f json > create.json'])

# Container config
self.dockerfile = profile.runner.get('dockerfile')
self.docker_build_context = profile.runner.get('docker_build_context')
self.image = profile.runner.get('image')
Expand Down Expand Up @@ -155,20 +172,25 @@ def run_command(self, command, log=True):
return stdout_log, stderr_log

def create_runner_environment(self):
shutil.rmtree(self.abs_runner_home_path, ignore_errors=True)
volumes = {self.abs_host_path: {'bind': self.abs_docker_path, 'mode': 'rw'}}
environment = {'CONAN_RUNNER_ENVIRONMENT': '1'}
if self.cache == 'shared':
volumes[ConfigAPI(self.conan_api).home()] = {'bind': '/root/.conan2', 'mode': 'rw'}
if self.cache in ['clean', 'copy']:
shutil.rmtree(self.abs_runner_home_path, ignore_errors=True)
os.mkdir(self.abs_runner_home_path)
os.mkdir(os.path.join(self.abs_runner_home_path, 'profiles'))

# Copy all conan config files to docker workspace
for file_name in ['global.conf', 'settings.yml', 'remotes.json']:
src_file = os.path.join(ConfigAPI(self.conan_api).home(), file_name)
if os.path.exists(src_file):
shutil.copy(src_file, os.path.join(self.abs_runner_home_path, file_name))
self._copy_profiles(self.args.profile_build)
self._copy_profiles(self.args.profile_host)

# Copy all profiles to docker workspace
for current_path, new_path in self.profiles:
shutil.copy(current_path, new_path)

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}')
Expand All @@ -178,11 +200,12 @@ def create_runner_environment(self):
def init_container(self):
min_conan_version = '2.1'
stdout, _ = self.run_command('conan --version', log=True)
docker_conan_version = str(stdout.replace('Conan version ', '').replace('\n', '').replace('\r', '')) # Remove all characters and color
docker_conan_version = str(stdout.split('Conan version ')[1].replace('\n', '').replace('\r', '')) # Remove all characters and color
print(docker_conan_version)
if Version(docker_conan_version) <= Version(min_conan_version):
ConanOutput().status(f'ERROR: conan version inside the container must be greater than {min_conan_version}', fg=Color.BRIGHT_RED)
raise ConanException( f'conan version inside the container must be greater than {min_conan_version}')
if self.cache == 'shared':
if self.cache != 'shared':
self.run_command('mkdir -p ${HOME}/.conan2/profiles', log=False)
self.run_command('cp -r "'+self.abs_docker_path+'/.conanrunner/profiles/." ${HOME}/.conan2/profiles/.', log=False)
for file_name in ['global.conf', 'settings.yml', 'remotes.json']:
Expand All @@ -198,10 +221,3 @@ def update_local_cache(self):
tgz_path = os.path.join(self.abs_runner_home_path, 'docker_cache_save.tgz')
docker_info(f'Restore host cache from: {tgz_path}')
package_list = self.conan_api.cache.restore(tgz_path)

def _copy_profiles(self, profiles):
cwd = os.getcwd()
if profiles:
for profile in profiles:
profile_path = ProfileLoader.get_profile_path(os.path.join(ConfigAPI(self.conan_api).home(), 'profiles'), profile, cwd)
shutil.copy(profile_path, os.path.join(self.abs_runner_home_path, 'profiles', os.path.basename(profile_path)))
64 changes: 61 additions & 3 deletions conans/test/integration/command/runner_test.py
Expand Up @@ -242,7 +242,65 @@ def package(self):
client.save({"profile": profile})
settings = "-s os=Linux -s arch=x86_64 -s build_type={} -o hello/*:shared={}".format(build_type, shared)
# create should also work
client.run("create . --name=hello --version=1.0 {} -pr:h profile -pr:b profile".format(settings))
print(client.out)
client.run("create . --name=hello --version=1.0 {} -pr:h=profile -pr:b=profile".format(settings))
assert 'cmake -G "Ninja"' in client.out
assert "main: {}!".format(build_type) in client.out
assert "main: {}!".format(build_type) in client.out

@pytest.mark.skipif(docker_skip(), reason="Only docker running")
# @pytest.mark.xfail(reason="conan inside docker optional test")
def test_create_docker_runner_profile_abs_path():
"""
Tests the ``conan create . ``
"""
client = TestClient()
profile_build = textwrap.dedent(f"""\
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
""")
profile_host = textwrap.dedent(f"""\
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
[runner]
type=docker
dockerfile={dockerfile_path("Dockerfile_test")}
docker_build_context={conan_base_path()}
image=conan-runner-default-test
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.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 "Removing container" in client.out

0 comments on commit 2c50c14

Please sign in to comment.