summaryrefslogtreecommitdiff
path: root/packaging/os
diff options
context:
space:
mode:
authorBrian Coca <bcoca@ansible.com>2016-01-19 09:11:41 -0500
committerBrian Coca <bcoca@ansible.com>2016-01-19 09:11:41 -0500
commitad2208c7b593d5df5e96dfc0c005d070717356dc (patch)
tree0a8b363f3b00e64f1087c161d4a2c654d37a3333 /packaging/os
parente9450df878632531fae574b5eaf28bf0f7916948 (diff)
parent2b69a2b14c6d4c88281eaaf885b6fb4becbf8f5f (diff)
downloadansible-modules-extras-ad2208c7b593d5df5e96dfc0c005d070717356dc.tar.gz
Merge pull request #1201 from bonds/devel
add ports support to openbsd_pkg
Diffstat (limited to 'packaging/os')
-rw-r--r--packaging/os/openbsd_pkg.py112
1 files changed, 109 insertions, 3 deletions
diff --git a/packaging/os/openbsd_pkg.py b/packaging/os/openbsd_pkg.py
index 13cafa26..a72140b3 100644
--- a/packaging/os/openbsd_pkg.py
+++ b/packaging/os/openbsd_pkg.py
@@ -18,8 +18,10 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+import os
import re
import shlex
+import sqlite3
DOCUMENTATION = '''
---
@@ -29,6 +31,7 @@ version_added: "1.1"
short_description: Manage packages on OpenBSD.
description:
- Manage packages on OpenBSD using the pkg tools.
+requirements: [ "python >= 2.5" ]
options:
name:
required: true
@@ -41,6 +44,23 @@ options:
- C(present) will make sure the package is installed.
C(latest) will make sure the latest version of the package is installed.
C(absent) will make sure the specified package is not installed.
+ build:
+ required: false
+ choices: [ yes, no ]
+ default: no
+ description:
+ - Build the package from source instead of downloading and installing
+ a binary. Requires that the port source tree is already installed.
+ Automatically builds and installs the 'sqlports' package, if it is
+ not already installed.
+ version_added: "2.1"
+ ports_dir:
+ required: false
+ default: /usr/ports
+ description:
+ - When used in combination with the 'build' option, allows overriding
+ the default ports source directory.
+ version_added: "2.1"
'''
EXAMPLES = '''
@@ -53,6 +73,9 @@ EXAMPLES = '''
# Make sure nmap is not installed
- openbsd_pkg: name=nmap state=absent
+# Make sure nmap is installed, build it from source if it is not
+- openbsd_pkg: name=nmap state=present build=yes
+
# Specify a pkg flavour with '--'
- openbsd_pkg: name=vim--nox11 state=present
@@ -118,15 +141,33 @@ def get_package_state(name, pkg_spec, module):
# Function used to make sure a package is present.
def package_present(name, installed_state, pkg_spec, module):
+ build = module.params['build']
+
if module.check_mode:
install_cmd = 'pkg_add -Imn'
else:
- install_cmd = 'pkg_add -Im'
+ if build is True:
+ port_dir = "%s/%s" % (module.params['ports_dir'], get_package_source_path(name, pkg_spec, module))
+ if os.path.isdir(port_dir):
+ if pkg_spec['flavor']:
+ flavors = pkg_spec['flavor'].replace('-', ' ')
+ install_cmd = "cd %s && make clean=depends && FLAVOR=\"%s\" make install && make clean=depends" % (port_dir, flavors)
+ elif pkg_spec['subpackage']:
+ install_cmd = "cd %s && make clean=depends && SUBPACKAGE=\"%s\" make install && make clean=depends" % (port_dir, pkg_spec['subpackage'])
+ else:
+ install_cmd = "cd %s && make install && make clean=depends" % (port_dir)
+ else:
+ module.fail_json(msg="the port source directory %s does not exist" % (port_dir))
+ else:
+ install_cmd = 'pkg_add -Im'
if installed_state is False:
# Attempt to install the package
- (rc, stdout, stderr) = execute_command("%s %s" % (install_cmd, name), module)
+ if build is True and not module.check_mode:
+ (rc, stdout, stderr) = module.run_command(install_cmd, module, use_unsafe_shell=True)
+ else:
+ (rc, stdout, stderr) = execute_command("%s %s" % (install_cmd, name), module)
# The behaviour of pkg_add is a bit different depending on if a
# specific version is supplied or not.
@@ -134,7 +175,7 @@ def package_present(name, installed_state, pkg_spec, module):
# When a specific version is supplied the return code will be 0 when
# a package is found and 1 when it is not, if a version is not
# supplied the tool will exit 0 in both cases:
- if pkg_spec['version']:
+ if pkg_spec['version'] or build is True:
# Depend on the return code.
module.debug("package_present(): depending on return code")
if rc:
@@ -177,6 +218,10 @@ def package_present(name, installed_state, pkg_spec, module):
# Function used to make sure a package is the latest available version.
def package_latest(name, installed_state, pkg_spec, module):
+
+ if module.params['build'] is True:
+ module.fail_json(msg="the combination of build=%s and state=latest is not supported" % module.params['build'])
+
if module.check_mode:
upgrade_cmd = 'pkg_add -umn'
else:
@@ -275,6 +320,7 @@ def parse_package_name(name, pkg_spec, module):
pkg_spec['version'] = match.group('version')
pkg_spec['flavor_separator'] = match.group('flavor_separator')
pkg_spec['flavor'] = match.group('flavor')
+ pkg_spec['style'] = 'version'
else:
module.fail_json(msg="Unable to parse package name at version_match: " + name)
@@ -287,6 +333,7 @@ def parse_package_name(name, pkg_spec, module):
pkg_spec['version'] = None
pkg_spec['flavor_separator'] = '-'
pkg_spec['flavor'] = match.group('flavor')
+ pkg_spec['style'] = 'versionless'
else:
module.fail_json(msg="Unable to parse package name at versionless_match: " + name)
@@ -299,6 +346,7 @@ def parse_package_name(name, pkg_spec, module):
pkg_spec['version'] = None
pkg_spec['flavor_separator'] = None
pkg_spec['flavor'] = None
+ pkg_spec['style'] = 'stem'
else:
module.fail_json(msg="Unable to parse package name at else: " + name)
@@ -309,6 +357,48 @@ def parse_package_name(name, pkg_spec, module):
if match:
module.fail_json(msg="Trailing dash in flavor: " + pkg_spec['flavor'])
+# Function used for figuring out the port path.
+def get_package_source_path(name, pkg_spec, module):
+ pkg_spec['subpackage'] = None
+ if pkg_spec['stem'] == 'sqlports':
+ return 'databases/sqlports'
+ else:
+ # try for an exact match first
+ conn = sqlite3.connect('/usr/local/share/sqlports')
+ first_part_of_query = 'SELECT fullpkgpath, fullpkgname FROM ports WHERE fullpkgname'
+ query = first_part_of_query + ' = ?'
+ cursor = conn.execute(query, (name,))
+ results = cursor.fetchall()
+
+ # next, try for a fuzzier match
+ if len(results) < 1:
+ looking_for = pkg_spec['stem'] + (pkg_spec['version_separator'] or '-') + (pkg_spec['version'] or '%')
+ query = first_part_of_query + ' LIKE ?'
+ if pkg_spec['flavor']:
+ looking_for += pkg_spec['flavor_separator'] + pkg_spec['flavor']
+ cursor = conn.execute(query, (looking_for,))
+ elif pkg_spec['style'] == 'versionless':
+ query += ' AND fullpkgname NOT LIKE ?'
+ cursor = conn.execute(query, (looking_for, "%s-%%" % looking_for,))
+ else:
+ cursor = conn.execute(query, (looking_for,))
+ results = cursor.fetchall()
+
+ # error if we don't find exactly 1 match
+ conn.close()
+ if len(results) < 1:
+ module.fail_json(msg="could not find a port by the name '%s'" % name)
+ if len(results) > 1:
+ matches = map(lambda x:x[1], results)
+ module.fail_json(msg="too many matches, unsure which to build: %s" % ' OR '.join(matches))
+
+ # there's exactly 1 match, so figure out the subpackage, if any, then return
+ fullpkgpath = results[0][0]
+ parts = fullpkgpath.split(',')
+ if len(parts) > 1 and parts[1][0] == '-':
+ pkg_spec['subpackage'] = parts[1]
+ return parts[0]
+
# Function used for upgrading all installed packages.
def upgrade_packages(module):
if module.check_mode:
@@ -348,12 +438,16 @@ def main():
argument_spec = dict(
name = dict(required=True),
state = dict(required=True, choices=['absent', 'installed', 'latest', 'present', 'removed']),
+ build = dict(default='no', type='bool'),
+ ports_dir = dict(default='/usr/ports'),
),
supports_check_mode = True
)
name = module.params['name']
state = module.params['state']
+ build = module.params['build']
+ ports_dir = module.params['ports_dir']
rc = 0
stdout = ''
@@ -361,6 +455,18 @@ def main():
result = {}
result['name'] = name
result['state'] = state
+ result['build'] = build
+
+ if build is True:
+ if not os.path.isdir(ports_dir):
+ module.fail_json(msg="the ports source directory %s does not exist" % (ports_dir))
+
+ # build sqlports if its not installed yet
+ pkg_spec = {}
+ parse_package_name('sqlports', pkg_spec, module)
+ installed_state = get_package_state(name, pkg_spec, module)
+ if not installed_state:
+ package_present('sqlports', installed_state, pkg_spec, module)
if name == '*':
if state != 'latest':