build: add tool to install a bootable ISO to a removable block device

This commit is contained in:
2023-05-07 12:21:25 +01:00
parent a79d109fcc
commit 9e16a2e70c
2 changed files with 176 additions and 0 deletions

View File

@@ -96,6 +96,11 @@ $(BUILD_DIR)/compile_commands.json:
@./tools/socks.compiledb @./tools/socks.compiledb
cd: $(BUILD_DIR)/socks-kernel.iso
install-cd: $(BUILD_DIR)/socks-kernel.iso
@./tools/socks.install-cd
compile-db: $(BUILD_DIR)/compile_commands.json compile-db: $(BUILD_DIR)/compile_commands.json
tools: tools:

171
tools/socks.install-cd Executable file
View 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])