FEAT: first short at installing .pkg/.mpkg on OS X.

This commit is contained in:
David Cournapeau 2014-12-17 09:58:35 -08:00
parent 71bba6c676
commit 236ec08250
2 changed files with 153 additions and 0 deletions

View File

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
'''
Installer support for OS X.
Installer is the native .pkg/.mpkg package manager for OS X.
'''
import os.path
from salt.ext.six.moves import urllib
PKGUTIL = "/usr/sbin/pkgutil"
def __virtual__():
'''
Set the virtual pkg module if the os is Solaris
'''
if __grains__['os'] == 'MacOS':
return 'darwin_pkgutil'
return False
def list():
'''
List the installed packages.
'''
cmd = PKGUTIL + ' --pkgs'
return __salt__['cmd.run_stdout'](cmd)
def is_installed(package_id):
'''
Returns whether a given package id is installed.
'''
def has_package_id(lines):
for line in lines:
if line == package_id:
return True
return False
cmd = PKGUTIL + ' --pkgs'
out = __salt__['cmd.run_stdout'](cmd)
return has_package_id(out.splitlines())
def _install_from_path(path):
if not os.path.exists(path):
msg = "Path {0!r} does not exist, cannot install".format(path)
raise ValueError(msg)
else:
cmd = 'installer -pkg "{0}" -target /'.format(path)
return __salt__['cmd.retcode'](cmd)
def install(source, package_id=None):
'''
Install a .pkg from an URI or an absolute path.
'''
if package_id is not None and is_installed(package_id):
return ''
uri = urllib.parse.urlparse(source)
if uri.scheme == "":
return _install_from_path(source)
else:
msg = "Unsupported scheme for source uri: {0!r}".format(uri.scheme)
raise ValueError(msg)

View File

@ -0,0 +1,85 @@
from salt.modules import darwin_pkgutil
from salttesting import TestCase, skipIf
from salttesting.mock import NO_MOCK, NO_MOCK_REASON, MagicMock, patch
darwin_pkgutil.__salt__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
class DarwingPkgutilTestCase(TestCase):
def test_list_installed_command(self):
# Given
r_output = "com.apple.pkg.iTunes"
# When
mock_cmd = MagicMock(return_value=r_output)
with patch.dict(darwin_pkgutil.__salt__, {'cmd.run_stdout': mock_cmd}):
output = darwin_pkgutil.list()
# Then
mock_cmd.assert_called_with("/usr/sbin/pkgutil --pkgs")
def test_list_installed_output(self):
# Given
r_output = "com.apple.pkg.iTunes"
# When
mock_cmd = MagicMock(return_value=r_output)
with patch.dict(darwin_pkgutil.__salt__, {'cmd.run_stdout': mock_cmd}):
output = darwin_pkgutil.list()
# Then
self.assertEqual(output, r_output)
def test_is_installed(self):
# Given
r_output = "com.apple.pkg.iTunes"
# When
mock_cmd = MagicMock(return_value=r_output)
with patch.dict(darwin_pkgutil.__salt__, {'cmd.run_stdout': mock_cmd}):
ret = darwin_pkgutil.is_installed("com.apple.pkg.iTunes")
# Then
self.assertTrue(ret)
# When
with patch.dict(darwin_pkgutil.__salt__, {'cmd.run_stdout': mock_cmd}):
ret = darwin_pkgutil.is_installed("com.apple.pkg.Safari")
# Then
self.assertFalse(ret)
def test_install(self):
# Given
source = "/foo/bar/fubar.pkg"
package_id = "com.foo.fubar.pkg"
# When
mock_cmd = MagicMock(return_value=True)
with patch("salt.modules.darwin_pkgutil.is_installed",
return_value=False) as is_installed:
with patch("salt.modules.darwin_pkgutil._install_from_path",
return_value=True) as _install_from_path:
ret = darwin_pkgutil.install(source, package_id)
# Then
_install_from_path.assert_called_with(source)
def test_install_already_there(self):
# Given
source = "/foo/bar/fubar.pkg"
package_id = "com.foo.fubar.pkg"
# When
mock_cmd = MagicMock(return_value=True)
with patch("salt.modules.darwin_pkgutil.is_installed",
return_value=True) as is_installed:
with patch("salt.modules.darwin_pkgutil._install_from_path",
return_value=True) as _install_from_path:
ret = darwin_pkgutil.install(source, package_id)
# Then
self.assertEqual(_install_from_path.called, 0)