From 87d9f355e207a293600e84e18964da2f0b11fb5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Tich=C3=A1k?= Date: Mon, 19 May 2025 17:15:48 +0200 Subject: [PATCH] [core] split CreateEnvironment to Create and Run functions --- core/environment/manager.go | 20 ++++++++++++++---- core/server.go | 41 +++++++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/core/environment/manager.go b/core/environment/manager.go index 0f239b73..07d9e90b 100644 --- a/core/environment/manager.go +++ b/core/environment/manager.go @@ -202,7 +202,7 @@ func (envs *Manager) GetActiveDetectors() system.IDMap { return response } -func (envs *Manager) CreateEnvironment(workflowPath string, userVars map[string]string, public bool, newId uid.ID, autoTransition bool) (uid.ID, error) { +func (envs *Manager) CreateEnvironment(workflowPath string, userVars map[string]string, public bool, newId uid.ID) (uid.ID, error) { // Before we load the workflow, we get the list of currently active detectors. This query must be performed before // loading the workflow in order to compare the currently used detectors with the detectors required by the newly // created environment. @@ -403,7 +403,19 @@ func (envs *Manager) CreateEnvironment(workflowPath string, userVars map[string] WithField("level", infologger.IL_Devel). Debug("envman write unlock") - err = env.TryTransition(NewDeployTransition( + return env.id, nil +} + +func (envs *Manager) RunEnvironment(workflowPath string, envId uid.ID, autoTransition bool) error { + envs.mu.Lock() + env, ok := envs.m[envId] + envs.mu.Unlock() + + if !ok { + return errors.New(fmt.Sprintf("trying to run unknown env id: %v", envId)) + } + + err := env.TryTransition(NewDeployTransition( envs.taskman, nil, // roles, nil), @@ -524,7 +536,7 @@ func (envs *Manager) CreateEnvironment(workflowPath string, userVars map[string] }() } - return env.id, err + return err } // Deployment/configuration failure code path starts here @@ -567,7 +579,7 @@ func (envs *Manager) CreateEnvironment(workflowPath string, userVars map[string] Info("environment deployment failed, tasks were cleaned up") log.WithField("partition", env.Id().String()).Info("environment teardown complete") - return env.id, err + return err } func (envs *Manager) TeardownEnvironment(environmentId uid.ID, force bool) error { diff --git a/core/server.go b/core/server.go index 0ad0ab56..3e6c8c48 100644 --- a/core/server.go +++ b/core/server.go @@ -309,13 +309,13 @@ func (m *RpcServer) doNewEnvironmentAsync(cxt context.Context, userVars map[stri // we store the last known request user in the environment lastRequestUserJ, _ := json.Marshal(requestUser) userVars["last_request_user"] = string(lastRequestUserJ[:]) - id, err = m.state.environments.CreateEnvironment(workflowTemplate, userVars, public, id, autoTransition) + err = m.state.environments.RunEnvironment(workflowTemplate, id, autoTransition) if err != nil { the.EventWriterWithTopic(topic.Environment).WriteEvent(&evpb.Ev_EnvironmentEvent{ EnvironmentId: id.String(), State: "ERROR", Error: err.Error(), - Message: "cannot create new environment", // GUI listens for this concrete string + Message: "cannot run new environment", // GUI listens for this concrete string LastRequestUser: requestUser, WorkflowTemplateInfo: &evpb.WorkflowTemplateInfo{ Public: public, @@ -374,7 +374,26 @@ func (m *RpcServer) NewEnvironmentAsync(cxt context.Context, request *pb.NewEnvi } defer setCurrentUnixMilli(&reply.Timestamp) - go m.doNewEnvironmentAsync(cxt, userVars, request.GetRequestUser(), request.GetWorkflowTemplate(), request.GetPublic(), request.GetAutoTransition(), id) + public := request.GetPublic() + workflowTemplate := request.GetWorkflowTemplate() + requestUser := request.GetRequestUser() + + id, err = m.state.environments.CreateEnvironment(request.GetWorkflowTemplate(), userVars, request.GetPublic(), id) + if err != nil { + the.EventWriterWithTopic(topic.Environment).WriteEvent(&evpb.Ev_EnvironmentEvent{ + EnvironmentId: id.String(), + State: "ERROR", + Error: err.Error(), + Message: "cannot create new environment", // GUI listens for this concrete string + LastRequestUser: requestUser, + WorkflowTemplateInfo: &evpb.WorkflowTemplateInfo{ + Public: public, + Path: workflowTemplate, + }, + }) + return + } + go m.doNewEnvironmentAsync(cxt, userVars, requestUser, workflowTemplate, public, request.GetAutoTransition(), id) return } @@ -421,7 +440,7 @@ func (m *RpcServer) NewEnvironment(cxt context.Context, request *pb.NewEnvironme // Create new Environment instance with some roles, we get back a UUID id := uid.New() - id, err = m.state.environments.CreateEnvironment(request.GetWorkflowTemplate(), inputUserVars, request.GetPublic(), id, request.GetAutoTransition()) + id, err = m.state.environments.CreateEnvironment(request.GetWorkflowTemplate(), inputUserVars, request.GetPublic(), id) if err != nil { st := status.Newf(codes.Internal, "cannot create new environment: %s", utils.TruncateString(err.Error(), MAX_ERROR_LENGTH)) ei := &pb.EnvironmentInfo{ @@ -436,6 +455,20 @@ func (m *RpcServer) NewEnvironment(cxt context.Context, request *pb.NewEnvironme return } + err = m.state.environments.RunEnvironment(request.GetWorkflowTemplate(), id, request.GetAutoTransition()) + if err != nil { + st := status.Newf(codes.Internal, "cannot run new environment: %s", utils.TruncateString(err.Error(), MAX_ERROR_LENGTH)) + ei := &pb.EnvironmentInfo{ + Id: id.String(), + CreatedWhen: time.Now().UnixMilli(), + State: "ERROR", // not really, but close + NumberOfFlps: 0, + } + st, _ = st.WithDetails(ei) + err = st.Err() + + return + } newEnv, err := m.state.environments.Environment(id) if err != nil { st := status.Newf(codes.Internal, "cannot get newly created environment: %s", utils.TruncateString(err.Error(), MAX_ERROR_LENGTH))