Explorar o código

[ADD] workflow

robert %!s(int64=6) %!d(string=hai) anos
pai
achega
903f61de77
Modificáronse 11 ficheiros con 373 adicións e 284 borrados
  1. 1 1
      __init__.py
  2. BIN=BIN
      __init__.pyc
  3. 3 4
      __openerp__.py
  4. 1 1
      models/__init__.py
  5. BIN=BIN
      models/__init__.pyc
  6. 0 165
      models/odoo_container.py
  7. BIN=BIN
      models/odoo_container.pyc
  8. 214 0
      models/system_instance.py
  9. 154 7
      templates.xml
  10. 0 63
      views/odoo_container.xml
  11. 0 43
      views/payment_plan.xml

+ 1 - 1
__init__.py

@@ -1,2 +1,2 @@
 # -*- coding: utf-8 -*-
-import models
+import models

BIN=BIN
__init__.pyc


+ 3 - 4
__openerp__.py

@@ -5,11 +5,10 @@
     'category': 'Tools',
     'version': '0.1',
     'depends': [
-        'base'
+        'base',
+        'web'
     ],
     'data': [
-        'templates.xml',
-        'views/odoo_container.xml',
-        'views/payment_plan.xml'
+        'templates.xml'
     ]
 }

+ 1 - 1
models/__init__.py

@@ -1,3 +1,3 @@
 # -*- coding: utf-8 -*-
 import payment_plan
-import odoo_container
+import system_instance

BIN=BIN
models/__init__.pyc


+ 0 - 165
models/odoo_container.py

@@ -1,165 +0,0 @@
-# -*- coding: utf-8 -*-
-from openerp import models, fields, api
-from openerp.tools import config
-from openerp.exceptions import Warning
-from random import randint
-from jinja2 import Environment, PackageLoader
-from subprocess import check_output
-from ..utils import docker_api
-import os
-import unicodedata
-import stringcase
-import time
-
-
-class OdooContainer(models.Model):
-    _name = 'odoo.container'
-
-    CONTAINER_STATUS = [
-        ('draft', 'Por activar'),
-        ('activated', 'Activado'),
-        ('disapproved', 'No aprobado'),
-        ('suspended', 'Suspendido'),
-        ('destroyed', 'Eliminado')
-    ]
-
-    name = fields.Char(string='Name', size=50)
-    normalized_name = fields.Char(string='Normalized name', compute='_normalize_name', size=50)
-    logo = fields.Binary(string='Logo')
-    internal_ip = fields.Char(string='Internal IP', size=15)
-    internal_port = fields.Integer(string='Internal port')
-    external_ip = fields.Char(string='External IP', size=15)
-    external_port = fields.Integer(string='External port')
-    expose_ip = fields.Boolean(string='Expose IP', default=True)
-    state = fields.Selection(string='Estado', selection=CONTAINER_STATUS, default='draft')
-    demo = fields.Boolean(string='Is Demo?', default=False)
-    domain = fields.Char(string='Dominio', size=100)
-    active = fields.Boolean(string='Is Active', default=False)
-    payment_plan_id = fields.Many2one(string='Payment plan', comodel_name='payment.plan', required=True)
-
-    @api.one
-    # @api.depends('name')
-    def _normalize_name(self):
-        try:
-            name = unicodedata.normalize('NFKD', self.name)
-            name = name.encode('ASCII', 'ignore')
-        except TypeError:
-            pass
-
-        name = stringcase.trimcase(name)
-        name = stringcase.lowercase(name)
-        self.normalized_name = stringcase.snakecase(name)
-
-    @api.one
-    def action_activate(self):
-        print(self)
-
-    def check_existence(self):
-        root_path = config['odoo_root_path'] or None
-
-        if not root_path:
-            raise Warning('No se puede encontrar la configuración')
-
-        system_path = os.path.join(root_path, self.normalized_name)
-
-        if system_path:
-            raise Warning('Ya existe un sistema con este nombre')
-
-        return True
-
-    def check_docker_port(self, port):
-        if port == 0:
-            return False
-
-        if port in docker_api.get_all_external_ports():
-            return False
-
-        return True
-
-    def take_randomized_port(self):
-        port_range = config['odoo_ports_range']
-        port_range = map(lambda x: int(x.strip()), port_range.split(','))
-
-        port = 0
-
-        while not self.check_docker_port(port):
-            port = randint(port_range[0], port_range[1])
-            time.sleep(0.3)
-
-        self.external_port = port
-
-    def create_odoo_folders(self):
-        root_path = config('odoo_root_path')
-        defaults_path = config('odoo_defaults_path')
-
-        for p in defaults_path:
-            full_path = os.path.join(root_path, self.normalized_name, p.strip())
-            os.makedirs(full_path)
-
-            time.sleep(0.3)
-
-        return True
-
-    def create_odoo_config(self):
-        config_path = os.path.join(config('odoo_root_path'), self.normalized_name, 'config')
-
-        if not os.path.exists(config_path):
-            return False
-
-        env = Environment(loader=PackageLoader('resources'))
-
-        template = env.get_template('openerp-server.j2')
-        rendered = template.stream({
-            'admin_password': config('odoo_default_password'),
-            'db_host': config('odoo_db_host'),
-            'db_name': self.normalized_name,
-            'db_user': config('db_user'),
-            'db_password': config('db_password')
-        })
-
-        rendered.dump(os.path.join(config_path, 'openerp-server.conf'))
-
-        return True
-
-    def create_odoo_db(self):
-        cmd = 'createdb -U %s %s' % (config('db_user'), self.normalized_name)
-        result = docker_api.run_command(config('odoo_db_container'), cmd)
-
-        return result
-
-    def copy_odoo_db_seed(self):
-        backup_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'resources', 'odoo.tar')
-        return docker_api.copy_in(config('odoo_db_container'), '/tmp', backup_path)
-
-    def restore_odoo_db(self):
-        cmd = 'psql -U %s -d %s -f %s' % (config('db_user'), self.normalized_name, '/tmp/odoo.sql')
-        return docker_api.run_command(config('odoo_db_container'), cmd)
-
-    def remove_odoo_db_seed(self):
-        cmd = 'rm -f %s' % '/tmp/odoo.sql'
-        return docker_api.run_command(config('odoo_db_container'), cmd)
-
-    def create_odoo_container(self):
-        result = docker_api.run_container(
-            image=config('odoo_image'),
-            name=self.normalized_name,
-            ports={'8069/tcp': self.external_port},
-            volumes=None,
-            network=config('odoo_network'),
-            memory_limit='150M',
-            memory_swap_limit='150M'
-        )
-
-        if not result:
-            raise Warning('No se pudo crear el contenedor')
-
-        return True
-
-    def apply_odoo_folders_permission(self):
-        full_path = os.path.join(config('odoo_root_path'), self.normalized_name)
-        check_output(['chmod', '-Rf', '777'], full_path)
-
-        return True
-
-    def take_internal_ip(self):
-        self.internal_ip = docker_api.get_internal_ip(self.normalized_name)

BIN=BIN
models/odoo_container.pyc


+ 214 - 0
models/system_instance.py

@@ -0,0 +1,214 @@
+# -*- coding: utf-8 -*-
+from openerp import models, fields, api
+from openerp.tools import config
+from openerp.exceptions import Warning
+# from random import randint
+# from jinja2 import Environment, PackageLoader
+# from subprocess import check_output
+# from ..utils import docker_api
+# import os
+import unicodedata
+import stringcase
+# import time
+
+print(config['docker_sock'])
+
+
+class SystemInstance(models.Model):
+    _name = 'system.instance'
+
+    CONTAINER_STATUS = [
+        ('draft', 'Por activar'),
+        ('activated', 'Activado'),
+        ('disapproved', 'No aprobado'),
+        ('suspended', 'Suspendido'),
+        ('destroyed', 'Eliminado')
+    ]
+
+    name = fields.Char(string='Nombre', size=50)
+    normalized_name = fields.Char(string='Nombre normalizado', compute='_normalize_name', size=50)
+    logo = fields.Binary(string='Logo')
+    internal_ip = fields.Char(string='IP interno', size=15)
+    internal_port = fields.Integer(string='Puerto interno')
+    external_ip = fields.Char(string='IP externo', size=15)
+    external_port = fields.Integer(string='Puerto externo')
+    expose_ip = fields.Boolean(string='Exponer IP', default=True)
+    state = fields.Selection(string='Estado', selection=CONTAINER_STATUS, default='draft')
+    demo = fields.Boolean(string='Es un demo?', default=False)
+    domain = fields.Char(string='Dominio', size=100)
+    running = fields.Boolean(string='Está online?', default=False)
+    payment_plan_id = fields.Many2one(string='Plan de pago', comodel_name='payment.plan', required=True)
+
+    @api.one
+    @api.onchange('name')
+    def _onchange_name(self):
+        if self.name:
+            self.name = self.name.title()
+
+    @api.one
+    @api.depends('name')
+    def _normalize_name(self):
+        name = None
+
+        try:
+            name = unicodedata.normalize('NFKD', self.name)
+            name = name.encode('ASCII', 'ignore')
+        except TypeError:
+            pass
+
+        if not name:
+            return
+
+        name = stringcase.trimcase(name)
+        name = stringcase.lowercase(name)
+
+        self.normalized_name = stringcase.snakecase(name)
+
+    @api.one
+    def action_activate(self):
+        if self.state not in ('draft', 'suspended'):
+            raise Warning('No se puede activar un sistema ya activo')
+
+        self.state = 'activated'
+
+    @api.one
+    def action_suspend(self):
+        if self.state != 'activated':
+            raise Warning('No se puede suspender un sistema no activo')
+
+        self.state = 'suspended'
+
+    @api.one
+    def copy(self):
+        raise Warning('Atención', 'No se puede duplicar una instancia. Por favor, cree un nuevo')
+
+    @api.one
+    def action_destroy(self):
+        if self.state == 'destroyed':
+            raise Warning('No se puede eliminar un sistema ya eliminado')
+
+        self.state = 'destroyed'
+
+    @api.one
+    def action_start(self):
+        if self.running:
+            raise Warning('Atención', 'No se puede arrancar una instancia que ya está arrancada')
+
+        self.running = True
+
+    @api.one
+    def action_restart(self):
+        if not self.running:
+            raise Warning('Atención', 'No se puede parar y arrancar una instancia que ya está parada')
+
+        self.running = True
+
+    # def check_existence(self):
+    #     root_path = config['odoo_root_path'] or None
+
+    #     if not root_path:
+    #         raise Warning('No se puede encontrar la configuración')
+
+    #     system_path = os.path.join(root_path, self.normalized_name)
+
+    #     if system_path:
+    #         raise Warning('Ya existe un sistema con este nombre')
+
+    #     return True
+
+    # def check_docker_port(self, port):
+    #     if port == 0:
+    #         return False
+
+    #     if port in docker_api.get_all_external_ports():
+    #         return False
+
+    #     return True
+
+    # def take_randomized_port(self):
+    #     port_range = config['odoo_ports_range']
+    #     port_range = map(lambda x: int(x.strip()), port_range.split(','))
+
+    #     port = 0
+
+    #     while not self.check_docker_port(port):
+    #         port = randint(port_range[0], port_range[1])
+    #         time.sleep(0.3)
+
+    #     self.external_port = port
+
+    # def create_odoo_folders(self):
+    #     root_path = config('odoo_root_path')
+    #     defaults_path = config('odoo_defaults_path')
+
+    #     for p in defaults_path:
+    #         full_path = os.path.join(root_path, self.normalized_name, p.strip())
+    #         os.makedirs(full_path)
+
+    #         time.sleep(0.3)
+
+    #     return True
+
+    # def create_odoo_config(self):
+    #     config_path = os.path.join(config('odoo_root_path'), self.normalized_name, 'config')
+
+    #     if not os.path.exists(config_path):
+    #         return False
+
+    #     env = Environment(loader=PackageLoader('resources'))
+
+    #     template = env.get_template('openerp-server.j2')
+    #     rendered = template.stream({
+    #         'admin_password': config('odoo_default_password'),
+    #         'db_host': config('odoo_db_host'),
+    #         'db_name': self.normalized_name,
+    #         'db_user': config('db_user'),
+    #         'db_password': config('db_password')
+    #     })
+
+    #     rendered.dump(os.path.join(config_path, 'openerp-server.conf'))
+
+    #     return True
+
+    # def create_odoo_db(self):
+    #     cmd = 'createdb -U %s %s' % (config('db_user'), self.normalized_name)
+    #     result = docker_api.run_command(config('odoo_db_container'), cmd)
+
+    #     return result
+
+    # def copy_odoo_db_seed(self):
+    #     backup_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'resources', 'odoo.tar')
+    #     return docker_api.copy_in(config('odoo_db_container'), '/tmp', backup_path)
+
+    # def restore_odoo_db(self):
+    #     cmd = 'psql -U %s -d %s -f %s' % (config('db_user'), self.normalized_name, '/tmp/odoo.sql')
+    #     return docker_api.run_command(config('odoo_db_container'), cmd)
+
+    # def remove_odoo_db_seed(self):
+    #     cmd = 'rm -f %s' % '/tmp/odoo.sql'
+    #     return docker_api.run_command(config('odoo_db_container'), cmd)
+
+    # def create_odoo_container(self):
+    #     result = docker_api.run_container(
+    #         image=config('odoo_image'),
+    #         name=self.normalized_name,
+    #         ports={'8069/tcp': self.external_port},
+    #         volumes=None,
+    #         network=config('odoo_network'),
+    #         memory_limit='150M',
+    #         memory_swap_limit='150M'
+    #     )
+
+    #     if not result:
+    #         raise Warning('No se pudo crear el contenedor')
+
+    #     return True
+
+    # def apply_odoo_folders_permission(self):
+    #     full_path = os.path.join(config('odoo_root_path'), self.normalized_name)
+    #     check_output(['chmod', '-Rf', '777'], full_path)
+
+    #     return True
+
+    # def take_internal_ip(self):
+    #     self.internal_ip = docker_api.get_internal_ip(self.normalized_name)

+ 154 - 7
templates.xml

@@ -1,23 +1,170 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <openerp>
     <data>
-        <!-- odoo container action window -->
+        <!-- system.instance tree view -->
+        <record id="system_instance_tree_view" model="ir.ui.view">
+            <field name="name">system.instance.tree</field>
+            <field name="model">system.instance</field>
+            <field name="arch" type="xml">
+                <tree colors="green:running == True and state == 'activated';red:running == False and state == 'activated';blue:state == 'draft';yellow:state == 'disapproved';gray:state == 'destroyed'" delete="false" copy="false">
+                    <field name="name" />
+                    <field name="domain" class="oe_link" />
+                    <field name="demo" />
+                    <field name="running" />
+                    <field name="state" invisible="1" />
+                    <button
+                            type="object"
+                            name="action_start"
+                            icon="gtk-media-play"
+                            string="Arrancar"
+                            attrs="{'invisible': ['|', ('running', '=', True), ('state', '!=', 'activated')]}" />
+                    <button
+                            type="object"
+                            name="action_restart"
+                            icon="gtk-refresh"
+                            string="Parar y arrancar"
+                            attrs="{'invisible': ['|', ('running', '=', False), ('state', '!=', 'activated')]}" />
+                </tree>
+            </field>
+        </record>
+
+        <!-- system.instance form view -->
+        <record id="system_instance_form_view" model="ir.ui.view">
+            <field name="name">system.instance.form</field>
+            <field name="model">system.instance</field>
+            <field name="arch" type="xml">
+                <form string="Sistema Odoo" delete="false" duplicate="false" copy="false">
+                    <header>
+                        <button
+                                name="action_activate"
+                                states="draft,suspended"
+                                string="Activar"
+                                type="object"
+                                class="oe_highlight"
+                                modifiers="{'invisible': [('state', 'not in', ['draft', 'suspended'])]}" />
+                        <button
+                                name="action_suspend"
+                                states="activated"
+                                string="Suspender"
+                                type="object"
+                                class="oe_highlight"
+                                modifiers="{'invisible': [('state', '!=', 'activated')]}" />
+                        <button
+                                name="action_destroy"
+                                states="activated,suspended"
+                                string="Eliminar"
+                                type="object"
+                                class="oe_highlight"
+                                modifiers="{'invisible': [('state', 'not in', ['activated', 'suspended'])]}" />
+                        <field
+                                name="state"
+                                widget="statusbar"
+                                statusbar="draft,activated,disapproved,suspended,destroyed"
+                                statusbar_colors='{"activated":"blue", "destroyed": "red"}' />
+                    </header>
+                    <sheet>
+                        <div class="oe_button_box oe_right">
+                            <button
+                                type="object"
+                                name="action_start"
+                                icon="fa-play"
+                                string="Arrancar"
+                                class="oe_inline oe_stat_button"
+                                attrs="{'invisible': ['|', ('running', '=', True), ('state', '!=', 'activated')]}" />
+                            <button
+                                type="object"
+                                name="action_restart"
+                                icon="fa-refresh"
+                                string="Parar y arrancar"
+                                class="oe_inline oe_stat_button"
+                                attrs="{'invisible': ['|', ('running', '=', False), ('state', '!=', 'activated')]}" />
+                        </div>
+                         <div class="oe_left" style="width: 500px;">
+                             <field name="logo" widget="image" class="oe_avatar oe_left" modifiers="{}" />
+                             <div class="oe_title" style="width: 390px;">
+                                 <label class="oe_edit_only" for="name" string="Name" />
+                                 <h1>
+                                     <field name="name" class="oe_inline" modifiers="{'required': true}" />
+                                 </h1>
+                                 <field name="normalized_name" />
+                             </div>
+                         </div>
+                        <group>
+                            <group string="Información del Servicio">
+                                <field name="payment_plan_id" widget="selection" />
+                                <field name="domain" />
+                                <field name="demo" />
+                                <field name="running" />
+                            </group>
+                            <group string="Información del Contenedor">
+                                <field name="internal_ip" />
+                                <field name="internal_port" />
+                                <field name="external_ip" />
+                                <field name="external_port" />
+                                <field name="expose_ip" />
+                            </group>
+                        </group>
+                    </sheet>
+                </form>
+            </field>
+        </record>
+
+        <!-- payment.plan tree view -->
+        <record id="payment_plan_tree_view" model="ir.ui.view">
+            <field name="name">payment.plan.tree</field>
+            <field name="model">payment.plan</field>
+            <field name="arch" type="xml">
+                <tree>
+                    <field name="name" />
+                    <field name="amount" />
+                </tree>
+            </field>
+        </record>
+
+        <!-- payment.plan form view -->
+        <record id="payment_plan_form_view" model="ir.ui.view">
+            <field name="name">payment.plan.form</field>
+            <field name="model">payment.plan</field>
+            <field name="arch" type="xml">
+                <form>
+                    <sheet>
+                        <div class="oe_title oe_left">
+                            <label class="oe_edit_only" for="name" string="Name" />
+                            <h1>
+                                <field name="name" class="oe_inline" />
+                            </h1>
+                        </div>
+                        <group>
+                            <group string="Información de pago">
+                                <field name="amount" />
+                            </group>
+                            <group string="Información del servicio">
+                                <field name="storage_limit" />
+                                <field name="ttl" />
+                            </group>
+                        </group>
+                    </sheet>
+                </form>
+            </field>
+        </record>
+
+        <!-- system.instance action -->
         <record id="odoo_container_action" model="ir.actions.act_window">
-            <field name="name">Odoo Systems</field>
+            <field name="name">Sistemas Odoo</field>
             <field name="type">ir.actions.act_window</field>
-            <field name="res_model">odoo.container</field>
+            <field name="res_model">system.instance</field>
             <field name="view_mode">tree,form</field>
             <field name="view_type">form</field>
             <field name="help" type="html">
                 <p class="oe_view_nocontent_create">
-                    Cree una nueva sistema de Odoo
+                    Cree una nueva instancia de Odoo
                 </p>
             </field>
         </record>
 
-        <!-- payment plan action window -->
+        <!-- payment.plan action -->
         <record id="payment_plan_action" model="ir.actions.act_window">
-            <field name="name">Payment Plans</field>
+            <field name="name">Planes de Pago</field>
             <field name="type">ir.actions.act_window</field>
             <field name="res_model">payment.plan</field>
             <field name="view_mode">tree,form</field>
@@ -34,7 +181,7 @@
 
         <!-- containers menu -->
         <menuitem id="containers_menu_categ" name="Contenedores" parent="sysadmin_menu_root" />
-        <menuitem id="odoo_container_menu_act" name="Sistemas" parent="containers_menu_categ" action="odoo_container_action" />
+        <menuitem id="systems_menu_act" name="Sistemas" parent="containers_menu_categ" action="odoo_container_action" />
         
         <!-- configuration menu  -->
         <menuitem id="configuration_menu_categ" name="Configuración" parent="sysadmin_menu_root" />

+ 0 - 63
views/odoo_container.xml

@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<openerp>
-    <data>
-        <!--Tree-->
-        <record id="odoo_management.odoo_container_tree" model="ir.ui.view">
-            <field name="name">odoo.container.tree</field>
-            <field name="model">odoo.container</field>
-            <field name="arch" type="xml">
-                <tree string="Sistemas odoo">
-                    <field name="name" />
-                    <field name="normalized_name" />
-                    <field name="external_port" />
-                    <field name="state" />
-                </tree>
-            </field>
-        </record>
-
-        <!--Form-->
-        <record id="odoo_management.odoo_container_form" model="ir.ui.view">
-            <field name="name">odoo.container.form</field>
-            <field name="model">odoo.container</field>
-            <field name="arch" type="xml">
-                <form string="Sistema odoo">
-                    <header>
-                        <button name="action_activate" states="draft" string="Activar" type="object" modifiers="{'invisible': [('state', '!=', 'draft')]}" />
-                        <button name="action_destroy" states="destroyed" string="Destruir" type="object" modifiers="{'invisible': [('state', '!=', 'draft'), ('active', '=', True)]}" />
-                        <field name="state" widget="statusbar" statusbar="draft,activated,disapproved,suspended,destroyed" readonly="1" modifiers="{'readonly': true}" />
-                    </header>
-                    <sheet>
-                        <div class="oe_button_box oe_right">
-                            <button string="Schedule Meeting" name="action_makeMeeting" type="object" />
-                        </div>
-                        <div class="oe_left" style="width: 500px;">
-                            <field name="logo" widget="image" class="oe_avatar oe_left" modifiers="{}" />
-                            <div class="oe_title" style="width: 390px;">
-                                <label class="oe_edit_only" for="name" string="Name" />
-                                <h1>
-                                    <field name="name" class="oe_inline" modifiers="{'required': true}" />
-                                </h1>
-                                <field name="normalized_name" />
-                            </div>
-                        </div>
-                        <group>
-                            <group string="Información del Servicio">
-                                <field name="payment_plan_id" widget="selection" />
-                                <field name="domain" />
-                                <field name="demo" />
-                                <field name="active" />
-                            </group>
-                            <group string="Información del Contenedor">
-                                <field name="internal_ip" />
-                                <field name="internal_port" />
-                                <field name="external_ip" />
-                                <field name="external_port" />
-                                <field name="expose_ip" />
-                            </group>
-                        </group>
-                    </sheet>
-                </form>
-            </field>
-        </record>
-    </data>
-</openerp>

+ 0 - 43
views/payment_plan.xml

@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<openerp>
-    <data>
-        <!-- payment.plan tree view -->
-        <record id="odoo_management.payment_plan_tree" model="ir.ui.view">
-            <field name="name">payment.plan.tree</field>
-            <field name="model">payment.plan</field>
-            <field name="arch" type="xml">
-                <tree>
-                    <field name="name" />
-                    <field name="amount" />
-                </tree>
-            </field>
-        </record>
-
-        <!-- payment.plan form view -->
-        <record id="odoo_management.payment_plan_form" model="ir.ui.view">
-            <field name="name">payment.plan.form</field>
-            <field name="model">payment.plan</field>
-            <field name="arch" type="xml">
-                <form>
-                    <sheet>
-                        <div class="oe_title oe_left">
-                            <label class="oe_edit_only" for="name" string="Name" />
-                            <h1>
-                                <field name="name" class="oe_inline" />
-                            </h1>
-                        </div>
-                        <group>
-                            <group string="Información de pago">
-                                <field name="amount" />
-                            </group>
-                            <group string="Información del servicio">
-                                <field name="storage_limit" />
-                                <field name="ttl" />
-                            </group>
-                        </group>
-                    </sheet>
-                </form>
-            </field>
-        </record>
-    </data>
-</openerp>