← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~jugmac00/lpcraft:fix-lpcraft-for-projects-with-underscores into lpcraft:main

 

Jürgen Gmach has proposed merging ~jugmac00/lpcraft:fix-lpcraft-for-projects-with-underscores into lpcraft:main.

Commit message:
Sanitize input for generating instance name

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jugmac00/lpcraft/+git/lpcraft/+merge/414412
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~jugmac00/lpcraft:fix-lpcraft-for-projects-with-underscores into lpcraft:main.
diff --git a/lpcraft/providers/_base.py b/lpcraft/providers/_base.py
index 559143b..691dae4 100644
--- a/lpcraft/providers/_base.py
+++ b/lpcraft/providers/_base.py
@@ -16,6 +16,19 @@ from typing import Dict, Generator, List, Optional
 from craft_providers import bases, lxd
 
 
+def sanitize_lxd_instance_name(name: str) -> str:
+    """LXD instance names need to follow a certain pattern
+
+    Make sure we follow this pattern:
+    https://linuxcontainers.org/lxd/docs/master/instances/
+    """
+    # There is no need to check for all edge cases, as e.g. we control how
+    # the string starts and ends anyway.
+    name = name.replace("_", "-")  # no underscores
+    name = name.replace(".", "-")  # no dots
+    return name[:63]
+
+
 class Provider(ABC):
     """A build environment provider for lpcraft."""
 
@@ -60,10 +73,11 @@ class Provider(ABC):
         :param series: Distribution series name.
         :param architecture: Targeted architecture name.
         """
-        return (
+        name = (
             f"lpcraft-{project_name}-{project_path.stat().st_ino}"
             f"-{series}-{architecture}"
         )
+        return sanitize_lxd_instance_name(name)
 
     def get_command_environment(self) -> Dict[str, Optional[str]]:
         """Construct the required environment."""
diff --git a/lpcraft/providers/tests/test_base.py b/lpcraft/providers/tests/test_base.py
new file mode 100644
index 0000000..e96482d
--- /dev/null
+++ b/lpcraft/providers/tests/test_base.py
@@ -0,0 +1,18 @@
+# Copyright 2022 Canonical Ltd.  This software is licensed under the
+# GNU General Public License version 3 (see the file LICENSE).
+
+import pytest
+
+from lpcraft.providers._base import sanitize_lxd_instance_name
+
+
+@pytest.mark.parametrize(
+    "test_input, expected",
+    [
+        ("et_xmlfile", "et-xmlfile"),  # no underscores
+        ("et.xmlfile", "et-xmlfile"),  # no dots
+        ("a" * 100, "a" * 63),  # max len is 63
+    ],
+)
+def test_sanitize_lxd_instance_name(test_input, expected):
+    assert expected == sanitize_lxd_instance_name(test_input)
diff --git a/lpcraft/providers/tests/test_lxd.py b/lpcraft/providers/tests/test_lxd.py
index cc8255e..dcc586a 100644
--- a/lpcraft/providers/tests/test_lxd.py
+++ b/lpcraft/providers/tests/test_lxd.py
@@ -234,6 +234,20 @@ class TestLXDProvider(TestCase):
             ),
         )
 
+    def test_get_sanitized_instance_name(self):
+        # e.g. underscores are not allowed
+        provider = self.makeLXDProvider()
+
+        self.assertEqual(
+            "lpcraft-my-project-12345-focal-amd64",
+            provider.get_instance_name(
+                project_name="my_project",
+                project_path=self.mock_path,
+                series="focal",
+                architecture="amd64",
+            ),
+        )
+
     @patch("os.environ", {"IGNORE": "sentinel", "PATH": "not-using-host-path"})
     def test_get_command_environment_minimal(self):
         provider = self.makeLXDProvider()