summaryrefslogtreecommitdiffstats
path: root/helper/fileutil.inc
blob: aae654bc8fcea04599a60d58a9ea68cb5f9cc410 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#
# copy list of files using tar
tarcopy () {
	if [ $# -gt 0 -a "x$1" == "x-i" ]; then
		shift
		local IGNORE_ERROR="--ignore-failed-read"
	else
		local IGNORE_ERROR=
	fi
	if [ "x$IGNORE_TAR_ERROR" != "x" ]; then
		unset IGNORE_TAR_ERROR
		IGNORE_ERROR="--ignore-failed-read"
	fi
	[ $# -ne 2 ] && perror "Sanity check failed: tarcopy needs exactly two params, but $# were given."
	local FROM=$(trim "$1")
	local TO=$(trim "$2")
	if [ -z "$FROM" ]; then
		pwarning "tarcopy called with empty input list (dest was '$TO')"
		return
	fi
	local SHORT=$FROM
	[ ${#SHORT} -gt 30 ] && SHORT=$(echo "$SHORT" | sed ':a;N;$!ba;s/\n/ /g' | cut -c-25)...$(echo "$SHORT" | cut -c$[${#SHORT} - 4]-)
	[ -z "$TO" ] && perror "tarcopy called with empty destination."
	[ ! -d "$TO" ] && { mkdir -p "$TO" || perror "could not create destination "$TO" for tar-copy."; } 
	# TODO count files copied? would remove the need to do it everywhere :)
	tar $IGNORE_ERROR -cpP $FROM | tar -xp -C "$TO" 2> /dev/null
	local PS=(${PIPESTATUS[*]})
	[ "x$IGNORE_ERROR" == "x" -a "x${PS[0]}" != "x0" ] && perror "packing-part of tar-copy from '$SHORT' to '$TO' failed. (${PS[0]})"
	[ "x${PS[1]}" != "x0" ] && perror "unpacking-part of tar-copy from '$SHORT' to '$TO' failed. (${PS[1]})"
}

# get all files of required packages by a module
list_packet_files() {
	[ -z "$REQUIRED_CONTENT_PACKAGES" ] && pinfo "No required packages for $TOOL"  && return 1
	local PACKAGE=""
	for PACKAGE in $REQUIRED_CONTENT_PACKAGES; do
		local OPTIONAL="$(echo "$PACKAGE" | cut -c 1)"
		[ "x$OPTIONAL" = "x@" ] && PACKAGE="$(echo "$PACKAGE" | cut -c 2-)"
		local FILES=""
		if [ "$PACKET_HANDLER" = "dpkg" ]; then
			PACKAGECOMMAND="dpkg -L"
		elif [ "$PACKET_HANDLER" = "rpm" ]; then
			PACKAGECOMMAND="rpm -ql"
		fi

		if [ -n "$REQUIRED_PACKET_FILES_BLACKLIST" ]; then
			FILES="$($PACKAGECOMMAND "$PACKAGE" | grep "^/" | \
				grep -v "$REQUIRED_PACKET_FILES_BLACKLIST" | \
				grep -v -E 'share/(man|doc)|/var/run|/var/log'; \
				echo ":###:${PIPESTATUS[0]}")"
		else 
			FILES="$($PACKAGECOMMAND "$PACKAGE" | grep "^/" | grep -v -E 'share/(man|doc)|/var/run|/var/log'; echo ":###:${PIPESTATUS[0]}")"
		fi
# FILES="$(rpm -ql "$PACKAGE" | grep "^/" | grep -v -E 'share/(man|doc)|/var/run|/var/log'; echo ":###:${PIPESTATUS[0]}")"

		# ugly hack to get our return value
		#local LPRET=$(echo "$FILES" | tail -1 | sed 's/^.*:###:\([0-9]*\)$/\1/g')
		#FILES=$(echo "$FILES" | sed 's/^\(.*\):###:[0-9]*$/\1/g')
		local LPRET=$(echo "$FILES" | awk -F ':###:' '{printf $2}')
		FILES=$(echo "$FILES" | awk -F ':###:' '{print $1}')
		if [ "x$LPRET" != "x0" -a "x$OPTIONAL" != "x@" ]; then
			pdebug "FILES: '$FILES'"
			perror "dpkg/rpm exited with code '$LPRET' for required package ${PACKAGE}."
		fi
		[ "x$LPRET" != "x0" ] && pwarning "dpkg/rpm exited with code '$LPRET' for optional package ${PACKAGE}." && continue
		[ -z "$FILES" ] && pwarning "list_packet_files empty for packet ${PACKAGE}." && continue
		pdebug "Packet $PACKAGE has $(echo $FILES | wc -w) files..."
		for FILE in $FILES; do
			[ ! -d "$FILE" ] && echo "$FILE"
		done
	done
}
#
# Conveniance function
#
# install all dependencies of a module
# goes through all package as given in the variable REQUIRED_INSTALLED_PACKAGES
install_dependencies() {
	[ -z "$REQUIRED_INSTALLED_PACKAGES" ] && return 
	install_packages "$REQUIRED_INSTALLED_PACKAGES"
}
# 
# install given packet through system's packet manager
# uses PACKET_HANDLER as determined in helper/system.inc
#
install_packages() {
	[ $# -eq 0 ] && perror "Sanity check failed: no argument given to install_package"
	local PACKAGE_LIST="$@"
	local INSTALLED_PACKAGES=""

	for PKG in ${PACKAGE_LIST}; do
		# check if installed
		if [ "x$PACKET_HANDLER" == "xdpkg" ]; then
			dpkg -l ${PKG} > /dev/null 2>&1
		elif [ "x$PACKET_HANDLER" == "xrpm" ]; then
			rpm -ql ${PKG} > /dev/null 2>&1
		else
			perror "No packet manager / handler determined, this should not happen!"
		fi

		local LRET=$?
		if [ "x$LRET" == "x0" ]; then
			# check if it is completly installed,
			# not just leftover configuration files
			local INSTALL_STATUS=$(dpkg -l $PKG | grep $PKG | cut -c1-2)
			if [[ $INSTALL_STATUS != "ii" ]]; then
				pinfo "$PKG not installed!"
				install_package $PKG
			else
				# package installed
				pdebug "$PKG installed!"
			fi
		else
			# package not installed
			pdebug "$PKG not installed!"
			install_package $PKG
		fi
	done
	[ ! -z "$INSTALLED_PACKAGES" ] && pinfo "Packages installed: ${INSTALLED_PACKAGES}"
}

#
# install individual package depending on package manager
#
install_package() {
	if [ "$#" -ne 1 ]; then
		perror "Only call install_package with one argument!"
	fi

	if [ "x$PACKET_MANAGER" == "xapt" ]; then
		apt-get install -y ${PKG}
		local IRET=$?
		if [ "x$IRET" == "x0" ]; then
			# $PGK was installed successfully
			INSTALLED_PACKAGES+="$PKG "
		else
			# PKG was not installed
			# TODO error handling
			perror "install_packages: apt-get failed with '$IRET' for package '$PKG'"
		fi
	elif [ "x$PACKET_MANAGER" == "xzypper" ]; then
		zypper --no-refresh --non-interactive install ${PKG}
		local IRET=$?
		if [ "x$IRET" == "x0" ]; then
		# $PGK was installed successfully
			INSTALLED_PACKAGES+="$PKG "
		else
			# PKG was not installed
			# TODO error handling
			perror "install_packages: zypper failed with '$IRET' for package '$PKG'"
		fi
	elif [ "x$PACKET_MANAGER" == "xyum" ]; then
		yum --assumeyes install ${PKG}
		local IRET=$?	
		if [ "x$IRET" == "x0" ]; then
			# $PGK was installed successfully
			INSTALLED_PACKAGES+="$PKG "
		else
			# PKG was not installed
			# TODO error handling
			perror "install_packages: yum failed with '$IRET' for package '$PKG'"
		fi
	else
		perror "No packet manager determined, this should not happen!"
	fi
}

#
# copies static data files from <MODULE>/data/ to <TARGET_BUILD_DIR>
#
copy_static_data() {
	[ ! -d "${MODULE_DIR}/data" ] && pinfo "${MODULE} has no static 'data' directory." && return
	cp -r "${MODULE_DIR}/data/"* ${TARGET_BUILD_DIR} || perror "Could not copy static data of ${MODULE}"
}

copy_system_files() {
	[ ! -z "$REQUIRED_SYSTEM_FILES" ] && tarcopy "$REQUIRED_SYSTEM_FILES" "$TARGET_BUILD_DIR"
}

calc_size() {

	local CURRENT_BUILD_SIZE=$(du -bc "${TARGET_BUILD_DIR}" | awk 'END {print $1}')

	[ ! -z "${BUILD_SIZE[$MODULE]}" ] && local OLD_MODULE_SIZE=${BUILD_SIZE[$MODULE]} || local OLD_MODULE_SIZE=0
	local diff=$((CURRENT_BUILD_SIZE-TARGET_BUILD_SIZE+OLD_MODULE_SIZE))

	if [ -z "${BUILD_SIZE[$MODULE]}" ]; then 
		echo "BUILD_SIZE[$MODULE]=${diff}" >> "${ROOT_DIR}/logs/${TARGET}.size"
	else
		sed -i "s/^BUILD_SIZE\[${MODULE}\]=.*$/BUILD_SIZE\[${MODULE}\]=${diff}/g" "${ROOT_DIR}/logs/${TARGET}.size"
	fi
	
	MODULE_BUILD_SIZE=$(echo $diff | awk '{ sum=$1; hum[1024^3]="GB"; hum[1024^2]="MB"; hum[1024]="KB"; 
					for (x=1024^3; x>=1024; x/=1024){ 
        					if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x]; break }
					}
				}')
}

#
# generate initramfs of directory
# usage:
#	generate_initramfs <source_dir> <files> <destination_dir/filename>
# example:
#	generate_initramfs "./server/boot/stage32_sqfs" "./mnt/openslx.sqfs" "./server/boot/initramfs2"
#	generate_initramfs "./server/build/stage31" "." "./server/boot/initramfs"
generate_initramfs() {
	[ $# -ne 3 ] && perror "Sanity check failed: generate_initramfs needs exactly two params, but $# were given."
        cd "$1" || perror "Cannot cd to '$1'"
	
        find $2 | cpio --format="newc" --create | gzip -9 > "$3"
        local PS=(${PIPESTATUS[*]})
        [ "x${PS[0]}" != "x0" ] && perror "'find $2' in '$(pwd)' failed."
        [ "x${PS[1]}" != "x0" ] && perror "cpio create failed."
        [ "x${PS[2]}" != "x0" ] && perror "gzip to '$3' failed."
        cd - &> /dev/null
        pinfo "Created initramfs of $1 at $3"
	pinfo "Size: $(du -bsh "$3" | awk 'END {print $1}')"
}

# generates squashfs of directory
# usage:
#	generate_squashfs <source_dir> <destination_dir/filename>
generate_squashfs() {
	[ $# -ne 2 ] && perror "Sanity check failed: generate_squashfs needs exactly two params, but $# were given."
	[ -d "$1" ] || perror "$1 is not a directory."
	mksquashfs "$1" "$2" -comp xz -b 1M -no-recovery >&6 \
	        || perror "mksquashfs failed ($?)."
	pinfo "Created squashfs of $1 at $2"
	pinfo "Size: $(du -bsh "$2" | awk 'END {print $1}')"
}