From aaa142d76b1e577be629e9ad669b7aa7cbde148b Mon Sep 17 00:00:00 2001
From: Daniel Heule <hda@sfs.biz>
Date: Wed, 11 Dec 2013 17:11:22 +0100
Subject: [PATCH] __package_zypper can now handle the version parameter

---
 .../__package_zypper/explorer/pkg_version     |  2 +-
 .../conf/type/__package_zypper/gencode-remote | 53 ++++++++++++-------
 cdist/conf/type/__package_zypper/man.text     | 17 ++++--
 .../type/__package_zypper/parameter/optional  |  1 +
 4 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/cdist/conf/type/__package_zypper/explorer/pkg_version b/cdist/conf/type/__package_zypper/explorer/pkg_version
index aaa1da89..7f203067 100644
--- a/cdist/conf/type/__package_zypper/explorer/pkg_version
+++ b/cdist/conf/type/__package_zypper/explorer/pkg_version
@@ -19,7 +19,7 @@
 # along with cdist. If not, see <http://www.gnu.org/licenses/>.
 #
 #
-# Retrieve the status of a package off different types
+# Retrieve the status of a package of different types
 #
 
 if [ -f "$__object/parameter/name" ]; then
diff --git a/cdist/conf/type/__package_zypper/gencode-remote b/cdist/conf/type/__package_zypper/gencode-remote
index ef3bf029..51713590 100644
--- a/cdist/conf/type/__package_zypper/gencode-remote
+++ b/cdist/conf/type/__package_zypper/gencode-remote
@@ -29,42 +29,59 @@
 globalopts="--quiet --non-interactive"
 
 if [ -f "$__object/parameter/name" ]; then
-   name="$__object/parameter/name"
+    name="$__object/parameter/name"
 else
-   name="$__object_id"
+    name="$__object_id"
 fi
 
 if [ -f "$__object/parameter/state" ]; then
-   state_should="$(cat "$__object/parameter/state")"
+    state_should="$(cat "$__object/parameter/state")"
 else
-   state_should="present"
+    state_should="present"
 fi
 
 if [ -f "$__object/parameter/ptype" ]; then
-   ptype="$(cat "$__object/parameter/ptype")"
+    ptype="$(cat "$__object/parameter/ptype")"
 else
-   ptype="package"
+    ptype="package"
+fi
+
+if [ -f "$__object/parameter/version" ]; then
+    version_should="$(cat "$__object/parameter/version")"
+    if [ "$ptype" != "package" ]; then
+        echo "version support only for type package implemented" >&2
+        exit 2
+    fi
+else
+    version_should=""
 fi
 
 pkg_version="$(cat "$__object/explorer/pkg_version")"
 if [ -z "$pkg_version" ]; then
     state_is="absent"
+    version_is=""
 else
     state_is="present"
+    version_is=${pkg_version##* }
 fi
 
-# Exit if nothing is needed to be done
-[ "$state_is" = "$state_should" ] && exit 0
 
 case "$state_should" in
-   present)
-         echo zypper $globalopts install --type \"$ptype\" --auto-agree-with-licenses \"$name\" ">/dev/null"
-   ;;
-   absent)
-         echo zypper $globalopts remove --type \"$ptype\" \"$name\" ">/dev/null"
-   ;;
-   *)
-      echo "Unknown state: $state_should" >&2
-      exit 1
-   ;;
+    present)
+        if [ -z "$version_should" ]; then
+            [ "$state_is" = "present" ] && exit 0 # if state is present, we dont need to do anything
+            echo zypper $globalopts install --type \"$ptype\" --auto-agree-with-licenses \"$name\" ">/dev/null"
+        else
+            [ "$state_is" = "present" ] && [ "$version_should" = "$version_is" ] && exit 0 # if state is present and version is correct, we dont need to do anything
+            echo zypper $globalopts install --oldpackage --type \"$ptype\" --auto-agree-with-licenses \"$name\" = \"$version_should\" ">/dev/null"
+        fi
+    ;;
+    absent)
+        [ "$state_is" = "absent" ] && exit 0 # if state is absent, we dont need to do anything
+        echo zypper $globalopts remove --type \"$ptype\" \"$name\" ">/dev/null"
+    ;;
+    *)
+        echo "Unknown state: $state_should" >&2
+        exit 1
+    ;;
 esac
diff --git a/cdist/conf/type/__package_zypper/man.text b/cdist/conf/type/__package_zypper/man.text
index 465b21be..21c5c5bb 100644
--- a/cdist/conf/type/__package_zypper/man.text
+++ b/cdist/conf/type/__package_zypper/man.text
@@ -1,6 +1,6 @@
 cdist-type__package_zypper(7)
 =============================
-Nico Schottelius <nico-cdist--@--schottelius.org>
+Daniel Heule <hda--@--sfs.biz>
 
 
 NAME
@@ -26,6 +26,11 @@ name::
 state::
     Either "present" or "absent", defaults to "present"
 
+version::
+    The version of the package to install. Default is to install the version
+    choosen by the local package manager. For a list of version have a look to
+    the output of "zypper se -s packagename"
+
 ptype::
     Either "package", "patch", "pattern", "product" or "srcpackage", defaults to "package". For a description see man zypper.
 
@@ -34,12 +39,15 @@ EXAMPLES
 --------
 
 --------------------------------------------------------------------------------
-# Ensure zsh in installed
+# Ensure zsh is installed
 __package_zypper zsh --state present
 
 # If you don't want to follow pythonX packages, but always use python
 __package_zypper python --state present --name python2
 
+# Ensure binutils is installed and the version is forced to be 2.23.1-0.19.2
+__package_zypper binutils --state present --version 2.23.1-0.19.2
+
 # Remove package
 __package_zypper cfengine --state absent
 
@@ -56,5 +64,6 @@ SEE ALSO
 
 COPYING
 -------
-Copyright \(C) 2012 Nico Schottelius. Free use of this software is
-granted under the terms of the GNU General Public License version 3 (GPLv3).
+Copyright \(C) 2012 Nico Schottelius.
+Copyright \(C) 2013 Daniel Heule.
+Free use of this software is granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/cdist/conf/type/__package_zypper/parameter/optional b/cdist/conf/type/__package_zypper/parameter/optional
index b484bf07..bc8565fc 100644
--- a/cdist/conf/type/__package_zypper/parameter/optional
+++ b/cdist/conf/type/__package_zypper/parameter/optional
@@ -1,3 +1,4 @@
 name
 state
 ptype
+version