Conan: scm "url" = "auto" vs GitLab CI runner

Created on 26 Nov 2018  路  14Comments  路  Source: conan-io/conan

My CI scripts simultaneously build Windows and Linux binaries on an internal GitLab server using Gitlab runners. Both Windows and Linux runner uses docker if that matters. And most the time one of them fails to upload a package to an internal Artifactory CE repo:

Remote manifest:
Time: 2018-11-26 11:45:30
conanfile.py, MD5: 3dd4f4769e515e72d79466d548dd2d32

Local manifest:
Time: 2018-11-26 11:44:54
conanfile.py, MD5: d7535264b9001b772fdf0317e1f95aef

Local 'conanfile.py' using '\n' line-ends
Remote 'conanfile.py' using '\n' line-ends

----------------------------------------
Traceback (most recent call last):
  File "build.py", line 44, in <module>
    main()
  File "build.py", line 41, in main
    builder.run()
  File "/usr/local/lib/python2.7/dist-packages/cpt/packager.py", line 443, in run
    self.run_builds(base_profile_name=base_profile_name)
  File "/usr/local/lib/python2.7/dist-packages/cpt/packager.py", line 518, in run_builds
    r.run()
  File "/usr/local/lib/python2.7/dist-packages/cpt/runner.py", line 88, in run
    self._upload, package_id)
  File "/usr/local/lib/python2.7/dist-packages/cpt/uploader.py", line 43, in upload_packages
    retry=int(self._upload_retry))
  File "/usr/local/lib/python2.7/dist-packages/conans/client/conan_api.py", line 88, in wrapper
    return f(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/conans/client/conan_api.py", line 818, in upload
    retry_wait, integrity_check, policy, remote_name, query=query)
  File "/usr/local/lib/python2.7/dist-packages/conans/client/cmd/uploader.py", line 68, in upload
    integrity_check, policy, remote_name, recorder)
  File "/usr/local/lib/python2.7/dist-packages/conans/client/cmd/uploader.py", line 90, in _upload
    remote_manifest = self._check_recipe_date(conan_ref, recipe_remote)
  File "/usr/local/lib/python2.7/dist-packages/conans/client/cmd/uploader.py", line 165, in _check_recipe_date
    (remote_recipe_manifest.time, local_manifest.time))
conans.errors.ConanException: Remote recipe is newer than local recipe: 
 Remote date: 1543232730
 Local date: 1543232694

If I rerun the failing job manually, it succeeds. Any Idea how to fix/work around this? Both Windows and Linux docker instances are running on the same physical server, so time sync issues are hardly the problem. Even if they are, can I somehow prevent conan from detecting that difference and failing with an exception?

low medium feature

Most helpful comment

@lasote I would still prefer automatic credential removal by conan, proposed by @jgsogo. Yes, your function is tiny, but one should not forget to copy/paste it each time a new conan package is created. But if it's too hard, of course explicit git.get_remote_url() is a way to go.

All 14 comments

My initial analysis was totally wrong. Here is an updated one. I have a recipe with

class BuildConan(ConanFile):
    scm = {
        "type": "git",
        "url": "auto",
        "revision": "auto",
        "submodule": "recursive"
    }

that I build with GitLab CI. "url": "auto" is supposed to be replaced by the real git repo url. But when GitLab runner executes CI job git url contain a unique job token needed to access a git repo: http://gitlab-ci-token:[email protected]/user/repo.git. This token changes each time CI job is run. So concurrent jobs generate different conanfile.py and I see the above output.

Replacing auto with the real url http://git.host.local/user/repo.git (gitlab-ci-token stripped) seems to help. Maybe conan should do that itself? (or at least issue a warning if it sees something@ in the scm.url?)

Thanks for the explanation. I think we cannot assume that Conan should clear always the credentials, it could happen a user actually wants them. Maybe we could add a new argument to the scm, something like clear_url_credentials: True/False (Default True?).

I think that those url credentials should be removed always... if the user wants to save inside the recipe the username and password, there are fields in the scm dict dedicated to that info.

Yes, a new argument looks good to me. But maybe also check for some well known CI credentials like gitlab-ci-token:xxxxxxxx@ and strip them unconditionally (maybe with a warning)?

Sorry, missed @jgsogo comment. For me, "removing always" (with a warning that url credentials have been removed) is even better.

@db4 Do you happen to have a link to the Dockerfile you used to create the Docker image for Windows? I have been trying to test it but it looks way more complicated than the Linux docker file, getting and installing msvc compiler is just a pain...

@AliAskari You can find my Docker file here: https://github.com/conan-io/conan-docker-tools/issues/50#issuecomment-419881449

@jgsogo ok, we can remove them always. We can add the flag later if it is requested.

@AliAskari about docker windows, there is a WIP here. Please try to avoid mixing topics in the same issue if they are not related.

Hi! I think #3183 feature from @jgsogo could help with this issue. You could write a tinny function now to remove the credentials from the URL. I think that the mechanism is generic and good enough. Could this issue be closed when merged?

e.g:

import os
from conans import ConanFile
from conans.client.tools.scm import Git


def get_url():
    here = os.path.dirname(__file__)
    git = Git(here)
    tmp = git.get_remote_url()
    # REPLACE HERE YOUR URL
    return tmp

class MyLib(ConanFile):
    name = "issue"
    version = "3831"
    scm = {'type': 'git', 'url': get_url(), 'revision': "auto"}

@lasote I would still prefer automatic credential removal by conan, proposed by @jgsogo. Yes, your function is tiny, but one should not forget to copy/paste it each time a new conan package is created. But if it's too hard, of course explicit git.get_remote_url() is a way to go.

Thanks for the feedback

Hey @lasote ,

I have exactly the same problem with gitlab and it already hurt alot across my projects because CI get really noisy.

I also think that a directl url cleanup in conan would be great, because copy paste the get_url it into every recipe is not that pratical. But I think you can make that opt-in, so f.e.

class BuildConan(ConanFile):
    scm = {
        "type": "git",
        "url": "auto",
        "revision": "auto",
        "submodule": "recursive",
        "credential_removal" : True # <= new option
    }

Maybe you can call it remove_sensitve_data or something like that.

The nice thing is that it is an opt-in feature, so every recipe author can decide if removal is required or not. It also wont fail in older conan version,but not removal would happen.

If you don't like the option, it would be nice to have a "ready to use" function in tools.

Will be released into 1.12. Thanks guys!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

uilianries picture uilianries  路  3Comments

zomeck picture zomeck  路  3Comments

petermbauer picture petermbauer  路  3Comments

niosHD picture niosHD  路  3Comments

uilianries picture uilianries  路  3Comments