1 ##########################################################################
2 # Copyright (c) 2016, ETH Zurich.
5 # This file is distributed under the terms in the attached LICENSE file.
6 # If you do not find this file, copies can be found by writing to:
7 # ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
8 ##########################################################################
15 def __init__(self, image, size):
21 self._sizeMB= size * 1024 * 1024
24 # size of the disk in blocks
25 self._sizeBlocks= self._sizeMB / self._blockSize
26 # first block of partition
27 self._startBlock = 2048
29 # size of partition in blocks
30 self._partSizeBlocks = self._sizeBlocks - self._startBlock
32 # calculate byte offset to first partition and format as mformat name
33 self._mformatImage="%s@@%d" % (self._image, self._startBlock*self._blockSize)
37 def _cmd(self, command, **kwargs):
38 print(" ".join(command))
39 return subprocess.check_call(command, **kwargs)
43 self._cmd(["dd", "if=/dev/zero", "of=%s" % self._image,
44 "bs=%d" % self._blockSize, "count=1",
45 "seek=%d" % (self._sizeBlocks - 1)])
47 self._cmd(["/sbin/parted", "-s", self._image, "mktable", "gpt"])
48 self._cmd(["/sbin/parted", "-s", self._image, "mkpart", "primary", "fat32",
49 "%ds" % self._startBlock, "%ds" % self._partSizeBlocks])
50 self._cmd(["/sbin/parted", "-s", self._image, "align-check", "optimal", "1"])
51 self._cmd(["/sbin/parted", "-s", self._image, "name", "1", "UEFI"])
53 self._cmd(["mformat", "-i", self._mformatImage, "-T",
54 str(self._partSizeBlocks), "-h", "1", "-s", "1"])
55 # mdir fails if the root directory is empty. We create a directory here
56 # to make sure _initDirCache does not fail.
57 self._cmd(["mmd", "-i", self._mformatImage, "dummy"])
59 # reset directory cache
62 def _initDirCache(self):
63 if not self._dirs is None:
66 cmd = ["mdir", "-i", self._mformatImage, "-/b"]
68 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
69 for line in proc.stdout:
70 if line.endswith("/"):
71 self._dirs.add(line[:-1])
73 def _createParentDir(self, dirName):
74 """ Create a parent directory for passed directory name """
75 parentDir = os.path.dirname(dirName)
78 basename = "::/%s" % parentDir
79 if not basename in self._dirs:
80 self._createParentDir(parentDir)
81 self._cmd(["mmd", "-i", self._mformatImage, basename])
82 self._dirs.add(basename)
85 def addFile(self, inFile, fileName):
86 if self._dirs is None:
88 dirName = self._createParentDir(fileName)
89 targetFile = os.path.join(dirName, os.path.basename(fileName))
90 self._cmd(["mcopy", "-o", "-s", "-i", self._mformatImage, inFile, targetFile])
92 def writeFile(self, fileName, contents):
93 if self._dirs is None:
95 dirName = self._createParentDir(fileName)
96 cmd = ["mcopy", "-o", "-s", "-i", self._mformatImage, "-", os.path.join(dirName, os.path.basename(fileName))]
98 proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
99 proc.communicate(contents)