/src/actions/extract.py

https://github.com/clearkimura/Customizer · Python · 91 lines · 73 code · 13 blank · 5 comment · 13 complexity · 9ac2464d78e2c0323443cef3d6d12581 MD5 · raw file

  1. #!/usr/bin/python2.7
  2. import os, tempfile
  3. import lib.misc as misc
  4. import lib.config as config
  5. import lib.message as message
  6. import actions.common as common
  7. # TODO: this is not the best way to do it, exception can be raised at any time
  8. mount_dir = None
  9. def unmount_iso():
  10. if not mount_dir:
  11. return
  12. message.sub_info('Unmounting', mount_dir)
  13. misc.system_command((misc.whereis('umount'), '-fl', mount_dir))
  14. message.sub_info('Removing', mount_dir)
  15. os.rmdir(mount_dir)
  16. def main():
  17. global mount_dir
  18. if not os.path.isfile(config.ISO):
  19. raise(message.exception('ISO does not exist', config.ISO))
  20. elif not u'{}'.format(config.ISO).endswith('.iso'):
  21. raise(message.exception('File is not ISO', config.ISO))
  22. common.clean_work_dirs()
  23. common.create_work_dirs()
  24. message.sub_info('Creating mount directory')
  25. mount_dir = tempfile.mkdtemp(prefix=config.MOUNT_DIR + '/')
  26. message.sub_debug('Mount directory is', mount_dir)
  27. message.sub_info('Mounting ISO', config.ISO)
  28. try:
  29. # load the required kernel modules in cases the are not, if they are
  30. # builtin the command fails so ignoring that. the "-b" argument is to
  31. # ensure blacklisted modules are respected
  32. try:
  33. misc.system_command((misc.whereis('modprobe'), '-ba', 'loop', 'iso9660'))
  34. except:
  35. pass
  36. misc.system_command((misc.whereis('mount'), '-t', 'iso9660', '-o', \
  37. 'ro,loop', config.ISO, mount_dir))
  38. except:
  39. message.sub_info('Removing', mount_dir)
  40. os.rmdir(mount_dir)
  41. common.clean_work_dirs()
  42. raise
  43. message.sub_info('Checking ISO')
  44. for spath in (mount_dir + '/casper/filesystem.squashfs', \
  45. mount_dir + '/casper/filesystem.manifest', \
  46. mount_dir + '/casper/filesystem.manifest-remove', \
  47. mount_dir + '/.disk', mount_dir + '/isolinux', ):
  48. if not os.path.exists(spath):
  49. message.sub_debug('Non-existing path', spath)
  50. common.clean_work_dirs()
  51. unmount_iso()
  52. raise(message.exception('Invalid ISO', config.ISO))
  53. message.sub_info('Unsquashing filesystem')
  54. try:
  55. misc.system_command((misc.whereis('unsquashfs'), '-f', '-d', \
  56. config.FILESYSTEM_DIR, mount_dir + '/casper/filesystem.squashfs'))
  57. except:
  58. unmount_iso()
  59. raise
  60. message.sub_info('Checking architecture')
  61. fs_arch = misc.chroot_exec(('dpkg', '--print-architecture'), \
  62. prepare=False, mount=False, output=True)
  63. host_arch = os.uname()[4]
  64. message.sub_debug('Filesystem architecture', fs_arch)
  65. message.sub_debug('Host architecture', host_arch)
  66. if fs_arch == 'amd64' and not host_arch == 'x86_64':
  67. message.sub_debug('The ISO architecture is amd64 and yours is not')
  68. common.clean_work_dirs()
  69. unmount_iso()
  70. raise(message.exception('The ISO architecture is amd64 and yours is not'))
  71. message.sub_info('Copying ISO files')
  72. for sfile in misc.list_files(mount_dir):
  73. if sfile.endswith('casper/filesystem.squashfs'):
  74. continue
  75. else:
  76. message.sub_debug('Copying', sfile)
  77. misc.copy_file(sfile, sfile.replace(mount_dir, config.ISO_DIR))
  78. unmount_iso()