From e438189a198a3bc656a99be9d82793ddf6077c53 Mon Sep 17 00:00:00 2001
From: Pierre Riteau <pierre@stackhpc.com>
Date: Thu, 2 Dec 2021 22:41:53 +0100
Subject: [PATCH] Fix installation prefix detection

When multiple 'lib' components are present in the installation path,
Kayobe fails to detect the right installation prefix which causes
various commands to raise an error.

Rewrite logic to detect the last 'lib' component in path instead. This
should work as long as this function is not stored under a lib directory
inside the Kayobe source tree.

Change-Id: Ie9b15db6563546ede9ce9735292ec566d540432a
Story: 2009721
Task: 44109
---
 kayobe/tests/unit/test_utils.py                          | 7 +++++++
 kayobe/utils.py                                          | 9 +++------
 .../install-prefix-multiple-lib-9288e8c11da3c0bc.yaml    | 6 ++++++
 3 files changed, 16 insertions(+), 6 deletions(-)
 create mode 100644 releasenotes/notes/install-prefix-multiple-lib-9288e8c11da3c0bc.yaml

diff --git a/kayobe/tests/unit/test_utils.py b/kayobe/tests/unit/test_utils.py
index 85e98337..e1b4e2b0 100644
--- a/kayobe/tests/unit/test_utils.py
+++ b/kayobe/tests/unit/test_utils.py
@@ -179,6 +179,13 @@ key2: value2
         result = utils._detect_install_prefix(path)
         self.assertEqual(expected, os.path.normpath(result))
 
+    def test_detect_install_prefix_multiple_lib_components(self):
+        tmp_path = os.path.realpath('/tmp')
+        path = "%s/lib/test/local/lib/python3.6/dist-packages" % tmp_path
+        expected = os.path.normpath("%s/lib/test/local/" % tmp_path)
+        result = utils._detect_install_prefix(path)
+        self.assertEqual(expected, os.path.normpath(result))
+
     def test_intersect_limits_no_arg_no_cli(self):
         result = utils.intersect_limits(None, None)
         self.assertEqual("", result)
diff --git a/kayobe/utils.py b/kayobe/utils.py
index 2ded367c..727fd783 100644
--- a/kayobe/utils.py
+++ b/kayobe/utils.py
@@ -14,7 +14,6 @@
 
 import base64
 import glob
-import itertools
 import logging
 import os
 import shutil
@@ -40,13 +39,11 @@ def _detect_install_prefix(path):
     script_path = os.path.realpath(path)
     script_path = os.path.normpath(script_path)
     components = script_path.split(os.sep)
-    # use heuristic: anything before 'lib' in path is the prefix
+    # use heuristic: anything before the last 'lib' in path is the prefix
     if 'lib' not in components:
         return None
-    prefix = itertools.takewhile(
-        lambda x: x != "lib",
-        components
-    )
+    last_lib = len(components) - 1 - components[::-1].index('lib')
+    prefix = components[:last_lib]
     prefix_path = os.sep.join(prefix)
     return prefix_path
 
diff --git a/releasenotes/notes/install-prefix-multiple-lib-9288e8c11da3c0bc.yaml b/releasenotes/notes/install-prefix-multiple-lib-9288e8c11da3c0bc.yaml
new file mode 100644
index 00000000..4043b6de
--- /dev/null
+++ b/releasenotes/notes/install-prefix-multiple-lib-9288e8c11da3c0bc.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fixes a failure to detect the Kayobe installation prefix when ``lib`` is
+    present multiple times in the installation path. See `story 2009721
+    <https://storyboard.openstack.org/#!/story/2009721>`__ for details.
-- 
GitLab