@@ -254,51 +254,6 @@ func validateLocalVolumeSizes(volumes map[string]*instance.VolumeServerTemplate,
254254 return nil
255255}
256256
257- // sanitizeVolumeMap removes extra data for API validation.
258- //
259- // On the api side, there are two possibles validation schemas for volumes and the validator will be chosen dynamically depending on the passed JSON request
260- // - With an image (in that case the root volume can be skipped because it is taken from the image)
261- // - Without an image (in that case, the root volume must be defined)
262- func sanitizeVolumeMap (volumes map [string ]* instance.VolumeServerTemplate ) map [string ]* instance.VolumeServerTemplate {
263- m := make (map [string ]* instance.VolumeServerTemplate )
264-
265- for index , v := range volumes {
266- // Remove extra data for API validation.
267- switch {
268- // If a volume already got an ID it is passed as it to the API without specifying the volume type.
269- // TODO: Fix once instance accept volume type in the schema validation
270- case v .ID != nil :
271- if strings .HasPrefix (string (v .VolumeType ), "sbs" ) {
272- // If volume is from SBS api, the type must be passed
273- // This rules come from instance API and may not be documented
274- v = & instance.VolumeServerTemplate {
275- ID : v .ID ,
276- Boot : v .Boot ,
277- VolumeType : v .VolumeType ,
278- }
279- } else {
280- v = & instance.VolumeServerTemplate {
281- ID : v .ID ,
282- Name : v .Name ,
283- Boot : v .Boot ,
284- }
285- }
286- // For the root volume (index 0) if the size is 0, it is considered as a volume created from an image.
287- // The size is not passed to the API, so it's computed by the API
288- case index == "0" && v .Size == nil :
289- v = & instance.VolumeServerTemplate {
290- VolumeType : v .VolumeType ,
291- Boot : v .Boot ,
292- }
293- // If none of the above conditions are met, the volume is passed as it to the API
294- default :
295- }
296- m [index ] = v
297- }
298-
299- return m
300- }
301-
302257func preparePrivateNIC (
303258 ctx context.Context , data interface {},
304259 server * instance.Server , vpcAPI * vpc.API ,
@@ -535,34 +490,53 @@ func instanceIPHasMigrated(d *schema.ResourceData) bool {
535490}
536491
537492func instanceServerAdditionalVolumeTemplate (api * BlockAndInstanceAPI , zone scw.Zone , volumeID string ) (* instance.VolumeServerTemplate , error ) {
538- vol , err := api .GetVolume (& instance.GetVolumeRequest {
539- Zone : zone ,
493+ vol , err := api .GetUnknownVolume (& GetUnknownVolumeRequest {
540494 VolumeID : locality .ExpandID (volumeID ),
495+ Zone : zone ,
541496 })
542- if err == nil {
543- return & instance.VolumeServerTemplate {
544- ID : & vol .Volume .ID ,
545- Name : & vol .Volume .Name ,
546- VolumeType : vol .Volume .VolumeType ,
547- Size : & vol .Volume .Size ,
548- }, nil
549- }
550- if ! httperrors .Is404 (err ) {
497+ if err != nil {
551498 return nil , err
552499 }
500+ return vol .VolumeTemplate (), nil
501+ }
502+
503+ func prepareRootVolume (rootVolumeI map [string ]any , serverType * instance.ServerType , image string ) * UnknownVolume {
504+ serverTypeCanBootOnBlock := serverType .VolumesConstraint .MaxSize == 0
505+
506+ rootVolumeIsBootVolume := types .ExpandBoolPtr (types .GetMapValue [bool ](rootVolumeI , "boot" ))
507+ rootVolumeType := types .GetMapValue [string ](rootVolumeI , "volume_type" )
508+ sizeInput := types .GetMapValue [int ](rootVolumeI , "size_in_gb" )
509+ rootVolumeID := zonal .ExpandID (types .GetMapValue [string ](rootVolumeI , "volume_id" )).ID
510+
511+ // If the rootVolumeType is not defined, define it depending on the offer
512+ if rootVolumeType == "" {
513+ if serverTypeCanBootOnBlock {
514+ rootVolumeType = instance .VolumeVolumeTypeBSSD .String ()
515+ } else {
516+ rootVolumeType = instance .VolumeVolumeTypeLSSD .String ()
517+ }
518+ }
553519
554- blockVol , err := api .blockAPI .GetVolume (& blockSDK.GetVolumeRequest {
555- Zone : zone ,
556- VolumeID : locality .ExpandID (volumeID ),
557- })
558- if err == nil {
559- return & instance.VolumeServerTemplate {
560- ID : & blockVol .ID ,
561- Name : & blockVol .Name ,
562- VolumeType : "sbs_volume" ,
563- Size : & blockVol .Size ,
564- }, nil
520+ rootVolumeName := ""
521+ if image == "" { // When creating an instance from an image, volume should not have a name
522+ rootVolumeName = types .NewRandomName ("vol" )
565523 }
566524
567- return nil , err
525+ var rootVolumeSize * scw.Size
526+ if sizeInput == 0 && rootVolumeType == instance .VolumeVolumeTypeLSSD .String () {
527+ // Compute the rootVolumeSize so it will be valid against the local volume constraints
528+ // It wouldn't be valid if another local volume is added, but in this case
529+ // the user would be informed that it does not fulfill the local volume constraints
530+ rootVolumeSize = scw .SizePtr (serverType .VolumesConstraint .MaxSize )
531+ } else if sizeInput > 0 {
532+ rootVolumeSize = scw .SizePtr (scw .Size (uint64 (sizeInput ) * gb ))
533+ }
534+
535+ return & UnknownVolume {
536+ Name : rootVolumeName ,
537+ ID : rootVolumeID ,
538+ InstanceVolumeType : instance .VolumeVolumeType (rootVolumeType ),
539+ Size : rootVolumeSize ,
540+ Boot : rootVolumeIsBootVolume ,
541+ }
568542}
0 commit comments