Commit 5ab072ed authored by Nigel Kukard's avatar Nigel Kukard
Browse files

Merge branch 'nkupdates' into 'master'

Nkupdates

See merge request idms-linux-rolling/projects/idms-linux-installer!9
parents efd8ac3d ad6c27c7
......@@ -127,6 +127,7 @@ class Ili:
steps = [
self._plugins.commit_diskusage_strategy,
self._plugins.commit_disklayout_strategy,
self._plugins.create_filesystems,
self._plugins.mount_filesystems,
self._plugins.pre_install_base,
self._plugins.install_base,
......@@ -194,6 +195,10 @@ class Ili:
if self._preseed.has_option('storage', 'disklayout_strategy'):
self._status_callback('preseed storage -> disklayout_strategy')
self.state.disklayout_strategy = self._preseed.get('storage', 'disklayout_strategy').upper()
# Process root_size
if self._preseed.has_option('system', 'root_size'):
self._status_callback('preseed system -> root_size')
self.state.root_size = int(self._preseed.get('system', 'root_size'))
# Process system section
if self._preseed.has_section('system'):
......
......@@ -37,6 +37,8 @@ class IliState:
# Chosen strategies
_diskusage_strategy: Optional[str]
_disklayout_strategy: Optional[str]
# root size in Gbytes
_root_size: int
# Chosen hostname
_hostname: Optional[str]
# Chosen locale
......@@ -105,6 +107,7 @@ class IliState:
self._install_disks = []
self._diskusage_strategy = None
self._disklayout_strategy = None
self._root_size = 10
self._hostname = None
self._locale = 'en_US.UTF-8'
self._timezone = 'UTC'
......@@ -179,6 +182,17 @@ class IliState:
"""Set the diskusage_strategy."""
self._diskusage_strategy = value
# Root size
@property
def root_size(self):
"""Return the root_size."""
return self._root_size
@root_size.setter
def root_size(self, value: int):
"""Set the root_size."""
self._root_size = value
# Hostname
@property
def hostname(self):
......@@ -345,6 +359,17 @@ class IliState:
self._blockdevices[usage] = blockdevice
def replace_blockdevice(self, usage: str, blockdevice: str):
"""Replace a block device."""
if usage not in ['efi', 'boot', 'root']:
raise RuntimeError(f'Unknown blockdevice usage "{usage}"')
if usage not in self._blockdevices:
raise RuntimeError(f'Blockdevice usage "{usage}" not set')
self._blockdevices[usage] = blockdevice
@property
def blockdevices(self):
"""Return the block devices we should create filesystems on."""
......
......@@ -48,6 +48,10 @@ class Plugin:
"""Commit the disk layout strategy."""
raise NotImplementedError
def create_filesystems(self, ili_state: IliState):
"""Create filesystems."""
raise NotImplementedError
def mount_filesystems(self, ili_state: IliState):
"""Mount filesystems."""
raise NotImplementedError
......@@ -114,9 +118,14 @@ class PluginCollection:
self._call_plugins(ili_state, 'commit_disklayout_strategy')
def create_filesystems(self, ili_state: IliState):
"""Call plugins to create our filesystems."""
self._call_plugins(ili_state, 'create_filesystems')
# Make sure we've got filesystems in our state now
if not ili_state.filesystems:
raise RuntimeError('At least one of the disk layout strategies should of setup the filesystems for install.')
raise RuntimeError('At least one of the create_filesystems plugins should of setup the filesystems for install.')
def mount_filesystems(self, ili_state: IliState):
"""Call plugins to mount our filesystems."""
......
# Copyright (c) 2019, AllWorldIT
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
"""Create filesystems on the provided block devices."""
from typing import Callable, Dict, List, Optional
from idmslinux_installer.ilistate import IliState
from idmslinux_installer.plugin import Plugin
from idmslinux_installer.util.mkfs import Mkfs
# Ignore warning that we have not overridden all base class methods.
# pylama:ignore=W:select=W023
class CreateFilesystems(Plugin):
"""Create filesystems on the provided block devices."""
def __init__(self):
"""Plugin init method."""
self.description = "Create Filesystems"
Plugin.__init__(self)
def create_filesystems(self, ili_state: IliState):
"""Create the filesystems we need on the block devices."""
# Mount the root filesystem
ili_state.output_callback('Mounting root filesystem')
# Create an mkfs object
mkfs = Mkfs()
# Check which block devices we need to create filesystems for
if 'efi' in ili_state.blockdevices:
ili_state.output_callback('Configuring EFI filesystem')
uuid = mkfs.run('vfat', ili_state.blockdevices['efi'], fslabel="efi", args=['-F', '32'],
output_callback=ili_state.output_callback)
ili_state.add_filesystem('efi', uuid, 'vfat', ili_state.blockdevices['efi'])
if 'boot' in ili_state.blockdevices:
ili_state.output_callback('Configuring boot filesystem')
uuid = mkfs.run('ext3', ili_state.blockdevices['boot'], fslabel="boot",
output_callback=ili_state.output_callback)
ili_state.add_filesystem('boot', uuid, 'ext3', ili_state.blockdevices['boot'])
if 'root' in ili_state.blockdevices:
ili_state.output_callback('Configuring root filesystem')
uuid = mkfs.run('ext4', ili_state.blockdevices['root'], fslabel="root",
output_callback=ili_state.output_callback)
ili_state.add_filesystem('root', uuid, 'ext4', ili_state.blockdevices['root'])
......@@ -43,24 +43,6 @@ class DiskLayoutFLAT(Plugin):
# Check the strategy to use for these block devices
if ili_state.disklayout_strategy == 'FLAT':
# Create an mkfs object
mkfs = Mkfs()
ili_state.output_callback('Creating FLAT disk layout')
# Check which block devices we need to create filesystems for
if 'efi' in ili_state.blockdevices:
ili_state.output_callback('Configuring EFI filesystem')
uuid = mkfs.run('vfat', ili_state.blockdevices['efi'], fslabel="efi", args=['-F', '32'],
output_callback=ili_state.output_callback)
ili_state.add_filesystem('efi', uuid, 'vfat', ili_state.blockdevices['efi'])
if 'boot' in ili_state.blockdevices:
ili_state.output_callback('Configuring boot filesystem')
uuid = mkfs.run('ext3', ili_state.blockdevices['boot'], fslabel="boot",
output_callback=ili_state.output_callback)
ili_state.add_filesystem('boot', uuid, 'ext3', ili_state.blockdevices['boot'])
if 'root' in ili_state.blockdevices:
ili_state.output_callback('Configuring root filesystem')
uuid = mkfs.run('ext4', ili_state.blockdevices['root'], fslabel="root",
output_callback=ili_state.output_callback)
ili_state.add_filesystem('root', uuid, 'ext4', ili_state.blockdevices['root'])
# We don't actually have to do anything here as we already have the block devices
......@@ -19,6 +19,7 @@ from typing import List
from idmslinux_installer.ilistate import IliState
from idmslinux_installer.plugin import Plugin
from idmslinux_installer.util.lvm import Lvm
# Ignore warning that we have not overridden all base class methods.
......@@ -36,3 +37,37 @@ class DiskLayoutLVM(Plugin):
"""Check which strategies we can provided based on the disk usage."""
ili_state.add_disklayout_strategy('LVM', 'Use LVM volumes')
def commit_disklayout_strategy(self, ili_state: IliState):
"""Commit disk layout strategy and add the root, boot and efi filesystem path."""
# Check the strategy to use for these block devices
if ili_state.disklayout_strategy == 'LVM':
ili_state.output_callback('Configuring LVM')
# Create an lvm object
lvm = Lvm()
# What we do here is we take the 'root' device we already have and create a PV/VG/LV
pv_device = ili_state.blockdevices['root']
# Create the PV
lvm.create_pv(pv_device, output_callback=ili_state.output_callback)
# If we have been setup with RAID, use the name of 'lvm-raid' else use 'main'
if ili_state.diskusage_strategy.find('RAID') > 0:
vg_name = 'lvm-raid'
else:
vg_name = 'main'
# Create the VG
lvm.create_vg(pv_device, vg_name, output_callback=ili_state.output_callback)
# Create a 10G LV
lvm.create_lv(vg_name, 'root', f'{ili_state.root_size}G', output_callback=ili_state.output_callback)
# Replace the 'root' block device
ili_state.replace_blockdevice('root', f'/dev/{vg_name}/root')
# Add lvm2 to the base packages
ili_state.add_base_package('lvm2')
......@@ -104,8 +104,8 @@ class DiskUsageMDRAID(Plugin):
# Add the block devices to the installer
ili_state.output_callback('Adding block devices')
ili_state.add_blockdevice('efi', f'{efi_disk}2')
ili_state.add_blockdevice('boot', f'{boot_disk}')
ili_state.add_blockdevice('root', f'{root_disk}')
ili_state.add_blockdevice('boot', boot_disk)
ili_state.add_blockdevice('root', root_disk)
# Add the MBR device to the installer
ili_state.output_callback('Adding device for MBR')
......
# Copyright (c) 2019, AllWorldIT
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
"""Support class for lvm."""
from typing import Optional
from idmslinux_installer.util.asyncsubprocess import (AsyncSubprocess,
OutputCallback)
class Lvm:
"""The Lvm class handles our interface to lvm."""
def __init__(self, load: bool = True):
"""Initialize our class and load system partition types."""
def create_pv(self, device: str, output_callback: OutputCallback = None):
"""Create LVM physical volume."""
# If we didn't get an output_callback, set it to our own class method
if not output_callback:
output_callback = self._default_output_callback
# Run lvm to create the physical volume
proc = AsyncSubprocess(['pvcreate', device], output_callback=output_callback)
proc.run()
# Raise an exception if we didn't get a positive response back
if proc.retcode != 0:
raise OSError(f'Failed to create LVM PV on "{device}", return code {proc.retcode}')
def create_vg(self, pv_device: str, vg_name: str, pe_size: Optional[str] = None, output_callback: OutputCallback = None):
"""Create LVM volume group."""
# If we didn't get an output_callback, set it to our own class method
if not output_callback:
output_callback = self._default_output_callback
# Use 32M physical extent size by default
if not pe_size:
pe_size = '32M'
# Run lvm to create the physical volume
proc = AsyncSubprocess(['vgcreate', '--physicalextentsize', pe_size, vg_name, pv_device], output_callback=output_callback)
proc.run()
# Raise an exception if we didn't get a positive response back
if proc.retcode != 0:
raise OSError(f'Failed to create LVM VG "{vg_name}" on "{pv_device}", return code {proc.retcode}')
def create_lv(self, vg_name: str, lv_name: str, lv_size: str, output_callback: OutputCallback = None):
"""Create LVM volume."""
# If we didn't get an output_callback, set it to our own class method
if not output_callback:
output_callback = self._default_output_callback
# Work out the size option we're going to use
if lv_size.find('%') > 0:
size_opt = '--extents'
else:
size_opt = '--size'
# Run lvm to create the physical volume
proc = AsyncSubprocess(['lvcreate', '--wipesignatures', 'y', '--yes', size_opt, lv_size, '--name', lv_name, vg_name],
output_callback=output_callback)
proc.run()
# Raise an exception if we didn't get a positive response back
if proc.retcode != 0:
raise OSError(f'Failed to create LVM LV "{lv_name}" on VG "{vg_name}", return code {proc.retcode}')
def _default_output_callback(self, line: str):
line.rstrip()
print(f'lvm: {line}')
......@@ -48,4 +48,4 @@ class Mdadm:
def _default_output_callback(self, line: str):
line.rstrip()
print(f'grub: {line}')
print(f'mdadm: {line}')
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment