← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad-buildd/lxd-missing-etc-hosts into lp:launchpad-buildd

 

Colin Watson has proposed merging lp:~cjwatson/launchpad-buildd/lxd-missing-etc-hosts into lp:launchpad-buildd.

Commit message:
Use a fallback if /etc/hosts is missing from the chroot.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-buildd/lxd-missing-etc-hosts/+merge/329908
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad-buildd/lxd-missing-etc-hosts into lp:launchpad-buildd.
=== modified file 'lpbuildd/target/lxd.py'
--- lpbuildd/target/lxd.py	2017-08-29 12:51:42 +0000
+++ lpbuildd/target/lxd.py	2017-08-30 12:22:10 +0000
@@ -33,6 +33,16 @@
 LXD_RUNNING = 103
 
 
+fallback_hosts = dedent("""\
+    127.0.0.1\tlocalhost
+    ::1\tlocalhost ip6-localhost ip6-loopback
+    fe00::0\tip6-localnet
+    ff00::0\tip6-mcastprefix
+    ff02::1\tip6-allnodes
+    ff02::2\tip6-allrouters
+    """)
+
+
 policy_rc_d = dedent("""\
     #! /bin/sh
     while :; do
@@ -283,7 +293,11 @@
             }, wait=True)
 
         with tempfile.NamedTemporaryFile(mode="w+b") as hosts_file:
-            self.copy_out("/etc/hosts", hosts_file.name)
+            try:
+                self.copy_out("/etc/hosts", hosts_file.name)
+            except LXDAPIException:
+                hosts_file.seek(0, os.SEEK_SET)
+                hosts_file.write(fallback_hosts.encode("UTF-8"))
             hosts_file.seek(0, os.SEEK_END)
             print("\n127.0.1.1\t%s" % self.name, file=hosts_file)
             hosts_file.flush()

=== modified file 'lpbuildd/target/tests/test_lxd.py'
--- lpbuildd/target/tests/test_lxd.py	2017-08-29 12:51:42 +0000
+++ lpbuildd/target/tests/test_lxd.py	2017-08-30 12:22:10 +0000
@@ -39,6 +39,7 @@
 
 from lpbuildd.target.lxd import (
     LXD,
+    fallback_hosts,
     policy_rc_d,
     )
 
@@ -228,6 +229,43 @@
         container.start.assert_called_once_with(wait=True)
         self.assertEqual(LXD_RUNNING, container.status_code)
 
+    def test_start_missing_etc_hosts(self):
+        fs_fixture = self.useFixture(FakeFilesystem())
+        fs_fixture.add("/sys")
+        fs_fixture.add("/run")
+        os.makedirs("/run/launchpad-buildd")
+        fs_fixture.add("/etc")
+        os.mkdir("/etc")
+        with open("/etc/resolv.conf", "w") as f:
+            print("host resolv.conf", file=f)
+        os.chmod("/etc/resolv.conf", 0o644)
+        self.useFixture(MockPatch("pylxd.Client"))
+        client = pylxd.Client()
+        client.profiles.get.side_effect = FakeLXDAPIException
+        container = client.containers.create.return_value
+        client.containers.get.return_value = container
+        container.start.side_effect = (
+            lambda wait=False: setattr(container, "status_code", LXD_RUNNING))
+        files_api = container.api.files
+        files_api._api_endpoint = "/1.0/containers/lp-xenial-amd64/files"
+        files_api.session.get.return_value.status_code = 404
+        files_api.session.get.return_value.json.return_value = {
+            "error": "not found",
+            }
+        processes_fixture = self.useFixture(FakeProcesses())
+        processes_fixture.add(lambda _: {}, name="sudo")
+        LXD("1", "xenial", "amd64").start()
+
+        files_api.session.get.assert_called_once_with(
+            "/1.0/containers/lp-xenial-amd64/files",
+            params={"path": "/etc/hosts"}, stream=True)
+        files_api.post.assert_any_call(
+            params={"path": "/etc/hosts"},
+            data=(
+                fallback_hosts +
+                "\n127.0.1.1\tlp-xenial-amd64\n").encode("UTF-8"),
+            headers={"X-LXD-uid": 0, "X-LXD-gid": 0, "X-LXD-mode": "0644"})
+
     def test_run(self):
         processes_fixture = self.useFixture(FakeProcesses())
         processes_fixture.add(lambda _: {}, name="lxc")