launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32791
[Merge] ~ruinedyourlife/launchpad-buildd:maven-local-repo into launchpad-buildd:master
Quentin Debhi has proposed merging ~ruinedyourlife/launchpad-buildd:maven-local-repo into launchpad-buildd:master.
Commit message:
Maven local repos & exclusive mirrors
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~ruinedyourlife/launchpad-buildd/+git/launchpad-buildd/+merge/489582
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~ruinedyourlife/launchpad-buildd:maven-local-repo into launchpad-buildd:master.
diff --git a/lpbuildd/target/build_craft.py b/lpbuildd/target/build_craft.py
index 69106a8..0ff403f 100644
--- a/lpbuildd/target/build_craft.py
+++ b/lpbuildd/target/build_craft.py
@@ -326,18 +326,53 @@ class BuildCraft(
</pluginRepositories>
</profile>
"""
+
+ # Add a local plugin repository profile
+ settings_xml += """ <profile>
+ <id>local-plugin-repo</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>local-plugin-repo</id>
+ <name>Local Plugin Repository</name>
+ <url>file:///usr/share/maven-repo</url>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+"""
+
+ # Add a local repository profile
+ settings_xml += """ <profile>
+ <id>local-repo</id>
+ <repositories>
+ <repository>
+ <id>local-repo</id>
+ <name>Local Repository</name>
+ <url>file:///usr/share/maven-repo</url>
+ </repository>
+ </repositories>
+ </profile>
+"""
# Add mirror configurations to ensure all requests go through Artifactory
+ # but exclude local repositories
settings_xml += """ </profiles>
<mirrors>
"""
for name, repo in repositories.items():
if "url" in repo:
+ other_ids = [
+ f"!{other}" for other in repositories if other != name
+ ]
+ other_ids += ["!local-repo", "!local-plugin-repo"]
+ mirror_of = "*,{}".format(",".join(other_ids))
settings_xml += f""" <mirror>
<id>{name}</id>
<name>Maven Repository Manager running on {name}</name>
<url>{repo['url']}</url>
- <mirrorOf>*</mirrorOf>
+ <mirrorOf>{mirror_of}</mirrorOf>
</mirror>
"""
diff --git a/lpbuildd/target/tests/test_build_craft.py b/lpbuildd/target/tests/test_build_craft.py
index fe342c4..15fdba7 100644
--- a/lpbuildd/target/tests/test_build_craft.py
+++ b/lpbuildd/target/tests/test_build_craft.py
@@ -1332,7 +1332,7 @@ class TestBuildCraft(TestCase):
# Check mirrors
self.assertIn(' <mirror>', settings_content)
- self.assertIn(' <mirrorOf>*</mirrorOf>', settings_content)
+ self.assertIn(' <mirrorOf>*,!local-repo,!local-plugin-repo</mirrorOf>', settings_content)
# Verify activeProfiles section is not present
self.assertNotIn('<activeProfiles>', settings_content)
@@ -1399,7 +1399,10 @@ class TestBuildCraft(TestCase):
# Check mirrors with exact indentation
self.assertIn(f' <id>{repo_name}</id>', settings_content)
- self.assertIn(' <mirrorOf>*</mirrorOf>', settings_content)
+
+ # Check that mirrors exclude each other and local repositories
+ self.assertIn('<mirrorOf>*,!artifactory2,!local-repo,!local-plugin-repo</mirrorOf>', settings_content)
+ self.assertIn('<mirrorOf>*,!artifactory1,!local-repo,!local-plugin-repo</mirrorOf>', settings_content)
# Verify activeProfiles section is not present
self.assertNotIn('<activeProfiles>', settings_content)
@@ -1417,3 +1420,182 @@ class TestBuildCraft(TestCase):
]
),
)
+
+ def test_build_with_local_repositories_only(self):
+ """Test that local repositories are configured when no external Maven repos are provided."""
+ args = [
+ "build-craft",
+ "--backend=fake",
+ "--series=xenial",
+ "--arch=amd64",
+ "1",
+ "--branch",
+ "lp:foo",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY_URL=https://canonical.example.com/artifactory/api/maven/maven-upstream/",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY_READ_AUTH=user:token123",
+ "test-image",
+ ]
+ build_craft = parse_args(args=args).operation
+ build_craft.build()
+
+ # Check that .m2/settings.xml was created with local repositories
+ maven_settings_path = "/home/buildd/test-image/.m2/settings.xml"
+ self.assertTrue(build_craft.backend.path_exists(maven_settings_path))
+ with build_craft.backend.open(maven_settings_path) as f:
+ settings_content = f.read()
+
+ # Check local plugin repository profile
+ self.assertIn(' <profile>', settings_content)
+ self.assertIn(' <id>local-plugin-repo</id>', settings_content)
+ self.assertIn(' <activeByDefault>true</activeByDefault>', settings_content)
+ self.assertIn(' <pluginRepository>', settings_content)
+ self.assertIn(' <name>Local Plugin Repository</name>', settings_content)
+ self.assertIn(' <url>file:///usr/share/maven-repo</url>', settings_content)
+
+ # Check local repository profile (should not be activated by default)
+ self.assertIn(' <id>local-repo</id>', settings_content)
+ self.assertIn(' <repository>', settings_content)
+ self.assertIn(' <name>Local Repository</name>', settings_content)
+
+ # Should not have activation for local-repo
+ local_repo_section_start = settings_content.find('<id>local-repo</id>')
+ local_repo_section_end = settings_content.find('</profile>', local_repo_section_start)
+ local_repo_section = settings_content[local_repo_section_start:local_repo_section_end]
+ self.assertNotIn('<activation>', local_repo_section)
+
+ def test_build_with_maven_credentials_and_local_repos(self):
+ """Test that both external and local repositories are configured correctly."""
+ args = [
+ "build-craft",
+ "--backend=fake",
+ "--series=xenial",
+ "--arch=amd64",
+ "1",
+ "--branch",
+ "lp:foo",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY_URL=https://canonical.example.com/artifactory/api/maven/maven-upstream/",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY_READ_AUTH=user:token123",
+ "test-image",
+ ]
+ build_craft = parse_args(args=args).operation
+ build_craft.build()
+
+ # Check that .m2/settings.xml was created correctly
+ maven_settings_path = "/home/buildd/test-image/.m2/settings.xml"
+ self.assertTrue(build_craft.backend.path_exists(maven_settings_path))
+ with build_craft.backend.open(maven_settings_path) as f:
+ settings_content = f.read()
+
+ # Check external repository configuration
+ self.assertIn(' <id>artifactory</id>', settings_content)
+ self.assertIn(' <username>user</username>', settings_content)
+ self.assertIn(' <password>token123</password>', settings_content)
+
+ # Check local repositories are still present
+ self.assertIn(' <id>local-plugin-repo</id>', settings_content)
+ self.assertIn(' <id>local-repo</id>', settings_content)
+ self.assertIn('file:///usr/share/maven-repo', settings_content)
+
+ # Check mirror excludes local repositories
+ self.assertIn('<mirrors>', settings_content)
+ self.assertIn(' <mirrorOf>*,!local-repo,!local-plugin-repo</mirrorOf>', settings_content)
+
+ def test_build_with_multiple_maven_credentials_mirror_exclusions(self):
+ """Test that mirrors properly exclude each other and local repositories."""
+ args = [
+ "build-craft",
+ "--backend=fake",
+ "--series=xenial",
+ "--arch=amd64",
+ "1",
+ "--branch",
+ "lp:foo",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY1_URL=https://canonical.example.com/artifactory/api/maven/maven-upstream1/",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY1_READ_AUTH=user1:token1",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY2_URL=https://canonical.example.com/artifactory/api/maven/maven-upstream2/",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY2_READ_AUTH=user2:token2",
+ "test-image",
+ ]
+ build_craft = parse_args(args=args).operation
+ build_craft.build()
+
+ # Check that .m2/settings.xml was created correctly
+ maven_settings_path = "/home/buildd/test-image/.m2/settings.xml"
+ self.assertTrue(build_craft.backend.path_exists(maven_settings_path))
+ with build_craft.backend.open(maven_settings_path) as f:
+ settings_content = f.read()
+
+ # Check that each mirror excludes the other repositories and local repos
+ # Find the mirrors section first
+ mirrors_start = settings_content.find('<mirrors>')
+ mirrors_end = settings_content.find('</mirrors>')
+ mirrors_section = settings_content[mirrors_start:mirrors_end]
+
+ # artifactory1 mirror should exclude artifactory2, and local repos
+ artifactory1_mirror_start = mirrors_section.find('<id>artifactory1</id>')
+ artifactory1_mirror_end = mirrors_section.find('</mirror>', artifactory1_mirror_start)
+ artifactory1_mirror = mirrors_section[artifactory1_mirror_start:artifactory1_mirror_end]
+ self.assertIn('<mirrorOf>*,!artifactory2,!local-repo,!local-plugin-repo</mirrorOf>', artifactory1_mirror)
+
+ # artifactory2 mirror should exclude artifactory1, and local repos
+ artifactory2_mirror_start = mirrors_section.find('<id>artifactory2</id>')
+ artifactory2_mirror_end = mirrors_section.find('</mirror>', artifactory2_mirror_start)
+ artifactory2_mirror = mirrors_section[artifactory2_mirror_start:artifactory2_mirror_end]
+ self.assertIn('<mirrorOf>*,!artifactory1,!local-repo,!local-plugin-repo</mirrorOf>', artifactory2_mirror)
+
+ # Verify all repositories have both release and snapshot server configs
+ for repo_name in ['artifactory1', 'artifactory2']:
+ self.assertIn(f' <id>{repo_name}</id>', settings_content)
+ self.assertIn(f' <id>{repo_name}-snapshots</id>', settings_content)
+
+ # Verify local repositories are configured
+ self.assertIn(' <id>local-plugin-repo</id>', settings_content)
+ self.assertIn(' <id>local-repo</id>', settings_content)
+
+ def test_build_maven_local_repo_file_path(self):
+ """Test that local repository paths use the correct file:// URL format."""
+ args = [
+ "build-craft",
+ "--backend=fake",
+ "--series=xenial",
+ "--arch=amd64",
+ "1",
+ "--branch",
+ "lp:foo",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY_URL=https://canonical.example.com/artifactory/api/maven/maven-upstream/",
+ "--environment-variable",
+ "MAVEN_ARTIFACTORY_READ_AUTH=user:token123",
+ "test-image",
+ ]
+ build_craft = parse_args(args=args).operation
+ build_craft.build()
+
+ # Check that .m2/settings.xml was created with correct file URLs
+ maven_settings_path = "/home/buildd/test-image/.m2/settings.xml"
+ self.assertTrue(build_craft.backend.path_exists(maven_settings_path))
+ with build_craft.backend.open(maven_settings_path) as f:
+ settings_content = f.read()
+
+ # Should have exactly 2 occurrences of the local repo URL
+ file_url_count = settings_content.count('file:///usr/share/maven-repo')
+ self.assertEqual(2, file_url_count,
+ "Should have local repo URL in both repository and pluginRepository")
+
+ # Verify both repository and pluginRepository sections exist
+ self.assertIn('<repositories>', settings_content)
+ self.assertIn('<pluginRepositories>', settings_content)
+
+ # Verify the local plugin repo is activated by default
+ local_plugin_section_start = settings_content.find('<id>local-plugin-repo</id>')
+ local_plugin_section_end = settings_content.find('</profile>', local_plugin_section_start)
+ local_plugin_section = settings_content[local_plugin_section_start:local_plugin_section_end]
+ self.assertIn('<activeByDefault>true</activeByDefault>', local_plugin_section)