Skip to content

Instantly share code, notes, and snippets.

@zvin
Created September 12, 2018 12:46
Show Gist options
  • Save zvin/2717a09886b5aea19ce872257352e5de to your computer and use it in GitHub Desktop.
Save zvin/2717a09886b5aea19ce872257352e5de to your computer and use it in GitHub Desktop.
#! /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()
@pdcastro
Copy link

pdcastro commented May 14, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment