mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-06-15 14:24:22 +02:00
feat: ipv6 options for network container creation (#1029)
Here is a final proposal for ipv6 enablement on temporary network created by gitea runner --------- Co-authored-by: Nicolas <bircni@icloud.com> Co-authored-by: Nicolas Schwartz <9308314+StarAurryon@users.noreply.github.com> Reviewed-on: https://gitea.com/gitea/runner/pulls/1029 Reviewed-by: Nicolas <bircni@icloud.com> Co-authored-by: StarAurryon <206206+staraurryon@noreply.gitea.com> Co-committed-by: StarAurryon <206206+staraurryon@noreply.gitea.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"gitea.com/gitea/runner/act/artifactcache"
|
||||
"gitea.com/gitea/runner/act/common"
|
||||
"gitea.com/gitea/runner/act/container"
|
||||
"gitea.com/gitea/runner/act/model"
|
||||
"gitea.com/gitea/runner/act/runner"
|
||||
"gitea.com/gitea/runner/internal/pkg/client"
|
||||
@@ -33,7 +34,7 @@ import (
|
||||
|
||||
"connectrpc.com/connect"
|
||||
runnerv1 "gitea.dev/actions-proto-go/runner/v1"
|
||||
"github.com/moby/moby/api/types/container"
|
||||
docker_container "github.com/moby/moby/api/types/container"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -418,22 +419,26 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
|
||||
AllocatePTY: r.cfg.Runner.AllocatePTY,
|
||||
ActionOfflineMode: r.cfg.Cache.OfflineMode,
|
||||
|
||||
ReuseContainers: false,
|
||||
ForcePull: r.cfg.Container.ForcePull,
|
||||
ForceRebuild: r.cfg.Container.ForceRebuild,
|
||||
LogOutput: true,
|
||||
JSONLogger: false,
|
||||
Env: envs,
|
||||
Secrets: task.Secrets,
|
||||
GitHubInstance: strings.TrimSuffix(r.client.Address(), "/"),
|
||||
AutoRemove: true,
|
||||
NoSkipCheckout: true,
|
||||
PresetGitHubContext: preset,
|
||||
EventJSON: string(eventJSON),
|
||||
ContainerNamePrefix: fmt.Sprintf("GITEA-ACTIONS-TASK-%d", task.Id),
|
||||
ContainerMaxLifetime: maxLifetime,
|
||||
CleanWorkdir: true,
|
||||
ContainerNetworkMode: container.NetworkMode(r.cfg.Container.Network),
|
||||
ReuseContainers: false,
|
||||
ForcePull: r.cfg.Container.ForcePull,
|
||||
ForceRebuild: r.cfg.Container.ForceRebuild,
|
||||
LogOutput: true,
|
||||
JSONLogger: false,
|
||||
Env: envs,
|
||||
Secrets: task.Secrets,
|
||||
GitHubInstance: strings.TrimSuffix(r.client.Address(), "/"),
|
||||
AutoRemove: true,
|
||||
NoSkipCheckout: true,
|
||||
PresetGitHubContext: preset,
|
||||
EventJSON: string(eventJSON),
|
||||
ContainerNamePrefix: fmt.Sprintf("GITEA-ACTIONS-TASK-%d", task.Id),
|
||||
ContainerMaxLifetime: maxLifetime,
|
||||
CleanWorkdir: true,
|
||||
ContainerNetworkMode: docker_container.NetworkMode(r.cfg.Container.Network),
|
||||
ContainerNetworkCreateOptions: container.NewDockerNetworkCreateExecutorInput{
|
||||
EnableIPv4: r.cfg.Container.NetworkCreateOptions.EnableIPv4,
|
||||
EnableIPv6: r.cfg.Container.NetworkCreateOptions.EnableIPv6,
|
||||
},
|
||||
ContainerOptions: r.cfg.Container.Options,
|
||||
ContainerDaemonSocket: r.cfg.Container.DockerHost,
|
||||
Privileged: r.cfg.Container.Privileged,
|
||||
|
||||
@@ -116,6 +116,13 @@ container:
|
||||
# If it's empty, runner will create a network automatically.
|
||||
# Deprecated: `network_mode` is still accepted for old configs; use `network` instead.
|
||||
network: ""
|
||||
# network_create_options only apply when `network` is left empty and the runner
|
||||
# auto-creates a per-job network that does not already exist. They have no effect
|
||||
# when a custom `network` name is set, because that network is used as-is and never
|
||||
# created by the runner. Omit the entire block to use Docker's defaults.
|
||||
network_create_options:
|
||||
enable_ipv4: true # Omit to use Docker's default (IPv4 enabled). Set false to disable IPv4.
|
||||
enable_ipv6: false # Omit to use Docker's default (IPv6 disabled). Enabling it requires dockerd started with --ipv6.
|
||||
# Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
|
||||
privileged: false
|
||||
# Any other options to be used when the container is started (e.g., --add-host=my.gitea.url:host-gateway).
|
||||
|
||||
@@ -58,18 +58,24 @@ type Cache struct {
|
||||
|
||||
// Container represents the configuration for the container.
|
||||
type Container struct {
|
||||
Network string `yaml:"network"` // Network specifies the network for the container.
|
||||
NetworkMode string `yaml:"network_mode"` // Deprecated: use Network instead. Could be removed after Gitea 1.20
|
||||
Privileged bool `yaml:"privileged"` // Privileged indicates whether the container runs in privileged mode.
|
||||
Options string `yaml:"options"` // Options specifies additional options for the container.
|
||||
WorkdirParent string `yaml:"workdir_parent"` // WorkdirParent specifies the parent directory for the container's working directory.
|
||||
ValidVolumes []string `yaml:"valid_volumes"` // ValidVolumes specifies the volumes (including bind mounts) can be mounted to containers.
|
||||
DockerHost string `yaml:"docker_host"` // DockerHost specifies the Docker host. It overrides the value specified in environment variable DOCKER_HOST.
|
||||
ForcePull bool `yaml:"force_pull"` // Pull docker image(s) even if already present
|
||||
ForceRebuild bool `yaml:"force_rebuild"` // Rebuild docker image(s) even if already present
|
||||
RequireDocker bool `yaml:"require_docker"` // Always require a reachable docker daemon, even if not required by runner
|
||||
DockerTimeout time.Duration `yaml:"docker_timeout"` // Timeout to wait for the docker daemon to be reachable, if docker is required by require_docker or runner
|
||||
BindWorkdir bool `yaml:"bind_workdir"` // BindWorkdir binds the workspace to the host filesystem instead of using Docker volumes. Required for DinD when jobs use docker compose with bind mounts.
|
||||
Network string `yaml:"network"` // Network specifies the network for the container.
|
||||
NetworkCreateOptions ContainerNetworkCreateOptions `yaml:"network_create_options"` // Add options when the network need to be created by the runner
|
||||
NetworkMode string `yaml:"network_mode"` // Deprecated: use Network instead. Could be removed after Gitea 1.20
|
||||
Privileged bool `yaml:"privileged"` // Privileged indicates whether the container runs in privileged mode.
|
||||
Options string `yaml:"options"` // Options specifies additional options for the container.
|
||||
WorkdirParent string `yaml:"workdir_parent"` // WorkdirParent specifies the parent directory for the container's working directory.
|
||||
ValidVolumes []string `yaml:"valid_volumes"` // ValidVolumes specifies the volumes (including bind mounts) can be mounted to containers.
|
||||
DockerHost string `yaml:"docker_host"` // DockerHost specifies the Docker host. It overrides the value specified in environment variable DOCKER_HOST.
|
||||
ForcePull bool `yaml:"force_pull"` // Pull docker image(s) even if already present
|
||||
ForceRebuild bool `yaml:"force_rebuild"` // Rebuild docker image(s) even if already present
|
||||
RequireDocker bool `yaml:"require_docker"` // Always require a reachable docker daemon, even if not required by runner
|
||||
DockerTimeout time.Duration `yaml:"docker_timeout"` // Timeout to wait for the docker daemon to be reachable, if docker is required by require_docker or runner
|
||||
BindWorkdir bool `yaml:"bind_workdir"` // BindWorkdir binds the workspace to the host filesystem instead of using Docker volumes. Required for DinD when jobs use docker compose with bind mounts.
|
||||
}
|
||||
|
||||
type ContainerNetworkCreateOptions struct {
|
||||
EnableIPv4 *bool `yaml:"enable_ipv4"` // Enable or disable IPv4 for the network (true for docker by default)
|
||||
EnableIPv6 *bool `yaml:"enable_ipv6"` // Enable or disable IPv6 for the network (false for docker by default)
|
||||
}
|
||||
|
||||
// Host represents the configuration for the host.
|
||||
|
||||
@@ -117,3 +117,50 @@ func TestLoadDefault_MalformedYAMLReturnsParseError(t *testing.T) {
|
||||
assert.Contains(t, err.Error(), "parse config file")
|
||||
assert.NotContains(t, err.Error(), "defaults metadata")
|
||||
}
|
||||
|
||||
func TestContainerNetworkCreateOptions(t *testing.T) {
|
||||
// Verify that the enable_ipv4/enable_ipv6 YAML keys unmarshal into the *bool fields,
|
||||
// distinguishing an explicit true/false from an omitted key (nil). A nil here is
|
||||
// forwarded as-is to Docker, which applies its own default.
|
||||
loadOptions := func(t *testing.T, yaml string) ContainerNetworkCreateOptions {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "config.yaml")
|
||||
require.NoError(t, os.WriteFile(path, []byte(yaml), 0o600))
|
||||
|
||||
cfg, err := LoadDefault(path)
|
||||
require.NoError(t, err)
|
||||
return cfg.Container.NetworkCreateOptions
|
||||
}
|
||||
|
||||
t.Run("enable_ipv6 true unmarshals to non-nil true", func(t *testing.T) {
|
||||
opts := loadOptions(t, "container:\n network_create_options:\n enable_ipv6: true\n")
|
||||
require.NotNil(t, opts.EnableIPv6)
|
||||
assert.True(t, *opts.EnableIPv6)
|
||||
})
|
||||
|
||||
t.Run("enable_ipv6 false unmarshals to non-nil false", func(t *testing.T) {
|
||||
opts := loadOptions(t, "container:\n network_create_options:\n enable_ipv6: false\n")
|
||||
require.NotNil(t, opts.EnableIPv6)
|
||||
assert.False(t, *opts.EnableIPv6)
|
||||
})
|
||||
|
||||
t.Run("enable_ipv4 false unmarshals to non-nil false", func(t *testing.T) {
|
||||
opts := loadOptions(t, "container:\n network_create_options:\n enable_ipv4: false\n")
|
||||
require.NotNil(t, opts.EnableIPv4)
|
||||
assert.False(t, *opts.EnableIPv4)
|
||||
})
|
||||
|
||||
t.Run("omitted keys stay nil", func(t *testing.T) {
|
||||
opts := loadOptions(t, "container:\n network_create_options:\n enable_ipv4: true\n")
|
||||
require.NotNil(t, opts.EnableIPv4)
|
||||
assert.True(t, *opts.EnableIPv4)
|
||||
assert.Nil(t, opts.EnableIPv6, "an omitted enable_ipv6 must remain nil so Docker's default applies")
|
||||
})
|
||||
|
||||
t.Run("omitted block leaves both nil", func(t *testing.T) {
|
||||
opts := loadOptions(t, "container:\n network: \"\"\n")
|
||||
assert.Nil(t, opts.EnableIPv4)
|
||||
assert.Nil(t, opts.EnableIPv6)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user