Skip to content

Commit 963171d

Browse files
authored
fix(controller): scale cover structure (#169)
1 parent 0be99a3 commit 963171d

3 files changed

Lines changed: 29 additions & 22 deletions

File tree

rootfs/api/models/app.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
from docker import auth as docker_auth
1717
from django.conf import settings
1818
from django.db import models
19+
from django.db.models import F, Func, Value, JSONField
1920
from django.contrib.auth import get_user_model
2021
from rest_framework.exceptions import ValidationError, NotFound
2122

22-
from api.utils import get_session
23+
from api.utils import get_session, dict_diff
2324
from api.exceptions import AlreadyExists, DryccException, ServiceUnavailable
2425
from api.utils import DeployLock, generate_app_name, apply_tasks
2526
from scheduler import KubeHTTPException, KubeException
@@ -828,29 +829,36 @@ def _scale(self, user, structure, release, app_settings): # noqa
828829
structure[target] = int(count)
829830
validate_app_structure(structure)
830831
except (TypeError, ValueError, ValidationError) as e:
831-
raise DryccException('Invalid scaling format: {}'.format(e))
832+
err_msg = 'Invalid scaling format: {}'.format(e)
833+
self.log(err_msg)
834+
raise DryccException(err_msg)
832835

833836
# test for available process types
834837
for ptype in structure:
835838
if ptype not in (PTYPE_WEB, PTYPE_RUN) and \
836839
ptype not in release.ptypes:
837-
raise NotFound(
838-
'Container type {} does not exist in application'.format(ptype))
839-
840-
# merge current structure and the new items together
841-
old_structure = self.structure
842-
new_structure = old_structure.copy()
843-
new_structure.update(structure)
844-
if new_structure != self.structure:
840+
err_msg = 'Container type {} does not exist in application'.format(ptype)
841+
self.log(err_msg)
842+
raise NotFound(err_msg)
843+
844+
new_scale = dict_diff(structure, self.structure).get("changed", {})
845+
old_scale = dict_diff(self.structure, structure).get("changed", {})
846+
847+
if new_scale:
845848
try:
846-
self._scale_pods(structure, release, app_settings)
849+
self._scale_pods(new_scale, release, app_settings)
847850
except ServiceUnavailable:
848851
# scaling failed, go back to old scaling numbers
849-
self._scale_pods(old_structure, release, app_settings)
852+
self._scale_pods(old_scale, release, app_settings)
850853
raise
851854
# save new structure to the database
852-
self.structure = new_structure
853-
self.save()
855+
App.objects.filter(id=self.id).update(
856+
structure=Func(
857+
F("structure"),
858+
Value(new_scale, JSONField()),
859+
function="jsonb_concat",
860+
)
861+
)
854862
msg = '{} scaled pods '.format(user.username) + ' '.join(
855863
"{}={}".format(k, v) for k, v in list(structure.items()))
856864
self.log(msg)

rootfs/api/tests/test_build.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,23 +259,23 @@ def test_build_forgotten_procfile(self, mock_requests):
259259
response = self.client.post(url, body)
260260
self.assertEqual(response.status_code, 201, response.data)
261261

262-
# verify worker is not there
262+
# verify worker is not there, only web
263263
url = f"/v2/apps/{app_id}/pods/"
264264
response = self.client.get(url)
265265
self.assertEqual(response.status_code, 200, response.data)
266-
self.assertEqual(len(response.data['results']), 0)
266+
self.assertEqual(len(response.data['results']), 1)
267267

268-
# verify web is not there
268+
# verify web is in there
269269
url = f"/v2/apps/{app_id}/pods/"
270270
response = self.client.get(url)
271271
self.assertEqual(response.status_code, 200, response.data)
272-
self.assertEqual(len(response.data['results']), 0)
272+
self.assertEqual(len(response.data['results']), 1)
273273

274274
# look at the app structure
275275
url = f"/v2/apps/{app_id}"
276276
response = self.client.get(url)
277277
self.assertEqual(response.status_code, 200, response.data)
278-
self.assertEqual(response.json()['structure'], {'web': 0})
278+
self.assertEqual(response.json()['structure'], {'web': 1})
279279

280280
@override_settings(DRYCC_DEPLOY_PROCFILE_MISSING_REMOVE=False)
281281
def test_build_no_remove_process(self, mock_requests):

rootfs/api/tests/test_pods.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,11 +752,10 @@ def test_modified_procfile_from_build_removes_pods(self, mock_requests):
752752
}
753753
response = self.client.post(build_url, body)
754754
self.assertEqual(response.status_code, 201, response.data)
755-
756-
# make sure no pods are web
755+
# web is default ptype
757756
application = App.objects.get(id=app_id)
758757
pods = application.list_pods(type='web')
759-
self.assertEqual(len(pods), 0)
758+
self.assertEqual(len(pods), 4)
760759

761760
def test_list_pods_failure(self, mock_requests):
762761
"""

0 commit comments

Comments
 (0)