Skip to content

Package for Remote-Debugging via SSH #90

Open
@bassklampfe

Description

@bassklampfe

Dear @pkulchenko

It started as an attempt to use ZBS as remote IDE for Raspi, but it turned out to provide a generic package for remote debugging via SSH. Please kindly review the package and if you like it, add it to https://github.com/pkulchenko/ZeroBranePackage

But I also have some issues with this. During remote debug every output line is displayed twice in ZBS.

Twiddling with

debugger.port =9876
debugger.redirect = 'r'
debugger.hostname="192.168.1.27"

in project settings seems to have no effect on the rundebug argument passed to sshlua:frun(). Maybe you can give me advice.

So here it is sshlua.lua :

--[[
Remote debugging for ZeroBrane via ssh. Initial create to be used with Raspi,
but then shows up to be of general use.

#1. Setting up the remote system

How to read:
_#_         comment lines not to be entered
_remote>_   command to be entered in the remote system
_local>_    command to be entered on the local host
_ipaddr_    address of the remote system
_username_  username on the remote system

#1.1 Make ssh functional

 # install SSH server
 _remote>_ sudo apt install openssh-server
 # install SSH client
 _local>_ sudo apt install openssh-client
 # create as public/private rsa key pair
 _local>_ ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/luassh
 # authenticate by key file
 _local>_ ssh-copy-id -i .ssh/luassh.pub username@ipaddr
 # test connection
 _local>_ ssh username@ipaddr

#1.2 Install required lua packages

 # install lua packages
 _remote>_ sudo apt install lua5.1 lua-socket
 # copy mobdebug to right place on remote system
 _local>_ scp /opt/zbstudio/lualibs/mobdebug/mobdebug.lua username@ipaddr:.
 _remote>_ sudo mkdir -p /usr/local/share/lua/5.1/
 _remote>_ sudo mv ~/mobdebug.lua /usr/local/share/lua/5.1/

#1.3 (Optional) packages I recommend (but this depends on your needs)

 _remote>_ sudo apt install lua-filesystem lua-bitop lua5.1-doc
 _remote>_ sudo cp /usr/share/doc/lua5.1-doc/etc/strict.lua /usr/local/share/lua/5.1/

#2. Setting up your project

* Install https://github.com/pkulchenko/ZeroBranePackage/blob/master/projectsettings.lua to Zerobrane
* Restart ZBS and open your project
* Invoke menu "Edit" / "Preferences" / "Settings: Project"
* Enter the following lines
---------------------
package "sshlua.lua"
ide.packages.sshlua.sshlogin="username@ipaddr"
ide.packages.sshlua.subdir="mytest"
---------------------
and save
* Rightclick on the "user.lua" tab and select "Open containing folder"
* Copy sshlua.lua into this folder
* Restart ZBS and open your project

#3. How to use

Just edit, run or debug files in your project, as normal. 
On Save files will be copied to subdir on remote system. 
Run and Debug will execute the script on remote system.
--]]

------------------------------------------------------------
--PACKAGE
------------------------------------------------------------
local sshlua=
{
	name = "sshlua",
	description = "ssh remote lua",
	author = "J.Jørgen von Bargen",
	version = 0.1,
	hasdebugger = true,
}

--
-- common utilities functions
--
local function quoteshell(path)
	return "'"..path:gsub("'","'\\''").."'"
end

local sprintf=string.format
local function printf(...)
	ide:Print((sprintf(...):gsub("%s+$","")))
end

local function vis(val)
	if type(val)~="string" then return tostring(val) end
	return '"'..val..'"'
end



function sshlua:get_remote_path(doc_path)
	--
	-- ignore files outside project
	--
	local proj_dir=ide:GetProject()
	if doc_path:sub(1,#proj_dir)~=proj_dir then return nil end
	local remote_path=doc_path:sub(#proj_dir+1)
	--
	-- ignore files in .zbstudio folder
	--
	if remote_path:match("^%.zbstudio") then return nil end
	--
	-- create relative to subdir
	--
	if self.subdir then remote_path=self.subdir.."/"..remote_path end
	return remote_path
end

function sshlua:frun(wfilename,rundebug)
	printf("interpreter:frun(%s,%s)\n",vis(wfilename:GetFullPath()),vis(rundebug))
 	--
	-- verify the path belongs to the project and get remothe path
	--
	local local_path=wfilename:GetFullPath()
	local remote_path=self:get_remote_path(local_path)
	if not remote_path then return end
	--
	-- build command to be executed remotely
	--
	local luacmd=rundebug and sprintf("lua -e %q %q",rundebug,remote_path)
	or sprintf("lua %q",remote_path)
	printf("luacmd=[[%s]]\n",luacmd)
	local sshcmd="ssh -4 "..self.sshlogin.." "..quoteshell(luacmd).." 2>&1"
	printf("sshcmd=[[%s]]\n",sshcmd)
	local pid=CommandLineRun(sshcmd,ide:GetProject(),true,false)
	return pid
end

function sshlua:onRegister()
	ide:AddInterpreter(self.name, self)
	ProjectSetInterpreter(self.name)
end

function sshlua:onEditorSave(ed)
	--
	-- get document
	--
	local doc = ide:GetDocument(ed)
	if not doc then return end
	--
	-- verify the path belongs to the project and get remothe path
	--
	local local_path=doc:GetFilePath()
	local remote_path=self:get_remote_path(local_path)
	if not remote_path then return end

	--
	-- copy file to remote system via scp
	--
	local scpcmd=sprintf("scp -4 %s "..self.sshlogin..":%s",quoteshell(local_path),quoteshell(remote_path))
	local sts=os.execute(scpcmd.." 2>&1")
	printf("[[%s]] sts %s\n",scpcmd,vis(sts))

	if sts~=true then
		--
		-- maybe dir is missing ??? try to create
		--
		local remote_dir=remote_path:match("(.*)/") or "."
		local mkdircmd="ssh -4 "..self.sshlogin.." "..quoteshell("mkdir -vp \""..remote_dir.."\"")
		sts=os.execute(mkdircmd.." 2>&1")
		printf("[[%s]] sts %s\n",mkdircmd,vis(sts))
		if sts~=true then
			printf("cmd=[[%s]] failed\n",mkdircmd)
			return
		end
		--
		-- retry copy
		--
		sts=os.execute(scpcmd.." 2>&1")
		printf("[[%s]] sts %s\n",scpcmd,vis(sts))
	end
	if sts~=true then
		printf("cmd=[[%s]] failed\n",scpcmd)
		return
	end
end

return sshlua

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions