def create_image(self, size, iformat): '''Creates a disk image and rounds up the size to full blocks for best alignment. QEMU has a problem if the block size is less than 4096 bytes so we round to full 4096 bytes blocks. The function returns the rounded size. Supported images are: qcow, qcow2, raw :param int size: size in bytes :param str iformat: image format. See \ :data:`servus.validators.VALID_DISKFMT` :raises ValueError: if the iformat parameter is not a valid image format :raises servus.exceptions.DiskError: if the image creation failed :raises IOError: if the image file already exists :returns int: rounded up size for best alignment ''' if not iformat in ('qcow', 'qcow2', 'raw'): raise ValueError('Invalid disk format \'%s\'' % iformat) if self.exists: raise IOError('Can\'t create image file. Image \'%s\' '\ 'already exists' % self._devpath ) nsize = blktools.blockround(size, blocksize=4096) qemu.create_imagefile(self._devpath, nsize, iformat) self._size = nsize self._exists = True self._disk_format = iformat return nsize
def parts_align(partlist, disksize, roundto=4096, startpos=1048576): '''Aligns the partitions for later partitioning :param list partlist: a list of :class:`servus.block.Partition`\ instances :param int size: size of the disk in bytes :param str filesystem: default filesystem :param int startpos: defaults to 1048576 bytes (2048 Blocks of 512 Bytes) :param int roundto: round to full blocks of this size. Defaults to 4096\ because of some NBD quirks. Its also the default block size for most\ modern file systems like Ext4 and therefore the choice for best\ alignment. ''' if not len(partlist): return [] num = 0 empty = None asize = startpos for part in partlist: size = part.size if size is not None: size = blktools.blockround(size, roundto) asize += size else: if empty is not None: raise exc.DiskError('ERROR: Can\'t calculate partition size '\ 'because more than one partitions don\'t have a size given') empty = num part.sysnum = num + 1 num += 1 if empty is not None: left = disksize - asize psize = blktools.blockround(left, roundto, round_down=True) partlist[empty].size = psize asize += psize if asize > disksize: missing = asize - disksize raise exc.DiskError('ERROR: The size of all partitions is larger '\ 'than the whole disk. Missing at least %d bytes' % missing) partlist[0].startpos = startpos nstart = startpos + partlist[0].size for part in partlist[1:]: part.startpos = nstart nstart += part.size