Implementation of dracut kiwi-dump module

Provide the capabilities of the oem install code as
dracut module. The implementation covers the result
of the installiso="true" configuration. Installation
from remote sources still needs to be done and will
follow in an extra pull request. This addresses
Issue #576
This commit is contained in:
Marcus Schäfer 2017-11-23 11:56:55 +01:00
parent 02dc8e32e1
commit d582dc90bd
17 changed files with 637 additions and 87 deletions

View File

@ -0,0 +1,311 @@
#!/bin/bash
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
type setup_debug >/dev/null 2>&1 || . /lib/kiwi-lib.sh
type run_dialog >/dev/null 2>&1 || . /lib/kiwi-dialog-lib.sh
type get_block_device_kbsize >/dev/null 2>&1 || . /lib/kiwi-partitions-lib.sh
#======================================
# Functions
#--------------------------------------
function scan_softraid_devices {
# TODO: run ataraid scan so that they appear in lsblk
:
}
function scan_multipath_devices {
# TODO: run multipath scan/daemon so that they appear in lsblk
:
}
function get_disk_list {
declare kiwi_oemdevicefilter=${kiwi_oemdevicefilter}
declare kiwi_oemataraid_scan=${kiwi_oemataraid_scan}
declare kiwi_oemmultipath_scan=${kiwi_oemmultipath_scan}
declare kiwi_devicepersistency=${kiwi_devicepersistency}
local disk_id="by-id"
local disk_size
local disk_device
local disk_device_by_id
local disk_meta
local item_status=on
local list_items
if [ ! -z "${kiwi_devicepersistency}" ];then
disk_id=${kiwi_devicepersistency}
fi
if [ ! -z "${kiwi_oemataraid_scan}" ];then
scan_softraid_devices
fi
if [ ! -z "${kiwi_oemmultipath_scan}" ];then
scan_multipath_devices
fi
for disk_meta in $(
lsblk -n -r -o NAME,SIZE,TYPE | grep disk | tr ' ' ":"
);do
disk_device="/dev/$(echo "${disk_meta}" | cut -f1 -d:)"
disk_size=$(echo "${disk_meta}" | cut -f2 -d:)
disk_device_by_id=$(
get_persistent_device_from_unix_node "${disk_device}" "${disk_id}"
)
if [ ! -z "${disk_device_by_id}" ];then
disk_device=${disk_device_by_id}
fi
# check for static filter rules
if [[ ${disk_device} =~ ^/dev/fd ]];then
# ignore floppy disk devices
continue
fi
# check for custom filter rule
if [ ! -z "${kiwi_oemdevicefilter}" ];then
if [[ ${disk_device} =~ ${kiwi_oemdevicefilter} ]];then
info "${disk_device} filtered out by: ${kiwi_oemdevicefilter}"
continue
fi
fi
list_items="${list_items} ${disk_device} ${disk_size} ${item_status}"
item_status=off
done
if [ -z "${list_items}" ];then
local no_device_text="No device(s) for installation found"
run_dialog --msgbox "\"${no_device_text}\"" 5 60
die "${no_device_text}"
fi
echo "${list_items}"
}
function get_selected_disk {
declare kiwi_oemunattended=${kiwi_oemunattended}
declare kiwi_oemunattended_id=${kiwi_oemunattended_id}
local disk_list
local device_array
disk_list=$(get_disk_list)
if [ ! -z "${disk_list}" ];then
local count=0
local device_index=0
for entry in ${disk_list};do
if [ $((count % 3)) -eq 0 ];then
device_array[${device_index}]=${entry}
device_index=$((device_index + 1))
fi
count=$((count + 1))
done
if [ "${device_index}" -eq 1 ];then
# one single disk device found, use it
echo "${device_array[0]}"
elif [ ! -z "${kiwi_oemunattended}" ];then
if [ -z "${kiwi_oemunattended_id}" ];then
# unattended mode requested but no target specifier,
# thus use first device from list
echo "${device_array[0]}"
else
# unattended mode requested with target specifier
# use this device if present
local device
for device in ${device_array[*]}; do
if [[ ${device} =~ ${kiwi_oemunattended_id} ]];then
echo "${device}"
return
fi
done
fi
else
# manually select from storage list
if ! run_dialog \
--radiolist "\"Select Installation Disk\"" 20 75 15 \
"$(get_disk_list)"
then
die "System installation canceled"
fi
get_dialog_result
fi
fi
}
function export_image_metadata {
local image_source_files=$1
export checksum
export blocks
export blocksize
export zblocks
export zblocksize
local meta_file
meta_file="$(echo "${image_source_files}" | cut -f2 -d\|)"
if ! read -r checksum blocks blocksize zblocks zblocksize < "${meta_file}"
then
die "Reading ${meta_file} failed"
fi
echo "Image checksum: ${checksum}"
echo "Image blocks: ${blocks} / blocksize: ${blocksize}"
if [ ! -z "${zblocks}" ];then
echo "Image compressed blocks: ${zblocks} / blocksize: ${zblocksize}"
fi
}
function check_image_fits_target {
local image_target=$1
local need_mbytes
local have_mbytes
need_mbytes=$((blocks * blocksize / 1048576))
have_mbytes=$(($(get_block_device_kbsize "${image_target}") / 1024))
echo "Have size: ${image_target} -> ${have_mbytes} MB"
echo "Need size: ${image_source} -> ${need_mbytes} MB"
if [ ${need_mbytes} -gt ${have_mbytes} ];then
die "Not enough space available for this image"
fi
}
function dump_local_image {
declare kiwi_oemsilentinstall=${kiwi_oemsilentinstall}
declare kiwi_oemunattended=${kiwi_oemunattended}
local image_source_files=$1
local image_target=$2
local image_source
local image_basename
image_source="$(echo "${image_source_files}" | cut -f1 -d\|)"
image_basename=$(basename "${image_source}")
local progress=/dev/install_progress
local load_text="Loading ${image_basename}..."
local title_text="Installation..."
read_local_image_metadata "${image_source}"
check_image_fits_target "${image_target}"
if [ -z "${kiwi_oemunattended}" ];then
local ack_dump_text="Destroying ALL data on ${image_target}, continue ?"
if ! run_dialog --yesno "\"${ack_dump_text}\"" 5 80; then
local install_cancel_text="System installation canceled"
run_dialog --msgbox "\"${install_cancel_text}\"" 5 60
die "${install_cancel_text}"
fi
fi
echo "${load_text} [${image_target}]..."
if command -v pv &>/dev/null && [ -z "${kiwi_oemsilentinstall}" ];then
# dump with dialog based progress information
setup_progress_fifo ${progress}
#run_progress_dialog "${load_text}" "${title_text}" &
(
pv -n "${image_source}" | dd bs=32k of="${image_target}" &>/dev/null
) 2>${progress} &
run_progress_dialog "${load_text}" "${title_text}"
#stop_dialog
else
# dump with silently blocked console
if ! dd if="${image_source}" bs=32k of="${image_target}" &>/dev/null
then
die "Failed to install image"
fi
fi
}
function dump_remote_image {
# TODO
:
}
function check_image_integrity {
declare kiwi_oemskipverify=${kiwi_oemskipverify}
declare kiwi_oemsilentverify=${kiwi_oemsilentverify}
local image_target=$1
local progress=/dev/install_verify_progress
local verify_text="Verifying ${image_target}"
local title_text="Installation..."
local verify_result=/dumped_image.md5
if [ ! -z "${kiwi_oemskipverify}" ];then
# no verification wanted
return
fi
if command -v pv &>/dev/null && [ -z "${kiwi_oemsilentverify}" ];then
# verify with dialog based progress information
setup_progress_fifo ${progress}
run_progress_dialog "${verify_text}" "${title_text}" &
(
pv --size $((blocks * blocksize)) --stop-at-size \
-n "${image_target}" | md5sum - > ${verify_result}
) 2>${progress}
stop_dialog
else
# verify with silently blocked console
head --bytes=$((blocks * blocksize)) "${image_target}" |\
md5sum - > ${verify_result}
fi
local checksum_dumped_image
local checksum_fileref
read -r checksum_dumped_image checksum_fileref < ${verify_result}
echo "Dumped Image checksum: ${checksum_dumped_image}/${checksum_fileref}"
if [ "${checksum}" != "${checksum_dumped_image}" ];then
die "Image checksum test failed"
fi
}
function get_local_image_source_files {
declare root=${root}
local iso_device="${root#install:}"
local iso_mount_point=/run/install
local image_mount_point=/run/image
local image_source
local image_md5
mkdir -m 0755 -p "${iso_mount_point}"
if ! mount -n "${iso_device}" "${iso_mount_point}"; then
die "Failed to mount install ISO device"
fi
mkdir -m 0755 -p "${image_mount_point}"
if ! mount -n "${iso_mount_point}"/*.squashfs ${image_mount_point};then
die "Failed to mount install image squashfs filesystem"
fi
image_source="$(echo "${image_mount_point}"/*.raw)"
image_md5="$(echo "${image_mount_point}"/*.md5)"
echo "${image_source}|${image_md5}"
}
function get_remote_image_source_files {
# TODO:
:
}
function boot_installed_system {
local boot_options
boot_options="$(cat /config.bootoptions)"
if getargbool 0 rd.kiwi.debug; then
boot_options="${boot_options} rd.kiwi.debug"
fi
kexec -l /run/install/boot/*/loader/linux \
--initrd /run/install/initrd.system_image \
--command-line "${boot_options}"
if ! kexec -e; then
die "Failed to boot system"
fi
}
#======================================
# Perform image dump/install operations
#--------------------------------------
setup_debug
udev_pending
stop_plymouth
image_target=$(get_selected_disk)
if getargbool 0 rd.kiwi.install.pxe; then
image_source_files=$(get_remote_image_source_files)
else
image_source_files=$(get_local_image_source_files)
fi
export_image_metadata "${image_source_files}"
if getargbool 0 rd.kiwi.install.pxe; then
dump_remote_image "${image_source_files}" "${image_target}"
else
dump_local_image "${image_source_files}" "${image_target}"
fi
check_image_integrity "${image_target}"
boot_installed_system
emergency_shell
exit 0

View File

@ -0,0 +1,23 @@
#!/bin/bash
# called by dracut
depends() {
echo rootfs-block dm kiwi-lib
return 0
}
# called by dracut
installkernel() {
instmods squashfs loop iso9660
}
# called by dracut
install() {
declare moddir=${moddir}
inst_multiple \
tr lsblk dd md5sum head pv kexec
inst_hook cmdline 30 "${moddir}/parse-kiwi-install.sh"
inst_hook pre-mount 30 "${moddir}/kiwi-dump-image.sh"
inst_rules 60-cdrom_id.rules
dracut_need_initqueue
}

View File

@ -0,0 +1,31 @@
#!/bin/bash
# install images are specified with
# root=install:CDLABEL=label
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
[ -z "${root}" ] && root=$(getarg root=)
if [ "${root%%:*}" = "install" ] ; then
installroot=${root}
fi
[ "${installroot%%:*}" = "install" ] || return 1
modprobe -q loop
case "${installroot}" in
install:CDLABEL=*|CDLABEL=*) \
root="${root#install:}"
root="$(echo "${root}" | sed 's,/,\\x2f,g')"
root="install:/dev/disk/by-label/${root#CDLABEL=}"
rootok=1 ;;
esac
[ "$rootok" = "1" ] || return 1
info "root was ${installroot}, is now ${root}"
# make sure that init doesn't complain
[ -z "${root}" ] && root="install"
return 0

View File

@ -13,24 +13,57 @@ function run_dialog {
local dialog_exit_code=/tmp/dialog_code
{
echo "dialog $* 2>$dialog_result"
echo -n \$? >$dialog_exit_code
echo "echo -n \$? >$dialog_exit_code"
} >/bin/dracut-interactive
_run_interactive
return "$(cat $dialog_exit_code)"
}
function setup_progress_fifo {
local fifo=$1
export current_progress_fifo="${fifo}"
[ -e "${fifo}" ] || mkfifo "${fifo}"
}
function stop_dialog {
_stop_interactive
}
function run_progress_dialog {
# """
# Run the gauge dialog via systemd reading progress
# status information from stdin
# """
declare fifo=${current_progress_fifo}
local title=$1
local backtitle=$2
local progress_at="${fifo}"
if [ ! -e "${progress_at}" ];then
return
fi
{
echo -n "cat ${fifo} | dialog --backtitle \"${backtitle}\" "
echo -n "--gauge \"${title}\"" 7 65 0
echo
} >/bin/dracut-interactive
_run_interactive
}
function get_dialog_result {
local dialog_result=/tmp/dialog_result
[ -e "${dialog_result}" ] && cat ${dialog_result}; rm -f ${dialog_result}
}
function stop_plymouth {
plymouth --quit --wait
}
#=========================================
# Methods considered private
#-----------------------------------------
function _setup_interactive_service {
local service=/usr/lib/systemd/system/dracut-run-interactive.service
local script=/bin/dracut-interactive
local unicode_font=/lib/b16.pcf.gz
[ -e ${service} ] && return
{
echo "[Unit]"
@ -45,7 +78,7 @@ function _setup_interactive_service {
echo "Environment=NEWROOT=/sysroot"
echo "WorkingDirectory=/"
if _fbiterm_ok; then
echo "ExecStart=fbiterm -m ${unicode_font} -- /bin/bash ${script}"
echo "ExecStart=fbiterm -- /bin/bash ${script} "
else
echo "ExecStart=/bin/bash ${script}"
fi
@ -55,7 +88,6 @@ function _setup_interactive_service {
echo "StandardError=inherit"
echo "KillMode=process"
echo "IgnoreSIGPIPE=no"
echo "TaskMax=infinity"
echo "KillSignal=SIGHUP"
} > ${service}
}
@ -65,6 +97,10 @@ function _run_interactive {
systemctl start dracut-run-interactive.service
}
function _stop_interactive {
systemctl stop dracut-run-interactive.service
}
function _fbiterm_ok {
if [ ! -e /dev/fb0 ];then
# no framebuffer device found

View File

@ -20,7 +20,7 @@ install() {
btrfs xfs_growfs resize2fs \
e2fsck btrfsck xfs_repair \
vgs vgchange lvextend lvcreate lvresize pvresize \
mdadm cryptsetup
mdadm cryptsetup dialog
if [[ "$(uname -m)" =~ s390 ]];then
inst_multiple fdasd
fi

View File

@ -129,11 +129,12 @@ class BootImageBase(object):
"""
raise NotImplementedError
def create_initrd(self, mbrid=None):
def create_initrd(self, mbrid=None, basename=None):
"""
Implements creation of the initrd
:param object mbrid: instance of ImageIdentifier
:param string basename: base initrd file name
"""
raise NotImplementedError

View File

@ -104,11 +104,12 @@ class BootImageKiwi(BootImageBase):
self.setup.call_image_script()
self.setup.create_init_link_from_linuxrc()
def create_initrd(self, mbrid=None):
def create_initrd(self, mbrid=None, basename=None):
"""
Create initrd from prepared boot system tree and compress the result
:param object mbrid: instance of ImageIdentifier
:param string basename: base initrd file name
"""
if self.is_prepared():
log.info('Creating initrd cpio archive')
@ -119,6 +120,10 @@ class BootImageKiwi(BootImageBase):
# boot directory should not be changed because we rely
# on other data in boot/ e.g the kernel to be available
# for the entire image building process
if basename:
kiwi_initrd_basename = basename
else:
kiwi_initrd_basename = self.initrd_base_name
temp_boot_root_directory = mkdtemp(
prefix='kiwi_boot_root_copy.'
)
@ -143,7 +148,7 @@ class BootImageKiwi(BootImageBase):
mbrid.write(image_identifier)
cpio = ArchiveCpio(
os.sep.join([self.target_dir, self.initrd_base_name])
os.sep.join([self.target_dir, kiwi_initrd_basename])
)
# the following is a list of directories which were needed
# during the process of creating an image but not when the
@ -165,7 +170,7 @@ class BootImageKiwi(BootImageBase):
'--> xz compressing archive'
)
compress = Compress(
os.sep.join([self.target_dir, self.initrd_base_name])
os.sep.join([self.target_dir, kiwi_initrd_basename])
)
compress.xz(
['--check=crc32', '--lzma2=dict=1MiB', '--threads=0']

View File

@ -57,18 +57,23 @@ class BootImageDracut(BootImageBase):
self.dracut_options.append('--install')
self.dracut_options.append('/.profile')
def create_initrd(self, mbrid=None):
def create_initrd(self, mbrid=None, basename=None):
"""
Call dracut as chroot operation to create the initrd and move
the result into the image build target directory
:param object mbrid: unused
:param string basename: base initrd file name
"""
if self.is_prepared():
log.info('Creating generic dracut initrd archive')
kernel_info = Kernel(self.boot_root_directory)
kernel_details = kernel_info.get_kernel(raise_on_not_found=True)
dracut_initrd_basename = self.initrd_base_name + '.xz'
if basename:
dracut_initrd_basename = basename
else:
dracut_initrd_basename = self.initrd_base_name
dracut_initrd_basename += '.xz'
Command.run(
[
'chroot', self.boot_root_directory,

View File

@ -146,6 +146,10 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
'root=live:CDLABEL={0}'.format(self.volume_id),
'rd.live.image'
]
self.install_boot_options = [
'root=install:CDLABEL={0}'.format(Defaults.get_install_volume_id()),
'loglevel=0'
]
if self.xml_state.build_type.get_hybridpersistent():
self.live_boot_options += \
Defaults.get_live_iso_persistent_boot_options(
@ -326,8 +330,12 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
'default_boot': self.get_install_image_boot_default(),
'kernel_file': kernel,
'initrd_file': initrd,
'boot_options': self.cmdline,
'failsafe_boot_options': self.cmdline_failsafe,
'boot_options': ' '.join(
[self.cmdline] + self.install_boot_options
),
'failsafe_boot_options': ' '.join(
[self.cmdline_failsafe] + self.install_boot_options
),
'gfxmode': self.gfxmode,
'theme': self.theme,
'boot_timeout': self.timeout,

View File

@ -98,6 +98,11 @@ class BootLoaderConfigIsoLinux(BootLoaderConfigBase):
'root=live:CDLABEL={0}'.format(self.volume_id),
'rd.live.image'
]
self.install_boot_options = [
'root=install:CDLABEL={0}'.format(Defaults.get_install_volume_id()),
'loglevel=0'
]
if self.xml_state.build_type.get_hybridpersistent():
self.live_boot_options += \
Defaults.get_live_iso_persistent_boot_options(
@ -160,8 +165,12 @@ class BootLoaderConfigIsoLinux(BootLoaderConfigBase):
'default_boot': self.get_install_image_boot_default('isolinux'),
'kernel_file': kernel,
'initrd_file': initrd,
'boot_options': self.cmdline,
'failsafe_boot_options': self.cmdline_failsafe,
'boot_options': ' '.join(
[self.cmdline] + self.install_boot_options
),
'failsafe_boot_options': ' '.join(
[self.cmdline_failsafe] + self.install_boot_options
),
'gfxmode': self.gfxmode,
'boot_timeout': self.timeout,
'title': self.get_menu_entry_install_title()

View File

@ -28,7 +28,6 @@ from kiwi.bootloader.config import BootLoaderConfig
from kiwi.bootloader.install import BootLoaderInstall
from kiwi.system.identifier import SystemIdentifier
from kiwi.boot.image import BootImage
from kiwi.boot.image import BootImageKiwi
from kiwi.storage.setup import DiskSetup
from kiwi.storage.loop_device import LoopDevice
from kiwi.firmware import FirmWare
@ -392,31 +391,6 @@ class DiskBuilder(object):
# prepare for install media if requested
if self.install_media:
if self.initrd_system == 'dracut':
# for the installation process we need a kiwi initrd
# Therefore an extra install boot root system needs to
# be prepared if dracut was set as the initrd system
# to boot the system image
log.info('Preparing extra install boot system')
self.xml_state.build_type.set_initrd_system('kiwi')
self.initrd_system = self.xml_state.get_initrd_system()
self.boot_image = BootImageKiwi(
self.xml_state, self.target_dir,
signing_keys=self.signing_keys
)
self.boot_image.prepare()
# apply disk builder metadata also needed in the install initrd
self._write_partition_id_config_to_boot_image()
self._write_recovery_metadata_to_boot_image()
self._write_raid_config_to_boot_image()
self.system_setup.export_modprobe_setup(
self.boot_image.boot_root_directory
)
log.info('Saving boot image instance to file')
self.boot_image.dump(
self.target_dir + '/boot_image.pickledump'
@ -677,6 +651,7 @@ class DiskBuilder(object):
'dracut_rescue_image="no"'
]
dracut_modules = []
dracut_modules_omit = ['kiwi-dump']
if self.root_filesystem_is_overlay:
dracut_modules.append('kiwi-overlay')
if self.build_type_name == 'oem':
@ -685,6 +660,9 @@ class DiskBuilder(object):
dracut_config.append(
'add_dracutmodules+=" {0} "'.format(' '.join(dracut_modules))
)
dracut_config.append(
'omit_dracutmodules+=" {0} "'.format(' '.join(dracut_modules_omit))
)
with open(dracut_config_file, 'w') as config:
for entry in dracut_config:
config.write(entry + os.linesep)
@ -832,6 +810,20 @@ class DiskBuilder(object):
)
self.bootloader_config.write()
log.info('Creating config.bootoptions')
filename = ''.join(
[self.boot_image.boot_root_directory, '/config.bootoptions']
)
kexec_boot_options = ' '.join(
[
self.bootloader_config.get_boot_cmdline(root_uuid)
] + boot_options
)
with open(filename, 'w') as boot_options:
boot_options.write(
'{0}{1}'.format(kexec_boot_options, os.linesep)
)
partition_id_map = self.disk.get_public_partition_id_map()
boot_partition_id = partition_id_map['kiwi_RootPart']
if 'kiwi_BootPart' in partition_id_map:

View File

@ -15,8 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
#
import os
from tempfile import mkdtemp
import platform
import shutil
# project
from kiwi.command import Command
@ -72,6 +74,7 @@ class InstallImageBuilder(object):
self.target_dir = target_dir
self.boot_image_task = boot_image_task
self.xml_state = xml_state
self.initrd_system = xml_state.get_initrd_system()
self.firmware = FirmWare(xml_state)
self.diskname = ''.join(
[
@ -100,6 +103,9 @@ class InstallImageBuilder(object):
'.install.tar.xz'
]
)
self.dracut_config_file = ''.join(
[self.root_dir, '/etc/dracut.conf.d/02-kiwi.conf']
)
self.squashed_diskname = ''.join(
[xml_state.xml_data.get_name(), '.raw']
)
@ -133,7 +139,7 @@ class InstallImageBuilder(object):
# custom iso metadata
self.custom_iso_args = {
'create_options': [
'-V', '"KIWI Installation System"',
'-V', Defaults.get_install_volume_id(),
'-A', self.mbrid.get_id()
]
}
@ -146,8 +152,10 @@ class InstallImageBuilder(object):
checksum = Checksum(self.diskname)
checksum.md5(self.squashed_contents + '/' + self.md5name)
# the kiwi initrd code triggers the install by trigger files
self._create_iso_install_trigger_files()
# the system image name is stored in a config file
self._write_install_image_info_to_iso_image()
if self.initrd_system == 'kiwi':
self._write_install_image_info_to_boot_image()
# the system image is stored as squashfs embedded file
log.info('Creating squashfs embedded disk image')
@ -203,6 +211,9 @@ class InstallImageBuilder(object):
log.info('Creating install image boot image')
self._create_iso_install_kernel_and_initrd()
# the system image initrd is stored to allow kexec
self._copy_system_image_initrd_to_iso_image()
# create iso filesystem from media_dir
log.info('Creating ISO filesystem')
iso_image = FileSystemIsoFs(
@ -263,8 +274,9 @@ class InstallImageBuilder(object):
checksum = Checksum(self.diskname)
checksum.md5(pxe_md5_filename)
# the kiwi initrd code triggers the install by trigger files
self._create_pxe_install_trigger_files()
# the install image name is stored in a config file
if self.initrd_system == 'kiwi':
self._write_install_image_info_to_boot_image()
# create pxe config append information
# this information helps to configure the boot server correctly
@ -311,7 +323,9 @@ class InstallImageBuilder(object):
'No hypervisor in boot image tree %s found' %
self.boot_image_task.boot_root_directory
)
self.boot_image_task.create_initrd(self.mbrid)
if self.initrd_system == 'dracut':
self._create_dracut_install_config()
self.boot_image_task.create_initrd(self.mbrid, 'initrd_kiwi_install')
Command.run(
[
'mv', self.boot_image_task.initrd_filename,
@ -338,7 +352,10 @@ class InstallImageBuilder(object):
'No hypervisor in boot image tree %s found' %
self.boot_image_task.boot_root_directory
)
self.boot_image_task.create_initrd(self.mbrid)
if self.initrd_system == 'dracut':
self._create_dracut_install_config()
self._add_system_image_boot_options_to_boot_image()
self.boot_image_task.create_initrd(self.mbrid, 'initrd_kiwi_install')
Command.run(
[
'mv', self.boot_image_task.initrd_filename,
@ -346,23 +363,56 @@ class InstallImageBuilder(object):
]
)
def _create_iso_install_trigger_files(self):
initrd_trigger = \
self.boot_image_task.boot_root_directory + '/config.vmxsystem'
def _add_system_image_boot_options_to_boot_image(self):
filename = ''.join(
[self.boot_image_task.boot_root_directory, '/config.bootoptions']
)
self.boot_image_task.include_file(
os.sep + os.path.basename(filename)
)
def _copy_system_image_initrd_to_iso_image(self):
system_image_initrd = self.root_dir + '/boot/initrd'
shutil.copy(
system_image_initrd, self.media_dir + '/initrd.system_image'
)
def _write_install_image_info_to_iso_image(self):
iso_trigger = self.media_dir + '/config.isoclient'
with open(initrd_trigger, 'w') as vmx_system:
vmx_system.write('IMAGE="%s"\n' % self.squashed_diskname)
with open(iso_trigger, 'w') as iso_system:
iso_system.write('IMAGE="%s"\n' % self.squashed_diskname)
def _create_pxe_install_trigger_files(self):
def _write_install_image_info_to_boot_image(self):
initrd_trigger = \
self.boot_image_task.boot_root_directory + '/config.vmxsystem'
with open(initrd_trigger, 'w') as vmx_system:
vmx_system.write('IMAGE="%s"\n' % self.squashed_diskname)
def _create_dracut_install_config(self):
dracut_config = [
'hostonly="no"',
'dracut_rescue_image="no"'
]
dracut_modules = ['kiwi-lib', 'kiwi-dump']
dracut_modules_omit = ['kiwi-overlay', 'kiwi-repart']
dracut_config.append(
'add_dracutmodules+=" {0} "'.format(' '.join(dracut_modules))
)
dracut_config.append(
'omit_dracutmodules+=" {0} "'.format(' '.join(dracut_modules_omit))
)
with open(self.dracut_config_file, 'w') as config:
for entry in dracut_config:
config.write(entry + os.linesep)
def _delete_dracut_install_config(self):
if os.path.exists(self.dracut_config_file):
os.remove(self.dracut_config_file)
def __del__(self):
log.info('Cleaning up %s instance', type(self).__name__)
if self.initrd_system == 'dracut':
self._delete_dracut_install_config()
if self.media_dir:
Path.wipe(self.media_dir)
if self.pxe_dir:

View File

@ -204,6 +204,13 @@ class Defaults(object):
"""
return 'CDROM'
@classmethod
def get_install_volume_id(self):
"""
Implements default value for ISO volume ID for install media
"""
return 'INSTALL'
@classmethod
def get_default_video_mode(self):
"""

View File

@ -138,6 +138,15 @@ class TestBootImageKiwi(object):
compress.xz.assert_called_once_with(
['--check=crc32', '--lzma2=dict=1MiB', '--threads=0']
)
mock_cpio.reset_mock()
mock_compress.reset_mock()
self.boot_image.create_initrd(mbrid, 'foo')
mock_cpio.assert_called_once_with(
self.boot_image.target_dir + '/foo'
)
mock_compress.assert_called_once_with(
self.boot_image.target_dir + '/foo'
)
@patch('kiwi.boot.image.base.Path.wipe')
@patch('os.path.exists')

View File

@ -70,3 +70,20 @@ class TestBootImageKiwi(object):
'some-target-dir'
])
]
mock_command.reset_mock()
self.boot_image.create_initrd(basename='foo')
assert mock_command.call_args_list == [
call([
'chroot', 'system-directory',
'dracut', '--force', '--no-hostonly',
'--no-hostonly-cmdline', '--xz',
'--install', 'system-directory/etc/foo',
'--install', '/system-directory/var/lib/bar',
'foo.xz', '1.2.3'
]),
call([
'mv',
'system-directory/foo.xz',
'some-target-dir'
])
]

View File

@ -134,6 +134,9 @@ class TestDiskBuilder(object):
return_value=self.bootloader_install
)
self.bootloader_config = mock.Mock()
self.bootloader_config.get_boot_cmdline = mock.Mock(
return_value='boot_cmdline'
)
kiwi.builder.disk.BootLoaderConfig = mock.MagicMock(
return_value=self.bootloader_config
)
@ -159,11 +162,6 @@ class TestDiskBuilder(object):
kiwi.builder.disk.SystemSetup = mock.Mock(
return_value=self.setup
)
self.boot_image_kiwi = mock.Mock()
self.boot_image_kiwi.boot_root_directory = 'boot_dir_kiwi'
kiwi.builder.disk.BootImageKiwi = mock.Mock(
return_value=self.boot_image_kiwi
)
self.install_image = mock.Mock()
kiwi.builder.disk.InstallImageBuilder = mock.Mock(
return_value=self.install_image
@ -336,15 +334,17 @@ class TestDiskBuilder(object):
'image', '.profile', '.kconfig', '.buildenv', 'var/cache/kiwi',
'boot/*', 'boot/.*', 'boot/efi/*', 'boot/efi/.*'
])
assert mock_open.call_args_list[0:3] == [
assert mock_open.call_args_list[0:4] == [
call('boot_dir/config.partids', 'w'),
call('root_dir/boot/mbrid', 'w'),
call('boot_dir/config.bootoptions', 'w'),
call('/dev/some-loop', 'wb')
]
assert self.file_mock.write.call_args_list == [
call('kiwi_BootPart="1"\n'),
call('kiwi_RootPart="1"\n'),
call('0x0f0f0f0f\n'),
call('boot_cmdline\n'),
call(bytes(b'\x0f\x0f\x0f\x0f')),
]
assert mock_command.call_args_list == [
@ -379,13 +379,6 @@ class TestDiskBuilder(object):
self.disk_builder.create_disk()
self.setup.create_recovery_archive.assert_called_once_with()
call = self.setup.export_modprobe_setup.call_args_list[0]
assert self.setup.export_modprobe_setup.call_args_list[0] == \
call('boot_dir')
call = self.setup.export_modprobe_setup.call_args_list[1]
assert self.setup.export_modprobe_setup.call_args_list[1] == \
call('boot_dir_kiwi')
self.setup.set_selinux_file_contexts.assert_called_once_with(
'/etc/selinux/targeted/contexts/files/file_contexts'
)
@ -423,10 +416,7 @@ class TestDiskBuilder(object):
'target_dir/LimeJeOS-openSUSE-13.2.x86_64-1.13.2.raw',
'/dev/boot-device'
)
self.boot_image_kiwi.prepare.assert_called_once_with()
self.boot_image_task.prepare.assert_called_once_with()
call = filesystem.create_on_device.call_args_list[0]
assert filesystem.create_on_device.call_args_list[0] == \
call(label='EFI')
@ -453,8 +443,8 @@ class TestDiskBuilder(object):
call('boot_dir/config.partids', 'w'),
call('root_dir/boot/mbrid', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w'),
call('/dev/some-loop', 'wb'),
call('boot_dir_kiwi/config.partids', 'w')
call('boot_dir/config.bootoptions', 'w'),
call('/dev/some-loop', 'wb')
]
assert self.file_mock.write.call_args_list == [
call('kiwi_BootPart="1"\n'),
@ -463,14 +453,13 @@ class TestDiskBuilder(object):
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
call('add_dracutmodules+=" kiwi-lib kiwi-repart "\n'),
call(bytes(b'\x0f\x0f\x0f\x0f')),
call('kiwi_BootPart="1"\n'),
call('kiwi_RootPart="1"\n')
call('omit_dracutmodules+=" kiwi-dump "\n'),
call('boot_cmdline\n'),
call(bytes(b'\x0f\x0f\x0f\x0f'))
]
assert mock_command.call_args_list == [
call(['cp', 'root_dir/recovery.partition.size', 'boot_dir']),
call(['mv', 'initrd', 'root_dir/boot/initramfs-1.2.3.img']),
call(['cp', 'root_dir/recovery.partition.size', 'boot_dir_kiwi'])
call(['mv', 'initrd', 'root_dir/boot/initramfs-1.2.3.img'])
]
self.setup.export_package_list.assert_called_once_with(
'target_dir'
@ -478,6 +467,7 @@ class TestDiskBuilder(object):
self.setup.export_package_verification.assert_called_once_with(
'target_dir'
)
print(self.boot_image_task.include_file.call_args_list)
assert self.boot_image_task.include_file.call_args_list == [
call('/config.partids'),
call('/recovery.partition.size')
@ -576,9 +566,9 @@ class TestDiskBuilder(object):
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
call('add_dracutmodules+=" kiwi-overlay kiwi-lib kiwi-repart "\n'),
call(b'\x0f\x0f\x0f\x0f'),
call('kiwi_BootPart="1"\n'),
call('kiwi_RootPart="1"\n')
call('omit_dracutmodules+=" kiwi-dump "\n'),
call('boot_cmdline\n'),
call(b'\x0f\x0f\x0f\x0f')
]
@patch('kiwi.builder.disk.FileSystem')
@ -724,7 +714,8 @@ class TestDiskBuilder(object):
'root_dir/etc/crypttab'
)
assert self.boot_image_task.include_file.call_args_list == [
call('/config.partids'), call('/etc/crypttab')
call('/config.partids'),
call('/etc/crypttab')
]
@patch('kiwi.builder.disk.FileSystem')

View File

@ -56,6 +56,9 @@ class TestInstallImageBuilder(object):
return_value=self.kernel
)
self.xml_state = mock.Mock()
self.xml_state.get_initrd_system = mock.Mock(
return_value='kiwi'
)
self.xml_state.xml_data.get_name = mock.Mock(
return_value='result-image'
)
@ -90,13 +93,15 @@ class TestInstallImageBuilder(object):
)
assert install_image.arch == 'ix86'
@patch('kiwi.builder.install.shutil.copy')
@patch('kiwi.builder.install.mkdtemp')
@patch_open
@patch('kiwi.builder.install.Command.run')
@patch('kiwi.builder.install.Iso.create_hybrid')
@patch('kiwi.builder.install.Defaults.get_grub_boot_directory_name')
def test_create_install_iso(
self, mock_grub_dir, mock_hybrid, mock_command, mock_open, mock_dtemp
self, mock_grub_dir, mock_hybrid, mock_command, mock_open,
mock_dtemp, mock_copy
):
tmpdir_name = ['temp-squashfs', 'temp_media_dir']
@ -118,9 +123,12 @@ class TestInstallImageBuilder(object):
self.checksum.md5.assert_called_once_with(
'temp-squashfs/result-image.md5'
)
mock_copy.assert_called_once_with(
'root_dir/boot/initrd', 'temp_media_dir/initrd.system_image'
)
assert mock_open.call_args_list == [
call('initrd_dir/config.vmxsystem', 'w'),
call('temp_media_dir/config.isoclient', 'w')
call('temp_media_dir/config.isoclient', 'w'),
call('initrd_dir/config.vmxsystem', 'w')
]
assert file_mock.write.call_args_list == [
call('IMAGE="result-image.raw"\n'),
@ -141,7 +149,7 @@ class TestInstallImageBuilder(object):
call(), call()
]
self.boot_image_task.create_initrd.assert_called_once_with(
self.mbrid
self.mbrid, 'initrd_kiwi_install'
)
self.kernel.copy_kernel.assert_called_once_with(
'temp_media_dir/boot/x86_64/loader', '/linux'
@ -170,6 +178,28 @@ class TestInstallImageBuilder(object):
'uefi'
)
tmpdir_name = ['temp-squashfs', 'temp_media_dir']
file_mock.write.reset_mock()
mock_open.reset_mock()
self.install_image.initrd_system = 'dracut'
self.install_image.create_install_iso()
self.boot_image_task.include_file.assert_called_once_with(
'/config.bootoptions'
)
assert mock_open.call_args_list == [
call('temp_media_dir/config.isoclient', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w')
]
assert file_mock.write.call_args_list == [
call('IMAGE="result-image.raw"\n'),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
call('add_dracutmodules+=" kiwi-lib kiwi-dump "\n'),
call('omit_dracutmodules+=" kiwi-overlay kiwi-repart "\n')
]
@patch('kiwi.builder.install.mkdtemp')
@patch_open
@patch('kiwi.builder.install.Command.run')
@ -277,7 +307,7 @@ class TestInstallImageBuilder(object):
'tmpdir', '/pxeboot.xen.gz'
)
self.boot_image_task.create_initrd.assert_called_once_with(
self.mbrid
self.mbrid, 'initrd_kiwi_install'
)
assert mock_command.call_args_list[1] == call(
['mv', 'initrd', 'tmpdir/pxeboot.initrd.xz']
@ -289,12 +319,37 @@ class TestInstallImageBuilder(object):
'tmpdir', xz_options=None
)
file_mock.write.reset_mock()
mock_open.reset_mock()
self.install_image.initrd_system = 'dracut'
self.install_image.create_install_pxe_archive()
assert mock_open.call_args_list == [
call('tmpdir/result-image.append', 'w'),
call('root_dir/etc/dracut.conf.d/02-kiwi.conf', 'w')
]
assert file_mock.write.call_args_list == [
call('pxe=1 custom_kernel_options\n'),
call('hostonly="no"\n'),
call('dracut_rescue_image="no"\n'),
call('add_dracutmodules+=" kiwi-lib kiwi-dump "\n'),
call('omit_dracutmodules+=" kiwi-overlay kiwi-repart "\n')
]
@patch('kiwi.builder.install.Path.wipe')
def test_destructor(self, mock_wipe):
@patch('os.path.exists')
@patch('os.remove')
def test_destructor(self, mock_remove, mock_exists, mock_wipe):
mock_exists.return_value = True
self.install_image.initrd_system = 'dracut'
self.install_image.pxe_dir = 'pxe-dir'
self.install_image.media_dir = 'media-dir'
self.install_image.squashed_contents = 'squashed-dir'
self.install_image.__del__()
mock_remove.assert_called_once_with(
'root_dir/etc/dracut.conf.d/02-kiwi.conf'
)
assert mock_wipe.call_args_list == [
call('media-dir'), call('pxe-dir'), call('squashed-dir')
]