package disk import ( "io" "math/rand" "github.com/google/uuid" "github.com/osbuild/osbuild-composer/internal/blueprint" ) const ( sectorSize = 512 BIOSBootPartitionGUID = "21686148-6449-6E6F-744E-656564454649" BIOSBootPartitionUUID = "FAC7F1FB-3E8D-4137-A512-961DE09A5549" FilesystemDataGUID = "0FC63DAF-8483-4772-8E79-3D69D8477DE4" FilesystemDataUUID = "CB07C243-BC44-4717-853E-28852021225B" EFISystemPartitionGUID = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" EFISystemPartitionUUID = "68B2905B-DF3E-4FB3-80FA-49D1E773AA33" EFIFilesystemUUID = "7B77-95E7" RootPartitionUUID = "6264D520-3FB9-423F-8AB8-7A0A8E3D3562" ) func CreatePartitionTable( mountpoints []blueprint.FilesystemCustomization, imageSize uint64, basePartitionTable PartitionTable, rng *rand.Rand, ) PartitionTable { if bootPartition := basePartitionTable.BootPartition(); bootPartition != nil { // the boot partition UUID needs to be set since this // needs to be randomly generated bootPartition.Filesystem.UUID = uuid.Must(newRandomUUIDFromReader(rng)).String() } for _, m := range mountpoints { if m.Mountpoint != "/" { partitionSize := m.MinSize / sectorSize partition := basePartitionTable.createPartition(m.Mountpoint, partitionSize, rng) basePartitionTable.Partitions = append(basePartitionTable.Partitions, partition) } } if tableSize := basePartitionTable.getPartitionTableSize(); imageSize < tableSize { imageSize = tableSize } basePartitionTable.Size = imageSize // start point for all of the arches is // 2048 sectors. var start uint64 = basePartitionTable.updatePartitionStartPointOffsets(2048) // treat the root partition as a special case // by setting the size dynamically rootPartition := basePartitionTable.RootPartition() rootPartition.Size = ((imageSize / sectorSize) - start - 100) rootPartition.Filesystem.UUID = uuid.Must(newRandomUUIDFromReader(rng)).String() basePartitionTable.updateRootPartition(*rootPartition) return basePartitionTable } func (pt *PartitionTable) createPartition(mountpoint string, size uint64, rng *rand.Rand) Partition { filesystem := Filesystem{ Type: "xfs", UUID: uuid.Must(newRandomUUIDFromReader(rng)).String(), Mountpoint: mountpoint, FSTabOptions: "defaults", FSTabFreq: 0, FSTabPassNo: 0, } if pt.Type != "gpt" { return Partition{ Size: size, Filesystem: &filesystem, } } return Partition{ Size: size, Type: FilesystemDataGUID, UUID: uuid.Must(newRandomUUIDFromReader(rng)).String(), Filesystem: &filesystem, } } func newRandomUUIDFromReader(r io.Reader) (uuid.UUID, error) { var id uuid.UUID _, err := io.ReadFull(r, id[:]) if err != nil { return uuid.Nil, err } id[6] = (id[6] & 0x0f) | 0x40 // Version 4 id[8] = (id[8] & 0x3f) | 0x80 // Variant is 10 return id, nil }