Skip to content

fix: leave container memory swappiness unset by default - #7270

Open
huijoohwee wants to merge 3 commits into
cloudflare:mainfrom
huijoohwee:fix/optional-memory-swappiness
Open

fix: leave container memory swappiness unset by default#7270
huijoohwee wants to merge 3 commits into
cloudflare:mainfrom
huijoohwee:fix/optional-memory-swappiness

Conversation

@huijoohwee

@huijoohwee huijoohwee commented Sep 8, 2026

Copy link
Copy Markdown

Container creation currently serializes HostConfig.MemorySwappiness as 0 even when workerd never configures it. Podman accepts the create request, but crun on cgroup v2 rejects starting the container with cannot set memory swappiness with cgroupv2: OCI runtime error. This prevents the container egress sidecar from starting during local Workers development.

Represent this optional JSON field with Json.Value, so an uninitialized value is omitted while explicit numeric values, including zero, remain representable. This changes only the swappiness field; other default-valued request fields keep their existing encoding. No container-engine detection or request-rewriting proxy is added.

The two focused KJ tests cover omission and explicit zero/nonzero values, and verify that PublishAllPorts and StopTimeout retain their encoding. The test target depends on the API schema and JSON codec rather than the complete container client/runtime.

Validation

  • Compiled the generated schema and both added KJ tests locally using Apple Clang 21 and workerd's pinned Cap'n Proto revision 7077d443af81e94ea923e41b9990f697058e3b56: 2 passed.
  • Compiled and ran the same omission assertion against the original schema: fails as expected because MemorySwappiness is present.
  • Generated complete create requests from the original and fixed schemas with that pinned Cap'n Proto JSON codec. They differ only by removal of MemorySwappiness: 0. Against rootless Podman 6.1.1, crun 1.29.1, Fedora 44, cgroup v2:
    • Original: create 201, start 500, swappiness error.
    • Fixed: create 201, start 204, wait 200 / exit 0.
    • Both reproduction containers were removed successfully.
  • Pinned clang-format 18.1.8, buildifier 8.2.1, and git diff --check pass.
  • Attempted bazel test //src/workerd/server:docker-api-test@ //src/workerd/server:docker-api-test@all-autogates --jobs=4 --test_output=errors. Dependency extraction stopped with No space left on device before test execution. The local C++ tests above were then built directly with the pinned Cap'n Proto source via CMake. The Bazel targets, full workerd build, and full Workers/Sandbox E2E suite have not passed locally.

Hosted checks

internal-build stops before compilation because the fork owner is not a public Cloudflare organization member; an upstream maintainer will need to assist with that build. CLA Assistant also requires the contributor signature. Neither check is a successful build/test result.

Minimal Podman reproduction

Use a running Podman Unix socket and an image already available to that engine. This reproduces the API distinction without Wrangler or a Docker CLI dependency. For macOS, the socket is reported by podman machine inspect <machine> --format '{{.ConnectionInfo.PodmanSocket.Path}}'.

export PODMAN_SOCKET=/path/to/podman.sock
export TEST_IMAGE=your-local-image-with-sh
import http.client, json, os, socket, uuid

class UnixHTTP(http.client.HTTPConnection):
    def connect(self):
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.sock.settimeout(15)
        self.sock.connect(os.environ["PODMAN_SOCKET"])

def request(method, path, body=None):
    conn = UnixHTTP("localhost", timeout=15)
    conn.request(method, path,
                 body=json.dumps(body) if body is not None else None,
                 headers={"Content-Type": "application/json"})
    response = conn.getresponse()
    status, data = response.status, response.read().decode()
    conn.close()
    return status, data

for host_config in [{"MemorySwappiness": 0}, {}]:
    name = "swappiness-repro-" + uuid.uuid4().hex[:12]
    status, data = request("POST", "/v1.45/containers/create?name=" + name, {
        "Image": os.environ["TEST_IMAGE"],
        "Cmd": ["sh", "-c", "exit 0"],
        "HostConfig": host_config,
    })
    assert status == 201, (status, data)
    container = "/v1.45/containers/" + json.loads(data)["Id"]
    try:
        status, data = request("POST", container + "/start")
        print(host_config, status, data)
        if status == 204:
            print("wait", request("POST", container + "/wait"))
    finally:
        print("remove", request("DELETE", container))

On the environment above, the first start returns 500 with the crun swappiness error; the second returns 204 and exits zero. This addresses the workerd API failure independently of Wrangler's separate Podman build-flag compatibility issue (workers-sdk#9755).

@huijoohwee
huijoohwee requested review from a team as code owners September 8, 2026 03:18
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@huijoohwee

Copy link
Copy Markdown
Author

Could a maintainer help run the internal build for this change? The failed workflow stops at the fork-owner organization-membership check before compilation and directs external contributors to ask reviewers for assistance.

The PR includes two focused schema/codec tests and a Podman reproduction where omitting MemorySwappiness changes container start from HTTP 500 to HTTP 204. The full Bazel and Workers/Sandbox E2E validation remains outstanding. The contributor CLA signature is also still pending.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant