]> git.ipfire.org Git - people/jschlag/ipfire-3.x-image.git/blob - functions.sh
095e3dda12f8b88df08d3666a8891892e181f17e
[people/jschlag/ipfire-3.x-image.git] / functions.sh
1 #!/bin/bash
2
3 # Constants
4
5 # Proper error codes
6 EXIT_OK=0
7 EXIT_ERROR=1
8 EXIT_CONF_ERROR=2
9 EXIT_NOT_SUPPORTED=3
10 EXIT_NOT_HANDLED=4
11 EXIT_COMMAND_NOT_FOUND=127
12 EXIT_ERROR_ASSERT=128
13
14 EXIT_TRUE=0
15 EXIT_FALSE=1
16 EXIT_UNKNOWN=2
17
18 TRUE=0
19 FALSE=1
20
21 IMAGE_RELEASE=${FALSE}
22
23 # maybe mounted dirs
24 MOUNTED_DIRS="/proc" "/sys" "dev/pts" "dev/shm" "dev" "run" "tmp" ""
25
26
27 # Functions
28
29 log() {
30 local level=${1}
31 local message=${2}
32 echo "[${level}] ${message}"
33 }
34
35 cmd() {
36 local cmd="$@"
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
56 cleanup_stage_1() {
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
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
85 is_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
96 cleanup_stage_2() {
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
111 # Drop working dir
112 if [ -d "${WORKING_DIR}" ]; then
113 rm -dfR "${WORKING_DIR}"
114 fi
115 }
116
117 cleanup() {
118 cleanup_stage_1
119 cleanup_stage_2
120 }
121
122 generate_image_filename() {
123 local distro=${1}
124 local version=${2}
125 local arch=${3}
126
127 echo "${distro}-${version}-${arch}"
128 }
129
130 check_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
148 compress_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
179 reset_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
191 clone_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
212 publish() {
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
252 convert_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
272 get_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
288 check_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
305 parse_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
321 chroot_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 }