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 <i@wolfogre.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-committed-by: Zettat123 <zettat123@gmail.com>
This commit is contained in:
Zettat123
2024-03-26 10:14:06 +00:00
committed by Jason Song
parent 79a7577c15
commit 0054a45d1b
2 changed files with 41 additions and 18 deletions

View File

@@ -6,7 +6,6 @@ import (
"time" "time"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container"
"github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/model"
) )
@@ -118,26 +117,31 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
defer cancel() defer cancel()
logger := common.Logger(ctx) logger := common.Logger(ctx)
logger.Infof("Cleaning up services for job %s", rc.JobName) // For Gitea
if err := rc.stopServiceContainers()(ctx); err != nil { // We don't need to call `stopServiceContainers` here since it will be called by following `info.stopContainer`
logger.Errorf("Error while cleaning services: %v", err) // 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) logger.Infof("Cleaning up container for job %s", rc.JobName)
if err = info.stopContainer()(ctx); err != nil { if err = info.stopContainer()(ctx); err != nil {
logger.Errorf("Error while stop job container: %v", err) logger.Errorf("Error while stop job container: %v", err)
} }
if !rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" {
// clean network in docker mode only // For Gitea
// if the value of `ContainerNetworkMode` is empty string, // We don't need to call `NewDockerNetworkRemoveExecutor` here since it is called by above `info.stopContainer`
// it means that the network to which containers are connecting is created by `act_runner`, // if !rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" {
// so, we should remove the network at last. // // clean network in docker mode only
networkName, _ := rc.networkName() // // if the value of `ContainerNetworkMode` is empty string,
logger.Infof("Cleaning up network for job %s, and network name is: %s", rc.JobName, networkName) // // it means that the network to which containers are connecting is created by `act_runner`,
if err := container.NewDockerNetworkRemoveExecutor(networkName)(ctx); err != nil { // // so, we should remove the network at last.
logger.Errorf("Error while cleaning network: %v", err) // 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) setJobResult(ctx, info, rc, jobError == nil)
setJobOutputs(ctx, rc) setJobOutputs(ctx, rc)

View File

@@ -95,10 +95,11 @@ func (rc *RunContext) jobContainerName() string {
return createSimpleContainerName(rc.Config.ContainerNamePrefix, "WORKFLOW-"+rc.Run.Workflow.Name, "JOB-"+rc.Name) 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, // networkName return the name of the network which will be created by `act` automatically for job,
// only create network if using a service container // only create network if using a service container
func (rc *RunContext) networkName() (string, bool) { 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 return fmt.Sprintf("%s-%s-network", rc.jobContainerName(), rc.Run.JobID), true
} }
if rc.Config.ContainerNetworkMode == "" { if rc.Config.ContainerNetworkMode == "" {
@@ -107,6 +108,14 @@ func (rc *RunContext) networkName() (string, bool) {
return string(rc.Config.ContainerNetworkMode), false 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 { func getDockerDaemonSocketMountPath(daemonPath string) string {
if protoIndex := strings.Index(daemonPath, "://"); protoIndex != -1 { if protoIndex := strings.Index(daemonPath, "://"); protoIndex != -1 {
scheme := daemonPath[:protoIndex] 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 <networkName> <image>) // specify the network to which the container will connect when `docker create` stage. (like execute command line: docker create --network <networkName> <image>)
// if using service containers, will create a new network for the containers. // if using service containers, will create a new network for the containers.
// and it will be removed after at last. // and it will be removed after at last.
networkName, createAndDeleteNetwork := rc.networkName() networkName, createAndDeleteNetwork := rc.networkNameForGitea()
// add service containers // add service containers
for serviceID, spec := range rc.Run.Job().Services { for serviceID, spec := range rc.Run.Job().Services {
@@ -307,6 +316,11 @@ func (rc *RunContext) startJobContainer() common.Executor {
for k, v := range interpolatedEnvs { for k, v := range interpolatedEnvs {
envs = append(envs, fmt.Sprintf("%s=%s", k, v)) 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) username, password, err = rc.handleServiceCredentials(ctx, spec.Credentials)
if err != nil { if err != nil {
return fmt.Errorf("failed to handle service %s credentials: %w", serviceID, err) 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), Image: rc.ExprEval.Interpolate(ctx, spec.Image),
Username: username, Username: username,
Password: password, Password: password,
Cmd: interpolatedCmd,
Env: envs, Env: envs,
Mounts: serviceMounts, Mounts: serviceMounts,
Binds: serviceBinds, Binds: serviceBinds,
@@ -342,6 +357,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
Privileged: rc.Config.Privileged, Privileged: rc.Config.Privileged,
UsernsMode: rc.Config.UsernsMode, UsernsMode: rc.Config.UsernsMode,
Platform: rc.Config.ContainerArchitecture, Platform: rc.Config.ContainerArchitecture,
AutoRemove: rc.Config.AutoRemove,
Options: rc.ExprEval.Interpolate(ctx, spec.Options), Options: rc.ExprEval.Interpolate(ctx, spec.Options),
NetworkMode: networkName, NetworkMode: networkName,
NetworkAliases: []string{serviceID}, NetworkAliases: []string{serviceID},
@@ -390,6 +406,9 @@ func (rc *RunContext) startJobContainer() common.Executor {
jobContainerNetwork = "host" jobContainerNetwork = "host"
} }
// For Gitea, `jobContainerNetwork` should be the same as `networkName`
jobContainerNetwork = networkName
rc.JobContainer = container.NewContainer(&container.NewContainerInput{ rc.JobContainer = container.NewContainer(&container.NewContainerInput{
Cmd: nil, Cmd: nil,
Entrypoint: []string{"/bin/sleep", fmt.Sprint(rc.Config.ContainerMaxLifetime.Round(time.Second).Seconds())}, Entrypoint: []string{"/bin/sleep", fmt.Sprint(rc.Config.ContainerMaxLifetime.Round(time.Second).Seconds())},