blob: a8b6b96840bbed6ca4158d69fa9017d743892e39 [file] [log] [blame]
#!/usr/bin/env python
"""
Copyright 2017 The Fuchsia Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
This modules provides an interface to build minfs images from fuchsia
manifest files.
"""
import os
import stat
import subprocess
import sys
def _get_file_len(path):
"""Returns the length of an input file in bytes. """
fd = os.open(path, os.O_RDONLY)
try:
return os.lseek(fd, 0, os.SEEK_END)
finally:
os.close(fd)
def build_minfs_image(manifest_path, minfs_image_path, minfs_bin):
"""Populate a minfs container with the contents specified by the fuchsia
manifest file.
"""
# Determine the length of the minfs image. Note that this works on
# regular files as well as block devices so it should allow us to
# use the minfs tool to manipulate block devices.
minfs_image_len = _get_file_len(minfs_image_path)
disk_path = "%s@%d" % (minfs_image_path, minfs_image_len)
minfs_cmd = [minfs_bin, disk_path, "cp", None, None]
# parse the manifest file and find the files to copy
file_count = 0
created_dirs = set()
with open(manifest_path, "r") as manifest_file:
for line in manifest_file:
if "=" not in line:
continue
if line.count("=") != 1:
raise Exception("Unexpected format, too many equal signs: %d" %
line.count("="))
parts = line.split("=")
parts[0] = parts[0].strip()
parts[1] = parts[1].strip()
# first figure out if we need to make a directory for this file
# This should split file name off the past
dir_path = os.path.split(parts[0])[0]
# track the directories we need to make for this file
dirs_to_make = []
# see if the directory for this file has been created
while dir_path != "" and dir_path not in created_dirs:
dir_path, new_dir = os.path.split(dir_path)
dirs_to_make.append(new_dir)
# now create the directory path
while len(dirs_to_make) > 0:
dir_path = os.path.join(dir_path, dirs_to_make.pop())
mkdir_cmd = [minfs_bin, disk_path, "mkdir", "::%s" % dir_path]
try:
subprocess.check_call(mkdir_cmd)
except (subprocess.CalledProcessError):
print "Error creating directory '%s'" % dir_path
sys.exit(-1)
except (OSError):
print "Unable to execute minfs"
sys.exit(-1)
# record that we've created this directory
created_dirs.add(dir_path)
targ_path = "::%s" % parts[0]
minfs_cmd[3] = parts[1]
minfs_cmd[4] = targ_path
try:
subprocess.check_call(minfs_cmd)
except (subprocess.CalledProcessError):
print "Error copying file %s" % parts[1]
sys.exit(-1)
except (OSError):
print "Unable to execute minfs"
sys.exit(-1)
file_count += 1
# some status output
sys.stdout.write("%s\r" % (" " * 100))
sys.stdout.write("Copying '%s' \r" % parts[0])
sys.stdout.flush()
return file_count