forked from ungleich-public/cdist
		
	intial take on fixing the file type
- upload file in a safer way - remove destination if it is not a file - only set attributes if required Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
This commit is contained in:
		
					parent
					
						
							
								4302b7592d
							
						
					
				
			
			
				commit
				
					
						db29ea8e70
					
				
			
		
					 7 changed files with 150 additions and 76 deletions
				
			
		| 
						 | 
				
			
			@ -1,30 +0,0 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# 2011-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 file exists or not
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
destination="/$__object_id"
 | 
			
		||||
 | 
			
		||||
if [ -e "$destination" ]; then
 | 
			
		||||
    echo yes
 | 
			
		||||
else
 | 
			
		||||
    echo no
 | 
			
		||||
fi
 | 
			
		||||
							
								
								
									
										30
									
								
								cdist/conf/type/__file/explorer/stat
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								cdist/conf/type/__file/explorer/stat
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
 | 
			
		||||
 | 
			
		||||
destination="/$__object_id"
 | 
			
		||||
 | 
			
		||||
# nothing to work with, nothing we could do
 | 
			
		||||
[ -e "$destination" ] || exit 0
 | 
			
		||||
 | 
			
		||||
os=$("$__explorer/os")
 | 
			
		||||
case "$os" in
 | 
			
		||||
   "freebsd")
 | 
			
		||||
      # FIXME: should be something like this based on man page, but can not test
 | 
			
		||||
      stat -f "type: %ST
 | 
			
		||||
owner: %Du %Su
 | 
			
		||||
group: %Dg %Sg
 | 
			
		||||
mode: %Op %Sp
 | 
			
		||||
size: %Dz
 | 
			
		||||
links: %Dl
 | 
			
		||||
" "$destination"
 | 
			
		||||
   ;;
 | 
			
		||||
   *)
 | 
			
		||||
      stat --printf="type: %F
 | 
			
		||||
owner: %u %U
 | 
			
		||||
group: %g %G
 | 
			
		||||
mode: %a %A
 | 
			
		||||
size: %s
 | 
			
		||||
links: %h
 | 
			
		||||
" "$destination"
 | 
			
		||||
   ;;
 | 
			
		||||
esac
 | 
			
		||||
							
								
								
									
										16
									
								
								cdist/conf/type/__file/explorer/type
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								cdist/conf/type/__file/explorer/type
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
 | 
			
		||||
 | 
			
		||||
destination="/$__object_id"
 | 
			
		||||
 | 
			
		||||
if [ ! -e "$destination" ]; then
 | 
			
		||||
   echo none
 | 
			
		||||
elif [ -h "$destination" ]; then
 | 
			
		||||
   echo symlink
 | 
			
		||||
elif [ -f "$destination" ]; then
 | 
			
		||||
   echo file
 | 
			
		||||
elif [ -d "$destination" ]; then
 | 
			
		||||
   echo directory
 | 
			
		||||
else
 | 
			
		||||
   echo unknown
 | 
			
		||||
fi
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
			
		||||
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
 | 
			
		||||
#
 | 
			
		||||
# This file is part of cdist.
 | 
			
		||||
#
 | 
			
		||||
| 
						 | 
				
			
			@ -17,34 +18,46 @@
 | 
			
		|||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# __file is a very basic type, which will probably be reused quite often
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
destination="/$__object_id"
 | 
			
		||||
state_should=present
 | 
			
		||||
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
 | 
			
		||||
exists="$(cat "$__object/explorer/exists")"
 | 
			
		||||
state_should="$(cat "$__object/parameter/state")"
 | 
			
		||||
type="$(cat "$__object/explorer/type")"
 | 
			
		||||
 | 
			
		||||
[ "$state_should" = "exists" -a "$exists" = "yes" ] && exit 0 # nothing to do
 | 
			
		||||
[ "$state_should" = "exists" -a "$type" = "file" ] && exit 0 # nothing to do
 | 
			
		||||
 | 
			
		||||
upload_file=
 | 
			
		||||
create_file=
 | 
			
		||||
if [ "$state_should" = "present" -o "$state_should" = "exists" ]; then
 | 
			
		||||
   if [ -f "$__object/parameter/source" ]; then
 | 
			
		||||
   if [ ! -f "$__object/parameter/source" ]; then
 | 
			
		||||
      create_file=1
 | 
			
		||||
   else
 | 
			
		||||
      source="$(cat "$__object/parameter/source")"
 | 
			
		||||
      if [ "$source" = "-" ]; then
 | 
			
		||||
         source="$__object/stdin"
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      if [ -f "$source" ]; then
 | 
			
		||||
         local_cksum="$(cksum < "$source")"
 | 
			
		||||
         remote_cksum="$(cat "$__object/explorer/cksum")"
 | 
			
		||||
 | 
			
		||||
         if [ "$local_cksum" != "$remote_cksum" ]; then
 | 
			
		||||
            echo "$__remote_copy" "$source" "${__target_host}:${destination}"
 | 
			
		||||
         fi
 | 
			
		||||
      else
 | 
			
		||||
      if [ ! -f "$source" ]; then
 | 
			
		||||
         echo "Source \"$source\" does not exist." >&2
 | 
			
		||||
         exit 1
 | 
			
		||||
      else
 | 
			
		||||
         if [ "$type" != "file" ]; then
 | 
			
		||||
            # destination is not a regular file, upload source to replace it
 | 
			
		||||
            upload_file=1
 | 
			
		||||
         else
 | 
			
		||||
            local_cksum="$(cksum < "$source")"
 | 
			
		||||
            remote_cksum="$(cat "$__object/explorer/cksum")"
 | 
			
		||||
            if [ "$local_cksum" != "$remote_cksum" ]; then
 | 
			
		||||
               # destination is a regular file, but not the right one
 | 
			
		||||
               upload_file=1
 | 
			
		||||
            fi
 | 
			
		||||
         fi
 | 
			
		||||
      fi
 | 
			
		||||
   fi
 | 
			
		||||
   if [ "$create_file" -o "$upload_file" ]; then
 | 
			
		||||
      mkdir "$__object/files"
 | 
			
		||||
      tempfile_template="${destination}.cdist.XXXXXXXXXX"
 | 
			
		||||
      echo "$__remote_exec ${__target_host} \"mktemp $tempfile_template\" > \"$__object/files/destination_upload\""
 | 
			
		||||
      if [ "$upload_file" ]; then
 | 
			
		||||
         echo "$__remote_copy $source ${__target_host}:\$(cat \"$__object/files/destination_upload\")"
 | 
			
		||||
      fi
 | 
			
		||||
   fi
 | 
			
		||||
fi
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
 | 
			
		||||
# 2013 Steven Armstrong (steven-cdist armstrong.cc)
 | 
			
		||||
#
 | 
			
		||||
# This file is part of cdist.
 | 
			
		||||
#
 | 
			
		||||
| 
						 | 
				
			
			@ -17,52 +18,86 @@
 | 
			
		|||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# __file is a very basic type, which will probably be reused quite often
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
destination="/$__object_id"
 | 
			
		||||
state_should=present
 | 
			
		||||
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
 | 
			
		||||
exists="$(cat "$__object/explorer/exists")"
 | 
			
		||||
state_should="$(cat "$__object/parameter/state")"
 | 
			
		||||
type="$(cat "$__object/explorer/type")"
 | 
			
		||||
stat_file="$__object/explorer/stat"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
get_current_value() {
 | 
			
		||||
   if [ -s "$stat_file" ]; then
 | 
			
		||||
      _name="$1"
 | 
			
		||||
      _value="$2"
 | 
			
		||||
      case "$_value" in
 | 
			
		||||
         [0-9]*)
 | 
			
		||||
            _index=2
 | 
			
		||||
         ;;
 | 
			
		||||
         *)
 | 
			
		||||
            _index=3
 | 
			
		||||
         ;;
 | 
			
		||||
      esac
 | 
			
		||||
      awk '/'"$_name"':/ { print $'$_index' }' "$stat_file"
 | 
			
		||||
      unset _name _value _index
 | 
			
		||||
   fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
set_group() {
 | 
			
		||||
   echo chgrp \"$1\" \"$destination\"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
set_owner() {
 | 
			
		||||
   echo chown \"$1\" \"$destination\"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
set_mode() {
 | 
			
		||||
   echo chmod \"$1\" \"$destination\"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
set_attributes=
 | 
			
		||||
case "$state_should" in
 | 
			
		||||
   present|exists)
 | 
			
		||||
      # No source? Create empty file
 | 
			
		||||
      if [ ! -f "$__object/parameter/source" ]; then
 | 
			
		||||
         if [ "$exists" = "no" ]; then
 | 
			
		||||
            echo touch \"$destination\"
 | 
			
		||||
      if [ -f "$__object/files/destination_upload" ]; then
 | 
			
		||||
         # we uploaded a file, move it into place and set all attributes
 | 
			
		||||
         destination_upload="$(cat "$__object/files/destination_upload")"
 | 
			
		||||
         set_attributes=1
 | 
			
		||||
         if [ "$type" = "directory" ]; then
 | 
			
		||||
            # our destination is currently a directory, move it out of the way,
 | 
			
		||||
            # then delete it after moving our upload into place
 | 
			
		||||
            cat << DONE
 | 
			
		||||
destination_old="\$(mktemp "${destination}.cdist.XXXXXXXXXX")"
 | 
			
		||||
mv "$destination" "$destination_old"
 | 
			
		||||
mv "$destination_upload" "$destination"
 | 
			
		||||
rm -rf "$destination_old"
 | 
			
		||||
DONE
 | 
			
		||||
         else
 | 
			
		||||
            # move our upload into place
 | 
			
		||||
            echo "mv \"$destination_upload\" \"$destination\""
 | 
			
		||||
         fi
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      # Group
 | 
			
		||||
      if [ -f "$__object/parameter/group" ]; then
 | 
			
		||||
         echo chgrp \"$(cat "$__object/parameter/group")\" \"$destination\"
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      # Owner
 | 
			
		||||
      if [ -f "$__object/parameter/owner" ]; then
 | 
			
		||||
         echo chown \"$(cat "$__object/parameter/owner")\" \"$destination\"
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      # Mode - needs to happen last as a chown/chgrp can alter mode by
 | 
			
		||||
      # Note: Mode - needs to happen last as a chown/chgrp can alter mode by
 | 
			
		||||
      #  clearing S_ISUID and S_ISGID bits (see chown(2))
 | 
			
		||||
      if [ -f "$__object/parameter/mode" ]; then
 | 
			
		||||
         echo chmod \"$(cat "$__object/parameter/mode")\" \"$destination\"
 | 
			
		||||
      for attribute in group owner mode; do
 | 
			
		||||
         if [ -f "$__object/parameter/$attribute" ]; then
 | 
			
		||||
            value_should="$(cat "$__object/parameter/$attribute")"
 | 
			
		||||
            value_is="$(get_current_value "$attribute" "$value_should")"
 | 
			
		||||
            if [ "$set_attributes" -o "$value_should" != "$value_is" ]; then
 | 
			
		||||
               "set_$attribute" "$value_should"
 | 
			
		||||
            fi
 | 
			
		||||
         fi
 | 
			
		||||
      done
 | 
			
		||||
   ;;
 | 
			
		||||
 | 
			
		||||
   absent)
 | 
			
		||||
 | 
			
		||||
      if [ "$exists" = "yes" ]; then
 | 
			
		||||
      # FIXME: only delete if it's a file? or no matter what?
 | 
			
		||||
      if [ "$type" = "file" ]; then
 | 
			
		||||
         echo rm -f \"$destination\"
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
   ;;
 | 
			
		||||
 | 
			
		||||
   *)
 | 
			
		||||
      echo "Unknown state: $state_should" >&2
 | 
			
		||||
      exit 1
 | 
			
		||||
   ;;
 | 
			
		||||
 | 
			
		||||
esac
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,15 @@ DESCRIPTION
 | 
			
		|||
This cdist type allows you to create files, remove files and set file
 | 
			
		||||
attributes on the target.
 | 
			
		||||
 | 
			
		||||
If the file already exists on the target, then if it is a:
 | 
			
		||||
- regular file, and state is:
 | 
			
		||||
   present: replace it with the source file if they are not equal
 | 
			
		||||
   exists: do nothing
 | 
			
		||||
- symlink: replace it with the source file
 | 
			
		||||
- directory: replace it with the source file
 | 
			
		||||
 | 
			
		||||
In any case, make sure that the file attributes are as specified.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
REQUIRED PARAMETERS
 | 
			
		||||
-------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								cdist/conf/type/__file/parameter/default/state
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								cdist/conf/type/__file/parameter/default/state
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
present
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue