Skip to content

Commit 9cfc4ec

Browse files
committed
fix(dryccfile): config not set
1 parent bfe13e5 commit 9cfc4ec

3 files changed

Lines changed: 103 additions & 39 deletions

File tree

rootfs/api/models/build.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -110,28 +110,43 @@ def _get_or_create_config(self):
110110
"""
111111
dryccfile to config
112112
"""
113-
latest_release = Release.latest(self.app)
114-
config_values, config_values_ref, config_healthcheck = [], {}, {}
115-
for group, values in self.dryccfile.get('config', {}).items():
116-
for value in values:
117-
value['group'] = group
118-
config_values.append(value)
113+
config_values, config_values_ref, config_healthcheck, changed_fields = [], {}, {}, set()
114+
if 'config' in self.dryccfile:
115+
for group, values in self.dryccfile.get('config', {}).items():
116+
for value in values:
117+
value['group'] = group
118+
config_values.append(value)
119+
changed_fields.update(["values", "values_refs"])
120+
121+
replace_values_ptypes, replace_healthcheck_ptypes = set(), set()
119122
for ptype, values in self.dryccfile.get('deploy', {}).items():
120-
for value in values.get('config', {}).get('env', []):
121-
value['ptype'] = ptype
122-
config_values.append(value)
123-
for config_ref in values.get('config', {}).get('ref', []):
124-
if ptype not in config_values_ref:
125-
config_values_ref[ptype] = [config_ref]
126-
else:
127-
config_values_ref[ptype].append(config_ref)
123+
if 'config' in values:
124+
for value in values.get('config', {}).get('env', []):
125+
value['ptype'] = ptype
126+
config_values.append(value)
127+
replace_values_ptypes.add(ptype)
128+
for config_ref in values.get('config', {}).get('ref', []):
129+
if ptype not in config_values_ref:
130+
config_values_ref[ptype] = [config_ref]
131+
else:
132+
config_values_ref[ptype].append(config_ref)
133+
replace_values_ptypes.add(ptype)
134+
changed_fields.update(["values", "values_refs"])
135+
128136
if 'healthcheck' in values:
129137
config_healthcheck[ptype] = values.get('healthcheck')
130-
if not config_values:
131-
return latest_release.config
138+
changed_fields.add("healthcheck")
139+
replace_healthcheck_ptypes.add(ptype)
140+
141+
old_config = self.app.release_set.filter(failed=False).latest().config
142+
if not changed_fields:
143+
return old_config
132144
config = Config(
133145
owner=self.owner, app=self.app, values=config_values, values_refs=config_values_ref,
134146
healthcheck=config_healthcheck,
135147
)
136-
config.save(ignore_update_fields=["values", "values_refs", "healthcheck"])
148+
config.merge_field("values", old_config, replace_values_ptypes)
149+
config.merge_field("values_refs", old_config, replace_values_ptypes)
150+
config.merge_field("healthcheck", old_config, replace_healthcheck_ptypes)
151+
config.save(ignore_update_fields=changed_fields)
137152
return config

rootfs/api/models/config.py

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,23 @@ def save(self, ignore_update_fields=None, *args, **kwargs):
134134
previous_config = self.app.config_set.latest()
135135
for field in self.allof_fields:
136136
if ignore_update_fields is None or field not in ignore_update_fields:
137-
getattr(
138-
self,
139-
"_update_%s" % field,
140-
partial(self._update_field, field)
141-
)(previous_config)
137+
self.merge_field(field, previous_config)
142138
except Config.DoesNotExist:
143139
self._update_tags(previous_config={'tags': {}})
144140
return super(Config, self).save(*args, **kwargs)
145141

146-
def _update_field(self, field, previous_config):
147-
data = getattr(previous_config, field, {}).copy()
142+
def merge_field(self, field, old_config, replace_ptypes=[]):
143+
getattr(
144+
self,
145+
"_update_%s" % field,
146+
partial(self._update_field, field)
147+
)(old_config, replace_ptypes)
148+
149+
def _update_field(self, field, previous_config, replace_ptypes=[]):
150+
data = {
151+
k: v for k, v in getattr(previous_config, field, {}).copy().items()
152+
if k not in replace_ptypes
153+
}
148154
new_data = getattr(self, field, {}).copy()
149155
# remove config keys if a null value is provided
150156
for key, value in new_data.items():
@@ -158,8 +164,11 @@ def _update_field(self, field, previous_config):
158164
data[key] = self._merge_data(field, data.get(key, {}), value)
159165
setattr(self, field, data)
160166

161-
def _update_values(self, previous_config):
162-
data = getattr(previous_config, 'values', []).copy()
167+
def _update_values(self, previous_config, replace_ptypes=[]):
168+
data = [
169+
item for item in getattr(previous_config, 'values', []).copy()
170+
if item.get('ptype') not in replace_ptypes
171+
]
163172
new_data = getattr(self, 'values', []).copy()
164173
for new_item in new_data:
165174
added = True
@@ -175,12 +184,15 @@ def _update_values(self, previous_config):
175184
else: # force to string
176185
new_item['value'] = str(new_item['value'])
177186
break
178-
if added and new_item['value'] is not None and new_item['value'] != "":
187+
if added and new_item['value'] is not None:
179188
data.append(new_item)
180189
setattr(self, 'values', data)
181190

182-
def _update_values_refs(self, previous_config):
183-
data = getattr(previous_config, 'values_refs', {}).copy()
191+
def _update_values_refs(self, previous_config, replace_ptypes=[]):
192+
data = {
193+
k: v for k, v in getattr(previous_config, 'values_refs', {}).copy().items()
194+
if k not in replace_ptypes
195+
}
184196
new_data = getattr(self, 'values_refs', {}).copy()
185197
# remove config keys if a null value is provided
186198
for ptype, values in new_data.items():
@@ -192,7 +204,7 @@ def _update_values_refs(self, previous_config):
192204
data.pop(ptype)
193205
else:
194206
values_refs = data.get(ptype, [])
195-
values_refs.extend(new_data.get(ptype, []))
207+
values_refs.extend(values)
196208
data[ptype] = list(set(values_refs))
197209
setattr(self, 'values_refs', data)
198210

@@ -208,9 +220,12 @@ def _merge_data(self, field, data, new_data):
208220
data[key] = value
209221
return data
210222

211-
def _update_tags(self, previous_config):
223+
def _update_tags(self, previous_config, replace_ptypes=[]):
212224
"""verify the tags exist on any nodes as labels"""
213-
data = getattr(previous_config, 'tags', {}).copy()
225+
data = {
226+
k: v for k, v in getattr(previous_config, 'tags', {}).copy().items()
227+
if k not in replace_ptypes
228+
}
214229
new_data = getattr(self, 'tags', {}).copy()
215230
# remove config keys if a null value is provided
216231
for ptype, values in new_data.items():
@@ -236,14 +251,17 @@ def _update_tags(self, previous_config):
236251
'tags', data.get(ptype, {}), values)
237252
setattr(self, 'tags', data)
238253

239-
def _update_limits(self, previous_config):
240-
data = getattr(previous_config, 'limits', {}).copy()
254+
def _update_limits(self, previous_config, replace_ptypes=[]):
255+
data = {
256+
k: v for k, v in getattr(previous_config, 'limits', {}).copy().items()
257+
if k not in replace_ptypes
258+
}
241259
new_data = getattr(self, 'limits', {}).copy()
242260
# check procfile
243-
for key, value in new_data.items():
261+
for ptype, value in new_data.items():
244262
if value is None:
245-
if key in self.app.ptypes:
263+
if ptype in self.app.ptypes:
246264
raise UnprocessableEntity(
247-
"the %s has already been used and cannot be deleted" % key)
265+
"the %s has already been used and cannot be deleted" % ptype)
248266
self._merge_data('limits', data, new_data)
249267
setattr(self, 'limits', data)

rootfs/api/tests/test_config.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
Run the tests with "./manage.py test api"
66
"""
7+
import copy
78
from io import StringIO
89
from django.contrib.auth import get_user_model
910
from django.core.cache import cache
@@ -829,7 +830,7 @@ def test_config_from_dryccfile(self, mock_requests):
829830
'deploy': {
830831
'web': {
831832
'image': "127.0.0.1/cat/cat"
832-
}
833+
},
833834
}
834835
},
835836
}
@@ -876,7 +877,7 @@ def test_config_from_dryccfile(self, mock_requests):
876877
release.config.envs("web"),
877878
{
878879
'GROUP': 'g1', 'DEBUG': 'tr', 'TEST1': 'g1', 'TEST2': 'tr', 'PENV1': 'web',
879-
'PENV2': 'web'
880+
'PENV2': 'web', "WEBSITE": "www.drycc.cc",
880881
}
881882
)
882883
build_body['dryccfile']['deploy']['web']['healthcheck'] = {
@@ -901,3 +902,33 @@ def test_config_from_dryccfile(self, mock_requests):
901902
release.config.healthcheck['web'],
902903
build_body['dryccfile']['deploy']['web']['healthcheck'],
903904
)
905+
# test use old config and healthcheck
906+
new_build_body = copy.deepcopy(build_body)
907+
del new_build_body['dryccfile']['config']
908+
del new_build_body['dryccfile']['deploy']['web']['config']
909+
del new_build_body['dryccfile']['deploy']['web']['healthcheck']
910+
with mock.patch('scheduler.resources.pod.Pod.watch') as mock_kube:
911+
mock_kube.return_value = ['up', 'down']
912+
url = f"/v2/apps/{app_id}/build"
913+
response = self.client.post(url, new_build_body)
914+
self.assertEqual(response.status_code, 201, response.data)
915+
release = app.release_set.latest()
916+
self.assertEqual(release.failed, False)
917+
self.assertEqual(release.config.healthcheck, release.previous().config.healthcheck)
918+
self.assertEqual(release.config.values, release.previous().config.values)
919+
self.assertEqual(release.config.values_refs, release.previous().config.values_refs)
920+
# set empty
921+
new_build_body = copy.deepcopy(build_body)
922+
new_build_body['dryccfile']['config'] = {}
923+
new_build_body['dryccfile']['deploy']['web']['config'] = {}
924+
new_build_body['dryccfile']['deploy']['web']['healthcheck'] = {}
925+
with mock.patch('scheduler.resources.pod.Pod.watch') as mock_kube:
926+
mock_kube.return_value = ['up', 'down']
927+
url = f"/v2/apps/{app_id}/build"
928+
response = self.client.post(url, new_build_body)
929+
self.assertEqual(response.status_code, 201, response.data)
930+
release = app.release_set.latest()
931+
self.assertEqual(release.failed, False)
932+
self.assertEqual(release.config.healthcheck, {'web': {}})
933+
self.assertEqual(release.config.envs("web"), {"WEBSITE": "www.drycc.cc"})
934+
self.assertEqual(release.config.values_refs, {})

0 commit comments

Comments
 (0)