diff --git a/conans/client/graph/graph_binaries.py b/conans/client/graph/graph_binaries.py index d8a81deeddb..d759f8d6d38 100644 --- a/conans/client/graph/graph_binaries.py +++ b/conans/client/graph/graph_binaries.py @@ -100,9 +100,11 @@ def _evaluate_cache_pkg(self, node, package_layout, pref, metadata, remote, remo def _get_package_info(self, node, pref, remote): return self._remote_manager.get_package_info(pref, remote, info=node.conanfile.info) - def _evaluate_remote_pkg(self, node, pref, remote, remotes): + def _evaluate_remote_pkg(self, node, pref, remote, remotes, remote_selected): remote_info = None - if remote: + # If the remote is pinned (remote_selected) we won't iterate the remotes. + # The "remote" can come from -r or from the registry (associated ref) + if remote_selected or remote: try: remote_info, pref = self._get_package_info(node, pref, remote) except NotFoundException: @@ -111,10 +113,16 @@ def _evaluate_remote_pkg(self, node, pref, remote, remotes): node.conanfile.output.error("Error downloading binary package: '{}'".format(pref)) raise - # If the "remote" came from the registry but the user didn't specified the -r, with - # revisions iterate all remotes - if not remote or (not remote_info and self._cache.config.revisions_enabled): - for r in remotes.values(): # FIXME: Here we hit the same remote we did before + # If we didn't pin a remote with -r and: + # - The remote is None (not registry entry) + # or + # - We didn't find a package but having revisions enabled + # We iterate the other remotes to find a binary + if not remote_selected and (not remote or + (not remote_info and self._cache.config.revisions_enabled)): + for r in remotes.values(): + if r == remote: + continue try: remote_info, pref = self._get_package_info(node, pref, r) except NotFoundException: @@ -243,6 +251,7 @@ def _process_node(self, node, pref, build_mode, update, remotes): metadata = self._evaluate_clean_pkg_folder_dirty(node, package_layout, pref) remote = remotes.selected + remote_selected = remote is not None metadata = metadata or package_layout.load_metadata() if not remote: @@ -260,7 +269,8 @@ def _process_node(self, node, pref, build_mode, update, remotes): recipe_hash = None else: # Binary does NOT exist locally # Returned remote might be different than the passed one if iterating remotes - recipe_hash, remote = self._evaluate_remote_pkg(node, pref, remote, remotes) + recipe_hash, remote = self._evaluate_remote_pkg(node, pref, remote, remotes, + remote_selected) if build_mode.outdated: if node.binary in (BINARY_CACHE, BINARY_DOWNLOAD, BINARY_UPDATE): diff --git a/conans/test/functional/revisions_test.py b/conans/test/functional/revisions_test.py index 94c9f25473d..b4f31113fe1 100644 --- a/conans/test/functional/revisions_test.py +++ b/conans/test/functional/revisions_test.py @@ -1598,3 +1598,20 @@ def test_necessary_update(): c.save({"conanfile.py": GenConanfile("app", "0.1").with_requires("pkg/0.1#{}".format(rrev2))}) c.run("install .") assert rrev2 in c.out + + +def test_touching_other_server(): + # https://github.com/conan-io/conan/issues/9333 + servers = OrderedDict([("remote1", TestServer()), + ("remote2", None)]) # None server will crash if touched + c = TestClient(servers=servers, users={"remote1": [("conan", "password")]}) + c.run("config set general.revisions_enabled=True") + c.save({"conanfile.py": GenConanfile().with_settings("os")}) + c.run("create . pkg/0.1@conan/channel -s os=Windows") + c.run("upload * --all -c -r=remote1") + c.run("remove * -f") + + # This is OK, binary found + c.run("install pkg/0.1@conan/channel -r=remote1 -s os=Windows") + c.run("install pkg/0.1@conan/channel -r=remote1 -s os=Linux", assert_error=True) + assert "ERROR: Missing binary: pkg/0.1@conan/channel" in c.out diff --git a/conans/test/integration/command/install/install_update_test.py b/conans/test/integration/command/install/install_update_test.py index f802336f07f..39b4a0c96d9 100644 --- a/conans/test/integration/command/install/install_update_test.py +++ b/conans/test/integration/command/install/install_update_test.py @@ -290,6 +290,7 @@ def test_fail_usefully_when_failing_retrieving_package(): client.run("install {}".format(ref2), assert_error=True) assert "ERROR: Error downloading binary package: '{}'".format(pref1) in client.out + def test_evil_insertions(): ref = ConanFileReference.loads("lib1/1.0@conan/stable") ref2 = ConanFileReference.loads("lib2/1.0@conan/stable") diff --git a/conans/test/integration/remote/test_request_headers.py b/conans/test/integration/remote/test_request_headers.py index 29c61cb828c..4cea918ab66 100644 --- a/conans/test/integration/remote/test_request_headers.py +++ b/conans/test/integration/remote/test_request_headers.py @@ -50,7 +50,7 @@ def setUp(self): def _get_header(self, requester, header_name): hits = sum([header_name in headers for _, headers in requester.requests]) - assert hits == 2 if self.revs_enabled else 1 + assert hits <= 2 if self.revs_enabled else 1 for url, headers in requester.requests: if header_name in headers: if self.revs_enabled: