2 ###############################################################################
3 # IPFire.org - An Open Source Firewall Solution #
4 # Copyright (C) - IPFire Development Team <info@ipfire.org> #
5 ###############################################################################
15 EXIT_COMMAND_NOT_FOUND
=127
27 echo "[${level}] ${message}"
32 umount
${IMAGE_MOUNT_DIR}
34 # Remove partition from the kernel table.
37 # Remove loopback device
41 if [ -d "${WORKING_DIR}" ]; then
42 rm -dfR "${WORKING_DIR}"
46 generate_image_filename
() {
51 echo "${distro}-${version}-${arch}"
58 # Check that pakfire-server binary is available
59 # Check that pakfire binary is available
61 # Check that repo files are installed. (pakfire need to know which repos exist)
62 local repo_dir
="/etc/pakfire/repos"
64 if [ ! -d "${repo_dir}" ]; then
65 log ERROR
"Could not find respository directory ${repo_dir}"
69 return ${return_value}
73 local compression
=${1}
77 log debug
"Compressing ${image_file} with ${compression}"
79 case "${compression}" in
81 # Check that the file does not exist yet
82 if [ -f "${image_file}.xz" ]; then
83 log ERROR
"Failed to compress the image. The file already exists"
86 xz
"-${level}" "${image_file}"
89 # Check that the file does not exist yet
90 if [ -f "${image_file}.zip" ]; then
91 log ERROR
"Failed to compress the image. The file already exists"
95 zip "-${level}" "${image_file}.zip" "${image_file}"
96 # Remove the file which we compressed+
103 reset_root_password
() {
106 cp -avf ${root_dir}/etc
/passwd
${root_dir}/etc
/passwd.orig
108 # Drop root password.
109 sed -e "s/^\(root:\)[^:]*:/\1:/" ${root_dir}/etc
/passwd.orig
> ${root_dir}/etc
/passwd
111 # Remove passwd backup file.
112 rm -rvf ${root_dir}/etc
/passwd.orig
116 # Dir where the repos should be located
127 # Clone git repositories.
128 for repo
in ${repos}; do
134 # This function is used to publish the produced images
138 # The image we created usually a img. file
139 local image_base_file
=${2}
141 local image_name_final
="$(generate_image_filename "${DISTRO}" "${VERSION}" "${ARCH}")"
144 local compression_type
146 # Do these steps for every image format we like to publish
147 for image_type
in ${IMAGE_TYPES_PUBLISH}; do
148 # Get compressioon type
149 compression_type
="$(get_compression_type ${image_type})"
150 # Convert images to the type specified in IMAGE_TYPES_PUBLISH
151 convert_image
"${image_type}" "${image_base_file}" "${image_name_final}"
154 compress_image
"${compression_type}" "${image_name_final}.${image_type}" "1"
156 # Move images to this path
157 mv -f "${image_name_final}.${image_type}.${compression_type}" ${path}
159 # point the latest links to these images
160 ln -s -f "${path}/${image_name_final}.${image_type}.${compression_type}" \
161 "${path}/$(generate_image_filename "${DISTRO}" "latest" "${ARCH}").${image_type}.${compression_type}"
172 if [[ ${type} = "img
" ]]; then
173 # We do not need to convert the image here but we need to rename
174 mv -f ${from} ${to}.${type}
177 if [[ ${type} = "qcow2
" ]]; then
178 local cmd="qemu-img convert
-c -O ${type} ${from} ${to}.${type}"
180 local cmd="qemu-img convert
-O ${type} ${from} ${to}.${type}"
185 # Execute the command to convert the image
189 get_compression_type() {
190 local image_type=${1}
192 case "${image_type}" in
194 # These types can be used only under Unix so we use xz as compression
198 # These types can be also under Windows so we use zip as compression
205 check_for_free_space() {
209 # Space needs to passed in MB
210 # df returns bytes so we multiple by 1024²
211 space=$(( ${space} * 1024 * 1024 ))
213 if [[ $(df --output=avail ${path} | tail -n 1) -lt ${space} ]]; then
214 log error "Not enough free space available under
${path}"
215 log error "Free space is $
(df
-h -B MB
--output=avail
${path} |
tail -n 1) but we need
at least $
(( ${space} / 1024 / 1024 ))MB
"
226 VERSION="$
(date +"%Y%m%d")"
227 WORKING_DIR=$(mktemp -d /tmp/ipfire3_image.XXXXXXXX)
229 log DEBUG "Working dir is
${WORKING_DIR}"
236 IMAGE_BASE_FILE="$
(mktemp
-u ${WORKING_DIR}/image_base_file.XXXXXXX.img
)"
238 IMAGE_MOUNT_DIR="$
(mktemp
-d ${WORKING_DIR}/image.XXXXXXX
)"
240 IMAGE_TYPES_PUBLISH="qcow2 vmdk vdi img
"
242 # The used filesystem.
245 # Additional packages which should be installed.
246 PACKAGES="xfsprogs kernel openssh-server wget htop tmux
"
248 # Use git network stack. ( When using the git network stack,
249 # development tools and git automatically will be installed.)
250 USE_GIT_NETWORK_STACK="True
"
252 # List of packages which are required to build the network stack.
253 NETWORK_BUILD_DEPS="autoconf automake docbook-xsl libnl3-devel libxslt systemd-devel
"
255 # Install development tools.
256 INSTALL_DEV_PACKAGES="False
"
258 # List of development tools which should be installed.
259 DEVELOPMENT_PACKAGES="make gcc libtool git
"
262 # Git repositories which also should be checked, out.
266 # Stuff for the local repo
269 # Use local repository.
270 USE_LOCAL_REPO="True
"
272 # Source path for the local repo packages.
273 LOCAL_REPO_SOURCE_PATH="/var
/lib
/pakfire
/local
/"
275 # Path were the local repo is created
276 LOCAL_REPO_DIR="$
(mktemp
-d ${WORKING_DIR}/ipfire-repo.XXXXXXX
)"
278 # Config file for the local repo
279 LOCAL_REPO_FILE="/etc
/pakfire
/repos
/local.repo
"
282 # Check that pakfire is working
285 if ! check_for_free_space 10000 "${WORKING_DIR}"; then
289 # Check that the image does not exist yet
290 if [ -f ${IMAGE_BASE_FILE} ]; then
291 log ERROR "Image
file does already exists
"
295 # Check that the local repo file does not exists yet.
296 # We do not want to override custom user configurations.
297 if [ -f "${LOCAL_REPO_FILE}" ]; then
298 log ERROR "Config
file ${LOCAL_REPO_FILE} for the
local repo does already exists
"
302 # cd into working directory
303 cd ${WORKING_DIR} || exit ${EXIT_ERROR}
306 ## Create the disk image.
308 dd if=/dev/zero of=${IMAGE_BASE_FILE} seek=${IMAGE_SIZE}MB count=1k bs=1
310 # Setup the loopback device.
311 outlo=`losetup -f --show ${IMAGE_BASE_FILE}`
313 log INFO "Create partions and filesystem
"
315 # Create and msdos compatible table on the image.
316 parted ${outlo} mklabel msdos
318 # Add a new partition to the image.
319 parted ${outlo} mkpart primary ${FILESYSTEM} 2048k 100% -a minimal
321 # Make the primary partition bootable.
322 parted ${outlo} set 1 boot on
324 # Notify the kernel about the new partition.
328 ## Create the filesystem.
330 mkfs.${FILESYSTEM} ${outlo}p1
333 ## Mount the filesystem.
336 log INFO "Mount partion
in ${IMAGE_MOUNT_DIR}"
338 # Create a temporary mountpoint.
339 mkdir -p ${IMAGE_MOUNT_DIR}
341 # Afterwards mount the image.
342 mount -t ${FILESYSTEM} ${outlo}p1 ${IMAGE_MOUNT_DIR}
345 ## Install IPFire 3.x.
348 # Add grub on x86_64 to the package list.
349 if [ "${ARCH}" == "x86_64
" ] || [ "${ARCH}" == "i686
" ]; then
350 PACKAGES="${PACKAGES} grub
"
352 # Store, that grub is present.
356 # Check if the git network stack should be installed.
357 if [ "${USE_GIT_NETWORK_STACK}" == "True
" ]; then
358 GIT_REPOS="${GIT_REPOS} git
://git.ipfire.org
/network.git
"
360 # Add build dependencies of network package.
361 PACKAGES="${PACKAGES} ${NETWORK_BUILD_DEPS}"
364 # Add develoment packes to the package list, if required.
365 if [ "${INSTALL_DEV_PACKAGES}" == "True
" ] || [ ! -z "${GIT_REPOS}" ]; then
366 PACKAGES="${PACKAGES} ${DEVELOPMENT_PACKAGES}"
369 log INFO "Create
local respository
"
372 # Check if the local repo should be used.
373 if [ "${USE_LOCAL_REPO}" == "True
" ]; then
374 # Create local repository.
375 mkdir -pv "${LOCAL_REPO_DIR}"
378 if ! pakfire-server repo create ${LOCAL_REPO_DIR} ${LOCAL_REPO_SOURCE_PATH}; then
379 log ERROR "Failed to create a
local respository
"
384 # Create temporary pakfire repo file.
385 echo "[repo
:local]" >> "${LOCAL_REPO_FILE}"
386 echo "description
= Local repository.
" >> "${LOCAL_REPO_FILE}"
387 echo "enabled
= 0" >> "${LOCAL_REPO_FILE}"
388 echo "baseurl
= ${LOCAL_REPO_DIR}" >> "${LOCAL_REPO_FILE}"
390 ENABLE_LOCAL="--enable-repo=local"
393 # Install IPFire 3.x in the created image.
394 yes | pakfire --root=${IMAGE_MOUNT_DIR} ${ENABLE_LOCAL} install @Base ${PACKAGES}
397 # Enable serial console
401 #echo "GRUB_TERMINAL
=\"serial console
\"" >> "${IMAGE_MOUNT_DIR}/etc
/default
/grub
"
402 #echo "GRUB_SERIAL_COMMAND
=\"serial
--unit=0 --speed=115200\"" >> "${IMAGE_MOUNT_DIR}/etc
/default
/grub
"
404 #Hack to install a /etc/default/grub file
406 cp -f grub "${IMAGE_MOUNT_DIR}/etc
/default
"
409 ## Install grub2 if neccessary
411 if [ "${HAVE_GRUB}" == "True
" ]; then
412 grub2-install --boot-directory=${IMAGE_MOUNT_DIR}/boot/ --modules="${FILESYSTEM} part_msdos" ${outlo}
419 # Gather the uuid of the partition.
420 FS_UUID=$(blkid -o value -s UUID ${outlo}p1)
423 echo "UUID
=${FS_UUID} / ${FILESYSTEM} defaults 0 0" > ${IMAGE_MOUNT_DIR}/etc
/fstab
426 ## Remove the password for user root.
429 reset_root_password
"${IMAGE_MOUNT_DIR}"
432 ## Setup git repositories.
435 clone_git_repos
"${IMAGE_MOUNT_DIR}/build" ${GIT_REPOS}
438 ## Prepare chrooting into the image.
441 # Check if the network stack should be build.
442 if [ "${USE_GIT_NETWORK_STACK}" == "True" ]; then
443 BUILD_NETWORK_CMDS
="cd network/ && ./autogen.sh && ./configure && make && make install"
446 ENABLE_GETTY
="/bin/systemctl enable getty@.service"
448 # Check if the arch uses grub
449 if [ "${HAVE_GRUB}" == "True" ]; then
450 GENERATE_GRUB_CONF
="grub-mkconfig -o /boot/grub2/grub.cfg"
453 # Use systemd-nspawn to spawn a chroot environment and execute
454 # commands inside it.
456 # The first command enables the terminal on TTY1.
457 # The second command generates the configuration file for grub2.
460 systemd-nspawn
-D ${IMAGE_MOUNT_DIR} --bind /dev
--capability=CAP_SYS_ADMIN
,CAP_SYS_RAWIO
--bind /proc
--bind /sys
<< END
461 echo "Execute commands inside chroot"
463 ${GENERATE_GRUB_CONF}
465 ${BUILD_NETWORK_CMDS}
466 echo "All commands executed"
471 # Insert the UUID because grub-mkconfig often fails to
472 # detect that correctly
474 sed -i "${IMAGE_MOUNT_DIR}/boot/grub2/grub.cfg" \
475 -e "s/root=[A-Za-z0-9\/=-]*/root=UUID=${FS_UUID}/g"
477 cat "${IMAGE_MOUNT_DIR}/boot/grub2/grub.cfg"
485 # Check filesystem for damage.
486 fsck.
${FILESYSTEM} ${outlo}p1
491 publish
"/home/jschlag/public/ipfire3-images" "${IMAGE_BASE_FILE}"
493 #compress_image "xz" "${IMAGE_BASE_FILE}"