forked from ungleich-public/cdist
		
	Merge branch 'master' into __package_absent_present
This commit is contained in:
		
				commit
				
					
						605eaeb039
					
				
			
		
					 51 changed files with 1002 additions and 427 deletions
				
			
		
							
								
								
									
										2
									
								
								README
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								README
									
										
									
									
									
								
							| 
						 | 
					@ -89,7 +89,7 @@ cdist was tested or is know to run on at least
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Installation
 | 
					## Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Preperation
 | 
					### Preparation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ensure you have Python 3.2 installed on the machine you use to **deploy to the targets**
 | 
					Ensure you have Python 3.2 installed on the machine you use to **deploy to the targets**
 | 
				
			||||||
(the ***source host***).
 | 
					(the ***source host***).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								build
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								build
									
										
									
									
									
								
							| 
						 | 
					@ -85,7 +85,7 @@ case "$1" in
 | 
				
			||||||
   ;;
 | 
					   ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   release)
 | 
					   release)
 | 
				
			||||||
      "$0" clean && "$0" man && "$0" web
 | 
					        ./doc/dev/releasechecklist
 | 
				
			||||||
   ;;
 | 
					   ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   speeches)
 | 
					   speeches)
 | 
				
			||||||
| 
						 | 
					@ -113,8 +113,8 @@ case "$1" in
 | 
				
			||||||
      # cp ${SPEECHESDIR}/*.pdf ${WEBDIR}/${WEBBASE}/speeches
 | 
					      # cp ${SPEECHESDIR}/*.pdf ${WEBDIR}/${WEBBASE}/speeches
 | 
				
			||||||
      # git describe > ${WEBDIR}/${WEBBASE}/man/VERSION
 | 
					      # git describe > ${WEBDIR}/${WEBBASE}/man/VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      cp ${MAN1DSTDIR}/*.html ${WEBMAN}/man1 
 | 
					      cp ${MAN1DSTDIR}/*.html ${MAN1DSTDIR}/*.css ${WEBMAN}/man1 
 | 
				
			||||||
      cp ${MAN7DSTDIR}/*.html ${WEBMAN}/man7
 | 
					      cp ${MAN7DSTDIR}/*.html ${MAN7DSTDIR}/*.css ${WEBMAN}/man7
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      cd ${WEBDIR} && git add ${WEBBASE}
 | 
					      cd ${WEBDIR} && git add ${WEBBASE}
 | 
				
			||||||
      cd ${WEBDIR} && git commit -m "cdist update" ${WEBBASE} ${WEBPAGE}
 | 
					      cd ${WEBDIR} && git commit -m "cdist update" ${WEBBASE} ${WEBPAGE}
 | 
				
			||||||
| 
						 | 
					@ -123,7 +123,7 @@ case "$1" in
 | 
				
			||||||
      # Fix ikiwiki, which does not like symlinks for pseudo security
 | 
					      # Fix ikiwiki, which does not like symlinks for pseudo security
 | 
				
			||||||
      ssh tee.schottelius.org \
 | 
					      ssh tee.schottelius.org \
 | 
				
			||||||
        "cd /home/services/www/nico/www.nico.schottelius.org/www/software/cdist/man &&
 | 
					        "cd /home/services/www/nico/www.nico.schottelius.org/www/software/cdist/man &&
 | 
				
			||||||
            ln -sf "$version" latest"
 | 
					            rm -f latest && ln -sf "$version" latest"
 | 
				
			||||||
   ;;
 | 
					   ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   p|pu|pub)
 | 
					   p|pu|pub)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								conf/explorer/runlevel
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										26
									
								
								conf/explorer/runlevel
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This file is part of cdist.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set +e
 | 
				
			||||||
 | 
					executable=$(which runlevel 2>/dev/null)
 | 
				
			||||||
 | 
					if [ -x "$executable" ]; then
 | 
				
			||||||
 | 
					   "$executable" | awk '{ print $2 }'
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
							
								
								
									
										53
									
								
								conf/type/__key_value/explorer/state
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										53
									
								
								conf/type/__key_value/explorer/state
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This file is part of cdist.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					key="$(cat "$__object/parameter/key" 2>/dev/null \
 | 
				
			||||||
 | 
					   || echo "$__object_id")"
 | 
				
			||||||
 | 
					state="$(cat "$__object/parameter/state" 2>/dev/null \
 | 
				
			||||||
 | 
					   || echo "present")"
 | 
				
			||||||
 | 
					file="$(cat "$__object/parameter/file")"
 | 
				
			||||||
 | 
					delimiter="$(cat "$__object/parameter/delimiter")"
 | 
				
			||||||
 | 
					value="$(cat "$__object/parameter/value" 2>/dev/null \
 | 
				
			||||||
 | 
					   || echo "__CDIST_NOTSET__")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case "$state" in
 | 
				
			||||||
 | 
					   absent)
 | 
				
			||||||
 | 
					      if grep -q -E "^$key$delimiter+" "$file"; then
 | 
				
			||||||
 | 
					         # if the key exists, with whatever value, we will have to remove it
 | 
				
			||||||
 | 
					         # so report it as present
 | 
				
			||||||
 | 
					         echo present
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					         # key does not exist
 | 
				
			||||||
 | 
					         echo absent
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					   ;;
 | 
				
			||||||
 | 
					   present)
 | 
				
			||||||
 | 
					      if grep -q -E "^$key$delimiter+$value$" "$file"; then
 | 
				
			||||||
 | 
					         # key exists and value is same
 | 
				
			||||||
 | 
					         echo present
 | 
				
			||||||
 | 
					      elif grep -q -E "^$key$delimiter+" "$file"; then
 | 
				
			||||||
 | 
					         # key exists, but value is empty or different
 | 
				
			||||||
 | 
					         echo wrongvalue
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					         # key does not exist
 | 
				
			||||||
 | 
					         echo absent
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					   ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
| 
						 | 
					@ -18,35 +18,40 @@
 | 
				
			||||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
value_is="$(cat "$__object/explorer/value")"
 | 
					 | 
				
			||||||
value_should="$(cat "$__object/parameter/value")"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
key="$(cat "$__object/parameter/key")"
 | 
					key="$(cat "$__object/parameter/key")"
 | 
				
			||||||
file="$(cat "$__object/parameter/file")"
 | 
					file="$(cat "$__object/parameter/file")"
 | 
				
			||||||
delimiter="$(cat "$__object/parameter/delimiter")"
 | 
					delimiter="$(cat "$__object/parameter/delimiter")"
 | 
				
			||||||
 | 
					value="$(cat "$__object/parameter/value")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [ "$value_is" != "$value_should" ]; then
 | 
					state_is="$(cat "$__object/explorer/state")"
 | 
				
			||||||
   case "$value_is" in
 | 
					state_should="$(cat "$__object/parameter/state")"
 | 
				
			||||||
      __NOTSET__)
 | 
					 | 
				
			||||||
         # add key and value
 | 
					 | 
				
			||||||
         echo "echo \"${key}${delimiter}${value_should}\" >> \"$file\""
 | 
					 | 
				
			||||||
      ;;
 | 
					 | 
				
			||||||
      *)
 | 
					 | 
				
			||||||
         if [ "$value_should" = '__NOTSET__' ]; then
 | 
					 | 
				
			||||||
            # remove key and value
 | 
					 | 
				
			||||||
            cat << DONE
 | 
					 | 
				
			||||||
sed -i '/^${key}/d' "$file"
 | 
					 | 
				
			||||||
DONE
 | 
					 | 
				
			||||||
         else
 | 
					 | 
				
			||||||
            # change value
 | 
					 | 
				
			||||||
            cat << DONE
 | 
					 | 
				
			||||||
awk -F "$delimiter" '
 | 
					 | 
				
			||||||
/${key}${delimiter}*/{gsub("$value_is", "$value_should")};{print}' "$file" > "${file}+" \
 | 
					 | 
				
			||||||
&& mv "${file}+" "$file"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DONE
 | 
					if [ "$state_is" = "$state_should" ]; then
 | 
				
			||||||
         fi
 | 
					   # nothing to do
 | 
				
			||||||
      ;;
 | 
					   exit 0
 | 
				
			||||||
   esac
 | 
					 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case "$state_should" in
 | 
				
			||||||
 | 
					   absent)
 | 
				
			||||||
 | 
					      # remove lines starting with key
 | 
				
			||||||
 | 
					      echo "sed -i '/^$key\($delimiter\+\)/d' \"$file\""
 | 
				
			||||||
 | 
					   ;;
 | 
				
			||||||
 | 
					   present)
 | 
				
			||||||
 | 
					      case "$state_is" in
 | 
				
			||||||
 | 
					         absent)
 | 
				
			||||||
 | 
					            # add new key and value
 | 
				
			||||||
 | 
					            echo "echo \"${key}${delimiter}${value}\" >> \"$file\""
 | 
				
			||||||
 | 
					         ;;
 | 
				
			||||||
 | 
					         wrongvalue)
 | 
				
			||||||
 | 
					            # change exisiting value
 | 
				
			||||||
 | 
					            echo "sed -i \"s|^$key\($delimiter\+\).*|$key\1$value|\" \"$file\""
 | 
				
			||||||
 | 
					         ;;
 | 
				
			||||||
 | 
					         *)
 | 
				
			||||||
 | 
					            echo "Unknown explorer state: $state_is" >&2
 | 
				
			||||||
 | 
					            exit 1
 | 
				
			||||||
 | 
					      esac
 | 
				
			||||||
 | 
					   ;;
 | 
				
			||||||
 | 
					   *)
 | 
				
			||||||
 | 
					      echo "Unknown state: $state_should" >&2
 | 
				
			||||||
 | 
					      exit 1
 | 
				
			||||||
 | 
					esac 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,9 +16,6 @@ file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
REQUIRED PARAMETERS
 | 
					REQUIRED PARAMETERS
 | 
				
			||||||
-------------------
 | 
					-------------------
 | 
				
			||||||
value::
 | 
					 | 
				
			||||||
   The value for the key. Setting the value to `__NOTSET__` will remove the key
 | 
					 | 
				
			||||||
   from the file.
 | 
					 | 
				
			||||||
file::
 | 
					file::
 | 
				
			||||||
   The file to operate on.
 | 
					   The file to operate on.
 | 
				
			||||||
delimiter::
 | 
					delimiter::
 | 
				
			||||||
| 
						 | 
					@ -27,8 +24,13 @@ delimiter::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OPTIONAL PARAMETERS
 | 
					OPTIONAL PARAMETERS
 | 
				
			||||||
-------------------
 | 
					-------------------
 | 
				
			||||||
 | 
					state::
 | 
				
			||||||
 | 
					   present or absent, defaults to present. If present, sets the key to value,
 | 
				
			||||||
 | 
					   if absent, removes the key from the file.
 | 
				
			||||||
key::
 | 
					key::
 | 
				
			||||||
   The key to change. Defaults to object_id.
 | 
					   The key to change. Defaults to object_id.
 | 
				
			||||||
 | 
					value::
 | 
				
			||||||
 | 
					   The value for the key. Optional if state=absent, required otherwise.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXAMPLES
 | 
					EXAMPLES
 | 
				
			||||||
| 
						 | 
					@ -45,6 +47,9 @@ __key_value my-fancy-id --file /etc/login.defs --key SYS_UID_MAX --value 666 \
 | 
				
			||||||
# Enable packet forwarding
 | 
					# Enable packet forwarding
 | 
				
			||||||
__key_value net.ipv4.ip_forward --file /etc/sysctl.conf --value 1 \
 | 
					__key_value net.ipv4.ip_forward --file /etc/sysctl.conf --value 1 \
 | 
				
			||||||
   --delimiter '='
 | 
					   --delimiter '='
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Remove existing key/value
 | 
				
			||||||
 | 
					__key_value LEGACY_KEY --file /etc/somefile --state absent --delimiter '=' 
 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,9 +18,13 @@
 | 
				
			||||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [ -f "$__object/parameter/key" ]; then
 | 
					# set defaults
 | 
				
			||||||
   key="$(cat "$__object/parameter/key")"
 | 
					key="$(cat "$__object/parameter/key" 2>/dev/null \
 | 
				
			||||||
else
 | 
					   || echo "$__object_id" | tee "$__object/parameter/key")"
 | 
				
			||||||
   echo "$__object_id" > "$__object/parameter/key"
 | 
					state="$(cat "$__object/parameter/state" 2>/dev/null \
 | 
				
			||||||
fi
 | 
					   || echo "present" | tee "$__object/parameter/state")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$state" = "present" -a ! -f "$__object/parameter/value" ]; then
 | 
				
			||||||
 | 
					   echo "Missing required parameter 'value'" >&2
 | 
				
			||||||
 | 
					   exit 1
 | 
				
			||||||
 | 
					fi 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1 +1,3 @@
 | 
				
			||||||
key
 | 
					key
 | 
				
			||||||
 | 
					value
 | 
				
			||||||
 | 
					state
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,2 @@
 | 
				
			||||||
value
 | 
					 | 
				
			||||||
file
 | 
					file
 | 
				
			||||||
delimiter
 | 
					delimiter
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,14 +35,15 @@ else
 | 
				
			||||||
    pip="pip"
 | 
					    pip="pip"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# which is not posix, but command is :-)
 | 
					# If there is no pip, it may get created from somebody else.
 | 
				
			||||||
 | 
					# If it will be created, there is probably no package installed.
 | 
				
			||||||
if ! command -v "$pip" >/dev/null 2>&1; then
 | 
					if ! command -v "$pip" >/dev/null 2>&1; then
 | 
				
			||||||
    echo "No usable pip found at path \"$pip\"" >&2
 | 
					 | 
				
			||||||
    exit 1
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if "$pip" freeze | grep -i -q "^$name=="; then
 | 
					 | 
				
			||||||
    echo present
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
    echo absent
 | 
					    echo absent
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if "$pip" freeze | grep -i -q "^$name=="; then
 | 
				
			||||||
 | 
					        echo present
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        echo absent
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
cdist-type__package_pip(7)
 | 
					cdist-type__package_pip(7)
 | 
				
			||||||
=============================
 | 
					==========================
 | 
				
			||||||
Nico Schottelius <nico-cdist--@--schottelius.org>
 | 
					Nico Schottelius <nico-cdist--@--schottelius.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										64
									
								
								conf/type/__start_on_boot/explorer/state
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										64
									
								
								conf/type/__start_on_boot/explorer/state
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This file is part of cdist.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Check whether the given name will be started on boot or not
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					os=$("$__explorer/os")
 | 
				
			||||||
 | 
					runlevel=$("$__explorer/runlevel")
 | 
				
			||||||
 | 
					name="$__object_id"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case "$os" in
 | 
				
			||||||
 | 
					    archlinux)
 | 
				
			||||||
 | 
					        # convert bash array to shell
 | 
				
			||||||
 | 
					        daemons=$(grep ^DAEMONS /etc/rc.conf | sed -e 's/^.*=(//' -e 's/)$//')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # absent, as long as not found
 | 
				
			||||||
 | 
					        state="absent"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # iterate, last one wins.
 | 
				
			||||||
 | 
					        for daemon in $daemons; do
 | 
				
			||||||
 | 
					            if [ "$daemon" = "$name" -o "$daemon" = "@${name}" ]; then
 | 
				
			||||||
 | 
					                state="present"
 | 
				
			||||||
 | 
					            elif [ "$daemon" = "!${name}" ]; then
 | 
				
			||||||
 | 
					                state="absent"
 | 
				
			||||||
 | 
					            fi
 | 
				
			||||||
 | 
					        done
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    debian|ubuntu)
 | 
				
			||||||
 | 
					        state="present"
 | 
				
			||||||
 | 
					        [ -f "/etc/rc$runlevel.d/S"??"$name" ] || state="absent"
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    centos|fedora|owl|redhat)
 | 
				
			||||||
 | 
					        state="present"
 | 
				
			||||||
 | 
					        state=$(chkconfig --level "$runlevel" \"$name\" || echo absent)
 | 
				
			||||||
 | 
					        [ "$state" ] || state="present"
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *)  
 | 
				
			||||||
 | 
					       echo "Unsupported os: $os" >&2
 | 
				
			||||||
 | 
					       exit 1
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo $state
 | 
				
			||||||
							
								
								
									
										89
									
								
								conf/type/__start_on_boot/gencode-remote
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										89
									
								
								conf/type/__start_on_boot/gencode-remote
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,89 @@
 | 
				
			||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This file is part of cdist.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# cdist is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					state_should="$(cat "$__object/parameter/state")"
 | 
				
			||||||
 | 
					state_is=$(cat "$__object/explorer/state")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Nothing todo, go away
 | 
				
			||||||
 | 
					[ "$state_should" = "$state_is" ] && exit 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					os=$(cat "$__global/explorer/os")
 | 
				
			||||||
 | 
					name="$__object_id"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case "$state_should" in
 | 
				
			||||||
 | 
					    present)
 | 
				
			||||||
 | 
					        case "$os" in
 | 
				
			||||||
 | 
					            archlinux)
 | 
				
			||||||
 | 
					                echo "sed -i /etc/rc.conf \'s/^\\(DAEMONS=.*\\))/\\1 $name)/\'"
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					            debian|ubuntu)
 | 
				
			||||||
 | 
					                echo "update-rc.d \"$name\" defaults >/dev/null"
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#           FIXME: Disabled until the explorer is checked
 | 
				
			||||||
 | 
					#            gentoo)
 | 
				
			||||||
 | 
					#                echo rc-update add \"$name\" default
 | 
				
			||||||
 | 
					#            ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            centos|fedora|owl|redhat)
 | 
				
			||||||
 | 
					                echo chkconfig \"$name\" on
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            *)
 | 
				
			||||||
 | 
					               echo "Unsupported os: $os" >&2
 | 
				
			||||||
 | 
					               exit 1
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        esac
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    absent)
 | 
				
			||||||
 | 
					        case "$os" in
 | 
				
			||||||
 | 
					            archlinux)
 | 
				
			||||||
 | 
					                # Replace a) at the beginning b) in the middle c) end d) only
 | 
				
			||||||
 | 
					                # Support @name as well...makes it more ugly, but well...
 | 
				
			||||||
 | 
					                echo "sed -i /etc/rc.conf -e 's/^\\(DAEMONS=(\\)@\\{0,1\\}$name /\\1/' -e 's/^\\(DAEMONS=(.* \\)@\\{0,1\\}$name \\(.*\\)/\\1\\2/' -e 's/^\\(DAEMONS=(.*\\) @\\{0,1\\}$name)/\\1)/' -e 's/^\\(DAEMONS=(\\)@\\{0,1\\}$name)/\\1)/'"
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					            debian|ubuntu)
 | 
				
			||||||
 | 
					                echo update-rc.d -f \"$name\" remove
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# FIXME: Disabled until the explorer is checked
 | 
				
			||||||
 | 
					#            gentoo)
 | 
				
			||||||
 | 
					#                echo rc-update del \"$name\"
 | 
				
			||||||
 | 
					#            ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            centos|fedora|owl|redhat)
 | 
				
			||||||
 | 
					                echo chkconfig \"$name\" off
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            *)
 | 
				
			||||||
 | 
					               echo "Unsupported os: $os" >&2
 | 
				
			||||||
 | 
					               exit 1
 | 
				
			||||||
 | 
					            ;;
 | 
				
			||||||
 | 
					        esac
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *)
 | 
				
			||||||
 | 
					        echo "Unknown state: $state_should" >&2
 | 
				
			||||||
 | 
					        exit 1
 | 
				
			||||||
 | 
					    ;;
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
							
								
								
									
										53
									
								
								conf/type/__start_on_boot/man.text
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								conf/type/__start_on_boot/man.text
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,53 @@
 | 
				
			||||||
 | 
					cdist-type__start_on_boot(7)
 | 
				
			||||||
 | 
					============================
 | 
				
			||||||
 | 
					Nico Schottelius <nico-cdist--@--schottelius.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NAME
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					cdist-type__start_on_boot - Manage stuff to be started at boot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DESCRIPTION
 | 
				
			||||||
 | 
					-----------
 | 
				
			||||||
 | 
					This cdist type allows you to enable or disable stuff to be started
 | 
				
			||||||
 | 
					at boot of your operating system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Warning: This type has not been tested intensively and is not fully
 | 
				
			||||||
 | 
					supported (i.e. gentoo and *bsd are not implemented).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REQUIRED PARAMETERS
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					None.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTIONAL PARAMETERS
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					state::
 | 
				
			||||||
 | 
					   'present' or 'absent', defaults to 'present'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXAMPLES
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# Ensure snmpd is started at boot
 | 
				
			||||||
 | 
					__start_on_boot snmpd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Same, but more explicit
 | 
				
			||||||
 | 
					__start_on_boot snmpd --state present
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ensure legacy configuration management will not be started
 | 
				
			||||||
 | 
					__start_on_boot puppet --state absent
 | 
				
			||||||
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SEE ALSO
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					- cdist-type(7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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).
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#!/bin/sh
 | 
					#!/bin/sh
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 | 
					# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 | 
				
			||||||
 | 
					# 2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# This file is part of cdist.
 | 
					# This file is part of cdist.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -17,21 +18,7 @@
 | 
				
			||||||
# You should have received a copy of the GNU General Public License
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
					# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Get the current value of key or __NOTSET__ if the key doesn't exist.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ -f "$__object/parameter/key" ]; then
 | 
					 | 
				
			||||||
   key="$(cat "$__object/parameter/key")"
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
   key="$__object_id"
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
file="$(cat "$__object/parameter/file")"
 | 
					 | 
				
			||||||
delimiter="$(cat "$__object/parameter/delimiter")"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
awk -F "$delimiter" '
 | 
					 | 
				
			||||||
BEGIN { found=0 }
 | 
					 | 
				
			||||||
/^'$key'/ { print $2; found=1 }
 | 
					 | 
				
			||||||
END { if (found) exit 0; else exit 1 }' "$file" \
 | 
					 | 
				
			||||||
|| echo "__NOTSET__"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# set default: present, if not setup
 | 
				
			||||||
 | 
					statefile="$__object/parameter/state"
 | 
				
			||||||
 | 
					[ -f "$statefile" ] || echo present > "$statefile"
 | 
				
			||||||
							
								
								
									
										1
									
								
								conf/type/__start_on_boot/parameter/optional
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								conf/type/__start_on_boot/parameter/optional
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					state
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@ cd "$__object/parameter"
 | 
				
			||||||
if grep -q "^${name}:" "$__object/explorer/passwd"; then
 | 
					if grep -q "^${name}:" "$__object/explorer/passwd"; then
 | 
				
			||||||
   for property in $(ls .); do
 | 
					   for property in $(ls .); do
 | 
				
			||||||
      new_value="$(cat "$property")"
 | 
					      new_value="$(cat "$property")"
 | 
				
			||||||
 | 
					      unset current_value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      file="$__object/explorer/passwd"
 | 
					      file="$__object/explorer/passwd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,9 +37,16 @@ if grep -q "^${name}:" "$__object/explorer/passwd"; then
 | 
				
			||||||
            if $(echo "$new_value" | grep -q '^[0-9][0-9]*$'); then
 | 
					            if $(echo "$new_value" | grep -q '^[0-9][0-9]*$'); then
 | 
				
			||||||
               field=4
 | 
					               field=4
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
               # group name
 | 
					               # We were passed a group name.  Compare the gid in
 | 
				
			||||||
               file="$__object/explorer/group"
 | 
					               # the user's /etc/passwd entry with the gid of the
 | 
				
			||||||
               field=1
 | 
					               # group returned by the group explorer.
 | 
				
			||||||
 | 
					               gid_from_group=$(awk -F: '{ print $3 }' "$__object/explorer/group")
 | 
				
			||||||
 | 
					               gid_from_passwd=$(awk -F: '{ print $4 }' "$file")
 | 
				
			||||||
 | 
					               if [ "$gid_from_group" != "$gid_from_passwd" ]; then
 | 
				
			||||||
 | 
					                  current_value="$gid_from_passwd"
 | 
				
			||||||
 | 
					               else
 | 
				
			||||||
 | 
					                  current_value="$new_value"
 | 
				
			||||||
 | 
					               fi
 | 
				
			||||||
            fi
 | 
					            fi
 | 
				
			||||||
         ;;
 | 
					         ;;
 | 
				
			||||||
         password)
 | 
					         password)
 | 
				
			||||||
| 
						 | 
					@ -51,8 +59,12 @@ if grep -q "^${name}:" "$__object/explorer/passwd"; then
 | 
				
			||||||
         uid)     field=3 ;;
 | 
					         uid)     field=3 ;;
 | 
				
			||||||
      esac
 | 
					      esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      export field
 | 
					      # If we haven't already set $current_value above, pull it from the
 | 
				
			||||||
      current_value="$(awk -F: '{ print $ENVIRON["field"] }' < "$file")"
 | 
					      # appropriate file/field.
 | 
				
			||||||
 | 
					      if [ -z "$current_value" ]; then
 | 
				
			||||||
 | 
					         export field
 | 
				
			||||||
 | 
					         current_value="$(awk -F: '{ print $ENVIRON["field"] }' < "$file")"
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if [ "$new_value" != "$current_value" ]; then
 | 
					      if [ "$new_value" != "$current_value" ]; then
 | 
				
			||||||
         set -- "$@" "--$property" \'$new_value\'
 | 
					         set -- "$@" "--$property" \'$new_value\'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,11 +4,22 @@ Changelog
 | 
				
			||||||
	* Changes are always commented with their author in (braces)
 | 
						* Changes are always commented with their author in (braces)
 | 
				
			||||||
	* Exception: No braces means author == Nico Schottelius
 | 
						* Exception: No braces means author == Nico Schottelius
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2.0.7:
 | 
					2.0.8:
 | 
				
			||||||
 | 
						* Cleanup: Better hint to source of error
 | 
				
			||||||
 | 
						* Cleanup: Do not output failing script, but path to script only
 | 
				
			||||||
 | 
						* Cleanup: Remove support for __debug variable in manifests (Type != Core
 | 
				
			||||||
 | 
							debugging)
 | 
				
			||||||
 | 
						* Feature Core: Support boolean parameters (Steven Armstrong)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2.0.7: 2012-02-13
 | 
				
			||||||
	* Bugfix __file: Use chmod after chown/chgrp (Matt Coddington)
 | 
						* Bugfix __file: Use chmod after chown/chgrp (Matt Coddington)
 | 
				
			||||||
	* Bugfix __user: Correct shadow field in explorer (Matt Coddington)
 | 
						* Bugfix __user: Correct shadow field in explorer (Matt Coddington)
 | 
				
			||||||
	* Bugfix __link: Properly handle existing links (Steven Armstrong)
 | 
						* Bugfix __link: Properly handle existing links (Steven Armstrong)
 | 
				
			||||||
 | 
						* Bugfix __key_value: More robust implementation (Steven Armstrong)
 | 
				
			||||||
 | 
						* Bugfix __user: Fix for changing a user's group by name (Matt Coddington)
 | 
				
			||||||
	* New Type: __package_pip
 | 
						* New Type: __package_pip
 | 
				
			||||||
 | 
						* Bugfix/Cleanup: Correctly allow Object ID to start and end with /, but
 | 
				
			||||||
 | 
							not contain //.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2.0.6: 2012-01-28
 | 
					2.0.6: 2012-01-28
 | 
				
			||||||
	* Bugfix __apt_ppa:
 | 
						* Bugfix __apt_ppa:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								doc/dev/logs/2012-02-10.object_id-and-slashes
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								doc/dev/logs/2012-02-10.object_id-and-slashes
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					__typename /foo/bar # possible, usual use case
 | 
				
			||||||
 | 
					require="__a//b" __typename /foo/bar # possible and happens often for __a/$id in loops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__typename /foo/bar/ # trailing slash will be stripped, can be documented
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__typename /foo//bar//baz # // will be converted to / implicitly through fs; error prone; disallow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require="__a//b//c" __typename # // will be converted to / implicitly through fs; error prone; disallow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Solution:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    1) allow require __a//b: type __a, object id /b
 | 
				
			||||||
 | 
					        => strip first slash of object id, as we do in non-dep-mode
 | 
				
			||||||
 | 
					    2) allow _one_ trailing /: __type /foo/bar/ and require="__foo/abc/"
 | 
				
			||||||
 | 
					        => strip one leading slash of object id
 | 
				
			||||||
 | 
					    3) disallow // within object id
 | 
				
			||||||
 | 
					    4) disallow starting or ending / after 1) and 2)
 | 
				
			||||||
							
								
								
									
										23
									
								
								doc/dev/logs/2012-02-13.dependencies
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								doc/dev/logs/2012-02-13.dependencies
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					possible dependencies:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - unix pattern __foo/*
 | 
				
			||||||
 | 
					    - object: __foo//bar, __foo/bar
 | 
				
			||||||
 | 
					    - singleton with object_id: __foo/singleton
 | 
				
			||||||
 | 
					    - singleton without object_id: __foo/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					solving dependencies:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    solve_dep(object, run_list):
 | 
				
			||||||
 | 
					        - list = [me]
 | 
				
			||||||
 | 
					        - if status == IN_DEPENDENCY:
 | 
				
			||||||
 | 
					            fail: circular dependency
 | 
				
			||||||
 | 
					        - status = IN_DEPENDENCY
 | 
				
			||||||
 | 
					        - create_list_of_deps(object)
 | 
				
			||||||
 | 
					            - try pattern expansion
 | 
				
			||||||
 | 
					        - for each dependency:
 | 
				
			||||||
 | 
					            if object does not exist:
 | 
				
			||||||
 | 
					                fail
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                list.append(solve_dep(object, run_list)):
 | 
				
			||||||
 | 
					        - status == IN_LIST
 | 
				
			||||||
 | 
					        - return [me, dependencies [, dependencies of dependencies]]
 | 
				
			||||||
							
								
								
									
										132
									
								
								doc/dev/logs/2012-02-15.steven
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								doc/dev/logs/2012-02-15.steven
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,132 @@
 | 
				
			||||||
 | 
					- parameter/setting default from manifest
 | 
				
			||||||
 | 
					    ==> BRANCH[feature_default_parameters],
 | 
				
			||||||
 | 
					    ==> PERSON[Steven or Nico]
 | 
				
			||||||
 | 
					    ==> PROPOSAL(1)
 | 
				
			||||||
 | 
					    - current bug
 | 
				
			||||||
 | 
					    - proposal 1: parameter/default/$name (for optional ones)
 | 
				
			||||||
 | 
					        - new way
 | 
				
			||||||
 | 
					        - catches --state absent|present
 | 
				
			||||||
 | 
					        - needs changes of types
 | 
				
			||||||
 | 
					        - also possible for explorer
 | 
				
			||||||
 | 
					        - support for it in core?
 | 
				
			||||||
 | 
					            - handling of ${o} $o "$o" ?
 | 
				
			||||||
 | 
					            - handling which variables?
 | 
				
			||||||
 | 
					            - introduction of "templating language"
 | 
				
			||||||
 | 
					                - aka macros
 | 
				
			||||||
 | 
					                - possible problems:
 | 
				
			||||||
 | 
					                    - inconsistency
 | 
				
			||||||
 | 
					                    - redoing shell functionality
 | 
				
			||||||
 | 
					                    - raising expectations for more templating from users
 | 
				
			||||||
 | 
					                - possible benefit
 | 
				
			||||||
 | 
					                    - no need for eval
 | 
				
			||||||
 | 
					                    - once in core, not everytime in type
 | 
				
			||||||
 | 
					                        - OTOH: one extra word. 
 | 
				
			||||||
 | 
					                        - a=$(cat $__object/parameter/name) vs. $(eval $(cat $__object/parameter/name))
 | 
				
			||||||
 | 
					        - only possible for static defaults
 | 
				
			||||||
 | 
					            - --name overrides name not possible vs. object_id
 | 
				
			||||||
 | 
					                - Is this the only case????
 | 
				
			||||||
 | 
					                    - if yes: don't care.
 | 
				
			||||||
 | 
					                - possible solution:
 | 
				
			||||||
 | 
					                    - echo '/$__object_id' > typename/parameter/default/name
 | 
				
			||||||
 | 
					                    - eval $(cat $__object/parameter/name)
 | 
				
			||||||
 | 
					                        - probably allows code injection
 | 
				
			||||||
 | 
					                            - is possible anyway???
 | 
				
			||||||
 | 
					                            - $(cat /etc/shadow)
 | 
				
			||||||
 | 
					                        - other eval side effects???
 | 
				
			||||||
 | 
					                            - none: go for it
 | 
				
			||||||
 | 
					                            - some: have headache
 | 
				
			||||||
 | 
					                            - many: don't do
 | 
				
			||||||
 | 
					    - proposal 2: 2 dbs (user input vs. stuff changable by type)
 | 
				
			||||||
 | 
					        - explicit 2nd db [parameter_user and parameter/]
 | 
				
			||||||
 | 
					        - not very clean (both agreed)
 | 
				
			||||||
 | 
					    - proposal 3: parameter are read-only
 | 
				
			||||||
 | 
					        - breaks current types (in core probably elsewhere)
 | 
				
			||||||
 | 
					        - can't enforce, but user is on his own => breaks, her problem
 | 
				
			||||||
 | 
					        + clean seperation between core and type (nico)
 | 
				
			||||||
 | 
					            - parameter belongs to type not core (steven)
 | 
				
			||||||
 | 
					    - proposal 4: core ignores changes in parameter/* of object
 | 
				
			||||||
 | 
					        - implicit 2nd db [see automagic below]
 | 
				
			||||||
 | 
					        - steven+++
 | 
				
			||||||
 | 
					        - does not work with divergent emulator not being in core
 | 
				
			||||||
 | 
					            - because emulators primary db __is__ fs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1 manifest:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__foo bar == emulator
 | 
				
			||||||
 | 
					echo present > $__global/object/__foo/bar/parameter/state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# fails
 | 
				
			||||||
 | 
					__foo bar == emulator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! automagic / filesystem
 | 
				
			||||||
 | 
					    ! fsproperty:
 | 
				
			||||||
 | 
					        - kill, write explicitly to disk
 | 
				
			||||||
 | 
					    ==> BRANCH[cleanup_fsproperty]
 | 
				
			||||||
 | 
					    ==> PERSON[Steven]
 | 
				
			||||||
 | 
					    ==> PROPOSAL(just cleanup)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - implicit/automatic writes/read to fs
 | 
				
			||||||
 | 
					        - explicit interfaces are better then implicit
 | 
				
			||||||
 | 
					        - same problems as in cdist 1.x to 2.x move! (environment!)
 | 
				
			||||||
 | 
					    - format on disk should not change/dictate code flow
 | 
				
			||||||
 | 
					        - degrade python to shell (nico++! steven--)
 | 
				
			||||||
 | 
					            - user should not care about python, ruby, .net or ASM implementation (steven++ nico++)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ? proposal 1: diverge emulator / core
 | 
				
			||||||
 | 
					        - emulator verifies input
 | 
				
			||||||
 | 
					        - emulator writes to fs
 | 
				
			||||||
 | 
					        - core reads/syncs from/to fs before passing control to user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ? proposal 2: emulator is dumb and passes data to core
 | 
				
			||||||
 | 
					        - core creates objects
 | 
				
			||||||
 | 
					        - no fs involved
 | 
				
			||||||
 | 
					        - core reads/syncs from/to fs before passing control to user
 | 
				
			||||||
 | 
					        - passing:
 | 
				
			||||||
 | 
					            - full objects via pickle
 | 
				
			||||||
 | 
					            - parameters only
 | 
				
			||||||
 | 
					            - how???
 | 
				
			||||||
 | 
					                - unix socket?
 | 
				
			||||||
 | 
					                    - not everywhere possible?
 | 
				
			||||||
 | 
					                - tcp / ip
 | 
				
			||||||
 | 
					                    - not everywhere possible
 | 
				
			||||||
 | 
					                        - chroot / local only
 | 
				
			||||||
 | 
					                - rfc 1149
 | 
				
			||||||
 | 
					                    - not everywhere possible
 | 
				
			||||||
 | 
					                        - missing avian carriers
 | 
				
			||||||
 | 
					                - 0mq
 | 
				
			||||||
 | 
					                    - not everywhere possible
 | 
				
			||||||
 | 
					                        - not installed
 | 
				
			||||||
 | 
					                - shm (ipcs and friends)
 | 
				
			||||||
 | 
					                    - not everywhere possible
 | 
				
			||||||
 | 
					                        - no /dev/shm, different libraries? cleanups needed...
 | 
				
			||||||
 | 
					                - what speaks against FS?
 | 
				
			||||||
 | 
					                    - emulator_input/.../
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                - nico: to fancy probably
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! boolean implementation
 | 
				
			||||||
 | 
					    ==> BRANCH[feature_boolean_parameter]
 | 
				
			||||||
 | 
					    ==> PERSON[Steven]
 | 
				
			||||||
 | 
					    - nico: 
 | 
				
			||||||
 | 
					        - parameters/boolean: document
 | 
				
			||||||
 | 
					        - argparse changes (consider parameters/boolean)
 | 
				
			||||||
 | 
					            - create 
 | 
				
			||||||
 | 
					    - can be implemented with changes in emulator
 | 
				
			||||||
 | 
					        - use store_true, del if false => never seen by core
 | 
				
			||||||
 | 
					    - INDEPENDENT INDEPENDT OF FS.PROPERTIES!!111111!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- emulator:
 | 
				
			||||||
 | 
					    - how much integrated into core
 | 
				
			||||||
 | 
					        - also: using CdistObject????
 | 
				
			||||||
 | 
					    - dependency on filesystem: good (nico) | bad (steven)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- singleton / support without object_id
 | 
				
			||||||
 | 
					    - not discussed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- __apt_ppa:
 | 
				
			||||||
 | 
					    ==> BRANCH[bugfix_do_not_change_state_in_manifest]
 | 
				
			||||||
 | 
					    ==> PERSON[Nico]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- logging divergent between emulator / core
 | 
				
			||||||
 | 
					    - no problem (nico)
 | 
				
			||||||
 | 
					    - may be helpful (steven)
 | 
				
			||||||
| 
						 | 
					@ -15,11 +15,21 @@ changelog_version=$(grep '^[[:digit:]]' doc/changelog | head -n1 | sed 's/:.*//'
 | 
				
			||||||
#git_version=$(git describe)
 | 
					#git_version=$(git describe)
 | 
				
			||||||
lib_version=$(grep ^VERSION lib/cdist/__init__.py | sed -e 's/.*= //' -e 's/"//g')
 | 
					lib_version=$(grep ^VERSION lib/cdist/__init__.py | sed -e 's/.*= //' -e 's/"//g')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# get date
 | 
				
			||||||
 | 
					date_today="$(date +%Y-%m-%d)"
 | 
				
			||||||
 | 
					date_changelog=$(grep '^[[:digit:]]' doc/changelog | head -n1 | sed 's/.*: //')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "Ensure you fixed/prepared version files: $files"
 | 
					echo "Ensure you fixed/prepared version files: $files"
 | 
				
			||||||
echo "changelog: $changelog_version"
 | 
					echo "changelog: $changelog_version"
 | 
				
			||||||
#echo "git: $git_version"
 | 
					#echo "git: $git_version"
 | 
				
			||||||
echo "lib: $lib_version"
 | 
					echo "lib: $lib_version"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$date_today" != "$date_changelog" ]; then
 | 
				
			||||||
 | 
					    echo "Messed up date, not releasing:"
 | 
				
			||||||
 | 
					    echo "Changelog: $date_changelog"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [ "$lib_version" != "$changelog_version" ]; then
 | 
					if [ "$lib_version" != "$changelog_version" ]; then
 | 
				
			||||||
    echo "Messed up versions, not releasing"
 | 
					    echo "Messed up versions, not releasing"
 | 
				
			||||||
    exit 1
 | 
					    exit 1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,3 +35,5 @@ USER INTERFACE
 | 
				
			||||||
TYPES
 | 
					TYPES
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
- Add testing framework (proposed by Evax Software)
 | 
					- Add testing framework (proposed by Evax Software)
 | 
				
			||||||
 | 
					- __user
 | 
				
			||||||
 | 
					   add option to include --create-home
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,13 @@
 | 
				
			||||||
- __file/foo/bar//bar
 | 
					- introduce default parameters
 | 
				
			||||||
    - fails later
 | 
					
 | 
				
			||||||
 | 
					- cleanup object_id handling
 | 
				
			||||||
 | 
					    - have a look at singletons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- __user
 | 
					 | 
				
			||||||
   add option to include --create-home
 | 
					 | 
				
			||||||
- ensure that all types, which support --state support
 | 
					- ensure that all types, which support --state support
 | 
				
			||||||
    present and absent (consistent look and feel)
 | 
					    present and absent (consistent look and feel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- update/create docs
 | 
					- update/create docs
 | 
				
			||||||
    - cdist-cache::
 | 
					    - cdist-cache::
 | 
				
			||||||
        How to get use information about the hosts we have been working on [advanced]
 | 
					        How to get use information about the hosts we have been working on [advanced]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,10 +49,10 @@ The following global explorers are available:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
eof
 | 
					eof
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
   cd ../../conf/explorer
 | 
					    cd ../../conf/explorer
 | 
				
			||||||
   for explorer in *; do
 | 
					    for explorer in *; do
 | 
				
			||||||
      echo "- $explorer"
 | 
					       echo "- $explorer"
 | 
				
			||||||
   done
 | 
					    done
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cat << eof 
 | 
					cat << eof 
 | 
				
			||||||
| 
						 | 
					@ -62,77 +62,80 @@ PATHS
 | 
				
			||||||
If not specified otherwise, all paths are relative to the checkout directory.
 | 
					If not specified otherwise, all paths are relative to the checkout directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/::
 | 
					conf/::
 | 
				
			||||||
   Contains the (static) configuration like manifests, types and explorers.  
 | 
					    Contains the (static) configuration like manifests, types and explorers.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/manifest/init::
 | 
					conf/manifest/init::
 | 
				
			||||||
   This is the central entry point used by cdist-manifest-init(1).
 | 
					    This is the central entry point used by cdist-manifest-init(1).
 | 
				
			||||||
   It is an executable (+x bit set) shell script that can use
 | 
					    It is an executable (+x bit set) shell script that can use
 | 
				
			||||||
   values from the explorers to decide which configuration to create
 | 
					    values from the explorers to decide which configuration to create
 | 
				
			||||||
   for the specified target host.
 | 
					    for the specified target host.
 | 
				
			||||||
   It should be primary used to define mapping from configurations to hosts.
 | 
					    It should be primary used to define mapping from configurations to hosts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/manifest/*::
 | 
					conf/manifest/*::
 | 
				
			||||||
   All other files in this directory are not directly used by cdist, but you
 | 
					    All other files in this directory are not directly used by cdist, but you
 | 
				
			||||||
   can seperate configuration mappings, if you have a lot of code in the
 | 
					    can seperate configuration mappings, if you have a lot of code in the
 | 
				
			||||||
   manifest/init file. This may also be helpful to have different admins
 | 
					    manifest/init file. This may also be helpful to have different admins
 | 
				
			||||||
   maintain different groups of hosts.
 | 
					    maintain different groups of hosts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/explorer/<name>::
 | 
					conf/explorer/<name>::
 | 
				
			||||||
   Contains explorers to be run on the target hosts, see cdist-explorer(7).
 | 
					    Contains explorers to be run on the target hosts, see cdist-explorer(7).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/::
 | 
					conf/type/::
 | 
				
			||||||
   Contains all available types, which are used to provide
 | 
					    Contains all available types, which are used to provide
 | 
				
			||||||
   some kind of functionality. See cdist-type(7).
 | 
					    some kind of functionality. See cdist-type(7).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/::
 | 
					conf/type/<name>/::
 | 
				
			||||||
   Home of the type <name>.
 | 
					    Home of the type <name>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   This directory is referenced by the variable __type (see below).
 | 
					    This directory is referenced by the variable __type (see below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/man.text::
 | 
					conf/type/<name>/man.text::
 | 
				
			||||||
   Manpage in Asciidoc format (required for inclusion into upstream)
 | 
					    Manpage in Asciidoc format (required for inclusion into upstream)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/manifest::
 | 
					conf/type/<name>/manifest::
 | 
				
			||||||
   Used to generate additional objects from a type.
 | 
					    Used to generate additional objects from a type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/gencode-local::
 | 
					conf/type/<name>/gencode-local::
 | 
				
			||||||
   Used to generate code to be executed on the server.
 | 
					    Used to generate code to be executed on the server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/gencode-remote::
 | 
					conf/type/<name>/gencode-remote::
 | 
				
			||||||
   Used to generate code to be executed on the client.
 | 
					    Used to generate code to be executed on the client.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/parameters/required::
 | 
					conf/type/<name>/parameter/required::
 | 
				
			||||||
   Parameters required by type, \n seperated list.
 | 
					    Parameters required by type, \n seperated list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/parameters/optional::
 | 
					conf/type/<name>/parameter/optional::
 | 
				
			||||||
   Parameters optionally accepted by type, \n seperated list.
 | 
					    Parameters optionally accepted by type, \n seperated list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					conf/type/<name>/parameter/boolean::
 | 
				
			||||||
 | 
					   Boolean parameters accepted by type, \n seperated list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf/type/<name>/explorer::
 | 
					conf/type/<name>/explorer::
 | 
				
			||||||
   Location of the type specific explorers.
 | 
					    Location of the type specific explorers.
 | 
				
			||||||
   This directory is referenced by the variable __type_explorer (see below).
 | 
					    This directory is referenced by the variable __type_explorer (see below).
 | 
				
			||||||
   See cdist-explorer(7).
 | 
					    See cdist-explorer(7).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out/::
 | 
					out/::
 | 
				
			||||||
   This directory contains output of cdist and is usually located
 | 
					    This directory contains output of cdist and is usually located
 | 
				
			||||||
   in a temporary directory and thus will be removed after the run.
 | 
					    in a temporary directory and thus will be removed after the run.
 | 
				
			||||||
   This directory is referenced by the variable __global (see below).
 | 
					    This directory is referenced by the variable __global (see below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out/explorer::
 | 
					out/explorer::
 | 
				
			||||||
   Output of general explorers.
 | 
					    Output of general explorers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out/object::
 | 
					out/object::
 | 
				
			||||||
   Objects created for the host.
 | 
					    Objects created for the host.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out/object/<object>::
 | 
					out/object/<object>::
 | 
				
			||||||
   Contains all object specific information.
 | 
					    Contains all object specific information.
 | 
				
			||||||
   This directory is referenced by the variable __object (see below).
 | 
					    This directory is referenced by the variable __object (see below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out/object/<object>/explorers::
 | 
					out/object/<object>/explorers::
 | 
				
			||||||
   Output of type specific explorers, per object.
 | 
					    Output of type specific explorers, per object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tmp_dir::
 | 
					tmp_dir::
 | 
				
			||||||
   A tempdir and a tempfile is used by cdist internally,
 | 
					    A tempdir and a tempfile is used by cdist internally,
 | 
				
			||||||
   which will be removed when the scripts end automatically.
 | 
					    which will be removed when the scripts end automatically.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TYPES
 | 
					TYPES
 | 
				
			||||||
-----
 | 
					-----
 | 
				
			||||||
| 
						 | 
					@ -141,13 +144,13 @@ The following types are available:
 | 
				
			||||||
eof
 | 
					eof
 | 
				
			||||||
 | 
					
 | 
				
			||||||
for type in man7/cdist-type__*.text; do
 | 
					for type in man7/cdist-type__*.text; do
 | 
				
			||||||
   no_dir="${type#man7/}";
 | 
					    no_dir="${type#man7/}";
 | 
				
			||||||
   no_type="${no_dir#cdist-type}";
 | 
					    no_type="${no_dir#cdist-type}";
 | 
				
			||||||
   name="${no_type%.text}";
 | 
					    name="${no_type%.text}";
 | 
				
			||||||
   name_no_underline="$(echo $name | sed 's/^__/\\__/g')"
 | 
					    name_no_underline="$(echo $name | sed 's/^__/\\__/g')"
 | 
				
			||||||
   man="${no_dir%.text}(7)"
 | 
					    man="${no_dir%.text}(7)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   echo "- $name_no_underline" "($man)"
 | 
					    echo "- $name_no_underline" "($man)"
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cat << eof
 | 
					cat << eof
 | 
				
			||||||
| 
						 | 
					@ -159,43 +162,47 @@ For object to object communication and tests, the following paths are
 | 
				
			||||||
usable within a object directory:
 | 
					usable within a object directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
changed::
 | 
					changed::
 | 
				
			||||||
   This empty file exists in an object directory, if the object has
 | 
					    This empty file exists in an object directory, if the object has
 | 
				
			||||||
   code to be excuted (either remote or local)
 | 
					    code to be excuted (either remote or local)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENVIRONMENT VARIABLES
 | 
					ENVIRONMENT VARIABLES
 | 
				
			||||||
---------------------
 | 
					---------------------
 | 
				
			||||||
__explorer::
 | 
					__explorer::
 | 
				
			||||||
   Directory that contains all global explorers.
 | 
					    Directory that contains all global explorers.
 | 
				
			||||||
   Available for: explorer
 | 
					    Available for: explorer, type explorer
 | 
				
			||||||
__manifest::
 | 
					__manifest::
 | 
				
			||||||
   Directory that contains the initial manifest.
 | 
					    Directory that contains the initial manifest.
 | 
				
			||||||
   Available for: initial manifest
 | 
					    Available for: initial manifest
 | 
				
			||||||
__global::
 | 
					__global::
 | 
				
			||||||
   Directory that contains generic output like explorer.
 | 
					    Directory that contains generic output like explorer.
 | 
				
			||||||
   Available for: initial manifest, type manifest, type gencode
 | 
					    Available for: initial manifest, type manifest, type gencode
 | 
				
			||||||
__object::
 | 
					__object::
 | 
				
			||||||
   Directory that contains the current object.
 | 
					    Directory that contains the current object.
 | 
				
			||||||
   Available for: type manifest, type explorer, type gencode
 | 
					    Available for: type manifest, type explorer, type gencode
 | 
				
			||||||
__object_id::
 | 
					__object_id::
 | 
				
			||||||
   The type unique object id.
 | 
					    The type unique object id.
 | 
				
			||||||
   Available for: type manifest, type explorer, type gencode
 | 
					    Available for: type manifest, type explorer, type gencode
 | 
				
			||||||
   Note: The leading "/" will always be stripped.
 | 
					
 | 
				
			||||||
 | 
					    Note: The leading and the trailing "/" will always be stripped (caused by
 | 
				
			||||||
 | 
					    the filesystem database and ensured by the core).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Note: Double slashes ("//") will not be fixed and result in an error.
 | 
				
			||||||
__self::
 | 
					__self::
 | 
				
			||||||
   DEPRECATED: Same as __object_name, do not use anymore, use __object_name instead.
 | 
					    DEPRECATED: Same as __object_name, do not use anymore, use __object_name instead.
 | 
				
			||||||
   Will be removed in cdist 3.x.
 | 
					    Will be removed in cdist 3.x.
 | 
				
			||||||
__object_name::
 | 
					__object_name::
 | 
				
			||||||
   The full qualified name of the current object.
 | 
					    The full qualified name of the current object.
 | 
				
			||||||
   Available for: type manifest, type explorer, type gencode
 | 
					    Available for: type manifest, type explorer, type gencode
 | 
				
			||||||
__target_host::
 | 
					__target_host::
 | 
				
			||||||
   The host we are deploying to.
 | 
					    The host we are deploying to.
 | 
				
			||||||
   Available for: initial manifest, type manifest, type gencode
 | 
					    Available for: explorer, initial manifest, type explorer, type manifest, type gencode
 | 
				
			||||||
__type::
 | 
					__type::
 | 
				
			||||||
   Path to the current type.
 | 
					    Path to the current type.
 | 
				
			||||||
   Available for: type manifest, type gencode
 | 
					    Available for: type manifest, type gencode
 | 
				
			||||||
__type_explorer::
 | 
					__type_explorer::
 | 
				
			||||||
   Directory that contains the type explorers.
 | 
					    Directory that contains the type explorers.
 | 
				
			||||||
   Available for: type explorer
 | 
					    Available for: type explorer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SEE ALSO
 | 
					SEE ALSO
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,12 +61,19 @@ including it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HOW TO SUBMIT A NEW TYPE
 | 
					HOW TO SUBMIT A NEW TYPE
 | 
				
			||||||
------------------------
 | 
					------------------------
 | 
				
			||||||
 | 
					For detailled information about types, see cdist-type(7).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Submitting a type works as described above, with the additional requirement
 | 
					Submitting a type works as described above, with the additional requirement
 | 
				
			||||||
that a corresponding manpage named man.text in asciidoc format with
 | 
					that a corresponding manpage named man.text in asciidoc format with
 | 
				
			||||||
the manpage-name "cdist-type__NAME" is included in the type directory
 | 
					the manpage-name "cdist-type__NAME" is included in the type directory
 | 
				
			||||||
AND asciidoc is able to compile it (i.e. do NOT have to many "=" in the second
 | 
					AND asciidoc is able to compile it (i.e. do NOT have to many "=" in the second
 | 
				
			||||||
line).
 | 
					line).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Warning: Submitting "exec" or "run" types that simply echo their parameter in
 | 
				
			||||||
 | 
					gencode* will not be accepted, because they are of no use. Every type can output
 | 
				
			||||||
 | 
					code and thus such a type introduces redundant functionality that is given by
 | 
				
			||||||
 | 
					core cdist already.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SEE ALSO
 | 
					SEE ALSO
 | 
				
			||||||
--------
 | 
					--------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,15 +72,42 @@ To begin a new type, just create the directory **conf/type/__NAME**.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFINING PARAMETERS
 | 
					DEFINING PARAMETERS
 | 
				
			||||||
-------------------
 | 
					-------------------
 | 
				
			||||||
Every type consists of optional and required parameters, which must
 | 
					Every type consists of required, optional and boolean parameters, which must
 | 
				
			||||||
be created in a newline seperated file in ***parameters/required*** and
 | 
					be created in a newline seperated file in ***parameter/required***,
 | 
				
			||||||
***parameters/optional***. If either or both missing, the type will have
 | 
					***parameter/optional*** and ***parameter/boolean***. If either is missing,
 | 
				
			||||||
no required, no optional or no parameters at all.
 | 
					the type will have no required, no optional, no boolean or no parameters at
 | 
				
			||||||
 | 
					all.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
echo servername >> conf/type/__nginx_vhost/parameter/required
 | 
					echo servername >> conf/type/__nginx_vhost/parameter/required
 | 
				
			||||||
echo logdirectory >> conf/type/__nginx_vhost/parameter/optional
 | 
					echo logdirectory >> conf/type/__nginx_vhost/parameter/optional
 | 
				
			||||||
 | 
					echo use_ssl >> conf/type/__nginx_vhost/parameter/boolean
 | 
				
			||||||
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					USING PARAMETERS
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					The parameters given to a type can be accessed and used in all type scripts
 | 
				
			||||||
 | 
					(e.g manifest, gencode-*, explorer/*). Note that boolean parameters are
 | 
				
			||||||
 | 
					represented by file existence. File exists -> True,
 | 
				
			||||||
 | 
					file does not exist -> False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example: (e.g. in conf/type/__nginx_vhost/manifest)
 | 
				
			||||||
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					# required parameter
 | 
				
			||||||
 | 
					servername="$(cat "$__object/parameter/servername")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# optional parameter
 | 
				
			||||||
 | 
					if [ -f "$__object/parameter/logdirectory" ]; then
 | 
				
			||||||
 | 
					   logdirectory="$(cat "$__object/parameter/logdirectory")"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# boolean parameter
 | 
				
			||||||
 | 
					if [ -f "$__object/parameter/use_ssl" ]; then
 | 
				
			||||||
 | 
					   # file exists -> True
 | 
				
			||||||
 | 
					   # do some fancy ssl stuff
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
--------------------------------------------------------------------------------
 | 
					--------------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VERSION     = "2.0.6"
 | 
					VERSION     = "2.0.7"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BANNER = """
 | 
					BANNER = """
 | 
				
			||||||
             ..          .       .x+=:.        s
 | 
					             ..          .       .x+=:.        s
 | 
				
			||||||
| 
						 | 
					@ -44,15 +44,17 @@ class Error(Exception):
 | 
				
			||||||
    """Base exception class for this project"""
 | 
					    """Base exception class for this project"""
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CdistObjectError(Error):
 | 
				
			||||||
 | 
					    """Something went wrong with an object"""
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
class MissingEnvironmentVariableError(Error):
 | 
					    def __init__(self, cdist_object, message):
 | 
				
			||||||
    """Raised when a required environment variable is not set."""
 | 
					        self.name = cdist_object.name
 | 
				
			||||||
 | 
					        self.source = " ".join(cdist_object.source)
 | 
				
			||||||
 | 
					        self.message = message
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, name):
 | 
					 | 
				
			||||||
        self.name = name
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return 'Missing required environment variable: ' + str(self.name)
 | 
					        return '%s: %s (defined at %s)' % (self.name, self.message, self.source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def file_to_list(filename):
 | 
					def file_to_list(filename):
 | 
				
			||||||
    """Return list from \n seperated file"""
 | 
					    """Return list from \n seperated file"""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,9 +89,9 @@ class ConfigInstall(object):
 | 
				
			||||||
        new_objects_created = True
 | 
					        new_objects_created = True
 | 
				
			||||||
        while new_objects_created:
 | 
					        while new_objects_created:
 | 
				
			||||||
            new_objects_created = False
 | 
					            new_objects_created = False
 | 
				
			||||||
            for cdist_object in core.Object.list_objects(self.local.object_path,
 | 
					            for cdist_object in core.CdistObject.list_objects(self.local.object_path,
 | 
				
			||||||
                                                         self.local.type_path):
 | 
					                                                         self.local.type_path):
 | 
				
			||||||
                if cdist_object.state == core.Object.STATE_PREPARED:
 | 
					                if cdist_object.state == core.CdistObject.STATE_PREPARED:
 | 
				
			||||||
                    self.log.debug("Skipping re-prepare of object %s", cdist_object)
 | 
					                    self.log.debug("Skipping re-prepare of object %s", cdist_object)
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
| 
						 | 
					@ -103,16 +103,16 @@ class ConfigInstall(object):
 | 
				
			||||||
        self.log.info("Running manifest and explorers for " + cdist_object.name)
 | 
					        self.log.info("Running manifest and explorers for " + cdist_object.name)
 | 
				
			||||||
        self.explorer.run_type_explorers(cdist_object)
 | 
					        self.explorer.run_type_explorers(cdist_object)
 | 
				
			||||||
        self.manifest.run_type_manifest(cdist_object)
 | 
					        self.manifest.run_type_manifest(cdist_object)
 | 
				
			||||||
        cdist_object.state = core.Object.STATE_PREPARED
 | 
					        cdist_object.state = core.CdistObject.STATE_PREPARED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def object_run(self, cdist_object):
 | 
					    def object_run(self, cdist_object):
 | 
				
			||||||
        """Run gencode and code for an object"""
 | 
					        """Run gencode and code for an object"""
 | 
				
			||||||
        self.log.debug("Trying to run object " + cdist_object.name)
 | 
					        self.log.debug("Trying to run object " + cdist_object.name)
 | 
				
			||||||
        if cdist_object.state == core.Object.STATE_DONE:
 | 
					        if cdist_object.state == core.CdistObject.STATE_DONE:
 | 
				
			||||||
            # TODO: remove once we are sure that this really never happens.
 | 
					            # TODO: remove once we are sure that this really never happens.
 | 
				
			||||||
            raise cdist.Error("Attempting to run an already finished object: %s", cdist_object)
 | 
					            raise cdist.Error("Attempting to run an already finished object: %s", cdist_object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cdist_type = cdist_object.type
 | 
					        cdist_type = cdist_object.cdist_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Generate
 | 
					        # Generate
 | 
				
			||||||
        self.log.info("Generating and executing code for " + cdist_object.name)
 | 
					        self.log.info("Generating and executing code for " + cdist_object.name)
 | 
				
			||||||
| 
						 | 
					@ -130,13 +130,13 @@ class ConfigInstall(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Mark this object as done
 | 
					        # Mark this object as done
 | 
				
			||||||
        self.log.debug("Finishing run of " + cdist_object.name)
 | 
					        self.log.debug("Finishing run of " + cdist_object.name)
 | 
				
			||||||
        cdist_object.state = core.Object.STATE_DONE
 | 
					        cdist_object.state = core.CdistObject.STATE_DONE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def stage_run(self):
 | 
					    def stage_run(self):
 | 
				
			||||||
        """The final (and real) step of deployment"""
 | 
					        """The final (and real) step of deployment"""
 | 
				
			||||||
        self.log.info("Generating and executing code")
 | 
					        self.log.info("Generating and executing code")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        objects = core.Object.list_objects(
 | 
					        objects = core.CdistObject.list_objects(
 | 
				
			||||||
            self.local.object_path,
 | 
					            self.local.object_path,
 | 
				
			||||||
            self.local.type_path)
 | 
					            self.local.type_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,11 +19,11 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from cdist.core.type import Type
 | 
					from cdist.core.cdist_type      import CdistType
 | 
				
			||||||
from cdist.core.type import NoSuchTypeError
 | 
					from cdist.core.cdist_type      import NoSuchTypeError
 | 
				
			||||||
from cdist.core.object import Object
 | 
					from cdist.core.cdist_object    import CdistObject
 | 
				
			||||||
from cdist.core.object import IllegalObjectIdError
 | 
					from cdist.core.cdist_object    import IllegalObjectIdError
 | 
				
			||||||
from cdist.core.object import OBJECT_MARKER
 | 
					from cdist.core.cdist_object    import OBJECT_MARKER
 | 
				
			||||||
from cdist.core.explorer import Explorer
 | 
					from cdist.core.explorer        import Explorer
 | 
				
			||||||
from cdist.core.manifest import Manifest
 | 
					from cdist.core.manifest        import Manifest
 | 
				
			||||||
from cdist.core.code import Code
 | 
					from cdist.core.code            import Code
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 | 
					# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
 | 
				
			||||||
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
 | 
					# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# This file is part of cdist.
 | 
					# This file is part of cdist.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ class IllegalObjectIdError(cdist.Error):
 | 
				
			||||||
        return '%s: %s' % (self.message, self.object_id)
 | 
					        return '%s: %s' % (self.message, self.object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Object(object):
 | 
					class CdistObject(object):
 | 
				
			||||||
    """Represents a cdist object.
 | 
					    """Represents a cdist object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    All interaction with objects in cdist should be done through this class.
 | 
					    All interaction with objects in cdist should be done through this class.
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ class Object(object):
 | 
				
			||||||
        """Return a list of object instances"""
 | 
					        """Return a list of object instances"""
 | 
				
			||||||
        for object_name in cls.list_object_names(object_base_path):
 | 
					        for object_name in cls.list_object_names(object_base_path):
 | 
				
			||||||
            type_name, object_id = cls.split_name(object_name)
 | 
					            type_name, object_id = cls.split_name(object_name)
 | 
				
			||||||
            yield cls(cdist.core.Type(type_base_path, type_name), object_base_path, object_id=object_id)
 | 
					            yield cls(cdist.core.CdistType(type_base_path, type_name), object_base_path, object_id=object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def list_type_names(cls, object_base_path):
 | 
					    def list_type_names(cls, object_base_path):
 | 
				
			||||||
| 
						 | 
					@ -96,30 +96,58 @@ class Object(object):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return os.path.join(type_name, object_id)
 | 
					        return os.path.join(type_name, object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    def validate_object_id(self):
 | 
				
			||||||
    def validate_object_id(object_id):
 | 
					        # FIXME: also check that there is no object ID when type is singleton?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        """Validate the given object_id and raise IllegalObjectIdError if it's not valid.
 | 
					        """Validate the given object_id and raise IllegalObjectIdError if it's not valid.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if object_id:
 | 
					        if self.object_id:
 | 
				
			||||||
            if object_id.startswith('/'):
 | 
					            if OBJECT_MARKER in self.object_id.split(os.sep):
 | 
				
			||||||
                raise IllegalObjectIdError(object_id, 'object_id may not start with /')
 | 
					                raise IllegalObjectIdError(self.object_id, 'object_id may not contain \'%s\'' % OBJECT_MARKER)
 | 
				
			||||||
            if OBJECT_MARKER in object_id.split(os.sep):
 | 
					            if '//' in self.object_id:
 | 
				
			||||||
                raise IllegalObjectIdError(object_id, 'object_id may not contain \'%s\'' % OBJECT_MARKER)
 | 
					                raise IllegalObjectIdError(self.object_id, 'object_id may not contain //')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If no object_id and type is not singleton => error out
 | 
				
			||||||
 | 
					        if not self.object_id and not self.cdist_type.is_singleton:
 | 
				
			||||||
 | 
					            raise IllegalObjectIdError(self.object_id,
 | 
				
			||||||
 | 
					                "Missing object_id and type is not a singleton.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, cdist_type, base_path, object_id=None):
 | 
					    def __init__(self, cdist_type, base_path, object_id=None):
 | 
				
			||||||
        self.validate_object_id(object_id)
 | 
					        self.cdist_type = cdist_type # instance of Type
 | 
				
			||||||
        self.type = cdist_type # instance of Type
 | 
					 | 
				
			||||||
        self.base_path = base_path
 | 
					        self.base_path = base_path
 | 
				
			||||||
        self.object_id = object_id
 | 
					        self.object_id = object_id
 | 
				
			||||||
        self.name = self.join_name(self.type.name, self.object_id)
 | 
					
 | 
				
			||||||
        self.path = os.path.join(self.type.path, self.object_id, OBJECT_MARKER)
 | 
					        self.validate_object_id()
 | 
				
			||||||
 | 
					        self.sanitise_object_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.name = self.join_name(self.cdist_type.name, self.object_id)
 | 
				
			||||||
 | 
					        self.path = os.path.join(self.cdist_type.path, self.object_id, OBJECT_MARKER)
 | 
				
			||||||
        self.absolute_path = os.path.join(self.base_path, self.path)
 | 
					        self.absolute_path = os.path.join(self.base_path, self.path)
 | 
				
			||||||
        self.code_local_path = os.path.join(self.path, "code-local")
 | 
					        self.code_local_path = os.path.join(self.path, "code-local")
 | 
				
			||||||
        self.code_remote_path = os.path.join(self.path, "code-remote")
 | 
					        self.code_remote_path = os.path.join(self.path, "code-remote")
 | 
				
			||||||
        self.parameter_path = os.path.join(self.path, "parameter")
 | 
					        self.parameter_path = os.path.join(self.path, "parameter")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def object_from_name(self, object_name):
 | 
				
			||||||
 | 
					        """Convenience method for creating an object instance from an object name.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Mainly intended to create objects when resolving requirements.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        e.g:
 | 
				
			||||||
 | 
					            <CdistObject __foo/bar>.object_from_name('__other/object') -> <CdistObject __other/object>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        base_path = self.base_path
 | 
				
			||||||
 | 
					        type_path = self.cdist_type.base_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        type_name, object_id = self.split_name(object_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cdist_type = self.cdist_type.__class__(type_path, type_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.__class__(cdist_type, base_path, object_id=object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return '<Object %s>' % self.name
 | 
					        return '<CdistObject %s>' % self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __eq__(self, other):
 | 
					    def __eq__(self, other):
 | 
				
			||||||
        """define equality as 'name is the same'"""
 | 
					        """define equality as 'name is the same'"""
 | 
				
			||||||
| 
						 | 
					@ -128,23 +156,23 @@ class Object(object):
 | 
				
			||||||
    def __hash__(self):
 | 
					    def __hash__(self):
 | 
				
			||||||
        return hash(self.name)
 | 
					        return hash(self.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __lt__(self, other):
 | 
					    def __lt__(self, other):
 | 
				
			||||||
        return isinstance(other, self.__class__) and self.name < other.name
 | 
					        return isinstance(other, self.__class__) and self.name < other.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def object_from_name(self, object_name):
 | 
					    def sanitise_object_id(self):
 | 
				
			||||||
        """Convenience method for creating an object instance from an object name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Mainly intended to create objects when resolving requirements.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        e.g:
 | 
					 | 
				
			||||||
            <Object __foo/bar>.object_from_name('__other/object') -> <Object __other/object>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        type_path = self.type.base_path
 | 
					        Remove leading and trailing slash (one only)
 | 
				
			||||||
        base_path = self.base_path
 | 
					        """
 | 
				
			||||||
        type_name, object_id = self.split_name(object_name)
 | 
					
 | 
				
			||||||
        return self.__class__(self.type.__class__(type_path, type_name), base_path, object_id=object_id)
 | 
					        # Allow empty object id for singletons
 | 
				
			||||||
 | 
					        if self.object_id:
 | 
				
			||||||
 | 
					            # Remove leading slash
 | 
				
			||||||
 | 
					            if self.object_id[0] == '/':
 | 
				
			||||||
 | 
					                self.object_id = self.object_id[1:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Remove trailing slash
 | 
				
			||||||
 | 
					            if self.object_id[-1] == '/':
 | 
				
			||||||
 | 
					                self.object_id = self.object_id[:-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # FIXME: still needed?
 | 
					    # FIXME: still needed?
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ class NoSuchTypeError(cdist.Error):
 | 
				
			||||||
        return "Type '%s' does not exist at %s" % (self.type_path, self.type_absolute_path)
 | 
					        return "Type '%s' does not exist at %s" % (self.type_path, self.type_absolute_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Type(object):
 | 
					class CdistType(object):
 | 
				
			||||||
    """Represents a cdist type.
 | 
					    """Represents a cdist type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    All interaction with types in cdist should be done through this class.
 | 
					    All interaction with types in cdist should be done through this class.
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ class Type(object):
 | 
				
			||||||
        # name is second argument
 | 
					        # name is second argument
 | 
				
			||||||
        name = args[1]
 | 
					        name = args[1]
 | 
				
			||||||
        if not name in cls._instances:
 | 
					        if not name in cls._instances:
 | 
				
			||||||
            instance = super(Type, cls).__new__(cls)
 | 
					            instance = super(CdistType, cls).__new__(cls)
 | 
				
			||||||
            cls._instances[name] = instance
 | 
					            cls._instances[name] = instance
 | 
				
			||||||
            # return instance so __init__ is called
 | 
					            # return instance so __init__ is called
 | 
				
			||||||
        return cls._instances[name]
 | 
					        return cls._instances[name]
 | 
				
			||||||
| 
						 | 
					@ -82,9 +82,10 @@ class Type(object):
 | 
				
			||||||
        self.__explorers = None
 | 
					        self.__explorers = None
 | 
				
			||||||
        self.__required_parameters = None
 | 
					        self.__required_parameters = None
 | 
				
			||||||
        self.__optional_parameters = None
 | 
					        self.__optional_parameters = None
 | 
				
			||||||
 | 
					        self.__boolean_parameters = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return '<Type %s>' % self.name
 | 
					        return '<CdistType %s>' % self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __eq__(self, other):
 | 
					    def __eq__(self, other):
 | 
				
			||||||
        return isinstance(other, self.__class__) and self.name == other.name
 | 
					        return isinstance(other, self.__class__) and self.name == other.name
 | 
				
			||||||
| 
						 | 
					@ -144,3 +145,19 @@ class Type(object):
 | 
				
			||||||
            finally:
 | 
					            finally:
 | 
				
			||||||
                self.__optional_parameters = parameters
 | 
					                self.__optional_parameters = parameters
 | 
				
			||||||
        return self.__optional_parameters
 | 
					        return self.__optional_parameters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def boolean_parameters(self):
 | 
				
			||||||
 | 
					        """Return a list of boolean parameters"""
 | 
				
			||||||
 | 
					        if not self.__boolean_parameters:
 | 
				
			||||||
 | 
					            parameters = []
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                with open(os.path.join(self.absolute_path, "parameter", "boolean")) as fd:
 | 
				
			||||||
 | 
					                    for line in fd:
 | 
				
			||||||
 | 
					                        parameters.append(line.strip())
 | 
				
			||||||
 | 
					            except EnvironmentError:
 | 
				
			||||||
 | 
					                # error ignored
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					            finally:
 | 
				
			||||||
 | 
					                self.__boolean_parameters = parameters
 | 
				
			||||||
 | 
					        return self.__boolean_parameters
 | 
				
			||||||
| 
						 | 
					@ -92,17 +92,14 @@ class Code(object):
 | 
				
			||||||
            '__global': self.local.out_path,
 | 
					            '__global': self.local.out_path,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if log.getEffectiveLevel() == logging.DEBUG:
 | 
					 | 
				
			||||||
            self.env.update({'__debug': "yes" })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _run_gencode(self, cdist_object, which):
 | 
					    def _run_gencode(self, cdist_object, which):
 | 
				
			||||||
        cdist_type = cdist_object.type
 | 
					        cdist_type = cdist_object.cdist_type
 | 
				
			||||||
        script = os.path.join(self.local.type_path, getattr(cdist_type, 'gencode_%s_path' % which))
 | 
					        script = os.path.join(self.local.type_path, getattr(cdist_type, 'gencode_%s_path' % which))
 | 
				
			||||||
        if os.path.isfile(script):
 | 
					        if os.path.isfile(script):
 | 
				
			||||||
            env = os.environ.copy()
 | 
					            env = os.environ.copy()
 | 
				
			||||||
            env.update(self.env)
 | 
					            env.update(self.env)
 | 
				
			||||||
            env.update({
 | 
					            env.update({
 | 
				
			||||||
                '__type': cdist_object.type.absolute_path,
 | 
					                '__type': cdist_object.cdist_type.absolute_path,
 | 
				
			||||||
                '__object': cdist_object.absolute_path,
 | 
					                '__object': cdist_object.absolute_path,
 | 
				
			||||||
                '__object_id': cdist_object.object_id,
 | 
					                '__object_id': cdist_object.object_id,
 | 
				
			||||||
                '__object_name': cdist_object.name,
 | 
					                '__object_name': cdist_object.name,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,8 +73,6 @@ class Explorer(object):
 | 
				
			||||||
            '__target_host': self.target_host,
 | 
					            '__target_host': self.target_host,
 | 
				
			||||||
            '__explorer': self.remote.global_explorer_path,
 | 
					            '__explorer': self.remote.global_explorer_path,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if self.log.getEffectiveLevel() == logging.DEBUG:
 | 
					 | 
				
			||||||
            self.env.update({'__debug': "yes" })
 | 
					 | 
				
			||||||
        self._type_explorers_transferred = []
 | 
					        self._type_explorers_transferred = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ### global
 | 
					    ### global
 | 
				
			||||||
| 
						 | 
					@ -121,15 +119,28 @@ class Explorer(object):
 | 
				
			||||||
        in the object.
 | 
					        in the object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.log.debug("Transfering type explorers for type: %s", cdist_object.type)
 | 
					        self.log.debug("Transfering type explorers for type: %s", cdist_object.cdist_type)
 | 
				
			||||||
        self.transfer_type_explorers(cdist_object.type)
 | 
					        self.transfer_type_explorers(cdist_object.cdist_type)
 | 
				
			||||||
        self.log.debug("Transfering object parameters for object: %s", cdist_object.name)
 | 
					        self.log.debug("Transfering object parameters for object: %s", cdist_object.name)
 | 
				
			||||||
        self.transfer_object_parameters(cdist_object)
 | 
					        self.transfer_object_parameters(cdist_object)
 | 
				
			||||||
        for explorer in self.list_type_explorer_names(cdist_object.type):
 | 
					        for explorer in self.list_type_explorer_names(cdist_object.cdist_type):
 | 
				
			||||||
            output = self.run_type_explorer(explorer, cdist_object)
 | 
					            output = self.run_type_explorer(explorer, cdist_object)
 | 
				
			||||||
            self.log.debug("Running type explorer '%s' for object '%s'", explorer, cdist_object.name)
 | 
					            self.log.debug("Running type explorer '%s' for object '%s'", explorer, cdist_object.name)
 | 
				
			||||||
            cdist_object.explorers[explorer] = output
 | 
					            cdist_object.explorers[explorer] = output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run_type_explorer(self, explorer, cdist_object):
 | 
				
			||||||
 | 
					        """Run the given type explorer for the given object and return it's output."""
 | 
				
			||||||
 | 
					        cdist_type = cdist_object.cdist_type
 | 
				
			||||||
 | 
					        env = self.env.copy()
 | 
				
			||||||
 | 
					        env.update({
 | 
				
			||||||
 | 
					            '__object': os.path.join(self.remote.object_path, cdist_object.path),
 | 
				
			||||||
 | 
					            '__object_id': cdist_object.object_id,
 | 
				
			||||||
 | 
					            '__object_fq': cdist_object.path,
 | 
				
			||||||
 | 
					            '__type_explorer': os.path.join(self.remote.type_path, cdist_type.explorer_path)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        script = os.path.join(self.remote.type_path, cdist_type.explorer_path, explorer)
 | 
				
			||||||
 | 
					        return self.remote.run_script(script, env=env, return_output=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def transfer_type_explorers(self, cdist_type):
 | 
					    def transfer_type_explorers(self, cdist_type):
 | 
				
			||||||
        """Transfer the type explorers for the given type to the remote side."""
 | 
					        """Transfer the type explorers for the given type to the remote side."""
 | 
				
			||||||
        if cdist_type.explorers:
 | 
					        if cdist_type.explorers:
 | 
				
			||||||
| 
						 | 
					@ -149,16 +160,3 @@ class Explorer(object):
 | 
				
			||||||
            destination = os.path.join(self.remote.object_path, cdist_object.parameter_path)
 | 
					            destination = os.path.join(self.remote.object_path, cdist_object.parameter_path)
 | 
				
			||||||
            self.remote.mkdir(destination)
 | 
					            self.remote.mkdir(destination)
 | 
				
			||||||
            self.remote.transfer(source, destination)
 | 
					            self.remote.transfer(source, destination)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def run_type_explorer(self, explorer, cdist_object):
 | 
					 | 
				
			||||||
        """Run the given type explorer for the given object and return it's output."""
 | 
					 | 
				
			||||||
        cdist_type = cdist_object.type
 | 
					 | 
				
			||||||
        env = self.env.copy()
 | 
					 | 
				
			||||||
        env.update({
 | 
					 | 
				
			||||||
            '__object': os.path.join(self.remote.object_path, cdist_object.path),
 | 
					 | 
				
			||||||
            '__object_id': cdist_object.object_id,
 | 
					 | 
				
			||||||
            '__object_fq': cdist_object.path,
 | 
					 | 
				
			||||||
            '__type_explorer': os.path.join(self.remote.type_path, cdist_type.explorer_path)
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        script = os.path.join(self.remote.type_path, cdist_type.explorer_path, explorer)
 | 
					 | 
				
			||||||
        return self.remote.run_script(script, env=env, return_output=True)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ class Manifest(object):
 | 
				
			||||||
        self.local.run_script(script, env=env)
 | 
					        self.local.run_script(script, env=env)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run_type_manifest(self, cdist_object):
 | 
					    def run_type_manifest(self, cdist_object):
 | 
				
			||||||
        script = os.path.join(self.local.type_path, cdist_object.type.manifest_path)
 | 
					        script = os.path.join(self.local.type_path, cdist_object.cdist_type.manifest_path)
 | 
				
			||||||
        if os.path.isfile(script):
 | 
					        if os.path.isfile(script):
 | 
				
			||||||
            env = os.environ.copy()
 | 
					            env = os.environ.copy()
 | 
				
			||||||
            env.update(self.env)
 | 
					            env.update(self.env)
 | 
				
			||||||
| 
						 | 
					@ -96,7 +96,7 @@ class Manifest(object):
 | 
				
			||||||
                '__object_id': cdist_object.object_id,
 | 
					                '__object_id': cdist_object.object_id,
 | 
				
			||||||
                '__object_name': cdist_object.name,
 | 
					                '__object_name': cdist_object.name,
 | 
				
			||||||
                '__self': cdist_object.name,
 | 
					                '__self': cdist_object.name,
 | 
				
			||||||
                '__type': cdist_object.type.absolute_path,
 | 
					                '__type': cdist_object.cdist_type.absolute_path,
 | 
				
			||||||
                '__cdist_manifest': script,
 | 
					                '__cdist_manifest': script,
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            self.local.run_script(script, env=env)
 | 
					            self.local.run_script(script, env=env)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
 | 
					# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# This file is part of cdist.
 | 
					# This file is part of cdist.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -26,29 +26,22 @@ import os
 | 
				
			||||||
import cdist
 | 
					import cdist
 | 
				
			||||||
from cdist import core
 | 
					from cdist import core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class IllegalRequirementError(cdist.Error):
 | 
					 | 
				
			||||||
    def __init__(self, requirement, message=None):
 | 
					 | 
				
			||||||
        self.requirement = requirement
 | 
					 | 
				
			||||||
        self.message = message or 'Illegal requirement'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        return '%s: %s' % (self.message, self.requirement)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Emulator(object):
 | 
					class Emulator(object):
 | 
				
			||||||
    def __init__(self, argv):
 | 
					    def __init__(self, argv):
 | 
				
			||||||
        self.argv           = argv
 | 
					        self.argv           = argv
 | 
				
			||||||
        self.object_id      = False
 | 
					        self.object_id      = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.global_path    = os.environ['__global']
 | 
					        self.global_path    = os.environ['__global']
 | 
				
			||||||
        self.object_source  = os.environ['__cdist_manifest']
 | 
					 | 
				
			||||||
        self.target_host    = os.environ['__target_host']
 | 
					        self.target_host    = os.environ['__target_host']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Internally only
 | 
				
			||||||
 | 
					        self.object_source  = os.environ['__cdist_manifest']
 | 
				
			||||||
        self.type_base_path = os.environ['__cdist_type_base_path']
 | 
					        self.type_base_path = os.environ['__cdist_type_base_path']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.object_base_path = os.path.join(self.global_path, "object")
 | 
					        self.object_base_path = os.path.join(self.global_path, "object")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.type_name      = os.path.basename(argv[0])
 | 
					        self.type_name      = os.path.basename(argv[0])
 | 
				
			||||||
        self.cdist_type     = core.Type(self.type_base_path, self.type_name)
 | 
					        self.cdist_type     = core.CdistType(self.type_base_path, self.type_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.__init_log()
 | 
					        self.__init_log()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +87,7 @@ class Emulator(object):
 | 
				
			||||||
    def commandline(self):
 | 
					    def commandline(self):
 | 
				
			||||||
        """Parse command line"""
 | 
					        """Parse command line"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        parser = argparse.ArgumentParser(add_help=False)
 | 
					        parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for parameter in self.cdist_type.optional_parameters:
 | 
					        for parameter in self.cdist_type.optional_parameters:
 | 
				
			||||||
            argument = "--" + parameter
 | 
					            argument = "--" + parameter
 | 
				
			||||||
| 
						 | 
					@ -102,6 +95,9 @@ class Emulator(object):
 | 
				
			||||||
        for parameter in self.cdist_type.required_parameters:
 | 
					        for parameter in self.cdist_type.required_parameters:
 | 
				
			||||||
            argument = "--" + parameter
 | 
					            argument = "--" + parameter
 | 
				
			||||||
            parser.add_argument(argument, dest=parameter, action='store', required=True)
 | 
					            parser.add_argument(argument, dest=parameter, action='store', required=True)
 | 
				
			||||||
 | 
					        for parameter in self.cdist_type.boolean_parameters:
 | 
				
			||||||
 | 
					            argument = "--" + parameter
 | 
				
			||||||
 | 
					            parser.add_argument(argument, dest=parameter, action='store_const', const='')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # If not singleton support one positional parameter
 | 
					        # If not singleton support one positional parameter
 | 
				
			||||||
        if not self.cdist_type.is_singleton:
 | 
					        if not self.cdist_type.is_singleton:
 | 
				
			||||||
| 
						 | 
					@ -113,20 +109,15 @@ class Emulator(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_object(self):
 | 
					    def setup_object(self):
 | 
				
			||||||
        # FIXME: verify object id
 | 
					        # Setup object_id - FIXME: unset / do not setup anymore!
 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Setup object_id
 | 
					 | 
				
			||||||
        if self.cdist_type.is_singleton:
 | 
					        if self.cdist_type.is_singleton:
 | 
				
			||||||
            self.object_id = "singleton"
 | 
					            self.object_id = "singleton"
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.object_id = self.args.object_id[0]
 | 
					            self.object_id = self.args.object_id[0]
 | 
				
			||||||
            del self.args.object_id
 | 
					            del self.args.object_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # strip leading slash from object_id
 | 
					 | 
				
			||||||
            self.object_id = self.object_id.lstrip('/')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Instantiate the cdist object we are defining
 | 
					        # Instantiate the cdist object we are defining
 | 
				
			||||||
        self.cdist_object = core.Object(self.cdist_type, self.object_base_path, self.object_id)
 | 
					        self.cdist_object = core.CdistObject(self.cdist_type, self.object_base_path, self.object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Create object with given parameters
 | 
					        # Create object with given parameters
 | 
				
			||||||
        self.parameters = {}
 | 
					        self.parameters = {}
 | 
				
			||||||
| 
						 | 
					@ -137,12 +128,15 @@ class Emulator(object):
 | 
				
			||||||
        if self.cdist_object.exists:
 | 
					        if self.cdist_object.exists:
 | 
				
			||||||
            if self.cdist_object.parameters != self.parameters:
 | 
					            if self.cdist_object.parameters != self.parameters:
 | 
				
			||||||
                raise cdist.Error("Object %s already exists with conflicting parameters:\n%s: %s\n%s: %s"
 | 
					                raise cdist.Error("Object %s already exists with conflicting parameters:\n%s: %s\n%s: %s"
 | 
				
			||||||
                    % (self.cdist_object, " ".join(self.cdist_object.source), self.cdist_object.parameters, self.object_source, self.parameters)
 | 
					                    % (self.cdist_object.name, " ".join(self.cdist_object.source), self.cdist_object.parameters, self.object_source, self.parameters)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.cdist_object.create()
 | 
					            self.cdist_object.create()
 | 
				
			||||||
            self.cdist_object.parameters = self.parameters
 | 
					            self.cdist_object.parameters = self.parameters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Record / Append source
 | 
				
			||||||
 | 
					        self.cdist_object.source.append(self.object_source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def record_requirements(self):
 | 
					    def record_requirements(self):
 | 
				
			||||||
        """record requirements"""
 | 
					        """record requirements"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,25 +145,17 @@ class Emulator(object):
 | 
				
			||||||
            self.log.debug("reqs = " + requirements)
 | 
					            self.log.debug("reqs = " + requirements)
 | 
				
			||||||
            for requirement in requirements.split(" "):
 | 
					            for requirement in requirements.split(" "):
 | 
				
			||||||
                # Ignore empty fields - probably the only field anyway
 | 
					                # Ignore empty fields - probably the only field anyway
 | 
				
			||||||
                if len(requirement) == 0:
 | 
					                if len(requirement) == 0: continue
 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                requirement_type_name, requirement_object_id = core.Object.split_name(requirement)
 | 
					                # Raises an error, if object cannot be created
 | 
				
			||||||
                # Instantiate type which fails if type does not exist
 | 
					                cdist_object = self.cdist_object.object_from_name(requirement)
 | 
				
			||||||
                requirement_type = core.Type(self.type_base_path, requirement_type_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if requirement_object_id:
 | 
					 | 
				
			||||||
                    # Validate object_id if any
 | 
					 | 
				
			||||||
                    core.Object.validate_object_id(requirement_object_id)
 | 
					 | 
				
			||||||
                elif not requirement_type.is_singleton:
 | 
					 | 
				
			||||||
                    # Only singeltons have no object_id
 | 
					 | 
				
			||||||
                    raise IllegalRequirementError(requirement, "Missing object_id and type is not a singleton.")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                self.log.debug("Recording requirement: " + requirement)
 | 
					                self.log.debug("Recording requirement: " + requirement)
 | 
				
			||||||
                self.cdist_object.requirements.append(requirement)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Record / Append source
 | 
					                # Save the sanitised version, not the user supplied one
 | 
				
			||||||
        self.cdist_object.source.append(self.object_source)
 | 
					                # (__file//bar => __file/bar)
 | 
				
			||||||
 | 
					                # This ensures pattern matching is done against sanitised list
 | 
				
			||||||
 | 
					                self.cdist_object.requirements.append(cdist_object.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def record_auto_requirements(self):
 | 
					    def record_auto_requirements(self):
 | 
				
			||||||
        """An object shall automatically depend on all objects that it defined in it's type manifest.
 | 
					        """An object shall automatically depend on all objects that it defined in it's type manifest.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,18 +32,6 @@ import logging
 | 
				
			||||||
import cdist
 | 
					import cdist
 | 
				
			||||||
from cdist import core
 | 
					from cdist import core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class LocalScriptError(cdist.Error):
 | 
					 | 
				
			||||||
    def __init__(self, script, command, script_content):
 | 
					 | 
				
			||||||
        self.script = script
 | 
					 | 
				
			||||||
        self.command = command
 | 
					 | 
				
			||||||
        self.script_content = script_content
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        plain_command = " ".join(self.command)
 | 
					 | 
				
			||||||
        return "Local script execution failed: %s" % plain_command
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Local(object):
 | 
					class Local(object):
 | 
				
			||||||
    """Execute commands locally.
 | 
					    """Execute commands locally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,35 +107,16 @@ class Local(object):
 | 
				
			||||||
        command = ["/bin/sh", "-e"]
 | 
					        command = ["/bin/sh", "-e"]
 | 
				
			||||||
        command.append(script)
 | 
					        command.append(script)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.log.debug("Local run script: %s", command)
 | 
					        return self.run(command, env, return_output)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if env is None:
 | 
					 | 
				
			||||||
            env = os.environ.copy()
 | 
					 | 
				
			||||||
        # Export __target_host for use in __remote_{copy,exec} scripts
 | 
					 | 
				
			||||||
        env['__target_host'] = self.target_host
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.log.debug("Local run script env: %s", env)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            if return_output:
 | 
					 | 
				
			||||||
                return subprocess.check_output(command, env=env).decode()
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                subprocess.check_call(command, env=env)
 | 
					 | 
				
			||||||
        except subprocess.CalledProcessError as error:
 | 
					 | 
				
			||||||
            script_content = self.run(["cat", script], return_output=True)
 | 
					 | 
				
			||||||
            self.log.error("Code that raised the error:\n%s", script_content)
 | 
					 | 
				
			||||||
            raise LocalScriptError(script, command, script_content)
 | 
					 | 
				
			||||||
        except EnvironmentError as error:
 | 
					 | 
				
			||||||
            raise cdist.Error(" ".join(command) + ": " + error.args[1])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def link_emulator(self, exec_path):
 | 
					    def link_emulator(self, exec_path):
 | 
				
			||||||
        """Link emulator to types"""
 | 
					        """Link emulator to types"""
 | 
				
			||||||
        src = os.path.abspath(exec_path)
 | 
					        src = os.path.abspath(exec_path)
 | 
				
			||||||
        for cdist_type in core.Type.list_types(self.type_path):
 | 
					        for cdist_type in core.CdistType.list_types(self.type_path):
 | 
				
			||||||
            dst = os.path.join(self.bin_path, cdist_type.name)
 | 
					            dst = os.path.join(self.bin_path, cdist_type.name)
 | 
				
			||||||
            self.log.debug("Linking emulator: %s to %s", src, dst)
 | 
					            self.log.debug("Linking emulator: %s to %s", src, dst)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                os.symlink(src, dst)
 | 
					                os.symlink(src, dst)
 | 
				
			||||||
            except OSError as e:
 | 
					            except OSError as e:
 | 
				
			||||||
                raise cdist.Error("Linking emulator from " + src + " to " + dst + " failed: " + e.__str__())
 | 
					                raise cdist.Error("Linking emulator from %s to %s failed: %s" % (src, dst, e.__str__()))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,8 +20,6 @@
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# FIXME: common base class with Local?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import io
 | 
					import io
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
| 
						 | 
					@ -30,17 +28,6 @@ import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cdist
 | 
					import cdist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class RemoteScriptError(cdist.Error):
 | 
					 | 
				
			||||||
    def __init__(self, script, command, script_content):
 | 
					 | 
				
			||||||
        self.script = script
 | 
					 | 
				
			||||||
        self.command = command
 | 
					 | 
				
			||||||
        self.script_content = script_content
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        plain_command = " ".join(self.command)
 | 
					 | 
				
			||||||
        return "Remote script execution failed: %s" % plain_command
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DecodeError(cdist.Error):
 | 
					class DecodeError(cdist.Error):
 | 
				
			||||||
    def __init__(self, command):
 | 
					    def __init__(self, command):
 | 
				
			||||||
        self.command = command
 | 
					        self.command = command
 | 
				
			||||||
| 
						 | 
					@ -93,6 +80,17 @@ class Remote(object):
 | 
				
			||||||
        command.extend(["-r", source, self.target_host + ":" + destination])
 | 
					        command.extend(["-r", source, self.target_host + ":" + destination])
 | 
				
			||||||
        self._run_command(command)
 | 
					        self._run_command(command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run_script(self, script, env=None, return_output=False):
 | 
				
			||||||
 | 
					        """Run the given script with the given environment on the remote side.
 | 
				
			||||||
 | 
					        Return the output as a string.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        command = ["/bin/sh", "-e"]
 | 
				
			||||||
 | 
					        command.append(script)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.run(command, env, return_output)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run(self, command, env=None, return_output=False):
 | 
					    def run(self, command, env=None, return_output=False):
 | 
				
			||||||
        """Run the given command with the given environment on the remote side.
 | 
					        """Run the given command with the given environment on the remote side.
 | 
				
			||||||
        Return the output as a string.
 | 
					        Return the output as a string.
 | 
				
			||||||
| 
						 | 
					@ -101,7 +99,15 @@ class Remote(object):
 | 
				
			||||||
        # prefix given command with remote_exec
 | 
					        # prefix given command with remote_exec
 | 
				
			||||||
        cmd = self._exec.split()
 | 
					        cmd = self._exec.split()
 | 
				
			||||||
        cmd.append(self.target_host)
 | 
					        cmd.append(self.target_host)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # can't pass environment to remote side, so prepend command with
 | 
				
			||||||
 | 
					        # variable declarations
 | 
				
			||||||
 | 
					        if env:
 | 
				
			||||||
 | 
					            remote_env = ["%s=%s" % item for item in env.items()]
 | 
				
			||||||
 | 
					            cmd.extend(remote_env)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cmd.extend(command)
 | 
					        cmd.extend(command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self._run_command(cmd, env=env, return_output=return_output)
 | 
					        return self._run_command(cmd, env=env, return_output=return_output)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _run_command(self, command, env=None, return_output=False):
 | 
					    def _run_command(self, command, env=None, return_output=False):
 | 
				
			||||||
| 
						 | 
					@ -115,14 +121,6 @@ class Remote(object):
 | 
				
			||||||
        os_environ = os.environ.copy()
 | 
					        os_environ = os.environ.copy()
 | 
				
			||||||
        os_environ['__target_host'] = self.target_host
 | 
					        os_environ['__target_host'] = self.target_host
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # can't pass environment to remote side, so prepend command with
 | 
					 | 
				
			||||||
        # variable declarations
 | 
					 | 
				
			||||||
        if env:
 | 
					 | 
				
			||||||
            cmd = ["%s=%s" % item for item in env.items()]
 | 
					 | 
				
			||||||
            cmd.extend(command)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            cmd = command
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.log.debug("Remote run: %s", command)
 | 
					        self.log.debug("Remote run: %s", command)
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if return_output:
 | 
					            if return_output:
 | 
				
			||||||
| 
						 | 
					@ -135,39 +133,3 @@ class Remote(object):
 | 
				
			||||||
            raise cdist.Error(" ".join(*args) + ": " + error.args[1])
 | 
					            raise cdist.Error(" ".join(*args) + ": " + error.args[1])
 | 
				
			||||||
        except UnicodeDecodeError:
 | 
					        except UnicodeDecodeError:
 | 
				
			||||||
            raise DecodeError(command)
 | 
					            raise DecodeError(command)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def run_script(self, script, env=None, return_output=False):
 | 
					 | 
				
			||||||
        """Run the given script with the given environment on the remote side.
 | 
					 | 
				
			||||||
        Return the output as a string.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        command = self._exec.split()
 | 
					 | 
				
			||||||
        command.append(self.target_host)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # export target_host for use in __remote_{exec,copy} scripts
 | 
					 | 
				
			||||||
        os_environ = os.environ.copy()
 | 
					 | 
				
			||||||
        os_environ['__target_host'] = self.target_host
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # can't pass environment to remote side, so prepend command with
 | 
					 | 
				
			||||||
        # variable declarations
 | 
					 | 
				
			||||||
        if env:
 | 
					 | 
				
			||||||
            command.extend(["%s=%s" % item for item in env.items()])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        command.extend(["/bin/sh", "-e"])
 | 
					 | 
				
			||||||
        command.append(script)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.log.debug("Remote run script: %s", command)
 | 
					 | 
				
			||||||
        if env:
 | 
					 | 
				
			||||||
            self.log.debug("Remote run script env: %s", env)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            if return_output:
 | 
					 | 
				
			||||||
                return subprocess.check_output(command, env=os_environ).decode()
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                subprocess.check_call(command, env=os_environ)
 | 
					 | 
				
			||||||
        except subprocess.CalledProcessError as error:
 | 
					 | 
				
			||||||
            script_content = self.run(["cat", script], return_output=True)
 | 
					 | 
				
			||||||
            self.log.error("Code that raised the error:\n%s", script_content)
 | 
					 | 
				
			||||||
            raise RemoteScriptError(script, command, script_content)
 | 
					 | 
				
			||||||
        except EnvironmentError as error:
 | 
					 | 
				
			||||||
            raise cdist.Error(" ".join(command) + ": " + error.args[1])
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,7 @@ class DependencyResolver(object):
 | 
				
			||||||
            resolved.append(cdist_object)
 | 
					            resolved.append(cdist_object)
 | 
				
			||||||
            unresolved.remove(cdist_object)
 | 
					            unresolved.remove(cdist_object)
 | 
				
			||||||
        except RequirementNotFoundError as e:
 | 
					        except RequirementNotFoundError as e:
 | 
				
			||||||
            raise cdist.Error(cdist_object.name + " requires non-existing " + e.requirement)
 | 
					            raise cdist.CdistObjectError(cdist_object, "requires non-existing " + e.requirement)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __iter__(self):
 | 
					    def __iter__(self):
 | 
				
			||||||
        """Iterate over all unique objects while resolving dependencies.
 | 
					        """Iterate over all unique objects while resolving dependencies.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,8 @@ class CodeTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.code = code.Code(self.target_host, self.local, self.remote)
 | 
					        self.code = code.Code(self.target_host, self.local, self.remote)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.cdist_type = core.Type(self.local.type_path, '__dump_environment')
 | 
					        self.cdist_type = core.CdistType(self.local.type_path, '__dump_environment')
 | 
				
			||||||
        self.cdist_object = core.Object(self.cdist_type, self.local.object_path, 'whatever')
 | 
					        self.cdist_object = core.CdistObject(self.cdist_type, self.local.object_path, 'whatever')
 | 
				
			||||||
        self.cdist_object.create()
 | 
					        self.cdist_object.create()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.log = logging.getLogger("cdist")
 | 
					        self.log = logging.getLogger("cdist")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,7 @@ class EmulatorTestCase(test.CdistTestCase):
 | 
				
			||||||
        os.environ.update(self.env)
 | 
					        os.environ.update(self.env)
 | 
				
			||||||
        os.environ['require'] = '__file'
 | 
					        os.environ['require'] = '__file'
 | 
				
			||||||
        emu = emulator.Emulator(argv)
 | 
					        emu = emulator.Emulator(argv)
 | 
				
			||||||
        self.assertRaises(emulator.IllegalRequirementError, emu.run)
 | 
					        self.assertRaises(core.IllegalObjectIdError, emu.run)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_singleton_object_requirement(self):
 | 
					    def test_singleton_object_requirement(self):
 | 
				
			||||||
        argv = ['__file', '/tmp/foobar']
 | 
					        argv = ['__file', '/tmp/foobar']
 | 
				
			||||||
| 
						 | 
					@ -119,14 +119,14 @@ class AutoRequireEmulatorTestCase(test.CdistTestCase):
 | 
				
			||||||
    def test_autorequire(self):
 | 
					    def test_autorequire(self):
 | 
				
			||||||
        initial_manifest = os.path.join(self.local.manifest_path, "init")
 | 
					        initial_manifest = os.path.join(self.local.manifest_path, "init")
 | 
				
			||||||
        self.manifest.run_initial_manifest(initial_manifest)
 | 
					        self.manifest.run_initial_manifest(initial_manifest)
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__saturn')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__saturn')
 | 
				
			||||||
        cdist_object = core.Object(cdist_type, self.local.object_path, 'singleton')
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'singleton')
 | 
				
			||||||
        self.manifest.run_type_manifest(cdist_object)
 | 
					        self.manifest.run_type_manifest(cdist_object)
 | 
				
			||||||
        expected = ['__planet/Saturn', '__moon/Prometheus']
 | 
					        expected = ['__planet/Saturn', '__moon/Prometheus']
 | 
				
			||||||
        self.assertEqual(sorted(cdist_object.requirements), sorted(expected))
 | 
					        self.assertEqual(sorted(cdist_object.requirements), sorted(expected))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ArgumentsWithDashesTestCase(test.CdistTestCase):
 | 
					class ArgumentsTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.temp_dir = self.mkdtemp()
 | 
					        self.temp_dir = self.mkdtemp()
 | 
				
			||||||
| 
						 | 
					@ -156,6 +156,62 @@ class ArgumentsWithDashesTestCase(test.CdistTestCase):
 | 
				
			||||||
        emu = emulator.Emulator(argv)
 | 
					        emu = emulator.Emulator(argv)
 | 
				
			||||||
        emu.run()
 | 
					        emu.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__arguments_with_dashes')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__arguments_with_dashes')
 | 
				
			||||||
        cdist_object = core.Object(cdist_type, self.local.object_path, 'some-id')
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'some-id')
 | 
				
			||||||
        self.assertTrue('with-dash' in cdist_object.parameters)
 | 
					        self.assertTrue('with-dash' in cdist_object.parameters)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_boolean(self):
 | 
				
			||||||
 | 
					        type_name = '__arguments_boolean'
 | 
				
			||||||
 | 
					        object_id = 'some-id'
 | 
				
			||||||
 | 
					        argv = [type_name, object_id, '--boolean1']
 | 
				
			||||||
 | 
					        os.environ.update(self.env)
 | 
				
			||||||
 | 
					        emu = emulator.Emulator(argv)
 | 
				
			||||||
 | 
					        emu.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cdist_type = core.CdistType(self.local.type_path, type_name)
 | 
				
			||||||
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
 | 
				
			||||||
 | 
					        self.assertTrue('boolean1' in cdist_object.parameters)
 | 
				
			||||||
 | 
					        self.assertFalse('boolean2' in cdist_object.parameters)
 | 
				
			||||||
 | 
					        # empty file -> True
 | 
				
			||||||
 | 
					        self.assertTrue(cdist_object.parameters['boolean1'] == '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_required(self):
 | 
				
			||||||
 | 
					        type_name = '__arguments_required'
 | 
				
			||||||
 | 
					        object_id = 'some-id'
 | 
				
			||||||
 | 
					        value = 'some value'
 | 
				
			||||||
 | 
					        argv = [type_name, object_id, '--required1', value, '--required2', value]
 | 
				
			||||||
 | 
					        os.environ.update(self.env)
 | 
				
			||||||
 | 
					        emu = emulator.Emulator(argv)
 | 
				
			||||||
 | 
					        emu.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cdist_type = core.CdistType(self.local.type_path, type_name)
 | 
				
			||||||
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
 | 
				
			||||||
 | 
					        self.assertTrue('required1' in cdist_object.parameters)
 | 
				
			||||||
 | 
					        self.assertTrue('required2' in cdist_object.parameters)
 | 
				
			||||||
 | 
					        self.assertEqual(cdist_object.parameters['required1'], value)
 | 
				
			||||||
 | 
					        self.assertEqual(cdist_object.parameters['required2'], value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#    def test_required_missing(self):
 | 
				
			||||||
 | 
					#        type_name = '__arguments_required'
 | 
				
			||||||
 | 
					#        object_id = 'some-id'
 | 
				
			||||||
 | 
					#        value = 'some value'
 | 
				
			||||||
 | 
					#        argv = [type_name, object_id, '--required1', value]
 | 
				
			||||||
 | 
					#        os.environ.update(self.env)
 | 
				
			||||||
 | 
					#        emu = emulator.Emulator(argv)
 | 
				
			||||||
 | 
					#        
 | 
				
			||||||
 | 
					#        self.assertRaises(SystemExit, emu.run)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_optional(self):
 | 
				
			||||||
 | 
					        type_name = '__arguments_optional'
 | 
				
			||||||
 | 
					        object_id = 'some-id'
 | 
				
			||||||
 | 
					        value = 'some value'
 | 
				
			||||||
 | 
					        argv = [type_name, object_id, '--optional1', value]
 | 
				
			||||||
 | 
					        os.environ.update(self.env)
 | 
				
			||||||
 | 
					        emu = emulator.Emulator(argv)
 | 
				
			||||||
 | 
					        emu.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cdist_type = core.CdistType(self.local.type_path, type_name)
 | 
				
			||||||
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
 | 
				
			||||||
 | 
					        self.assertTrue('optional1' in cdist_object.parameters)
 | 
				
			||||||
 | 
					        self.assertFalse('optional2' in cdist_object.parameters)
 | 
				
			||||||
 | 
					        self.assertEqual(cdist_object.parameters['optional1'], value)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					boolean1
 | 
				
			||||||
 | 
					boolean2
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					optional1
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					required1
 | 
				
			||||||
 | 
					required2
 | 
				
			||||||
| 
						 | 
					@ -83,19 +83,19 @@ class ExplorerClassTestCase(test.CdistTestCase):
 | 
				
			||||||
        shutil.rmtree(out_path)
 | 
					        shutil.rmtree(out_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_list_type_explorer_names(self):
 | 
					    def test_list_type_explorer_names(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__test_type')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__test_type')
 | 
				
			||||||
        expected = cdist_type.explorers
 | 
					        expected = cdist_type.explorers
 | 
				
			||||||
        self.assertEqual(self.explorer.list_type_explorer_names(cdist_type), expected)
 | 
					        self.assertEqual(self.explorer.list_type_explorer_names(cdist_type), expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_transfer_type_explorers(self):
 | 
					    def test_transfer_type_explorers(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__test_type')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__test_type')
 | 
				
			||||||
        self.explorer.transfer_type_explorers(cdist_type)
 | 
					        self.explorer.transfer_type_explorers(cdist_type)
 | 
				
			||||||
        source = os.path.join(self.local.type_path, cdist_type.explorer_path)
 | 
					        source = os.path.join(self.local.type_path, cdist_type.explorer_path)
 | 
				
			||||||
        destination = os.path.join(self.remote.type_path, cdist_type.explorer_path)
 | 
					        destination = os.path.join(self.remote.type_path, cdist_type.explorer_path)
 | 
				
			||||||
        self.assertEqual(os.listdir(source), os.listdir(destination))
 | 
					        self.assertEqual(os.listdir(source), os.listdir(destination))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_transfer_type_explorers_only_once(self):
 | 
					    def test_transfer_type_explorers_only_once(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__test_type')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__test_type')
 | 
				
			||||||
        # first transfer
 | 
					        # first transfer
 | 
				
			||||||
        self.explorer.transfer_type_explorers(cdist_type)
 | 
					        self.explorer.transfer_type_explorers(cdist_type)
 | 
				
			||||||
        source = os.path.join(self.local.type_path, cdist_type.explorer_path)
 | 
					        source = os.path.join(self.local.type_path, cdist_type.explorer_path)
 | 
				
			||||||
| 
						 | 
					@ -109,8 +109,8 @@ class ExplorerClassTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.assertFalse(os.listdir(destination))
 | 
					        self.assertFalse(os.listdir(destination))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_transfer_object_parameters(self):
 | 
					    def test_transfer_object_parameters(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__test_type')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__test_type')
 | 
				
			||||||
        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
 | 
				
			||||||
        cdist_object.create()
 | 
					        cdist_object.create()
 | 
				
			||||||
        cdist_object.parameters = {'first': 'first value', 'second': 'second value'}
 | 
					        cdist_object.parameters = {'first': 'first value', 'second': 'second value'}
 | 
				
			||||||
        self.explorer.transfer_object_parameters(cdist_object)
 | 
					        self.explorer.transfer_object_parameters(cdist_object)
 | 
				
			||||||
| 
						 | 
					@ -119,15 +119,15 @@ class ExplorerClassTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.assertEqual(sorted(os.listdir(source)), sorted(os.listdir(destination)))
 | 
					        self.assertEqual(sorted(os.listdir(source)), sorted(os.listdir(destination)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_run_type_explorer(self):
 | 
					    def test_run_type_explorer(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__test_type')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__test_type')
 | 
				
			||||||
        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
 | 
				
			||||||
        self.explorer.transfer_type_explorers(cdist_type)
 | 
					        self.explorer.transfer_type_explorers(cdist_type)
 | 
				
			||||||
        output = self.explorer.run_type_explorer('world', cdist_object)
 | 
					        output = self.explorer.run_type_explorer('world', cdist_object)
 | 
				
			||||||
        self.assertEqual(output, 'hello\n')
 | 
					        self.assertEqual(output, 'hello\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_run_type_explorers(self):
 | 
					    def test_run_type_explorers(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__test_type')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__test_type')
 | 
				
			||||||
        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
 | 
				
			||||||
        cdist_object.create()
 | 
					        cdist_object.create()
 | 
				
			||||||
        self.explorer.run_type_explorers(cdist_object)
 | 
					        self.explorer.run_type_explorers(cdist_object)
 | 
				
			||||||
        self.assertEqual(cdist_object.explorers, {'world': 'hello'})
 | 
					        self.assertEqual(cdist_object.explorers, {'world': 'hello'})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,8 +79,8 @@ class ManifestTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.assertEqual(output_dict['__manifest'], self.local.manifest_path)
 | 
					        self.assertEqual(output_dict['__manifest'], self.local.manifest_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_type_manifest_environment(self):
 | 
					    def test_type_manifest_environment(self):
 | 
				
			||||||
        cdist_type = core.Type(self.local.type_path, '__dump_environment')
 | 
					        cdist_type = core.CdistType(self.local.type_path, '__dump_environment')
 | 
				
			||||||
        cdist_object = core.Object(cdist_type, self.local.object_path, 'whatever')
 | 
					        cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'whatever')
 | 
				
			||||||
        handle, output_file = self.mkstemp(dir=self.temp_dir)
 | 
					        handle, output_file = self.mkstemp(dir=self.temp_dir)
 | 
				
			||||||
        os.close(handle)
 | 
					        os.close(handle)
 | 
				
			||||||
        os.environ['__cdist_test_out'] = output_file
 | 
					        os.environ['__cdist_test_out'] = output_file
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,8 @@ import shutil
 | 
				
			||||||
from cdist import test
 | 
					from cdist import test
 | 
				
			||||||
from cdist import core
 | 
					from cdist import core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cdist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os.path as op
 | 
					import os.path as op
 | 
				
			||||||
my_dir = op.abspath(op.dirname(__file__))
 | 
					my_dir = op.abspath(op.dirname(__file__))
 | 
				
			||||||
fixtures = op.join(my_dir, 'fixtures')
 | 
					fixtures = op.join(my_dir, 'fixtures')
 | 
				
			||||||
| 
						 | 
					@ -34,48 +36,48 @@ type_base_path = op.join(fixtures, 'type')
 | 
				
			||||||
class ObjectClassTestCase(test.CdistTestCase):
 | 
					class ObjectClassTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_list_object_names(self):
 | 
					    def test_list_object_names(self):
 | 
				
			||||||
        object_names = list(core.Object.list_object_names(object_base_path))
 | 
					        object_names = list(core.CdistObject.list_object_names(object_base_path))
 | 
				
			||||||
        self.assertEqual(object_names, ['__first/man', '__second/on-the', '__third/moon'])
 | 
					        self.assertEqual(object_names, ['__first/man', '__second/on-the', '__third/moon'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_list_type_names(self):
 | 
					    def test_list_type_names(self):
 | 
				
			||||||
        type_names = list(core.Object.list_type_names(object_base_path))
 | 
					        type_names = list(cdist.core.CdistObject.list_type_names(object_base_path))
 | 
				
			||||||
        self.assertEqual(type_names, ['__first', '__second', '__third'])
 | 
					        self.assertEqual(type_names, ['__first', '__second', '__third'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_list_objects(self):
 | 
					    def test_list_objects(self):
 | 
				
			||||||
        objects = list(core.Object.list_objects(object_base_path, type_base_path))
 | 
					        objects = list(core.CdistObject.list_objects(object_base_path, type_base_path))
 | 
				
			||||||
        objects_expected = [
 | 
					        objects_expected = [
 | 
				
			||||||
            core.Object(core.Type(type_base_path, '__first'), object_base_path, 'man'),
 | 
					            core.CdistObject(core.CdistType(type_base_path, '__first'), object_base_path, 'man'),
 | 
				
			||||||
            core.Object(core.Type(type_base_path, '__second'), object_base_path, 'on-the'),
 | 
					            core.CdistObject(core.CdistType(type_base_path, '__second'), object_base_path, 'on-the'),
 | 
				
			||||||
            core.Object(core.Type(type_base_path, '__third'), object_base_path, 'moon'),
 | 
					            core.CdistObject(core.CdistType(type_base_path, '__third'), object_base_path, 'moon'),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        self.assertEqual(objects, objects_expected)
 | 
					        self.assertEqual(objects, objects_expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ObjectIdTestCase(test.CdistTestCase):
 | 
					class ObjectIdTestCase(test.CdistTestCase):
 | 
				
			||||||
    def test_object_id_starts_with_slash(self):
 | 
					    def test_object_id_contains_double_slash(self):
 | 
				
			||||||
        cdist_type = core.Type(type_base_path, '__third')
 | 
					        cdist_type = core.CdistType(type_base_path, '__third')
 | 
				
			||||||
        illegal_object_id = '/object_id/may/not/start/with/slash'
 | 
					        illegal_object_id = '/object_id//may/not/contain/double/slash'
 | 
				
			||||||
        with self.assertRaises(core.IllegalObjectIdError):
 | 
					        with self.assertRaises(core.IllegalObjectIdError):
 | 
				
			||||||
            core.Object(cdist_type, object_base_path, illegal_object_id)
 | 
					            core.CdistObject(cdist_type, object_base_path, illegal_object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_object_id_contains_object_marker(self):
 | 
					    def test_object_id_contains_object_marker(self):
 | 
				
			||||||
        cdist_type = core.Type(type_base_path, '__third')
 | 
					        cdist_type = core.CdistType(type_base_path, '__third')
 | 
				
			||||||
        illegal_object_id = 'object_id/may/not/contain/%s/anywhere' % core.OBJECT_MARKER
 | 
					        illegal_object_id = 'object_id/may/not/contain/%s/anywhere' % core.OBJECT_MARKER
 | 
				
			||||||
        with self.assertRaises(core.IllegalObjectIdError):
 | 
					        with self.assertRaises(core.IllegalObjectIdError):
 | 
				
			||||||
            core.Object(cdist_type, object_base_path, illegal_object_id)
 | 
					            core.CdistObject(cdist_type, object_base_path, illegal_object_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_object_id_contains_object_marker_string(self):
 | 
					    def test_object_id_contains_object_marker_string(self):
 | 
				
			||||||
        cdist_type = core.Type(type_base_path, '__third')
 | 
					        cdist_type = core.CdistType(type_base_path, '__third')
 | 
				
			||||||
        illegal_object_id = 'object_id/may/contain_%s_in_filename' % core.OBJECT_MARKER
 | 
					        illegal_object_id = 'object_id/may/contain_%s_in_filename' % core.OBJECT_MARKER
 | 
				
			||||||
        core.Object(cdist_type, object_base_path, illegal_object_id)
 | 
					        core.CdistObject(cdist_type, object_base_path, illegal_object_id)
 | 
				
			||||||
        # if we get here, the test passed
 | 
					        # if we get here, the test passed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ObjectTestCase(test.CdistTestCase):
 | 
					class ObjectTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.cdist_type = core.Type(type_base_path, '__third')
 | 
					        self.cdist_type = core.CdistType(type_base_path, '__third')
 | 
				
			||||||
        self.cdist_object = core.Object(self.cdist_type, object_base_path, 'moon') 
 | 
					        self.cdist_object = core.CdistObject(self.cdist_type, object_base_path, 'moon') 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tearDown(self):
 | 
					    def tearDown(self):
 | 
				
			||||||
        self.cdist_object.changed = False
 | 
					        self.cdist_object.changed = False
 | 
				
			||||||
| 
						 | 
					@ -159,16 +161,16 @@ class ObjectTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.assertEqual(self.cdist_object.state, '')
 | 
					        self.assertEqual(self.cdist_object.state, '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_state_prepared(self):
 | 
					    def test_state_prepared(self):
 | 
				
			||||||
        self.cdist_object.state = core.Object.STATE_PREPARED
 | 
					        self.cdist_object.state = core.CdistObject.STATE_PREPARED
 | 
				
			||||||
        self.assertEqual(self.cdist_object.state, core.Object.STATE_PREPARED)
 | 
					        self.assertEqual(self.cdist_object.state, core.CdistObject.STATE_PREPARED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_state_running(self):
 | 
					    def test_state_running(self):
 | 
				
			||||||
        self.cdist_object.state = core.Object.STATE_RUNNING
 | 
					        self.cdist_object.state = core.CdistObject.STATE_RUNNING
 | 
				
			||||||
        self.assertEqual(self.cdist_object.state, core.Object.STATE_RUNNING)
 | 
					        self.assertEqual(self.cdist_object.state, core.CdistObject.STATE_RUNNING)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_state_done(self):
 | 
					    def test_state_done(self):
 | 
				
			||||||
        self.cdist_object.state = core.Object.STATE_DONE
 | 
					        self.cdist_object.state = core.CdistObject.STATE_DONE
 | 
				
			||||||
        self.assertEqual(self.cdist_object.state, core.Object.STATE_DONE)
 | 
					        self.assertEqual(self.cdist_object.state, core.CdistObject.STATE_DONE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_source(self):
 | 
					    def test_source(self):
 | 
				
			||||||
        self.assertEqual(list(self.cdist_object.source), [])
 | 
					        self.assertEqual(list(self.cdist_object.source), [])
 | 
				
			||||||
| 
						 | 
					@ -195,6 +197,6 @@ class ObjectTestCase(test.CdistTestCase):
 | 
				
			||||||
        self.cdist_object.code_remote = 'Hello World'
 | 
					        self.cdist_object.code_remote = 'Hello World'
 | 
				
			||||||
        other_name = '__first/man'
 | 
					        other_name = '__first/man'
 | 
				
			||||||
        other_object = self.cdist_object.object_from_name(other_name)
 | 
					        other_object = self.cdist_object.object_from_name(other_name)
 | 
				
			||||||
        self.assertTrue(isinstance(other_object, core.Object))
 | 
					        self.assertTrue(isinstance(other_object, core.CdistObject))
 | 
				
			||||||
        self.assertEqual(other_object.type.name, '__first')
 | 
					        self.assertEqual(other_object.cdist_type.name, '__first')
 | 
				
			||||||
        self.assertEqual(other_object.object_id, 'man')
 | 
					        self.assertEqual(other_object.object_id, 'man')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@ type_base_path = op.join(fixtures, 'type')
 | 
				
			||||||
class ResolverTestCase(test.CdistTestCase):
 | 
					class ResolverTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.objects = list(core.Object.list_objects(object_base_path, type_base_path))
 | 
					        self.objects = list(core.CdistObject.list_objects(object_base_path, type_base_path))
 | 
				
			||||||
        self.object_index = dict((o.name, o) for o in self.objects)
 | 
					        self.object_index = dict((o.name, o) for o in self.objects)
 | 
				
			||||||
        self.dependency_resolver = resolver.DependencyResolver(self.objects)
 | 
					        self.dependency_resolver = resolver.DependencyResolver(self.objects)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,115 +33,126 @@ class TypeTestCase(test.CdistTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_list_type_names(self):
 | 
					    def test_list_type_names(self):
 | 
				
			||||||
        base_path = op.join(fixtures, 'list_types')
 | 
					        base_path = op.join(fixtures, 'list_types')
 | 
				
			||||||
        type_names = core.Type.list_type_names(base_path)
 | 
					        type_names = core.CdistType.list_type_names(base_path)
 | 
				
			||||||
        self.assertEqual(type_names, ['__first', '__second', '__third'])
 | 
					        self.assertEqual(type_names, ['__first', '__second', '__third'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_list_types(self):
 | 
					    def test_list_types(self):
 | 
				
			||||||
        base_path = op.join(fixtures, 'list_types')
 | 
					        base_path = op.join(fixtures, 'list_types')
 | 
				
			||||||
        types = list(core.Type.list_types(base_path))
 | 
					        types = list(core.CdistType.list_types(base_path))
 | 
				
			||||||
        types_expected = [
 | 
					        types_expected = [
 | 
				
			||||||
            core.Type(base_path, '__first'),
 | 
					            core.CdistType(base_path, '__first'),
 | 
				
			||||||
            core.Type(base_path, '__second'),
 | 
					            core.CdistType(base_path, '__second'),
 | 
				
			||||||
            core.Type(base_path, '__third'),
 | 
					            core.CdistType(base_path, '__third'),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        self.assertEqual(types, types_expected)
 | 
					        self.assertEqual(types, types_expected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_only_one_instance(self):
 | 
					    def test_only_one_instance(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type1 = core.Type(base_path, '__name_path')
 | 
					        cdist_type1 = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        cdist_type2 = core.Type(base_path, '__name_path')
 | 
					        cdist_type2 = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(id(cdist_type1), id(cdist_type2))
 | 
					        self.assertEqual(id(cdist_type1), id(cdist_type2))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_nonexistent_type(self):
 | 
					    def test_nonexistent_type(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        self.assertRaises(core.NoSuchTypeError, core.Type, base_path, '__i-dont-exist')
 | 
					        self.assertRaises(core.NoSuchTypeError, core.CdistType, base_path, '__i-dont-exist')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_name(self):
 | 
					    def test_name(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.name, '__name_path')
 | 
					        self.assertEqual(cdist_type.name, '__name_path')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_path(self):
 | 
					    def test_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.path, '__name_path')
 | 
					        self.assertEqual(cdist_type.path, '__name_path')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_base_path(self):
 | 
					    def test_base_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.base_path, base_path)
 | 
					        self.assertEqual(cdist_type.base_path, base_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_absolute_path(self):
 | 
					    def test_absolute_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.absolute_path, os.path.join(base_path, '__name_path'))
 | 
					        self.assertEqual(cdist_type.absolute_path, os.path.join(base_path, '__name_path'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_manifest_path(self):
 | 
					    def test_manifest_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.manifest_path, os.path.join('__name_path', 'manifest'))
 | 
					        self.assertEqual(cdist_type.manifest_path, os.path.join('__name_path', 'manifest'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_explorer_path(self):
 | 
					    def test_explorer_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.explorer_path, os.path.join('__name_path', 'explorer'))
 | 
					        self.assertEqual(cdist_type.explorer_path, os.path.join('__name_path', 'explorer'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_gencode_local_path(self):
 | 
					    def test_gencode_local_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.gencode_local_path, os.path.join('__name_path', 'gencode-local'))
 | 
					        self.assertEqual(cdist_type.gencode_local_path, os.path.join('__name_path', 'gencode-local'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_gencode_remote_path(self):
 | 
					    def test_gencode_remote_path(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__name_path')
 | 
					        cdist_type = core.CdistType(base_path, '__name_path')
 | 
				
			||||||
        self.assertEqual(cdist_type.gencode_remote_path, os.path.join('__name_path', 'gencode-remote'))
 | 
					        self.assertEqual(cdist_type.gencode_remote_path, os.path.join('__name_path', 'gencode-remote'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_singleton_is_singleton(self):
 | 
					    def test_singleton_is_singleton(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__singleton')
 | 
					        cdist_type = core.CdistType(base_path, '__singleton')
 | 
				
			||||||
        self.assertTrue(cdist_type.is_singleton)
 | 
					        self.assertTrue(cdist_type.is_singleton)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_not_singleton_is_singleton(self):
 | 
					    def test_not_singleton_is_singleton(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__not_singleton')
 | 
					        cdist_type = core.CdistType(base_path, '__not_singleton')
 | 
				
			||||||
        self.assertFalse(cdist_type.is_singleton)
 | 
					        self.assertFalse(cdist_type.is_singleton)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_install_is_install(self):
 | 
					    def test_install_is_install(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__install')
 | 
					        cdist_type = core.CdistType(base_path, '__install')
 | 
				
			||||||
        self.assertTrue(cdist_type.is_install)
 | 
					        self.assertTrue(cdist_type.is_install)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_not_install_is_install(self):
 | 
					    def test_not_install_is_install(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__not_install')
 | 
					        cdist_type = core.CdistType(base_path, '__not_install')
 | 
				
			||||||
        self.assertFalse(cdist_type.is_install)
 | 
					        self.assertFalse(cdist_type.is_install)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_with_explorers(self):
 | 
					    def test_with_explorers(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__with_explorers')
 | 
					        cdist_type = core.CdistType(base_path, '__with_explorers')
 | 
				
			||||||
        self.assertEqual(cdist_type.explorers, ['whatever'])
 | 
					        self.assertEqual(cdist_type.explorers, ['whatever'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_without_explorers(self):
 | 
					    def test_without_explorers(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__without_explorers')
 | 
					        cdist_type = core.CdistType(base_path, '__without_explorers')
 | 
				
			||||||
        self.assertEqual(cdist_type.explorers, [])
 | 
					        self.assertEqual(cdist_type.explorers, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_with_required_parameters(self):
 | 
					    def test_with_required_parameters(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__with_required_parameters')
 | 
					        cdist_type = core.CdistType(base_path, '__with_required_parameters')
 | 
				
			||||||
        self.assertEqual(cdist_type.required_parameters, ['required1', 'required2'])
 | 
					        self.assertEqual(cdist_type.required_parameters, ['required1', 'required2'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_without_required_parameters(self):
 | 
					    def test_without_required_parameters(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__without_required_parameters')
 | 
					        cdist_type = core.CdistType(base_path, '__without_required_parameters')
 | 
				
			||||||
        self.assertEqual(cdist_type.required_parameters, [])
 | 
					        self.assertEqual(cdist_type.required_parameters, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_with_optional_parameters(self):
 | 
					    def test_with_optional_parameters(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__with_optional_parameters')
 | 
					        cdist_type = core.CdistType(base_path, '__with_optional_parameters')
 | 
				
			||||||
        self.assertEqual(cdist_type.optional_parameters, ['optional1', 'optional2'])
 | 
					        self.assertEqual(cdist_type.optional_parameters, ['optional1', 'optional2'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_without_optional_parameters(self):
 | 
					    def test_without_optional_parameters(self):
 | 
				
			||||||
        base_path = fixtures
 | 
					        base_path = fixtures
 | 
				
			||||||
        cdist_type = core.Type(base_path, '__without_optional_parameters')
 | 
					        cdist_type = core.CdistType(base_path, '__without_optional_parameters')
 | 
				
			||||||
        self.assertEqual(cdist_type.optional_parameters, [])
 | 
					        self.assertEqual(cdist_type.optional_parameters, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_with_boolean_parameters(self):
 | 
				
			||||||
 | 
					        base_path = fixtures
 | 
				
			||||||
 | 
					        cdist_type = core.CdistType(base_path, '__with_boolean_parameters')
 | 
				
			||||||
 | 
					        self.assertEqual(cdist_type.boolean_parameters, ['boolean1', 'boolean2'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_without_boolean_parameters(self):
 | 
				
			||||||
 | 
					        base_path = fixtures
 | 
				
			||||||
 | 
					        cdist_type = core.CdistType(base_path, '__without_boolean_parameters')
 | 
				
			||||||
 | 
					        self.assertEqual(cdist_type.boolean_parameters, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					boolean1
 | 
				
			||||||
 | 
					boolean2
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue