Phase5
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 9s
CI / Go — node-agent tests (push) Failing after 9s
CI / Go — edge-gateway build (push) Successful in 13s

This commit is contained in:
smueller
2026-06-26 13:00:01 +02:00
parent 4262464cd5
commit d29a02f2a4
93 changed files with 1875 additions and 55 deletions

View File

@@ -570,6 +570,66 @@ func (m *Manager) HandleWorldReplace(ctx context.Context, correlationID string,
})
}
// HandleAddonInstall downloads and installs an addon JAR.
func (m *Manager) HandleAddonInstall(ctx context.Context, correlationID string, payload protocol.ServerAddonInstallPayload) {
meta := payload.OperationMeta
rec, ok := m.getServer(meta.ServerID)
if !ok {
m.failOperation(ctx, correlationID, meta, "addon.install", "SERVER_NOT_FOUND", "server is not provisioned on this node")
return
}
if rec.State == ServerStateRunning {
m.failOperation(ctx, correlationID, meta, "addon.install", "SERVER_RUNNING", "server must be stopped before installing addons")
return
}
localPath, err := files.ResolvePath(rec.DataPath, payload.RelativePath)
if err != nil {
m.failOperation(ctx, correlationID, meta, "addon.install", filesErrorCode(err), err.Error())
return
}
if err := transfer.DownloadFile(payload.DownloadURL, localPath); err != nil {
m.failOperation(ctx, correlationID, meta, "addon.install", "DOWNLOAD_FAILED", err.Error())
return
}
if err := transfer.VerifySha512File(localPath, payload.Sha512); err != nil {
_ = os.Remove(localPath)
m.failOperation(ctx, correlationID, meta, "addon.install", "HASH_MISMATCH", err.Error())
return
}
m.completeOperation(ctx, correlationID, meta, "addon.install", map[string]string{
"path": payload.RelativePath,
})
}
// HandleAddonRemove deletes an installed addon file.
func (m *Manager) HandleAddonRemove(ctx context.Context, correlationID string, payload protocol.ServerAddonRemovePayload) {
meta := payload.OperationMeta
rec, ok := m.getServer(meta.ServerID)
if !ok {
m.failOperation(ctx, correlationID, meta, "addon.remove", "SERVER_NOT_FOUND", "server is not provisioned on this node")
return
}
if rec.State == ServerStateRunning {
m.failOperation(ctx, correlationID, meta, "addon.remove", "SERVER_RUNNING", "server must be stopped before removing addons")
return
}
if err := files.DeleteFile(rec.DataPath, payload.RelativePath); err != nil {
m.failOperation(ctx, correlationID, meta, "addon.remove", filesErrorCode(err), err.Error())
return
}
m.completeOperation(ctx, correlationID, meta, "addon.remove", map[string]string{
"path": payload.RelativePath,
})
}
func (m *Manager) getServer(serverID string) (*serverRecord, bool) {
m.mu.RLock()
defer m.mu.RUnlock()