<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    On 2014年01月21日 13:09, Zhou Zheng Sheng wrote:<br>
    <font color="#000000"><span style="white-space: pre;">&gt; on
        2014/01/21 11:31, Zhou Zheng Sheng wrote:<br>
        &gt;&gt; on 2014/01/17 10:24, Aline Manera wrote:<br>
        &gt;&gt;&gt; From: Aline Manera <a class="moz-txt-link-rfc2396E" href="mailto:alinefm@br.ibm.com">&lt;alinefm@br.ibm.com&gt;</a><br>
        &gt;&gt;&gt; <br>
        &gt;&gt;&gt; I am sending the first patch set to refactor model
        It is not<br>
        &gt;&gt;&gt; completed. I still need to do a lot of tests and so
        on. But I<br>
        &gt;&gt;&gt; would like to share it with you to get your
        suggestion.<br>
        &gt;&gt;&gt; <br>
        &gt;&gt;&gt; Basically, the common code between model and
        mockmodel was placed<br>
        &gt;&gt;&gt; into model/&lt;resource&gt;.py and the specific
        code into<br>
        &gt;&gt;&gt; model/libvirtbackend.py and mockbackend.py<br>
        &gt;&gt;&gt; <br>
        &gt;&gt;&gt; *** It still needs a lot of work *** - Tests all
        functions -<br>
        &gt;&gt;&gt; Update Makefile and spec files - Update test cases<br>
        &gt;&gt;&gt; <br>
        &gt;&gt;&gt; Aline Manera (13): refactor model: Create a
        separated model for<br>
        &gt;&gt;&gt; task resource refactor model: Create a separated
        model for<br>
        &gt;&gt;&gt; debugreport resource refactor model: Create a
        separated model for<br>
        &gt;&gt;&gt; config resource refactor model: Create a separated
        model for host<br>
        &gt;&gt;&gt; resource refactor model: Create a separated model
        for plugin<br>
        &gt;&gt;&gt; resource refactor model: Create a separated model
        for libvirt<br>
        &gt;&gt;&gt; connection refactor model: Move StoragePooldef from
        model to <br>
        &gt;&gt;&gt; libvirtstoragepools.py refactor model: Create a
        separated model<br>
        &gt;&gt;&gt; for storagepool resource refactor model: Create a
        separated model<br>
        &gt;&gt;&gt; for storagevolume resource refactor model: Create a
        separated<br>
        &gt;&gt;&gt; model for interface and network resources refactor
        model: Create<br>
        &gt;&gt;&gt; a separated model for template resource refactor
        model: Create a<br>
        &gt;&gt;&gt; separated model for vm resource refactor model:
        Update server.py<br>
        &gt;&gt;&gt; and root.py to use new models<br>
        &gt;&gt;&gt; <br>
        &gt;&gt;&gt; src/kimchi/control/base.py             |   32 +- <br>
        &gt;&gt;&gt; src/kimchi/control/config.py           |   30 +- <br>
        &gt;&gt;&gt; src/kimchi/control/debugreports.py     |   18 +- <br>
        &gt;&gt;&gt; src/kimchi/control/host.py             |   24 +- <br>
        &gt;&gt;&gt; src/kimchi/control/interfaces.py       |   11 +- <br>
        &gt;&gt;&gt; src/kimchi/control/networks.py         |   11 +- <br>
        &gt;&gt;&gt; src/kimchi/control/plugins.py          |   13 +- <br>
        &gt;&gt;&gt; src/kimchi/control/storagepools.py     |   32 +- <br>
        &gt;&gt;&gt; src/kimchi/control/storagevolumes.py   |   24 +- <br>
        &gt;&gt;&gt; src/kimchi/control/tasks.py            |   11 +- <br>
        &gt;&gt;&gt; src/kimchi/control/templates.py        |   11 +- <br>
        &gt;&gt;&gt; src/kimchi/control/utils.py            |    2 +- <br>
        &gt;&gt;&gt; src/kimchi/control/vms.py              |   17 +- <br>
        &gt;&gt;&gt; src/kimchi/mockmodel.py                |  784
        -------------- <br>
        &gt;&gt;&gt; src/kimchi/model.py                    | 1827<br>
        &gt;&gt;&gt; --------------------------------
        src/kimchi/model/__init__.py<br>
        &gt;&gt;&gt; |   21 + src/kimchi/model/config.py             |  
        52 + <br>
        &gt;&gt;&gt; src/kimchi/model/debugreports.py       |   86 ++ <br>
        &gt;&gt;&gt; src/kimchi/model/host.py               |   49 + <br>
        &gt;&gt;&gt; src/kimchi/model/interfaces.py         |   48 + <br>
        &gt;&gt;&gt; src/kimchi/model/libvirtbackend.py     |  955
        +++++++++++++++++ <br>
        &gt;&gt;&gt; src/kimchi/model/libvirtconnection.py  |  123 +++ <br>
        &gt;&gt;&gt; src/kimchi/model/libvirtstoragepool.py |  225 ++++
        <br>
        &gt;&gt;&gt; src/kimchi/model/mockbackend.py        |  338
        ++++++ <br>
        &gt;&gt;&gt; src/kimchi/model/networks.py           |  115 ++ <br>
        &gt;&gt;&gt; src/kimchi/model/plugins.py            |   29 + <br>
        &gt;&gt;&gt; src/kimchi/model/storagepools.py       |   86 ++ <br>
        &gt;&gt;&gt; src/kimchi/model/storagevolumes.py     |   95 ++ <br>
        &gt;&gt;&gt; src/kimchi/model/tasks.py              |   45 + <br>
        &gt;&gt;&gt; src/kimchi/model/templates.py          |   89 ++ <br>
        &gt;&gt;&gt; src/kimchi/model/vms.py                |  164 +++ <br>
        &gt;&gt;&gt; src/kimchi/networkxml.py               |    6 +- <br>
        &gt;&gt;&gt; src/kimchi/root.py                     |   24 +- <br>
        &gt;&gt;&gt; src/kimchi/server.py                   |   16 +- <br>
        &gt;&gt;&gt; src/kimchi/vmtemplate.py               |   18 +- 35
        files<br>
        &gt;&gt;&gt; changed, 2674 insertions(+), 2757 deletions(-)
        delete mode 100644<br>
        &gt;&gt;&gt; src/kimchi/mockmodel.py delete mode 100644
        src/kimchi/model.py <br>
        &gt;&gt;&gt; create mode 100644 src/kimchi/model/__init__.py
        create mode<br>
        &gt;&gt;&gt; 100644 src/kimchi/model/config.py create mode
        100644<br>
        &gt;&gt;&gt; src/kimchi/model/debugreports.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/host.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/interfaces.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/libvirtbackend.py create mode
        100644<br>
        &gt;&gt;&gt; src/kimchi/model/libvirtconnection.py create mode
        100644<br>
        &gt;&gt;&gt; src/kimchi/model/libvirtstoragepool.py create mode
        100644<br>
        &gt;&gt;&gt; src/kimchi/model/mockbackend.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/networks.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/plugins.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/storagepools.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/storagevolumes.py create mode
        100644<br>
        &gt;&gt;&gt; src/kimchi/model/tasks.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/templates.py create mode 100644<br>
        &gt;&gt;&gt; src/kimchi/model/vms.py<br>
        &gt;&gt;&gt; <br>
        &gt;&gt; <br>
        &gt;&gt; I do not like this approach. It just put everything
        into the <br>
        &gt;&gt; libvirtbackend instead of in the current monolithic
        model class.<br>
        &gt;&gt; We still get monolithic libvirtbackend module. While
        the change is<br>
        &gt;&gt; big, but we do not benefit much in terms of logic
        splitting and<br>
        &gt;&gt; modulization.<br>
        &gt;&gt; <br>
        &gt;&gt; I'm proposing another mechanism. Maybe I'll send the
        patches<br>
        &gt;&gt; later.<br>
        &gt;&gt; <br>
        &gt; <br>
        &gt; The libvirtbackend in "Refactor model" patches is still a
        monolithic <br>
        &gt; class. This is due to the following reasons.<br>
        &gt; <br>
        &gt; 1. Before the split, all controllers use the same model
        instance, and<br>
        &gt; we can feed the root controller a mock model instance to
        have all <br>
        &gt; controllers work on the mock one.<br>
        &gt; <br>
        &gt; 2. After the controller split and model split, we want
        concrete <br>
        &gt; controllers call concrete models, for example, VM
        controller calls<br>
        &gt; VM model. This seems OK but there is no way to switch all
        concrete <br>
        &gt; controllers to call mock models.<br>
        &gt; <br>
        &gt; 3. So comes a new layer of abstraction. A "backend" concept
        was <br>
        &gt; introduced and the "backend" does the actual work. The
        models share<br>
        &gt; the same "backend", and we just feed a real "backend" or
        mock<br>
        &gt; "backend" to switch between production mode and test mode.
        The key<br>
        &gt; problem of "share one thing" v.s. "modulization" is still
        not<br>
        &gt; solved.<br>
        &gt; <br>
        &gt; I think we have many ways to solve this problem. The key
        problem is <br>
        &gt; after split how we enable the concrete controllers call
        concrete<br>
        &gt; models while we can easily switch between real models and
        mock<br>
        &gt; models.<br>
        &gt; <br>
        &gt; The first way is that we can have it automatically
        synthesize a<br>
        &gt; single module instance from all the concrete instances, and
        all the<br>
        &gt; controllers still call this single model instance. This is
        feasible<br>
        &gt; because the synthesis is automatic, the logic and
        responsibilities<br>
        &gt; are still split to each concrete model.</span></font><br>
    I think common logic abstraction is good.<br>
    While Zhengsheng's point here is to maintain the consistency between
    old model api and new model api(e.g. vms_get_list),<br>
    So that testcases in test_model.py can switch to newest seamless.
    What about combine 1st and 2nd proposal?<br>
    <br>
    Our aim is:<br>
    1. reuse common logic between mockmodel implementation and model
    implementation.<br>
    2. make libvirt or mock implementation confined to there own class
    and transparent to caller.<br>
    3. keep consistency between old model api and refactored api to make
    test_model.py testcases reusable.<br>
    <br>
    To address 1 and 2 we can adopt Zhengsheng's proposal of factory
    pattern.<br>
        1. Abstract common logic in a parent class, like we did in
    VMScreenshot(we need to limit the lookup inside)<br>
        2. libvirt and mock reload their own logic as we do in
    LibvirtVMScreenshot and MockVMScreenshot.<br>
    <br>
    To address 3 we can use a synthesize single module together with
    Sheldon's module function probe:<br>
    (REF: [Kimchi-devel] [PATCH 1/4] improve controller: add a method to
    load root sub collections/resouces automatically)<br>
    <br>
    Under model directory: there are vm.py, storagepool.py, etc<br>
    <br>
    in __init__.py:<br>
    <br>
    class LibvirtModel(object):<br>
        model_type = 'real'<br>
    <br>
        def __init__(self):<br>
    <br>
             modules = listPathModules('./')<br>
             for module in modules:<br>
                 # probe libvirt vm modules and classes, see sheldon's
    patch for module probe implementation<br>
                 module = imp.load_module()<br>
                 cls_names = self._get_classes(module)<br>
    <br>
                 # assgin these class methods to Model class, see
    zhengsheng's patch for synthesize:<br>
                 ....<br>
                 m =getattr(model_instance,member_name,None)<br>
                 setattr(self,'%s_%s'%(method_prefix,member_name),m)<br>
                <br>
    <br>
        def _get_classes(module):<br>
            klasses = []<br>
            for name, obj in inspect.getmembers(module):<br>
                if inspect.isclass(obj):<br>
                    klasses.append(name)<br>
    <br>
    The whole refactor thing is huge, I suggest we do it one by one,
    starting from parts which is easy to decouple, like distro, host<br>
    and things depend less on each other, not swallow it all at once.<br>
    Also Mark has proposal to make the db and libvirt connection to be a
    singleton so that class does not need to keep instance of it.<br>
    He will follow up with this thread.|<br>
    <br>
    <span style="white-space: pre;">&gt; <br>
      &gt; <br>
      &gt; The second way is to introduce an abstract model factory. We
      can have<br>
      &gt; a "real" model factory instance and a "mock" one to produce
      only<br>
      &gt; "mock" model instance. We let the concrete controller request
      the<br>
      &gt; model factory instance to construct a concrete model
      instance. Then<br>
      &gt; we can easily switch between the production mode and test
      mode by<br>
      &gt; feeding the root controller with a real model factory
      instance or a<br>
      &gt; mock one. This is feasible because the factory just cares the<br>
      &gt; creation of a concrete model, the inner model
      responsibilities are<br>
      &gt; still wrapped within the concrete model.<br>
      &gt; <br>
      &gt; I'm proposing the first way because the change will be
      minimum and <br>
      &gt; non-intrusive. I'm trying to send the patches later...<br>
      &gt; </span><br>
    <br>
    <br>
  </body>
</html>