summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-02-09 14:59:06 +0800
committerGitHub <[email protected]>2026-02-09 14:59:06 +0800
commite859e1eb0f86c5109e7f7b6dc9c2ce87c9a74c93 (patch)
tree4a4091c893432c0b4746253e7cc937703f0e5ba9
parentf9fc4cd7f3f96be6bf0f3ae20633cd4c8b378b2f (diff)
parentff21702cec1348b5ae84526210650bdfd356f4dd (diff)
Merge pull request #7306 from xmake-io/remote
Improve remote build
-rw-r--r--xmake/actions/service/xmake.lua9
-rw-r--r--xmake/modules/private/service/client_config.lua14
-rw-r--r--xmake/modules/private/service/remote_build/client.lua123
3 files changed, 127 insertions, 19 deletions
diff --git a/xmake/actions/service/xmake.lua b/xmake/actions/service/xmake.lua
index ed6772749..b292a73a2 100644
--- a/xmake/actions/service/xmake.lua
+++ b/xmake/actions/service/xmake.lua
@@ -38,7 +38,9 @@ task("service")
" - xmake service --connect",
" - xmake service --connect --remote",
" - xmake service --connect --distcc",
- " - xmake service --connect --remote --distcc" },
+ " - xmake service --connect --remote --distcc",
+ " - xmake service --connect --host=windows",
+ " - xmake service --connect --host=10.5.139.8:9691" },
{nil, "session" , "kv", nil,"Connect with the given session name, it will generate a session id via name.",
"e.g.",
" -- xmake service --connect --ccache --session=foo" },
@@ -68,6 +70,11 @@ task("service")
{nil, "gen-token", "k", nil, "Generate a new token in the server.",
"e.g.",
" - xmake service --gen-token" },
+ {nil, "host", "kv", nil, "Connect to the specific host by name or address.",
+ "e.g.",
+ " - xmake service --connect --host=windows",
+ " - xmake service --connect --host=10.5.139.8:9691",
+ " - xmake service --connect --host=10.5.139.8" },
{nil, "logs", "k", nil, "Show service logs if the daemon service has been started." },
{nil, "status", "k", nil, "Show service status if the daemon service has been started." },
{nil, "values", "vs", nil, "The values list for pull/.. options." }
diff --git a/xmake/modules/private/service/client_config.lua b/xmake/modules/private/service/client_config.lua
index 2c6baff27..b20e081d6 100644
--- a/xmake/modules/private/service/client_config.lua
+++ b/xmake/modules/private/service/client_config.lua
@@ -38,17 +38,19 @@ function _generate_configfile()
local filepath = configfile()
assert(not _g.configs and not os.isfile(filepath))
local token = _get_local_server_token()
- print("generating the config file to %s ..", filepath)
+ print("generating config file to %s ..", filepath)
local configs = {
send_timeout = -1,
recv_timeout = -1,
connect_timeout = 10000,
remote_build = {
- -- without authorization: "127.0.0.1:9691"
- -- with user authorization: "[email protected]:9691"
- connect = "127.0.0.1:9691",
- -- with token authorization
- token = token
+ hosts = {
+ {
+ name = "local",
+ connect = "127.0.0.1:9691",
+ token = token
+ }
+ }
},
remote_cache = {
connect = "127.0.0.1:9692",
diff --git a/xmake/modules/private/service/remote_build/client.lua b/xmake/modules/private/service/remote_build/client.lua
index c951740e2..09ac126a6 100644
--- a/xmake/modules/private/service/remote_build/client.lua
+++ b/xmake/modules/private/service/remote_build/client.lua
@@ -41,10 +41,6 @@ local super = remote_build_client:class()
function remote_build_client:init()
super.init(self)
- -- init address
- local address = assert(config.get("remote_build.connect"), "config(remote_build.connect): not found!")
- self:address_set(address)
-
-- get project directory
local projectdir = os.projectdir()
local projectfile = os.projectfile()
@@ -55,6 +51,9 @@ function remote_build_client:init()
raise("we need to enter a project directory with xmake.lua first!")
end
+ -- init host
+ self:_init_host()
+
-- init filesync
local filesync = new_filesync(self:projectdir(), path.join(self:workdir(), "manifest.txt"))
filesync:ignorefiles_add(".git/**")
@@ -80,18 +79,22 @@ function remote_build_client:connect()
end
-- Do we need user authorization?
- local token = config.get("remote_build.token")
- if not token and self:user() then
+ local user = self:user()
+ local token = self:token()
+ if not token and user then
-- get user password
- cprint("Please input user ${bright}%s${clear} password to connect <%s:%d>:", self:user(), self:addr(), self:port())
+ cprint("Please input user ${bright}%s${clear} password to connect <%s:%d>:", user, self:addr(), self:port())
io.flush()
local pass = (io.read() or ""):trim()
assert(pass ~= "", "password is empty!")
-- compute user authorization
- token = base64.encode(self:user() .. ":" .. pass)
+ token = base64.encode(user .. ":" .. pass)
token = hash.md5(bytes(token))
+
+ -- update the computed token
+ self:token_set(token)
end
-- do connect
@@ -127,6 +130,7 @@ function remote_build_client:connect()
status.addr = addr
status.port = port
status.token = token
+ status.user = user
status.connected = ok
status.session_id = session_id
self:status_save()
@@ -397,7 +401,12 @@ end
-- get user token
function remote_build_client:token()
- return self:status().token
+ return self._TOKEN or self:status().token
+end
+
+-- set user token
+function remote_build_client:token_set(token)
+ self._TOKEN = token
end
-- get the session id, only for unique project
@@ -405,6 +414,96 @@ function remote_build_client:session_id()
return self:status().session_id or hash.uuid(option.get("session")):split("-", {plain = true})[1]:lower()
end
+-- init host address and token
+--
+-- Supported configuration formats:
+--
+-- New format (multiple hosts):
+-- remote_build = {
+-- hosts = {
+-- {
+-- name = "windows",
+-- connect = "10.5.139.8:9691",
+-- token = "0e052f8c7153a6111d5a418e514020ee"
+-- },
+-- {
+-- name = "linux",
+-- connect = "192.168.1.100:9691",
+-- token = "abc123def456"
+-- }
+-- }
+-- }
+--
+-- Old format (single host, backward compatible):
+-- remote_build = {
+-- connect = "10.5.139.8:9691",
+-- token = "0e052f8c7153a6111d5a418e514020ee"
+-- }
+--
+-- Usage:
+-- xmake service --connect --host=windows # connect by name
+-- xmake service --connect --host=10.5.139.8:9691 # connect by address
+-- xmake service --connect # use default host
+function remote_build_client:_init_host()
+ local remote_build_config = config.get("remote_build") or {}
+ local address
+ local token
+
+ -- if already connected, use status first
+ if self:is_connected() then
+ local status = self:status()
+ if status.addr and status.port then
+ address = status.addr .. ":" .. status.port
+ token = status.token
+ self:address_set(address)
+ if token then
+ self:token_set(token)
+ end
+ return
+ end
+ end
+
+ -- support new hosts format
+ if remote_build_config.hosts then
+ local host_name = option.get("host")
+ if host_name then
+ -- find host by name or address
+ for _, host in ipairs(remote_build_config.hosts) do
+ local host_ip, _ = host.connect:split(":", {plain = true})
+ if host.name == host_name or
+ host.connect == host_name or
+ (host_ip == host_name and not host_name:find(":", 1, true)) then
+ address = host.connect
+ token = host.token
+ break
+ end
+ end
+ if not address then
+ raise("host '%s' not found in configuration!", host_name)
+ end
+ else
+ -- use first host as default
+ if #remote_build_config.hosts > 0 then
+ address = remote_build_config.hosts[1].connect
+ token = remote_build_config.hosts[1].token
+ end
+ end
+ -- support old format for backward compatibility
+ elseif remote_build_config.connect then
+ address = remote_build_config.connect
+ token = remote_build_config.token
+ end
+
+ if not address then
+ raise("config(remote_build.connect) or config(remote_build.hosts) not found!")
+ end
+
+ self:address_set(address)
+ if token then
+ self:token_set(token)
+ end
+end
+
-- set the given client address
function remote_build_client:address_set(address)
local addr, port, user = self:address_parse(address)
@@ -415,17 +514,17 @@ end
-- get user name
function remote_build_client:user()
- return self._USER
+ return self._USER or self:status().user
end
-- get the ip address
function remote_build_client:addr()
- return self._ADDR
+ return self._ADDR or self:status().addr
end
-- get the address port
function remote_build_client:port()
- return self._PORT
+ return self._PORT or self:status().port
end
-- get filesync