fix: preserve admin-set host state across worker re-registration in makeWorker_

When a worker re-joins and already exists in workermgr, makeWorker_()
now overrides the existing slot instead of returning EEXIST. Admin-set
flags (LOCKEDU, CLOSED, HIDDEN, CLOSED_BY_ADMIN) survive the override.

Add XCE_WORKER_CLOSED_BY_ADMIN flag to distinguish admin-closed hosts
from workload-closed ones. worker_ctrl sets/clears it alongside CLOSED.

Refactor worker_init/worker_destroy into copy_worker/kill_worker helpers
shared by both fresh creation and override paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-05-13 10:38:39 +00:00
parent d47b3375e7
commit febb4a6c4d
6 changed files with 111 additions and 57 deletions

View file

@ -536,21 +536,16 @@ func validateHost(ctx *gin.Context, control int, hostnames []string) (successHos
}
func isHostControlActionAllowed(actionType int, status int) bool {
isClosed := (status&models.HOSTSTAT["CLOSED"]) != 0 ||
(status&models.HOSTSTAT["CLOSED_BY_ADMIN"]) != 0
switch actionType {
case 1: // open strictly
if status&models.HOSTSTAT["CLOSED"] != 0 {
return true
}
case 1: // open
return isClosed
case 2: // close
if (status & models.HOSTSTAT["CLOSED"]) != 0 {
return false
} else {
return true
}
return !isClosed
default:
return false
}
return false
}
func preCheckHostControlRequest(req *models.HostControlRequest) (bool, error) {
logger.Debug("Enter preCheckHostControlRequest")

View file

@ -10,16 +10,19 @@ const (
var SupportedHostActions = []string{"open", "close"}
var HOSTSTAT = map[string]int{
"UNAVAIL": 0x00010000,
"LOCKEDU": 0x00020000,
"LOCKEDW": 0x00040000,
"BUSY": 0x00080000,
"CLOSED": 0x00100000,
"UNAVAIL": 0x00010000,
"LOCKEDU": 0x00020000,
"LOCKEDW": 0x00040000,
"BUSY": 0x00080000,
"CLOSED": 0x00100000,
"CLOSED_BY_ADMIN": 0x00400000,
}
func HostStateStr(state int) string {
if (state & HOSTSTAT["UNAVAIL"]) != 0 {
return "UNAVAIL"
} else if (state & HOSTSTAT["CLOSED_BY_ADMIN"]) != 0 {
return "CLOSED_BY_ADMIN"
} else if (state & HOSTSTAT["CLOSED"]) != 0 {
return "CLOSED"
} else if (state & HOSTSTAT["BUSY"]) != 0 {

View file

@ -23,6 +23,11 @@ func TestHostStateStr(t *testing.T) {
state: HOSTSTAT["CLOSED"],
want: "CLOSED",
},
{
name: "CLOSED_BY_ADMIN flag",
state: HOSTSTAT["CLOSED_BY_ADMIN"],
want: "CLOSED_BY_ADMIN",
},
{
name: "BUSY flag",
state: HOSTSTAT["BUSY"],
@ -48,6 +53,11 @@ func TestHostStateStr(t *testing.T) {
state: HOSTSTAT["UNAVAIL"] | HOSTSTAT["CLOSED"],
want: "UNAVAIL", // UNAVAIL takes priority
},
{
name: "combined CLOSED+CLOSED_BY_ADMIN flags",
state: HOSTSTAT["CLOSED"] | HOSTSTAT["CLOSED_BY_ADMIN"],
want: "CLOSED_BY_ADMIN", // CLOSED_BY_ADMIN overrides generic CLOSED
},
}
for _, tt := range tests {