From 0054a45d1babab3105a0ed1a912e7edaa8fe8ec6 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 26 Mar 2024 10:14:06 +0000 Subject: [PATCH] Fix bugs related to services (#100) Related to #99 - use `networkNameForGitea` function instead of `networkName` to get network name - add the missing `Cmd` and `AutoRemove` when creating service containers Reviewed-on: https://gitea.com/gitea/act/pulls/100 Reviewed-by: Jason Song Co-authored-by: Zettat123 Co-committed-by: Zettat123 --- pkg/runner/job_executor.go | 36 ++++++++++++++++++++---------------- pkg/runner/run_context.go | 23 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/pkg/runner/job_executor.go b/pkg/runner/job_executor.go index 2df323b..6b4ae7f 100644 --- a/pkg/runner/job_executor.go +++ b/pkg/runner/job_executor.go @@ -6,7 +6,6 @@ import ( "time" "github.com/nektos/act/pkg/common" - "github.com/nektos/act/pkg/container" "github.com/nektos/act/pkg/model" ) @@ -118,26 +117,31 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo defer cancel() logger := common.Logger(ctx) - logger.Infof("Cleaning up services for job %s", rc.JobName) - if err := rc.stopServiceContainers()(ctx); err != nil { - logger.Errorf("Error while cleaning services: %v", err) - } + // For Gitea + // We don't need to call `stopServiceContainers` here since it will be called by following `info.stopContainer` + // logger.Infof("Cleaning up services for job %s", rc.JobName) + // if err := rc.stopServiceContainers()(ctx); err != nil { + // logger.Errorf("Error while cleaning services: %v", err) + // } logger.Infof("Cleaning up container for job %s", rc.JobName) if err = info.stopContainer()(ctx); err != nil { logger.Errorf("Error while stop job container: %v", err) } - if !rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" { - // clean network in docker mode only - // if the value of `ContainerNetworkMode` is empty string, - // it means that the network to which containers are connecting is created by `act_runner`, - // so, we should remove the network at last. - networkName, _ := rc.networkName() - logger.Infof("Cleaning up network for job %s, and network name is: %s", rc.JobName, networkName) - if err := container.NewDockerNetworkRemoveExecutor(networkName)(ctx); err != nil { - logger.Errorf("Error while cleaning network: %v", err) - } - } + + // For Gitea + // We don't need to call `NewDockerNetworkRemoveExecutor` here since it is called by above `info.stopContainer` + // if !rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" { + // // clean network in docker mode only + // // if the value of `ContainerNetworkMode` is empty string, + // // it means that the network to which containers are connecting is created by `act_runner`, + // // so, we should remove the network at last. + // networkName, _ := rc.networkName() + // logger.Infof("Cleaning up network for job %s, and network name is: %s", rc.JobName, networkName) + // if err := container.NewDockerNetworkRemoveExecutor(networkName)(ctx); err != nil { + // logger.Errorf("Error while cleaning network: %v", err) + // } + // } } setJobResult(ctx, info, rc, jobError == nil) setJobOutputs(ctx, rc) diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index e6380a9..b36cd35 100644 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -95,10 +95,11 @@ func (rc *RunContext) jobContainerName() string { return createSimpleContainerName(rc.Config.ContainerNamePrefix, "WORKFLOW-"+rc.Run.Workflow.Name, "JOB-"+rc.Name) } +// Deprecated: use `networkNameForGitea` // networkName return the name of the network which will be created by `act` automatically for job, // only create network if using a service container func (rc *RunContext) networkName() (string, bool) { - if len(rc.Run.Job().Services) >= 0 { // For Gitea, always create network + if len(rc.Run.Job().Services) > 0 { return fmt.Sprintf("%s-%s-network", rc.jobContainerName(), rc.Run.JobID), true } if rc.Config.ContainerNetworkMode == "" { @@ -107,6 +108,14 @@ func (rc *RunContext) networkName() (string, bool) { return string(rc.Config.ContainerNetworkMode), false } +// networkNameForGitea return the name of the network +func (rc *RunContext) networkNameForGitea() (string, bool) { + if rc.Config.ContainerNetworkMode != "" { + return string(rc.Config.ContainerNetworkMode), false + } + return fmt.Sprintf("%s-%s-network", rc.jobContainerName(), rc.Run.JobID), true +} + func getDockerDaemonSocketMountPath(daemonPath string) string { if protoIndex := strings.Index(daemonPath, "://"); protoIndex != -1 { scheme := daemonPath[:protoIndex] @@ -294,7 +303,7 @@ func (rc *RunContext) startJobContainer() common.Executor { // specify the network to which the container will connect when `docker create` stage. (like execute command line: docker create --network ) // if using service containers, will create a new network for the containers. // and it will be removed after at last. - networkName, createAndDeleteNetwork := rc.networkName() + networkName, createAndDeleteNetwork := rc.networkNameForGitea() // add service containers for serviceID, spec := range rc.Run.Job().Services { @@ -307,6 +316,11 @@ func (rc *RunContext) startJobContainer() common.Executor { for k, v := range interpolatedEnvs { envs = append(envs, fmt.Sprintf("%s=%s", k, v)) } + // interpolate cmd + interpolatedCmd := make([]string, 0, len(spec.Cmd)) + for _, v := range spec.Cmd { + interpolatedCmd = append(interpolatedCmd, rc.ExprEval.Interpolate(ctx, v)) + } username, password, err = rc.handleServiceCredentials(ctx, spec.Credentials) if err != nil { return fmt.Errorf("failed to handle service %s credentials: %w", serviceID, err) @@ -334,6 +348,7 @@ func (rc *RunContext) startJobContainer() common.Executor { Image: rc.ExprEval.Interpolate(ctx, spec.Image), Username: username, Password: password, + Cmd: interpolatedCmd, Env: envs, Mounts: serviceMounts, Binds: serviceBinds, @@ -342,6 +357,7 @@ func (rc *RunContext) startJobContainer() common.Executor { Privileged: rc.Config.Privileged, UsernsMode: rc.Config.UsernsMode, Platform: rc.Config.ContainerArchitecture, + AutoRemove: rc.Config.AutoRemove, Options: rc.ExprEval.Interpolate(ctx, spec.Options), NetworkMode: networkName, NetworkAliases: []string{serviceID}, @@ -390,6 +406,9 @@ func (rc *RunContext) startJobContainer() common.Executor { jobContainerNetwork = "host" } + // For Gitea, `jobContainerNetwork` should be the same as `networkName` + jobContainerNetwork = networkName + rc.JobContainer = container.NewContainer(&container.NewContainerInput{ Cmd: nil, Entrypoint: []string{"/bin/sleep", fmt.Sprint(rc.Config.ContainerMaxLifetime.Round(time.Second).Seconds())},