forked from saltstack/salt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -431,6 +431,7 @@ execution modules | |
smbios | ||
smf_service | ||
smtp | ||
snap | ||
snapper | ||
solaris_fmadm | ||
solaris_group | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
================= | ||
salt.modules.snap | ||
================= | ||
|
||
.. automodule:: salt.modules.snap | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -287,6 +287,7 @@ state modules | |
slack | ||
smartos | ||
smtp | ||
snap | ||
snapper | ||
solrcloud | ||
splunk | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
================ | ||
salt.states.snap | ||
================ | ||
|
||
.. automodule:: salt.states.snap | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Manage snap packages via Salt | ||
:depends: snapd for distribution | ||
""" | ||
|
||
from __future__ import absolute_import, print_function, unicode_literals | ||
|
||
import subprocess | ||
|
||
import salt.utils.path | ||
|
||
SNAP_BINARY_NAME = "snap" | ||
|
||
__virtualname__ = "snap" | ||
|
||
|
||
def __virtual__(): | ||
if salt.utils.path.which("snap"): | ||
return __virtualname__ | ||
|
||
return ( | ||
False, | ||
'The snap execution module cannot be loaded: the "snap" binary is not in the path.', | ||
) | ||
|
||
|
||
def install(pkg, channel=None, refresh=False): | ||
""" | ||
Install the specified snap package from the specified channel. | ||
Returns a dictionary of "result" and "output". | ||
pkg | ||
The snap package name | ||
channel | ||
Optional. The snap channel to install from, eg "beta" | ||
refresh : False | ||
If True, use "snap refresh" instead of "snap install". | ||
This allows changing the channel of a previously installed package. | ||
""" | ||
args = [] | ||
ret = {"result": None, "output": ""} | ||
|
||
if refresh: | ||
cmd = "refresh" | ||
else: | ||
cmd = "install" | ||
|
||
if channel: | ||
args.append("--channel=" + channel) | ||
|
||
try: | ||
# Try to run it, merging stderr into output | ||
ret["output"] = subprocess.check_output( | ||
[SNAP_BINARY_NAME, cmd, pkg] + args, stderr=subprocess.STDOUT | ||
) | ||
ret["result"] = True | ||
except subprocess.CalledProcessError as e: | ||
ret["output"] = e.output | ||
ret["result"] = False | ||
|
||
return ret | ||
|
||
|
||
def is_installed(pkg): | ||
""" | ||
Returns True if there is any version of the specified package installed. | ||
pkg | ||
The package name | ||
""" | ||
return bool(versions_installed(pkg)) | ||
|
||
|
||
def remove(pkg): | ||
""" | ||
Remove the specified snap package. Returns a dictionary of "result" and "output". | ||
pkg | ||
The package name | ||
""" | ||
ret = {"result": None, "output": ""} | ||
try: | ||
ret["output"] = subprocess.check_output([SNAP_BINARY_NAME, "remove", pkg]) | ||
ret["result"] = True | ||
except subprocess.CalledProcessError as e: | ||
ret["output"] = e.output | ||
ret["result"] = False | ||
|
||
|
||
# Parse 'snap list' into a dict | ||
def versions_installed(pkg): | ||
""" | ||
Query which version(s) of the specified snap package are installed. | ||
Returns a list of 0 or more dictionaries. | ||
pkg | ||
The package name | ||
""" | ||
|
||
try: | ||
# Try to run it, merging stderr into output | ||
output = subprocess.check_output( | ||
[SNAP_BINARY_NAME, "list", pkg], stderr=subprocess.STDOUT | ||
) | ||
except subprocess.CalledProcessError: | ||
return [] | ||
|
||
lines = output.splitlines()[1:] | ||
ret = [] | ||
for item in lines: | ||
# If fields contain spaces this will break. | ||
i = item.split() | ||
# Ignore 'Notes' field | ||
ret.append( | ||
{ | ||
"name": i[0], | ||
"version": i[1], | ||
"rev": i[2], | ||
"tracking": i[3], | ||
"publisher": i[4], | ||
} | ||
) | ||
|
||
return ret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Management of snap packages | ||
=============================================== | ||
""" | ||
from __future__ import absolute_import, print_function, unicode_literals | ||
|
||
import salt.utils.path | ||
|
||
__virtualname__ = "snap" | ||
|
||
|
||
def __virtual__(): | ||
if salt.utils.path.which("snap"): | ||
return __virtualname__ | ||
|
||
return ( | ||
False, | ||
'The snap state module cannot be loaded: the "snap" binary is not in the path.', | ||
) | ||
|
||
|
||
def installed(name, channel=None): | ||
""" | ||
Ensure that the named snap package is installed | ||
name | ||
The snap package | ||
channel | ||
Optional. The channel to install the package from. | ||
""" | ||
ret = {"name": name, "changes": {}, "pchanges": {}, "result": None, "comment": ""} | ||
|
||
old = __salt__["snap.versions_installed"](name) | ||
if not old: | ||
if __opts__["test"]: | ||
ret["comment"] = 'Package "{0}" would have been installed'.format(name) | ||
ret["pchanges"]["new"] = name | ||
ret["pchanges"]["old"] = None | ||
ret["result"] = None | ||
return ret | ||
|
||
install = __salt__["snap.install"](name, channel=channel) | ||
if install["result"]: | ||
ret["comment"] = 'Package "{0}" was installed'.format(name) | ||
ret["changes"]["new"] = name | ||
ret["changes"]["old"] = None | ||
ret["result"] = True | ||
return ret | ||
|
||
ret["comment"] = 'Package "{0}" failed to install'.format(name) | ||
ret["comment"] += "\noutput:\n" + install["output"] | ||
ret["result"] = False | ||
return ret | ||
|
||
# Currently snap always returns only one line? | ||
old_channel = old[0]["tracking"] | ||
if old_channel != channel and channel is not None: | ||
if __opts__["test"]: | ||
ret[ | ||
"comment" | ||
] = 'Package "{0}" would have been switched to channel {1}'.format( | ||
name, channel | ||
) | ||
ret["pchanges"]["old_channel"] = old_channel | ||
ret["pchanges"]["new_channel"] = channel | ||
ret["result"] = None | ||
return ret | ||
|
||
refresh = __salt__["snap.install"](name, channel=channel, refresh=True) | ||
if refresh["result"]: | ||
ret["comment"] = 'Package "{0}" was switched to channel {1}'.format( | ||
name, channel | ||
) | ||
ret["pchanges"]["old_channel"] = old_channel | ||
ret["pchanges"]["new_channel"] = channel | ||
ret["result"] = True | ||
return ret | ||
|
||
ret["comment"] = 'Failed to switch Package "{0}" to channel {1}'.format( | ||
name, channel | ||
) | ||
ret["comment"] += "\noutput:\n" + install["output"] | ||
ret["result"] = False | ||
return ret | ||
|
||
ret["comment"] = 'Package "{0}" is already installed'.format(name) | ||
if __opts__["test"]: | ||
ret["result"] = None | ||
return ret | ||
|
||
ret["result"] = True | ||
return ret | ||
|
||
|
||
def removed(name): | ||
""" | ||
Ensure that the named snap package is not installed | ||
name | ||
The snap package | ||
""" | ||
|
||
ret = {"name": name, "changes": {}, "pchanges": {}, "result": None, "comment": ""} | ||
|
||
old = __salt__["snap.versions_installed"](name) | ||
if not old: | ||
ret["comment"] = "Package {0} is not installed".format(name) | ||
ret["result"] = True | ||
return ret | ||
|
||
if __opts__["test"]: | ||
ret["comment"] = "Package {0} would have been removed".format(name) | ||
ret["result"] = None | ||
ret["pchanges"]["old"] = old[0]["version"] | ||
ret["pchanges"]["new"] = None | ||
return ret | ||
|
||
remove = __salt__["snap.remove"](name) | ||
ret["comment"] = "Package {0} removed".format(name) | ||
ret["result"] = True | ||
ret["changes"]["old"] = old[0]["version"] | ||
ret["changes"]["new"] = None | ||
return ret |