Commit ad6c27c7 authored by Nigel Kukard's avatar Nigel Kukard
Browse files

Added LVM support

parent 6b6aef58
......@@ -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')
# 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}')
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