|
16 | 16 | from docker import auth as docker_auth |
17 | 17 | from django.conf import settings |
18 | 18 | from django.db import models |
| 19 | +from django.db.models import F, Func, Value, JSONField |
19 | 20 | from django.contrib.auth import get_user_model |
20 | 21 | from rest_framework.exceptions import ValidationError, NotFound |
21 | 22 |
|
22 | | -from api.utils import get_session |
| 23 | +from api.utils import get_session, dict_diff |
23 | 24 | from api.exceptions import AlreadyExists, DryccException, ServiceUnavailable |
24 | 25 | from api.utils import DeployLock, generate_app_name, apply_tasks |
25 | 26 | from scheduler import KubeHTTPException, KubeException |
@@ -828,29 +829,36 @@ def _scale(self, user, structure, release, app_settings): # noqa |
828 | 829 | structure[target] = int(count) |
829 | 830 | validate_app_structure(structure) |
830 | 831 | 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) |
832 | 835 |
|
833 | 836 | # test for available process types |
834 | 837 | for ptype in structure: |
835 | 838 | if ptype not in (PTYPE_WEB, PTYPE_RUN) and \ |
836 | 839 | 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: |
845 | 848 | try: |
846 | | - self._scale_pods(structure, release, app_settings) |
| 849 | + self._scale_pods(new_scale, release, app_settings) |
847 | 850 | except ServiceUnavailable: |
848 | 851 | # 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) |
850 | 853 | raise |
851 | 854 | # 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 | + ) |
854 | 862 | msg = '{} scaled pods '.format(user.username) + ' '.join( |
855 | 863 | "{}={}".format(k, v) for k, v in list(structure.items())) |
856 | 864 | self.log(msg) |
|
0 commit comments