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