172 lines
4.5 KiB
Python
Executable File
172 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
import os
|
|
import plistlib
|
|
import subprocess
|
|
from pprint import pprint
|
|
|
|
|
|
def disk_prewrite_darwin(dev_path):
|
|
diskutil = subprocess.Popen([ 'sudo', 'diskutil', 'unmountDisk', dev_path ])
|
|
diskutil.communicate()
|
|
|
|
if diskutil.returncode != 0:
|
|
print('Cannot unmount device {}'.format(dev_path))
|
|
print(' diskutil returned error code {}'.format(diskutil.returncode))
|
|
exit(-1)
|
|
|
|
|
|
def disk_prewrite(dev_path):
|
|
if sys.platform == 'darwin':
|
|
disk_prewrite_darwin(dev_path)
|
|
|
|
|
|
def disk_postwrite_darwin(dev_path):
|
|
sync = subprocess.Popen([ 'sync' ])
|
|
sync.communicate()
|
|
|
|
diskutil = subprocess.Popen([ 'sudo', 'diskutil', 'unmountDisk', dev_path ])
|
|
diskutil.communicate()
|
|
|
|
|
|
def disk_postwrite_linux(dev_path):
|
|
sync = subprocess.Popen([ 'sync' ])
|
|
sync.communicate()
|
|
|
|
|
|
def disk_postwrite(dev_path):
|
|
if sys.platform == 'darwin':
|
|
disk_postwrite_darwin(dev_path);
|
|
elif sys.platform == 'linux':
|
|
disk_postwrite_linux(dev_path)
|
|
|
|
|
|
def get_devices_darwin():
|
|
diskutil = subprocess.Popen([ 'diskutil', 'list', '-plist' ], stdout=subprocess.PIPE)
|
|
(out, err) = diskutil.communicate()
|
|
|
|
if diskutil.returncode != 0:
|
|
print('Cannot query storage devices')
|
|
print(' diskutil returned error code {}'.format(diskutil.returncode))
|
|
print(err)
|
|
exit(-1)
|
|
|
|
all_device_data = plistlib.loads(out)
|
|
device_names = []
|
|
|
|
for v in all_device_data['AllDisksAndPartitions']:
|
|
if v['OSInternal']:
|
|
continue
|
|
|
|
device_names.append(v['DeviceIdentifier'])
|
|
|
|
final_list = []
|
|
|
|
for dev in device_names:
|
|
diskutil = subprocess.Popen([ 'diskutil', 'info', '-plist', dev ], stdout=subprocess.PIPE)
|
|
(out, err) = diskutil.communicate()
|
|
|
|
if diskutil.returncode != 0:
|
|
print('Cannot query device {}'.format(dev))
|
|
print(' diskutil returned error code {}'.format(diskutil.returncode))
|
|
print(err)
|
|
exit(-1)
|
|
|
|
dev_info = plistlib.loads(out)
|
|
|
|
if dev_info['BusProtocol'] != 'USB':
|
|
continue
|
|
|
|
final_list.append(('/dev/r{}'.format(dev_info['DeviceIdentifier']), dev_info['MediaName']))
|
|
|
|
return final_list
|
|
|
|
|
|
def get_devices_linux():
|
|
final_list = []
|
|
dev_list = os.listdir('/sys/block')
|
|
|
|
for dev_name in dev_list:
|
|
with open('/sys/block/{}/removable'.format(dev_name), 'r') as dev_removable:
|
|
is_removable = int(dev_removable.read(1))
|
|
if is_removable != 1:
|
|
continue
|
|
|
|
with open('/sys/block/{}/device/model'.format(dev_name)) as dev_model_name:
|
|
model_name = dev_model_name.read().strip()
|
|
final_list.append(('/dev/{}'.format(dev_name), model_name))
|
|
|
|
return final_list
|
|
|
|
|
|
def get_devices():
|
|
if sys.platform == 'darwin':
|
|
return get_devices_darwin()
|
|
elif sys.platform == 'linux':
|
|
return get_devices_linux()
|
|
else:
|
|
print('This script cannot be used on {}'.format(sys.platform))
|
|
exit(-1)
|
|
|
|
|
|
def choice_options(num_devices):
|
|
if num_devices == 1:
|
|
return '1'
|
|
|
|
return '1-{}'.format(num_devices)
|
|
|
|
|
|
if not os.path.isfile('build/mango-kernel.iso'):
|
|
print('No system ISO image found.')
|
|
print('Please run \'make cd\' to generate an ISO image')
|
|
exit(-1)
|
|
|
|
devices = get_devices()
|
|
|
|
if len(devices) == 0:
|
|
print('No devices are available for installation')
|
|
print('Note: this script only considers removable USB drives for installation')
|
|
exit(-1)
|
|
|
|
print('Available Devices:')
|
|
for i, dev in enumerate(devices):
|
|
print(' {}. {} ({})'.format(i + 1, dev[1], dev[0]))
|
|
|
|
choice = 0
|
|
while True:
|
|
print('Selection [{}]: '.format(choice_options(len(devices))), end='')
|
|
choice_str = input()
|
|
|
|
try:
|
|
choice = int(choice_str)
|
|
except:
|
|
print(' {} is not a valid option'.format(choice_str))
|
|
continue
|
|
|
|
if choice < 1 or choice > len(devices):
|
|
print(' {} is not a valid option'.format(choice_str))
|
|
continue
|
|
|
|
choice -= 1
|
|
break
|
|
|
|
print('Installing to {} at {}'.format(devices[choice][1], devices[choice][0]))
|
|
|
|
disk_prewrite(devices[choice][0])
|
|
|
|
dd_args = [
|
|
'sudo',
|
|
'dd',
|
|
'if=build/mango-kernel.iso',
|
|
'of={}'.format(devices[choice][0]),
|
|
'bs=1{}'.format('m' if sys.platform == 'darwin' else 'M')
|
|
]
|
|
|
|
dd = subprocess.Popen(dd_args)
|
|
dd.communicate()
|
|
if dd.returncode != 0:
|
|
print('Cannot write ISO file to device {}'.format(devices[choice][0]))
|
|
print(' dd returned error code {}'.format(dd.returncode))
|
|
|
|
disk_postwrite(devices[choice][0])
|