2 ###############################################################################
3 # IPFire.org - An Open Source Firewall Solution #
4 # Copyright (C) - IPFire Development Team <info@ipfire.org> #
5 ###############################################################################
9 SCRIPT_PATH
="$(dirname "$
(readlink
-f "$0")")"
19 EXIT_COMMAND_NOT_FOUND
=127
36 echo "[${level}] ${message}"
43 log DEBUG
"Running command: ${cmd}"
53 log DEBUG
"Returned with code '${ret}'"
61 umount
${IMAGE_MOUNT_DIR}
63 # Remove partition from the kernel table.
66 # Remove loopback device
70 if [ -d "${WORKING_DIR}" ]; then
71 rm -dfR "${WORKING_DIR}"
75 generate_image_filename
() {
80 echo "${distro}-${version}-${arch}"
87 # Check that pakfire-server binary is available
88 # Check that pakfire binary is available
90 # Check that repo files are installed. (pakfire need to know which repos exist)
91 local repo_dir
="/etc/pakfire/repos"
93 if [ ! -d "${repo_dir}" ]; then
94 log ERROR
"Could not find respository directory ${repo_dir}"
98 return ${return_value}
102 local compression
=${1}
103 local image_file
=${2}
106 log debug
"Compressing ${image_file} with ${compression}"
108 case "${compression}" in
110 # Check that the file does not exist yet
111 if [ -f "${image_file}.xz" ]; then
112 log ERROR
"Failed to compress the image. The file already exists"
115 cmd xz
"-${level}" "${image_file}"
118 # Check that the file does not exist yet
119 if [ -f "${image_file}.zip" ]; then
120 log ERROR
"Failed to compress the image. The file already exists"
124 cmd
zip "-${level}" "${image_file}.zip" "${image_file}"
125 # Remove the file which we compressed+
126 rm -f "${image_file}"
132 reset_root_password
() {
135 cp -avf ${root_dir}/etc
/passwd
${root_dir}/etc
/passwd.orig
137 # Drop root password.
138 sed -e "s/^\(root:\)[^:]*:/\1:/" ${root_dir}/etc
/passwd.orig
> ${root_dir}/etc
/passwd
140 # Remove passwd backup file.
141 rm -rvf ${root_dir}/etc
/passwd.orig
145 # Dir where the repos should be located
156 # Clone git repositories.
157 for repo
in ${repos}; do
163 # This function is used to publish the produced images
167 # The image we created usually a img. file
168 local image_base_file
=${2}
170 local image_name_final
="$(generate_image_filename "${DISTRO}" "${VERSION}" "${ARCH}")"
173 local compression_type
174 local compression_level
=1
176 if [[ ${IMAGE_RELEASE} -eq ${TRUE} ]]; then
180 # Do these steps for every image format we like to publish
181 for image_type
in ${IMAGE_TYPES_PUBLISH}; do
182 # Get compressioon type
183 compression_type
="$(get_compression_type ${image_type})"
184 # Convert images to the type specified in IMAGE_TYPES_PUBLISH
185 convert_image
"${image_type}" "${image_base_file}" "${image_name_final}"
188 compress_image
"${compression_type}" "${image_name_final}.${image_type}" ${compression_level}
190 # Move images to this path
191 mv -f "${image_name_final}.${image_type}.${compression_type}" ${path}
193 # point the latest links to these images
194 ln -s -f "${path}/${image_name_final}.${image_type}.${compression_type}" \
195 "${path}/$(generate_image_filename "${DISTRO}" "latest" "${ARCH}").${image_type}.${compression_type}"
206 if [[ ${type} = "img" ]]; then
207 # We do not need to convert the image here but we need to rename
208 mv -f ${from} ${to}.${type}
212 if [[ ${type} = "qcow2" ]]; then
213 local command="qemu-img convert -c -O ${type} ${from} ${to}.${type}"
215 local command="qemu-img convert -O ${type} ${from} ${to}.${type}"
221 get_compression_type
() {
222 local image_type
=${1}
224 case "${image_type}" in
226 # These types can be used only under Unix so we use xz as compression
230 # These types can be also under Windows so we use zip as compression
237 check_for_free_space
() {
241 # Space needs to passed in MB
242 # df returns bytes so we multiple by 1024
243 space
=$
(( ${space} * 1024 ))
245 log debug $
(df
--output=avail
${path} |
tail -n 1)
248 if [ $
(df
--output=avail
${path} |
tail -n 1) -lt ${space} ]; then
249 log error
"Not enough free space available under ${path}"
250 log error
"Free space is $(df -h -B MB --output=avail ${path} | tail -n 1) but we need at least $(( ${space} / 1024 / 1024 ))MB"
256 while [ $# -gt 0 ]; do
259 IMAGE_RELEASE
=${TRUE}
263 error
"Invalid argument: ${1}"
264 return ${EXIT_CONF_ERROR}
277 VERSION
="$(date +"%Y
%m
%d
")"
278 WORKING_DIR
=$
(mktemp
-d /tmp
/ipfire3_image.XXXXXXXX
)
280 log DEBUG
"Working dir is ${WORKING_DIR}"
286 IMAGE_BASE_FILE
="$(mktemp -u ${WORKING_DIR}/image_base_file.XXXXXXX.img)"
288 IMAGE_MOUNT_DIR
="$(mktemp -d ${WORKING_DIR}/image.XXXXXXX)"
290 IMAGE_TYPES_PUBLISH
="qcow2 vmdk vdi img"
292 # The used filesystem.
295 # Additional packages which should be installed.
296 PACKAGES
="xfsprogs kernel openssh-server wget htop tmux"
298 # Use git network stack. ( When using the git network stack,
299 # development tools and git automatically will be installed.)
300 USE_GIT_NETWORK_STACK
="True"
302 # List of packages which are required to build the network stack.
303 NETWORK_BUILD_DEPS
="autoconf automake docbook-xsl libnl3-devel libxslt systemd-devel"
305 # Install development tools.
306 INSTALL_DEV_PACKAGES
="True"
308 # List of development tools which should be installed.
309 DEVELOPMENT_PACKAGES
="make gcc libtool git"
312 # Git repositories which also should be checked, out.
316 # Stuff for the local repo
319 # Use local repository.
320 USE_LOCAL_REPO
="True"
322 # Source path for the local repo packages.
323 LOCAL_REPO_SOURCE_PATH
="/var/lib/pakfire/local/"
325 # Path were the local repo is created
326 LOCAL_REPO_DIR
="$(mktemp -d ${WORKING_DIR}/ipfire-repo.XXXXXXX)"
328 # Config file for the local repo
329 LOCAL_REPO_FILE
="/etc/pakfire/repos/local.repo"
333 # Scripts starts here
339 # Check that pakfire is working
342 if ! check_for_free_space
10000 "${WORKING_DIR}"; then
346 # Check that the image does not exist yet
347 if [ -f ${IMAGE_BASE_FILE} ]; then
348 log ERROR
"Image file does already exists"
352 # Check that the local repo file does not exists yet.
353 # We do not want to override custom user configurations.
354 if [ -f "${LOCAL_REPO_FILE}" ]; then
355 log ERROR
"Config file ${LOCAL_REPO_FILE} for the local repo does already exists"
359 # cd into working directory
360 cd ${WORKING_DIR} ||
exit ${EXIT_ERROR}
363 ## Create the disk image.
365 dd if=/dev
/zero of
=${IMAGE_BASE_FILE} seek
=${IMAGE_SIZE}M count
=1k bs
=1
367 # Setup the loopback device.
368 outlo
=`losetup -f --show ${IMAGE_BASE_FILE}`
370 log INFO
"Create partions and filesystem"
372 # Create and msdos compatible table on the image.
373 parted
${outlo} mklabel msdos
375 # Add a new partition to the image.
376 parted
${outlo} mkpart primary
${FILESYSTEM} 2048k
100% -a minimal
378 # Make the primary partition bootable.
379 parted
${outlo} set 1 boot on
381 # Notify the kernel about the new partition.
385 ## Create the filesystem.
387 mkfs.
${FILESYSTEM} ${outlo}p1
390 ## Mount the filesystem.
393 log INFO
"Mount partion in ${IMAGE_MOUNT_DIR}"
395 # Afterwards mount the image.
396 mount
-t ${FILESYSTEM} ${outlo}p1 ${IMAGE_MOUNT_DIR}
399 ## Install IPFire 3.x.
402 # Add grub on x86_64 to the package list.
403 if [ "${ARCH}" == "x86_64" ] ||
[ "${ARCH}" == "i686" ]; then
404 PACKAGES
="${PACKAGES} grub"
406 # Store, that grub is present.
410 # Check if the git network stack should be installed.
411 if [ "${USE_GIT_NETWORK_STACK}" == "True" ]; then
412 GIT_REPOS
="${GIT_REPOS} git://git.ipfire.org/network.git"
414 # Add build dependencies of network package.
415 PACKAGES
="${PACKAGES} ${NETWORK_BUILD_DEPS}"
418 # Add develoment packes to the package list, if required.
419 if [ "${INSTALL_DEV_PACKAGES}" == "True" ] ||
[ ! -z "${GIT_REPOS}" ]; then
420 PACKAGES
="${PACKAGES} ${DEVELOPMENT_PACKAGES}"
423 log INFO
"Create local respository"
426 # Check if the local repo should be used.
427 if [ "${USE_LOCAL_REPO}" == "True" ]; then
428 # Create local repository.
429 mkdir
-pv "${LOCAL_REPO_DIR}"
432 if ! pakfire-server repo create
${LOCAL_REPO_DIR} ${LOCAL_REPO_SOURCE_PATH}; then
433 log ERROR
"Failed to create a local respository"
438 # Create temporary pakfire repo file.
439 echo "[repo:local]" >> "${LOCAL_REPO_FILE}"
440 echo "description = Local repository." >> "${LOCAL_REPO_FILE}"
441 echo "enabled = 0" >> "${LOCAL_REPO_FILE}"
442 echo "baseurl = ${LOCAL_REPO_DIR}" >> "${LOCAL_REPO_FILE}"
444 ENABLE_LOCAL
="--enable-repo=local"
447 # Install IPFire 3.x in the created image.
448 yes | pakfire
--root=${IMAGE_MOUNT_DIR} ${ENABLE_LOCAL} install @Base ${PACKAGES}
451 # Enable serial console
455 #echo "GRUB_TERMINAL=\"serial console\"" >> "${IMAGE_MOUNT_DIR}/etc/default/grub"
456 #echo "GRUB_SERIAL_COMMAND=\"serial --unit=0 --speed=115200\"" >> "${IMAGE_MOUNT_DIR}/etc/default/grub"
458 #Hack to install a /etc/default/grub file
460 cmd
cp -f "${SCRIPT_PATH}/grub" "${IMAGE_MOUNT_DIR}/etc/default"
463 ## Install grub2 if neccessary
465 if [ "${HAVE_GRUB}" == "True" ]; then
466 grub2-install
--boot-directory=${IMAGE_MOUNT_DIR}/boot/ --modules="${FILESYSTEM} part_msdos" ${outlo}
473 # Gather the uuid of the partition.
474 FS_UUID
=$
(blkid
-o value
-s UUID
${outlo}p1
)
477 echo "UUID=${FS_UUID} / ${FILESYSTEM} defaults 0 0" > ${IMAGE_MOUNT_DIR}/etc/fstab
480 ## Remove the password for user root.
483 reset_root_password "${IMAGE_MOUNT_DIR}"
486 ## Setup git repositories.
489 clone_git_repos "${IMAGE_MOUNT_DIR}/build
" ${GIT_REPOS}
492 ## Prepare chrooting into the image.
495 # Check if the network stack should be build.
496 if [ "${USE_GIT_NETWORK_STACK}" == "True
" ]; then
497 BUILD_NETWORK_CMDS="cd network
/ && .
/autogen.sh
&& .
/configure
&& make && make install"
500 ENABLE_GETTY="/bin
/systemctl
enable getty@.service
"
502 # Check if the arch uses grub
503 if [ "${HAVE_GRUB}" == "True
" ]; then
504 GENERATE_GRUB_CONF="grub-mkconfig
-o /boot
/grub
2/grub.cfg
"
507 # Use systemd-nspawn to spawn a chroot environment and execute
508 # commands inside it.
510 # The first command enables the terminal on TTY1.
511 # The second command generates the configuration file for grub2.
514 systemd-nspawn -D ${IMAGE_MOUNT_DIR} --bind /dev --capability=CAP_SYS_ADMIN,CAP_SYS_RAWIO --bind /proc --bind /sys << END
515 echo "Execute commands inside chroot
"
517 ${GENERATE_GRUB_CONF}
519 ${BUILD_NETWORK_CMDS}
520 echo "All commands executed
"
525 # Insert the UUID because grub-mkconfig often fails to
526 # detect that correctly
528 sed -i "${IMAGE_MOUNT_DIR}/boot
/grub
2/grub.cfg
" \
529 -e "s
/root
=[A-Za-z0-9\
/=-]*/root
=UUID
=${FS_UUID}/g
"
531 cat "${IMAGE_MOUNT_DIR}/boot
/grub
2/grub.cfg
"
539 # Check filesystem for damage.
540 fsck.${FILESYSTEM} ${outlo}p1
542 publish "/home
/jschlag
/public
/ipfire3-images
" "${IMAGE_BASE_FILE}"