mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-09 22:16:58 +02:00
feat(disk_util): Add 'format' command to create filesystems in an image.
This will replace the less flexible code in base_image_util.sh
This commit is contained in:
parent
ab23353448
commit
ba45152b4b
@ -35,7 +35,7 @@ def LoadPartitionConfig(options):
|
|||||||
valid_keys = set(('_comment', 'metadata', 'layouts'))
|
valid_keys = set(('_comment', 'metadata', 'layouts'))
|
||||||
valid_layout_keys = set((
|
valid_layout_keys = set((
|
||||||
'_comment', 'type', 'num', 'label', 'blocks', 'block_size', 'fs_blocks',
|
'_comment', 'type', 'num', 'label', 'blocks', 'block_size', 'fs_blocks',
|
||||||
'fs_block_size', 'features', 'uuid', 'alignment'))
|
'fs_block_size', 'fs_type', 'features', 'uuid', 'alignment'))
|
||||||
integer_layout_keys = set((
|
integer_layout_keys = set((
|
||||||
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'alignment'))
|
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'alignment'))
|
||||||
required_layout_keys = set(('type', 'num', 'label', 'blocks'))
|
required_layout_keys = set(('type', 'num', 'label', 'blocks'))
|
||||||
@ -94,6 +94,10 @@ def LoadPartitionConfig(options):
|
|||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise InvalidLayout('Invalid uuid %r: %s' % (part['uuid'], e))
|
raise InvalidLayout('Invalid uuid %r: %s' % (part['uuid'], e))
|
||||||
|
|
||||||
|
if 'fs_type' in part:
|
||||||
|
if part['fs_type'] not in ('ext2', 'ext4', 'vfat'):
|
||||||
|
raise InvalidLayout('Invalid fs_type: %r' % part['fs_type'])
|
||||||
|
|
||||||
|
|
||||||
def Align(count, alignment):
|
def Align(count, alignment):
|
||||||
offset = count % alignment
|
offset = count % alignment
|
||||||
@ -131,6 +135,7 @@ def LoadPartitionConfig(options):
|
|||||||
|
|
||||||
disk_block_count = Align(disk_block_count, part['alignment'])
|
disk_block_count = Align(disk_block_count, part['alignment'])
|
||||||
part['first_block'] = disk_block_count
|
part['first_block'] = disk_block_count
|
||||||
|
part['first_byte'] = disk_block_count * metadata['block_size']
|
||||||
disk_block_count += part['blocks']
|
disk_block_count += part['blocks']
|
||||||
|
|
||||||
part.setdefault('uuid', str(uuid.uuid4()))
|
part.setdefault('uuid', str(uuid.uuid4()))
|
||||||
@ -171,16 +176,19 @@ def GetPartitionTableFromConfig(options):
|
|||||||
return partitions
|
return partitions
|
||||||
|
|
||||||
|
|
||||||
def WritePartitionTable(options):
|
def WritePartitionTable(options, config=None, partitions=None):
|
||||||
"""Writes the given partition table to a disk image or device.
|
"""Writes the given partition table to a disk image or device.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
options: Flags passed to the script
|
options: Flags passed to the script
|
||||||
|
config: Complete layout configuration file object
|
||||||
|
partitions: Selected layout configuration object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def Cgpt(*args):
|
def Cgpt(*args):
|
||||||
subprocess.check_call(['cgpt'] + [str(a) for a in args])
|
subprocess.check_call(['cgpt'] + [str(a) for a in args])
|
||||||
|
|
||||||
|
if not (config and partitions):
|
||||||
config, partitions = LoadPartitionConfig(options)
|
config, partitions = LoadPartitionConfig(options)
|
||||||
|
|
||||||
Cgpt('create', '-c', '-s', config['metadata']['blocks'], options.disk_image)
|
Cgpt('create', '-c', '-s', config['metadata']['blocks'], options.disk_image)
|
||||||
@ -211,6 +219,108 @@ def WritePartitionTable(options):
|
|||||||
Cgpt('show', options.disk_image)
|
Cgpt('show', options.disk_image)
|
||||||
|
|
||||||
|
|
||||||
|
def Sudo(cmd, stdout_null=False):
|
||||||
|
"""Little wrapper around sudo with support for redirecting to /dev/null
|
||||||
|
|
||||||
|
Some tools like tune2fs don't have a quiet mode which just adds
|
||||||
|
useless noise to our build output, drowning out what may be more
|
||||||
|
interesting news.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cmd: a command and arguments to run.
|
||||||
|
stdout_null: bool to enable redirecting stdout to /dev/null.
|
||||||
|
"""
|
||||||
|
|
||||||
|
null = None
|
||||||
|
if stdout_null:
|
||||||
|
null = open('/dev/null', 'w')
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.check_call(['sudo'] + [str(c) for c in cmd], stdout=null)
|
||||||
|
finally:
|
||||||
|
if null:
|
||||||
|
null.close()
|
||||||
|
|
||||||
|
|
||||||
|
def FormatExt(part, device):
|
||||||
|
"""Format an ext2 or ext4 filesystem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
part: dict defining the partition
|
||||||
|
device: name of the block device to format
|
||||||
|
"""
|
||||||
|
Sudo(['mke2fs', '-q',
|
||||||
|
'-t', part['fs_type'],
|
||||||
|
'-b', part['fs_block_size'],
|
||||||
|
device,
|
||||||
|
part['fs_blocks']])
|
||||||
|
|
||||||
|
# TODO(marineam): Make more of these fs options configurable.
|
||||||
|
Sudo(['tune2fs', '-L', part['label'],
|
||||||
|
'-U', 'clear',
|
||||||
|
'-T', '20091119110000',
|
||||||
|
'-c', '0', '-i', '0', # Disable auto fsck
|
||||||
|
'-m', '0', '-r', '0', # Disable reserve blocks
|
||||||
|
'-e', 'remount-ro',
|
||||||
|
device],
|
||||||
|
stdout_null=True)
|
||||||
|
|
||||||
|
|
||||||
|
def FormatFat(part, device):
|
||||||
|
"""Format a FAT filesystem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
part: dict defining the partition
|
||||||
|
device: name of the block device to format
|
||||||
|
"""
|
||||||
|
# The block-count argument to mkfs.vfat is in units of 1k
|
||||||
|
vfat_block_size = 1024
|
||||||
|
vfat_blocks = part['bytes'] // vfat_block_size
|
||||||
|
|
||||||
|
Sudo(['mkfs.vfat', '-n', part['label'],
|
||||||
|
device,
|
||||||
|
vfat_blocks],
|
||||||
|
stdout_null=True)
|
||||||
|
|
||||||
|
|
||||||
|
def Format(options):
|
||||||
|
"""Writes the given partition table and initialize fresh filesystems.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
options: Flags passed to the script
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Note on using sudo: We don't really need to do this stuff as root
|
||||||
|
# but mke2fs and friends doesn't have an option to make filesystems at
|
||||||
|
# arbitrary offsets but using loop devices makes that possible.
|
||||||
|
|
||||||
|
config, partitions = LoadPartitionConfig(options)
|
||||||
|
WritePartitionTable(options, config, partitions)
|
||||||
|
|
||||||
|
for part in partitions.itervalues():
|
||||||
|
if 'fs_type' not in part:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print "Formatting partition %s (%s) as %s" % (
|
||||||
|
part['num'], part['label'], part['fs_type'])
|
||||||
|
|
||||||
|
loop_dev = subprocess.check_output(['sudo', 'losetup',
|
||||||
|
'--offset', str(part['first_byte']),
|
||||||
|
'--sizelimit', str(part['bytes']),
|
||||||
|
'--find', '--show', options.disk_image])
|
||||||
|
loop_dev = loop_dev.strip()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if part['fs_type'] in ('ext2', 'ext4'):
|
||||||
|
FormatExt(part, loop_dev)
|
||||||
|
elif part['fs_type'] == 'vfat':
|
||||||
|
FormatFat(part, loop_dev)
|
||||||
|
else:
|
||||||
|
raise Exception("Unhandled fs type %s" % part['fs_type'])
|
||||||
|
finally:
|
||||||
|
Sudo(['losetup', '--detach', loop_dev])
|
||||||
|
|
||||||
|
|
||||||
def GetPartitionByNumber(partitions, num):
|
def GetPartitionByNumber(partitions, num):
|
||||||
"""Given a partition table and number returns the partition object.
|
"""Given a partition table and number returns the partition object.
|
||||||
|
|
||||||
@ -403,6 +513,12 @@ def main(argv):
|
|||||||
a.add_argument('disk_image', help='path to disk image file')
|
a.add_argument('disk_image', help='path to disk image file')
|
||||||
a.set_defaults(func=WritePartitionTable)
|
a.set_defaults(func=WritePartitionTable)
|
||||||
|
|
||||||
|
a = actions.add_parser('format', help='write gpt and filesystems to image')
|
||||||
|
a.add_argument('--mbr_boot_code',
|
||||||
|
help='path to mbr boot block, such as syslinux/gptmbr.bin')
|
||||||
|
a.add_argument('disk_image', help='path to disk image file')
|
||||||
|
a.set_defaults(func=Format)
|
||||||
|
|
||||||
a = actions.add_parser('readblocksize', help='get device block size')
|
a = actions.add_parser('readblocksize', help='get device block size')
|
||||||
a.set_defaults(func=GetBlockSize)
|
a.set_defaults(func=GetBlockSize)
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
"1":{
|
"1":{
|
||||||
"label":"EFI-SYSTEM",
|
"label":"EFI-SYSTEM",
|
||||||
"type":"efi",
|
"type":"efi",
|
||||||
"blocks":"262144"
|
"blocks":"262144",
|
||||||
|
"fs_type":"vfat"
|
||||||
},
|
},
|
||||||
"2":{
|
"2":{
|
||||||
"label":"BOOT-B",
|
"label":"BOOT-B",
|
||||||
@ -22,7 +23,8 @@
|
|||||||
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
|
"uuid":"7130c94a-213a-4e5a-8e26-6cce9662f132",
|
||||||
"type":"coreos-rootfs",
|
"type":"coreos-rootfs",
|
||||||
"blocks":"2097152",
|
"blocks":"2097152",
|
||||||
"fs_blocks":"262144"
|
"fs_blocks":"262144",
|
||||||
|
"fs_type":"ext2"
|
||||||
},
|
},
|
||||||
"4":{
|
"4":{
|
||||||
"label":"ROOT-B",
|
"label":"ROOT-B",
|
||||||
@ -40,7 +42,8 @@
|
|||||||
"6":{
|
"6":{
|
||||||
"label":"OEM",
|
"label":"OEM",
|
||||||
"type":"data",
|
"type":"data",
|
||||||
"blocks":"262144"
|
"blocks":"262144",
|
||||||
|
"fs_type":"ext4"
|
||||||
},
|
},
|
||||||
"7":{
|
"7":{
|
||||||
"type":"blank",
|
"type":"blank",
|
||||||
@ -55,7 +58,8 @@
|
|||||||
"9":{
|
"9":{
|
||||||
"label":"STATE",
|
"label":"STATE",
|
||||||
"type":"data",
|
"type":"data",
|
||||||
"blocks":"1048576"
|
"blocks":"1048576",
|
||||||
|
"fs_type":"ext4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vm":{
|
"vm":{
|
||||||
|
Loading…
Reference in New Issue
Block a user