build: add tool to install a bootable ISO to a removable block device
This commit is contained in:
171
tools/socks.install-cd
Executable file
171
tools/socks.install-cd
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/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/socks-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/socks-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])
|
||||
Reference in New Issue
Block a user