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}'"
62 umount
${IMAGE_MOUNT_DIR}
64 # Remove partition from the kernel table.
67 # Remove loopback device
72 # Cleanup Config file for the local repo
73 if [ -f "${LOCAL_REPO_FILE}" ]; then
74 rm -f "${LOCAL_REPO_FILE}"
81 if [ -d "${WORKING_DIR}" ]; then
82 rm -dfR "${WORKING_DIR}"
91 generate_image_filename
() {
96 echo "${distro}-${version}-${arch}"
103 # Check that pakfire-server binary is available
104 # Check that pakfire binary is available
106 # Check that repo files are installed. (pakfire need to know which repos exist)
107 local repo_dir
="/etc/pakfire/repos"
109 if [ ! -d "${repo_dir}" ]; then
110 log ERROR
"Could not find respository directory ${repo_dir}"
114 return ${return_value}
118 local compression
=${1}
119 local image_file
=${2}
122 log debug
"Compressing ${image_file} with ${compression}"
124 case "${compression}" in
126 # Check that the file does not exist yet
127 if [ -f "${image_file}.xz" ]; then
128 log ERROR
"Failed to compress the image. The file already exists"
131 cmd xz
"-${level}" "${image_file}"
134 # Check that the file does not exist yet
135 if [ -f "${image_file}.zip" ]; then
136 log ERROR
"Failed to compress the image. The file already exists"
140 cmd
zip "-${level}" "${image_file}.zip" "${image_file}"
141 # Remove the file which we compressed+
142 rm -f "${image_file}"
148 reset_root_password
() {
151 cp -avf ${root_dir}/etc
/passwd
${root_dir}/etc
/passwd.orig
153 # Drop root password.
154 sed -e "s/^\(root:\)[^:]*:/\1:/" ${root_dir}/etc
/passwd.orig
> ${root_dir}/etc
/passwd
156 # Remove passwd backup file.
157 rm -rvf ${root_dir}/etc
/passwd.orig
161 # Dir where the repos should be located
172 # Clone git repositories.
173 for repo
in ${repos}; do
179 # This function is used to publish the produced images
183 # The image we created usually a img. file
184 local image_base_file
=${2}
186 local image_name_final
="$(generate_image_filename "${DISTRO}" "${VERSION}" "${ARCH}")"
189 # Do these steps for every image format we like to publish
190 for image_type
in ${IMAGE_TYPES_PUBLISH}; do
191 # Convert images to the type specified in IMAGE_TYPES_PUBLISH
192 convert_image
"${image_type}" "${image_base_file}" "${image_name_final}"
195 if [[ ${IMAGE_RELEASE} -eq ${TRUE} ]]; then
196 local compression_type
197 local compression_level
200 # Get compressioon type
201 compression_type
="$(get_compression_type ${image_type})"
204 compress_image
"${compression_type}" "${image_name_final}.${image_type}" ${compression_level}
206 # Move images to this path
207 mv -f "${image_name_final}.${image_type}.${compression_type}" ${path}
209 # point the latest links to these images
210 ln -s -f "${path}/${image_name_final}.${image_type}.${compression_type}" \
211 "${path}/$(generate_image_filename "${DISTRO}" "latest" "${ARCH}").${image_type}.${compression_type}"
214 # Move images to this path
215 mv -f "${image_name_final}.${image_type}" ${path}
226 if [[ ${type} = "img
" ]]; then
227 # We do not need to convert the image here but we need to rename
228 mv -f ${from} ${to}.${type}
232 if [[ ${type} = "qcow2
" ]]; then
233 local command="qemu-img convert
-c -O ${type} ${from} ${to}.${type}"
235 local command="qemu-img convert
-O ${type} ${from} ${to}.${type}"
241 get_compression_type() {
242 local image_type=${1}
244 case "${image_type}" in
246 # These types can be used only under Unix so we use xz as compression
250 # These types can be also under Windows so we use zip as compression
257 check_for_free_space() {
260 local space_in_path=0
262 space_in_path=$(df -h -B MB --output=avail ${path} | tail -n 1)
263 space_in_path=${space_in_path%MB}
264 log debug ${space_in_path}
267 if [ ${space_in_path} -lt ${space} ]; then
268 log error "Not enough free space available under
${path}"
269 log error "Free space is
${space_in_path}MB but we need
at least
${space}MB
"
275 while [ $# -gt 0 ]; do
278 IMAGE_RELEASE=${TRUE}
282 error "Invalid argument
: ${1}"
283 return ${EXIT_CONF_ERROR}
296 VERSION="$
(date +"%Y%m%d")"
297 WORKING_DIR=$(mktemp -d /var/tmp/ipfire3_image.XXXXXXXX)
299 log DEBUG "Working dir is
${WORKING_DIR}"
305 IMAGE_BASE_FILE="$
(mktemp
-u ${WORKING_DIR}/image_base_file.XXXXXXX.img
)"
307 IMAGE_MOUNT_DIR="$
(mktemp
-d ${WORKING_DIR}/image.XXXXXXX
)"
309 IMAGE_TYPES_PUBLISH="qcow2 vmdk vdi img
"
310 IMAGE_DIR_PUBLISH="/home
/jschlag
/public
/ipfire3-images
"
312 # The used filesystem.
315 # Additional packages which should be installed.
316 PACKAGES="xfsprogs kernel openssh-server wget htop tmux
"
318 # Use git network stack. ( When using the git network stack,
319 # development tools and git automatically will be installed.)
320 USE_GIT_NETWORK_STACK="True
"
322 # List of packages which are required to build the network stack.
323 NETWORK_BUILD_DEPS="asciidoc autoconf automake docbook-xsl libnl3-devel libxslt systemd-devel
"
325 # Install development tools.
326 INSTALL_DEV_PACKAGES="True
"
328 # List of development tools which should be installed.
329 DEVELOPMENT_PACKAGES="make gcc libtool git
"
332 # Git repositories which also should be checked, out.
336 # Stuff for the local repo
339 # Use local repository.
340 USE_LOCAL_REPO="True
"
342 # Source path for the local repo packages.
343 LOCAL_REPO_SOURCE_PATH="/var
/lib
/pakfire
/local
/"
345 # Path were the local repo is created
346 LOCAL_REPO_DIR="$
(mktemp
-d ${WORKING_DIR}/ipfire-repo.XXXXXXX
)"
348 # Config file for the local repo
349 LOCAL_REPO_FILE="/etc
/pakfire
/repos
/local.repo
"
353 # Scripts starts here
359 # Check that pakfire is working
362 if ! check_for_free_space 10000 "${WORKING_DIR}"; then
366 # Check that the image does not exist yet
367 if [ -f ${IMAGE_BASE_FILE} ]; then
368 log ERROR "Image
file does already exists
"
372 # Check that the local repo file does not exists yet.
373 # We do not want to override custom user configurations.
374 if [ -f "${LOCAL_REPO_FILE}" ]; then
375 log ERROR "Config
file ${LOCAL_REPO_FILE} for the
local repo does already exists
"
379 # cd into working directory
380 cd ${WORKING_DIR} || exit ${EXIT_ERROR}
383 ## Create the disk image.
385 dd if=/dev/zero of=${IMAGE_BASE_FILE} seek=${IMAGE_SIZE}M count=1k bs=1
387 # Setup the loopback device.
388 outlo=`losetup -f --show ${IMAGE_BASE_FILE}`
390 log INFO "Create partions and filesystem
"
392 # Create and msdos compatible table on the image.
393 parted ${outlo} mklabel msdos
395 # Add a new partition to the image.
396 parted ${outlo} mkpart primary ${FILESYSTEM} 2048k 100% -a minimal
398 # Make the primary partition bootable.
399 parted ${outlo} set 1 boot on
401 # Notify the kernel about the new partition.
405 ## Create the filesystem.
407 mkfs.${FILESYSTEM} ${outlo}p1
410 ## Mount the filesystem.
413 log INFO "Mount partion
in ${IMAGE_MOUNT_DIR}"
415 # Afterwards mount the image.
416 mount -t ${FILESYSTEM} ${outlo}p1 ${IMAGE_MOUNT_DIR}
419 ## Install IPFire 3.x.
422 # Add grub on x86_64 to the package list.
423 if [ "${ARCH}" == "x86_64
" ] || [ "${ARCH}" == "i686
" ]; then
424 PACKAGES="${PACKAGES} grub
"
426 # Store, that grub is present.
430 # Check if the git network stack should be installed.
431 if [ "${USE_GIT_NETWORK_STACK}" == "True
" ]; then
432 GIT_REPOS="${GIT_REPOS} git
://git.ipfire.org
/network.git
"
434 # Add build dependencies of network package.
435 PACKAGES="${PACKAGES} ${NETWORK_BUILD_DEPS}"
438 # Add develoment packes to the package list, if required.
439 if [ "${INSTALL_DEV_PACKAGES}" == "True
" ] || [ ! -z "${GIT_REPOS}" ]; then
440 PACKAGES="${PACKAGES} ${DEVELOPMENT_PACKAGES}"
443 log INFO "Create
local respository
"
446 # Check if the local repo should be used.
447 if [ "${USE_LOCAL_REPO}" == "True
" ]; then
448 # Create local repository.
449 mkdir -pv "${LOCAL_REPO_DIR}"
452 if ! pakfire-server repo create ${LOCAL_REPO_DIR} ${LOCAL_REPO_SOURCE_PATH}; then
453 log ERROR "Failed to create a
local respository
"
458 # Create temporary pakfire repo file.
459 echo "[repo
:local]" >> "${LOCAL_REPO_FILE}"
460 echo "description
= Local repository.
" >> "${LOCAL_REPO_FILE}"
461 echo "enabled
= 0" >> "${LOCAL_REPO_FILE}"
462 echo "baseurl
= ${LOCAL_REPO_DIR}" >> "${LOCAL_REPO_FILE}"
464 ENABLE_LOCAL="--enable-repo=local"
467 # Install IPFire 3.x in the created image.
468 yes | pakfire --root=${IMAGE_MOUNT_DIR} ${ENABLE_LOCAL} install @Base ${PACKAGES}
471 # Enable serial console
475 #echo "GRUB_TERMINAL
=\"serial console
\"" >> "${IMAGE_MOUNT_DIR}/etc
/default
/grub
"
476 #echo "GRUB_SERIAL_COMMAND
=\"serial
--unit=0 --speed=115200\"" >> "${IMAGE_MOUNT_DIR}/etc
/default
/grub
"
478 #Hack to install a /etc/default/grub file
480 cmd cp -f "${SCRIPT_PATH}/grub
" "${IMAGE_MOUNT_DIR}/etc
/default
"
486 # Gather the uuid of the partition.
487 FS_UUID=$(blkid -o value -s UUID ${outlo}p1)
490 echo "UUID
=${FS_UUID} / ${FILESYSTEM} defaults 0 0" > "${IMAGE_MOUNT_DIR}/etc
/fstab
"
492 cat "${IMAGE_MOUNT_DIR}/etc
/fstab
"
495 ## Remove the password for user root.
498 reset_root_password "${IMAGE_MOUNT_DIR}"
501 ## Setup git repositories.
504 clone_git_repos "${IMAGE_MOUNT_DIR}/build
" ${GIT_REPOS}
507 ## Prepare chrooting into the image.
510 # Check if the network stack should be build.
511 if [ "${USE_GIT_NETWORK_STACK}" == "True
" ]; then
512 BUILD_NETWORK_CMDS="cd network
/ && .
/autogen.sh
&& .
/configure
&& make && make install"
515 ENABLE_GETTY="/bin
/systemctl
enable getty@.service
"
517 # Check if the arch uses grub
518 if [ "${HAVE_GRUB}" == "True
" ]; then
519 GENERATE_GRUB_CONF="grub-install
--boot-directory=${IMAGE_MOUNT_DIR}/boot/ --modules="${FILESYSTEM} part_msdos" ${outlo} && \
520 grub-mkconfig
-o /boot
/grub
/grub.cfg
"
524 # Use systemd-nspawn to spawn a chroot environment and execute
525 # commands inside it.
527 # The first command enables the terminal on TTY1.
528 # The second command generates the configuration file for grub2.
531 systemd-nspawn -D ${IMAGE_MOUNT_DIR} --bind /dev --capability=CAP_SYS_ADMIN,CAP_SYS_RAWIO --bind /proc --bind /sys << END
532 echo "Execute commands inside chroot
"
534 ${GENERATE_GRUB_CONF}
536 ${BUILD_NETWORK_CMDS}
537 echo "All commands executed
"
542 # Insert the UUID because grub-mkconfig often fails to
543 # detect that correctly
545 sed -i "${IMAGE_MOUNT_DIR}/boot
/grub
/grub.cfg
" \
546 -e "s
/root
=[A-Za-z0-9\
/=-]*/root
=UUID
=${FS_UUID}/g
"
548 cat "${IMAGE_MOUNT_DIR}/boot
/grub
/grub.cfg
"
550 cat "${IMAGE_MOUNT_DIR}/etc
/fstab
"
560 # Check filesystem for damage.
561 fsck.${FILESYSTEM} ${outlo}p1
565 publish "${IMAGE_DIR_PUBLISH}" "${IMAGE_BASE_FILE}"