@@ -35,6 +35,7 @@ protected function configure()
35
35
'Set the disk size (in MB) of apps or services. '
36
36
. "\nItems are in the format <info>name:value</info> as above. "
37
37
)
38
+ ->addOption ('force ' , 'f ' , InputOption::VALUE_NONE , 'Try to run the update, even if it might exceed your limits ' )
38
39
->addOption ('dry-run ' , null , InputOption::VALUE_NONE , 'Show the changes that would be made, without changing anything ' )
39
40
->addProjectOption ()
40
41
->addEnvironmentOption ()
@@ -134,11 +135,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
134
135
&& $ input ->getOption ('disk ' ) === [];
135
136
136
137
$ updates = [];
138
+ $ current = [];
137
139
foreach ($ services as $ name => $ service ) {
138
140
$ type = $ this ->typeName ($ service );
139
141
$ group = $ this ->group ($ service );
140
142
141
143
$ properties = $ service ->getProperties ();
144
+ $ current [$ group ][$ name ]['resources ' ]['profile_size ' ] = $ properties ['resources ' ]['profile_size ' ];
145
+ $ current [$ group ][$ name ]['instance_count ' ] = $ properties ['instance_count ' ];
146
+ $ current [$ group ][$ name ]['disk ' ] = $ properties ['disk ' ];
147
+ $ current [$ group ][$ name ]['sizes ' ] = $ containerProfiles [$ properties ['container_profile ' ]];
142
148
143
149
$ header = '<options=bold> ' . ucfirst ($ type ) . ': </><options=bold,underscore> ' . $ name . '</> ' ;
144
150
$ headerShown = false ;
@@ -259,6 +265,49 @@ protected function execute(InputInterface $input, OutputInterface $output)
259
265
260
266
$ this ->debug ('Raw updates: ' . json_encode ($ updates , JSON_UNESCAPED_SLASHES ));
261
267
268
+ $ project = $ this ->getSelectedProject ();
269
+ $ organization = $ this ->api ()->getClient ()->getOrganizationById ($ project ->getProperty ('organization ' ));
270
+ $ profile = $ organization ->getProfile ();
271
+ if ($ input ->getOption ('force ' ) === false && isset ($ profile ->resources_limit ) && $ profile ->resources_limit ) {
272
+ $ diff = $ this ->computeMemoryCPUStorageDiff ($ updates , $ current );
273
+ $ limit = $ profile ->resources_limit ['limit ' ];
274
+ $ used = $ profile ->resources_limit ['used ' ]['totals ' ];
275
+
276
+ $ this ->debug ('Raw diff: ' . json_encode ($ diff , JSON_UNESCAPED_SLASHES ));
277
+ $ this ->debug ('Raw limits: ' . json_encode ($ limit , JSON_UNESCAPED_SLASHES ));
278
+ $ this ->debug ('Raw used: ' . json_encode ($ used , JSON_UNESCAPED_SLASHES ));
279
+
280
+ $ errored = false ;
281
+ if ($ limit ['cpu ' ] < $ used ['cpu ' ] + $ diff ['cpu ' ]) {
282
+ $ this ->stdErr ->writeln (sprintf (
283
+ 'The requested resources will exceed your organization \'s trial CPU limit, which is: <comment>%s</comment>. ' ,
284
+ $ limit ['cpu ' ],
285
+ ));
286
+ $ errored = true ;
287
+ }
288
+
289
+ if ($ limit ['memory ' ] < $ used ['memory ' ] + ($ diff ['memory ' ] / 1024 )) {
290
+ $ this ->stdErr ->writeln (sprintf (
291
+ 'The requested resources will exceed your organization \'s trial memory limit, which is: <comment>%sGB</comment>. ' ,
292
+ $ limit ['memory ' ],
293
+ ));
294
+ $ errored = true ;
295
+ }
296
+
297
+ if ($ limit ['storage ' ] < $ used ['storage ' ] + ($ diff ['disk ' ] / 1024 )) {
298
+ $ this ->stdErr ->writeln (sprintf (
299
+ 'The requested resources will exceed your organization \'s trial storage limit, which is: <comment>%sGB</comment>. ' ,
300
+ $ limit ['storage ' ],
301
+ ));
302
+ $ errored = true ;
303
+ }
304
+
305
+ if ($ errored ) {
306
+ $ this ->stdErr ->writeln ('Please adjust your resources or activate your subscription. ' );
307
+ return 1 ;
308
+ }
309
+ }
310
+
262
311
if ($ input ->getOption ('dry-run ' )) {
263
312
return 0 ;
264
313
}
@@ -581,4 +630,65 @@ private function formatErrors(array $errors, $optionName)
581
630
}
582
631
return $ ret ;
583
632
}
633
+
634
+ /**
635
+ * Compute the total memory/CPU/storage diff that will occur when the given update
636
+ * is applied.
637
+ *
638
+ * @param array $updates
639
+ * @param array $current
640
+ *
641
+ * @return array
642
+ */
643
+ private function computeMemoryCPUStorageDiff (array $ updates , array $ current )
644
+ {
645
+ $ diff = [
646
+ 'memory ' => 0 ,
647
+ 'cpu ' => 0 ,
648
+ 'disk ' => 0 ,
649
+ ];
650
+ foreach ($ updates as $ group => $ groupUpdates ) {
651
+ foreach ($ groupUpdates as $ serviceName => $ serviceUpdates ) {
652
+ if (isset ($ current [$ group ][$ serviceName ]['instance_count ' ]) === false ) {
653
+ $ current [$ group ][$ serviceName ]['instance_count ' ] = 1 ;
654
+ }
655
+ if (isset ($ current [$ group ][$ serviceName ]['disk ' ]) === false ) {
656
+ $ current [$ group ][$ serviceName ]['disk ' ] = 0 ;
657
+ }
658
+
659
+ $ currentCount = $ current [$ group ][$ serviceName ]['instance_count ' ];
660
+ $ currentSize = $ current [$ group ][$ serviceName ]['resources ' ]['profile_size ' ];
661
+ $ currentStorage = $ current [$ group ][$ serviceName ]['disk ' ];
662
+
663
+ $ newCount = $ currentCount ;
664
+ $ newSize = $ currentSize ;
665
+ $ newStorage = $ currentStorage ;
666
+ if (isset ($ serviceUpdates ['instance_count ' ])) {
667
+ $ newCount = $ serviceUpdates ['instance_count ' ];
668
+ }
669
+ if (isset ($ serviceUpdates ['resources ' ])) {
670
+ $ newSize = $ serviceUpdates ['resources ' ]['profile_size ' ];
671
+ }
672
+ if (isset ($ serviceUpdates ['disk ' ])) {
673
+ $ newStorage = $ serviceUpdates ['disk ' ];
674
+ }
675
+
676
+ $ currentService = $ current [$ group ][$ serviceName ];
677
+ $ currentSize = $ currentService ['resources ' ]['profile_size ' ];
678
+ $ currentProfile = $ currentService ['sizes ' ][$ currentSize ];
679
+ $ currentCPU = $ currentCount * $ currentProfile ['cpu ' ];
680
+ $ currentRAM = $ currentCount * $ currentProfile ['memory ' ];
681
+
682
+ $ newProfile = $ currentService ['sizes ' ][$ newSize ];
683
+ $ newCPU = $ newCount * $ newProfile ['cpu ' ];
684
+ $ newRAM = $ newCount * $ newProfile ['memory ' ];
685
+
686
+ $ diff ['memory ' ] += $ newRAM - $ currentRAM ;
687
+ $ diff ['cpu ' ] += $ newCPU - $ currentCPU ;
688
+ $ diff ['disk ' ] += $ newStorage - $ currentStorage ;
689
+ }
690
+ }
691
+
692
+ return $ diff ;
693
+ }
584
694
}
0 commit comments