@@ -424,7 +424,11 @@ func (o *ops) findEfiDirectory(device string) (string, error) {
424
424
err error
425
425
)
426
426
if err = utils .Retry (3 , 5 * time .Second , o .log , func () (err error ) {
427
- _ , err = o .ExecPrivilegeCommand (nil , "mount" , partitionForDevice (device , "2" ), "/mnt" )
427
+ partitionPath , err := o .partitionForDevice (device , 2 )
428
+ if err != nil {
429
+ return errors .Wrapf (err , "failed to get partition for device %s" , device )
430
+ }
431
+ _ , err = o .ExecPrivilegeCommand (nil , "mount" , partitionPath , "/mnt" )
428
432
return
429
433
}); err != nil {
430
434
return "" , errors .Wrap (err , "failed to mount efi device" )
@@ -1029,59 +1033,125 @@ func (o *ops) ignitionPlatformId() string {
1029
1033
return id
1030
1034
}
1031
1035
1036
+ type lsblkBlockDevice struct {
1037
+ Name string `json:"name"`
1038
+ Type string `json:"type"`
1039
+ Size int64 `json:"size"`
1040
+ Children []* lsblkBlockDevice `json:"children"`
1041
+ }
1042
+
1043
+ type lsblkOutput struct {
1044
+ Blockdevices []* lsblkBlockDevice `json:"blockdevices"`
1045
+ }
1046
+
1032
1047
func stripDev (device string ) string {
1033
1048
return strings .Replace (device , "/dev/" , "" , 1 )
1034
1049
}
1035
1050
1036
- func partitionNameForDeviceName (deviceName , partitionNumber string ) string {
1037
- var format string
1038
- switch {
1039
- case strings .HasPrefix (deviceName , "nvme" ):
1040
- format = "%sp%s"
1041
- case strings .HasPrefix (deviceName , "mmcblk" ):
1042
- format = "%sP%s"
1043
- default :
1044
- format = "%s%s"
1051
+ func findDeviceInLsblkOutput (device string , devices []* lsblkBlockDevice ) (* lsblkBlockDevice , error ) {
1052
+ for _ , blockDev := range devices {
1053
+ if blockDev .Name == device {
1054
+ return blockDev , nil
1055
+ }
1045
1056
}
1046
- return fmt .Sprintf (format , deviceName , partitionNumber )
1057
+
1058
+ // Now recurse on Children
1059
+ for _ , blockDev := range devices {
1060
+ if blockDev .Children == nil {
1061
+ continue
1062
+ }
1063
+
1064
+ if found , err := findDeviceInLsblkOutput (device , blockDev .Children ); err == nil {
1065
+ return found , nil
1066
+ }
1067
+ }
1068
+
1069
+ return nil , errors .Errorf ("device %s not found in lsblk output" , device )
1047
1070
}
1048
1071
1049
- func partitionForDevice (device , partitionNumber string ) string {
1050
- return "/dev/" + partitionNameForDeviceName (stripDev (device ), partitionNumber )
1072
+ func getPartitionInLsblkOutput (deviceName string , partitionNumber int , lsblkJsonOutRaw string ) (string , error ) {
1073
+ if partitionNumber < 1 {
1074
+ return "" , errors .Errorf ("partition number must be greater than 0, got %d" , partitionNumber )
1075
+ }
1076
+
1077
+ // The partition number is 1-based, so we need to subtract 1 to get the correct index
1078
+ partitionIndex := partitionNumber - 1
1079
+
1080
+ var output lsblkOutput
1081
+ if err := json .Unmarshal ([]byte (lsblkJsonOutRaw ), & output ); err != nil {
1082
+ return "" , errors .Wrapf (err , "failed to parse lsblk JSON output for device %s" , deviceName )
1083
+ }
1084
+
1085
+ dev , err := findDeviceInLsblkOutput (deviceName , output .Blockdevices )
1086
+ if err != nil {
1087
+ return "" , errors .Wrapf (err , "failed to find device %s in lsblk output" , deviceName )
1088
+ }
1089
+
1090
+ partitionChildren := funk .Filter (dev .Children , func (child * lsblkBlockDevice ) bool {
1091
+ return child .Type == "part"
1092
+ }).([]* lsblkBlockDevice )
1093
+
1094
+ if len (partitionChildren ) <= partitionIndex {
1095
+ return "" , errors .Errorf ("device %s has less than %d partitions" , deviceName , partitionNumber )
1096
+ }
1097
+
1098
+ return partitionChildren [partitionIndex ].Name , nil
1051
1099
}
1052
1100
1053
- func (o * ops ) calculateFreePercent (device string ) (int64 , error ) {
1054
- type node struct {
1055
- Name string
1056
- Size int64
1057
- Children []* node
1101
+ func (o * ops ) partitionNameForDeviceName (deviceName string , partitionNumber int ) (string , error ) {
1102
+ devPath := fmt .Sprintf ("/dev/%s" , deviceName )
1103
+ // We use --bytes because we want to share structs with calculateFreePercent which expects
1104
+ // lsblk sizes in bytes. If you don't do that, size can be displayed as a human readable string which
1105
+ // will cause an error when unmarshalling the JSON.
1106
+ lsblkOutputRaw , err := o .ExecPrivilegeCommand (nil , "lsblk" , "--bytes" , "--json" )
1107
+ if err != nil {
1108
+ return "" , errors .Wrapf (err , "failed to run lsblk on device %s" , devPath )
1058
1109
}
1059
- var disks struct {
1060
- Blockdevices []* node
1110
+
1111
+ partitionName , err := getPartitionInLsblkOutput (deviceName , partitionNumber , lsblkOutputRaw )
1112
+ if err != nil {
1113
+ return "" , errors .Wrapf (err , "failed to get partition name for device %s" , devPath )
1114
+ }
1115
+
1116
+ return partitionName , nil
1117
+ }
1118
+
1119
+ func (o * ops ) partitionForDevice (device string , partitionNumber int ) (string , error ) {
1120
+ partitionName , err := o .partitionNameForDeviceName (stripDev (device ), partitionNumber )
1121
+ if err != nil {
1122
+ return "" , errors .Wrapf (err , "failed to get partition name for device %s" , device )
1061
1123
}
1124
+ return fmt .Sprintf ("/dev/%s" , partitionName ), nil
1125
+ }
1126
+
1127
+ func (o * ops ) calculateFreePercent (device string ) (int64 , error ) {
1128
+ var disks lsblkOutput
1062
1129
var (
1063
- diskNode , partitionNode * node
1130
+ diskNode , partitionNode * lsblkBlockDevice
1064
1131
ok bool
1065
1132
)
1066
- ret , err := o .ExecPrivilegeCommand (nil , "lsblk" , "-b " , "-J " )
1133
+ ret , err := o .ExecPrivilegeCommand (nil , "lsblk" , "--bytes " , "--json " )
1067
1134
if err != nil {
1068
1135
return 0 , errors .Wrap (err , "failed to run lsblk command" )
1069
1136
}
1070
1137
if err = json .Unmarshal ([]byte (ret ), & disks ); err != nil {
1071
1138
return 0 , errors .Wrap (err , "failed to unmarshal lsblk output" )
1072
1139
}
1073
1140
deviceName := stripDev (device )
1074
- diskNode , ok = funk .Find (disks .Blockdevices , func (n * node ) bool { return deviceName == n .Name }).(* node )
1141
+ diskNode , ok = funk .Find (disks .Blockdevices , func (n * lsblkBlockDevice ) bool { return deviceName == n .Name }).(* lsblkBlockDevice )
1075
1142
if ! ok {
1076
1143
return 0 , errors .Errorf ("failed to find device is %s in lsblk output" , device )
1077
1144
}
1078
- partitionName := partitionNameForDeviceName (diskNode .Name , "4" )
1079
- partitionNode , ok = funk .Find (diskNode .Children , func (n * node ) bool { return partitionName == n .Name }).(* node )
1145
+ partitionName , err := o .partitionNameForDeviceName (diskNode .Name , 4 )
1146
+ if err != nil {
1147
+ return 0 , errors .Wrapf (err , "failed to find partition name for device %s" , diskNode .Name )
1148
+ }
1149
+ partitionNode , ok = funk .Find (diskNode .Children , func (n * lsblkBlockDevice ) bool { return partitionName == n .Name }).(* lsblkBlockDevice )
1080
1150
if ! ok {
1081
1151
return 0 , errors .Errorf ("failed to find partition node %s in lsblk output" , device )
1082
1152
}
1083
1153
var usedSize int64
1084
- funk .ForEach (diskNode .Children , func (n * node ) { usedSize += n .Size })
1154
+ funk .ForEach (diskNode .Children , func (n * lsblkBlockDevice ) { usedSize += n .Size })
1085
1155
1086
1156
// The assumption is that the extra space needed for image overwrite is not more than the existing partition size. So
1087
1157
// the partition size will be doubled, and the rest will remain as free space.
@@ -1116,9 +1186,18 @@ func (o *ops) OverwriteOsImage(osImage, device string, extraArgs []string) error
1116
1186
o .log .Infof ("Running on s390x archtiecture - skip overwrite image." )
1117
1187
return nil
1118
1188
}
1189
+ mntPartition , err := o .partitionForDevice (device , 4 )
1190
+ if err != nil {
1191
+ return errors .Wrapf (err , "failed to get fourth partition for device %s" , device )
1192
+ }
1193
+
1194
+ mntBootPartition , err := o .partitionForDevice (device , 3 )
1195
+ if err != nil {
1196
+ return errors .Wrapf (err , "failed to get third (boot) partition for device %s" , device )
1197
+ }
1119
1198
cmds := []* cmd {
1120
- makecmd ("mount" , partitionForDevice ( device , "4" ) , "/mnt" ),
1121
- makecmd ("mount" , partitionForDevice ( device , "3" ) , "/mnt/boot" ),
1199
+ makecmd ("mount" , mntPartition , "/mnt" ),
1200
+ makecmd ("mount" , mntBootPartition , "/mnt/boot" ),
1122
1201
growpartcmd ,
1123
1202
makecmd ("xfs_growfs" , "/mnt" ),
1124
1203
0 commit comments