bootstrap-vz/base/fs/partitions/base.py

106 lines
3.6 KiB
Python
Raw Normal View History

from abstract import AbstractPartition
class BasePartition(AbstractPartition):
2014-03-23 16:04:03 +01:00
"""Represents a partition that is actually a partition (and not a virtual one like 'Single')
"""
2014-03-23 16:04:03 +01:00
# Override the states of the abstract partition
# A real partition can be mapped and unmapped
events = [{'name': 'create', 'src': 'nonexistent', 'dst': 'unmapped'},
{'name': 'map', 'src': 'unmapped', 'dst': 'mapped'},
{'name': 'format', 'src': 'mapped', 'dst': 'formatted'},
{'name': 'mount', 'src': 'formatted', 'dst': 'mounted'},
{'name': 'unmount', 'src': 'mounted', 'dst': 'formatted'},
{'name': 'unmap', 'src': 'formatted', 'dst': 'unmapped_fmt'},
{'name': 'map', 'src': 'unmapped_fmt', 'dst': 'formatted'},
{'name': 'unmap', 'src': 'mapped', 'dst': 'unmapped'},
]
2014-02-23 17:52:05 +01:00
def __init__(self, size, filesystem, format_command, previous):
2014-03-23 16:04:03 +01:00
"""
Args:
size (Bytes): Size of the partition
filesystem (str): Filesystem the partition should be formatted with
format_command (list): Optional format command, valid variables are fs, device_path and size
previous (BasePartition): The partition that preceeds this one
"""
# By saving the previous partition we have
# a linked list that partitions can go backwards in to find the first partition.
self.previous = previous
from common.bytes import Bytes
2014-03-23 16:04:03 +01:00
# Initialize the offset to 0 bytes, may be changed later
self.offset = Bytes(0)
2014-03-23 16:04:03 +01:00
# List of flags that parted should put on the partition
2014-01-19 01:02:29 +01:00
self.flags = []
2014-02-23 17:52:05 +01:00
super(BasePartition, self).__init__(size, filesystem, format_command)
def create(self, volume):
2014-03-23 16:04:03 +01:00
"""Creates the partition
Args:
volume (Volume): The volume to create the partition on
"""
self.fsm.create(volume=volume)
def get_index(self):
2014-03-23 16:04:03 +01:00
"""Gets the index of this partition in the partition map
Returns:
int. The index of the partition in the partition map
"""
if self.previous is None:
2014-03-23 16:04:03 +01:00
# Partitions are 1 indexed
return 1
else:
2014-03-23 16:04:03 +01:00
# Recursive call to the previous partition, walking up the chain...
2013-12-14 19:37:23 +01:00
return self.previous.get_index() + 1
def get_start(self):
2014-03-23 16:04:03 +01:00
"""Gets the starting byte of this partition
Returns:
Bytes. The starting byte of this partition
"""
if self.previous is None:
2014-03-23 16:04:03 +01:00
# If there is no previous partition, this partition begins at the offset
2014-01-19 01:02:29 +01:00
return self.offset
else:
2014-03-23 16:04:03 +01:00
# Get the end of the previous partition and add the offset of this partition
2014-01-19 01:02:29 +01:00
return self.previous.get_end() + self.offset
def map(self, device_path):
2014-03-23 16:04:03 +01:00
"""Maps the partition to a device_path
Args:
device_path (str): The device patht his partition should be mapped to
"""
self.fsm.map(device_path=device_path)
2014-01-19 01:02:29 +01:00
def _before_create(self, e):
2014-03-23 16:04:03 +01:00
"""Creates the partition
"""
2014-01-19 01:02:29 +01:00
from common.tools import log_check_call
2014-03-23 16:04:03 +01:00
# The create command is failry simple, start and end are just Bytes objects coerced into strings
create_command = ('mkpart primary {start} {end}'
2014-01-19 01:02:29 +01:00
.format(start=str(self.get_start()),
end=str(self.get_end())))
2014-03-23 16:04:03 +01:00
# Create the partition
log_check_call(['parted', '--script', '--align', 'none', e.volume.device_path,
2014-01-19 01:02:29 +01:00
'--', create_command])
2014-03-23 16:04:03 +01:00
# Set any flags on the partition
2014-01-19 01:02:29 +01:00
for flag in self.flags:
log_check_call(['parted', '--script', e.volume.device_path,
2014-01-19 01:02:29 +01:00
'--', ('set {idx} {flag} on'
.format(idx=str(self.get_index()), flag=flag))])
def _before_map(self, e):
2014-03-23 16:04:03 +01:00
# Set the device path
self.device_path = e.device_path
def _before_unmap(self, e):
2014-03-23 16:04:03 +01:00
# When unmapped, the device_path ifnromation becomes invalid, so we delete it
self.device_path = None