mirror of
https://github.com/flatcar/scripts.git
synced 2026-05-04 19:56:32 +02:00
feat(disk_util): Add mount and unmount commands.
This will replace the assorted mix of mount/umount scripts.
This commit is contained in:
parent
ba45152b4b
commit
8ca62121d9
@ -35,7 +35,8 @@ def LoadPartitionConfig(options):
|
||||
valid_keys = set(('_comment', 'metadata', 'layouts'))
|
||||
valid_layout_keys = set((
|
||||
'_comment', 'type', 'num', 'label', 'blocks', 'block_size', 'fs_blocks',
|
||||
'fs_block_size', 'fs_type', 'features', 'uuid', 'alignment'))
|
||||
'fs_block_size', 'fs_type', 'features', 'uuid', 'alignment', 'mount',
|
||||
'binds'))
|
||||
integer_layout_keys = set((
|
||||
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'alignment'))
|
||||
required_layout_keys = set(('type', 'num', 'label', 'blocks'))
|
||||
@ -321,6 +322,81 @@ def Format(options):
|
||||
Sudo(['losetup', '--detach', loop_dev])
|
||||
|
||||
|
||||
def Mount(options):
|
||||
"""Mount the given disk image.
|
||||
|
||||
The existing partition table is used to determine what exists but the
|
||||
disk layout config is used to look up mount points and binds.
|
||||
|
||||
Args:
|
||||
options: Flags passed to the script
|
||||
"""
|
||||
|
||||
config, partitions = LoadPartitionConfig(options)
|
||||
mounts = {}
|
||||
|
||||
cgpt_show = subprocess.check_output(
|
||||
['cgpt', 'show', '-q', options.disk_image])
|
||||
for line in cgpt_show.split('\n'):
|
||||
if not line.strip():
|
||||
continue
|
||||
fields = line.split(None, 3)
|
||||
if len(fields) != 4 or not all(f.isdigit() for f in fields[:3]):
|
||||
raise Exception('Invalid output from cgpt show -q: %r' % line)
|
||||
|
||||
first_block = int(fields[0])
|
||||
blocks = int(fields[1])
|
||||
part_num = fields[2]
|
||||
part = partitions.get(part_num, {})
|
||||
path = part.get('mount', None)
|
||||
if not path or not path.startswith('/'):
|
||||
continue
|
||||
|
||||
mounts[path] = {'path': path,
|
||||
'offset': first_block * config['metadata']['block_size'],
|
||||
'size': blocks * config['metadata']['block_size'],
|
||||
'type': part.get('fs_type', 'auto'),
|
||||
'binds': part.get('binds', {})}
|
||||
|
||||
rootfs = mounts.pop('/', None)
|
||||
if not rootfs:
|
||||
raise InvalidLayout('No partition defined to mount on /')
|
||||
|
||||
def DoMount(mount):
|
||||
full_path = os.path.realpath(options.mount_dir + mount['path'])
|
||||
mount_opts = ['loop',
|
||||
'offset=%d' % mount['offset'],
|
||||
'sizelimit=%d' % mount['size']]
|
||||
if options.read_only:
|
||||
mount_opts.append('ro')
|
||||
else:
|
||||
Sudo(['mkdir', '-p', full_path])
|
||||
|
||||
Sudo(['mount', '-t', mount['type'],
|
||||
'-o', ','.join(mount_opts),
|
||||
options.disk_image, full_path])
|
||||
|
||||
for src, dst in mount['binds'].iteritems():
|
||||
# src may be relative or absolute, os.path.join handles this.
|
||||
full_src = os.path.realpath(
|
||||
options.mount_dir + os.path.join(mount['path'], src))
|
||||
full_dst = os.path.realpath(options.mount_dir + dst)
|
||||
Sudo(['mkdir', '-p', full_src, full_dst])
|
||||
Sudo(['mount', '--bind', full_src, full_dst])
|
||||
|
||||
DoMount(rootfs)
|
||||
for mount in mounts.itervalues():
|
||||
DoMount(mount)
|
||||
|
||||
def Umount(options):
|
||||
"""Unmount the given path.
|
||||
|
||||
Args:
|
||||
options: Flags passed to the script
|
||||
"""
|
||||
Sudo(['umount', '--recursive', '--detach-loop', options.mount_dir])
|
||||
|
||||
|
||||
def GetPartitionByNumber(partitions, num):
|
||||
"""Given a partition table and number returns the partition object.
|
||||
|
||||
@ -519,6 +595,16 @@ def main(argv):
|
||||
a.add_argument('disk_image', help='path to disk image file')
|
||||
a.set_defaults(func=Format)
|
||||
|
||||
a = actions.add_parser('mount', help='mount filesystems in image')
|
||||
a.add_argument('--read_only', '-r', help='mount filesystems read-only')
|
||||
a.add_argument('disk_image', help='path to disk image file')
|
||||
a.add_argument('mount_dir', help='path to root filesystem mount point')
|
||||
a.set_defaults(func=Mount)
|
||||
|
||||
a = actions.add_parser('umount', help='unmount a image mount point')
|
||||
a.add_argument('mount_dir', help='path to root filesystem mount point')
|
||||
a.set_defaults(func=Umount)
|
||||
|
||||
a = actions.add_parser('readblocksize', help='get device block size')
|
||||
a.set_defaults(func=GetBlockSize)
|
||||
|
||||
|
||||
@ -11,7 +11,8 @@
|
||||
"label":"EFI-SYSTEM",
|
||||
"type":"efi",
|
||||
"blocks":"262144",
|
||||
"fs_type":"vfat"
|
||||
"fs_type":"vfat",
|
||||
"mount":"/boot/efi"
|
||||
},
|
||||
"2":{
|
||||
"label":"BOOT-B",
|
||||
@ -24,7 +25,8 @@
|
||||
"type":"coreos-rootfs",
|
||||
"blocks":"2097152",
|
||||
"fs_blocks":"262144",
|
||||
"fs_type":"ext2"
|
||||
"fs_type":"ext2",
|
||||
"mount":"/"
|
||||
},
|
||||
"4":{
|
||||
"label":"ROOT-B",
|
||||
@ -43,7 +45,8 @@
|
||||
"label":"OEM",
|
||||
"type":"data",
|
||||
"blocks":"262144",
|
||||
"fs_type":"ext4"
|
||||
"fs_type":"ext4",
|
||||
"mount":"/usr/share/oem"
|
||||
},
|
||||
"7":{
|
||||
"type":"blank",
|
||||
@ -59,7 +62,15 @@
|
||||
"label":"STATE",
|
||||
"type":"data",
|
||||
"blocks":"1048576",
|
||||
"fs_type":"ext4"
|
||||
"fs_type":"ext4",
|
||||
"mount":"/media/state",
|
||||
"binds":{
|
||||
"overlays/home":"/home",
|
||||
"overlays/opt":"/opt",
|
||||
"overlays/srv":"/srv",
|
||||
"overlays/usr/local":"/usr/local",
|
||||
"overlays/var":"/var"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vm":{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user