summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-05-13 22:39:05 +0800
committerruki <[email protected]>2022-05-13 22:39:05 +0800
commita59bde3f54633aadc858df58a0803f18044d5bcc (patch)
treee23066f543b0b543752918da2e7342c670a6e0c0
parentb89c0a712d8e6d6fe056723e8c88e223d4b6e0c3 (diff)
connect and disconnect distcc
-rw-r--r--xmake/modules/private/service/distcc_build/client.lua240
-rw-r--r--xmake/modules/private/service/distcc_build/client_session.lua2
-rw-r--r--xmake/modules/private/service/distcc_build/server.lua2
-rw-r--r--xmake/modules/private/service/distcc_build/server_session.lua2
-rw-r--r--xmake/modules/private/service/remote_build/client.lua2
-rw-r--r--xmake/modules/private/service/server.lua2
6 files changed, 162 insertions, 88 deletions
diff --git a/xmake/modules/private/service/distcc_build/client.lua b/xmake/modules/private/service/distcc_build/client.lua
index 34e590f83..bb910547f 100644
--- a/xmake/modules/private/service/distcc_build/client.lua
+++ b/xmake/modules/private/service/distcc_build/client.lua
@@ -72,37 +72,159 @@ function distcc_build_client:hosts_set(hosts)
local hostinfo = {}
local address = assert(host.connect, "connect address not found in hosts configuration!")
local addr, port, user = self:address_parse(address)
- hostinfo.addr = addr
- hostinfo.port = port
- hostinfo.user = user
- hostinfo.token = host.token
- table.insert(hostinfos, hostinfo)
+ if addr and port then
+ hostinfo.addr = addr
+ hostinfo.port = port
+ hostinfo.user = user
+ hostinfo.token = host.token
+ table.insert(hostinfos, hostinfo)
+ end
end
self._HOSTS = hostinfos
end
-- connect to the distcc server
function distcc_build_client:connect()
+ if self:is_connected() then
+ print("%s: has been connected!", self)
+ return
+ end
+
+ -- do connect
+ local hosts = self:hosts()
+ assert(hosts and #hosts > 0, "hosts not found!")
+ local group_name = tostring(self) .. "/connect"
+ scheduler.co_group_begin(group_name, function ()
+ for _, host in ipairs(hosts) do
+ scheduler.co_start(self._connect_host, self, host)
+ end
+ end)
+ scheduler.co_group_wait(group_name)
+
+ -- all hosts are connected?
+ local connected = true
+ for _, host in ipairs(hosts) do
+ if not self:_is_connected(host.addr, host.port) then
+ connected = false
+ end
+ end
+
+ -- update status
+ local status = self:status()
+ status.connected = connected
+ self:status_save()
end
-- disconnect server
function distcc_build_client:disconnect()
+ if not self:is_connected() then
+ print("%s: has been disconnected!", self)
+ return
+ end
+
+ -- do disconnect
+ local hosts = self:hosts()
+ assert(hosts and #hosts > 0, "hosts not found!")
+ local group_name = tostring(self) .. "/connect"
+ scheduler.co_group_begin(group_name, function ()
+ for _, host in ipairs(hosts) do
+ scheduler.co_start(self._disconnect_host, self, host)
+ end
+ end)
+ scheduler.co_group_wait(group_name)
+
+ -- all hosts are connected?
+ local connected = true
+ for _, host in ipairs(hosts) do
+ if not self:_is_connected(host.addr, host.port) then
+ connected = false
+ end
+ end
+
+ -- update status
+ local status = self:status()
+ status.connected = connected
+ self:status_save()
end
---[[
--- connect to the distcc server
-function distcc_build_client:connect()
- if self:is_connected() then
- print("%s: has been connected!", self)
+-- is connected?
+function distcc_build_client:is_connected()
+ return self:status().connected
+end
+
+-- get the status
+function distcc_build_client:status()
+ local status = self._STATUS
+ local statusfile = self:statusfile()
+ if not status then
+ if os.isfile(statusfile) then
+ status = io.load(statusfile)
+ end
+ status = status or {}
+ self._STATUS = status
+ end
+ return status
+end
+
+-- save status
+function distcc_build_client:status_save()
+ io.save(self:statusfile(), self:status())
+end
+
+-- get the status file
+function distcc_build_client:statusfile()
+ return path.join(self:workdir(), "status.txt")
+end
+
+-- get the project directory
+function distcc_build_client:projectdir()
+ return self._PROJECTDIR
+end
+
+-- get working directory
+function distcc_build_client:workdir()
+ return self._WORKDIR
+end
+
+-- get the session id, only for unique project
+function distcc_build_client:_session_id(addr, port)
+ local hosts = self:status().hosts
+ if hosts then
+ local host = hosts[addr .. ":" .. port]
+ if host then
+ return host.session_id
+ end
+ end
+ return hash.uuid():split("-", {plain = true})[1]:lower()
+end
+
+-- is connected for the given host
+function distcc_build_client:_is_connected(addr, port)
+ local hosts = self:status().hosts
+ if hosts then
+ local host = hosts[addr .. ":" .. port]
+ if host then
+ return host.connected
+ end
+ end
+end
+
+-- connect to the host
+function distcc_build_client:_connect_host(host)
+ local addr = host.addr
+ local port = host.port
+ if self:_is_connected(addr, port) then
+ print("%s: %s:%d has been connected!", self, addr, port)
return
end
-- we need user authorization?
- local token = config.get("distcc_build.token")
- if not token and self:user() then
+ local user = host.user
+ local token = host.token
+ if not token and user then
-- get user password
- cprint("Please input user ${bright}%s${clear} password:", self:user())
+ cprint("Please input user ${bright}%s${clear} password to connect <%s:%d>:", user, addr, port)
io.flush()
local pass = (io.read() or ""):trim()
assert(pass ~= "", "password is empty!")
@@ -113,10 +235,8 @@ function distcc_build_client:connect()
end
-- do connect
- local addr = self:addr()
- local port = self:port()
local sock = assert(socket.connect(addr, port), "%s: server unreachable!", self)
- local session_id = self:session_id()
+ local session_id = self:_session_id(addr, port)
local ok = false
local errors
print("%s: connect %s:%d ..", self, addr, port)
@@ -135,37 +255,37 @@ function distcc_build_client:connect()
end
end
if ok then
- print("%s: connected!", self)
+ print("%s: %s:%d connected!", self, addr, port)
else
print("%s: connect %s:%d failed, %s", self, addr, port, errors or "unknown")
end
-- update status
local status = self:status()
- status.addr = addr
- status.port = port
- status.token = token
- status.connected = ok
- status.session_id = session_id
+ status.hosts = status.hosts or {}
+ status.hosts[addr .. ":" .. port] = {addr = addr, port = port, token = token, connected = ok, session_id = session_id}
self:status_save()
end
--- disconnect server
-function distcc_build_client:disconnect()
- if not self:is_connected() then
- print("%s: has been disconnected!", self)
+-- disconnect from the host
+function distcc_build_client:_disconnect_host(host)
+ local addr = host.addr
+ local port = host.port
+ if not self:_is_connected(addr, port) then
+ print("%s: %s:%d has been disconnected!", self, addr, port)
return
end
- local addr = self:addr()
- local port = self:port()
+
+ -- do disconnect
+ local token = host.token
local sock = socket.connect(addr, port)
- local session_id = self:session_id()
+ local session_id = self:_session_id(addr, port)
local errors
local ok = false
print("%s: disconnect %s:%d ..", self, addr, port)
if sock then
local stream = socket_stream(sock)
- if stream:send_msg(message.new_disconnect(session_id, {token = self:token()})) and stream:flush() then
+ if stream:send_msg(message.new_disconnect(session_id, {token = token})) and stream:flush() then
local msg = stream:recv_msg()
if msg then
vprint(msg:body())
@@ -182,66 +302,20 @@ function distcc_build_client:disconnect()
ok = true
end
if ok then
- print("%s: disconnected!", self)
+ print("%s: %s:%d disconnected!", self, addr, port)
else
print("%s: disconnect %s:%d failed, %s", self, addr, port, errors or "unknown")
end
-- update status
local status = self:status()
- status.token = nil
- status.connected = not ok
- self:status_save()
-end
-]]
-
--- is connected?
-function distcc_build_client:is_connected()
- return self:status().connected
-end
-
--- get the status
-function distcc_build_client:status()
- local status = self._STATUS
- local statusfile = self:statusfile()
- if not status then
- if os.isfile(statusfile) then
- status = io.load(statusfile)
- end
- status = status or {}
- self._STATUS = status
+ status.hosts = status.hosts or {}
+ local host_status = status.hosts[addr .. ":" .. port]
+ if host_status then
+ host_status.token = nil
+ host_status.connected = not ok
end
- return status
-end
-
--- save status
-function distcc_build_client:status_save()
- io.save(self:statusfile(), self:status())
-end
-
--- get the status file
-function distcc_build_client:statusfile()
- return path.join(self:workdir(), "status.txt")
-end
-
--- get the project directory
-function distcc_build_client:projectdir()
- return self._PROJECTDIR
-end
-
--- get working directory
-function distcc_build_client:workdir()
- return self._WORKDIR
-end
-
--- get user token
-function distcc_build_client:token()
- return self:status().token
-end
-
--- get the session id, only for unique project
-function distcc_build_client:session_id()
- return self:status().session_id or hash.uuid():split("-", {plain = true})[1]:lower()
+ self:status_save()
end
-- is connected? we cannot depend on client:init when run action
diff --git a/xmake/modules/private/service/distcc_build/client_session.lua b/xmake/modules/private/service/distcc_build/client_session.lua
index 957e3b550..9f9a36c79 100644
--- a/xmake/modules/private/service/distcc_build/client_session.lua
+++ b/xmake/modules/private/service/distcc_build/client_session.lua
@@ -86,7 +86,7 @@ end
-- get work directory
function client_session:workdir()
- return path.join(self:workdir(), "sessons", self:id())
+ return path.join(self:server():workdir(), "sessons", self:id())
end
-- is connected?
diff --git a/xmake/modules/private/service/distcc_build/server.lua b/xmake/modules/private/service/distcc_build/server.lua
index 80b0e38b3..5d61ab677 100644
--- a/xmake/modules/private/service/distcc_build/server.lua
+++ b/xmake/modules/private/service/distcc_build/server.lua
@@ -112,7 +112,7 @@ end
function distcc_build_server:_session(session_id)
local session = self._SESSIONS[session_id]
if not session then
- session = server_session(server, session_id)
+ session = server_session(self, session_id)
self._SESSIONS[session_id] = session
end
return session
diff --git a/xmake/modules/private/service/distcc_build/server_session.lua b/xmake/modules/private/service/distcc_build/server_session.lua
index 9c564f302..5dceedb16 100644
--- a/xmake/modules/private/service/distcc_build/server_session.lua
+++ b/xmake/modules/private/service/distcc_build/server_session.lua
@@ -86,7 +86,7 @@ end
-- get work directory
function server_session:workdir()
- return path.join(self:server(), "sessons", self:id())
+ return path.join(self:server():workdir(), "sessons", self:id())
end
-- is connected?
diff --git a/xmake/modules/private/service/remote_build/client.lua b/xmake/modules/private/service/remote_build/client.lua
index 143ec3d9d..565b0f3c3 100644
--- a/xmake/modules/private/service/remote_build/client.lua
+++ b/xmake/modules/private/service/remote_build/client.lua
@@ -78,7 +78,7 @@ function remote_build_client:connect()
if not token and self:user() then
-- get user password
- cprint("Please input user ${bright}%s${clear} password:", self:user())
+ cprint("Please input user ${bright}%s${clear} password to connect <%s:%d>:", self:user(), self:addr(), self:port())
io.flush()
local pass = (io.read() or ""):trim()
assert(pass ~= "", "password is empty!")
diff --git a/xmake/modules/private/service/server.lua b/xmake/modules/private/service/server.lua
index a3971899a..204d6e70e 100644
--- a/xmake/modules/private/service/server.lua
+++ b/xmake/modules/private/service/server.lua
@@ -106,7 +106,7 @@ end
-- verify user
function server:verify_user(token, peeraddr)
if not token then
- return false, "client has no authorization, we need add username to connect address or token to `remote_build.token`!"
+ return false, "client has no authorization, we need add username to connect address or token!"
end
-- check authorization