tools/image-info: add support for naked partitions
In case there is no partition table, we assume the whole image is one big partition and treat is as such. Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
parent
fd33ea1cc7
commit
18934d4249
1 changed files with 61 additions and 43 deletions
104
tools/image-info
104
tools/image-info
|
|
@ -59,25 +59,32 @@ def read_image_format(device):
|
|||
return qemu["format"]
|
||||
|
||||
|
||||
def read_partition(device, bootable, typ=None, start=0, size=0, type=None):
|
||||
blkid = subprocess_check_output(["blkid", "--output", "export", device], parse_environment_vars)
|
||||
return {
|
||||
"label": blkid.get("LABEL"), # doesn't exist for mbr
|
||||
"type": typ,
|
||||
"uuid": blkid["UUID"],
|
||||
"fstype": blkid["TYPE"],
|
||||
"bootable": bootable,
|
||||
"start": start,
|
||||
"size": size
|
||||
}
|
||||
|
||||
|
||||
def read_partition_table(device):
|
||||
sfdisk = subprocess_check_output(["sfdisk", "--json", device], json.loads)
|
||||
ptable = sfdisk["partitiontable"]
|
||||
assert ptable["unit"] == "sectors"
|
||||
|
||||
partitions = []
|
||||
for p in ptable["partitions"]:
|
||||
blkid = subprocess_check_output(["blkid", "--output", "export", p["node"]], parse_environment_vars)
|
||||
partitions.append({
|
||||
"label": blkid.get("LABEL"), # doesn't exist for mbr
|
||||
"type": p["type"],
|
||||
"uuid": blkid["UUID"],
|
||||
"fstype": blkid["TYPE"],
|
||||
"bootable": p.get("bootable", False),
|
||||
"start": p["start"] * 512,
|
||||
"size": p["size"] * 512
|
||||
})
|
||||
|
||||
return ptable["label"], ptable["id"], partitions
|
||||
try:
|
||||
sfdisk = subprocess_check_output(["sfdisk", "--json", device], json.loads)
|
||||
except subprocess.CalledProcessError:
|
||||
partitions.append(read_partition(device, False))
|
||||
return None, None, partitions
|
||||
else:
|
||||
ptable = sfdisk["partitiontable"]
|
||||
assert ptable["unit"] == "sectors"
|
||||
for p in ptable["partitions"]:
|
||||
partitions.append(read_partition(p["node"], p.get("bootable", False), p["type"], p["start"] * 512, p["size"] * 512))
|
||||
return ptable["label"], ptable["id"], partitions
|
||||
|
||||
|
||||
def read_bootloader_type(device):
|
||||
|
|
@ -123,38 +130,49 @@ def rpm_verify(tree):
|
|||
}
|
||||
|
||||
|
||||
def append_filesystem(report, tree):
|
||||
if os.path.exists(f"{tree}/etc/os-release"):
|
||||
report["packages"] = sorted(subprocess_check_output(["rpm", "--root", tree, "-qa"], str.split))
|
||||
report["rpm-verify"] = rpm_verify(tree)
|
||||
|
||||
with open(f"{tree}/etc/os-release") as f:
|
||||
report["os-release"] = parse_environment_vars(f.read())
|
||||
|
||||
try:
|
||||
with open(f"{tree}/etc/fstab") as f:
|
||||
report["fstab"] = sorted([line.split() for line in f.read().split("\n") if line and not line.startswith("#")])
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
with open(f"{tree}/etc/passwd") as f:
|
||||
report["passwd"] = sorted(f.read().strip().split("\n"))
|
||||
|
||||
with open(f"{tree}/etc/group") as f:
|
||||
report["groups"] = sorted(f.read().strip().split("\n"))
|
||||
|
||||
if os.path.exists(f"{tree}/boot") and len(os.listdir(f"{tree}/boot")) > 0:
|
||||
assert "bootmenu" not in report
|
||||
report["bootmenu"] = read_boot_entries(f"{tree}/boot")
|
||||
|
||||
elif len(glob.glob(f"{tree}/vmlinuz-*")) > 0:
|
||||
assert "bootmenu" not in report
|
||||
report["bootmenu"] = read_boot_entries(tree)
|
||||
|
||||
|
||||
report = {}
|
||||
with nbd_connect(image) as device:
|
||||
report["image-format"] = read_image_format(image)
|
||||
report["bootloader"] = read_bootloader_type(device)
|
||||
report["partition-table"], report["partition-table-id"], report["partitions"] = read_partition_table(device)
|
||||
|
||||
n_partitions = len(report["partitions"])
|
||||
for n in range(1, n_partitions + 1):
|
||||
with mount(device + f"p{n}") as tree:
|
||||
if os.path.exists(f"{tree}/etc/os-release"):
|
||||
report["packages"] = sorted(subprocess_check_output(["rpm", "--root", tree, "-qa"], str.split))
|
||||
report["rpm-verify"] = rpm_verify(tree)
|
||||
|
||||
with open(f"{tree}/etc/os-release") as f:
|
||||
report["os-release"] = parse_environment_vars(f.read())
|
||||
|
||||
with open(f"{tree}/etc/fstab") as f:
|
||||
report["fstab"] = sorted([line.split() for line in f.read().split("\n") if line and not line.startswith("#")])
|
||||
|
||||
with open(f"{tree}/etc/passwd") as f:
|
||||
report["passwd"] = sorted(f.read().strip().split("\n"))
|
||||
|
||||
with open(f"{tree}/etc/group") as f:
|
||||
report["groups"] = sorted(f.read().strip().split("\n"))
|
||||
|
||||
if os.path.exists(f"{tree}/boot") and len(os.listdir(f"{tree}/boot")) > 0:
|
||||
assert "bootmenu" not in report
|
||||
report["bootmenu"] = read_boot_entries(f"{tree}/boot")
|
||||
|
||||
elif len(glob.glob(f"{tree}/vmlinuz-*")) > 0:
|
||||
assert "bootmenu" not in report
|
||||
report["bootmenu"] = read_boot_entries(tree)
|
||||
if report["partition-table"]:
|
||||
n_partitions = len(report["partitions"])
|
||||
for n in range(1, n_partitions + 1):
|
||||
with mount(device + f"p{n}") as tree:
|
||||
append_filesystem(report, tree)
|
||||
else:
|
||||
with mount(device) as tree:
|
||||
append_filesystem(report, tree)
|
||||
|
||||
|
||||
json.dump(report, sys.stdout, sort_keys=True, indent=2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue