Networks created by forgejo-runner don't have IPv6 enabled #119

Closed
opened 2023-11-13 22:55:17 +00:00 by s3lph · 12 comments
Contributor

I have a docker host which has IPv6 enabled in the daemon.json configuration:

{
  "ipv6": true,
  "fixed-cidr-v6": "fd00:d0ca:1::/64",
  "default-address-pools": [
    {"base": "172.17.0.0/16", "size": 24},
    {"base": "fd00:d0ca:2::/104", "size": 112}
  ]
}

With this configuration, all containers on the default network get both IPv6 and IPv4 addresses assigned.
However, networks created by the Forgejo Runner are not IPv6-enabled:

[
    {
        "Name": "GITEA-ACTIONS-TASK-74_WORKFLOW_JOB-upload-network",
        "Id": "41c78b3d06894de9e177cf5980a5a5700cd6447aa1fc63e071989040631d640b",
        "Created": "2023-11-13T23:43:12.534191534+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.6.0/24",
                    "Gateway": "172.17.6.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "f3999f6586f30317206e9aee3309d2c19575eb50a3ea1733cf768b0a416250e6": {
                "Name": "GITEA-ACTIONS-TASK-74_WORKFLOW_JOB-upload",
                "EndpointID": "dfca438736c10af9a6795bd4425a4d6270dfce4c5769dc2c6baf3312e147b7f2",
                "MacAddress": "02:42:ac:11:06:02",
                "IPv4Address": "172.17.6.2/24",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

As a workaround, i can run the runner with container.network set to bridge, but I'd prefer Forgejo Runner to have a config option to enable IPv6 support on its auto-created networks.

I have a docker host which has IPv6 enabled in the `daemon.json` configuration: ```json { "ipv6": true, "fixed-cidr-v6": "fd00:d0ca:1::/64", "default-address-pools": [ {"base": "172.17.0.0/16", "size": 24}, {"base": "fd00:d0ca:2::/104", "size": 112} ] } ``` With this configuration, all containers on the default network get both IPv6 and IPv4 addresses assigned. However, networks created by the Forgejo Runner are not IPv6-enabled: ```json [ { "Name": "GITEA-ACTIONS-TASK-74_WORKFLOW_JOB-upload-network", "Id": "41c78b3d06894de9e177cf5980a5a5700cd6447aa1fc63e071989040631d640b", "Created": "2023-11-13T23:43:12.534191534+01:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.6.0/24", "Gateway": "172.17.6.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "f3999f6586f30317206e9aee3309d2c19575eb50a3ea1733cf768b0a416250e6": { "Name": "GITEA-ACTIONS-TASK-74_WORKFLOW_JOB-upload", "EndpointID": "dfca438736c10af9a6795bd4425a4d6270dfce4c5769dc2c6baf3312e147b7f2", "MacAddress": "02:42:ac:11:06:02", "IPv4Address": "172.17.6.2/24", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] ``` As a workaround, i can run the runner with `container.network` set to `bridge`, but I'd prefer Forgejo Runner to have a config option to enable IPv6 support on its auto-created networks.
earl-warren added the
Kind/Feature
label 2023-11-13 23:25:40 +00:00
Owner

The code that should be modified to support IPv6 is around https://code.forgejo.org/forgejo/act/src/branch/main/pkg/container/docker_network.go

The code that should be modified to support IPv6 is around https://code.forgejo.org/forgejo/act/src/branch/main/pkg/container/docker_network.go
Author
Contributor

@earl-warren thanks for the pointer. I did a first hacky implementation, and it appears to be working. Unfortunately, we can't simply hard-code EnableIPv6: true in the network creation, as this fails to create containers on non-IPv6 enabled docker hosts. So changes to both forgejo/act (for the implementation) and forgejo/runner (for the config flag) are required.

I'll clean up my code and open two PRs.

@earl-warren thanks for the pointer. I did a first hacky implementation, and it appears to be working. Unfortunately, we can't simply hard-code `EnableIPv6: true` in the network creation, as this fails to create containers on non-IPv6 enabled docker hosts. So changes to both forgejo/act (for the implementation) and forgejo/runner (for the config flag) are required. I'll clean up my code and open two PRs.
Owner

You will see lots of activity as a consequence of your PRs, from the cascading-pr user. It is a recent experimental addition that allows a companion PR to be created in the runner to verify the PR from ACT compiles.

It was a little too verbose / enthusiastic and made lots of noise, all of which should now be cleaned up.

The difficulty essentially is to properly test your changes. If you provide me with a list of commands to do that assuming they run on a newly provisioned Debian GNU/Linux bookworm, I will create the CI job to do the same.

You will see lots of activity as a consequence of your PRs, from the `cascading-pr` user. It is a recent experimental addition that allows a companion PR to be created in the runner to verify the PR from ACT compiles. It was a little too verbose / enthusiastic and made lots of noise, all of which should now be cleaned up. The difficulty essentially is to properly test your changes. If you provide me with a list of commands to do that assuming they run on a newly provisioned Debian GNU/Linux bookworm, I will create the CI job to do the same.
Author
Contributor

First of all, the docker daemon needs to be configured with IPv6 support, e.g.:

# apt update; apt install docker.io
# cat > /etc/docker/daemon.json <<EOF
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00:d0ca:1::/64",
  "default-address-pools": [
    {"base": "172.17.0.0/16", "size": 24},
    {"base": "fd00:d0ca:2::/104", "size": 112}
  ]
}
EOF
# systemctl restart docker

You can then run an action which checks for IPv6 connectivity, e.g.

---
on: push
jobs:
  ipv6:
    runs-on: docker
    steps:
      - run: |
          apt update; apt install --yes iputils-ping
          ping -c 1 -6 ::1          

If you run this with forgejo-runner exec, the job will fail:

# forgejo-runner exec
| ping: connect: Cannot assign requested address
[ipv6.yml/ipv6] exitcode '2': failure
[ipv6.yml/ipv6] Cleaning up services for job ipv6
INFO[0007] Parallel tasks (0) below minimum, setting to 1
[ipv6.yml/ipv6] Cleaning up container for job ipv6
[ipv6.yml/ipv6] Cleaning up network for job ipv6, and network name is: FORGEJO-ACTIONS-TASK-push_WORKFLOW-ipv6-yml_JOB-ipv6-network
[ipv6.yml/ipv6] 🏁  Job failed

If you run this again with forgejo-runner exec --enable-ipv6, the job should succeed:

# forgejo-runner exec --enable-ipv6
| PING ::1(::1) 56 data bytes
| 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.018 ms
|
| --- ::1 ping statistics ---
| 1 packets transmitted, 1 received, 0% packet loss, time 0ms
| rtt min/avg/max/mdev = 0.018/0.018/0.018/0.000 ms
[ipv6.yml/ipv6] Cleaning up services for job ipv6
[ipv6.yml/ipv6] Cleaning up container for job ipv6
[ipv6.yml/ipv6] Cleaning up network for job ipv6, and network name is: FORGEJO-ACTIONS-TASK-push_WORKFLOW-ipv6-yml_JOB-ipv6-network
[ipv6.yml/ipv6] 🏁  Job succeeded

The same should be tested with a forgejo-runner daemon with container.enable_ipv6: false and container.enable_ipv6: true, yielding the same results.

First of all, the docker daemon needs to be configured with IPv6 support, e.g.: ```shell-session # apt update; apt install docker.io # cat > /etc/docker/daemon.json <<EOF { "ipv6": true, "fixed-cidr-v6": "fd00:d0ca:1::/64", "default-address-pools": [ {"base": "172.17.0.0/16", "size": 24}, {"base": "fd00:d0ca:2::/104", "size": 112} ] } EOF # systemctl restart docker ``` You can then run an action which checks for IPv6 connectivity, e.g. ```yaml --- on: push jobs: ipv6: runs-on: docker steps: - run: | apt update; apt install --yes iputils-ping ping -c 1 -6 ::1 ``` If you run this with `forgejo-runner exec`, the job will fail: ```shell-session # forgejo-runner exec | ping: connect: Cannot assign requested address [ipv6.yml/ipv6] exitcode '2': failure [ipv6.yml/ipv6] Cleaning up services for job ipv6 INFO[0007] Parallel tasks (0) below minimum, setting to 1 [ipv6.yml/ipv6] Cleaning up container for job ipv6 [ipv6.yml/ipv6] Cleaning up network for job ipv6, and network name is: FORGEJO-ACTIONS-TASK-push_WORKFLOW-ipv6-yml_JOB-ipv6-network [ipv6.yml/ipv6] 🏁 Job failed ``` If you run this again with `forgejo-runner exec --enable-ipv6`, the job should succeed: ```shell-session # forgejo-runner exec --enable-ipv6 | PING ::1(::1) 56 data bytes | 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.018 ms | | --- ::1 ping statistics --- | 1 packets transmitted, 1 received, 0% packet loss, time 0ms | rtt min/avg/max/mdev = 0.018/0.018/0.018/0.000 ms [ipv6.yml/ipv6] Cleaning up services for job ipv6 [ipv6.yml/ipv6] Cleaning up container for job ipv6 [ipv6.yml/ipv6] Cleaning up network for job ipv6, and network name is: FORGEJO-ACTIONS-TASK-push_WORKFLOW-ipv6-yml_JOB-ipv6-network [ipv6.yml/ipv6] 🏁 Job succeeded ``` The same should be tested with a `forgejo-runner daemon` with `container.enable_ipv6: false` and `container.enable_ipv6: true`, yielding the same results.
Owner
This is perfect. My idea to modify https://code.forgejo.org/actions/setup-forgejo/src/branch/main/forgejo-runner.sh to support the ipv6 option and add what you described above to https://code.forgejo.org/actions/setup-forgejo/src/branch/main/.forgejo/workflows/integration-nested.yml to verify it works.
Owner

Also note that this new feature needs an update to the documentation at https://codeberg.org/forgejo/docs/src/branch/next/docs/admin/actions.md

Also note that this new feature needs an update to the documentation at https://codeberg.org/forgejo/docs/src/branch/next/docs/admin/actions.md
Author
Contributor

@earl-warren thanks for the hint. I've added a documentation snippet in https://codeberg.org/forgejo/docs/pulls/242

@earl-warren thanks for the hint. I've added a documentation snippet in https://codeberg.org/forgejo/docs/pulls/242
earl-warren self-assigned this 2023-11-15 16:43:12 +00:00
earl-warren added the
Kind/Testing
label 2023-11-15 16:43:19 +00:00
Owner

Re-opening pending the implementation of tests.

Re-opening pending the implementation of tests.
Owner

Now that the (many) Forgejo releases are done, I'll enjoy going back to working on this 🎉

Now that the (many) Forgejo releases are done, I'll enjoy going back to working on this 🎉
Owner

Unfortunately IPv6 is not enabled by default in LXC containers even when the host is IPv6 capable. I'll need to figure that out first.

$ curl -s -o /dev/null http://ipv6.google.com
$ echo $?
0
$ lxc-helpers.sh lxc_container_create mytest
$ lxc-helpers.sh lxc_container_start mytest
$ lxc-helpers.sh lxc_container_run mytest bash
root@mytest:/# apt-get update ; apt-get install curl  
root@mytest:/# curl -s -o /dev/null http://ipv6.google.com
root@mytest:/# echo $?
7
root@mytest:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:16:3e:cd:6e:17 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.3.76/24 brd 10.0.3.255 scope global dynamic eth0
       valid_lft 3516sec preferred_lft 3516sec
    inet6 fe80::216:3eff:fecd:6e17/64 scope link 
       valid_lft forever preferred_lft forever
Unfortunately IPv6 is not enabled by default in LXC containers even when the host is IPv6 capable. I'll need to figure that out first. ```sh $ curl -s -o /dev/null http://ipv6.google.com $ echo $? 0 $ lxc-helpers.sh lxc_container_create mytest $ lxc-helpers.sh lxc_container_start mytest $ lxc-helpers.sh lxc_container_run mytest bash root@mytest:/# apt-get update ; apt-get install curl root@mytest:/# curl -s -o /dev/null http://ipv6.google.com root@mytest:/# echo $? 7 root@mytest:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:cd:6e:17 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.0.3.76/24 brd 10.0.3.255 scope global dynamic eth0 valid_lft 3516sec preferred_lft 3516sec inet6 fe80::216:3eff:fecd:6e17/64 scope link valid_lft forever preferred_lft forever ```
Owner

Now that the runner includes IPv6 capables LXC containers, it will be possible to write the test for IPv6 capable docker containers.

Now that the runner includes IPv6 capables LXC containers, it will be possible to write the test for IPv6 capable docker containers.
Owner

This has been implemented & tested. The tests actually prevented a regression when upgrading the ACT version, which is exactly what they were supposed to do.

This has been implemented & tested. The tests actually prevented a regression when upgrading the ACT version, which is exactly what they were supposed to do.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: forgejo/runner#119
No description provided.