@@ -482,6 +482,7 @@ func diskPartitionCreate(
482482 log .Errorf ("Failed to get disk name from path %s: %v" , diskPath , err )
483483 return "" , fmt .Errorf ("failed to get disk name from path: %s" , diskPath )
484484 }
485+
485486 startSector , _ := getSectorOffsetFromSize (diskName , startSizeStr )
486487 var endSector uint64
487488 if partitionInfo .End == "0" {
@@ -505,60 +506,82 @@ func diskPartitionCreate(
505506 log .Infof ("Input partition end: " + endSizeStr + ", aligned end sector: " + endSectorStr )
506507
507508 // Create partition
508- var sfdiskScript strings.Builder
509- sfdiskScript .WriteString (fmt .Sprintf ("start=%d " , startSector ))
510- if endSector != 0 {
511- size := endSector - startSector
512- sfdiskScript .WriteString (fmt .Sprintf ("size=%d " , size ))
513- }
514-
515- // Set partition type
509+ // GPT with sgdisk & MBR with sfdisk
516510 if partitionTableType == "gpt" {
517- // For GPT, use GUID
518511 typeGUID := partitionInfo .TypeGUID
519512 if typeGUID == "" && partitionInfo .Type != "" {
520513 typeGUID , _ = PartitionTypeStrToGUID (partitionInfo .Type )
521514 }
515+
516+ startArg := fmt .Sprintf ("%d" , startSector )
517+ var endArg string
518+ if endSector == 0 {
519+ endArg = "0"
520+ } else {
521+ endArg = fmt .Sprintf ("%d" , endSector )
522+ }
523+
524+ // Build sgdisk command: -n (new), -t (type), -c (name)
525+ var parts []string
526+ parts = append (parts , fmt .Sprintf ("-n %d:%s:%s" , partitionNum , startArg , endArg ))
522527 if typeGUID != "" {
523- sfdiskScript . WriteString ( fmt .Sprintf ("type=%s " , typeGUID ))
528+ parts = append ( parts , fmt .Sprintf ("-t %d:%s" , partitionNum , typeGUID ))
524529 }
525- // Set partition name if provided
526530 if partitionName != "" {
527- sfdiskScript .WriteString (fmt .Sprintf ("name=\" %s\" " , partitionName ))
531+ safeName := strings .ReplaceAll (partitionName , "\" " , "\\ \" " )
532+ parts = append (parts , fmt .Sprintf ("-c %d:\" %s\" " , partitionNum , safeName ))
528533 }
534+
535+ cmdStr := fmt .Sprintf ("sudo sgdisk %s %s" , strings .Join (parts , " " ), diskPath )
536+ _ , err = shell .ExecCmd (cmdStr , false , shell .HostPath , nil )
537+ if err != nil {
538+ log .Errorf ("Failed to create GPT partition %d on disk %s: %v" , partitionNum , diskPath , err )
539+ return "" , fmt .Errorf ("failed to create GPT partition %d on disk %s: %w" , partitionNum , diskPath , err )
540+ }
541+
529542 } else {
530- // For MBR, use hex type code
531- var typeCode string
532- switch {
533- case partitionType == "extended" :
534- typeCode = "5"
535- case partitionInfo .FsType == "linux-swap" :
536- typeCode = "82"
537- default :
538- typeCode = "83" // Linux
543+ var sfdiskScript strings.Builder
544+ sfdiskScript .WriteString (fmt .Sprintf ("start=%d " , startSector ))
545+ if endSector != 0 {
546+ size := endSector - startSector
547+ sfdiskScript .WriteString (fmt .Sprintf ("size=%d " , size ))
548+ }
549+
550+ // Set partition type
551+ if partitionTableType == "mbr" {
552+ // For MBR, use hex type code
553+ var typeCode string
554+ switch {
555+ case partitionType == "extended" :
556+ typeCode = "5"
557+ case partitionInfo .FsType == "linux-swap" :
558+ typeCode = "82"
559+ default :
560+ typeCode = "83" // Linux
561+ }
562+ sfdiskScript .WriteString (fmt .Sprintf ("type=%s " , typeCode ))
539563 }
540- sfdiskScript .WriteString (fmt .Sprintf ("type=%s " , typeCode ))
541- }
542564
543- // Handle boot flag
544- for _ , flag := range partitionInfo .Flags {
545- if flag == "boot" {
546- sfdiskScript .WriteString ("bootable " )
547- break
565+ // Handle boot flag
566+ for _ , flag := range partitionInfo .Flags {
567+ if flag == "boot" {
568+ sfdiskScript .WriteString ("bootable " )
569+ break
570+ }
548571 }
549- }
550572
551- // Create the partition using sfdisk
552- cmdStr := fmt .Sprintf ("echo '%s' | sudo sfdisk --no-reread --append %s" ,
553- sfdiskScript .String (), diskPath )
554- _ , err = shell .ExecCmd (cmdStr , false , shell .HostPath , nil )
555- if err != nil {
556- log .Errorf ("Failed to create partition %d on disk %s: %v" , partitionNum , diskPath , err )
557- return "" , fmt .Errorf ("failed to create partition %d on disk %s: %w" , partitionNum , diskPath , err )
573+ // Create the partition using sfdisk
574+ cmdStr := fmt .Sprintf ("echo '%s' | sudo sfdisk --no-reread --append %s" ,
575+ sfdiskScript .String (), diskPath )
576+ _ , err = shell .ExecCmd (cmdStr , false , shell .HostPath , nil )
577+ if err != nil {
578+ log .Errorf ("Failed to create partition %d on disk %s: %v" , partitionNum , diskPath , err )
579+ return "" , fmt .Errorf ("failed to create partition %d on disk %s: %w" , partitionNum , diskPath , err )
580+ }
558581 }
559582
560583 // Refresh partition table using partx
561- cmdStr = fmt .Sprintf ("partx -u %s" , diskPath )
584+ cmdStr : = fmt .Sprintf ("partx -u %s" , diskPath )
562585 _ , err = shell .ExecCmd (cmdStr , true , shell .HostPath , nil )
563586 if err != nil {
564587 log .Errorf ("Failed to refresh partition table after creating partition %d: %v" , partitionNum , err )
@@ -698,8 +721,33 @@ func DiskPartitionsCreate(diskPath string, partitionsList []config.PartitionInfo
698721 return nil , fmt .Errorf ("failed to create GPT partition table on disk %s: %w" , diskPath , err )
699722 }
700723
724+ indexPlaceholder := map [int ]string {}
725+ for _ , p := range partitionsList {
726+ if p .Index != nil {
727+ if * p .Index <= 0 {
728+ return nil , fmt .Errorf ("partition %q: index must be > 0 (got %d)" , p .ID , * p .Index )
729+ }
730+ if prev , ok := indexPlaceholder [* p .Index ]; ok {
731+ return nil , fmt .Errorf ("duplicate partition index %d used by %q and %q" , * p .Index , prev , p .ID )
732+ }
733+ indexPlaceholder [* p .Index ] = p .ID
734+ }
735+ }
736+
737+ var partitionNum int
701738 for i , partitionInfo := range partitionsList {
702- partitionNum := i + 1
739+ if partitionInfo .Index != nil {
740+ partitionNum = * partitionInfo .Index
741+ } else {
742+ assignedIndex := i + 1
743+ for {
744+ if _ , used := indexPlaceholder [assignedIndex ]; ! used {
745+ break
746+ }
747+ assignedIndex ++
748+ }
749+ partitionNum = assignedIndex
750+ }
703751 diskPartDev , err := diskPartitionCreate (diskPath , partitionNum , partitionInfo , partitionTableType , "primary" )
704752 if err != nil {
705753 for i := 1 ; i < partitionNum ; i ++ {
0 commit comments