Exemple #1
0
 def test_write_value_at_offset(self):
     image = Image(self.img, MiB(2))
     image.write_value_at_offset(801, 130031)
     # Now open the path independently, seek to the given offset, and read
     # 4 bytes, then interpret it as a little-endian 32-bit integer.
     with open(image.path, 'rb') as fp:
         fp.seek(130031)
         # Unpack always returns a tuple, but there's only one item there.
         value, *ignore = unpack('<I', fp.read(4))
     self.assertEqual(value, 801)
 def test_write_value_at_offset(self):
     image = Image(self.img, MiB(2))
     image.write_value_at_offset(801, 130031)
     # Now open the path independently, seek to the given offset, and read
     # 4 bytes, then interpret it as a little-endian 32-bit integer.
     with open(image.path, 'rb') as fp:
         fp.seek(130031)
         # Unpack always returns a tuple, but there's only one item there.
         value, *ignore = unpack('<I', fp.read(4))
     self.assertEqual(value, 801)
Exemple #3
0
 def test_write_value_at_offsets_near_end(self):
     image = Image(self.img, 10000)
     # Attempt to write a bunch of values near the end of the file.  Since
     # the value will always be a 32-bit value, any positions farther out
     # than 4 bytes before the end will fail.
     results = set()
     for pos in range(9995, 10002):
         with suppress(ValueError):
             image.write_value_at_offset(801, pos)
             self.assertEqual(os.path.getsize(self.img), 10000)
             results.add(pos)
     self.assertEqual(results, {9995, 9996})
 def test_write_value_at_offsets_near_end(self):
     image = Image(self.img, 10000)
     # Attempt to write a bunch of values near the end of the file.  Since
     # the value will always be a 32-bit value, any positions farther out
     # than 4 bytes before the end will fail.
     results = set()
     for pos in range(9995, 10002):
         with suppress(ValueError):
             image.write_value_at_offset(801, pos)
             self.assertEqual(os.path.getsize(self.img), 10000)
             results.add(pos)
     self.assertEqual(results, {9995, 9996})
 def _make_one_disk(self, imgfile, name, volume):
     part_id = 1
     # Create the image object for the selected volume schema
     image = Image(imgfile, volume.image_size, volume.schema)
     offset_writes = []
     part_offsets = {}
     # We first create all the needed partitions.
     # For regular core16 and core18 builds, this means creating all of the
     # defined partitions.  For core20 (the so called 'seeded images'), we
     # only create all the role-less partitions and mbr + system-seed.
     # The rest is created dynamically by snapd on first boot.
     for part in volume.structures:
         if part.name is not None:
             part_offsets[part.name] = part.offset
         if part.offset_write is not None:
             offset_writes.append((part.offset, part.offset_write))
         if (part.role is StructureRole.mbr or part.type == 'bare' or
                 self._should_skip_partition(part)):
             continue
         activate = False
         if (volume.schema is VolumeSchema.mbr and
                 part.role is StructureRole.system_boot):
             activate = True
         elif (volume.schema is VolumeSchema.gpt and
                 part.role is StructureRole.system_data and
                 part.name is None):
             part.name = 'writable'
         image.partition(part.offset, part.size, part.name, activate)
     # Now since we're done, we need to do a second pass to copy the data
     # and set all the partition types.  This needs to be done like this as
     # libparted's commit() operation resets type GUIDs to defaults and
     # clobbers things like hybrid MBR partitions.
     part_id = 1
     for i, part in enumerate(volume.structures):
         if self._should_skip_partition(part):
             continue
         image.copy_blob(volume.part_images[i],
                         bs=image.sector_size,
                         seek=part.offset // image.sector_size,
                         count=ceil(part.size / image.sector_size),
                         conv='notrunc')
         if part.role is StructureRole.mbr or part.type == 'bare':
             continue
         image.set_parition_type(part_id, part.type)
         part_id += 1
     for value, dest in offset_writes:
         # Decipher non-numeric offset_write values.
         if isinstance(dest, tuple):
             dest = part_offsets[dest[0]] + dest[1]
         image.write_value_at_offset(value // image.sector_size, dest)
 def _make_one_disk(self, imgfile, name, volume):
     part_id = 1
     # Create the image object for the selected volume schema
     image = Image(imgfile, volume.image_size, volume.schema)
     offset_writes = []
     part_offsets = {}
     # We first create all the partitions.
     for part in volume.structures:
         if part.name is not None:
             part_offsets[part.name] = part.offset
         if part.offset_write is not None:
             offset_writes.append((part.offset, part.offset_write))
         if part.role is StructureRole.mbr or part.type == 'bare':
             continue
         activate = False
         if (volume.schema is VolumeSchema.mbr and
                 part.role is StructureRole.system_boot):
             activate = True
         elif (volume.schema is VolumeSchema.gpt and
                 part.role is StructureRole.system_data and
                 part.name is None):
             part.name = 'writable'
         image.partition(part.offset, part.size, part.name, activate)
     # Now since we're done, we need to do a second pass to copy the data
     # and set all the partition types.  This needs to be done like this as
     # libparted's commit() operation resets type GUIDs to defaults and
     # clobbers things like hybrid MBR partitions.
     part_id = 1
     for i, part in enumerate(volume.structures):
         image.copy_blob(volume.part_images[i],
                         bs=image.sector_size,
                         seek=part.offset // image.sector_size,
                         count=ceil(part.size / image.sector_size),
                         conv='notrunc')
         if part.role is StructureRole.mbr or part.type == 'bare':
             continue
         image.set_parition_type(part_id, part.type)
         part_id += 1
     for value, dest in offset_writes:
         # Decipher non-numeric offset_write values.
         if isinstance(dest, tuple):
             dest = part_offsets[dest[0]] + dest[1]
         image.write_value_at_offset(value // image.sector_size, dest)