Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
53c5b1d9
Commit
53c5b1d9
authored
Dec 13, 2013
by
jctanner
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4949 from eest/openbsd_pkg-rework-name-parsing
openbsd_pkg: rework package name parsing.
parents
dc419121
e66add13
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
116 additions
and
30 deletions
+116
-30
library/packaging/openbsd_pkg
+116
-30
No files found.
library/packaging/openbsd_pkg
View file @
53c5b1d9
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
import
re
import
re
import
shlex
import
shlex
import
syslog
DOCUMENTATION
=
'''
DOCUMENTATION
=
'''
---
---
...
@@ -54,8 +55,13 @@ EXAMPLES = '''
...
@@ -54,8 +55,13 @@ EXAMPLES = '''
- openbsd_pkg: name=nmap state=absent
- openbsd_pkg: name=nmap state=absent
'''
'''
# Control if we write debug information to syslog.
debug
=
False
# Function used for executing commands.
# Function used for executing commands.
def
execute_command
(
cmd
,
module
):
def
execute_command
(
cmd
,
module
):
if
debug
:
syslog
.
syslog
(
"execute_command(): cmd =
%
s"
%
cmd
)
# Break command line into arguments.
# Break command line into arguments.
# This makes run_command() use shell=False which we need to not cause shell
# This makes run_command() use shell=False which we need to not cause shell
# expansion of special characters like '*'.
# expansion of special characters like '*'.
...
@@ -63,33 +69,46 @@ def execute_command(cmd, module):
...
@@ -63,33 +69,46 @@ def execute_command(cmd, module):
return
module
.
run_command
(
cmd_args
)
return
module
.
run_command
(
cmd_args
)
# Function used for getting the name of a currently installed package.
# Function used for getting the name of a currently installed package.
def
get_current_name
(
name
,
specific_version
,
module
):
def
get_current_name
(
name
,
pkg_spec
,
module
):
info_cmd
=
'pkg_info'
info_cmd
=
'pkg_info'
(
rc
,
stdout
,
stderr
)
=
execute_command
(
"
%
s"
%
(
info_cmd
),
module
)
(
rc
,
stdout
,
stderr
)
=
execute_command
(
"
%
s"
%
(
info_cmd
),
module
)
if
rc
!=
0
:
if
rc
!=
0
:
return
(
rc
,
stdout
,
stderr
)
return
(
rc
,
stdout
,
stderr
)
if
specific_version
:
if
pkg_spec
[
'version'
]:
syntax
=
"
%
s"
pattern
=
"^
%
s"
%
name
elif
pkg_spec
[
'flavor'
]:
pattern
=
"^
%
s-.*-
%
s
\
s"
%
(
pkg_spec
[
'stem'
],
pkg_spec
[
'flavor'
])
else
:
else
:
syntax
=
"
%
s-"
pattern
=
"^
%
s-"
%
pkg_spec
[
'stem'
]
if
debug
:
syslog
.
syslog
(
"get_current_name(): pattern =
%
s"
%
pattern
)
for
line
in
stdout
.
splitlines
():
for
line
in
stdout
.
splitlines
():
if
syntax
%
name
in
line
:
if
debug
:
syslog
.
syslog
(
"get_current_name: line =
%
s"
%
line
)
match
=
re
.
search
(
pattern
,
line
)
if
match
:
current_name
=
line
.
split
()[
0
]
current_name
=
line
.
split
()[
0
]
return
current_name
return
current_name
# Function used to find out if a package is currently installed.
# Function used to find out if a package is currently installed.
def
get_package_state
(
name
,
specific_version
,
module
):
def
get_package_state
(
name
,
pkg_spec
,
module
):
info_cmd
=
'pkg_info -e'
info_cmd
=
'pkg_info -e'
if
specific_version
:
if
pkg_spec
[
'version'
]:
syntax
=
"
%
s
%
s"
command
=
"
%
s
%
s"
%
(
info_cmd
,
name
)
elif
pkg_spec
[
'flavor'
]:
command
=
"
%
s
%
s-*-
%
s"
%
(
info_cmd
,
pkg_spec
[
'stem'
],
pkg_spec
[
'flavor'
])
else
:
else
:
syntax
=
"
%
s
%
s-*"
command
=
"
%
s
%
s-*"
%
(
info_cmd
,
pkg_spec
[
'stem'
])
rc
,
stdout
,
stderr
=
execute_command
(
syntax
%
(
info_cmd
,
name
),
module
)
rc
,
stdout
,
stderr
=
execute_command
(
command
,
module
)
if
(
stderr
):
module
.
fail_json
(
msg
=
"failed in get_package_state(): "
+
stderr
)
if
rc
==
0
:
if
rc
==
0
:
return
True
return
True
...
@@ -97,7 +116,7 @@ def get_package_state(name, specific_version, module):
...
@@ -97,7 +116,7 @@ def get_package_state(name, specific_version, module):
return
False
return
False
# Function used to make sure a package is present.
# Function used to make sure a package is present.
def
package_present
(
name
,
installed_state
,
specific_version
,
module
):
def
package_present
(
name
,
installed_state
,
pkg_spec
,
module
):
if
module
.
check_mode
:
if
module
.
check_mode
:
install_cmd
=
'pkg_add -Imn'
install_cmd
=
'pkg_add -Imn'
else
:
else
:
...
@@ -114,12 +133,16 @@ def package_present(name, installed_state, specific_version, module):
...
@@ -114,12 +133,16 @@ def package_present(name, installed_state, specific_version, module):
# When a specific version is supplied the return code will be 0 when
# 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
# a package is found and 1 when it is not, if a version is not
# supplied the tool will exit 0 in both cases:
# supplied the tool will exit 0 in both cases:
if
specific_version
:
if
pkg_spec
[
'version'
]
:
# Depend on the return code.
# Depend on the return code.
if
debug
:
syslog
.
syslog
(
"package_present(): depending on return code"
)
if
rc
:
if
rc
:
changed
=
False
changed
=
False
else
:
else
:
# Depend on stderr instead.
# Depend on stderr instead.
if
debug
:
syslog
.
syslog
(
"package_present(): depending on stderr"
)
if
stderr
:
if
stderr
:
# There is a corner case where having an empty directory in
# There is a corner case where having an empty directory in
# installpath prior to the right location will result in a
# installpath prior to the right location will result in a
...
@@ -129,11 +152,18 @@ def package_present(name, installed_state, specific_version, module):
...
@@ -129,11 +152,18 @@ def package_present(name, installed_state, specific_version, module):
match
=
re
.
search
(
"
\
W
%
s-[^:]+: ok
\
W"
%
name
,
stdout
)
match
=
re
.
search
(
"
\
W
%
s-[^:]+: ok
\
W"
%
name
,
stdout
)
if
match
:
if
match
:
# It turns out we were able to install the package.
# It turns out we were able to install the package.
if
debug
:
syslog
.
syslog
(
"package_present(): we were able to install package"
)
pass
pass
else
:
else
:
# We really did fail, fake the return code.
# We really did fail, fake the return code.
if
debug
:
syslog
.
syslog
(
"package_present(): we really did fail"
)
rc
=
1
rc
=
1
changed
=
False
changed
=
False
else
:
if
debug
:
syslog
.
syslog
(
"package_present(): stderr was not set"
)
if
rc
==
0
:
if
rc
==
0
:
if
module
.
check_mode
:
if
module
.
check_mode
:
...
@@ -150,7 +180,7 @@ def package_present(name, installed_state, specific_version, module):
...
@@ -150,7 +180,7 @@ def package_present(name, installed_state, specific_version, module):
return
(
rc
,
stdout
,
stderr
,
changed
)
return
(
rc
,
stdout
,
stderr
,
changed
)
# Function used to make sure a package is the latest available version.
# Function used to make sure a package is the latest available version.
def
package_latest
(
name
,
installed_state
,
specific_version
,
module
):
def
package_latest
(
name
,
installed_state
,
pkg_spec
,
module
):
if
module
.
check_mode
:
if
module
.
check_mode
:
upgrade_cmd
=
'pkg_add -umn'
upgrade_cmd
=
'pkg_add -umn'
else
:
else
:
...
@@ -160,10 +190,13 @@ def package_latest(name, installed_state, specific_version, module):
...
@@ -160,10 +190,13 @@ def package_latest(name, installed_state, specific_version, module):
if
installed_state
is
True
:
if
installed_state
is
True
:
# Fetch name of currently installed package
# Fetch name of currently installed package.
pre_upgrade_name
=
get_current_name
(
name
,
specific_version
,
module
)
pre_upgrade_name
=
get_current_name
(
name
,
pkg_spec
,
module
)
if
debug
:
syslog
.
syslog
(
"package_latest(): pre_upgrade_name =
%
s"
%
pre_upgrade_name
)
# Attempt to upgrade the package
# Attempt to upgrade the package
.
(
rc
,
stdout
,
stderr
)
=
execute_command
(
"
%
s
%
s"
%
(
upgrade_cmd
,
name
),
module
)
(
rc
,
stdout
,
stderr
)
=
execute_command
(
"
%
s
%
s"
%
(
upgrade_cmd
,
name
),
module
)
# Look for output looking something like "nmap-6.01->6.25: ok" to see if
# Look for output looking something like "nmap-6.01->6.25: ok" to see if
...
@@ -195,7 +228,9 @@ def package_latest(name, installed_state, specific_version, module):
...
@@ -195,7 +228,9 @@ def package_latest(name, installed_state, specific_version, module):
else
:
else
:
# If package was not installed at all just make it present.
# If package was not installed at all just make it present.
return
package_present
(
name
,
installed_state
,
specific_version
,
module
)
if
debug
:
syslog
.
syslog
(
"package_latest(): package is not installed, calling package_present()"
)
return
package_present
(
name
,
installed_state
,
pkg_spec
,
module
)
# Function used to make sure a package is not installed.
# Function used to make sure a package is not installed.
def
package_absent
(
name
,
installed_state
,
module
):
def
package_absent
(
name
,
installed_state
,
module
):
...
@@ -206,7 +241,7 @@ def package_absent(name, installed_state, module):
...
@@ -206,7 +241,7 @@ def package_absent(name, installed_state, module):
if
installed_state
is
True
:
if
installed_state
is
True
:
# Attempt to remove the package
# Attempt to remove the package
.
rc
,
stdout
,
stderr
=
execute_command
(
"
%
s
%
s"
%
(
remove_cmd
,
name
),
module
)
rc
,
stdout
,
stderr
=
execute_command
(
"
%
s
%
s"
%
(
remove_cmd
,
name
),
module
)
if
rc
==
0
:
if
rc
==
0
:
...
@@ -225,6 +260,61 @@ def package_absent(name, installed_state, module):
...
@@ -225,6 +260,61 @@ def package_absent(name, installed_state, module):
return
(
rc
,
stdout
,
stderr
,
changed
)
return
(
rc
,
stdout
,
stderr
,
changed
)
# Function used to parse the package name based on packages-specs(7)
# The general name structure is "stem-version[-flavors]"
def
parse_package_name
(
name
,
pkg_spec
,
module
):
# Do some initial matches so we can base the more advanced regex on that.
version_match
=
re
.
search
(
"-[0-9]"
,
name
)
versionless_match
=
re
.
search
(
"--"
,
name
)
# Stop if someone is giving us a name that both has a version and is
# version-less at the same time.
if
version_match
and
versionless_match
:
module
.
fail_json
(
msg
=
"Package name both has a version and is version-less: "
+
name
)
# If name includes a version.
if
version_match
:
match
=
re
.
search
(
"^(?P<stem>.*)-(?P<version>[0-9][^-]*)(?P<flavor_separator>-)?(?P<flavor>[a-z].*)?$"
,
name
)
if
match
:
pkg_spec
[
'stem'
]
=
match
.
group
(
'stem'
)
pkg_spec
[
'version_separator'
]
=
'-'
pkg_spec
[
'version'
]
=
match
.
group
(
'version'
)
pkg_spec
[
'flavor_separator'
]
=
match
.
group
(
'flavor_separator'
)
pkg_spec
[
'flavor'
]
=
match
.
group
(
'flavor'
)
else
:
module
.
fail_json
(
msg
=
"Unable to parse package name at version_match: "
+
name
)
# If name includes no version but is version-less ("--").
elif
versionless_match
:
match
=
re
.
search
(
"^(?P<stem>.*)--(?P<flavor>[a-z].*)?$"
,
name
)
if
match
:
pkg_spec
[
'stem'
]
=
match
.
group
(
'stem'
)
pkg_spec
[
'version_separator'
]
=
'-'
pkg_spec
[
'version'
]
=
None
pkg_spec
[
'flavor_separator'
]
=
'-'
pkg_spec
[
'flavor'
]
=
match
.
group
(
'flavor'
)
else
:
module
.
fail_json
(
msg
=
"Unable to parse package name at versionless_match: "
+
name
)
# If name includes no version, and is not version-less, it is all a stem.
else
:
match
=
re
.
search
(
"^(?P<stem>.*)$"
,
name
)
if
match
:
pkg_spec
[
'stem'
]
=
match
.
group
(
'stem'
)
pkg_spec
[
'version_separator'
]
=
None
pkg_spec
[
'version'
]
=
None
pkg_spec
[
'flavor_separator'
]
=
None
pkg_spec
[
'flavor'
]
=
None
else
:
module
.
fail_json
(
msg
=
"Unable to parse package name at else: "
+
name
)
# Sanity check that there are no trailing dashes in flavor.
# Try to stop strange stuff early so we can be strict later.
if
pkg_spec
[
'flavor'
]:
match
=
re
.
search
(
"-$"
,
pkg_spec
[
'flavor'
])
if
match
:
module
.
fail_json
(
msg
=
"Trailing dash in flavor: "
+
pkg_spec
[
'flavor'
])
# ===========================================
# ===========================================
# Main control flow
# Main control flow
...
@@ -247,24 +337,20 @@ def main():
...
@@ -247,24 +337,20 @@ def main():
result
[
'name'
]
=
name
result
[
'name'
]
=
name
result
[
'state'
]
=
state
result
[
'state'
]
=
state
# Decide if the name contains a version number.
# Parse package name and put results in the pkg_spec dictionary.
# This regex is based on packages-specs(7).
pkg_spec
=
{}
match
=
re
.
search
(
"-[0-9]"
,
name
)
parse_package_name
(
name
,
pkg_spec
,
module
)
if
match
:
specific_version
=
True
else
:
specific_version
=
False
# Get package state
# Get package state
.
installed_state
=
get_package_state
(
name
,
specific_version
,
module
)
installed_state
=
get_package_state
(
name
,
pkg_spec
,
module
)
# Perform requested action
# Perform requested action
.
if
state
in
[
'installed'
,
'present'
]:
if
state
in
[
'installed'
,
'present'
]:
(
rc
,
stdout
,
stderr
,
changed
)
=
package_present
(
name
,
installed_state
,
specific_version
,
module
)
(
rc
,
stdout
,
stderr
,
changed
)
=
package_present
(
name
,
installed_state
,
pkg_spec
,
module
)
elif
state
in
[
'absent'
,
'removed'
]:
elif
state
in
[
'absent'
,
'removed'
]:
(
rc
,
stdout
,
stderr
,
changed
)
=
package_absent
(
name
,
installed_state
,
module
)
(
rc
,
stdout
,
stderr
,
changed
)
=
package_absent
(
name
,
installed_state
,
module
)
elif
state
==
'latest'
:
elif
state
==
'latest'
:
(
rc
,
stdout
,
stderr
,
changed
)
=
package_latest
(
name
,
installed_state
,
specific_version
,
module
)
(
rc
,
stdout
,
stderr
,
changed
)
=
package_latest
(
name
,
installed_state
,
pkg_spec
,
module
)
if
rc
!=
0
:
if
rc
!=
0
:
if
stderr
:
if
stderr
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment