]> git.ipfire.org Git - people/jschlag/ipfire-3.x-image.git/blame - functions.sh
Improve how we unmount dirs
[people/jschlag/ipfire-3.x-image.git] / functions.sh
CommitLineData
358ea1df
JS
1#!/bin/bash
2
3# Constants
4
5# Proper error codes
6EXIT_OK=0
7EXIT_ERROR=1
8EXIT_CONF_ERROR=2
9EXIT_NOT_SUPPORTED=3
10EXIT_NOT_HANDLED=4
11EXIT_COMMAND_NOT_FOUND=127
12EXIT_ERROR_ASSERT=128
13
14EXIT_TRUE=0
15EXIT_FALSE=1
16EXIT_UNKNOWN=2
17
18TRUE=0
19FALSE=1
20
b7ec229b
JS
21IMAGE_RELEASE=${FALSE}
22
7dc7fa1d
JS
23
24
358ea1df
JS
25# Functions
26
27log() {
28 local level=${1}
29 local message=${2}
30 echo "[${level}] ${message}"
31}
32
33cmd() {
8b38bb23 34 local cmd="$@"
358ea1df
JS
35 local ret
36
37 log DEBUG "Running command: ${cmd}"
38
39 ${cmd}
40 ret=$?
41
42 case "${ret}" in
43 ${EXIT_OK})
44 return ${EXIT_OK}
45 ;;
46 *)
47 log DEBUG "Returned with code '${ret}'"
48 return ${ret}
49 ;;
50 esac
51}
52
53
d26067f0
JS
54is_mounted() {
55 local mounted_dir=${1}
7dc7fa1d 56
d26067f0
JS
57 if [ ! -d ${mounted_dir} ]; then
58 log ERROR "Is not a directory ${mounted_dir}"
59 return ${FALSE}
60 else
61 mountpoint ${mounted_dir}
62 fi
63}
64
65unmount_dirs() {
7dc7fa1d 66 local mounted_dir
d26067f0
JS
67 local path
68
69 local return_value=${EXIT_OK}
7dc7fa1d 70
d26067f0
JS
71 for mounted_dir in "/proc" "/sys" "/dev/pts" "/dev/shm" "/dev" "/run" "/tmp" ""
72 do
73 path="${IMAGE_MOUNT_DIR}${mounted_dir}"
74
75 if is_mounted "${path}"; then
76 log DEBUG "Unmounting ${path}"
77 umount "${path}"
78 # Check once again
79 if is_mounted "${path}"; then
80 return_value=${EXIT_ERROR}
81 fi
7dc7fa1d 82 else
d26067f0 83 log DEBUG "${path} is not mounted"
7dc7fa1d
JS
84 fi
85 done
86
d26067f0
JS
87}
88
89
90
91
92cleanup_stage_1() {
358ea1df 93
d26067f0 94 if unmount_dirs; then
358ea1df 95
d26067f0
JS
96 # Remove partition from the kernel table.
97 partx -d ${outlo}p1
358ea1df 98
d26067f0
JS
99 # Remove loopback device
100 log DEBUG " Remove loopback device"
101 losetup -d ${outlo}
102 fi
358ea1df
JS
103
104
105 # Cleanup Config file for the local repo
106 if [ -f "${LOCAL_REPO_FILE}" ]; then
107 rm -f "${LOCAL_REPO_FILE}"
108 fi
109
110}
111
7dc7fa1d 112
358ea1df 113cleanup_stage_2() {
d26067f0
JS
114 if unmount_dirs; then
115 # Drop working dir
116 if [ -d "${WORKING_DIR}" ]; then
117 #rm -dfR "${WORKING_DIR}"
118 echo ""
7dc7fa1d 119 fi
358ea1df
JS
120 fi
121}
122
123cleanup() {
124 cleanup_stage_1
125 cleanup_stage_2
126}
127
128generate_image_filename() {
129 local distro=${1}
130 local version=${2}
131 local arch=${3}
132
133 echo "${distro}-${version}-${arch}"
134}
135
136check_for_pakfire() {
137 local return_value=0
138
139 # TODO
140 # Check that pakfire-server binary is available
141 # Check that pakfire binary is available
142
143 # Check that repo files are installed. (pakfire need to know which repos exist)
144 local repo_dir="/etc/pakfire/repos"
145
146 if [ ! -d "${repo_dir}" ]; then
147 log ERROR "Could not find respository directory ${repo_dir}"
148 return_value=1
149 fi
150
151 return ${return_value}
152}
153
154compress_image() {
155 local compression=${1}
156 local image_file=${2}
157 local level=${3}
158
159 log debug "Compressing ${image_file} with ${compression}"
160
161 case "${compression}" in
162 "xz")
163 # Check that the file does not exist yet
164 if [ -f "${image_file}.xz" ]; then
165 log ERROR "Failed to compress the image. The file already exists"
166 return ${EXIT_ERROR}
167 fi
168 cmd xz "-${level}" "${image_file}"
169 ;;
170 "zip")
171 # Check that the file does not exist yet
172 if [ -f "${image_file}.zip" ]; then
173 log ERROR "Failed to compress the image. The file already exists"
174 return ${EXIT_ERROR}
175
176 fi
177 cmd zip "-${level}" "${image_file}.zip" "${image_file}"
178 # Remove the file which we compressed+
179 rm -f "${image_file}"
180 ;;
181
182 esac
183}
184
185reset_root_password() {
186 local root_dir=${1}
187 # Backup passwd file
188 cp -avf ${root_dir}/etc/passwd ${root_dir}/etc/passwd.orig
189
190 # Drop root password.
191 sed -e "s/^\(root:\)[^:]*:/\1:/" ${root_dir}/etc/passwd.orig > ${root_dir}/etc/passwd
192
193 # Remove passwd backup file.
194 rm -rvf ${root_dir}/etc/passwd.orig
195}
196
197clone_git_repos() {
198 # Dir where the repos should be located
199 local dir=${1}
200 shift
201 local repos="$@"
202
203 local repo
204
205 mkdir -pv ${dir}
206
207 (
208 cd ${dir}
209 # Clone git repositories.
210 for repo in ${repos}; do
211 git clone ${repo}
212 done
213 )
214}
215
216# This function is used to publish the produced images
217
218publish() {
219 local path=${1}
220 # The image we created usually a img. file
221 local image_base_file=${2}
222
223 local image_name_final="$(generate_image_filename "${DISTRO}" "${VERSION}" "${ARCH}")"
224 local image_type
225
226 # Do these steps for every image format we like to publish
227 for image_type in ${IMAGE_TYPES_PUBLISH}; do
228 # Convert images to the type specified in IMAGE_TYPES_PUBLISH
229 convert_image "${image_type}" "${image_base_file}" "${image_name_final}"
230
231 # compress image.
232 if [[ ${IMAGE_RELEASE} -eq ${TRUE} ]]; then
233 local compression_type
234 local compression_level
235
236
237 # Get compressioon type
238 compression_type="$(get_compression_type ${image_type})"
239
240 compression_level=1
241 compress_image "${compression_type}" "${image_name_final}.${image_type}" ${compression_level}
242
243 # Move images to this path
244 mv -f "${image_name_final}.${image_type}.${compression_type}" ${path}
245
246 # point the latest links to these images
247 ln -s -f "${path}/${image_name_final}.${image_type}.${compression_type}" \
248 "${path}/$(generate_image_filename "${DISTRO}" "latest" "${ARCH}").${image_type}.${compression_type}"
249 else
250
251 # Move images to this path
252 mv -f "${image_name_final}.${image_type}" ${path}
253 fi
254 done
255
256}
257
258convert_image() {
259 local type=${1}
260 local from=${2}
261 local to=${3}
262
263 if [[ ${type} = "img" ]]; then
264 # We do not need to convert the image here but we need to rename
265 mv -f ${from} ${to}.${type}
266 return $?
267 fi
268
269 if [[ ${type} = "qcow2" ]]; then
270 local command="qemu-img convert -c -O ${type} ${from} ${to}.${type}"
271 else
272 local command="qemu-img convert -O ${type} ${from} ${to}.${type}"
273 fi
274
275 cmd ${command}
276}
277
278get_compression_type() {
279 local image_type=${1}
280
281 case "${image_type}" in
282 "qcow2" | "img")
283 # These types can be used only under Unix so we use xz as compression
284 echo "xz"
285 ;;
286 "vmdk" | "vdi")
287 # These types can be also under Windows so we use zip as compression
288 echo "zip"
289 ;;
290 esac
291
292}
293
294check_for_free_space() {
295 local space=${1}
296 local path=${2}
297 local space_in_path=0
298
299 space_in_path=$(df -h -B MB --output=avail ${path} | tail -n 1)
300 space_in_path=${space_in_path%MB}
301 log debug ${space_in_path}
302 log debug ${space}
303
304 if [ ${space_in_path} -lt ${space} ]; then
305 log error "Not enough free space available under ${path}"
306 log error "Free space is ${space_in_path}MB but we need at least ${space}MB"
307 return ${EXIT_ERROR}
308 fi
309}
310
311parse_cmdline() {
312 while [ $# -gt 0 ]; do
313 case "${1}" in
314 "--release")
315 IMAGE_RELEASE=${TRUE}
316 ;;
317
318 *)
319 error "Invalid argument: ${1}"
320 return ${EXIT_CONF_ERROR}
321 ;;
322 esac
323 shift
324 done
325}
326
7eb693d2
JS
327chroot_wrapper() {
328 local chroot_dir="${1}"
329
330 shift
331
332 local command
333
334 if [ ! -d ${chroot_dir} ]; then
335 log ERROR "Cannot chroot in a non directory ${chroot_dir}"
336 fi
337
338 mount proc "${chroot_dir}/proc" -t proc -o nosuid,noexec,nodev
339 mount sys "${chroot_dir}/sys" -t sysfs -o nosuid,noexec,nodev,ro
340 mount udev "${chroot_dir}/dev" -t devtmpfs -o mode=0755,nosuid
341 mount devpts "${chroot_dir}/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec
342 mount shm "${chroot_dir}/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev
343 mount /run "${chroot_dir}/run" --bind
344 mount tmp "${chroot_dir}/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid
345
346 for command in "$@"
347 do
348 cmd chroot "${chroot_dir}" "${command}"
349 done
350
351 umount "${chroot_dir}/proc"
352 umount "${chroot_dir}/sys"
353 umount "${chroot_dir}/dev/pts"
354 umount "${chroot_dir}/dev/shm"
355 umount "${chroot_dir}/dev"
356 umount "${chroot_dir}/run"
357 umount "${chroot_dir}/tmp"
358}