logo

live-bootstrap

Mirror of <https://github.com/fosslinux/live-bootstrap>

utils.py (2429B)


  1. #!/usr/bin/env python3
  2. """
  3. This file contains a few self-contained helper functions
  4. """
  5. # SPDX-License-Identifier: GPL-3.0-or-later
  6. # SPDX-FileCopyrightText: 2021 Andrius Štikonas <andrius@stikonas.eu>
  7. # SPDX-FileCopyrightText: 2021-23 fosslinux <fosslinux@aussies.space>
  8. import os
  9. import shutil
  10. import subprocess
  11. import sys
  12. def run(*args, cleanup=None, **kwargs):
  13. """A small wrapper around subprocess.run"""
  14. arguments = [str(arg) for arg in args if arg is not None]
  15. if kwargs.pop('verbose', False):
  16. print(arguments)
  17. try:
  18. return subprocess.run(arguments, check=True, **kwargs)
  19. except subprocess.CalledProcessError:
  20. print("Bootstrapping failed")
  21. if cleanup:
  22. cleanup()
  23. sys.exit(1)
  24. def run_as_root(*args, **kwargs):
  25. """A helper for run that invokes sudo when unprivileged"""
  26. if os.geteuid() != 0:
  27. return run("sudo", *args, **kwargs)
  28. return run(*args, **kwargs)
  29. # pylint: disable=too-many-arguments,too-many-positional-arguments
  30. def create_disk(image, disk_type, fs_type, size, bootable=False, mkfs_args=None):
  31. """Create a disk image, with a filesystem on it"""
  32. if mkfs_args is None:
  33. mkfs_args = []
  34. run('truncate', '-s', size, image)
  35. # Create the partition
  36. if disk_type != "none":
  37. # 1 GiB if bootable, 1 MiB otherwise
  38. offset = str(1024 * 1024 * (1024 if bootable else 1))
  39. run('parted', '--script', image, 'mklabel', disk_type, 'mkpart',
  40. 'primary', fs_type, offset + 'B', '100%')
  41. run('mkfs.' + fs_type, image, '-E', 'offset=' + offset, *mkfs_args)
  42. def mount(source, target, fs_type, options='', **kwargs):
  43. """Mount filesystem"""
  44. run_as_root('mount', source, target, '-t', fs_type, '-o', options, **kwargs)
  45. def umount(target, **kwargs):
  46. """Unmount filesystem"""
  47. run_as_root('umount', '--recursive', target, **kwargs)
  48. def copytree(src, dst, ignore=shutil.ignore_patterns('*.git*')):
  49. """Copy directory tree into another directory"""
  50. if not os.path.exists(dst):
  51. os.makedirs(dst)
  52. lst = os.listdir(src)
  53. if ignore:
  54. excl = ignore(src, lst)
  55. lst = [x for x in lst if x not in excl]
  56. for item in lst:
  57. source = os.path.join(src, item)
  58. dest = os.path.join(dst, item)
  59. if os.path.isdir(source):
  60. copytree(source, dest, ignore)
  61. else:
  62. shutil.copy2(source, dest)