1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2014, Peter Oliver <ansible@mavit.org.uk>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: pkg5
author:
- Peter Oliver (@mavit)
short_description: Manages packages with the Solaris 11 Image Packaging System
description:
- IPS packages are the native packages in Solaris 11 and higher.
notes:
- The naming of IPS packages is explained at U(http://www.oracle.com/technetwork/articles/servers-storage-admin/ips-package-versioning-2232906.html).
extends_documentation_fragment:
- community.general.attributes
attributes:
check_mode:
support: full
diff_mode:
support: none
options:
name:
description:
- An FRMI of the package(s) to be installed/removed/updated.
- Multiple packages may be specified, separated by V(,).
required: true
type: list
elements: str
state:
description:
- Whether to install (V(present), V(latest)), or remove (V(absent)) a package.
choices: [ absent, latest, present, installed, removed, uninstalled ]
default: present
type: str
accept_licenses:
description:
- Accept any licences.
type: bool
default: false
aliases: [ accept, accept_licences ]
be_name:
description:
- Creates a new boot environment with the given name.
type: str
refresh:
description:
- Refresh publishers before execution.
type: bool
default: true
verbose:
description:
- Set to V(true) to disable quiet execution.
type: bool
default: false
version_added: 9.0.0
'''
EXAMPLES = '''
- name: Install Vim
community.general.pkg5:
name: editor/vim
- name: Install Vim without refreshing publishers
community.general.pkg5:
name: editor/vim
refresh: false
- name: Remove finger daemon
community.general.pkg5:
name: service/network/finger
state: absent
- name: Install several packages at once
community.general.pkg5:
name:
- /file/gnu-findutils
- /text/gnu-grep
'''
import re
from ansible.module_utils.basic import AnsibleModule
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='list', elements='str', required=True),
state=dict(type='str', default='present', choices=['absent', 'installed', 'latest', 'present', 'removed', 'uninstalled']),
accept_licenses=dict(type='bool', default=False, aliases=['accept', 'accept_licences']),
be_name=dict(type='str'),
refresh=dict(type='bool', default=True),
verbose=dict(type='bool', default=False),
),
supports_check_mode=True,
)
params = module.params
packages = []
# pkg(5) FRMIs include a comma before the release number, but
# AnsibleModule will have split this into multiple items for us.
# Try to spot where this has happened and fix it.
for fragment in params['name']:
if re.search(r'^\d+(?:\.\d+)*', fragment) and packages and re.search(r'@[^,]*$', packages[-1]):
packages[-1] += ',' + fragment
else:
packages.append(fragment)
if params['state'] in ['present', 'installed']:
ensure(module, 'present', packages, params)
elif params['state'] in ['latest']:
ensure(module, 'latest', packages, params)
elif params['state'] in ['absent', 'uninstalled', 'removed']:
ensure(module, 'absent', packages, params)
def ensure(module, state, packages, params):
response = {
'results': [],
'msg': '',
}
behaviour = {
'present': {
'filter': lambda p: not is_installed(module, p),
'subcommand': 'install',
},
'latest': {
'filter': lambda p: (
not is_installed(module, p) or not is_latest(module, p)
),
'subcommand': 'install',
},
'absent': {
'filter': lambda p: is_installed(module, p),
'subcommand': 'uninstall',
},
}
if module.check_mode:
dry_run = ['-n']
else:
dry_run = []
if params['accept_licenses']:
accept_licenses = ['--accept']
else:
accept_licenses = []
if params['be_name']:
beadm = ['--be-name=' + module.params['be_name']]
else:
beadm = []
if params['refresh']:
no_refresh = []
else:
no_refresh = ['--no-refresh']
if params['verbose']:
verbosity = []
else:
verbosity = ['-q']
to_modify = list(filter(behaviour[state]['filter'], packages))
if to_modify:
rc, out, err = module.run_command(
['pkg', behaviour[state]['subcommand']] + dry_run + accept_licenses + beadm + no_refresh + verbosity + ['--'] + to_modify)
response['rc'] = rc
response['results'].append(out)
response['msg'] += err
response['changed'] = True
if rc == 4:
response['changed'] = False
response['failed'] = False
elif rc != 0:
module.fail_json(**response)
module.exit_json(**response)
def is_installed(module, package):
rc, out, err = module.run_command(['pkg', 'list', '--', package])
return not bool(int(rc))
def is_latest(module, package):
rc, out, err = module.run_command(['pkg', 'list', '-u', '--', package])
return bool(int(rc))
if __name__ == '__main__':
main()
|