summaryrefslogtreecommitdiffstats
path: root/vpp-api/lua/examples/cli/lua-cli.lua
diff options
context:
space:
mode:
Diffstat (limited to 'vpp-api/lua/examples/cli/lua-cli.lua')
-rw-r--r--vpp-api/lua/examples/cli/lua-cli.lua747
1 files changed, 0 insertions, 747 deletions
diff --git a/vpp-api/lua/examples/cli/lua-cli.lua b/vpp-api/lua/examples/cli/lua-cli.lua
deleted file mode 100644
index b3a24d7d0ef..00000000000
--- a/vpp-api/lua/examples/cli/lua-cli.lua
+++ /dev/null
@@ -1,747 +0,0 @@
---[[
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-]]
-
--- Experimental prototype CLI using API to VPP, with tab completion
---
--- Written by Andrew Yourtchenko (ayourtch@cisco.com) 2010,2016
---
-
-vpp = require "vpp-lapi"
-
-
-local dotdotdot = "..."
-
--- First the "readline" routine
-
-readln = {
-split = function(str, pat)
- local t = {} -- NOTE: use {n = 0} in Lua-5.0
- local fpat = "(.-)" .. pat
- local last_end = 1
- if str then
- local s, e, cap = str:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(t,cap)
- end
- last_end = e+1
- s, e, cap = str:find(fpat, last_end)
- end
- if last_end <= #str then
- cap = str:sub(last_end)
- table.insert(t, cap)
- end
- end
- return t
-end,
-
-reader = function()
- local rl = {}
-
- rl.init = function()
- os.execute("stty -icanon min 1 -echo")
- rl.rawmode = true
- end
-
- rl.done = function()
- os.execute("stty icanon echo")
- rl.rawmode = false
- end
-
- rl.prompt = ">"
- rl.history = { "" }
- rl.history_index = 1
- rl.history_length = 1
-
- rl.hide_cmd = function()
- local bs = string.char(8) .. " " .. string.char(8)
- for i = 1, #rl.command do
- io.stdout:write(bs)
- end
- end
-
- rl.show_cmd = function()
- if rl.command then
- io.stdout:write(rl.command)
- end
- end
-
- rl.store_history = function(cmd)
- if cmd == "" then
- return
- end
- rl.history[rl.history_length] = cmd
- rl.history_length = rl.history_length + 1
- rl.history_index = rl.history_length
- rl.history[rl.history_length] = ""
- end
-
- rl.readln = function()
- local done = false
- local need_prompt = true
- rl.command = ""
-
- if not rl.rawmode then
- rl.init()
- end
-
- while not done do
- if need_prompt then
- io.stdout:write(rl.prompt)
- io.stdout:write(rl.command)
- need_prompt = false
- end
-
- local ch = io.stdin:read(1)
- if ch:byte(1) == 27 then
- -- CONTROL
- local ch2 = io.stdin:read(1)
- -- arrows
- if ch2:byte(1) == 91 then
- local ch3 = io.stdin:read(1)
- local b = ch3:byte(1)
- if b == 65 then
- ch = "UP"
- elseif b == 66 then
- ch = "DOWN"
- elseif b == 67 then
- ch = "RIGHT"
- elseif b == 68 then
- ch = "LEFT"
- end
- -- print("Byte: " .. ch3:byte(1))
- -- if ch3:byte(1)
- end
- end
-
- if ch == "?" then
- io.stdout:write(ch)
- io.stdout:write("\n")
- if rl.help then
- rl.help(rl)
- end
- need_prompt = true
- elseif ch == "\t" then
- if rl.tab_complete then
- rl.tab_complete(rl)
- end
- io.stdout:write("\n")
- need_prompt = true
- elseif ch == "\n" then
- io.stdout:write(ch)
- done = true
- elseif ch == "\004" then
- io.stdout:write("\n")
- rl.command = nil
- done = true
- elseif ch == string.char(127) then
- if rl.command ~= "" then
- io.stdout:write(string.char(8) .. " " .. string.char(8))
- rl.command = string.sub(rl.command, 1, -2)
- end
- elseif #ch > 1 then
- -- control char
- if ch == "UP" then
- rl.hide_cmd()
- if rl.history_index == #rl.history then
- rl.history[rl.history_index] = rl.command
- end
- if rl.history_index > 1 then
- rl.history_index = rl.history_index - 1
- rl.command = rl.history[rl.history_index]
- end
- rl.show_cmd()
- elseif ch == "DOWN" then
- rl.hide_cmd()
- if rl.history_index < rl.history_length then
- rl.history_index = rl.history_index + 1
- rl.command = rl.history[rl.history_index]
- end
- rl.show_cmd()
- end
- else
- io.stdout:write(ch)
- rl.command = rl.command .. ch
- end
- end
- if rl.command then
- rl.store_history(rl.command)
- end
- return rl.command
- end
- return rl
-end
-
-}
-
---[[
-
-r = reader()
-
-local done = false
-
-while not done do
- local cmd = r.readln()
- print("Command: " .. tostring(cmd))
- if not cmd or cmd == "quit" then
- done = true
- end
-end
-
-r.done()
-
-]]
-
---------- MDS show tech parser
-
-local print_section = nil
-local list_sections = false
-
-local curr_section = "---"
-local curr_parser = nil
-
--- by default operate in batch mode
-local batch_mode = true
-
-local db = {}
-local device = {}
-device.output = {}
-local seen_section = {}
-
-function start_collection(name)
- device = {}
- seen_section = {}
-end
-
-function print_error(errmsg)
- print("@#$:" .. errmsg)
-end
-
-function keys(tbl)
- local t = {}
- for k, v in pairs(tbl) do
- table.insert(t, k)
- end
- return t
-end
-
-function tset (parent, ...)
-
- -- print ('set', ...)
-
- local len = select ('#', ...)
- local key, value = select (len-1, ...)
- local cutpoint, cutkey
-
- for i=1,len-2 do
-
- local key = select (i, ...)
- local child = parent[key]
-
- if value == nil then
- if child == nil then return
- elseif next (child, next (child)) then cutpoint = nil cutkey = nil
- elseif cutpoint == nil then cutpoint = parent cutkey = key end
-
- elseif child == nil then child = {} parent[key] = child end
-
- parent = child
- end
-
- if value == nil and cutpoint then cutpoint[cutkey] = nil
- else parent[key] = value return value end
- end
-
-
-function tget (parent, ...)
- local len = select ('#', ...)
- for i=1,len do
- parent = parent[select (i, ...)]
- if parent == nil then break end
- end
- return parent
- end
-
-
-local pager_lines = 23
-local pager_printed = 0
-local pager_skipping = false
-local pager_filter_pipe = nil
-
-function pager_reset()
- pager_printed = 0
- pager_skipping = false
- if pager_filter_pipe then
- pager_filter_pipe:close()
- pager_filter_pipe = nil
- end
-end
-
-
-function print_more()
- io.stdout:write(" --More-- ")
-end
-
-function print_nomore()
- local bs = string.char(8)
- local bs10 = bs .. bs .. bs .. bs .. bs .. bs .. bs .. bs .. bs .. bs
- io.stdout:write(bs10 .. " " .. bs10)
-end
-
-function print_line(txt)
- if pager_filter_pipe then
- pager_filter_pipe:write(txt .. "\n")
- return
- end
- if pager_printed >= pager_lines then
- print_more()
- local ch = io.stdin:read(1)
- if ch == " " then
- pager_printed = 0
- elseif ch == "\n" then
- pager_printed = pager_printed - 1
- elseif ch == "q" then
- pager_printed = 0
- pager_skipping = true
- end
- print_nomore()
- end
- if not pager_skipping then
- print(txt)
- pager_printed = pager_printed + 1
- else
- -- skip printing
- end
-end
-
-function paged_write(text)
- local t = readln.split(text, "[\n]")
- if string.sub(text, -1) == "\n" then
- table.insert(t, "")
- end
- for i, v in ipairs(t) do
- if i < #t then
- print_line(v)
- else
- if pager_filter_pipe then
- pager_filter_pipe:write(v)
- else
- io.stdout:write(v)
- end
- end
- end
-end
-
-
-
-
-
-function get_choices(tbl, key)
- local res = {}
- for k, v in pairs(tbl) do
- if string.sub(k, 1, #key) == key then
- table.insert(res, k)
- elseif 0 < #key and dotdotdot == k then
- table.insert(res, k)
- end
- end
- return res
-end
-
-function get_exact_choice(choices, val)
- local exact_idx = nil
- local substr_idx = nil
- local substr_seen = false
-
- if #choices == 1 then
- if choices[1] == dotdotdot then
- return 1
- elseif string.sub(choices[1], 1, #val) == val then
- return 1
- else
- return nil
- end
- else
- for i, v in ipairs(choices) do
- if v == val then
- exact_idx = i
- substr_seen = true
- elseif choices[i] ~= dotdotdot and string.sub(choices[i], 1, #val) == val then
- if substr_seen then
- substr_idx = nil
- else
- substr_idx = i
- substr_seen = true
- end
- elseif choices[i] == dotdotdot then
- if substr_seen then
- substr_idx = nil
- else
- substr_idx = i
- substr_seen = true
- end
- end
- end
- end
- return exact_idx or substr_idx
-end
-
-function device_cli_help(rl)
- local key = readln.split(rl.command, "[ ]+")
- local tree = rl.tree
- local keylen = #key
- local fullcmd = ""
- local error = false
- local terse = true
-
- if ((#rl.command >= 1) and (string.sub(rl.command, -1) == " ")) or (#rl.command == 0) then
- table.insert(key, "")
- terse = false
- end
-
- for i, v in ipairs(key) do
- local choices = get_choices(tree, v)
- local idx = get_exact_choice(choices, v)
- if idx then
- local choice = choices[idx]
- tree = tree[choice]
- fullcmd = fullcmd .. choice .. " "
- else
- if i < #key then
- error = true
- end
- end
-
- if i == #key and not error then
- for j, w in ipairs(choices) do
- if terse then
- paged_write(w .. "\t")
- else
- paged_write(" " .. w .. "\n")
- end
- end
- paged_write("\n")
- if terse then
- paged_write(" \n")
- end
- end
- end
- pager_reset()
-end
-
-function device_cli_tab_complete(rl)
- local key = readln.split(rl.command, "[ ]+")
- local tree = rl.tree
- local keylen = #key
- local fullcmd = ""
- local error = false
-
- for i, v in ipairs(key) do
- local choices = get_choices(tree, v)
- local idx = get_exact_choice(choices, v)
- if idx and choices[idx] ~= dotdotdot then
- local choice = choices[idx]
- tree = tree[choice]
- -- print("level " .. i .. " '" .. choice .. "'")
- fullcmd = fullcmd .. choice .. " "
- else
- -- print("level " .. i .. " : " .. table.concat(choices, " ") .. " ")
- error = true
- end
- end
- if not error then
- rl.command = fullcmd
- else
- -- print("\n\nerror\n")
- end
- pager_reset()
-end
-
-function device_cli_exec(rl)
-
- local cmd_nopipe = rl.command
- local cmd_pipe = nil
-
- local pipe1, pipe2 = string.find(rl.command, "[|]")
- if pipe1 then
- cmd_nopipe = string.sub(rl.command, 1, pipe1-1)
- cmd_pipe = string.sub(rl.command, pipe2+1, -1)
- end
-
- local key = readln.split(cmd_nopipe .. " <cr>", "[ ]+")
- local tree = rl.tree
- local keylen = #key
- local fullcmd = ""
- local error = false
- local func = nil
-
- if cmd_pipe then
- pager_filter_pipe = io.popen(cmd_pipe, "w")
- end
-
-
- rl.choices = {}
-
- for i, v in ipairs(key) do
- local choices = get_choices(tree, v)
- local idx = get_exact_choice(choices, v)
- if idx then
- local choice = choices[idx]
- if i == #key then
- func = tree[choice]
- else
- if choice == dotdotdot then
- -- keep the tree the same, update the choice value to match the input string
- choices[idx] = v
- choice = v
- else
- tree = tree[choice]
- end
- end
- -- print("level " .. i .. " '" .. choice .. "'")
- table.insert(rl.choices, choice)
- else
- -- print("level " .. i .. " : " .. table.concat(choices, " ") .. " ")
- error = true
- return nil
- end
- end
- return func
-end
-
-function populate_tree(commands)
- local tree = {}
-
- for k, v in pairs(commands) do
- local key = readln.split(k .. " <cr>", "[ ]+")
- local xtree = tree
- for i, kk in ipairs(key) do
- if i == 1 and kk == "sh" then
- kk = "show"
- end
- if i == #key then
- if type(v) == "function" then
- xtree[kk] = v
- else
- xtree[kk] = function(rl) paged_write(table.concat(v, "\n") .. "\n") end
- end
- else
- if not xtree[kk] then
- xtree[kk] = {}
- end
- xtree = xtree[kk]
- end
- end
- end
- return tree
-end
-
-function trim (s)
- return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
-end
-
-
-function init_vpp(vpp)
- local root_dir = "/home/ubuntu/vpp"
- local pneum_path = root_dir .. "/build-root/install-vpp_lite_debug-native/vpp-api/lib64/libpneum.so"
-
- vpp:init({ pneum_path = pneum_path })
-
- vpp:init({ pneum_path = pneum_path })
- vpp:json_api(root_dir .. "/build-root/install-vpp_lite_debug-native/vpp/vpp-api/vpe.api.json")
-
-
-
- vpp:connect("lua_cli")
-end
-
-function run_cli(vpp, cli)
- local reply = vpp:api_call("cli_inband", { cmd = cli })
- if reply and #reply == 1 then
- local rep = reply[1]
- if 0 == rep.retval then
- return rep.reply
- else
- return "XXXXXLUACLI: API RETVAL ERROR : " .. tostring(rep.retval)
- end
- else
- return "XXXXXLUACLI ERROR, RAW REPLY: " .. vpp.dump(reply)
- end
-end
-
-
-function toprintablestring(s)
- if type(s) == "string" then
- return "\n"..vpp.hex_dump(s)
- else
- return tostring(s)
- end
-end
-
-function interactive_cli(r)
- while not done do
- pager_reset()
- local cmd = r.readln()
- if not cmd then
- done = true
- elseif cmd == "quit" or cmd == "exit" then
- done = true
- else
- local func = device_cli_exec(r)
- if func then
- func(r)
- else
- if trim(cmd) == "" then
- else
- for i = 1, #r.prompt do
- paged_write(" ")
- end
- paged_write("^\n% Invalid input detected at '^' marker.\n\n")
- end
- end
- end
- end
-end
-
-device = {}
-device.output = {}
-
-init_vpp(vpp)
-cmds_str = run_cli(vpp, "?")
-vpp_cmds = readln.split(cmds_str, "\n")
-vpp_clis = {}
-
-for linenum, line in ipairs(vpp_cmds) do
- local m,h = string.match(line, "^ (.-) (.*)$")
- if m and #m > 0 then
- table.insert(vpp_clis, m)
- device.output["vpp debug cli " .. m] = function(rl)
- -- print("ARBITRARY CLI" .. vpp.dump(rl.choices))
- print("LUACLI command: " .. table.concat(rl.choices, " "))
- local sub = {}
- --
- for i=4, #rl.choices -1 do
- table.insert(sub, rl.choices[i])
- end
- local cli = table.concat(sub, " ")
- print("Running CLI: " .. tostring(cli))
- paged_write(run_cli(vpp, cli))
- end
- device.output["vpp debug cli " .. m .. " " .. dotdotdot] = function(rl)
- print("ARGH")
- end
-
- local ret = run_cli(vpp, "help " .. m)
- device.output["help vpp debug cli " .. m] = { ret }
- end
-end
-
-for linenum, line in ipairs(vpp_clis) do
- -- print(line, ret)
-end
-
-for msgnum, msgname in pairs(vpp.msg_number_to_name) do
- local cli, numspaces = string.gsub(msgname, "_", " ")
- device.output["call " .. cli .. " " .. dotdotdot] = function(rl)
- print("ARGH")
- end
- device.output["call " .. cli] = function(rl)
- print("LUACLI command: " .. table.concat(rl.choices, " "))
- print("Running API: " .. msgname) -- vpp.dump(rl.choices))
- local out = {}
- local args = {}
- local ntaken = 0
- local argname = ""
- for i=(1+1+numspaces+1), #rl.choices-1 do
- -- print(i, rl.choices[i])
- if ntaken > 0 then
- ntaken = ntaken -1
- else
- local fieldname = rl.choices[i]
- local field = vpp.msg_name_to_fields[msgname][fieldname]
- if field then
- local s = rl.choices[i+1]
- s=s:gsub("\\x(%x%x)",function (x) return string.char(tonumber(x,16)) end)
- args[fieldname] = s
- ntaken = 1
- end
- end
- end
- -- print("ARGS: ", vpp.dump(args))
- local ret = vpp:api_call(msgname, args)
- for i, reply in ipairs(ret) do
- table.insert(out, "=================== Entry #" .. tostring(i))
- for k, v in pairs(reply) do
- table.insert(out, " " .. tostring(k) .. " : " .. toprintablestring(v))
- end
- end
- -- paged_write(vpp.dump(ret) .. "\n\n")
- paged_write(table.concat(out, "\n").."\n\n")
- end
- device.output["call " .. cli .. " help"] = function(rl)
- local out = {}
- for k, v in pairs(vpp.msg_name_to_fields[msgname]) do
- table.insert(out, tostring(k) .. " : " .. v["ctype"] .. " ; " .. tostring(vpp.dump(v)) )
- end
- -- paged_write(vpp.dump(vpp.msg_name_to_fields[msgname]) .. "\n\n")
- paged_write(table.concat(out, "\n").."\n\n")
- end
--- vpp.msg_name_to_number = {}
-end
-
-
-
-local r = readln.reader()
-local done = false
-
-r.prompt = "VPP(luaCLI)#"
-
-r.help = device_cli_help
-r.tab_complete = device_cli_tab_complete
-print("===== CLI view, use ^D to end =====")
-
-r.tree = populate_tree(device.output)
--- readln.pretty("xxxx", r.tree)
-
-
-for idx, an_arg in ipairs(arg) do
- local fname = an_arg
- if fname == "-i" then
- pager_lines = 23
- interactive_cli(r)
- else
- pager_lines = 100000000
- for line in io.lines(fname) do
- r.command = line
- local func = device_cli_exec(r)
- if func then
- func(r)
- end
- end
- end
-end
-
-if #arg == 0 then
- print("You should specify '-i' as an argument for the interactive session,")
- print("but with no other sources of commands, we start interactive session now anyway")
- interactive_cli(r)
-end
-
-vpp:disconnect()
-r.done()
-
-