@@ -7,6 +7,7 @@ package api
77import (
88 "errors"
99 "fmt"
10+ "math"
1011 "os"
1112 "sort"
1213 "strings"
@@ -94,6 +95,36 @@ func CreateVolumeFromHumanSize(api *ScalewayAPI, size string) (*string, error) {
9495 return & volumeID , nil
9596}
9697
98+ // VolumesFromSize returns a string of standard sized volumes from a given size
99+ func VolumesFromSize (size uint64 ) string {
100+ const DefaultVolumeSize float64 = 50000000000
101+ StdVolumeSizes := []struct {
102+ kind string
103+ capacity float64
104+ }{
105+ {"150G" , 150000000000 },
106+ {"100G" , 100000000000 },
107+ {"50G" , 50000000000 },
108+ }
109+
110+ RequiredSize := float64 (size ) - DefaultVolumeSize
111+ Volumes := ""
112+ for _ , v := range StdVolumeSizes {
113+ q := RequiredSize / v .capacity
114+ r := math .Mod (RequiredSize , v .capacity )
115+ RequiredSize = r
116+
117+ if q > 0 {
118+ Volumes += strings .Repeat (v .kind + " " , int (q ))
119+ }
120+ if r == 0 {
121+ break
122+ }
123+ }
124+
125+ return strings .TrimSpace (Volumes )
126+ }
127+
97128// fillIdentifierCache fills the cache by fetching from the API
98129func fillIdentifierCache (api * ScalewayAPI , identifierType int ) {
99130 log .Debugf ("Filling the cache" )
@@ -290,6 +321,25 @@ type ConfigCreateServer struct {
290321 EnableIPV6 bool
291322}
292323
324+ // Return offer from any of the product name or alternate names
325+ func OfferNameFromName (name string , products * ScalewayProductsServers ) (* ProductServer , error ) {
326+ offer , ok := products .Servers [name ]
327+ if ok {
328+ return & offer , nil
329+ }
330+
331+ for _ , v := range products .Servers {
332+ for _ , alt := range v .AltNames {
333+ alt := strings .ToUpper (alt )
334+ if alt == name {
335+ return & v , nil
336+ }
337+ }
338+ }
339+
340+ return nil , fmt .Errorf ("Unknow commercial type: %v" , name )
341+ }
342+
293343// CreateServer creates a server using API based on typical server fields
294344func CreateServer (api * ScalewayAPI , c * ConfigCreateServer ) (string , error ) {
295345 commercialType := os .Getenv ("SCW_COMMERCIAL_TYPE" )
@@ -306,7 +356,7 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) {
306356
307357 var server ScalewayServerDefinition
308358
309- server .CommercialType = commercialType
359+ server .CommercialType = strings . ToUpper ( commercialType )
310360 server .Volumes = make (map [string ]string )
311361 server .DynamicIPRequired = & c .DynamicIPRequired
312362 server .EnableIPV6 = c .EnableIPV6
@@ -336,32 +386,19 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) {
336386 if c .Env != "" {
337387 server .Tags = strings .Split (c .Env , " " )
338388 }
339- switch c .CommercialType {
340- case "VC1M" , "X64-4GB" , "ARM64-4GB" :
341- if c .AdditionalVolumes == "" {
342- c .AdditionalVolumes = "50G"
343- log .Debugf ("This server needs a least 50G" )
344- }
345- case "VC1L" , "X64-8GB" , "X64-15GB" , "ARM64-8GB" :
346- if c .AdditionalVolumes == "" {
347- c .AdditionalVolumes = "150G"
348- log .Debugf ("This server needs a least 150G" )
349- }
350- case "X64-30GB" :
351- if c .AdditionalVolumes == "" {
352- c .AdditionalVolumes = "100G 150G"
353- log .Debugf ("This server needs a least 300G" )
354- }
355- case "X64-60GB" :
356- if c .AdditionalVolumes == "" {
357- c .AdditionalVolumes = "50G 150G 150G"
358- log .Debugf ("This server needs a least 400G" )
359- }
360- case "X64-120GB" :
361- if c .AdditionalVolumes == "" {
362- c .AdditionalVolumes = "150G 150G 150G"
363- log .Debugf ("This server needs a least 500G" )
364- }
389+
390+ products , err := api .GetProductsServers ()
391+ if err != nil {
392+ return "" , fmt .Errorf ("Unable to fetch products list from the Scaleway API: %v" , err )
393+ }
394+ offer , err := OfferNameFromName (server .CommercialType , products )
395+ if err != nil {
396+ return "" , fmt .Errorf ("Unknow commercial type %v: %v" , server .CommercialType , err )
397+ }
398+ if offer .VolumesConstraint .MinSize > 0 && c .AdditionalVolumes == "" {
399+ c .AdditionalVolumes = VolumesFromSize (offer .VolumesConstraint .MinSize )
400+ log .Debugf ("%s needs at least %s. Automatically creates the following volumes: %s" ,
401+ server .CommercialType , humanize .Bytes (offer .VolumesConstraint .MinSize ), c .AdditionalVolumes )
365402 }
366403 if c .AdditionalVolumes != "" {
367404 volumes := strings .Split (c .AdditionalVolumes , " " )
@@ -375,9 +412,9 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) {
375412 server .Volumes [volumeIDx ] = * volumeID
376413 }
377414 }
415+
378416 arch := os .Getenv ("SCW_TARGET_ARCH" )
379417 if arch == "" {
380- server .CommercialType = strings .ToUpper (server .CommercialType )
381418 switch server .CommercialType [:2 ] {
382419 case "C1" :
383420 arch = "arm"
@@ -394,7 +431,7 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) {
394431 }
395432 server .Name = c .Name
396433 inheritingVolume := false
397- _ , err : = humanize .ParseBytes (c .ImageName )
434+ _ , err = humanize .ParseBytes (c .ImageName )
398435 if err == nil {
399436 // Create a new root volume
400437 volumeID , errCreateVol := CreateVolumeFromHumanSize (api , c .ImageName )
0 commit comments