うたカモ技術ブログ

Linux OpenWrt

OpenWrt   Luaスクリプト専用UCI関数の使い方

post:     update: 

今回は、OpenWrtのLuaスクリプト用UCI操作関数の使い方について紹介します。

このUCI操作関数は、WebUIのLuCIまたはLuCIと連携するCGIシステムがUCIコンフィグレーションファイルを操作するために使用しているものです。 luci.model.uciモジュールに収録されています。

これら関数の使い方を理解することで、UCIコンフィグレーションファイルを操作するCGIシステムの開発が容易になります。

関数仕様の詳細については既に公式ドキュメントに記載されています。 そのため、この記事ではサンプルコードとその実行結果を掲載することで使い方を説明します。

目次

  1. 実施環境
  2. サンプルコード用UCIコンフィグレーションファイル(/etc/config/sample)
  3. モジュールロード
    1. Cursor
    2. cursor_state
  4. Luaスクリプト用UCI操作関数の使い方
    1. Cursor:add
    2. Cursor:apply
    3. Cursor:changes
    4. Cursor:commit
    5. Cursor:confirm
    6. Cursor:delete
    7. Cursor:delete_all
    8. Cursor:foreach
    9. Cursor:get
    10. Cursor:get_all
    11. Cursor:get_bool
    12. Cursor:get_confdir
    13. Cursor:get_first
    14. Cursor:get_list
    15. Cursor:get_savedir
    16. Cursor:get_session_id
    17. Cursor:load
    18. Cursor:revert
    19. Cursor:rollback
    20. Cursor:rollback_pending
    21. Cursor:save
    22. Cursor:section
    23. Cursor:set
    24. Cursor:set_confdir
    25. Cursor:set_list
    26. Cursor:set_savedir
    27. Cursor:set_session_id
    28. Cursor:substate
    29. Cursor:tset
    30. Cursor:unload

実施環境

この記事は以下の環境で実施した結果を元に作成しています。

#OpenWrtデバイス
  名称:Raspberry Pi3 Model B
  CPU:ARM Cortex-A53 (1.2GHz)
  SOC:Broadcom BCM2837
  RAM:1GB
  ストレージ(media):MicroSDカード
#OpenWrt
  OpenWrt 22.03
#Lua
  Ver 5.1.5
#依存パッケージ
  luci-compat
opkg install luci-compatまたは、bulidrootのmake menuconfigによるluci-compat指定により導入してください。
  lua5.3(今回はver5.3を使用しましたが最新版であればOKなはずです。)
opkg install luaまたは、buildrootのmake menuconfigによるlua指定により導入してください。

サンプルコード用UCIコンフィグレーションファイル(/etc/config/sample)

掲載サンプルコードの操作対象ファイルは、この記事のために作成したUCIコンフィグレーションファイル(/etc/config/sample)です。

このUCIコンフィグレーションファイルはUCIコマンドを使用して作成できます。 読者ご自身の環境で、サンプルコードを実行したい場合は、お手持ちのOpenWrtデバイスのコンソール上で以下のUCIコマンドを実行してください。

root@OpenWrt:~# touch /etc/config/sample
root@OpenWrt:~# uci batch << EOI
> set sample.sectionA=type
> set sample.sectionA.flag1=on
> set sample.sectionA.flag2=off
> set sample.sectionA.flag3=true
> set sample.sectionA.flag4=false
> set sample.sectionA.flag5=1
> set sample.sectionA.flag6=0
> set sample.sectionB=type
> set sample.sectionB.value=100
> set sample.sectionC=type
> add_list sample.sectionC.items=1
> add_list sample.sectionC.items=2
> add_list sample.sectionC.items=3
> add_list sample.sectionC.items=4
> add_list sample.sectionC.items=5
> EOI
root@OpenWrt:~# uci commit sample

上記のコマンド実行後、catコマンドでsampleファイルの中身を見てみると、次のように表示されるはずです。

root@OpenWrt:~# cat /etc/config/sample

config confirm 'sectionA'
        option flag1 'on'
        option flag2 'off'
        option flag3 'true'
        option flag4 'false'
        option flag5 '1'
        option flag6 '0'

config confirm 'sectionB'
        option value '100'

config confirm 'sectionC'
        list items '1'
        list items '2'
        list items '3'
        list items '4'
        list items '5'

以上より、この記事では、/etc/config/sampleに対してUCI操作をするコードを掲載します。 これを通してLuaスクリプト用UCI操作関数について、その使い方を理解して頂ければ幸いです。 それでは、次節から説明に入ります。

モジュールロード

今回のLuaスクリプト用UCI操作関数を使用するためには、事前準備として luci.model.uciモジュールをロードし、その中から関数の情報が格納されたテーブルを取得する必要があります。 モジュールをロードして、テーブルを取得するには以下の2つの方法があります。

cursor()
通常、Luaスクリプト上でUCI操作関数を使用する際は、本関数を次のように呼び出します。
local uci = require("luci.model.uci").cursor()
これにより、以降はuci変数を通して、各UCI操作関数を実行することが可能になります。
そのため、この記事の掲載サンプルコードは、各UCI操作関数を本関数によって取得されたをLuaテーブルを経由して実行します。
cursor_state() ※作成中です。
local uci = require("luci").cursor_state()

Luaスクリプト用UCI操作関数の使い方

各UCI操作関数についてサンプルコードとその実行結果を掲載し、説明します。

Cursor:add(config, type)
add関数は任意のUCIコンフィグレーションファイルに対して匿名セクションを作成します。 作成された匿名セクションはステージング領域(default: /tmp/.uci)に保存されます。 静的データとして確定したい場合は、commit関数によってフラッシュ領域(default: /etc/config)にコピー(マージ)する必要があります。
次はsampleコンフィグ配下にtestタイプの匿名セクションを作成するサンプルコードです。
-- add_test.lua
local uci = require("luci.model.uci").cursor()
uci:add("sample", "test")
実行してみると、ステージング領域のsampleファイルにtestタイプの匿名セクションが作成されることが確認できます。
root@OpenWrt:~# lua add_test.lua
root@OpenWrt:~# cat /tmp/.uci/sample --catの代わりにuci changesでも同様の結果が表示されます。
+sample.cfg046865='test'
----->Cursor:add関数仕様
Cursor:apply(rollback) ※作成中です。
-- add_apply.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:apply関数仕様
Cursor:changes(config)
changes関数はステージング領域(default: /tmp/.uci)に保存された変更内容をLuaテーブルとして取得する関数です。
次は、sample.sectionB.valueの値を初期値の"100"から"hello"に変更し、ステージング領域に 保存した変更内容をコンソールに表示するサンプルコードです。
-- changes_test.lua
local uci = require("luci.model.uci").cursor()

-- uci:set関数で以下のsampleコンフィグ設定を変更
-- 新規データとして、sample.sectionB.value='hello'をステージング領域に保存します。
uci:set("sample", "sectionB", "value", "hello")

local config_data = uci:changes("sample")

-- ステージング領域のsampleコンフィグを表示
for _, table in ipairs(config_data) do
        for _, val in ipairs(table) do
                io.write(val .. " ")
        end
        io.write("\n")
end
実行してみると、次のようにsampleコンフィグのステージング領域の変更内容が表示されます。 今回の場合では、sample.sectionB.valueが'hello'という値に更新(set)されたことがLuaテーブルの内容から分かります。
root@OpenWrt:~# lua changes_test.lua
set sectionB value hello
----->Cursor:changes関数仕様
Cursor:commit(config)
ステージング領域(default: /tmp/.uci)に保存された変更差分をフラッシュ領域(default: /etc/config)にコピー(マージ)します。 次はsample.sectionB.valueの値を初期値の"100"から"hello"に変更し、その変更内容をフラッシュ領域にコピー(マージ)するサンプルコードです。
-- commit_test.lua
local loca uci = require("luci.model.uci").cursor()

uci:set("sample", "sectionB", "value", "hello")
uci:commit("sample")
実行してみると、フラッシュ領域である/etc/config内の対応するUCIコンフィグレーションファイル(今回はsample) に変更内容が反映されていることが確認できます。
root@OpenWrt:~# lua commit_test.lua
root@OpenWrt:~# cat /etc/config/sample

config type 'sectionA'
        option flag1 'on'
        option flag2 'off'
        option flag3 'true'
        option flag4 'false'
        option flag5 '1'
        option flag6 '0'

config type 'sectionB'
        option value 'hello'

config type 'sectionC'
        list items '1'
        list items '2'
        list items '3'
        list items '4'
        list items '5'
----->Cursor:commit関数仕様
Cursor:confirm() ※作成中です。
-- confirm_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:confirm関数仕様
Cursor:delete(config, section, option)
[1]:指定セクションを削除する
任意セクションを削除します。削除内容はステージング領域(default:/tmp/.uci)の対応するUCIコンフィグレーションファイルに 保存されます。次はsample.sectionBを削除するサンプルコードです。
-- delete_section_test.lua
local uci = require("luci.model.uci").cursor()
uci:delete("sample", "sectionB")
実行してみると、ステージング領域に削除内容が保存されていることが確認できます。 通常、この後にcommit関数によってフラッシュ領域に削除内容をコピー(マージ)することで sample.sectionBの削除が確定します。
root@OpenWrt:~# lua delete_section_test.lua
root@OpenWrt:~# uci changes
-sample.sectionB
[2]:指定オプションを削除する
任意セクションのオプションを削除します。削除内容はステージング領域(default:/tmp/.uci)の対応するUCIコンフィグレーションファイルに 保存されます。次はsample.sectionB.valueを削除するサンプルコードです。
-- delete_option_test.lua
local uci = require("luci.model.uci").cursor()
uci:delete("sample", "sectionB", "value")
実行してみると、ステージング領域に削除内容が保存されていることが確認できます。 通常、この後にcommit関数によってフラッシュ領域に削除内容をコピー(マージ)することで sample.sectionB.valueの削除が確定します。
root@OpenWrt:~# lua delete_option_test.lua
root@OpenWrt:~# uci changes
-sample.sectionB.value
----->Cursor:delete関数仕様
Cursor:delete_all(config, type, comparator)
任意UCIコンフィグレーションファイル(config)の指定タイプ情報(type)を持つセクションを削除し、その変更内容をステージング領域(default: /tmp/.uci)に保存します。 このとき、第三引数にコールバック関数(comparator)を指定することで、削除対象セクションを本当に削除するか判定処理に掛けることができます。
次は、sampleコンフィグの"type"タイプを持つセクションで、名前が「sectionB」と「sectionA」のデータを削除するサンプルコードです。 コールバック関数としてcomparatorを定義し、その中でsectionBとsectionCの名前を持ったセクションを削除対象として最終決定しています。
-- delete_all_test.lua
local uci = require("luci.model.uci").cursor()
local call_cnt = 0

function output_msg(data, message)
        if type(data) == "table" then
                for key, val in pairs(data) do
                        local _message = message .. "[" .. key .. "]"
                        output_msg(val, _message)
                end

        elseif type(data) == "boolean" then
            if data == true then
                    io.write(message .. " = true\n")
            elseif data == false then
                    io.write(message .. " = false\n")
            end

        elseif type(data) == "string" or type(data) == "number" then
            io.write(message .. " = " .. data .. "\n")
        end
end

function comparator(table)

        local delete_flg = false

        call_cnt = call_cnt + 1
        print("---------[CALLED FUNC No." .. call_cnt .. "]----------")
        for key, val in pairs(table) do
                local message = "table[" .. key .. "]"
                output_msg(val, message)
                io.flush()
        end

        -- sampleからセクション名「sectionB」、「sectionC」のデータを削除します
        if table[".name"] == "sectionB" then
                delete_flg = true
        elseif table[".name"] == "sectionC" then
                delete_flg = true
        end

        -- 返却値がtrueならセクションを削除します
        return delete_flg
end

uci:delete_all("sample", "type", comparator)
実行してみると、「sectionB」と「sectionC」という名のセクションが削除され、ステージング領域にその変更が保存されます。
root@OpenWrt:~# lua delete_all_test.lua
---------[CALLED FUNC No.1]----------
table[.name] = sectionB
table[.type] = type
table[value] = hello
table[.anonymous] = false
table[.index] = 1
---------[CALLED FUNC No.2]----------
table[flag2] = off
table[.anonymous] = false
table[flag3] = true
table[.index] = 0
table[flag4] = false
table[flag6] = 0
table[flag5] = 1
table[flag1] = on
table[.name] = sectionA
table[.type] = type
---------[CALLED FUNC No.3]----------
table[.name] = sectionC
table[.type] = type
table[items][1] = 1
table[items][2] = 2
table[items][3] = 3
table[items][4] = 4
table[items][5] = 5
table[.anonymous] = false
table[.index] = 2
root@OpenWrt:~# uci changes
-sample.sectionB
-sample.sectionC
上記結果から、コールバック関数は各セクションの読み込みごとに呼び出されることが分かります。 そして、コールバック関数の戻り値がtrueであれば、そのセクションは最終的な削除対象となります。
----->Cursor:delete_all関数仕様
Cursor:foreach(config, type, callback)
任意UCIコンフィグレーションファイル(config)の指定タイプ情報(type)を持つセクションに対して、何等かの処理(callback)を実行したい場合に使用する イテレータ関数です。
次は、sampleコンフィグのconfirmタイプのセクションの中身を表示するサンプルコードです。 セクションの内容をコンソールに表示するコールバック関数を第三引数に指定することで、各対象セクションの読み込みごとに呼び出されます。
-- foreach_test.lua
local uci = require("luci.model.uci").cursor()
local call_cnt = 0

function output_msg(data, message)
        if type(data) == "table" then
                for key, val in pairs(data) do
                        local _message = message .. "[" .. key .. "]"
                        output_msg(val, _message)
                end

        elseif type(data) == "boolean" then
            if data == true then
                    io.write(message .. " = true\n")
            elseif data == false then
                    io.write(message .. " = false\n")
            end

        elseif type(data) == "string" or type(data) == "number" then
            io.write(message .. " = " .. data .. "\n")
        end
end

function callback(table)

        call_cnt = call_cnt + 1
        print("---------[CALLED FUNC No." .. call_cnt .. "]----------")
        for key, val in pairs(table) do
                local message = "table[" .. key .. "]"
                output_msg(val, message)
                io.flush()
        end
end

uci:foreach("sample", "type", callback)
実行してみると、各対象セクションごとにコールバック関数が呼び出され、展開されたLuaテーブルの内容が表示されます。
root@OpenWrt:~# lua foreach_test.lua
---------[CALLED FUNC No.1]----------
table[flag2] = off
table[.anonymous] = false
table[flag3] = true
table[.index] = 0
table[flag4] = false
table[flag6] = 0
table[flag5] = 1
table[flag1] = on
table[.name] = sectionA
table[.type] = type
---------[CALLED FUNC No.2]----------
table[.name] = sectionB
table[.type] = type
table[value] = hello
table[.anonymous] = false
table[.index] = 1
---------[CALLED FUNC No.3]----------
table[.name] = sectionC
table[.type] = type
table[items][1] = 1
table[items][2] = 2
table[items][3] = 3
table[items][4] = 4
table[items][5] = 5
table[.anonymous] = false
table[.index] = 2
----->Cursor:foreach関数仕様
Cursor:get(config, section)
任意UCIコンフィグレーションファイルの指定オプション値を取得する関数です。 次は、sample.sectionB.valueの値を取得して変数valに格納するサンプルコードです。
-- get_test.lua
local uci = require("luci.model.uci").cursor()
local val = uci:get("sample", "sectionB", "value")

print("sample.sectionB.value = " .. val)
実行してみると、次のようにsample.sectionB.valueの現在値が取得できます。
root@OpenWrt:~# lua get_test.lua
sample.sectionB.value = 100
----->Cursor:get関数仕様
Cursor:get_all(config, section)
任意UCIコンフィグレーションファイルの指定セクションが持つ全オプション値を取得します。 次は、sampleコンフィグが持つオプション値を全て取得してコンソールに表示するサンプルコードです。
-- get_all_test.lua
local uci = require("luci.model.uci").cursor()

local sample = uci:get_all("sample")

for key, val in pairs(sample) do
        for k, v in pairs(val) do
                if type(v) == "string" then
                        print("sample[" .. key .. "][" .. k .. "] = " .. v)
                elseif type(v) == "boolean" then
                        if v == true then
                                print("sample[" .. key .. "][" .. k .. "] = true")
                        else
                                print("sample[" .. key .. "][" .. k .. "] = false")
                        end
                end
        end
end
実行してみると、sampleコンフィグのboolセクションの全オプション値をLuaテーブルとして取得、コンソール上に表示します。
root@OpenWrt:~# lua get_all_test.lua
sample[option][.name] = sectionB
sample[option][.type] = type
sample[option][value] = hello
sample[option][.anonymous] = false
sample[bool][flag2] = off
sample[bool][.anonymous] = false
sample[bool][flag3] = true
sample[bool][flag4] = false
sample[bool][flag6] = 0
sample[bool][flag5] = 1
sample[bool][flag1] = on
sample[bool][.name] = sectionA
sample[bool][.type] = type
sample[list][.name] = sectionC
sample[list][.type] = type
sample[list][.anonymous] = false
----->Cursor:get_all関数仕様
Cursor:get_bool(config, section, option)
オプションやリストデータが持つ特定文字列をLuaスクリプトの論理値であるtrue/falseに変換します。 論理値として変換される対象文字列は下表の通りです。
真(true) 偽(false)
'on'左記以外
'true'
'yes'
'1'
次は、上記表の文字列を論理値に変換し、その結果をコンソールに表示するサンプルコードです。
-- get_bool_test.lua
local uci = require("luci.model.uci").cursor()

local flg = {}

flg.result1 = uci:get_bool("sample", "sectionA", "flag1") -- 'on'
flg.result2 = uci:get_bool("sample", "sectionA", "flag2") -- 'off'
flg.result3 = uci:get_bool("sample", "sectionA", "flag3") -- 'true'
flg.result4 = uci:get_bool("sample", "sectionA", "flag4") -- 'false'
flg.result5 = uci:get_bool("sample", "sectionA", "flag5") -- '1'
flg.result6 = uci:get_bool("sample", "sectionA", "flag6") -- '0'

for key, val in pairs(flg) do
    io.write("flg." .. key .. " = ")
    if val == true then
        io.write("true\n")
    else
        io.write("false\n")
    end
end
実行してみると、論理値を示す文字列が真(true)もしくは偽(false)に変換されます。 今回は、コンソール表示をするために"true"と"false"を出力するようにしています。
root@OpenWrt:~# lua get_bool_test.lua
flg.result6 = false
flg.result4 = false
flg.result1 = true
flg.result5 = true
flg.result3 = true
flg.result2 = false
----->Cursor:get_bool関数仕様
Cursor:get_confdir()
UCIコンフィグレーションファイルの格納ディレクトリ(フラッシュ領域)を文字列として取得します。2023年3月現在の実装では 戻り値が"/etc/config"としてハードコーティングされているため、常に"/etc/config"を返す関数になっています。
次はget_confdir関数を使用したサンプルコードです。
-- get_confdir_test.lua
local uci = require("luci.model.uci").cursor()
local flash_dir = uci:get_confdir()
print("flash dir: " .. flash_dir)
実行結果は以下の通りです。今後、フラッシュ領域のディレクトリ変更に対応した実装に変更される かもしれませんが、現在は自明の"/etc/config"が出力されます。
root@OpenWrt:~# lua get_confdir_test.lua
flash dir: /etc/config
----->Cursor:get_confdir関数仕様
Cursor:get_first (config, type, option, default) ※作成中です。
-- get_first_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:get_first関数仕様
Cursor:get_list(config, section, option)
任意UCIコンフィグレーションファイル(config)の指定セクション(section)のリスト(option)をLuaテーブルとして取得します。 次は、sampleコンフィグのlistセクション内にあるitemsリストを取得するサンプルコードです。
-- get_list_test.lua
local uci = require("luci.model.uci").cursor()
local table = uci:get_list("sample", "sectionC", "items")

for idx, val in ipairs(table) do
        print("table[" .. idx .. "] = " .. table[idx])
end
実行すると、次のようにLuaテーブルにリストの各データが格納されます。
root@OpenWrt:~# lua get_list_test.lua
table[1] = 1
table[2] = 2
table[3] = 3
table[4] = 4
table[5] = 5
----->Cursor:get_list関数仕様
Cursor:get_savedir()
UCIコンフィグレーションファイルのステージング領域を文字列として取得します。2023年3月現在の実装では 戻り値が"/tmp/.uci"としてハードコーティングされているため、常に"/tmp/.uci"を返す関数になっています。
次はget_savedir関数を使用したサンプルコードです。
-- get_savedir_test.lua
local uci = require("luci.model.uci").cursor()
local staging_dir = uci:get_savedir()
print("staging dir = " .. staging_dir)
実行結果は以下の通りです。今後、ステージング領域のディレクトリ変更に対応した実装に変更される かもしれませんが、現在は自明の"/tmp/.uci"が出力されます。
root@OpenWrt:~# lua get_savedir_test.lua
staging dir: /tmp/.uci
----->Cursor:get_savedir関数仕様
Cursor:get_session_id() ※作成中です。
-- get_session_id_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:get_session_id関数仕様
Cursor:load(config) ※作成中です。
-- load_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:load関数仕様
Cursor:revert(config)
ステージング領域(default:/tmp/.uci)に保存された任意のUCIコンフィグレーションファイルの変更差分を消去します。 次は、set関数によってステージング領域に保存したsampleコンフィグのvalueオプション値を消去するサンプルコードです。
-- revert_test.lua
local uci = require("luci.model.uci").cursor()
uci:set("sample", "sectionB", "value", "hello")
uci:revert("sample")
実行してみると、ステージング領域に保存されたvalueオプションの値である"hello"が消去されていることが確認できます。 (そのため、これは何の役にも立っていないスクリプトです。)
root@OpenWrt:~# lua revert_test.lua
root@OpenWrt:~# uci changes sample
root@Openwrt:~#                    #変更内容は消去されたので、何も表示されません
----->Cursor:revert関数仕様
Cursor:rollback() ※作成中です。
-- rollback_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:rollback関数仕様
Cursor:rollback_pending() ※作成中です。
-- rollback_pending_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:rollback_pending関数仕様
Cursor:save(config) ※作成中です。
-- save_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:save関数仕様
Cursor:section(config, type, name, values)
指定UCIコンフィグレーションファイル(config)に新しいタイプ(type)とセクション(name)、オプション(option)を追加し、その内容をステージング領域(default: /tmp/.uci)に保存します。 次は、sampleコンフィグに"new"タイプの"sectionD"セクションを追加し、配下にdata1とdata2オプションを追加するサンプルコードです。
-- section_test.lua
local uci = require("luci.model.uci").cursor()
local option = {
        data1 = "created!",
        data2 = "created!",
}

uci:section("sample", "new", "sectionD", option)
実行すると、確かにsampleコンフィグの新たなデータとしてnewセクションのdata1とdata2オプションがステージングされることが確認できます。
root@OpenWrt:~# lua section_test.lua
root@OpenWrt:~# uci changes
sample.sectionD='new'
sample.sectionD.data1='created!'
sample.sectionD.data2='created!'
----->Cursor:section関数仕様
Cursor:set(config, section, option, value)
任意UCIコンフィグレーションファイルの指定セクションに対するオプションの新規追加または値変更をします。 変更内容はステージング領域(default: /tmp/.uci)の対応するUCIコンフィグレーションファイルに保存されます。 次はsample.sectionB.valueの値を初期値の"100"から"hello"に変更するサンプルコードです。
-- set_test.lua
local uci = require("luci.model.uci").cursor()
uci:set("sample", "sectionB", "value", "hello")
実行してみると、ステージング領域に変更内容が保存されることが確認できます。 通常、続いてcommit関数を実行することでフラッシュ領域に変更内容がコピー(マージ)されます。
root@OpenWrt:~# lua set_test.lua
root@OpenWrt:~# uci changes
sample.sectionB.value='hello'
----->Cursor:set関数仕様
Cursor:set_confdir(directory) ※作成中です。
-- set_confdir_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:set_confdir関数仕様
Cursor:set_list(config, section, option, value)
任意UCIコンフィグレーションファイル(config)の指定セクション(section)配下にリストデータ(option)を作成し、その変更内容(value)を ステージング領域(default: /tmp/uci)に保存します。第三引数にLuaテーブルを指定することで一度 に複数のデータを追加することが可能です。指定したセクションが既に存在する場合、既存リストデータは消去され、新しいデータで上書きされます。
次は、sampleコンフィグの"sectionC"セクションに新たなリストデータgreetingsを作成するサンプルコードです。 追加するデータは3つ('good morning'、'hello'、'good bye')です。
-- set_list_test.lua
local uci = require("luci.model.uci").cursor()
local words = {
        "good morning",
        "hello",
        "good bye",
}

uci:set_list("sample", "sectionC", "greetings", words)
実行してみると、"sectionC"セクションにgreetingsが3つのデータを持った状態で作成され、その変更内容が ステージング領域に保存されることが確認できます。
root@OpenWrt:~# lua set_list_test.lua
root@OpenWrt:~# uci changes
sample.sectionC.greetings+='good morning'
sample.sectionC.greetings+='hello'
sample.sectionC.greetings+='good bye'
----->Cursor:set_list関数仕様
Cursor:set_session_id(id) ※作成中です。
-- set_session_id_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:set_session_id関数仕様
Cursor:substate() ※作成中です。
-- substate_test.lua
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:substate関数仕様
Cursor:tset(config, section, values)
指定UCIコンフィグレーションファイル(config)の既存セクション(section)に対して、オプション(values)を追加し、その内容をステージング領域(default: /tmp/.uci)に保存します。 追加するオプションはテーブルデータとして定義し、第三引数に指定することで対象セクションに追加することが可能です。 これにより、一度に複数のオプションを追加することが出来ます。
次は、sampleコンフィグの既存セクション「sectionB」に3つの新規オプション(greeting1~3)を追加するサンプルコードです。
-- tset_test.lua
local uci = require("luci.model.uci").cursor()

local new_options = {
    greeting1 = "good morning",
    greeting2 = "hello",
    greeting3 = "good bye",
}

uci:tset("sample", "sectionB", new_options)
実行すると、既存セクションの「sectionB」に新たなオプション(greeting1~3)が追加され、その内容がステージング領域に保存されることが 確認出来ます。
root@OpenWrt:~# lua tset_test.lua
root@OpenWrt:~# uci changes
sample.sectionB.greeting3='good bye'
sample.sectionB.greeting1='good morning'
sample.sectionB.greeting2='hello'
----->Cursor:tset関数仕様
Cursor:unload(config) ※作成中です。
#!/usr/bin/lua
local uci = require("luci.model.uci").cursor()
----->Cursor:unload関数仕様

関連記事

参考文献