<div dir="ltr">Hey, Fuelers<div><br></div><div>TL;DR This email is about how to make </div><div><br></div><div>* Intro</div><div>I want to bring up one of the important topics on how to make Fuel more flexible. Some of you know that we have been discussing means of doing this internally and now it is time to share these thoughts with all of you.</div><div><br></div><div>As you could know per Evgeniy Li's message [0] we are looking forward splitting Fuel (specifically it's Fuel-Web) part into set of microservices each one serving their own purpose like networking configuration, partitioning, etc. </div><div><br></div><div><br></div><div>And while we are working on this it seems that we need to get rid of so-called Nailgun serializers that are put too close to business logic engine, that have a lot of duplicating attributes; you are not able to easily modify or extend them; you are not able to change their behaviour even when Fuel Library is capable of doing so - everything is hardcoded in Nailgun code without clear separation between business logic and actual deployment workflow data generation and orchestration.</div><div><br></div><div>Let me give you an example:<br></div><div><br></div><div>* Case A. Replace Linux bridges with OVS bridges by default</div><div><br></div><div>We all know that we removed OVS as much as possible from our reference architecture due to its buginess. Imagine a situation when someone magically fixed OVS and wants to use it as a provider for generic bonds and bridge. It actually means that he needs to set default provider in network_scheme for l23network puppet module to 'ovs' instead of 'lnx'. Imagine, he has put this magical OVS into a package and created a plugin. The problem here will be that he needs to override what network serializer is sending to the nodes.</div><div><br></div><div>But the problem here is that he cannot do it without editing Nailgun code or override this serializer in any way.</div><div><br></div><div>* Case B. Make Swift Partitions Known to Fuel Library</div><div><br></div><div>Imagine, you altered the way you partition your disk in Nailgun. You created a special role for swift disks which should occupy the whole disk. In this case you should be able to get this info from api and feed it to swift deployment task. But it is not so easy - this stuff is still hardcoded in deployment serializers like {mp} field of nodes array of hashes.</div><div><br></div><div>* Proposed solution</div><div><br></div><div>In order to tackle this I propose to extract these so called serializers (see links [1] and [2]) and put them closer to library. You can see that half of the code is actually duplicated for deployment and provsioning serializers and there is actually no inheritance of common code betwen them. If you want to introduce new attribute and put it into astute.yaml, you will need to rewrite Nailgun code. This is not very deployment/sysop/sysadmin engineer-friendly. Essentially, the proposal is to introduce a library of such `serializers` (I would like to call them translators actually) which could leverage inheritance, polymorphism and incapsulation pretty much in OOP mode but with ability for deployment engineers to apply versioning to serializers and allow each particular task to work with different sources of data with different versions of API.</div><div><br></div><div>What this actually means: each task has a step called 'translation' which fetches attributes from any arbitrary set of sources and converts them into the format that is consumable by the deployment stage of this task. From our current architectural point of view it will look like generation of a set of yaml files that will be merged by hiera so that each puppet task can leverage the power of hiera. </div><div><br></div><div>This actually means that in scope of our modularization initiative each module should have an API which will be accessed by those tasks in runtime right before the tasks are executed. This also means that if a user changes some of the values in the databases of those modules, rerun of such task will lead to a different result of 'translation' and trigger some actions like 'keystone_config ~> Service[keystone]' in puppet.</div><div><br></div><div>There is a tough discussion (etherpad here:[4]) on:</div><div><br></div><div>1) how to handle versioning/revert capabilities</div><div>2) where to store output produced by those 'translators'</div><div>3) which type of the storage to use</div><div><br></div><div>Please, feel free to provide your feedback on this approach and tell me where this approach is going to be wrong.</div><div><br></div><div>[0] <a href="http://permalink.gmane.org/gmane.comp.cloud.openstack.devel/66563" target="_blank">http://permalink.gmane.org/gmane.comp.cloud.openstack.devel/66563</a><br></div><div>[1] <a href="https://github.com/stackforge/fuel-web/blob/master/nailgun/nailgun/orchestrator/deployment_serializers.py" target="_blank">https://github.com/stackforge/fuel-web/blob/master/nailgun/nailgun/orchestrator/deployment_serializers.py</a></div><div>[2] <a href="https://github.com/stackforge/fuel-web/blob/master/nailgun/nailgun/orchestrator/provisioning_serializers.py" target="_blank">https://github.com/stackforge/fuel-web/blob/master/nailgun/nailgun/orchestrator/provisioning_serializers.py</a></div><div>[3] <a href="https://github.com/xenolog/l23network">https://github.com/xenolog/l23network</a></div><div>[4] <a href="https://etherpad.openstack.org/p/data-processor-per-component">https://etherpad.openstack.org/p/data-processor-per-component</a><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div><div dir="ltr">Yours Faithfully,<br>Vladimir Kuklin,<br>Fuel Library Tech Lead,<br>Mirantis, Inc.<br>+7 (495) 640-49-04<br>+7 (926) 702-39-68<br>Skype kuklinvv<br>35bk3, Vorontsovskaya Str.<br>Moscow, Russia,<br><a href="http://www.mirantis.ru/" target="_blank">www.mirantis.com</a><br><a href="http://www.mirantis.ru/" target="_blank">www.mirantis.ru</a><br><a href="mailto:vkuklin@mirantis.com" target="_blank">vkuklin@mirantis.com</a></div></div></div></div>
</div></div>