diff --git a/README.md b/README.md index b5ffd56c181152f1465a65cfc2488fec26e61e01..24e325e88b7c7cee3c1600dcd1e65f46d7cbaeb8 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,9 @@ It is written in C programming language and depends on a number of libraries of Currently, `swmodd` can not create new execution environment and it depends on pre-created execution environments/containers. `swmodd` treats host as one execution environment and further it usages the pre-created lxc-containers as available execution environments for managing services. +`SWMODD` in du_list only shows information about the packages from `opkg list` which has services registered in init.d +`SWMODD` in eu_list only shows information about the packages present in `ubus call service list` + ## Concepts and Workflow `SWMODD` usages lxc library to interact with the lxc containers and opkg system utilities to manage the services running inside that container. `swmodd` is used to manage the software modules and exposes the functionality over ubus, whereas `libswmodd.so` is `bbf` plugin which exposes the SoftwareModules functionality over TR181 using `libbbf_api`. @@ -21,11 +24,12 @@ Currently, `swmodd` can not create new execution environment and it depends on p root@iopsys:~# ubus -v list swmodules 'swmodules' @b09f9fc4 "environment":{} - "du_list":{"eid":"Integer"} - "eu_list":{"eid":"Integer"} - "du_install":{"url":"String","uuid":"String","username":"String","password":"String","environment":"String"} - "du_update":{"uuid":"String","url":"String","username":"String","password":"String"} - "du_uninstall":{"name":"String","environment":"String"} + "du_list":{"eid":"Integer", "environment":"String"} + "eu_list":{"eid":"Integer", "environment":"String"} + "du_install":{"eid":"Integer","environment":"String","uuid":"String","url":"String","username":"String","password":"String"} + "du_update":{"eid":"Integer","environment":"String","uuid":"String","url":"String","username":"String","password":"String"} + "du_uninstall":{"eid":"Integer","environment":"String","name":"String"} + "eu_activate":{"eid":"Integer","environment":"String","service_name":"String","state":"Boolean"} root@iopsys:~# ``` @@ -248,10 +252,16 @@ root@iopsys:~# ubus call swmodules du_uninstall '{"name":"wfadatad", "environmen "status": true } ``` +#### Change the state of execution units +```bash +root@iopsys:~# ubus call swmodules eu_activate '{"eid":1, "service_name":"obuspa", "state":false}' +{ + "status": true +} +root@iopsys:~# +``` ## Limitations - `swmodd` can only manage host and pre-created lxc containers -- `swmodd` in du_list only shows information about the packages from `opkg list` which has services registered in init.d -- `swmodd` in eu_list only shows information about the packages present in `ubus call service list` ## Dependencies `swmodd` compile time and run time dependencies. diff --git a/docs/api/swmodules.md b/docs/api/swmodules.md index 292d2691d73beb1117372d0f1f90b506f98d3134..21cf7d61e918b72f7555ea24e9a26699cce38ca3 100644 --- a/docs/api/swmodules.md +++ b/docs/api/swmodules.md @@ -17,6 +17,7 @@ https://dev.iopsys.eu/iopsys/swmodd/schemas/ubus/swmodules.json | [du_uninstall](#du_uninstall) | Method | swmodules (this schema) | | [du_update](#du_update) | Method | swmodules (this schema) | | [environment](#environment) | Method | swmodules (this schema) | +| [eu_activate](#eu_activate) | Method | swmodules (this schema) | | [eu_list](#eu_list) | Method | swmodules (this schema) | ## du_install @@ -47,13 +48,25 @@ https://dev.iopsys.eu/iopsys/swmodd/schemas/ubus/swmodules.json `object` with following properties: -| Property | Type | Required | -| ------------- | ------ | ------------ | -| `environment` | string | Optional | -| `password` | string | Optional | -| `url` | string | **Required** | -| `username` | string | Optional | -| `uuid` | string | Optional | +| Property | Type | Required | +| ------------- | ------- | ------------ | +| `eid` | integer | Optional | +| `environment` | string | Optional | +| `uuid` | string | Optional | +| `url` | string | **Required** | +| `username` | string | Optional | +| `password` | string | Optional | + +#### eid + +`eid` + +- is optional +- type: `integer` + +##### eid Type + +`integer` #### environment @@ -113,7 +126,7 @@ https://dev.iopsys.eu/iopsys/swmodd/schemas/ubus/swmodules.json ### Ubus CLI Example ``` -ubus call swmodules du_install {"url":"nostrud aliqua","uuid":"nulla ipsum dolor enim","username":"in aliqua cillum","password":"ea in eiusmod ut","environment":"cillum non et anim aliqua"} +ubus call swmodules du_install {"url":"mollit deserunt","uuid":"nulla aliquip eu","username":"amet exe","password":"velit voluptate enim ad in","environment":"sed quis","eid":4} ``` ### JSONRPC Example @@ -128,11 +141,12 @@ ubus call swmodules du_install {"url":"nostrud aliqua","uuid":"nulla ipsum dolor "swmodules", "du_install", { - "url": "nostrud aliqua", - "uuid": "nulla ipsum dolor enim", - "username": "in aliqua cillum", - "password": "ea in eiusmod ut", - "environment": "cillum non et anim aliqua" + "url": "mollit deserunt", + "uuid": "nulla aliquip eu", + "username": "amet exe", + "password": "velit voluptate enim ad in", + "environment": "sed quis", + "eid": 4 } ] } @@ -149,22 +163,9 @@ ubus call swmodules du_install {"url":"nostrud aliqua","uuid":"nulla ipsum dolor `object` with following properties: -| Property | Type | Required | -| --------- | ------- | ------------ | -| `name` | string | Optional | -| `status` | boolean | **Required** | -| `version` | string | Optional | - -#### name - -`name` - -- is optional -- type: `string` - -##### name Type - -`string` +| Property | Type | Required | +| -------- | ------- | ------------ | +| `status` | boolean | **Required** | #### status @@ -177,21 +178,10 @@ ubus call swmodules du_install {"url":"nostrud aliqua","uuid":"nulla ipsum dolor `boolean` -#### version - -`version` - -- is optional -- type: `string` - -##### version Type - -`string` - ### Output Example ```json -{ "status": true, "name": "et Duis ipsum fugiat", "version": "ullamco consequat" } +{ "status": false } ``` ## du_list @@ -209,7 +199,7 @@ ubus call swmodules du_install {"url":"nostrud aliqua","uuid":"nulla ipsum dolor | Property | Type | Required | | -------- | ------ | -------- | | `input` | object | Optional | -| `output` | object | Optional | +| `output` | | Optional | #### input @@ -222,20 +212,48 @@ ubus call swmodules du_install {"url":"nostrud aliqua","uuid":"nulla ipsum dolor `object` with following properties: -| Property | Type | Required | -| -------- | ---- | -------- | -| None | None | None | +| Property | Type | Required | +| ------------- | ------- | -------- | +| `eid` | integer | Optional | +| `environment` | string | Optional | + +#### eid + +`eid` + +- is optional +- type: `integer` + +##### eid Type + +`integer` + +#### environment + +`environment` + +- is optional +- type: `string` + +##### environment Type + +`string` ### Ubus CLI Example ``` -ubus call swmodules du_list {} +ubus call swmodules du_list {"eid":6,"environment":"quis exercitation nisi ullamco"} ``` ### JSONRPC Example ```json -{ "jsonrpc": "2.0", "id": 0, "method": "call", "params": ["<SID>", "swmodules", "du_list", {}] } +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": ["<SID>", "swmodules", "du_list", { "eid": 6, "environment": "quis exercitation nisi ullamco" }] +} ``` #### output @@ -243,68 +261,74 @@ ubus call swmodules du_list {} `output` - is optional -- type: `object` +- type: complex ##### output Type -`object` with following properties: - -| Property | Type | Required | -| ---------------- | ----- | -------- | -| `execution_unit` | array | Optional | - -#### execution_unit - -`execution_unit` - -- is optional -- type: `array` - -##### execution_unit Type - -Array type: `array` - -All items must be of the type: Unknown type ``. +Unknown type ``. ```json { - "type": "array", - "items": [ + "oneof": [ { "type": "object", "properties": { - "name": { - "type": "string" - }, - "environment": { - "type": "string" - }, - "uuid": { - "type": "string" - }, - "duid": { - "type": "string" - }, - "url": { - "type": "string" - }, - "version": { - "type": "string" - }, - "config": { - "type": "string" - }, - "description": { - "type": "string" - }, - "vendor": { - "type": "string" + "execution_unit": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "environment": { + "type": "string" + }, + "eid": { + "type": "integer", + "minimum": 1 + }, + "uuid": { + "type": "string" + }, + "duid": { + "type": "string" + }, + "url": { + "type": "string" + }, + "version": { + "type": "string" + }, + "config": { + "type": "string" + }, + "description": { + "type": "string" + }, + "vendor": { + "type": "string" + } + }, + "required": ["name", "environment", "uuid", "duid", "url", "version", "config", "description", "vendor"] + } + ] } - }, - "required": ["name", "environment", "uuid", "duid", "url", "version", "config", "description", "vendor"] + } + }, + { + "type": "object", + "properties": { + "execution_unit": { + "type": "array", + "items": [] + } + } } ], - "simpletype": "`array`" + "out": "{\"oneof\":[{\"execution_unit\":[{\"name\":\"ea\",\"environment\":\"ullamco pariatur tempor\",\"uuid\":\"nostrud minim\",\"duid\":\"dolor in deserunt velit\",\"url\":\"Excepteur consequat\",\"version\":\"ut in nostrud nulla aliqu\",\"config\":\"qui\",\"description\":\"cillum ea incididunt pa\",\"vendor\":\"sed dolor\",\"eid\":6}]},{\"execution_unit\":[]}]}", + "simpletype": "complex" } ``` @@ -312,18 +336,24 @@ All items must be of the type: Unknown type ``. ```json { - "execution_unit": [ + "oneof": [ { - "name": "sint dolore", - "environment": "Ut Excepteur nisi", - "uuid": "ea in", - "duid": "ea Ut ad aliqua do", - "url": "enim minim voluptate nisi nulla", - "version": "ut fugiat proident", - "config": "in", - "description": "ullamco anim", - "vendor": "do" - } + "execution_unit": [ + { + "name": "ea", + "environment": "ullamco pariatur tempor", + "uuid": "nostrud minim", + "duid": "dolor in deserunt velit", + "url": "Excepteur consequat", + "version": "ut in nostrud nulla aliqu", + "config": "qui", + "description": "cillum ea incididunt pa", + "vendor": "sed dolor", + "eid": 6 + } + ] + }, + { "execution_unit": [] } ] } ``` @@ -356,10 +386,22 @@ All items must be of the type: Unknown type ``. `object` with following properties: -| Property | Type | Required | -| ------------- | ------ | ------------ | -| `environment` | string | Optional | -| `name` | string | **Required** | +| Property | Type | Required | +| ------------- | ------- | ------------ | +| `eid` | integer | Optional | +| `environment` | string | Optional | +| `name` | string | **Required** | + +#### eid + +`eid` + +- is optional +- type: `integer` + +##### eid Type + +`integer` #### environment @@ -386,7 +428,7 @@ All items must be of the type: Unknown type ``. ### Ubus CLI Example ``` -ubus call swmodules du_uninstall {"name":"incididunt ex minim","environment":"sit dolor tempor in aliqua"} +ubus call swmodules du_uninstall {"name":"est eiusmod culpa commodo","environment":"dolor ad","eid":8} ``` ### JSONRPC Example @@ -400,7 +442,7 @@ ubus call swmodules du_uninstall {"name":"incididunt ex minim","environment":"si "<SID>", "swmodules", "du_uninstall", - { "name": "incididunt ex minim", "environment": "sit dolor tempor in aliqua" } + { "name": "est eiusmod culpa commodo", "environment": "dolor ad", "eid": 8 } ] } ``` @@ -465,12 +507,36 @@ ubus call swmodules du_uninstall {"name":"incididunt ex minim","environment":"si `object` with following properties: -| Property | Type | Required | -| ---------- | ------ | ------------ | -| `password` | string | Optional | -| `url` | string | **Required** | -| `username` | string | Optional | -| `uuid` | string | **Required** | +| Property | Type | Required | +| ------------- | ------- | ------------ | +| `eid` | integer | Optional | +| `environment` | string | Optional | +| `password` | string | Optional | +| `url` | string | **Required** | +| `username` | string | Optional | +| `uuid` | string | **Required** | + +#### eid + +`eid` + +- is optional +- type: `integer` + +##### eid Type + +`integer` + +#### environment + +`environment` + +- is optional +- type: `string` + +##### environment Type + +`string` #### password @@ -519,7 +585,7 @@ ubus call swmodules du_uninstall {"name":"incididunt ex minim","environment":"si ### Ubus CLI Example ``` -ubus call swmodules du_update {"url":"mollit pariatur ullamco commodo","uuid":"dolore magna deserunt","username":"Duis eiusmod","password":"consequat"} +ubus call swmodules du_update {"url":"officia dolore eiusmod","uuid":"dolor sint","eid":4,"environment":"sit amet ad","username":"aliqua non sit dolore sint","password":"Lorem in ut Duis"} ``` ### JSONRPC Example @@ -534,10 +600,12 @@ ubus call swmodules du_update {"url":"mollit pariatur ullamco commodo","uuid":"d "swmodules", "du_update", { - "url": "mollit pariatur ullamco commodo", - "uuid": "dolore magna deserunt", - "username": "Duis eiusmod", - "password": "consequat" + "url": "officia dolore eiusmod", + "uuid": "dolor sint", + "eid": 4, + "environment": "sit amet ad", + "username": "aliqua non sit dolore sint", + "password": "Lorem in ut Duis" } ] } @@ -554,35 +622,9 @@ ubus call swmodules du_update {"url":"mollit pariatur ullamco commodo","uuid":"d `object` with following properties: -| Property | Type | Required | -| ------------- | ------- | ------------ | -| `environment` | string | Optional | -| `name` | string | Optional | -| `status` | boolean | **Required** | -| `uuid` | string | Optional | -| `version` | string | Optional | - -#### environment - -`environment` - -- is optional -- type: `string` - -##### environment Type - -`string` - -#### name - -`name` - -- is optional -- type: `string` - -##### name Type - -`string` +| Property | Type | Required | +| -------- | ------- | ------------ | +| `status` | boolean | **Required** | #### status @@ -595,38 +637,10 @@ ubus call swmodules du_update {"url":"mollit pariatur ullamco commodo","uuid":"d `boolean` -#### uuid - -`uuid` - -- is optional -- type: `string` - -##### uuid Type - -`string` - -#### version - -`version` - -- is optional -- type: `string` - -##### version Type - -`string` - ### Output Example ```json -{ - "status": true, - "name": "incididunt irure Duis", - "version": "nulla exercit", - "uuid": "quis magna irure", - "environment": "sint enim deserunt quis" -} +{ "status": false } ``` ## environment @@ -777,48 +791,105 @@ All items must be of the type: Unknown type ``. } ``` -## eu_list +## eu_activate -### Get list of execution units (running packages) +### Start or stop the execution of an EU -`eu_list` +`eu_activate` - type: `Method` -### eu_list Type +### eu_activate Type `object` with following properties: -| Property | Type | Required | -| -------- | ------ | -------- | -| `input` | object | Optional | -| `output` | object | Optional | +| Property | Type | Required | +| -------- | ------ | ------------ | +| `input` | object | **Required** | +| `output` | object | Optional | #### input `input` -- is optional +- is **required** - type: `object` ##### input Type `object` with following properties: -| Property | Type | Required | -| -------- | ---- | -------- | -| None | None | None | +| Property | Type | Required | +| -------------- | ------- | ------------ | +| `eid` | integer | Optional | +| `environment` | string | Optional | +| `service_name` | string | **Required** | +| `state` | boolean | **Required** | + +#### eid + +`eid` + +- is optional +- type: `integer` + +##### eid Type + +`integer` + +#### environment + +`environment` + +- is optional +- type: `string` + +##### environment Type + +`string` + +#### service_name + +`service_name` + +- is **required** +- type: `string` + +##### service_name Type + +`string` + +#### state + +`state` + +- is **required** +- type: `boolean` + +##### state Type + +`boolean` ### Ubus CLI Example ``` -ubus call swmodules eu_list {} +ubus call swmodules eu_activate {"service_name":"culpa","state":true,"eid":1,"environment":"enim dolore occaecat veniam labore"} ``` ### JSONRPC Example ```json -{ "jsonrpc": "2.0", "id": 0, "method": "call", "params": ["<SID>", "swmodules", "eu_list", {}] } +{ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": [ + "<SID>", + "swmodules", + "eu_activate", + { "service_name": "culpa", "state": true, "eid": 1, "environment": "enim dolore occaecat veniam labore" } + ] +} ``` #### output @@ -832,79 +903,192 @@ ubus call swmodules eu_list {} `object` with following properties: -| Property | Type | Required | -| ---------------- | ----- | -------- | -| `execution_unit` | array | Optional | +| Property | Type | Required | +| -------- | ------- | -------- | +| `status` | boolean | Optional | -#### execution_unit +#### status -`execution_unit` +`status` - is optional -- type: `array` +- type: `boolean` -##### execution_unit Type +##### status Type -Array type: `array` +`boolean` -All items must be of the type: Unknown type ``. +### Output Example + +```json +{ "status": true } +``` + +## eu_list + +### Get list of execution units (running packages) + +`eu_list` + +- type: `Method` + +### eu_list Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | -------- | +| `input` | object | Optional | +| `output` | | Optional | + +#### input + +`input` + +- is optional +- type: `object` + +##### input Type + +`object` with following properties: + +| Property | Type | Required | +| ------------- | ------- | -------- | +| `eid` | integer | Optional | +| `environment` | string | Optional | + +#### eid + +`eid` + +- is optional +- type: `integer` + +##### eid Type + +`integer` + +#### environment + +`environment` + +- is optional +- type: `string` + +##### environment Type + +`string` + +### Ubus CLI Example + +``` +ubus call swmodules eu_list {"eid":2,"environment":"eiusmod"} +``` + +### JSONRPC Example ```json { - "type": "array", - "items": [ + "jsonrpc": "2.0", + "id": 0, + "method": "call", + "params": ["<SID>", "swmodules", "eu_list", { "eid": 2, "environment": "eiusmod" }] +} +``` + +#### output + +`output` + +- is optional +- type: complex + +##### output Type + +Unknown type ``. + +```json +{ + "oneof": [ { "type": "object", "properties": { - "name": { - "type": "string" - }, - "command": { - "type": "string" - }, - "config": { - "type": "string" - }, - "version": { - "type": "string" - }, - "description": { - "type": "string" - }, - "environment": { - "type": "string" - }, - "euid": { - "type": "integer", - "minimum": 0 - }, - "disk_space": { - "type": "integer", - "minimum": 0 - }, - "memory_space": { - "type": "integer", - "minimum": 0 - }, - "vendor": { - "type": "string" + "execution_unit": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "command": { + "type": "string" + }, + "state": { + "type": "string" + }, + "config": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "environment": { + "type": "string" + }, + "eid": { + "type": "integer", + "minimum": 1 + }, + "euid": { + "type": "integer", + "minimum": 0 + }, + "disk_space": { + "type": "integer", + "minimum": 0 + }, + "memory_space": { + "type": "integer", + "minimum": 0 + }, + "vendor": { + "type": "string" + } + }, + "required": [ + "name", + "command", + "config", + "version", + "description", + "environment", + "euid", + "disk_space", + "memory_space", + "vendor" + ] + } + ] } - }, - "required": [ - "name", - "command", - "config", - "version", - "description", - "environment", - "euid", - "disk_space", - "memory_space", - "vendor" - ] + } + }, + { + "type": "object", + "properties": { + "execution_unit": { + "type": "array", + "items": [] + } + } } ], - "simpletype": "`array`" + "out": "{\"oneof\":[{\"execution_unit\":[{\"name\":\"in est aliqua aliquip\",\"command\":\"proident et \",\"config\":\"reprehenderit nisi qui esse\",\"version\":\"deserunt quis do qui laborum\",\"description\":\"ipsum fugiat non\",\"environment\":\"enim\",\"euid\":18216158,\"disk_space\":13070620,\"memory_space\":67344135,\"vendor\":\"consequat\",\"state\":\"enim sed dolore est elit\",\"eid\":7}]},{\"execution_unit\":[]}]}", + "simpletype": "complex" } ``` @@ -912,19 +1096,26 @@ All items must be of the type: Unknown type ``. ```json { - "execution_unit": [ + "oneof": [ { - "name": "Ut", - "command": "labore dolor fugiat veniam incididunt", - "config": "adipisicing tempor", - "version": "officia ", - "description": "incididunt sed dolore", - "environment": "mollit laboris ea commodo consectetu", - "euid": 75690020, - "disk_space": 80559588, - "memory_space": 11981129, - "vendor": "dolor" - } + "execution_unit": [ + { + "name": "in est aliqua aliquip", + "command": "proident et ", + "config": "reprehenderit nisi qui esse", + "version": "deserunt quis do qui laborum", + "description": "ipsum fugiat non", + "environment": "enim", + "euid": 18216158, + "disk_space": 13070620, + "memory_space": 67344135, + "vendor": "consequat", + "state": "enim sed dolore est elit", + "eid": 7 + } + ] + }, + { "execution_unit": [] } ] } ``` diff --git a/schemas/ubus/swmodules.json b/schemas/ubus/swmodules.json index 48a24ccf6d036b6cfd69bd247695322143016d4e..3b2fdf27c95601258949e3a08b0618005e8966df 100644 --- a/schemas/ubus/swmodules.json +++ b/schemas/ubus/swmodules.json @@ -82,67 +82,94 @@ "properties": { "input": { "type": "object", - "properties": {} + "properties": { + "eid": { + "type": "integer" + }, + "environment": { + "type": "string" + } + } }, "output": { - "type": "object", - "properties": { - "execution_unit": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "command": { - "type": "string" - }, - "config": { - "type": "string" - }, - "version": { - "type": "string" - }, - "description": { - "type": "string" - }, - "environment": { - "type": "string" - }, - "euid": { - "type": "integer", - "minimum": 0 - }, - "disk_space": { - "type": "integer", - "minimum": 0 - }, - "memory_space": { - "type": "integer", - "minimum": 0 - }, - "vendor": { - "type": "string" + "oneof": [ + { + "type": "object", + "properties": { + "execution_unit": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "command": { + "type": "string" + }, + "state": { + "type": "string" + }, + "config": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "environment": { + "type": "string" + }, + "eid": { + "type": "integer", + "minimum": 1 + }, + "euid": { + "type": "integer", + "minimum": 0 + }, + "disk_space": { + "type": "integer", + "minimum": 0 + }, + "memory_space": { + "type": "integer", + "minimum": 0 + }, + "vendor": { + "type": "string" + } + }, + "required": [ + "name", + "command", + "config", + "version", + "description", + "environment", + "euid", + "disk_space", + "memory_space", + "vendor" + ] } - }, - "required": [ - "name", - "command", - "config", - "version", - "description", - "environment", - "euid", - "disk_space", - "memory_space", - "vendor" ] } - ] + } + }, + { + "type": "object", + "properties": { + "execution_unit": { + "type": "array", + "items": [] + } + } } - } + ] } } }, @@ -152,60 +179,84 @@ "properties": { "input": { "type": "object", - "properties": {} + "properties": { + "eid": { + "type": "integer" + }, + "environment": { + "type": "string" + } + } }, "output": { - "type": "object", - "properties": { - "execution_unit": { - "type": "array", - "items": [ - { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "environment": { - "type": "string" - }, - "uuid": { - "type": "string" - }, - "duid": { - "type": "string" - }, - "url": { - "type": "string" - }, - "version": { - "type": "string" - }, - "config": { - "type": "string" - }, - "description": { - "type": "string" - }, - "vendor": { - "type": "string" + "oneof": [ + { + "type": "object", + "properties": { + "execution_unit": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "environment": { + "type": "string" + }, + "eid": { + "type": "integer", + "minimum": 1 + }, + "uuid": { + "type": "string" + }, + "duid": { + "type": "string" + }, + "url": { + "type": "string" + }, + "version": { + "type": "string" + }, + "config": { + "type": "string" + }, + "description": { + "type": "string" + }, + "vendor": { + "type": "string" + } + }, + "required": [ + "name", + "environment", + "uuid", + "duid", + "url", + "version", + "config", + "description", + "vendor" + ] } - }, - "required": [ - "name", - "environment", - "uuid", - "duid", - "url", - "version", - "config", - "description", - "vendor" ] } - ] + } + }, + { + "type": "object", + "properties": { + "execution_unit": { + "type": "array", + "items": [] + } + } } - } + ] } } }, @@ -219,19 +270,22 @@ "input": { "type": "object", "properties": { - "url": { + "eid": { + "type": "integer" + }, + "environment": { "type": "string" }, "uuid": { "type": "string" }, - "username": { + "url": { "type": "string" }, - "password": { + "username": { "type": "string" }, - "environment": { + "password": { "type": "string" } }, @@ -244,34 +298,11 @@ "properties": { "status": { "type": "boolean" - }, - "name": { - "type": "string" - }, - "version": { - "type": "string" } }, "required": [ "status" - ], - "if": { - "not": { - "properties": { - "status": { - "enum": [ - false - ] - } - } - } - }, - "then": { - "required": [ - "name", - "version" - ] - } + ] } } }, @@ -285,6 +316,12 @@ "input": { "type": "object", "properties": { + "eid": { + "type": "integer" + }, + "environment": { + "type": "string" + }, "uuid": { "type": "string" }, @@ -308,47 +345,50 @@ "properties": { "status": { "type": "boolean" + } + }, + "required": [ + "status" + ] + } + } + }, + "du_uninstall": { + "title": "Uninstall installed deployment units/packages", + "type": "object", + "required": [ + "input" + ], + "properties": { + "input": { + "type": "object", + "properties": { + "eid": { + "type": "integer" }, - "name": { - "type": "string" - }, - "version": { - "type": "string" - }, - "uuid": { + "environment": { "type": "string" }, - "environment": { + "name": { "type": "string" } }, "required": [ - "status" - ], - "if": { - "not": { - "properties": { - "status": { - "enum": [ - false - ] - } - } + "name" + ] + }, + "output": { + "type": "object", + "properties": { + "status": { + "type": "boolean" } - }, - "then": { - "required": [ - "name", - "version", - "uuid", - "environment" - ] } } } }, - "du_uninstall": { - "title": "Uninstall installed deployment units/packages", + "eu_activate": { + "title": "Start or stop the execution of an EU", "type": "object", "required": [ "input" @@ -357,15 +397,22 @@ "input": { "type": "object", "properties": { - "name": { - "type": "string" + "eid": { + "type": "integer" }, "environment": { "type": "string" + }, + "service_name": { + "type": "string" + }, + "state": { + "type": "boolean" } }, "required": [ - "name" + "service_name", + "state" ] }, "output": { diff --git a/src/datamodel.c b/src/datamodel.c index b72f697ff5586fe6758b772f729508d812f5027f..9742f62e9905ecf076167415ab5117a994d67a90 100644 --- a/src/datamodel.c +++ b/src/datamodel.c @@ -794,6 +794,56 @@ static int operate_SoftwareModulesDeploymentUnit_Uninstall(char *refparam, struc return (strcmp(status, "true") == 0) ? CMD_SUCCESS : CMD_FAIL; } +static operation_args softwaremodulesexecutionunit_setrequestedstate_args = { + .in = (const char *[]) { + "RequestedState", + NULL + } +}; + +static int get_operate_args_SoftwareModulesExecutionUnit_SetRequestedState(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = (char *)&softwaremodulesexecutionunit_setrequestedstate_args; + return 0; +} + +static int operate_SoftwareModulesExecutionUnit_SetRequestedState(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + char *req_state = dmjson_get_value((json_object *)value, 1, "RequestedState"); + if (req_state[0] == '\0') { + return CMD_INVALID_ARGUMENTS; + } + + char *eid = dmjson_get_value((json_object *)data, 1, "eid"); + char *name = dmjson_get_value((json_object *)data, 1, "name"); + char *status = dmjson_get_value((json_object *)data, 1, "state"); + + if (!eid || !name || !status) { + return CMD_FAIL; + } + + if (strcmp(req_state, "Idle") == 0 && (strcmp(status, "Active") == 0 || strcmp(status, "Starting") == 0)) { + /* state can be changed to Idle only when current state is either Active or Starting */ + dmubus_call_set("swmodules", "eu_activate", UBUS_ARGS{ + {"eid", eid, Integer}, + {"service_name", name, String}, + {"state", "false", Boolean}}, + 3); + } else if (strcmp(req_state, "Active") == 0 && strcmp(status, "Idle") == 0) { + /* state can be changed to Active only when current state is Idle */ + dmubus_call_set("swmodules", "eu_activate", UBUS_ARGS{ + {"eid", eid, Integer}, + {"service_name", name, String}, + {"state", "true", Boolean}}, + 3); + } else { + /* Ignore the request */ + return CMD_SUCCESS; + } + + return CMD_SUCCESS; +} + /********************************************************************************************************************************** * OBJ & PARAM DEFINITION ***********************************************************************************************************************************/ @@ -893,5 +943,6 @@ DMLEAF tSoftwareModulesExecutionUnitParams[] = { //{"VendorConfigList", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_VendorConfigList, NULL, BBFDM_BOTH}, //{"SupportedDataModelList", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_SupportedDataModelList, NULL, BBFDM_CWMP}, {"ExecutionEnvRef", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_ExecutionEnvRef, NULL, BBFDM_BOTH}, +{"SetRequestedState()", &DMSYNC, DMT_COMMAND, get_operate_args_SoftwareModulesExecutionUnit_SetRequestedState, operate_SoftwareModulesExecutionUnit_SetRequestedState, BBFDM_USP}, {0} }; diff --git a/src/swmod.c b/src/swmod.c index 85fe62b12753e38ad5640b57c7e18892485ad3d1..008b974530c4564abc6871a224130774b3492c16 100644 --- a/src/swmod.c +++ b/src/swmod.c @@ -42,61 +42,80 @@ ExecEnv environments[MAX_ENV] = {0}; ExecUnit exec_units[MAX_ENV] = {0}; enum { - DU_INSTALL_URL, + DU_INSTALL_ENV_ID, + DU_INSTALL_ENV, DU_INSTALL_UUID, + DU_INSTALL_URL, DU_INSTALL_USERNAME, DU_INSTALL_PASSWORD, - DU_INSTALL_ENV, - DU_INSTALL_ENV_ID, __DU_INSTALL_MAX }; enum { + DU_UPDATE_ENV_ID, + DU_UPDATE_ENV, DU_UPDATE_UUID, DU_UPDATE_URL, DU_UPDATE_USERNAME, DU_UPDATE_PASSWORD, - DU_UPDATE_ENV_ID, __DU_UPDATE_MAX }; enum { - DU_UNINSTALL_NAME, - DU_UNINSTALL_ENV, DU_UNINSTALL_ENV_ID, + DU_UNINSTALL_ENV, + DU_UNINSTALL_NAME, __DU_UNINSTALL_MAX }; enum { EU_DU_LIST_ENV_ID, + EU_DU_LIST_ENV, __EU_DU_LIST_MAX }; +enum { + EU_ACTIVATE_SERVICE_ENV_ID, + EU_ACTIVATE_SERVICE_ENV, + EU_ACTIVATE_SERVICE_NAME, + EU_ACTIVATE_SERVICE_STATUS, + __EU_ACTIVATE_SERVICE_MAX +}; + +static const struct blobmsg_policy eu_activate_policy[__EU_ACTIVATE_SERVICE_MAX] = { + [EU_ACTIVATE_SERVICE_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, + [EU_ACTIVATE_SERVICE_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, + [EU_ACTIVATE_SERVICE_NAME] = { .name = "service_name", .type = BLOBMSG_TYPE_STRING }, + [EU_ACTIVATE_SERVICE_STATUS] = { .name = "state", .type = BLOBMSG_TYPE_INT8 }, +}; + static const struct blobmsg_policy du_install_policy[__DU_INSTALL_MAX] = { - [DU_INSTALL_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING }, + [DU_INSTALL_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, + [DU_INSTALL_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, [DU_INSTALL_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING }, + [DU_INSTALL_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING }, [DU_INSTALL_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING }, [DU_INSTALL_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING }, - [DU_INSTALL_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, - [DU_INSTALL_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, }; static const struct blobmsg_policy du_update_policy[__DU_UPDATE_MAX] = { + [DU_UPDATE_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, + [DU_UPDATE_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_UUID] = { .name = "uuid", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_URL] = { .name = "url", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING }, [DU_UPDATE_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING }, - [DU_UPDATE_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, }; static const struct blobmsg_policy du_uninstall_policy[__DU_UNINSTALL_MAX] = { - [DU_UNINSTALL_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, - [DU_UNINSTALL_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, [DU_UNINSTALL_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, + [DU_UNINSTALL_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, + [DU_UNINSTALL_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, }; static const struct blobmsg_policy eu_du_list_policy[__EU_DU_LIST_MAX] = { [EU_DU_LIST_ENV_ID] = { .name = "eid", .type = BLOBMSG_TYPE_INT32 }, + [EU_DU_LIST_ENV] = { .name = "environment", .type = BLOBMSG_TYPE_STRING }, }; static void @@ -306,12 +325,13 @@ swmod_du_install(struct ubus_context *ctx, struct ubus_object *obj, if (blobmsg_parse(du_install_policy, __DU_INSTALL_MAX, tb, blob_data(msg), blob_len(msg))) return UBUS_STATUS_UNKNOWN_ERROR; - if (tb[DU_INSTALL_ENV_ID]) - eid = blobmsg_get_u32(tb[DU_INSTALL_ENV_ID]); - if (tb[DU_INSTALL_ENV]) eid = get_eid_from_env_name(blobmsg_get_string(tb[DU_INSTALL_ENV])); + /* Priority should be given on EID if both EID and ENV name are provided */ + if (tb[DU_INSTALL_ENV_ID]) + eid = blobmsg_get_u32(tb[DU_INSTALL_ENV_ID]); + if (!tb[DU_INSTALL_URL]) return UBUS_STATUS_INVALID_ARGUMENT; @@ -393,10 +413,15 @@ swmod_du_update(struct ubus_context *ctx, struct ubus_object *obj, if (blobmsg_parse(du_update_policy, __DU_UPDATE_MAX, tb, blob_data(msg), blob_len(msg))) return UBUS_STATUS_UNKNOWN_ERROR; - if (!tb[DU_UPDATE_URL] || !tb[DU_UPDATE_UUID] || !tb[DU_UPDATE_ENV_ID]) + if (!tb[DU_UPDATE_URL] || !tb[DU_UPDATE_UUID]) return UBUS_STATUS_INVALID_ARGUMENT; - eid = blobmsg_get_u32(tb[DU_UPDATE_ENV_ID]); + if (tb[DU_UPDATE_ENV]) + eid = get_eid_from_env_name(blobmsg_get_string(tb[DU_UPDATE_ENV])); + + /* Priority should be given on EID if both EID and ENV name are provided */ + if (tb[DU_UPDATE_ENV_ID]) + eid = blobmsg_get_u32(tb[DU_UPDATE_ENV_ID]); snprintf(url, sizeof(url), "%s", blobmsg_get_string(tb[DU_UPDATE_URL])); if (strchr(url, ':') != NULL) { @@ -443,12 +468,13 @@ swmod_du_uninstall(struct ubus_context *ctx, struct ubus_object *obj, memset(&bb, 0, sizeof(struct blob_buf)); blob_buf_init(&bb, 0); - if (tb[DU_UNINSTALL_ENV_ID]) - eid = blobmsg_get_u32(tb[DU_UNINSTALL_ENV_ID]); - if (tb[DU_UNINSTALL_ENV]) eid = get_eid_from_env_name(blobmsg_get_string(tb[DU_UNINSTALL_ENV])); + /* Priority should be given on EID if both EID and ENV name are provided */ + if (tb[DU_UNINSTALL_ENV_ID]) + eid = blobmsg_get_u32(tb[DU_UNINSTALL_ENV_ID]); + int err = swmod_remove_package(blobmsg_get_string(tb[DU_UNINSTALL_NAME]), eid); blobmsg_add_u8(&bb, "status", (!err) ? true : false); @@ -464,14 +490,16 @@ static int get_eid_from_blob(struct blob_attr *msg) struct blob_attr *tb[__EU_DU_LIST_MAX] = {NULL}; if (blobmsg_parse(eu_du_list_policy, __EU_DU_LIST_MAX, tb, blob_data(msg), blob_len(msg)) == 0) { + if (tb[EU_DU_LIST_ENV]) { + eid = get_eid_from_env_name(blobmsg_get_string(tb[EU_DU_LIST_ENV])); + } + + /* Priority given to EID if both EID and ENV name are provided */ if (tb[EU_DU_LIST_ENV_ID]) { eid = blobmsg_get_u32(tb[EU_DU_LIST_ENV_ID]); } } - if (eid > MAX_ENV) - return 0; - return eid; } @@ -484,9 +512,8 @@ static void prepare_du_list_result(unsigned int eid, struct blob_buf *bb) return; swmod_uci_foreach_section(map_du_fname, "deployment", ss) { - void *t; - t = blobmsg_open_table(bb, ""); + void *t = blobmsg_open_table(bb, ""); blobmsg_add_string(bb, "name", swmod_uci_get_value_by_section(ss, "name")); blobmsg_add_string(bb, "environment", swmod_uci_get_value_by_section(ss, "environment")); @@ -522,7 +549,8 @@ swmod_du_list(struct ubus_context *ctx, struct ubus_object *obj, swmod_uci_init(SWMOD_PATH); if (eid) { - prepare_du_list_result(eid, &bb); + eid <= MAX_ENV ? prepare_du_list_result(eid, &bb) : + PRINT_ERR("Invalid eid '%d', valid range [1 - %d]", eid, MAX_ENV); } else { for (int i = 1; i <= MAX_ENV; i++) { prepare_du_list_result(i, &bb); @@ -601,7 +629,8 @@ swmod_eu_list(struct ubus_context *ctx, struct ubus_object *obj, a = blobmsg_open_array(&bb, "execution_unit"); if (eid) { - prepare_eu_list_result(eid - 1, &bb); + eid <= MAX_ENV ? prepare_eu_list_result(eid - 1, &bb) : + PRINT_ERR("Invalid eid '%d', valid range [1 - %d]", eid, MAX_ENV); } else { for (int i = 0; i < MAX_ENV; i++) { prepare_eu_list_result(i, &bb); @@ -615,6 +644,65 @@ swmod_eu_list(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +static int +swmod_eu_activate(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_buf bb; + struct blob_attr *tb[__EU_ACTIVATE_SERVICE_MAX] = {NULL}; + char name[32] = {0}; + bool state = false; + int eid = 0; + + if (blobmsg_parse(eu_activate_policy, __EU_ACTIVATE_SERVICE_MAX, tb, blob_data(msg), blob_len(msg)) != 0) { + return UBUS_STATUS_INVALID_ARGUMENT; + } + + if (!tb[EU_ACTIVATE_SERVICE_NAME] || !tb[EU_ACTIVATE_SERVICE_STATUS]) { + return UBUS_STATUS_INVALID_ARGUMENT; + } + + if (tb[EU_ACTIVATE_SERVICE_ENV]) { + eid = get_eid_from_env_name(blobmsg_get_string(tb[EU_ACTIVATE_SERVICE_ENV])); + } + + /* Priority should be given on EID if both EID and ENV name are provided */ + if (tb[EU_ACTIVATE_SERVICE_ENV_ID]) { + eid = blobmsg_get_u32(tb[EU_ACTIVATE_SERVICE_ENV_ID]); + } + + if (eid <= 0 || eid > MAX_ENV) + return UBUS_STATUS_INVALID_ARGUMENT; + + snprintf(name, sizeof(name), "%s", blobmsg_get_string(tb[EU_ACTIVATE_SERVICE_NAME])); + state = blobmsg_get_bool(tb[EU_ACTIVATE_SERVICE_STATUS]); + + int index = eid - 1; + if (!environments[index].exists) { + PRINT_INFO("No environment exists at index: %d", index); + return -1; + } + + int err = -1; + if (strcmp(environments[index].name, HOST_SYSTEM) == 0) { + err = swmod_set_host_service_state(name, state); + } else { +#ifdef SWMOD_LXC + err = swmod_set_lxc_service_state(index, name, state); +#endif + } + + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + + blobmsg_add_u8(&bb, "status", (err >= 0) ? true : false); + + ubus_send_reply(ctx, req, bb.head); + blob_buf_free(&bb); + return 0; +} + static const struct ubus_method swmod_object_methods[] = { UBUS_METHOD_NOARG("environment", swmod_environment), UBUS_METHOD("du_list", swmod_du_list, eu_du_list_policy), @@ -622,6 +710,7 @@ static const struct ubus_method swmod_object_methods[] = { UBUS_METHOD("du_install", swmod_du_install, du_install_policy), UBUS_METHOD("du_update", swmod_du_update, du_update_policy), UBUS_METHOD("du_uninstall", swmod_du_uninstall, du_uninstall_policy), + UBUS_METHOD("eu_activate", swmod_eu_activate, eu_activate_policy), }; static struct ubus_object_type swmod_object_type = UBUS_OBJECT_TYPE("swmodules", swmod_object_methods); diff --git a/src/swmod_host.c b/src/swmod_host.c index 39adcc88b39b02c02cea4d02e5d8d3a506556950..2fffee59265ed546510b812b8c0eb7017030f97d 100644 --- a/src/swmod_host.c +++ b/src/swmod_host.c @@ -24,6 +24,7 @@ #include <stdbool.h> #include <sys/sysinfo.h> #include <sys/utsname.h> +#include <sys/statvfs.h> #include "tools.h" #include "swmod_uci.h" @@ -47,11 +48,19 @@ void populate_host_system_environment(void) struct sysinfo sinfo; if (sysinfo(&sinfo) == 0) { - environments[0].allocated_disk_space = 0; // TODO - environments[0].available_disk_space = 0; // TODO environments[0].allocated_memory = (sinfo.totalram / 1024); environments[0].available_memory = (sinfo.freeram / 1024); } + + struct statvfs dinfo; + if (statvfs("/", &dinfo) == 0) { + environments[0].allocated_disk_space = (dinfo.f_bsize * dinfo.f_blocks) / 1024; + environments[0].available_disk_space = (dinfo.f_bsize * dinfo.f_bfree) / 1024; + } else { + environments[0].allocated_disk_space = 0; + environments[0].available_disk_space = 0; + } + create_file("/etc/swmod/map_du"); } @@ -59,3 +68,8 @@ void service_get_cb(struct ubus_request *req, int type, struct blob_attr *msg) { update_eu_from_blob(NULL, 0, HOST_SYSTEM, msg); } + +int swmod_set_host_service_state(char *service, bool state) +{ + return ubus_call_service_state(service, state); +} diff --git a/src/swmod_host.h b/src/swmod_host.h index e31c52c96c7dc21ad5ca4300130bd149d4d30822..086eb7567a3fed5528ec53d7b26c5de82de47b97 100644 --- a/src/swmod_host.h +++ b/src/swmod_host.h @@ -28,5 +28,6 @@ void populate_host_system_environment(void); void populate_host_system_deployment_unit(void); void populate_host_system_execution_unit(void); void service_get_cb(struct ubus_request *req, int type, struct blob_attr *msg); +int swmod_set_host_service_state(char *name, bool state); #endif //HOST_H diff --git a/src/swmod_lxc.c b/src/swmod_lxc.c index 8e1fea6460bec13882b0b01960ac7d14b7f305de..e975294effe0f83362dfb2dc9f11f652a525dbc4 100644 --- a/src/swmod_lxc.c +++ b/src/swmod_lxc.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <unistd.h> #include <sys/sysinfo.h> +#include <sys/statvfs.h> #include <sys/utsname.h> #include <errno.h> @@ -48,6 +49,11 @@ typedef struct lxc_attach_args { int action; } lxc_attach_args; +struct service_state { + char *name; + bool state; +}; + const char *get_lxc_path_from_config(void) { return lxc_get_global_config_item(LXC_PATH); @@ -199,14 +205,45 @@ void populate_lxc_environment(void) FREE(g_lxc_buff); - environments[i+1].allocated_disk_space = 0; // TODO - environments[i+1].available_disk_space = 0; // TODO + /* get memory space limit in cgroup */ + char buffer[4096] = {0}; + int res = ct->get_cgroup_item(ct, "memory.limit_in_bytes", buffer, sizeof(buffer)); + if (res >= 0) { + unsigned long long memory = 0; + if (sscanf(buffer, "%llu", &memory)) { + memory = memory / 1024; /* converted to KB */ + if (memory < environments[i+1].allocated_memory) + environments[i+1].allocated_memory = memory; + } + } + + /* get free space from lxc info */ + memset(buffer, 0, sizeof(buffer)); + res = ct->get_cgroup_item(ct, "memory.usage_in_bytes", buffer, sizeof(buffer)); + if (res >= 0) { + unsigned long long used_space = 0; + if (sscanf(buffer, "%llu", &used_space)) { + used_space = used_space / 1024; /* converted to KB */ + environments[i+1].available_memory = environments[i+1].allocated_memory - used_space; + } + } } if (ret == -1) { swmod_strncpy(environments[i+1].status, "Error", 6); } + struct statvfs dinfo; + char lxc_root[4096] = {0}; + snprintf(lxc_root, sizeof(lxc_root), "%s/%s/", lxcpath, ct->name); + if (statvfs(lxc_root, &dinfo) == 0) { + environments[i+1].allocated_disk_space = (dinfo.f_bsize * dinfo.f_blocks) / 1024; + environments[i+1].available_disk_space = (dinfo.f_bsize * dinfo.f_bfree) / 1024; + } else { + environments[i+1].allocated_disk_space = 0; + environments[i+1].available_disk_space = 0; + } + lxc_container_put(ct); } @@ -592,3 +629,50 @@ end: return err; } + +static int lxc_attach_service_state_func(void *args) +{ + struct service_state *st = (struct service_state *)args; + + return ubus_call_service_state(st->name, st->state); +} + +int swmod_set_lxc_service_state(int index, char *name, bool state) +{ + int ret = -1; + const char *lxcpath = NULL; + int cid = index - 1; + + if (!lxc_is_supported(&lxcpath)) { + return ret; + } + + struct lxc_container **clist = NULL; + int lxc_nbr; + + lxc_nbr = list_all_containers(lxcpath, NULL, &clist); + + if (cid >= lxc_nbr) { + goto end; + } + + struct lxc_container *ct = clist[cid]; + + if (!ct->is_running(ct)) { + PRINT_INFO("lxc container not running"); + lxc_container_put(ct); + goto end; + } + + struct service_state st; + st.name = name; + st.state = state; + ret = lxc_attach_func(ct, lxc_attach_service_state_func, (lxc_attach_args *)&st); + lxc_container_put(ct); + +end: + if (lxc_nbr > 0) + FREE(clist); + + return ret; +} diff --git a/src/swmod_lxc.h b/src/swmod_lxc.h index 3cf195906d0605a72a2fa311b90ce2489cd8a75e..6379e942799db17636b93bb4195cda5da60a755b 100644 --- a/src/swmod_lxc.h +++ b/src/swmod_lxc.h @@ -36,5 +36,6 @@ int swmod_lxc_install_update_remove_package(const char *package_path, int eid, i void populate_lxc_eu(void); void get_pid_details_lxc(struct lxc_container *ct, int pid, char *cmdline, int *vsize); int swmod_lxc_copy_file_from_host(int cid, const char *package_path, char *lxc_pkg_path, int size); +int swmod_set_lxc_service_state(int index, char *name, bool state); #endif //LXC_H diff --git a/src/swmod_opkg.c b/src/swmod_opkg.c index 59aa0f2ce8c2a993bfbe2f74794a4f47ab5c63ed..22d0b33285cfb620612d23ca0ecc9eb2413b2c58 100644 --- a/src/swmod_opkg.c +++ b/src/swmod_opkg.c @@ -31,6 +31,14 @@ char package_name[64] = {0}; char package_version[64] = {0}; +static char compulsory_service[][64] = { + "opkg", + "ubus", + "ubusd", + "procd", + "swmodd" +}; + static int swmod_host_system_install_package(const char *package_path) { char command[1024] = {0}; @@ -110,7 +118,7 @@ int swmod_install_package(const char *package_path, int eid, bool dw_file) int index = 0; int ret = -1; - if (eid >= MAX_ENV || eid <= 0) + if (eid > MAX_ENV || eid <= 0) goto end; index = eid - 1; @@ -149,7 +157,7 @@ int swmod_update_package(const char *pkg, int eid, bool dw_file) int index = 0; int ret = -1; - if (eid >= MAX_ENV || eid <= 0) + if (eid > MAX_ENV || eid <= 0) goto end; index = eid - 1; @@ -188,7 +196,7 @@ int swmod_remove_package(const char *pname, int eid) int index = 0; int ret = -1; - if (eid >= MAX_ENV || eid <= 0) + if (eid > MAX_ENV || eid <= 0) return -1; index = eid - 1; @@ -212,7 +220,7 @@ int swmod_remove_package(const char *pname, int eid) bool is_opkg_service(const char *opkg_info, char *pkg_name) { /* Get Config from package_name.list */ - bool service = false; + bool service = true; char pkg_path[128] = {0}; snprintf(pkg_path, sizeof(pkg_path), "%s/%s.list", opkg_info, pkg_name); @@ -332,6 +340,10 @@ void populate_opkg_deployment_unit(int eid, const char *opkg_root, const char *d if (is_opkg_service(opkg_info, name) == false) continue; + if (is_compulsory_service(name) == true) { + continue; + } + /* Check if package name exists */ struct uci_section *sec; if (check_section_exist_by_option(conf, "deployment", "name", name, &sec)) { @@ -378,3 +390,13 @@ void populate_opkg_deployment_unit(int eid, const char *opkg_root, const char *d swmod_uci_fini(conf); } +bool is_compulsory_service(const char *service) +{ + for (int i = 0; i < sizeof(compulsory_service)/sizeof(compulsory_service[0]); i++) { + if (strcmp(compulsory_service[i], service) == 0) { + return true; + } + } + + return false; +} diff --git a/src/swmod_opkg.h b/src/swmod_opkg.h index 175530179231e53a56a161bf7c10c73f742c1aa1..41e1922d0e9c7a6c3a40d14f26e8ed8e4fab71a0 100644 --- a/src/swmod_opkg.h +++ b/src/swmod_opkg.h @@ -40,6 +40,6 @@ void populate_opkg_deployment_unit(int eid, const char *opkg_root, const char *d void get_description_from_package(const char *opkg_info, struct uci_section *s, char *pkg_name); void get_config_from_package(const char *opkg_info, struct uci_section *s, char *pkg_name); bool is_opkg_service(const char *opkg_info, char *pkg_name); - +bool is_compulsory_service(const char *service); #endif //__SWMOD_OPKG_H diff --git a/src/tools.c b/src/tools.c index d2fe5dd72e5bd2e844696824e5f36d873ef88f32..6cf08db25950b3c8c582684aa5f7a1431879c4e4 100644 --- a/src/tools.c +++ b/src/tools.c @@ -33,6 +33,7 @@ #include <errno.h> #include <uuid/uuid.h> #include <stdarg.h> +#include <libubus.h> #include "swmod_uci.h" #include "swmod_opkg.h" @@ -433,6 +434,10 @@ void update_eu_from_blob(void *lxc, int eid, const char *hname, struct blob_attr #endif exec_units[eid].exists = true; blobmsg_for_each_attr(service, msg, rem) { + if (is_compulsory_service(blobmsg_name(service)) == true) { + continue; + } + blobmsg_for_each_attr(instances, service, rem2) { exec_units[eid].eu_exists[nbr] = true; @@ -485,18 +490,45 @@ void populate_service_list(ubus_data_handler_t callback) struct ubus_context *ctx = ubus_connect(NULL); struct blob_buf bb; - memset(&bb, 0, sizeof(struct blob_buf)); - blob_buf_init(&bb, 0); - fault = ubus_lookup_id(ctx, "service", &id); if (fault) { PRINT_ERR("ubus service not found %d", fault); + ubus_free(ctx); return; } + memset(&bb, 0, sizeof(struct blob_buf)); + blob_buf_init(&bb, 0); + // Invoke Ubus to get data from uspd fault = ubus_invoke(ctx, id, "list", bb.head, callback, NULL, UBUS_TIMEOUT); blob_buf_free(&bb); + ubus_free(ctx); } +int ubus_call_service_state(char *service, bool state) +{ + uint32_t id; + int rc = -1; + + struct ubus_context *ctx = ubus_connect(NULL); + if (ctx == NULL) { + return rc; + } + + struct blob_buf b; + memset(&b, 0, sizeof(struct blob_buf)); + + blob_buf_init(&b, 0); + blobmsg_add_u8(&b, "spawn", state); + blobmsg_add_string(&b, "name", service); + + if (!ubus_lookup_id(ctx, "service", &id)) + rc = ubus_invoke(ctx, id, "state", b.head, NULL, NULL, 5); + + blob_buf_free(&b); + ubus_free(ctx); + + return rc; +} diff --git a/src/tools.h b/src/tools.h index 3a4e016b5f1fdb0993dadeb93df16c22c308cb45..998a158f27c9c7296694e9e66c744e9728b9019b 100644 --- a/src/tools.h +++ b/src/tools.h @@ -78,6 +78,7 @@ void print_debug(const char *format, ...); int get_pid_details(int pid, char *cmdline, int *vsize); void populate_service_list(ubus_data_handler_t callback); void update_eu_from_blob(void *ct, int eid, const char *hname, struct blob_attr *msg); +int ubus_call_service_state(char *service, bool state); #define PRINT_DEBUG(fmt, args...) \ print_debug("[%s:%d]"fmt, __func__, __LINE__, ##args) diff --git a/test/api/json/swmodules.validation.json b/test/api/json/swmodules.validation.json index 7804f54f1c82ff3d84e779f5c07c40a4fd236313..a9f1e70f589164d235a055790bfb485e90ef79a7 100644 --- a/test/api/json/swmodules.validation.json +++ b/test/api/json/swmodules.validation.json @@ -16,16 +16,88 @@ { "method": "eu_list", "args": { + "eid": 1 + }, + "rc": 0 + }, + { + "method": "eu_list", + "args": { + "environment": "OpenWRT_Linux" + }, + "rc": 0 + }, + { + "method": "eu_list", + "args": { + "eid": 1, + "environment": "test" + }, + "rc": 0 + }, + { + "method": "eu_list", + "args": { + "eid": 3 + }, + "rc": 0 + }, + { + "method": "eu_list", + "args": { + "eid": 12 + }, + "rc": 0 + }, + { + "method": "eu_list", + "args": { + }, + "rc": 0 + }, + { + "method": "du_list", + "rc": 0 + }, + { + "method": "du_list", + "args": { + }, + "rc": 0 + }, + { + "method": "du_list", + "args": { + "eid": 1 + }, + "rc": 0 + }, + { + "method": "du_list", + "args": { + "environment": "OpenWRT_Linux" }, "rc": 0 }, { "method": "du_list", + "args": { + "eid": 1, + "environment": "test" + }, "rc": 0 }, { "method": "du_list", "args": { + "eid": 3 + }, + "rc": 0 + }, + { + "method": "du_list", + "args": { + "eid": 12 }, "rc": 0 }, @@ -42,28 +114,72 @@ { "method": "du_install", "args": { - "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", - "username": "user", - "password": "pass", - "environment": "test" + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "environment": "test" }, "rc": 2 }, { "method": "du_install", "args": { - "url": "http://localhost/" + "url": "http://localhost/" + }, + "rc": 0 + }, + { + "method": "du_install", + "args": { + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "environment": "test" }, "rc": 0 }, { "method": "du_install", "args": { - "url": "http://localhost/", - "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", - "username": "user", - "password": "pass", - "environment": "test" + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "eid": 2 + }, + "rc": 2 + }, + { + "method": "du_install", + "args": { + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "eid": 2, + "environment": "test" + }, + "rc": 2 + }, + { + "method": "du_install", + "args": { + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "eid": 2 + }, + "rc": 0 + }, + { + "method": "du_install", + "args": { + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "eid": 2, + "environment": "test" }, "rc": 0 }, @@ -80,50 +196,92 @@ { "method": "du_update", "args": { - "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", - "username": "user", - "password": "pass" + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass" + }, + "rc": 2 + }, + { + "method": "du_update", + "args": { + "url": "http://localhost/", + "username": "user", + "password": "pass" }, "rc": 2 }, { "method": "du_update", "args": { - "url": "http://localhost/", - "username": "user", - "password": "pass" + "url": "http://localhost/" }, "rc": 2 }, { "method": "du_update", "args": { - "url": "http://localhost/" + "url": "http://localhost/", + "eid": 2 }, "rc": 2 }, { "method": "du_update", "args": { - "url": "http://localhost/", - "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad" + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad" + }, + "rc": 0 + }, + { + "method": "du_update", + "args": { + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass" }, "rc": 0 }, { "method": "du_update", "args": { - "url": "http://localhost/", - "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", - "username": "user", - "password": "pass" + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "eid": 2 }, "rc": 0 - }{ + }, + { + "method": "du_update", + "args": { + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "environment": "test" + }, + "rc": 0 + }, + { + "method": "du_update", + "args": { + "url": "http://localhost/", + "uuid": "8f292aa3-0df5-435e-b2a4-e0e3c018bfad", + "username": "user", + "password": "pass", + "eid": 2, + "environment": "test" + }, + "rc": 0 + }, + { "method": "du_uninstall", "rc": 9 }, -, { "method": "du_uninstall", "args": { @@ -133,22 +291,92 @@ { "method": "du_uninstall", "args": { - "environment": "test" + "environment": "test" }, "rc": 2 }, { "method": "du_uninstall", "args": { - "name": "testd" + "name": "testd" }, "rc": 0 }, { "method": "du_uninstall", "args": { - "name": "testd", - "environment": "test" + "name": "testd", + "environment": "test" + }, + "rc": 0 + }, + { + "method": "du_uninstall", + "args": { + "name": "testd", + "eid": 2 + }, + "rc": 0 + }, + { + "method": "du_uninstall", + "args": { + "name": "testd", + "eid": 2, + "environment": "test" + }, + "rc": 0 + }, + { + "method": "eu_activate", + "rc": 2 + }, + { + "method": "eu_activate", + "args": { + }, + "rc": 2 + }, + { + "method": "eu_activate", + "args": { + "service_name": "testd" + }, + "rc": 2 + }, + { + "method": "eu_activate", + "args": { + "service_name": "testd", + "state": false + }, + "rc": 2 + }, + { + "method": "eu_activate", + "args": { + "eid": 1, + "service_name": "testd", + "state": false + }, + "rc": 0 + }, + { + "method": "eu_activate", + "args": { + "environment": "OpenWRT_Linux", + "service_name": "testd", + "state": true + }, + "rc": 0 + }, + { + "method": "eu_activate", + "args": { + "eid": 1, + "environment": "test", + "service_name": "testd", + "state": false }, "rc": 0 }