Skip to content

Commit

Permalink
Check volumes (#60)
Browse files Browse the repository at this point in the history
This PR adds a `ValidVolumes` config. Users can specify the volumes (including bind mounts) that can be mounted to containers by this config.

Options related to volumes:
- [jobs.<job_id>.container.volumes](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idcontainervolumes)
- [jobs.<job_id>.services.<service_id>.volumes](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idservicesservice_idvolumes)

In addition, volumes specified by `options` will also be checked.

Currently, the following default volumes (see https://gitea.com/gitea/act/src/commit/a72822b3f83d3e68ffc697101b713b7badf57e2f/pkg/runner/run_context.go#L116-L166) will be added to `ValidVolumes`:
- `act-toolcache`
- `<container-name>` and `<container-name>-env`
- `/var/run/docker.sock` (We need to add a new configuration to control whether the docker daemon can be mounted)

Co-authored-by: Jason Song <i@wolfogre.com>
Reviewed-on: https://gitea.com/gitea/act/pulls/60
Reviewed-by: Jason Song <i@wolfogre.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-committed-by: Zettat123 <zettat123@gmail.com>
  • Loading branch information
2 people authored and GuessWhoSamFoo committed Aug 7, 2023
1 parent a857ed1 commit 715ac6d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
1 change: 1 addition & 0 deletions pkg/container/container_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type NewContainerInput struct {
Platform string
Options string
NetworkAliases []string
ValidVolumes []string
}

// FileEntry is a file to copy to a container
Expand Down
51 changes: 38 additions & 13 deletions pkg/runner/run_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,21 +290,17 @@ func (rc *RunContext) startJobContainer() common.Executor {
if err != nil {
return fmt.Errorf("failed to handle service %s credentials: %w", serviceId, err)
}
serviceBinds, serviceMounts := rc.GetServiceBindsAndMounts(spec.Volumes)
serviceContainerName := createContainerName(rc.jobContainerName(), serviceId)
c := container.NewContainer(&container.NewContainerInput{
Name: serviceContainerName,
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
Image: spec.Image,
Username: username,
Password: password,
Env: envs,
Mounts: map[string]string{
// TODO merge volumes
serviceId: ext.ToContainerPath(rc.Config.Workdir),
"act-toolcache": "/toolcache",
"act-actions": "/actions",
},
Binds: binds,
Name: serviceContainerName,
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
Image: spec.Image,
Username: username,
Password: password,
Env: envs,
Mounts: serviceMounts,
Binds: serviceBinds,
Stdout: logWriter,
Stderr: logWriter,
Privileged: rc.Config.Privileged,
Expand All @@ -313,6 +309,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
Options: spec.Options,
NetworkMode: networkName,
NetworkAliases: []string{serviceId},
ValidVolumes: rc.Config.ValidVolumes,
})
rc.ServiceContainers = append(rc.ServiceContainers, c)
}
Expand Down Expand Up @@ -345,6 +342,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
UsernsMode: rc.Config.UsernsMode,
Platform: rc.Config.ContainerArchitecture,
Options: rc.options(ctx),
ValidVolumes: rc.Config.ValidVolumes,
})
if rc.JobContainer == nil {
return errors.New("Failed to create job container")
Expand Down Expand Up @@ -983,3 +981,30 @@ func (rc *RunContext) handleServiceCredentials(ctx context.Context, creds map[st

return
}

// GetServiceBindsAndMounts returns the binds and mounts for the service container, resolving paths as appopriate
func (rc *RunContext) GetServiceBindsAndMounts(svcVolumes []string) ([]string, map[string]string) {
if rc.Config.ContainerDaemonSocket == "" {
rc.Config.ContainerDaemonSocket = "/var/run/docker.sock"
}
binds := []string{}
if rc.Config.ContainerDaemonSocket != "-" {
daemonPath := getDockerDaemonSocketMountPath(rc.Config.ContainerDaemonSocket)
binds = append(binds, fmt.Sprintf("%s:%s", daemonPath, "/var/run/docker.sock"))
}

mounts := map[string]string{}

for _, v := range svcVolumes {
if !strings.Contains(v, ":") || filepath.IsAbs(v) {
// Bind anonymous volume or host file.
binds = append(binds, v)
} else {
// Mount existing volume.
paths := strings.SplitN(v, ":", 2)
mounts[paths[0]] = paths[1]
}
}

return binds, mounts
}
1 change: 1 addition & 0 deletions pkg/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Config struct {
Matrix map[string]map[string]bool // Matrix config to run
ContainerMaxLifetime time.Duration // the max lifetime of job containers
ContainerNetworkMode docker_container.NetworkMode // the network mode of job containers (the value of --network)
ValidVolumes []string // only volumes (and bind mounts) in this slice can be mounted on the job container or service containers
}

type caller struct {
Expand Down

0 comments on commit 715ac6d

Please sign in to comment.