14:02:16 #startmeeting neutron_upgrades 14:02:16 Meeting started Thu Dec 14 14:02:16 2017 UTC and is due to finish in 60 minutes. The chair is ihrachys. Information about MeetBot at http://wiki.debian.org/MeetBot. 14:02:17 Useful Commands: #action #agreed #help #info #idea #link #topic #startvote. 14:02:19 The meeting name has been set to 'neutron_upgrades' 14:02:24 hi 14:02:28 o/ 14:02:31 Hi guys 14:03:09 ihrachys_: Error: Can't start another meeting, one is in progress. Use #endmeeting first. 14:03:27 sorry I was dropped 14:03:33 no problem 14:03:36 I presume bot still considers the meeting started :) 14:03:53 yes 14:04:03 there are no AIs 14:04:05 #topic OVO 14:04:26 https://review.openstack.org/#/q/status:open+project:openstack/neutron+branch:master+topic:bp/adopt-oslo-versioned-objects-for-db 14:04:36 going top to botton 14:04:40 *bottom 14:04:49 https://review.openstack.org/#/c/521797/ "Use Router OVO in external_net_db" 14:05:44 https://review.openstack.org/#/c/521797/10/neutron/db/external_net_db.py 14:05:55 hungpv, I don't follow what you try to achieve there 14:06:08 Hi 14:06:25 you shouldn't need any of that. just build filter dict and pass it to get_objects 14:06:59 I was trying that way 14:07:06 But it does 14:07:07 the only complexity there is that filter dict is built in several gos 14:08:15 It didn't pass the UT 14:08:33 So I come up with that so solution 14:08:35 hungpv, well, then unit test may need a refinement. do you have a link to the failure? 14:09:34 hungpv, we shouldn't routinely add new methods to objects. only when it's absolutely needed. and we should not routinely return sqlalchemy queries from those methods. 14:09:41 I think get_objects is fine for the job 14:09:46 and you just build the dict and pass it 14:09:54 I would need to see the failure to judge more 14:10:08 but it seems like the path forward there 14:10:34 lujinluo, hungpv do I make sense there? 14:10:59 yes, i think get_objects() would do the work 14:11:43 also we need to use LIKE statement 14:13:05 Hum I p'm 14:13:16 Thinking about that 14:13:27 lujinluo, LIKE for what exactly? 14:14:10 But I'm kinda stuck for that way. Trying to build filter dict, and somehow it didn't work 14:14:51 I see there is some more complexity there for rbac 14:15:00 i took a glance at Line 235 in old codes "l3_models.Router.tenant_id.in_(tenants_with_entries)" 14:15:19 tenants_with_entries comes from RBAC 14:15:28 yeah 14:15:53 it's SELECT ... WHERE tenant_id IN (SELECT ...) 14:16:17 this can't be easily modeled directly in OVO 14:17:11 and there is also NOT there 14:17:20 ~tenant_id.in_(...) 14:17:48 that's another thing not available in OVO 14:17:55 how about we manipulate with queried router ovo objects to find all router whose tenant does not belong to tenants_with_entries 14:19:37 thinking 14:20:24 line 206 and 207 is easier 14:21:10 we use get_objects(), then iterate every one of them to find gw_port_id in ports 14:21:11 for rbac subquery, we could just split it out 14:21:19 it shouldn't affect scalability 14:21:29 because it's O(1) 14:21:43 as for NOT, I think we may need to add it to OVO layer first 14:23:11 hmm, is router the only object we used NOT? 14:23:17 lujinluo, yes, ports calculation can be split too 14:23:34 lujinluo, apparently. we didn't have a need it seems before. 14:24:34 ok, then maybe we should add NOT first 14:25:18 another 'solution' is to actually have a specialized method for that matter (count_by_tenant?) to accommodate for lines 234-240 14:26:13 and leave NOT for later 14:26:34 but I am confident that the != '*' case doesn't need any of that, so we could simplify it there 14:27:31 i would prefer we get things done first, and leave some follow-ups to revisit 14:27:41 ok let's go this route. 14:27:59 +1 14:31:00 ok next is https://review.openstack.org/#/c/527570/ "Remove _get_subnets_by_cidr from neutron/db/extraroute_db.py" 14:31:09 I see it's +2, checking if I can nudge right away 14:31:26 thank you, Ihar 14:31:41 ok merging 14:31:49 \o/ 14:31:52 https://review.openstack.org/#/c/506037/ "Part II of Integrate Port OVO" 14:32:01 this seems not ready for prime time 14:32:04 awesome! thanks a lot! 14:32:04 lujinluo, correct? 14:32:17 thanks Ihar and Tuanvu :) 14:32:18 i am pissed off by all the mac_address modification 14:32:27 it comes back and forth 14:33:14 anyway, i will try to fix (hopefully) the remaining missing parts 14:33:46 ok. 14:34:02 https://review.openstack.org/#/c/407868/ "Integration of (Distributed) Port Binding OVO" was quite close to ready the last time I checked 14:34:15 slawek pointed a potential race condition 14:34:53 would you mind have a look? i was thinking making all the delete() + some modifications + create() in one transaction? 14:35:09 https://review.openstack.org/#/c/407868/80/neutron/objects/ports.py@53 ? 14:35:43 yes 14:36:53 ok. I think what slaweq suggests is to have a subtransaction opened for the whole body of update 14:37:38 like we do here https://github.com/openstack/neutron/blob/master/neutron/objects/base.py#L541 14:37:55 yes, this is what i was thinking too 14:37:59 so _load_object is called in scope of the same transaction 14:38:06 making sure we can load all attributes 14:39:31 do we also want a test for it? i was not able to come up with one 14:39:56 I don't think so. it's one of those cases where it just makes sense to have the code to avoid a potential for a race 14:40:15 also, I think we have a test somewhere that validates a single commit() 14:40:48 good. i will only add the subtransaction then 14:40:58 https://github.com/openstack/neutron/blob/master/neutron/tests/unit/objects/test_base.py#L1652-L1665 14:41:38 though it doesn't seem like it failed anywhere here: http://logs.openstack.org/37/506037/9/check/openstack-tox-py27/ea53df0/testr_results.html.gz 14:42:39 it's actually surprising 14:43:06 ah no, it's ot 14:43:07 *not 14:43:09 ^ bad link I guess? 14:43:11 you have some 'new_host' there 14:43:14 what's that? 14:43:20 why not reusing 'host'? 14:43:59 lujinluo, eh, yeah this is correct one: http://logs.openstack.org/68/407868/81/check/openstack-tox-py27/3520ebb/testr_results.html.gz 14:44:03 but it's still passing 14:44:12 I think it's because in the test case, we set all fields 14:44:13 cause then we cannot do self.delete() 14:44:24 but since new_host is not a field, it's not set and so super().update() is called 14:44:25 cause the binding with updated host does not exist yet 14:44:59 lujinluo, what we could do is store the original host in e.g. _load_object 14:45:09 lujinluo, and then reuse it whenever we update the field 14:45:12 to delete 14:45:22 and then use the new field value when creating 14:45:33 so in that way, you have both values available 14:45:50 it's actually surprising that we don't have a way to get old values of fields 14:45:57 in oslo.versionedobjects 14:46:01 yes 14:46:08 we can only get a list of field *names* that were touched 14:46:19 exactly 14:46:31 so, I think we can make an exception for host attribute and cache it on _load_object 14:46:35 does it make sense? 14:47:02 of course, that would belong to the object implementation not base _load_object 14:47:06 it does, but i also need to double check maybe tmr 14:47:21 so you would _load_object and then also setattr(obj, '_cached_host', obj.host) 14:49:12 i am having difficulty understanding '_cached_host' here 14:49:24 do you still suggest i add it as an attribute? 14:49:34 as an attribute, yes 14:49:52 but it would store the original host not the new one 14:50:02 new one would still be using the host field of the object 14:50:12 ah, i see your point 14:50:30 then in update(), when you first need to .delete() you would construct a new object using the cached host value, then call .delete() on it. 14:50:41 after that, you can move forward with .create() 14:50:58 it saves the clearance of 'new_host' 14:51:21 it should also make the UT fail 14:51:44 I would suggest to do the changes without subtransaction, then validate the test fails, then add subtransaction to check it now passes 14:52:04 ack! 14:52:13 cool! 14:52:27 https://review.openstack.org/#/c/527330/ "l3_agentschedulers_db: convert from Agent model to OVO" 14:52:56 I had a comment there 14:53:15 yes, Ihar. Could you please also check comment from An-san 14:53:18 ? 14:53:29 basically, since now we fetch using OVO interface, we should check that OVO class has a field, not that it has an attribute with the name 14:55:24 hmm ... 14:55:35 TuanVu, is it for [None] value? 14:55:55 I think value there is expected as None not [None]? 14:56:07 [None] would actually be true in boolean context 14:57:09 ihrachys, yes, you're right. 14:57:30 ihrachys, sorry i misunderstood here. 14:57:34 np 14:57:51 ok, I got it 14:57:52 I am honestly not entirely sure why this code is there but I would be hesitant to touch it 14:59:00 ok I think we are out of time. anything quick to discuss before we wrap up? 15:00:01 so we should abandon this patch? 15:00:08 no why? 15:00:47 as you mentioned, I guess we don't need to touch that snippet anymore 15:00:54 no, you just do not use getattr() 15:01:07 I think it's good. we still should move to OVO object. it just has different way to express presence of a field 15:01:14 right. 15:01:31 ihrachys, ok, got it. 15:01:37 use Agent.fields.get(...) 15:01:44 thank you, Ihar and Luo 15:01:44 ok we need to wrap up 15:01:50 thanks for all the work you do folks! 15:01:52 #endmeeting