|
9 | 9 | "strings"
|
10 | 10 |
|
11 | 11 | "github.com/bufbuild/connect-go"
|
| 12 | + "github.com/compose-spec/compose-go/v2/types" |
12 | 13 | "github.com/defang-io/defang/src/pkg"
|
13 | 14 | pb "github.com/defang-io/defang/src/protos/io/defang/v1"
|
14 | 15 | "github.com/defang-io/defang/src/protos/io/defang/v1/defangv1connect"
|
@@ -204,6 +205,16 @@ func ComposeStart(ctx context.Context, client defangv1connect.FabricControllerCl
|
204 | 205 | if svccfg.Deploy.EndpointMode != "" {
|
205 | 206 | return nil, &ComposeError{fmt.Errorf("unsupported compose directive: deploy endpoint_mode")}
|
206 | 207 | }
|
| 208 | + if svccfg.Deploy.Resources.Limits != nil && svccfg.Deploy.Resources.Reservations == nil { |
| 209 | + logrus.Warn("no reservations specified; using limits as reservations") |
| 210 | + } |
| 211 | + reservations := getResourceReservations(svccfg.Deploy.Resources) |
| 212 | + if reservations != nil && reservations.NanoCPUs != "" { |
| 213 | + cpus, err := strconv.ParseFloat(reservations.NanoCPUs, 32) |
| 214 | + if err != nil || cpus < 0 { // "0" just means "as small as possible" |
| 215 | + return nil, &ComposeError{fmt.Errorf("invalid value for cpus: %q", reservations.NanoCPUs)} |
| 216 | + } |
| 217 | + } |
207 | 218 | }
|
208 | 219 | }
|
209 | 220 |
|
@@ -249,15 +260,14 @@ func ComposeStart(ctx context.Context, client defangv1connect.FabricControllerCl
|
249 | 260 | deploy.Replicas = uint32(*svccfg.Deploy.Replicas)
|
250 | 261 | }
|
251 | 262 |
|
252 |
| - reservations := svccfg.Deploy.Resources.Reservations |
253 |
| - if reservations == nil { |
254 |
| - reservations = svccfg.Deploy.Resources.Limits |
255 |
| - } |
| 263 | + reservations := getResourceReservations(svccfg.Deploy.Resources) |
256 | 264 | if reservations != nil {
|
257 |
| - cpus, err := strconv.ParseFloat(reservations.NanoCPUs, 32) |
258 |
| - if err != nil { |
259 |
| - // TODO: move this validation up so we don't upload the build context if it's invalid |
260 |
| - return nil, &ComposeError{fmt.Errorf("invalid reservations cpus: %v", err)} |
| 265 | + cpus := 0.0 |
| 266 | + if reservations.NanoCPUs != "" { |
| 267 | + cpus, err = strconv.ParseFloat(reservations.NanoCPUs, 32) |
| 268 | + if err != nil { |
| 269 | + panic(err) // was already validated above |
| 270 | + } |
261 | 271 | }
|
262 | 272 | var devices []*pb.Device
|
263 | 273 | for _, d := range reservations.Devices {
|
@@ -380,3 +390,11 @@ func ComposeStart(ctx context.Context, client defangv1connect.FabricControllerCl
|
380 | 390 |
|
381 | 391 | return serviceInfos, nil
|
382 | 392 | }
|
| 393 | + |
| 394 | +func getResourceReservations(r types.Resources) *types.Resource { |
| 395 | + if r.Reservations == nil { |
| 396 | + // TODO: we might not want to default to all the limits, maybe only memory? |
| 397 | + return r.Limits |
| 398 | + } |
| 399 | + return r.Reservations |
| 400 | +} |
0 commit comments