-
Notifications
You must be signed in to change notification settings - Fork 2.2k
runc: add multi-container support to 'runc delete' and update tests #4940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@yzewei Perhaps we should first update the description of the |
Thanks! I’ve updated the runtime-spec |
Test Coverage UpdateI have supplemented this PR with comprehensive multi-container (batch) integration tests for Key areas of enhanced testing include:
Two issues regarding test stability were resolved during this process:
|
|
@lifubang I don't think we should do that -- the runtime-spec stuff is describing the more general operations, and supporting multiple arguments doesn't really belong there IMHO. |
Do you have a benchmark result? |
Signed-off-by: yzewei <yangzewei@loongson.cn>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of interest, was this code LLM-generated?
| path := filepath.Join(context.GlobalString("root"), id) | ||
| if e := os.RemoveAll(path); e != nil { | ||
| fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, e) | ||
| errs = append(errs, e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This removes the "--force ignores errors" case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I used AI to help me get this done. I still made sure to review and test everything myself.
| } | ||
| if force { | ||
| return nil | ||
| errs = append(errs, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
| fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, e) | ||
| var errs []error | ||
|
|
||
| for _, id := range context.Args() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the body of this loop should be a separate function and just have this loop do the error collection logic -- it's very easy to miss a continue and accidentally return an error.
| // When --force is given, we kill all container processes and | ||
| // then destroy the container. This is done even for a stopped | ||
| // container, because (in case it does not have its own PID | ||
| // namespace) there may be some leftover processes in the | ||
| // container's cgroup. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment has been removed, please add it back.
| switch s { | ||
| case libcontainer.Stopped: | ||
| if err := container.Destroy(); err != nil { | ||
| errs = append(errs, err) | ||
| } | ||
| case libcontainer.Created: | ||
| if err := killContainer(container); err != nil { | ||
| errs = append(errs, err) | ||
| } | ||
| default: | ||
| errs = append(errs, fmt.Errorf("cannot delete container %s that is not stopped: %s", id, s)) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think something more like
| switch s { | |
| case libcontainer.Stopped: | |
| if err := container.Destroy(); err != nil { | |
| errs = append(errs, err) | |
| } | |
| case libcontainer.Created: | |
| if err := killContainer(container); err != nil { | |
| errs = append(errs, err) | |
| } | |
| default: | |
| errs = append(errs, fmt.Errorf("cannot delete container %s that is not stopped: %s", id, s)) | |
| } | |
| switch s { | |
| case libcontainer.Stopped: | |
| err = container.Destroy() | |
| case libcontainer.Created: | |
| err = killContainer(container) | |
| default: | |
| err = fmt.Errorf("cannot delete container %s that is not stopped: %s", id, s) | |
| } | |
| if err != nil { | |
| errs = append(errs, err) | |
| } |
would be nicer.
| // if there was an aborted start or something of the sort then the container's directory could exist but | ||
| // libcontainer does not see it because the state.json file inside that directory was never created. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment has been changed, please just keep the old one if there isn't a good reason to change it.
|
@AkihiroSuda I also find that claim implausible without seeing benchmarks -- the only thing this PR is really saving is the overhead of fork+exec. This whole PR feels like it was generated by an LLM. |
|
Hi @cyphar, Thanks for the feedback. I might not be fully ready to address this yet. Please allow me some time to review the AI-generated code before I follow up. |
Background
Currently, the
runc deletecommand only supports deleting a single container. In high-frequency container creation and destruction environments, manually deleting stopped containers one by one is inefficient and may cause resource contention (e.g., cgroup locks or DBus delays).The community has discussed the need for batch deletion of stopped containers in runc discussion #4935.
Changes in this PR
delete.goto support deleting multiple containers at once.utils_linux.goto handle batch deletion safely.tests/integration/delete.batsto include tests for batch deletion.delete multitest case to ensure the feature works as expected.OCI Runtime Specification Alignment
Crucially, this change aligns with the updated OCI Runtime Specification. I have updated the
deleteoperation in the specification to officially support multiple container IDs, clarifying that each container is deleted independently, and errors are reported per container without affecting others.Comprehensive Batch Test Coverage
The integration test suite (
tests/integration/delete.bats) has been significantly expanded to ensure the batch delete feature is robust across all supported container states and Cgroup environments:--force).killrunning containers beforehand.Notes