Add support for Alpine Linux

This change implements support for Alpine Linux and it's package manager
apk.

Task: 22622
Task: 22623
Story: 2002765

Change-Id: I4027e50e33a512fd75a6d6be49c2f7665c4cbc7a
This commit is contained in:
Ehud Kaldor 2018-07-02 13:59:46 -07:00 committed by Joshua Hesketh
parent c373280025
commit 8c9ada45ff
3 changed files with 77 additions and 0 deletions

View File

@ -384,6 +384,9 @@ class Depends(object):
elif distro_id in ["arch"]:
atoms.add("pacman")
self.platform = Pacman()
elif distro_id in ["alpine"]:
atoms.add("apk")
self.platform = Apk()
else:
self.platform = Unknown()
return ["platform:%s" % (atom,) for atom in sorted(atoms)]
@ -530,6 +533,30 @@ class Pacman(Platform):
return elements[1]
class Apk(Platform):
"""apk (Alpine Linux) specific implementation.
This shells out to apk
"""
def get_pkg_version(self, pkg_name):
try:
output = subprocess.check_output(
['apk', 'version', pkg_name],
stderr=subprocess.STDOUT).decode(getpreferredencoding(False))
except subprocess.CalledProcessError as e:
if e.returncode == 1:
return None
raise
# output looks like
# version
output = output.strip()
elements = output.split()
if len(elements) < 4:
return None
return elements[4]
def _eval_diff(operator, diff):
"""Return the boolean result for operator given diff.

View File

@ -0,0 +1,6 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.7.0
PRETTY_NAME="Alpine Linux v3.7"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"

View File

@ -37,6 +37,7 @@ from bindep.depends import Dpkg
from bindep.depends import Emerge
from bindep.depends import Pacman
from bindep.depends import Rpm
from bindep.depends import Apk
# NOTE(notmorgan): In python3 subprocess.check_output returns bytes not
@ -195,6 +196,12 @@ class TestDepends(TestCase):
self.assertThat(
depends.platform_profiles(), Contains("platform:ubuntu"))
def test_detects_alpine(self):
with DistroFixture("Alpine"):
depends = Depends("")
self.assertThat(
depends.platform_profiles(), Contains("platform:alpine"))
def test_detects_release(self):
with DistroFixture("Ubuntu"):
depends = Depends("")
@ -263,6 +270,13 @@ class TestDepends(TestCase):
depends.platform_profiles(), Contains("platform:dpkg"))
self.assertIsInstance(depends.platform, Dpkg)
def test_alpine_implies_apk(self):
with DistroFixture("Alpine"):
depends = Depends("")
self.assertThat(
depends.platform_profiles(), Contains("platform:apk"))
self.assertIsInstance(depends.platform, Apk)
def test_arch_implies_pacman(self):
with DistroFixture("Arch"):
depends = Depends("")
@ -678,6 +692,36 @@ class TestPacman(TestCase):
stderr=subprocess.STDOUT)
class TestApk(TestCase):
def test_unknown_package(self):
platform = Apk()
def _side_effect_raise(*args, **kwargs):
raise subprocess.CalledProcessError(
1, [], b"Installed: Available:")
mock_checkoutput = self.useFixture(
fixtures.MockPatchObject(subprocess, "check_output")).mock
mock_checkoutput.side_effect = _side_effect_raise
self.assertEqual(None, platform.get_pkg_version("foo"))
mock_checkoutput.assert_called_once_with(
['apk', 'version', 'foo'],
stderr=subprocess.STDOUT)
self.assertEqual(None, platform.get_pkg_version("foo"))
def test_installed_version(self):
platform = Apk()
mock_checkoutput = self.useFixture(
fixtures.MockPatchObject(subprocess, "check_output")).mock
mock_checkoutput.return_value = b'Insd: Able: foo-4.0.0-r1 = 4.0.0-r1'
self.assertEqual('4.0.0-r1', platform.get_pkg_version("foo"))
mock_checkoutput.assert_called_once_with(
['apk', 'version', 'foo'],
stderr=subprocess.STDOUT)
class TestRpm(TestCase):
# NOTE: test_not_installed is not implemented as rpm seems to only be aware