2022/12/28

Try coverity scan for opensource project

coverity scan有提供 opensource 專案免費使用的服務。
就是用你的 github 帳號登入後,按下上面頁面的 "find your project"。
他就會列出你所有的 github project。
你就可以選一個你的 project (為了安全起見,最好選有 opensource license 的project,為你的project 增加 LICENSE 聲明可參考github 說明)。
然後就跟隨網頁說明,一步一步做..
接著就是 submit build

build 的動作要在自己的 local 完成。
download 他提供的 build (and analysis ?)tool,build project 後,把結果upload 到 coverity 網站。
他就會產生分析結果。

2022/12/22

simple example : swagger-py-codgen, ui and flask-resetful server

就是..從朽 api.yaml 開始,然後 codegen, 寫api.py,啟動 ui and restful sever,最後用 ui 測試 server 的 api

先寫一個簡單的 myapi.yaml: (copy from pet.yaml)
openapi: 3.0.0
info:
  version: 1.0.0
  title: Hello API
  description: An API to return hello in request language

servers:
  - url: http://127.0.0.1:5000/v1
    description: local server

paths:
  /api:
    get:
      tags:
        - Hello
      description: Return hello in specified language
      parameters:
        - in: query
          name: lang
          required: true
          description: language
          schema:
            type: string
            example: es

      responses:
        '200':
          description: hello in
          content:
            text/plain:
              schema:
                type: string
                example: hoa
然後 codegen..
$swagger_py_codegen --swagger-doc myapi.yaml site --ui --spec
然後為 api get 增加動作:
diff --git a/v1/api/api.py b/v1/api/api.py
index 2efe114..50aacd3 100644
--- a/v1/api/api.py
+++ b/v1/api/api.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 from __future__ import absolute_import, print_function
 
-from flask import request, g
+from flask import request, g, make_response
 
 from . import Resource
 from .. import schemas
@@ -10,6 +10,6 @@ from .. import schemas
 class Api(Resource):
 
     def get(self):
-        print(g.args)
+        print(request.args)
 
-        return None, 200, None
\ No newline at end of file
+        return make_response(request.args['lang'],200)
然後到 site/site 下啟動 resetfule and ui server:
python __init__py
開啟覽器,到 swagger-ui 位置: http://127.0.0.1:5000/static/swagger-ui/index.html。
就可以用 swagger-ui,測試剛剛寫的 restfule server。


有些要注意的地方..

因為啟動的 __init__.py 有設定 :
    app.register_blueprint(
        v1.bp,
        url_prefix='/v1')
所以會在後面 v1/routes.py 中, path-handler 定義的位址加上 /v1/:
routes = [
    dict(resource=Api, urls=['/api'], endpoint='api'),
]
上面 /api 會變成 /v1/api,所以 myapi.yaml 的 servers 就要加上 /v1 ,這樣 swagger-ui 才能對正確的 url 動作。
這個github project 就是上面的說明,增加了 new user, userlist 的 api: 有比較多的 api 可以測試。

restful api and flask-restful

restful api 除了 http 的 PUT,GET,POST,DELETE 之外,有兩個地方可以"傳遞"參數給resetful server (flask)
  • url : /device/<devicde_id>/voltage/<meter_id>
  • body : 一般用 json 格式傳遞內容

其中 url 的部份, flask 用 api.add_resource(devicevoltage,'/device/<devicde_id>/voltage/<meter_id>)
產生變數 device_id, meter_id 在 devicevoltage 這個實做 http handler class 的 api入口,作為 參數:
class devicevoltage(Resource):
  def get(self,device_id,meter_id):
    ..
至於 body 的部份,在 flask-resetful 中,就會用 request 這個公用變數(? module?) 來提供:
   email    = request.get_json().get('email')
   username = request.get_json().get('username')

2022/12/20

swagger-py-codegen, modify source, build and test

因為在 api yaml 中有 date-time 型別,做 codegen 時加上 --spec (因為要 run swagger-ui),就會出現 Error:
    raise TypeError(f'Object of type {o.__class__.__name__} '
    TypeError: Object of type date is not JSON serializable
查。這邊 ,和這邊,都說是因為用 python 內建的 json package,在對 datetime 做 dump 時出現的 error。

所以自己寫一個tostring 的 class
from datetime import datetime,date

class myobjtostr(json.JSONEncoder):
    
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        
        if isinstance(obj, date):
            return obj.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self, obj)
然後在call dump 的地方改成:
      json.dumps(mydata, cls=myobjtostr)

出現Error 的地方式..
  File "/home/charles-chang/miniconda3/envs/swagger3.7/lib/python3.7/site-packages/swagger_py_codegen/command.py", line 200, in generate
    for code in generator.generate():
  File "/home/charles-chang/miniconda3/envs/swagger3.7/lib/python3.7/site-packages/swagger_py_codegen/base.py", line 47, in generate
    for code in self._process():
  File "/home/charles-chang/miniconda3/envs/swagger3.7/lib/python3.7/site-packages/swagger_py_codegen/flask.py", line 216, in _process
    yield Specification(dict(swagger=json.dumps(swagger, indent=2)))
所以是 flask.py line 216
修改:
diff --git a/swagger_py_codegen/flask.py b/swagger_py_codegen/flask.py
index 92f58c8..589bedf 100644
--- a/swagger_py_codegen/flask.py
+++ b/swagger_py_codegen/flask.py
@@ -6,6 +6,8 @@ from .base import Code, CodeGenerator
 from .jsonschema import Schema, SchemaGenerator, build_default
 import six

+from datetime import date,datetime
+
 SUPPORT_METHODS = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head']


@@ -116,6 +118,15 @@ def _location(swagger_location):
     }
     return location_map.get(swagger_location)

+import json
+class myobj2str(json.JSONEncoder):
+    def default(self, obj):
+        if isinstance(obj, datetime):
+            return obj.strftime('%Y-%m-%d %H:%M:%S')
+        if isinstance(obj, date):
+            return obj.strftime('%Y-%m-%d')
+        else:
+            return json.JSONEncoder.default(self.obj)

 class FlaskGenerator(CodeGenerator):
     dependencies = [SchemaGenerator]
@@ -213,7 +224,7 @@ class FlaskGenerator(CodeGenerator):
             swagger.update(self.swagger.origin_data)
             swagger.pop('host', None)
             swagger.pop('schemes', None)
-            yield Specification(dict(swagger=json.dumps(swagger, indent=2)))
+            yield Specification(dict(swagger=json.dumps(swagger, indent=2,cls=myobj2str)))

         yield Validator()

修改完後,follow 這一篇,用source code 中寫好的 setup.py 來 test build and run.
其中 developement mode:
$ python setup.py develop
這樣就可以run swagger_py_codegen,而且是 run 在 swagger-py-codegen 里的 code。
所以如果有錯,直接修改就可以。
不用再 install (run setup.py)

這樣改完的確不會再發生 error

改完的code:
另外,不知什麼原因,有的python 環境有simplejson 的會出現 error : module simplejson has no dump()。
所以要修改:
diff --git a/swagger_py_codegen/flask.py b/swagger_py_codegen/flask.py
index 403df02..8c51936 100644
--- a/swagger_py_codegen/flask.py
+++ b/swagger_py_codegen/flask.py
@@ -216,10 +216,7 @@ class FlaskGenerator(CodeGenerator):
         for view in views:
             yield View(view, dist_env=dict(view=view['endpoint']))
         if self.with_spec:
-            try:
-                import simplejson as json
-            except ImportError:
-                import json
+            import json
             swagger = {}
             swagger.update(self.swagger.origin_data)
             swagger.pop('host', None)
不要用 simplejson。

2022/12/16

step by step. mender yocto kirkstone

export BRANCH="kirkstone"
mkdir mender-kirkstone && cd mender-kirkstone
repo init -u https://github.com/mendersoftware/meta-mender-community \
           -m meta-mender-raspberrypi/scripts/manifest-raspberrypi.xml \
           -b ${BRANCH}
repo sync
然後...
$ source setup-environment raspberrypi
You had no conf/local.conf file. This configuration file has therefore been
created for you from /home/charles-chang/mender-kirkstone/sources/poky/meta-poky/conf/local.conf.sample
You may wish to edit it to, for example, select a different MACHINE (target
hardware). See conf/local.conf for more information as common configuration
options are commented.

You had no conf/bblayers.conf file. This configuration file has therefore been
created for you from /home/charles-chang/mender-kirkstone/sources/poky/meta-poky/conf/bblayers.conf.sample
To add additional metadata layers into your configuration please add entries
to conf/bblayers.conf.

The Yocto Project has extensive documentation about OE including a reference
manual which can be found at:
    https://docs.yoctoproject.org

For more information about OpenEmbedded see the website:
    https://www.openembedded.org/


### Shell environment set up for builds. ###

You can now run 'bitbake <target>'

Common targets are:
    core-image-minimal
    core-image-full-cmdline
    core-image-sato
    core-image-weston
    meta-toolchain
    meta-ide-support

You can also run generated qemu images with a command like 'runqemu qemux86'

Other commonly useful commands are:
 - 'devtool' and 'recipetool' handle common recipe tasks
 - 'bitbake-layers' handles common layer tasks
 - 'oe-pkgdata-util' handles common target package tasks
kirkstone 的 target 比較多...
然後就是
bitbake core-image-full-cmdline
build OK. dd boot,果然有 ssh server.

2022/12/13

mender-yocto build test.

  • 必須要enable mender-client 的 dbus 功能。
  • 數於 add-on
  • mender-connect 有 opensource,有 build from source 的說明
這一篇有 mender 的 yocto for rpi3 的 build instruction。
build 完,dd 發現沒有 enable ssh server。
參考這一篇,選 target : core-image-full-cmdline 就會包含 ssh server。
或是修改 build/conf/local.conf ,用 EXTRA_IMAGE_FEATURES 變數加上 ssh-server-openssh

其實..依照說明O:
export BRANCH="dunfell"
source setup-environment raspberrypi
之後,就會進入 build 目錄,然後顯示:
You can now run 'bitbake <target>'

Common targets are:
    core-image-minimal
    core-image-sato
    meta-toolchain
    meta-ide-support

其中 core-image-sato 就是有dropbear (小型 ssh server) 的 config。

core-image-sato 的話,出現 Error:
ERROR: File system image of partition None is larger (417792 kB) than its allowed size 204800 kB
sato 好像包含x11, 太大了。
在 build/conf/local.conf 中,comments 有:
 Mender storage configuration
#
# More details on these variables is available at
#    https://docs.mender.io/devices/yocto-project/partition-configuration#configuring-storage
#
# Also, please be sure to check other config files as other
# layers, config fragments, etc may attempt to set values
# for specific platforms.  Using "bitbake -e "
# can help determine which files are setting these values
# in a given configuration.
#
# MENDER_STORAGE_TOTAL_SIZE_MB = "2048"
# MENDER_BOOT_PART_SIZE_MB = "16"
# MENDER_DATA_PART_SIZE_MB = "1024"
# MENDER_STORAGE_DEVICE = "/dev/mmcblk0"
# MENDER_BOOT_PART = "${MENDER_STORAGE_DEVICE_BASE}1"
# MENDER_DATA_PART = "${MENDER_STORAGE_DEVICE_BASE}4"
# MENDER_ROOTFS_PART_A = "${MENDER_STORAGE_DEVICE_BASE}2"
# MENDER_ROOTFS_PART_B = "${MENDER_STORAGE_DEVICE_BASE}3"
可能可以用來改 partition 大小。
加入 MENDER_STORAGE_TOTAL_SIZE_MB = "4096" 後,好像就 build OK 了。

這個 target run 起來沒有 uart console。所以還是不能用。
最後是用 core-image-full-cmdline
run 起來後有 ssh
但是 mender authorize 還是有問題。

ref: 說明 meta-mender layer
下面的各個 layer:

meta-mender-core:
  • build command
  • image partition
  • bootloader

meta-mender-community: 一堆板子相關的設定

meta-mender-demo 跟 demo 板有關。
build for production有說明如何build profuction image (不是跟 demo server 連線?)

要先remove meta-mender-demo layer。
要準備好 cert.ca,如果server 是 self signed,那還要有 server 的 ca.


對應的 mender server,不要做demo mode,做 production mode。參考installation with docker compose。

依照3.4.0 板來做,最後 ./run up -d 之後,user-admin 這個container 一直 fail, restart。
用 docker log 看,是 key 的 permission。
發現是依照keygen 的 production/key-generated/keys/useradm/private.key 和 deviceauth/private.key 的 attrib 沒有 rw,都改 777 後再啟動就 OK 了。

另外,browser 要對 domain name,不能對 ip 作用。

結果 server.crt 還是沒 build 進去,因為缺了 meder-server-certifaction 這個 layer.
查,dunfell 這個branch 還沒有這個 layer..

yocto 的 branch name : Release

所以dunfell 後的LTS 是 Kirkstone
嘗試用這格 branch 試試..

一樣先follow 這個,只是 BRANCH=kirkstone。
作完setup-environment 後,在 build 下,依照這篇 修改 local.conf
certification 那邊,就抄local.conf 的, copy 過來,果然是新版bitbake 的語法。

這個..參考yocto: fetching from local directory:
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
是真的 project folder 下有一個 files 目錄。
然後..下面這個file..
SRC_URI += " file://app.tgz"
是說,找local file,不是到網路上的link..

2022/12/12

bookmark : 68xx area scanner

mmwav industrial toolbox , area scanner。
這個 labs example 可以偵測固定跟移動的物件。
也就是說,靜止不動的物件不會被 clutter removal 當作背景移除。
另外,他的TLV 輸出也有分為 polar 跟 cartesian 座標系。