refactor: deployment infrastructure cleanup (4 fixes)
Some checks failed
CI / build (push) Failing after 46s
CI / docker (push) Has been skipped

1. Docker socket security: remove root group from Dockerfile, use
   group_add in docker-compose.yml for runtime-only socket access

2. M2M server communication: create ServerApiClient using Logto
   client_credentials grant with API resource scope. Add M2M server
   role in bootstrap. Replace hacky admin/admin login in
   AgentStatusService.

3. Async deployment: extract DeploymentExecutor as separate @Service
   so Spring's @Async proxy works (self-invocation bypasses proxy).
   Deploy now returns immediately, health check runs in background.

4. Bootstrap: M2M server role (cameleer-m2m-server) with server:admin
   scope, idempotent creation outside the M2M app creation block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-07 17:08:37 +02:00
parent 8407d8b3c0
commit 5d04a154f9
9 changed files with 314 additions and 188 deletions

View File

@@ -60,6 +60,9 @@ class DeploymentServiceTest {
@Mock
private AuditService auditService;
@Mock
private DeploymentExecutor deploymentExecutor;
private DeploymentService deploymentService;
private UUID appId;
@@ -75,12 +78,10 @@ class DeploymentServiceTest {
deploymentService = new DeploymentService(
deploymentRepository,
appRepository,
appService,
environmentRepository,
tenantRepository,
runtimeOrchestrator,
runtimeConfig,
auditService
auditService,
deploymentExecutor
);
appId = UUID.randomUUID();

View File

@@ -4,7 +4,7 @@ import net.siegeln.cameleer.saas.app.AppEntity;
import net.siegeln.cameleer.saas.app.AppRepository;
import net.siegeln.cameleer.saas.environment.EnvironmentEntity;
import net.siegeln.cameleer.saas.environment.EnvironmentRepository;
import net.siegeln.cameleer.saas.runtime.RuntimeConfig;
import net.siegeln.cameleer.saas.identity.ServerApiClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -23,14 +23,14 @@ class AgentStatusServiceTest {
@Mock private AppRepository appRepository;
@Mock private EnvironmentRepository environmentRepository;
@Mock private RuntimeConfig runtimeConfig;
@Mock private ServerApiClient serverApiClient;
private AgentStatusService agentStatusService;
@BeforeEach
void setUp() {
when(runtimeConfig.getCameleer3ServerEndpoint()).thenReturn("http://localhost:9999");
agentStatusService = new AgentStatusService(appRepository, environmentRepository, runtimeConfig);
when(serverApiClient.isAvailable()).thenReturn(false);
agentStatusService = new AgentStatusService(appRepository, environmentRepository, serverApiClient);
}
@Test