<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 01/21/2014 06:44 AM, Royce Lv wrote:<br>
    </div>
    <blockquote cite="mid:52DE335E.9050200@linux.vnet.ibm.com"
      type="cite">
      <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
      <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 moz-do-not-send="true"
            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>
    </blockquote>
    <br>
    Yeap! I think that way we will have a more modularized and reusable
    code<br>
    <br>
    <blockquote cite="mid:52DE335E.9050200@linux.vnet.ibm.com"
      type="cite"> <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>
    </blockquote>
    <br>
    In fact, in __init__.py I was thinking to add the code made by
    Zhengsheng (in plugins/__init__.py)<br>
    and libvirtmodel.py will have<br>
    <br>
    <br>
    class LibvirtModel(Model):<br>
        self.vms = VMsModel()<br>
        self.templates = TemplatesModel()<br>
        ....<br>
    <br>
    The same way, Zhengsheng did for RootModel() in "[PATCH] Break the
    'sample' plugin's monolithic model into several smaller ones"<br>
    <br>
    <blockquote cite="mid:52DE335E.9050200@linux.vnet.ibm.com"
      type="cite"> <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>
    </blockquote>
    <br>
  </body>
</html>