diff --git a/dracut/modules.d/90kiwi-repart/kiwi-repart-disk.sh b/dracut/modules.d/90kiwi-repart/kiwi-repart-disk.sh index 8caf53ff..2070c6c1 100755 --- a/dracut/modules.d/90kiwi-repart/kiwi-repart-disk.sh +++ b/dracut/modules.d/90kiwi-repart/kiwi-repart-disk.sh @@ -29,9 +29,6 @@ function initialize { root_device=${root#block:} export root_device - swapsize=$(get_requested_swap_size) - export swapsize - disk_free_mbytes=$(( $(get_free_disk_bytes "${disk}") / 1048576 )) @@ -43,26 +40,6 @@ function initialize { export disk_root_mbytes } -function get_requested_swap_size { - declare kiwi_oemswapMB=${kiwi_oemswapMB} - declare kiwi_oemswap=${kiwi_oemswap} - local swapsize - if [ -n "${kiwi_oemswapMB}" ];then - # swap size configured by kiwi description - swapsize=${kiwi_oemswapMB} - else - # default swap size is twice times ramsize - swapsize=$(( - $(grep MemTotal: /proc/meminfo | tr -dc '0-9') * 2 / 1024 - )) - fi - if [ ! "${kiwi_oemswap}" = "true" ];then - # no swap wanted by kiwi description - swapsize=0 - fi - echo ${swapsize} -} - function deactivate_device_mappings { if lvm_system;then deactivate_volume_group @@ -95,22 +72,18 @@ function repart_standard_disk { declare kiwi_RootPart=${kiwi_RootPart} if [ -z "${kiwi_oemrootMB}" ];then local disk_have_root_system_mbytes=$(( - disk_root_mbytes + disk_free_mbytes - swapsize + disk_root_mbytes + disk_free_mbytes )) - local min_additional_mbytes=${swapsize} + local min_additional_mbytes=5 else local disk_have_root_system_mbytes=${kiwi_oemrootMB} local min_additional_mbytes=$(( - swapsize + kiwi_oemrootMB - disk_root_mbytes + kiwi_oemrootMB - disk_root_mbytes )) fi if [ "${min_additional_mbytes}" -lt 5 ];then min_additional_mbytes=5 fi - local new_parts=0 - if [ "${kiwi_oemswap}" = "true" ];then - new_parts=$((new_parts + 1)) - fi # check if we can repart this disk if ! check_repart_possible \ ${disk_root_mbytes} ${disk_free_mbytes} ${min_additional_mbytes} @@ -122,7 +95,7 @@ function repart_standard_disk { # repart root partition local command_query local root_part_size=+${disk_have_root_system_mbytes}M - if [ -z "${kiwi_oemrootMB}" ] && [ ${new_parts} -eq 0 ];then + if [ -z "${kiwi_oemrootMB}" ];then # no new parts and no rootsize limit, use rest disk space root_part_size=. fi @@ -132,8 +105,6 @@ function repart_standard_disk { " create_parted_partitions \ "${disk}" "${command_query}" - # add swap partition - create_swap_partition "$new_parts" # finalize table changes finalize_disk_repart } @@ -153,13 +124,13 @@ function repart_lvm_disk { local disk_have_root_system_mbytes=$(( disk_root_mbytes + disk_free_mbytes )) - local min_additional_mbytes=${swapsize} + local min_additional_mbytes=5 else local disk_have_root_system_mbytes=$(( - kiwi_oemrootMB + swapsize + kiwi_oemrootMB )) local min_additional_mbytes=$(( - swapsize + kiwi_oemrootMB - disk_root_mbytes + kiwi_oemrootMB - disk_root_mbytes )) fi if [ "${min_additional_mbytes}" -lt 5 ];then @@ -193,38 +164,6 @@ function repart_lvm_disk { finalize_disk_repart } -function create_swap_volume { - if [ "${swapsize}" -gt "0" ];then - if create_volume "LVSwap" "${swapsize}";then - set_swap_map "$(get_volume_path_for_volume "LVSwap")" - fi - fi -} - -function create_swap_partition { - declare kiwi_oemrootMB=${kiwi_oemrootMB} - declare kiwi_RootPart=${kiwi_RootPart} - local new_parts=$1 - if [ "${swapsize}" -gt "0" ];then - local swap_part=$((kiwi_RootPart + 1)) - local swap_part_size=+${swapsize}M - if [ -z "${kiwi_oemrootMB}" ] && [ "${new_parts}" -eq "1" ];then - # exactly one new part and no rootsize limit, use rest disk space - swap_part_size=. - fi - command_query=" - n p:lxswap ${swap_part} . ${swap_part_size} - t ${swap_part} 82 - " - create_parted_partitions \ - "${disk}" "${command_query}" - set_swap_map \ - "$(get_persistent_device_from_unix_node \ - "$(get_partition_node_name "${disk}" "${swap_part}")" "by-id" - )" - fi -} - function check_repart_possible { declare kiwi_oemrootMB=${kiwi_oemrootMB} local disk_root_mbytes=$1 @@ -242,16 +181,13 @@ function check_repart_possible { fi fi if [ "${min_additional_mbytes}" -gt "${disk_free_mbytes}" ];then - # Requested sizes for root and swap exceeds free space on disk + # Requested size for root exceeds free space on disk local requested_size if [ -n "${kiwi_oemrootMB}" ];then requested_size="root:($((kiwi_oemrootMB - disk_root_mbytes)) MB)" else requested_size="root:(keep)" fi - if [ ${swapsize} -gt 0 ];then - requested_size="${requested_size}, swap:(${swapsize} MB)" - fi warn "Requested OEM systemsize exceeds free space on the disk:" warn "Disk won't be re-partitioned !" echo @@ -334,11 +270,7 @@ fi if lvm_system; then resize_pyhiscal_volumes activate_volume_group - create_swap_volume resize_lvm_volumes_and_filesystems else resize_filesystem "$(get_root_map)" fi - -# create swap space -create_swap "$(get_swap_map)" diff --git a/dracut/modules.d/90kiwi-repart/kiwi-update-fstab.sh b/dracut/modules.d/90kiwi-repart/kiwi-update-fstab.sh deleted file mode 100755 index 327a5e99..00000000 --- a/dracut/modules.d/90kiwi-repart/kiwi-update-fstab.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh -type merge_swap_to_fstab >/dev/null 2>&1 || . /lib/kiwi-filesystem-lib.sh - -merge_swap_to_fstab diff --git a/dracut/modules.d/90kiwi-repart/module-setup.sh b/dracut/modules.d/90kiwi-repart/module-setup.sh index a1a54257..01021fd7 100755 --- a/dracut/modules.d/90kiwi-repart/module-setup.sh +++ b/dracut/modules.d/90kiwi-repart/module-setup.sh @@ -20,6 +20,5 @@ installkernel() { install() { declare moddir=${moddir} inst_hook pre-mount 20 "${moddir}/kiwi-repart-disk.sh" - inst_hook pre-pivot 20 "${moddir}/kiwi-update-fstab.sh" dracut_need_initqueue } diff --git a/dracut/modules.d/99kiwi-lib/kiwi-filesystem-lib.sh b/dracut/modules.d/99kiwi-lib/kiwi-filesystem-lib.sh index c820fd93..c8964644 100644 --- a/dracut/modules.d/99kiwi-lib/kiwi-filesystem-lib.sh +++ b/dracut/modules.d/99kiwi-lib/kiwi-filesystem-lib.sh @@ -21,6 +21,9 @@ function resize_filesystem { resize_fs="${resize_fs} xfs_growfs ${mpoint}" resize_fs="${resize_fs};umount ${mpoint} && rmdir ${mpoint}" ;; + swap) + resize_fs="mkswap ${device} --label SWAP" + ;; *) # don't know how to resize this filesystem warn "Don't know how to resize ${fstype}... skipped" @@ -97,27 +100,6 @@ function probe_filesystem { echo ${fstype} } -function create_swap { - # """ - # create swap signature on device and create a - # fstab reference file which is used by a pre-pivot - # hook to update the system fstab - # """ - local device=$1 - local swap_label="SWAP" - test -n "${device}" || return - if ! mkswap "${device}" --label "${swap_label}" 1>&2;then - die "Failed to create swap signature" - fi - echo "LABEL=${swap_label} swap swap defaults 0 0" > /fstab.swap -} - -function merge_swap_to_fstab { - if [ -f /sysroot/etc/fstab ];then - test -f /fstab.swap && cat /fstab.swap >> /sysroot/etc/fstab - fi -} - #====================================== # Methods considered private #-------------------------------------- diff --git a/dracut/modules.d/99kiwi-lib/kiwi-lib.sh b/dracut/modules.d/99kiwi-lib/kiwi-lib.sh index 63871681..d23577d3 100644 --- a/dracut/modules.d/99kiwi-lib/kiwi-lib.sh +++ b/dracut/modules.d/99kiwi-lib/kiwi-lib.sh @@ -15,19 +15,10 @@ function set_root_map { export root_map } -function set_swap_map { - swap_map=$1 - export swap_map -} - function get_root_map { echo "${root_map}" } -function get_swap_map { - echo "${swap_map}" -} - function lookup_disk_device_from_root { declare root=${root} declare kiwi_RaidDev=${kiwi_RaidDev} diff --git a/kiwi/builder/disk.py b/kiwi/builder/disk.py index 73b82b0d..7ced0b97 100644 --- a/kiwi/builder/disk.py +++ b/kiwi/builder/disk.py @@ -106,6 +106,7 @@ class DiskBuilder: self.target_removable = xml_state.build_type.get_target_removable() self.root_filesystem_is_multipath = \ xml_state.get_oemconfig_oem_multipath_scan() + self.swap_mbytes = xml_state.get_oemconfig_swap_mbytes() self.disk_setup = DiskSetup( xml_state, root_dir ) @@ -338,7 +339,8 @@ class DiskBuilder: self.persistency_type, self.requested_filesystem ) self.system = volume_manager - device_map['root'] = volume_manager.get_device()['root'] + device_map['root'] = volume_manager.get_device().get('root') + device_map['swap'] = volume_manager.get_device().get('swap') else: log.info( 'Creating root(%s) filesystem on %s', @@ -358,6 +360,15 @@ class DiskBuilder: ) self.system = filesystem + # create swap on current root device if requested + if self.swap_mbytes: + swap = FileSystem( + 'swap', device_map['swap'] + ) + swap.create_on_device( + label='SWAP' + ) + # create a random image identifier self.mbrid = SystemIdentifier() self.mbrid.calculate_id() @@ -715,6 +726,13 @@ class DiskBuilder: ) disksize_used_mbytes += partition_mbsize + if self.swap_mbytes and not self.volume_manager_name: + log.info('--> creating SWAP partition') + self.disk.create_swap_partition( + self.swap_mbytes + ) + disksize_used_mbytes += self.swap_mbytes + if self.spare_part_mbsize and not self.spare_part_is_last: log.info('--> creating spare partition') self.disk.create_spare_partition( @@ -850,6 +868,15 @@ class DiskBuilder: self._add_generic_fstab_entry( device_map['spare'].get_device(), self.spare_part_mountpoint ) + if 'swap' in device_map: + if self.volume_manager_name: + self._add_simple_fstab_entry( + device_map['swap'].get_device(), 'swap', 'swap' + ) + else: + self._add_generic_fstab_entry( + device_map['swap'].get_device(), 'swap' + ) if 'boot' in device_map: if self.bootloader == 'grub2_s390x_emu': boot_mount_point = '/boot/zipl' @@ -866,6 +893,21 @@ class DiskBuilder: self.generic_fstab_entries ) + def _add_simple_fstab_entry( + self, device, mount_point, filesystem, options=None, check='0 0' + ): + if not options: + options = ['defaults'] + fstab_entry = ' '.join( + [ + device, mount_point, filesystem, ','.join(options), check + ] + ) + if fstab_entry not in self.generic_fstab_entries: + self.generic_fstab_entries.append( + fstab_entry + ) + def _add_generic_fstab_entry( self, device, mount_point, options=None, check='0 0' ): diff --git a/kiwi/defaults.py b/kiwi/defaults.py index 2a87e45e..69354607 100644 --- a/kiwi/defaults.py +++ b/kiwi/defaults.py @@ -68,6 +68,13 @@ class Defaults: """ return 256 + @staticmethod + def get_swapsize_mbytes(): + """ + Provides swapsize in MB + """ + return 128 + @staticmethod def get_xz_compression_options(): """ diff --git a/kiwi/filesystem/__init__.py b/kiwi/filesystem/__init__.py index a9df2ecf..c4291c17 100644 --- a/kiwi/filesystem/__init__.py +++ b/kiwi/filesystem/__init__.py @@ -16,17 +16,18 @@ # along with kiwi. If not, see # # project -from .ext2 import FileSystemExt2 -from .ext3 import FileSystemExt3 -from .ext4 import FileSystemExt4 -from .btrfs import FileSystemBtrfs -from .xfs import FileSystemXfs -from .fat16 import FileSystemFat16 -from .fat32 import FileSystemFat32 -from .squashfs import FileSystemSquashFs -from .clicfs import FileSystemClicFs +from kiwi.filesystem.ext2 import FileSystemExt2 +from kiwi.filesystem.ext3 import FileSystemExt3 +from kiwi.filesystem.ext4 import FileSystemExt4 +from kiwi.filesystem.btrfs import FileSystemBtrfs +from kiwi.filesystem.xfs import FileSystemXfs +from kiwi.filesystem.fat16 import FileSystemFat16 +from kiwi.filesystem.fat32 import FileSystemFat32 +from kiwi.filesystem.squashfs import FileSystemSquashFs +from kiwi.filesystem.clicfs import FileSystemClicFs +from kiwi.filesystem.swap import FileSystemSwap -from ..exceptions import ( +from kiwi.exceptions import ( KiwiFileSystemSetupError ) @@ -77,6 +78,10 @@ class FileSystem: return FileSystemClicFs( device_provider, root_dir, custom_args ) + elif name == 'swap': + return FileSystemSwap( + device_provider, root_dir, custom_args + ) else: raise KiwiFileSystemSetupError( 'Support for %s filesystem not implemented' % name diff --git a/kiwi/filesystem/swap.py b/kiwi/filesystem/swap.py new file mode 100644 index 00000000..f2221c6a --- /dev/null +++ b/kiwi/filesystem/swap.py @@ -0,0 +1,39 @@ +# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved. +# +# This file is part of kiwi. +# +# kiwi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# kiwi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with kiwi. If not, see + +# project +from kiwi.filesystem.base import FileSystemBase +from kiwi.command import Command + + +class FileSystemSwap(FileSystemBase): + """ + **Implements creation of swap space** + """ + def create_on_device(self, label=None): + """ + Create swap space on block device + + :param string label: label name + """ + device = self.device_provider.get_device() + if label: + self.custom_args['create_options'].append('-L') + self.custom_args['create_options'].append(label) + Command.run( + ['mkswap'] + self.custom_args['create_options'] + [device] + ) diff --git a/kiwi/partitioner/dasd.py b/kiwi/partitioner/dasd.py index ceaddf0b..6f15e475 100644 --- a/kiwi/partitioner/dasd.py +++ b/kiwi/partitioner/dasd.py @@ -38,6 +38,7 @@ class PartitionerDasd(PartitionerBase): self.flag_map = { 'f.active': None, 't.linux': '1', + 't.swap': '1', 't.lvm': '1', 't.raid': '1', 't.efi': None, diff --git a/kiwi/partitioner/gpt.py b/kiwi/partitioner/gpt.py index 40569c3f..8ef66fd0 100644 --- a/kiwi/partitioner/gpt.py +++ b/kiwi/partitioner/gpt.py @@ -42,6 +42,7 @@ class PartitionerGpt(PartitionerBase): 'f.active': None, 't.csm': 'EF02', 't.linux': '8300', + 't.swap': '8200', 't.lvm': '8E00', 't.raid': 'FD00', 't.efi': 'EF00' diff --git a/kiwi/partitioner/msdos.py b/kiwi/partitioner/msdos.py index ed98694a..a205497b 100644 --- a/kiwi/partitioner/msdos.py +++ b/kiwi/partitioner/msdos.py @@ -42,6 +42,7 @@ class PartitionerMsDos(PartitionerBase): self.flag_map = { 'f.active': True, 't.linux': '83', + 't.swap': '82', 't.lvm': '8e', 't.raid': 'fd', 't.efi': None, diff --git a/kiwi/storage/disk.py b/kiwi/storage/disk.py index d29d5521..14b4f6cf 100644 --- a/kiwi/storage/disk.py +++ b/kiwi/storage/disk.py @@ -180,6 +180,18 @@ class Disk(DeviceProvider): self._add_to_map('spare') self._add_to_public_id_map('kiwi_SparePart') + def create_swap_partition(self, mbsize): + """ + Create swap partition + + Populates kiwi_SwapPart(id) + + :param int mbsize: partition size + """ + self.partitioner.create('p.swap', mbsize, 't.swap') + self._add_to_map('swap') + self._add_to_public_id_map('kiwi_SwapPart') + def create_efi_csm_partition(self, mbsize): """ Create EFI bios grub partition diff --git a/kiwi/storage/setup.py b/kiwi/storage/setup.py index 88149b88..684ff978 100644 --- a/kiwi/storage/setup.py +++ b/kiwi/storage/setup.py @@ -39,6 +39,7 @@ class DiskSetup: """ def __init__(self, xml_state, root_dir): self.root_filesystem_is_overlay = xml_state.build_type.get_overlayroot() + self.swap_mbytes = xml_state.get_oemconfig_swap_mbytes() self.configured_size = xml_state.get_build_type_size() self.build_type_name = xml_state.get_build_type_name() self.filesystem = xml_state.build_type.get_filesystem() @@ -62,7 +63,7 @@ class DiskSetup: self.root_dir = root_dir self.xml_state = xml_state - def get_disksize_mbytes(self): + def get_disksize_mbytes(self): # noqa C901 """ Precalculate disk size requirements in mbytes @@ -94,6 +95,11 @@ class DiskSetup: log.info( '--> volume(s) size setup adding %s MB', volume_mbytes ) + elif self.swap_mbytes: + calculated_disk_mbytes += self.swap_mbytes + log.info( + '--> swap partition adding %s MB', self.swap_mbytes + ) legacy_bios_mbytes = self.firmware.get_legacy_bios_partition_size() if legacy_bios_mbytes: diff --git a/kiwi/system/profile.py b/kiwi/system/profile.py index 0c788456..bb92a535 100644 --- a/kiwi/system/profile.py +++ b/kiwi/system/profile.py @@ -117,8 +117,16 @@ class Profile: self._text(oemconfig.get_oem_swapsize()) self.dot_profile['kiwi_oemrootMB'] = \ self._text(oemconfig.get_oem_systemsize()) + + # kiwi_oemconfig is used in older boot code to run the swap + # creation and setup code at boot time. This version of kiwi + # handles swap as part of the build process and therefore + # has to disable swap handling such that we stay backward + # compatbile for some time. + # OBSOLETE: to be removed at: 2020-05-25 self.dot_profile['kiwi_oemswap'] = \ - self._text(oemconfig.get_oem_swap()) + self._text(False) + self.dot_profile['kiwi_oempartition_install'] = \ self._text(oemconfig.get_oem_partition_install()) self.dot_profile['kiwi_oemdevicefilter'] = \ diff --git a/kiwi/volume_manager/base.py b/kiwi/volume_manager/base.py index b181f88d..ef296942 100644 --- a/kiwi/volume_manager/base.py +++ b/kiwi/volume_manager/base.py @@ -214,7 +214,7 @@ class VolumeManagerBase(DeviceProvider): Implements creation of volume paths in the given root directory """ for volume in self.volumes: - if volume.realpath and not volume.realpath == os.sep: + if volume.realpath and volume.realpath not in ['/', 'swap']: volume_image_path = os.path.normpath( self.root_dir + os.sep + volume.realpath ) @@ -273,6 +273,10 @@ class VolumeManagerBase(DeviceProvider): """ [size_type, mbsize] = volume.size.split(':') lookup_path = volume.realpath + lookup_abspath = os.path.normpath( + os.sep.join([self.root_dir, lookup_path]) + ) + mbsize = int(mbsize) if image_type and image_type == 'oem': # only for vmx types we need to create the volumes in the @@ -281,9 +285,9 @@ class VolumeManagerBase(DeviceProvider): # image. Therefore the requested size is set to null # and we add the required minimum size to hold the data size_type = 'freespace' - mbsize = 0 + mbsize = Defaults.get_min_volume_mbytes() - if size_type == 'freespace': + if size_type == 'freespace' and os.path.exists(lookup_abspath): exclude_paths = [] for volume in all_volumes: volume_path = volume.realpath @@ -300,11 +304,9 @@ class VolumeManagerBase(DeviceProvider): os.path.normpath(self.root_dir + os.sep + volume_path) ) - volume_size = SystemSize( - os.path.normpath(self.root_dir + os.sep + lookup_path) - ) - mbsize = int(mbsize) + \ - Defaults.get_min_volume_mbytes() + volume_size = SystemSize(lookup_abspath) + if mbsize != Defaults.get_min_volume_mbytes(): + mbsize += Defaults.get_min_volume_mbytes() mbsize += volume_size.customize( volume_size.accumulate_mbyte_file_sizes(exclude_paths), filesystem_name diff --git a/kiwi/volume_manager/lvm.py b/kiwi/volume_manager/lvm.py index 4aaf92d1..1133dba4 100644 --- a/kiwi/volume_manager/lvm.py +++ b/kiwi/volume_manager/lvm.py @@ -75,6 +75,11 @@ class VolumeManagerLVM(VolumeManagerBase): # root partition device from the disk. Therefore use # the same key to put them on the same level volume_name = 'root' + if volume_name == 'LVSwap': + # LVSwap volume device takes precedence over the + # swap partition device from the disk. Therefore use + # the same key to put them on the same level + volume_name = 'swap' device_map[volume_name] = MappedDevice( device=volume_node, device_provider=self ) @@ -171,12 +176,13 @@ class VolumeManagerLVM(VolumeManagerBase): self.root_dir, volume ) self._add_to_volume_map(volume.name) - self._create_filesystem( - volume.name, volume.label, filesystem_name - ) - self._add_to_mount_list( - volume.name, volume.realpath - ) + if volume.name != 'LVSwap': + self._create_filesystem( + volume.name, volume.label, filesystem_name + ) + self._add_to_mount_list( + volume.name, volume.realpath + ) if canonical_volume_list.full_size_volume: full_size_volume = canonical_volume_list.full_size_volume diff --git a/kiwi/xml_state.py b/kiwi/xml_state.py index a3f87b3e..973cec6d 100644 --- a/kiwi/xml_state.py +++ b/kiwi/xml_state.py @@ -782,6 +782,27 @@ class XMLState: if oemconfig and oemconfig.get_oem_multipath_scan(): return oemconfig.get_oem_multipath_scan()[0] + def get_oemconfig_swap_mbytes(self): + """ + Return swapsize in MB if requested or None + + Operates on the value of oem-swap and if set to true + returns the given size or the default value. + + :return: Content of section value or default + + :rtype: int + """ + oemconfig = self.get_build_type_oemconfig_section() + if oemconfig and oemconfig.get_oem_swap(): + swap_requested = oemconfig.get_oem_swap()[0] + if swap_requested: + swapsize = oemconfig.get_oem_swapsize() + if swapsize: + return swapsize[0] + else: + return Defaults.get_swapsize_mbytes() + def get_build_type_containerconfig_section(self): """ First containerconfig section from the build type section @@ -1045,7 +1066,7 @@ class XMLState: container_config_section.set_labels(labels) - def get_volumes(self): + def get_volumes(self): # noqa C901 """ List of configured systemdisk volumes. @@ -1080,6 +1101,7 @@ class XMLState: """ volume_type_list = [] systemdisk_section = self.get_build_type_system_disk_section() + swap_mbytes = self.get_oemconfig_swap_mbytes() if not systemdisk_section: return volume_type_list @@ -1185,6 +1207,19 @@ class XMLState: ) ) + if swap_mbytes: + volume_type_list.append( + volume_type( + name='LVSwap', + size='size:{0}'.format(swap_mbytes), + fullsize=False, + mountpoint=None, + realpath='swap', + label='SWAP', + attributes=[] + ) + ) + return volume_type_list def get_volume_management(self): diff --git a/test/data/example_config.xml b/test/data/example_config.xml index f96a358c..0c838e36 100644 --- a/test/data/example_config.xml +++ b/test/data/example_config.xml @@ -51,6 +51,7 @@ 2048 true + 42 false diff --git a/test/data/example_disk_config.xml b/test/data/example_disk_config.xml index c27d60ee..a6c77e12 100644 --- a/test/data/example_disk_config.xml +++ b/test/data/example_disk_config.xml @@ -21,6 +21,7 @@ false + true diff --git a/test/data/example_disk_size_config.xml b/test/data/example_disk_size_config.xml index 1b6cb801..15b687c1 100644 --- a/test/data/example_disk_size_config.xml +++ b/test/data/example_disk_size_config.xml @@ -22,6 +22,7 @@ true 200 + true diff --git a/test/data/example_dot_profile_config.xml b/test/data/example_dot_profile_config.xml index 2571f643..408c4b13 100644 --- a/test/data/example_dot_profile_config.xml +++ b/test/data/example_dot_profile_config.xml @@ -28,6 +28,7 @@ + true 2048 true false diff --git a/test/unit/builder/disk_test.py b/test/unit/builder/disk_test.py index d8238816..391da88d 100644 --- a/test/unit/builder/disk_test.py +++ b/test/unit/builder/disk_test.py @@ -44,6 +44,7 @@ class TestDiskBuilder: ) self.device_map = { 'root': MappedDevice('/dev/root-device', mock.Mock()), + 'swap': MappedDevice('/dev/swap-device', mock.Mock()), 'readonly': MappedDevice('/dev/readonly-root-device', mock.Mock()), 'boot': MappedDevice('/dev/boot-device', mock.Mock()), 'prep': MappedDevice('/dev/prep-device', mock.Mock()), @@ -299,6 +300,9 @@ class TestDiskBuilder: self.disk.create_boot_partition.assert_called_once_with( self.disk_setup.boot_partition_size() ) + self.disk.create_swap_partition.assert_called_once_with( + 128 + ) self.disk.create_prep_partition.assert_called_once_with( self.firmware.get_prep_partition_size() ) @@ -713,7 +717,8 @@ class TestDiskBuilder: volume_manager = mock.Mock() volume_manager.get_device = mock.Mock( return_value={ - 'root': MappedDevice('/dev/systemVG/LVRoot', mock.Mock()) + 'root': MappedDevice('/dev/systemVG/LVRoot', mock.Mock()), + 'swap': MappedDevice('/dev/systemVG/LVSwap', mock.Mock()) } ) volume_manager.get_fstab = mock.Mock( @@ -744,6 +749,7 @@ class TestDiskBuilder: [ 'fstab_volume_entries', 'UUID=blkid_result / blkid_result_fs ro 0 0', + '/dev/systemVG/LVSwap swap swap defaults 0 0', 'UUID=blkid_result /boot blkid_result_fs defaults 0 0', 'UUID=blkid_result /boot/efi blkid_result_fs defaults 0 0' ] @@ -752,6 +758,7 @@ class TestDiskBuilder: [ 'fstab_volume_entries', 'UUID=blkid_result / blkid_result_fs ro 0 0', + '/dev/systemVG/LVSwap swap swap defaults 0 0', 'UUID=blkid_result /boot blkid_result_fs defaults 0 0', 'UUID=blkid_result /boot/efi blkid_result_fs defaults 0 0' ] diff --git a/test/unit/filesystem/init_test.py b/test/unit/filesystem/init_test.py index 6bbe2618..445130f2 100644 --- a/test/unit/filesystem/init_test.py +++ b/test/unit/filesystem/init_test.py @@ -65,3 +65,9 @@ class TestFileSystem: provider = mock.Mock() FileSystem('clicfs', provider, 'root_dir') mock_clicfs.assert_called_once_with(provider, 'root_dir', None) + + @patch('kiwi.filesystem.FileSystemSwap') + def test_filesystem_swap(self, mock_swap): + provider = mock.Mock() + FileSystem('swap', provider) + mock_swap.assert_called_once_with(provider, None, None) diff --git a/test/unit/filesystem/swap_test.py b/test/unit/filesystem/swap_test.py new file mode 100644 index 00000000..d74df625 --- /dev/null +++ b/test/unit/filesystem/swap_test.py @@ -0,0 +1,26 @@ +from mock import patch + +import mock + +from kiwi.filesystem.swap import FileSystemSwap + + +class TestFileSystemSwap: + @patch('os.path.exists') + def setup(self, mock_exists): + mock_exists.return_value = True + provider = mock.Mock() + provider.get_device = mock.Mock( + return_value='/dev/foo' + ) + self.swap = FileSystemSwap(provider, 'root_dir') + self.swap.setup_mountpoint = mock.Mock( + return_value='some-mount-point' + ) + + @patch('kiwi.filesystem.swap.Command.run') + def test_create_on_device(self, mock_command): + self.swap.create_on_device('label') + call = mock_command.call_args_list[0] + assert mock_command.call_args_list[0] == \ + call(['mkswap', '-L', 'label', '/dev/foo']) diff --git a/test/unit/storage/disk_test.py b/test/unit/storage/disk_test.py index 5ad68352..c4f766dd 100644 --- a/test/unit/storage/disk_test.py +++ b/test/unit/storage/disk_test.py @@ -118,6 +118,13 @@ class TestDisk: ) assert self.disk.public_partition_id_map['kiwi_SparePart'] == 1 + def test_create_swap_partition(self): + self.disk.create_swap_partition(42) + self.partitioner.create.assert_called_once_with( + 'p.swap', 42, 't.swap' + ) + assert self.disk.public_partition_id_map['kiwi_SwapPart'] == 1 + @patch('kiwi.storage.disk.Command.run') def test_create_prep_partition(self, mock_command): self.disk.create_prep_partition(8) diff --git a/test/unit/storage/setup_test.py b/test/unit/storage/setup_test.py index 1d1b6902..424b2de7 100644 --- a/test/unit/storage/setup_test.py +++ b/test/unit/storage/setup_test.py @@ -156,6 +156,7 @@ class TestDiskSetup: Defaults.get_default_legacy_bios_mbytes() + \ Defaults.get_default_efi_boot_mbytes() + \ Defaults.get_default_boot_mbytes() + \ + Defaults.get_swapsize_mbytes() + \ root_size + 42 + \ 200 * 1.7 diff --git a/test/unit/system/profile_test.py b/test/unit/system/profile_test.py index ffca91e0..7188d4c6 100644 --- a/test/unit/system/profile_test.py +++ b/test/unit/system/profile_test.py @@ -31,6 +31,7 @@ class TestProfile: 'kiwi_Volume_3': 'etc_volume|freespace:30|etc', 'kiwi_Volume_4': 'bin_volume|size:all|/usr/bin', 'kiwi_Volume_5': 'usr_bin|freespace:30|usr/bin', + 'kiwi_Volume_6': 'LVSwap|size:128|', 'kiwi_bootkernel': None, 'kiwi_bootloader': 'grub2', 'kiwi_bootprofile': None, @@ -73,9 +74,9 @@ class TestProfile: 'kiwi_oemsilentboot': None, 'kiwi_oemsilentinstall': None, 'kiwi_oemsilentverify': None, - 'kiwi_oemskipverify': None, + 'kiwi_oemskipverify': 'true', 'kiwi_oemswapMB': None, - 'kiwi_oemswap': 'true', + 'kiwi_oemswap': None, 'kiwi_oemtitle': 'schäfer', 'kiwi_oemunattended_id': None, 'kiwi_oemunattended': None, @@ -105,6 +106,7 @@ class TestProfile: "kiwi_Volume_3='etc_volume|freespace:30|etc'", "kiwi_Volume_4='bin_volume|size:all|/usr/bin'", "kiwi_Volume_5='usr_bin|freespace:30|usr/bin'", + "kiwi_Volume_6='LVSwap|size:128|'", "kiwi_bootloader='grub2'", "kiwi_cmdline='splash'", "kiwi_displayname='schäfer'", @@ -119,7 +121,7 @@ class TestProfile: "kiwi_lvm='true'", "kiwi_lvmgroup='systemVG'", "kiwi_oemrootMB='2048'", - "kiwi_oemswap='true'", + "kiwi_oemskipverify='true'", "kiwi_oemtitle='schäfer'", "kiwi_ramonly='true'", "kiwi_splash_theme='openSUSE'", diff --git a/test/unit/volume_manager/base_test.py b/test/unit/volume_manager/base_test.py index 7fa56944..b0a87128 100644 --- a/test/unit/volume_manager/base_test.py +++ b/test/unit/volume_manager/base_test.py @@ -99,7 +99,11 @@ class TestVolumeManagerBase: assert volume_list.full_size_volume.name == 'LVRoot' @patch('kiwi.volume_manager.base.SystemSize') - def test_get_volume_mbsize(self, mock_size): + @patch('os.path.exists') + def test_get_volume_mbsize( + self, mock_os_path_exists, mock_size + ): + mock_os_path_exists.return_value = True size = Mock() size.customize = Mock( return_value=42 @@ -111,7 +115,11 @@ class TestVolumeManagerBase: ) == 272 @patch('kiwi.volume_manager.base.SystemSize') - def test_get_volume_mbsize_for_oem_type(self, mock_size): + @patch('os.path.exists') + def test_get_volume_mbsize_for_oem_type( + self, mock_os_path_exists, mock_size + ): + mock_os_path_exists.return_value = True size = Mock() size.customize = Mock( return_value=42 @@ -123,7 +131,11 @@ class TestVolumeManagerBase: ) == 72 @patch('kiwi.volume_manager.base.SystemSize') - def test_get_volume_mbsize_nested_volumes(self, mock_size): + @patch('os.path.exists') + def test_get_volume_mbsize_nested_volumes( + self, mock_os_path_exists, mock_size + ): + mock_os_path_exists.return_value = True size = Mock() size.customize = Mock( return_value=42 @@ -148,7 +160,11 @@ class TestVolumeManagerBase: ) @patch('kiwi.volume_manager.base.SystemSize') - def test_get_volume_mbsize_root_volume(self, mock_size): + @patch('os.path.exists') + def test_get_volume_mbsize_root_volume( + self, mock_os_path_exists, mock_size + ): + mock_os_path_exists.return_value = True size = Mock() size.customize = Mock( return_value=42 diff --git a/test/unit/volume_manager/lvm_test.py b/test/unit/volume_manager/lvm_test.py index 2775c00f..a3408943 100644 --- a/test/unit/volume_manager/lvm_test.py +++ b/test/unit/volume_manager/lvm_test.py @@ -36,6 +36,10 @@ class TestVolumeManagerLVM: name='LVRoot', size='freespace:100', realpath='/', mountpoint=None, fullsize=False, label=None, attributes=[] ), + self.volume_type( + name='LVSwap', size='size:100', realpath='swap', + mountpoint=None, fullsize=False, label='SWAP', attributes=[] + ), self.volume_type( name='LVetc', size='freespace:200', realpath='/etc', mountpoint='/etc', fullsize=False, label='etc', attributes=[] @@ -82,12 +86,15 @@ class TestVolumeManagerLVM: def test_get_device(self, mock_path): mock_path.return_value = True self.volume_manager.volume_map = { - 'LVRoot': '/dev/lvroot', 'LVx': '/dev/lvx' + 'LVRoot': '/dev/lvroot', 'LVx': '/dev/lvx', + 'LVSwap': '/dev/lvswap', 'LVs': '/dev/lvs' } assert self.volume_manager.get_device()['LVx'].get_device() == \ '/dev/lvx' assert self.volume_manager.get_device()['root'].get_device() == \ '/dev/lvroot' + assert self.volume_manager.get_device()['swap'].get_device() == \ + '/dev/lvswap' @patch('kiwi.volume_manager.lvm.Command.run') @patch('kiwi.volume_manager.base.mkdtemp') @@ -141,6 +148,12 @@ class TestVolumeManagerLVM: self, mock_attrs, mock_mount, mock_mapped_device, mock_fs, mock_command, mock_size, mock_os_exists ): + mock_os_exists_return_list = [True, True, False, False, False] + + def mock_os_exists_return(path): + return mock_os_exists_return_list.pop() + + mock_os_exists.side_effect = mock_os_exists_return filesystem = Mock() mock_fs.return_value = filesystem self.volume_manager.mountpoint = 'tmpdir' @@ -150,7 +163,6 @@ class TestVolumeManagerLVM: return_value=42 ) mock_size.return_value = size - mock_os_exists.return_value = False self.volume_manager.volume_group = 'volume_group' self.volume_manager.create_volumes('ext3') myvol_size = 500 @@ -158,6 +170,13 @@ class TestVolumeManagerLVM: root_size = 100 + 42 + Defaults.get_min_volume_mbytes() assert mock_attrs.call_args_list == [ + call( + 'root_dir', self.volume_type( + name='LVSwap', size='size:100', realpath='swap', + mountpoint=None, fullsize=False, label='SWAP', + attributes=[] + ) + ), call( 'root_dir', self.volume_type( name='LVRoot', size='freespace:100', realpath='/', @@ -187,28 +206,60 @@ class TestVolumeManagerLVM: call(device='/dev/volume_group/LVhome', mountpoint='tmpdir//home') ] assert mock_command.call_args_list == [ - call(['mkdir', '-p', 'root_dir/etc']), - call(['mkdir', '-p', 'root_dir/data']), - call(['mkdir', '-p', 'root_dir/home']), - call([ - 'lvcreate', '-Zn', '-L', format(root_size), '-n', 'LVRoot', - 'volume_group' - ]), - call(['vgscan', '--mknodes']), - call([ - 'lvcreate', '-Zn', '-L', format(myvol_size), '-n', 'myvol', - 'volume_group' - ]), - call(['vgscan', '--mknodes']), - call([ - 'lvcreate', '-Zn', '-L', format(etc_size), '-n', 'LVetc', - 'volume_group' - ]), - call(['vgscan', '--mknodes']), - call([ - 'lvcreate', '-Zn', '-l', '+100%FREE', '-n', 'LVhome', 'volume_group' - ]), - call(['vgscan', '--mknodes']) + call( + ['mkdir', '-p', 'root_dir/etc'] + ), + call( + ['mkdir', '-p', 'root_dir/data'] + ), + call( + ['mkdir', '-p', 'root_dir/home'] + ), + call( + [ + 'lvcreate', '-Zn', '-L', '100', '-n', 'LVSwap', + 'volume_group' + ] + ), + call( + ['vgscan', '--mknodes'] + ), + call( + [ + 'lvcreate', '-Zn', '-L', format(root_size), '-n', 'LVRoot', + 'volume_group' + ] + ), + call( + ['vgscan', '--mknodes'] + ), + call( + [ + 'lvcreate', '-Zn', '-L', format(myvol_size), '-n', 'myvol', + 'volume_group' + ] + ), + call( + ['vgscan', '--mknodes'] + ), + call( + [ + 'lvcreate', '-Zn', '-L', format(etc_size), '-n', 'LVetc', + 'volume_group' + ] + ), + call( + ['vgscan', '--mknodes'] + ), + call( + [ + 'lvcreate', '-Zn', '-l', '+100%FREE', '-n', 'LVhome', + 'volume_group' + ] + ), + call( + ['vgscan', '--mknodes'] + ) ] assert mock_fs.call_args_list == [ call( diff --git a/test/unit/xml_state_test.py b/test/unit/xml_state_test.py index c2198adb..559ee128 100644 --- a/test/unit/xml_state_test.py +++ b/test/unit/xml_state_test.py @@ -326,6 +326,13 @@ class TestXMLState: mountpoint='/usr/bin', fullsize=True, label=None, attributes=[] + ), + volume_type( + name='LVSwap', size='size:128', + realpath='swap', + mountpoint=None, fullsize=False, + label='SWAP', + attributes=[] ) ] @@ -350,6 +357,13 @@ class TestXMLState: mountpoint=None, fullsize=True, label=None, attributes=[] + ), + volume_type( + name='LVSwap', size='size:128', + realpath='swap', + mountpoint=None, fullsize=False, + label='SWAP', + attributes=[] ) ] @@ -382,6 +396,13 @@ class TestXMLState: mountpoint=None, fullsize=False, label=None, attributes=[] + ), + volume_type( + name='LVSwap', size='size:128', + realpath='swap', + mountpoint=None, fullsize=False, + label='SWAP', + attributes=[] ) ] @@ -414,6 +435,21 @@ class TestXMLState: assert state.get_build_type_oemconfig_section().get_oem_swap()[0] is \ True + def test_get_oemconfig_swap_mbytes(self): + xml_data = self.description.load() + state = XMLState(xml_data, ['xenFlavour'], 'docker') + assert state.get_oemconfig_swap_mbytes() is None + state = XMLState(xml_data, ['vmxFlavour'], 'oem') + assert state.get_oemconfig_swap_mbytes() == 42 + + def test_get_oemconfig_swap_mbytes_default(self): + description = XMLDescription( + '../data/example_btrfs_config.xml' + ) + xml_data = description.load() + state = XMLState(xml_data) + assert state.get_oemconfig_swap_mbytes() == 128 + def test_get_users_sections(self): assert self.state.get_users_sections()[0].get_user()[0].get_name() == \ 'root'