|
@@ -31,12 +31,8 @@ author: Hiroaki Nakamura |
|
|
options: |
|
|
options: |
|
|
name: |
|
|
name: |
|
|
description: |
|
|
description: |
|
|
- The name of a atom library to install |
|
|
|
|
|
|
|
|
- The name of a atom library to install or a list of packages |
|
|
required: true |
|
|
required: true |
|
|
version: |
|
|
|
|
|
description: |
|
|
|
|
|
- The version to be installed |
|
|
|
|
|
required: false |
|
|
|
|
|
executable: |
|
|
executable: |
|
|
description: |
|
|
description: |
|
|
- The executable location for apm. |
|
|
- The executable location for apm. |
|
@@ -62,73 +58,44 @@ description: Remove the package "project-manager". |
|
|
''' |
|
|
''' |
|
|
|
|
|
|
|
|
import os |
|
|
import os |
|
|
|
|
|
import json |
|
|
|
|
|
|
|
|
class Apm(object): |
|
|
class Apm(object): |
|
|
def __init__(self, module, **kwargs): |
|
|
def __init__(self, module, **kwargs): |
|
|
self.module = module |
|
|
self.module = module |
|
|
self.name = kwargs['name'] |
|
|
|
|
|
self.version = kwargs['version'] |
|
|
|
|
|
|
|
|
|
|
|
if kwargs['executable']: |
|
|
if kwargs['executable']: |
|
|
self.executable = kwargs['executable'] |
|
|
self.executable = kwargs['executable'] |
|
|
else: |
|
|
else: |
|
|
self.executable = module.get_bin_path('apm', True) |
|
|
self.executable = module.get_bin_path('apm', True) |
|
|
|
|
|
|
|
|
if kwargs['version']: |
|
|
|
|
|
self.name_version = self.name + '@' + self.version |
|
|
|
|
|
else: |
|
|
|
|
|
self.name_version = self.name |
|
|
|
|
|
|
|
|
self.apm_list_result = json.loads(self._exec(['list', '--json'], True)) |
|
|
|
|
|
self.installed_packages = set(map(lambda p: p['name'],self.apm_list_result['user'])) |
|
|
|
|
|
self.apm_installed_packages_list_map = dict(zip(map(lambda p: p['name'],self.apm_list_result['user']),self.apm_list_result['user'])) |
|
|
|
|
|
|
|
|
|
|
|
self.apm_outdated_result = json.loads(self._exec(['outdated', '--json'], True)) |
|
|
|
|
|
self.outdated_packages = set(map(lambda p: p['name'],self.apm_outdated_result)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _exec(self, args, run_in_check_mode=False, check_rc=True): |
|
|
def _exec(self, args, run_in_check_mode=False, check_rc=True): |
|
|
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode): |
|
|
if not self.module.check_mode or (self.module.check_mode and run_in_check_mode): |
|
|
cmd = [self.executable] + args |
|
|
cmd = [self.executable] + args |
|
|
if self.name: |
|
|
|
|
|
cmd.append(self.name_version) |
|
|
|
|
|
rc, out, err = self.module.run_command(cmd, check_rc=check_rc) |
|
|
rc, out, err = self.module.run_command(cmd, check_rc=check_rc) |
|
|
return out |
|
|
return out |
|
|
return '' |
|
|
return '' |
|
|
|
|
|
|
|
|
def list(self): |
|
|
|
|
|
cmd = ['list'] |
|
|
|
|
|
|
|
|
|
|
|
installed = list() |
|
|
|
|
|
missing = list() |
|
|
|
|
|
data = self._exec(cmd, True, False) |
|
|
|
|
|
pattern = re.compile('^(?:\xe2\x94\x9c|\xe2\x94\x94)\xe2\x94\x80\xe2\x94\x80\s+(\S+)@') |
|
|
|
|
|
for dep in data.splitlines(): |
|
|
|
|
|
m = pattern.match(dep) |
|
|
|
|
|
if m: |
|
|
|
|
|
installed.append(m.group(1)) |
|
|
|
|
|
if self.name not in installed: |
|
|
|
|
|
missing.append(self.name) |
|
|
|
|
|
|
|
|
|
|
|
return installed, missing |
|
|
|
|
|
|
|
|
def install(self,args): |
|
|
|
|
|
return self._exec(['install'] + args) |
|
|
|
|
|
|
|
|
def install(self): |
|
|
|
|
|
return self._exec(['install']) |
|
|
|
|
|
|
|
|
|
|
|
def update(self): |
|
|
|
|
|
return self._exec(['update']) |
|
|
|
|
|
|
|
|
|
|
|
def uninstall(self): |
|
|
|
|
|
return self._exec(['uninstall']) |
|
|
|
|
|
|
|
|
|
|
|
def list_outdated(self): |
|
|
|
|
|
outdated = list() |
|
|
|
|
|
data = self._exec(['outdated'], True, False) |
|
|
|
|
|
pattern = re.compile('^(?:\xe2\x94\x9c|\xe2\x94\x94)\xe2\x94\x80\xe2\x94\x80\s+(\S+)') |
|
|
|
|
|
for dep in data.splitlines(): |
|
|
|
|
|
m = pattern.match(dep) |
|
|
|
|
|
if m and m.group(1) != '(empty)': |
|
|
|
|
|
outdated.append(m.group(1)) |
|
|
|
|
|
|
|
|
|
|
|
return outdated |
|
|
|
|
|
|
|
|
def update(self,args): |
|
|
|
|
|
return self._exec(['update'] + args) |
|
|
|
|
|
|
|
|
|
|
|
def uninstall(self,args): |
|
|
|
|
|
return self._exec(['uninstall'] + args) |
|
|
|
|
|
|
|
|
def main(): |
|
|
def main(): |
|
|
arg_spec = dict( |
|
|
arg_spec = dict( |
|
|
name=dict(default=None), |
|
|
|
|
|
version=dict(default=None), |
|
|
|
|
|
|
|
|
packages = dict(default=None, aliases=['pkg', 'name'], type='list'), |
|
|
executable=dict(default=None), |
|
|
executable=dict(default=None), |
|
|
state=dict(default='present', choices=['present', 'absent', 'latest']) |
|
|
state=dict(default='present', choices=['present', 'absent', 'latest']) |
|
|
) |
|
|
) |
|
@@ -137,35 +104,42 @@ def main(): |
|
|
supports_check_mode=True |
|
|
supports_check_mode=True |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
name = module.params['name'] |
|
|
|
|
|
version = module.params['version'] |
|
|
|
|
|
|
|
|
packages = list(module.params['packages']) |
|
|
executable = module.params['executable'] |
|
|
executable = module.params['executable'] |
|
|
state = module.params['state'] |
|
|
state = module.params['state'] |
|
|
|
|
|
|
|
|
if not name: |
|
|
|
|
|
module.fail_json(msg='name must be specified') |
|
|
|
|
|
|
|
|
if not packages: |
|
|
|
|
|
module.fail_json(msg='package must be specified') |
|
|
|
|
|
|
|
|
|
|
|
apm = Apm(module, executable=executable) |
|
|
|
|
|
|
|
|
|
|
|
packages_with_versions = set(map(lambda p: p.split('@',1)[0],filter(lambda p: len(p.split('@'))==2,packages))) |
|
|
|
|
|
packages_without_versions = set(filter(lambda p: len(p.split('@',1))==1,packages)) |
|
|
|
|
|
|
|
|
|
|
|
package_names = list(map(lambda p: p.split('@',1)[0],packages)) |
|
|
|
|
|
package_version_map = dict(zip(package_names, packages)) |
|
|
|
|
|
|
|
|
apm = Apm(module, name=name, version=version, executable=executable) |
|
|
|
|
|
|
|
|
missing_packages = set(package_names).difference(apm.installed_packages) |
|
|
|
|
|
outdated_packages = packages_without_versions.intersection(apm.outdated_packages) |
|
|
|
|
|
packages_with_wrong_version = set(filter(lambda p: package_version_map[p].split('@',1)[1] != apm.apm_installed_packages_list_map[p]['version'],packages_with_versions.intersection(apm.installed_packages))) |
|
|
|
|
|
|
|
|
changed = False |
|
|
|
|
|
if state == 'present': |
|
|
if state == 'present': |
|
|
installed, missing = apm.list() |
|
|
|
|
|
if len(missing): |
|
|
|
|
|
changed = True |
|
|
|
|
|
apm.install() |
|
|
|
|
|
|
|
|
install = list(map(lambda p: package_version_map[p], missing_packages.union(packages_with_wrong_version))) |
|
|
|
|
|
if len(install): |
|
|
|
|
|
output = apm.install(install) |
|
|
|
|
|
module.exit_json(changed=True,output=output,packages=packages,installed=install) |
|
|
elif state == 'latest': |
|
|
elif state == 'latest': |
|
|
installed, missing = apm.list() |
|
|
|
|
|
outdated = apm.list_outdated() |
|
|
|
|
|
if len(missing) or len(outdated): |
|
|
|
|
|
changed = True |
|
|
|
|
|
apm.install() |
|
|
|
|
|
|
|
|
install = list(map(lambda p: package_version_map[p], missing_packages.union(outdated_packages).union(packages_with_wrong_version))) |
|
|
|
|
|
if len(install): |
|
|
|
|
|
output = apm.install(install) |
|
|
|
|
|
module.exit_json(changed=True,output=output,packages=packages,installed=install) |
|
|
else: #absent |
|
|
else: #absent |
|
|
installed, missing = apm.list() |
|
|
|
|
|
if name in installed: |
|
|
|
|
|
changed = True |
|
|
|
|
|
apm.uninstall() |
|
|
|
|
|
|
|
|
uninstall = package_names.intersection(apm.installed_packages) |
|
|
|
|
|
if len(uninstall): |
|
|
|
|
|
output = apm.uninstall(list(uninstall)) |
|
|
|
|
|
module.exit_json(changed=True,output=output,packages=packages,uninstalled=uninstall) |
|
|
|
|
|
|
|
|
module.exit_json(changed=changed) |
|
|
|
|
|
|
|
|
module.exit_json(changed=False,packages=packages) |
|
|
|
|
|
|
|
|
# import module snippets |
|
|
# import module snippets |
|
|
from ansible.module_utils.basic import * |
|
|
from ansible.module_utils.basic import * |
|
|