yellow team mailing list archive
-
yellow team
-
Mailing list archive
-
Message #00828
[Merge] lp:~frankban/lpsetup/load-library into lp:lpsetup
Francesco Banconi has proposed merging lp:~frankban/lpsetup/load-library into lp:lpsetup.
Requested reviews:
Launchpad Yellow Squad (yellow)
For more details, see:
https://code.launchpad.net/~frankban/lpsetup/load-library/+merge/105212
== Changes ==
Changed the way liblxc is loaded.
If the library is not found in /usr/lib/lxc/, it is searched inside /usr/lib/$DEB_HOST_MULTIARCH/lxc/ as suggested by Serge. This way lxc-ip is compatible with the new quantal version of lxc.
I don't have the environment variable $DEB_HOST_MULTIARCH in my system, but I've found that it is easily retrievable using dpkg-architecture, (see http://wiki.debian.org/Multiarch/Implementation).
== Tests ==
$ cd lplxcip/ && sudo nosetests -v
test_error (tests.test_helpers.ErrorTest) ... ok
test_host_multiarch_path (tests.test_helpers.LoadLibraryTest) ... ok
test_library_not_found (tests.test_helpers.LoadLibraryTest) ... ok
test_usual_path (tests.test_helpers.LoadLibraryTest) ... ok
test_output_of_all_interfaces (tests.test_helpers.OutputTest) ... ok
test_output_of_explicit_interface (tests.test_helpers.OutputTest) ... ok
test_redirection (tests.test_helpers.RedirectStderrTest) ... ok
test_as_root (tests.test_helpers.RootRequiredTest) ... ok
test_as_unprivileged_user (tests.test_helpers.RootRequiredTest) ... ok
test_failure (tests.test_helpers.WrapTest) ... ok
test_success (tests.test_helpers.WrapTest) ... ok
test_all_interfaces (tests.test_lxcip.GetInterfacesTest) ... ok
test_container_does_not_exist (tests.test_lxcip.GetInterfacesTest) ... ok
test_container_not_running (tests.test_lxcip.GetInterfacesTest) ... ok
test_exclude (tests.test_lxcip.GetInterfacesTest) ... ok
test_interfaces_not_found (tests.test_lxcip.GetInterfacesTest) ... ok
test_not_root (tests.test_lxcip.GetInterfacesTest) ... ok
test_invalid_interface (tests.test_lxcip.LXCIpTest) ... ok
test_invalid_name (tests.test_lxcip.LXCIpTest) ... ok
test_invalid_pid (tests.test_lxcip.LXCIpTest) ... ok
test_ip_address (tests.test_lxcip.LXCIpTest) ... ok
test_loopback (tests.test_lxcip.LXCIpTest) ... ok
test_multiple_interfaces (tests.test_lxcip.LXCIpTest) ... ok
test_not_root (tests.test_lxcip.LXCIpTest) ... ok
test_race_condition (tests.test_lxcip.LXCIpTest) ... ok
test_restart (tests.test_lxcip.LXCIpTest) ... ok
test_assertion (tests.test_utils.AssertOSErrorTest) ... ok
test_assertion_fails_different_exception (tests.test_utils.AssertOSErrorTest) ... ok
test_assertion_fails_different_message (tests.test_utils.AssertOSErrorTest) ... ok
test_assertion_fails_no_exception (tests.test_utils.AssertOSErrorTest) ... ok
test_create (tests.test_utils.LXCTest) ... ok
test_destroy (tests.test_utils.LXCTest) ... ok
test_start (tests.test_utils.LXCTest) ... ok
test_stop (tests.test_utils.LXCTest) ... ok
test_write_config (tests.test_utils.LXCTest) ... ok
test_mock (tests.test_utils.MockGeteuidTest) ... ok
test_failure (tests.test_utils.RetryTest) ... ok
test_success (tests.test_utils.RetryTest) ... ok
test_stopped (tests.test_utils.StoppedTest) ... ok
test_with_errors (tests.test_utils.StoppedTest) ... ok
----------------------------------------------------------------------
Ran 40 tests in 21.188s
OK
--
https://code.launchpad.net/~frankban/lpsetup/load-library/+merge/105212
Your team Launchpad Yellow Squad is requested to review the proposed merge of lp:~frankban/lpsetup/load-library into lp:lpsetup.
=== modified file 'lplxcip/lxcip.py'
--- lplxcip/lxcip.py 2012-05-07 13:25:53 +0000
+++ lplxcip/lxcip.py 2012-05-09 14:40:56 +0000
@@ -12,6 +12,7 @@
import os
import socket
import struct
+import subprocess
import sys
@@ -55,6 +56,33 @@
return '\n'.join('{}: {}'.format(*i) for i in interface_ip_map)
+def _load_library(name, loader=None):
+ """Load a shared library into the process and return it.
+
+ Search the library `name` inside `/usr/lib` and, if *$DEB_HOST_MULTIARCH*
+ is retrievable, inside `/usr/lib/$DEB_HOST_MULTIARCH/`.
+
+ The optional argument `loader` is the callable used to load the library:
+ if None, `ctypes.cdll.LoadLibrary` is used.
+
+ Raise OSError if the library is not found.
+ """
+ if loader is None:
+ loader = ctypes.cdll.LoadLibrary
+ try:
+ return loader(os.path.join('/usr/lib/', name))
+ except OSError:
+ # Search the library in `/usr/lib/$DEB_HOST_MULTIARCH/`:
+ # see https://wiki.ubuntu.com/MultiarchSpec.
+ process = subprocess.Popen(
+ ['dpkg-architecture', '-qDEB_HOST_MULTIARCH'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if not process.returncode:
+ output, _ = process.communicate()
+ return loader(os.path.join('/usr/lib/', output.strip(), name))
+ raise
+
+
def _wrap(function, error_code):
"""Add error handling to the given C `function`.
@@ -142,7 +170,7 @@
Raise OSError if LXC is not installed or the container is not found.
"""
try:
- liblxc = ctypes.cdll.LoadLibrary('/usr/lib/lxc/liblxc.so.0')
+ liblxc = _load_library('lxc/liblxc.so.0')
except OSError:
raise _error('not_installed')
get_init_pid = _wrap(liblxc.get_init_pid, 'not_found')
=== modified file 'lplxcip/tests/test_helpers.py'
--- lplxcip/tests/test_helpers.py 2012-05-03 14:20:13 +0000
+++ lplxcip/tests/test_helpers.py 2012-05-09 14:40:56 +0000
@@ -5,6 +5,8 @@
"""Tests for the helpers functions in the lxcip module."""
import ctypes
+import os
+import subprocess
import tempfile
import unittest
@@ -21,6 +23,41 @@
self.assertIn(lxcip.ERRORS['not_found'], str(error))
+class LoadLibraryTest(unittest.TestCase):
+
+ library = 'library'
+
+ def multiarch_loader(self, path):
+ if path == os.path.join('/usr/lib/', self.library):
+ raise OSError
+ return path
+
+ def test_usual_path(self):
+ # Ensure a library residing under `/usr/lib/` is correctly loaded.
+ expected = os.path.join('/usr/lib/', self.library)
+ result = lxcip._load_library(self.library, loader=lambda path: path)
+ self.assertEqual(expected, result)
+
+ def test_host_multiarch_path(self):
+ # Ensure a library residing in `/usr/lib/$DEB_HOST_MULTIARCH/lxc/`
+ # is correctly loaded.
+ try:
+ output = subprocess.check_output(
+ ['dpkg-architecture', '-qDEB_HOST_MULTIARCH'],
+ stderr=subprocess.PIPE)
+ except subprocess.CalledProcessError:
+ self.skipTest('multiarch path not retrievable')
+ expected = os.path.join('/usr/lib/', output.strip(), self.library)
+ result = lxcip._load_library(
+ self.library, loader=self.multiarch_loader)
+ self.assertEqual(expected, result)
+
+ def test_library_not_found(self):
+ # Ensure an OSError is raised if the library is not found.
+ with self.assertRaises(OSError):
+ lxcip._load_library('__does_not_exist__')
+
+
class OutputTest(unittest.TestCase):
interfaces = ['eth0', 'lo']