Fix and improve rootfs flashing

This commit is contained in:
jld3103 2021-08-14 13:31:04 +02:00
parent da8a437341
commit e1ddf636b7
2 changed files with 115 additions and 29 deletions

23
boot.py
View file

@ -2,6 +2,7 @@ import os
import urllib.request import urllib.request
from image import get_device_and_flavour, get_image_name from image import get_device_and_flavour, get_image_name
from logger import logging, setup_logging, verbose_option from logger import logging, setup_logging, verbose_option
from flash import dump_bootimg, erase_dtbo
import click import click
import subprocess import subprocess
@ -17,20 +18,6 @@ boot_strategies = {
} }
def dump_bootimg(image_name: str) -> str:
path = '/tmp/boot.img'
result = subprocess.run([
'debugfs',
image_name,
'-R',
f'dump /boot/boot.img {path}',
])
if result.returncode != 0:
logging.fatal(f'Faild to dump boot.img')
exit(1)
return path
@click.command(name='boot', help=f'Leave TYPE empty or choose \'{JUMPDRIVE}\'') @click.command(name='boot', help=f'Leave TYPE empty or choose \'{JUMPDRIVE}\'')
@verbose_option @verbose_option
@click.argument('type', required=False) @click.argument('type', required=False)
@ -49,7 +36,13 @@ def cmd_boot(verbose, type):
else: else:
path = dump_bootimg(image_name) path = dump_bootimg(image_name)
result = subprocess.run(['fastboot', 'boot', path]) erase_dtbo()
result = subprocess.run([
'fastboot',
'boot',
path,
])
if result.returncode != 0: if result.returncode != 0:
logging.fatal(f'Failed to boot {path} using fastboot') logging.fatal(f'Failed to boot {path} using fastboot')
exit(1) exit(1)

121
flash.py
View file

@ -1,8 +1,12 @@
import atexit
from cmath import log
from email.mime import image
import shutil
from image import get_device_and_flavour, get_image_name from image import get_device_and_flavour, get_image_name
from boot import dump_bootimg
import os import os
import subprocess import subprocess
import click import click
import tempfile
from logger import logging, setup_logging, verbose_option from logger import logging, setup_logging, verbose_option
ROOTFS = 'rootfs' ROOTFS = 'rootfs'
@ -14,6 +18,31 @@ MICROSD = 'microsd'
locations = [EMMC, EMMCFILE, MICROSD] locations = [EMMC, EMMCFILE, MICROSD]
def dump_bootimg(image_name: str) -> str:
path = '/tmp/boot.img'
result = subprocess.run([
'debugfs',
image_name,
'-R',
f'dump /boot/boot.img {path}',
])
if result.returncode != 0:
logging.fatal(f'Faild to dump boot.img')
exit(1)
return path
def erase_dtbo():
result = subprocess.run([
'fastboot',
'erase',
'dtbo',
])
if result.returncode != 0:
logging.info(f'Failed to erase dtbo')
exit(1)
@click.command(name='flash') @click.command(name='flash')
@verbose_option @verbose_option
@click.argument('what') @click.argument('what')
@ -32,6 +61,7 @@ def cmd_flash(verbose, what, location):
logging.info(f'Invalid location {location}. Choose one of {", ".join(locations)} for location') logging.info(f'Invalid location {location}. Choose one of {", ".join(locations)} for location')
exit(1) exit(1)
path = ''
dir = '/dev/disk/by-id' dir = '/dev/disk/by-id'
for file in os.listdir(dir): for file in os.listdir(dir):
sanitized_file = file.replace('-', '').replace('_', '').lower() sanitized_file = file.replace('-', '').replace('_', '').lower()
@ -46,34 +76,97 @@ def cmd_flash(verbose, what, location):
f'Disk {path} has a size of 0B. That probably means it is not available (e.g. no microSD inserted or no microSD card slot installed in the device) or corrupt or defect' f'Disk {path} has a size of 0B. That probably means it is not available (e.g. no microSD inserted or no microSD card slot installed in the device) or corrupt or defect'
) )
exit(1) exit(1)
if path == '':
logging.fatal(f'Unable to discover Jumpdrive')
exit(1)
image_dir = tempfile.gettempdir()
image_path = os.path.join(image_dir, f'minimal-{image_name}')
def clean_dir():
shutil.rmtree(image_dir)
atexit.register(clean_dir)
shutil.copyfile(image_name, image_path)
result = subprocess.run([
'e2fsck',
'-fy',
image_path,
])
if result.returncode != 0:
logging.fatal(f'Failed to e2fsck {image_path}')
exit(1)
result = subprocess.run([
'resize2fs',
'-M',
image_path,
])
if result.returncode != 0:
logging.fatal(f'Failed to resize2fs {image_path}')
exit(1)
if location.endswith('-file'): if location.endswith('-file'):
logging.fatal('Not implemented yet') part_mount = '/mnt/kupfer/fs'
exit() if not os.path.exists(part_mount):
os.makedirs(part_mount)
def umount():
subprocess.run(
[
'umount',
'-lc',
part_mount,
],
stderr=subprocess.DEVNULL,
)
atexit.register(umount)
result = subprocess.run([
'mount',
path,
part_mount,
])
if result.returncode != 0:
logging.fatal(f'Failed to mount {path} to {part_mount}')
exit(1)
dir = os.path.join(part_mount, '.stowaways')
if not os.path.exists(dir):
os.makedirs(dir)
result = subprocess.run([
'rsync',
'--archive',
'--inplace',
'--partial',
'--progress',
'--human-readable',
image_path,
os.path.join(dir, 'kupfer.img'),
])
if result.returncode != 0:
logging.fatal(f'Failed to mount {path} to {part_mount}')
exit(1)
else: else:
result = subprocess.run([ result = subprocess.run([
'dd', 'dd',
f'if={image_name}', f'if={image_path}',
f'of={path}', f'of={path}',
'bs=20M', 'bs=20M',
'iflag=direct', 'iflag=direct',
'oflag=direct', 'oflag=direct',
'status=progress', 'status=progress',
'conv=sync,noerror',
]) ])
if result.returncode != 0: if result.returncode != 0:
logging.info(f'Failed to flash {image_name} to {path}') logging.info(f'Failed to flash {image_path} to {path}')
exit(1) exit(1)
elif what == BOOTIMG: elif what == BOOTIMG:
result = subprocess.run([
'fastboot',
'erase',
'dtbo',
])
if result.returncode != 0:
logging.info(f'Failed to erase dtbo')
exit(1)
path = dump_bootimg(image_name) path = dump_bootimg(image_name)
result = subprocess.run([ result = subprocess.run([
'fastboot', 'fastboot',