家用NAS系统openmediavault插件开发
admin
2023-07-29 14:22:05
0次

openmediavault 插件开发

OpenMediaVault,简称omv,是一个开源的基于Debian Linux的下一代网络附加存储(NAS)解决方案。它包含众多服务,如SSH,(S)FTP,SMB / CIFS,DAAP媒体服务器,RSync,BitTorrent客户机等。 并具有通过插件可增强的模块化设计框架特性。


OMV的插件开发,由三个部分组成

  • GUI

  • 配置文件与RPC

  • 模块与shell脚本

GUI(web界面)

后台自动扫描以下目录及其子目录

/var/www/openmediavault/js/omv/module/admin/
/var/www/openmediavault/js/omv/module/user/
/var/www/openmediavault/js/omv/module/public/
1.在service目录下新加一个目录example
/var/www/openmediavault/js/omv/module/admin/service/example
2.新增一个node(左侧导航栏的一个tree对象),创建/var/www/openmediavault/js/omv/module/admin/service/example/EXample.js
// Register a node in the navigation tree.
//
// id: 
//     Set the ID of the node.
// path: 
//     Parent path in the navigation view.
// Text: 
//     Service name/title. This is displayed in the navigation.
// icon16: 
//     16x16 pixel icon that is displayed in the navigation tree.
// iconSvg:
 //     SVG icon that is displayed in the navigation view.
 
 OMV.WorkspaceManager.registerNode({
    id: 'example',
    path: '/service',
    text: _('Example'),
    icon16: 'p_w_picpaths/example.png',
    iconSvg: 'p_w_picpaths/example.svg'});

注:test:_()这里面的内容能跟随页面自动翻译成各国语言

3.node的主视图(workspace)

从workspace类派生,创建Settings.js

Ext.define('OMV.module.admin.service.example.Settings', {
    extend: 'OMV.workspace.form.Panel',    
    
    // This path tells which RPC module and methods this panel will call to get 
    // and fetch its form values.
    
    rpcService: 'Example',
    rpcGetMethod: 'getSettings',
    rpcSetMethod: 'setSettings',    
    
    // getFormItems is a method which is automatically called in the 
    // instantiation of the panel. This method returns all fields for 
    // the panel.
    
    getFormItems: function() {        
            return [{           
            
             // xtype defines the type of this entry. Some different types
            // is: fieldset, checkbox, textfield and numberfield. 
            
            xtype: 'fieldset',
            title: _('General'),
            fieldDefaults: {
                labelSeparator: ''
            },            
            // The items array contains items inside the fieldset xtype.
            items: [{
                xtype: 'checkbox',              
                  
                // The name option is sent together with is value to RPC
                // and is also used when fetching from the RPC.
                
                name: 'enable',
                fieldLabel: _('Enable'),                
                // checked sets the default value of a checkbox.
                checked: false
            },
            {
                xtype: 'numberfield',
                name: 'max_value',
                fieldLabel: _('Max value'),
                minValue: 0,
                maxValue: 100,
                allowDecimals: false,
                allowBlank: true
            }]
        }];
    }
});
// Register a panel into the GUI.
//
// path: 
//     We want to add the panel in our example node. 
//     The node was configured with the path /service and the id example.
//     The path is therefore /service/example.//// className: 
//     The panel which should be registered and added (refers to
 //     the class name).
 
 OMV.WorkspaceManager.registerPanel({
    id: 'settings',
    path: '/service/example',
    text: _('Settings'),
    position: 10,
    className: 'OMV.module.admin.service.example.Settings'});

注:定义了rpc,此时在页面刷新会报错。“RPC service not found (name=Example)”,此时需要添加rpc文件/usr/share/openmediavault/engined/rpc/example.inc,内容见第二部分

配置文件config.xml和RPC

Config.xml

/etc/openmediavault/config.xml储存了插件设置项,可以在制作debian包时,写在postinst脚本里

#!/bin/shset -e

. /etc/default/openmediavault
. /usr/share/openmediavault/scripts/helper-functions

case "$1" in
    configure)
        SERVICE_XPATH_NAME="example"
        SERVICE_XPATH="/config/services/${SERVICE_XPATH_NAME}"

        # Add the default configuration
        if ! omv_config_exists "${SERVICE_XPATH}"; then
            omv_config_add_element "/config/services" "${SERVICE_XPATH_NAME}"
            omv_config_add_element "${SERVICE_XPATH}" "enable" "0"
            omv_config_add_element "${SERVICE_XPATH}" "max_value" "0"
        fi

        # Activate package triggers. These triggers are only set during the
        # package installation.
        dpkg-trigger update-fixperms
        dpkg-trigger update-locale
    ;;

    abort-upgrade|abort-remove|abort-deconfigure)
    ;;

    *)        echo "postinst called with unknown argument" >&2
        exit 1
    ;;esac
    
    #DEBHELPER#
    
    exit 0
The RPC = Remote Procedure Call

RPC文件存储在/usr/share/openmediavault/engined/rpc目录下,inc结尾的php文件,rpc文件连接了web GUI和config.xml,使得界面可以控制config文件
example.inc

registerMethod.
     *
     * @return void
     */
     
    public function initialize()
    {        $this->registerMethod('getSettings');        
             $this->registerMethod('setSettings');
    }    
    
    public function getSettings($params, $context)
    {        
       // $xmlConfig is needed when reading and writing from the configuration.
        global $xmlConfig;        
        
        // Validate the RPC caller context.
        //
        // validateMethodContext takes the currentcontext as the first
        // parameter. The second paramter is the valid context and that can be
        // OMV_ROLE_ADMINISTRATOR, OMV_ROLE_USER or OMV_ROLE_EVERYONE.
        // This is used to make sure that the right user accesses the method.
        $this->validateMethodContext($context, ['role' => OMV_ROLE_ADMINISTRATOR]);        
        // Get the configuration object.
        $object = $xmlConfig->get($this->getXpath());        
        
        // If no data was found, throw an exception and provide the XPath that
        // failed.
        if (is_null($object)) {            
                throw new OMVException(
                OMVErrorMsg::E_CONFIG_GET_OBJECT_FAILED,                
                $this->getXpath()
            );
        }        
        
        // Modify the result data.
        // boolval and intval converts strings and numbers to their boolean
        // and integer value.
        $object['enable'] = boolval($object['enable']);        
        $object['max_value'] = intval($object['max_value']);       
         return $object;
    }    
    
    public function setSettings($params, $context)
    {        
            global $xmlConfig;       
            $this->validateMethodContext($context, array(            
                   "role" => OMV_ROLE_ADMINISTRATOR
        ));       
        
         // Validate the parameters of the RPC service method.
        //
        // OpenMediavault uses JSON Schema to validate parameters. A more
        // detailed specification is provided here http://json-schema.org/
        $this->validateMethodParams(            
             $params,            '{
                "type": "object",
                "properties": {
                    "enable": {
                        "type": "boolean"
                    },
                    "max_value":{ 
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100
                    }
                }
            }'
        );        
        
        // Update the configuration object.
        $object = [            
                   'enable' => boolval($params['enable']),            
                   'max_value' => $params['max_value'],
        ];        
        
        // Update the configuration file. If it fails it throws an exception.
        if ($xmlConfig->replace($this->getXpath(), $object) === false) {            
                     throw new OMVException(
                                OMVErrorMsg::E_CONFIG_SET_OBJECT_FAILED,                
                                $this->getXpath()
            );
        }        
        
        // Notify configuration changes.
        //
        // This will notify event listeners such as the service module
        // to perform certain tasks. The most common one is to mark the
        // service as dirty.
        
        $dispatcher = &OMVNotifyDispatcher::getInstance();        
        $dispatcher->notify(OMV_NOTIFY_MODIFY, $this->eventMessagePath, $object);        
        
        return $object;
    }
}

// Register the RPC service.
$rpcServiceMgr = &OMVRpcServiceMgr::getInstance();
$rpcServiceMgr->registerService(new OMVRpcServiceExample());

模块与shell脚本

module

RPC用来实现界面修改和获取配置文件,模块用来监控和使其修改生效。模块目录在/usr/share/openmediavault/engined/module
Example.inc

get($this->getXpath());  
             
         if (is_null($object)) {            
                 throw new OMVException(
                OMVErrorMsg::E_CONFIG_GET_OBJECT_FAILED,                
                $this->getXpath()
            );
        }        
        
        // Return the status of the service. This information is displayed
        // under Diagnostics/Services.
        return array(           
               'name' => $this->getName(),            
               'title' => gettext('Example'),            
               'enabled' => boolval($object['enable']),            
               'running' => false
        );
    }   
    
     /**
     * Generate the configuration.
     *
     * @return void
     *
     * @throws OMVException
     */
    public function applyConfig()
    {        
                global $xmlConfig;        
                $cmd = sprintf('export LANG=C; omv-mkconf %s 2>&1', $this->getName());        
                if (0 !== $this->exec($cmd, $output)) {            
                      throw new OMVException(
                                OMVErrorMsg::E_EXEC_FAILED,                
                                $cmd,
                                implode(PHP_EOL, $output)
            );
        }
    }    
    
    /**
     * Bind listeners.
     *
     * @param OMVNotifyDispatcher $dispatcher
     * @return void
     */
    public function bindListeners(OMVNotifyDispatcher $dispatcher)
    {        
         $moduleMgr = &OMVModuleMgr::getInstance();        
         // Add listeners here. The most common thing is to monitor configuration
        // changes on the service. When the config is changed the module
        // sets itself as dirty (as seen below). Setting a module as dirty
        // makes the apply button appear in the web interface (which in turn
        // calls the applyConfig function on each module with a dirty state).
        
        $dispatcher->addListener(
            OMV_NOTIFY_MODIFY,           
             $this->eventMessagePath,
            [$this, 'setDirty']
        );
    }
}

// Register the module.
$moduleMgr = &OMVModuleMgr::getInstance();
$moduleMgr->registerModule(new OMVModuleExample());

注:模块注册了notify,rpc在修改配置文件后会通知notify文件为dirty状态,从而在页面触发apply change提示。

Shell脚本生成配置文件

在module中的applyconfig函数中,执行了omv-mkconf example命令,该命令调用了/usr/share/openmediavault/mkconf/example脚本
example

set -e. /etc/default/openmediavault
. /usr/share/openmediavault/scripts/helper-functions
OMV_EXAMPLE_XPATH="/config/services/example"OMV_EXAMPLE_CONF="/tmp/example.conf"

cat < ${OMV_EXAMPLE_CONF}enable    = $(omv_config_get "${OMV_EXAMPLE_XPATH}/enable")
max_value = $(omv_config_get "${OMV_EXAMPLE_XPATH}/max_value")
EOF

exit 0

注:需要755权限,执行完该脚本将会生成/tmp/example.conf文件。

至此,一个openmediavault的简单插件源码已经制作完成,接下来只需要制作包就可以啦。

refer:https://forum.openmediavault.org/index.php/Thread/5600-DIY-Plugin-Development/


相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...