Created
September 12, 2018 12:46
-
-
Save zvin/2717a09886b5aea19ce872257352e5de to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
import json | |
import sys | |
from contextlib import contextmanager, ExitStack | |
from os import chdir, getcwd | |
from pty import spawn | |
from sh import ErrorReturnCode_32, ErrorReturnCode_12 | |
from sh import losetup, lsblk, mkdir, mount, rmdir, umount | |
from tempfile import mkdtemp | |
from time import sleep | |
@contextmanager | |
def losetup_context_manager(image): | |
print("image", image, losetup) | |
device = losetup("-f", "--show", "-P", image).stdout.decode("utf8").strip() | |
yield device | |
losetup("-d", device) | |
@contextmanager | |
def mount_context_manager(parent_folder, part): | |
folder = parent_folder + "/" + part["name"] | |
mkdir(folder) | |
mounted = False | |
try: | |
mount(part["device"], folder) | |
mounted = True | |
except (ErrorReturnCode_32, ErrorReturnCode_12): | |
print("Warning: couldn't mount", part["name"]) | |
yield folder | |
if mounted: | |
umount(folder) | |
rmdir(folder) | |
@contextmanager | |
def chdir_context_manager(path): | |
old_dir = getcwd() | |
chdir(path) | |
yield | |
chdir(old_dir) | |
def part_name(part): | |
result = part["name"][part["name"].rfind("p") + 1:] | |
label = part["label"] | |
if label is not None: | |
result += "_" + label | |
return result | |
def part_device(part): | |
return "/dev/" + part["name"] | |
def main(): | |
with losetup_context_manager(sys.argv[1]) as device: | |
# sleep requied for labels | |
sleep(1) | |
parts = json.loads(lsblk("--json", "-o", "name,label", device).stdout) | |
parts = parts["blockdevices"][0]["children"] | |
tmpdir = mkdtemp() | |
parts = [ | |
{"name": part_name(part), "device": part_device(part)} | |
for part in parts | |
] | |
with ExitStack() as stack: | |
for part in parts: | |
stack.enter_context(mount_context_manager(tmpdir, part)) | |
print("All image partitons mounted in", tmpdir, "exit this shell to umount.") | |
try: | |
with chdir_context_manager(tmpdir): | |
spawn("/bin/bash") | |
except: | |
pass | |
rmdir(tmpdir) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The python 'sh' package needs to be installed. On Ubuntu 20.04, it can be installed with:
$ sudo apt-get update && sudo apt-get -y install python3 python3-pip $ sudo pip3 install sh $ chmod +x ./mount-image $ sudo ./mount-image balena.img