-
Notifications
You must be signed in to change notification settings - Fork 354
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
Add a relative_network_cgroups test as one of the integration tests #2986
base: main
Are you sure you want to change the base?
Conversation
4696ba0
to
b332eb0
Compare
Hey, thanks for the PR :) |
test_outside_container(spec, &|data| { | ||
test_result!(check_container_created(&data)); | ||
TestResult::Passed | ||
}) |
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.
Hey, here along with checking if the container is created, we also need validation for the created network cgroup resources - In the original test we call this function which does the validation, so need that here as well.
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.
Thank you.
Added validation for the created network cgroup resources.
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.
Hey, I don't think it is fixed yet. Let me clarify in case there is any confusion -
- In the original go test, at line https://github.com/opencontainers/runtime-tools/blob/master/validation/linux_cgroups_relative_network/linux_cgroups_relative_network.go#L24C1-L24C77, in the
test_outside_container
, they are passingutil.ValidateLinuxResourcesNetwork
function, which will do the validation that ok, the runtime has actually setup the relative network correctly. - The
util.ValidateLinuxResourcesNetwork
function defined at https://github.com/opencontainers/runtime-tools/blob/master/validation/util/linux_resources_network.go#L12 does the checking and validation of relative network cgroup. - The change you did in the last commit you pushed is actually almost a no-op. The original way of just calling the
test_outside_container
was correct, but also needs the cgroup checking logic as mentioned above.
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 added a new validate_network()
and changed the program to validate net_cls.classid and net_prio.ifpriomap.
However, network.rs only verifies check_container_created(&data)
.
Am I understanding this wrong?
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.
- validation of this test using runc is failing, can you check?
- If I'm correct, this is applicable only to cgroups v1, right?
let test_result = test_outside_container(spec.clone(), &|data| { | ||
test_result!(check_container_created(&data)); | ||
test_result!(validate_network(cgroup_name, &spec)); | ||
TestResult::Passed | ||
}); | ||
if let TestResult::Failed(_) = test_result { | ||
return test_result; | ||
} | ||
|
||
TestResult::Passed |
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.
You can just return the test_outside_container value like this -
let test_result = test_outside_container(spec.clone(), &|data| { | |
test_result!(check_container_created(&data)); | |
test_result!(validate_network(cgroup_name, &spec)); | |
TestResult::Passed | |
}); | |
if let TestResult::Failed(_) = test_result { | |
return test_result; | |
} | |
TestResult::Passed | |
test_outside_container(spec.clone(), &|data| { | |
test_result!(check_container_created(&data)); | |
test_result!(validate_network(cgroup_name, &spec)); | |
TestResult::Passed | |
}) |
The if let
part here is basically a no-op
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.
Unnecessary programs have been removed.
ca7ab449
let cgroup_path = PathBuf::from(CGROUP_ROOT) | ||
.join("net_cls,net_prio/runtime-test") | ||
.join(cgroup_name); |
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.
Is it ok to hard-code this here? I think in the can_run
below you mention the cgroup can be at a couple of different points.
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.
Address multiple network cgroup mount points.
Changed where to get paths for net_cls.classid
and net_prio.ifpriomap
.
ca7ab449
Signed-off-by: moz-sec <m0253c@gmail.com>
Signed-off-by: moz-sec <m0253c@gmail.com>
….ifpriomap Signed-off-by: moz-sec <m0253c@gmail.com>
Signed-off-by: moz-sec <m0253c@gmail.com>
2a8b217
to
ca7ab44
Compare
@YJDoc2 |
@YJDoc2 |
Hey @moz-sec , that makes sense. I have been busy for some time, and wasn't able to take more detailed look after your changes, apologies. Please go ahead with the implementation as discussed with utam0k. Do you plan to do it in this PR only, or a separate PR (I'm fine with either). Thanks :) |
@YJDoc2 |
Signed-off-by: moz-sec <m0253c@gmail.com>
Signed-off-by: moz-sec <m0253c@gmail.com>
@YJDoc2 |
Hey @moz-sec , apologies I haven't been able to take a look at this. I had been quite busy, and then got a bit sick, and currently just have a lot of things I need to work on 😅 I'll try my best to take a look at this as soon as possible. Sincere apologies, I should have done better managing this 🙏 @utam0k if I may ask of you, it would be great if you could help with reviewing this PR. Otherwise I'll get to this as soon as I can. |
Sure! |
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.
Thanks for your PR. I left some introductory comments. I'll return this week to review more details.
let (net_cls_path, net_prio_path) = if Path::new("/sys/fs/cgroup/net_cls/net_cls.classid") | ||
.exists() | ||
&& Path::new("/sys/fs/cgroup/net_prio/net_prio.ifpriomap").exists() | ||
{ | ||
( | ||
net_cls_path(PathBuf::from(CGROUP_ROOT).join("net_cls"), cgroup_name), | ||
net_prio_path(PathBuf::from(CGROUP_ROOT).join("net_prio"), cgroup_name), | ||
) | ||
} else if Path::new("/sys/fs/cgroup/net_cls,net_prio/net_cls.classid").exists() | ||
&& Path::new("/sys/fs/cgroup/net_cls,net_prio/net_prio.ifpriomap").exists() | ||
{ | ||
( | ||
net_cls_path( | ||
PathBuf::from(CGROUP_ROOT).join("net_cls,net_prio"), | ||
cgroup_name, | ||
), | ||
net_prio_path( | ||
PathBuf::from(CGROUP_ROOT).join("net_cls,net_prio"), | ||
cgroup_name, | ||
), | ||
) | ||
} else if Path::new("/sys/fs/cgroup/net_prio,net_cls/net_cls.classid").exists() | ||
&& Path::new("/sys/fs/cgroup/net_prio,net_cls/net_prio.ifpriomap").exists() | ||
{ | ||
( | ||
net_cls_path( | ||
PathBuf::from(CGROUP_ROOT).join("net_prio,net_cls"), | ||
cgroup_name, | ||
), | ||
net_prio_path( | ||
PathBuf::from(CGROUP_ROOT).join("net_prio,net_cls"), | ||
cgroup_name, | ||
), | ||
) | ||
} else { | ||
return Err(anyhow::anyhow!("Required cgroup paths do not exist")); | ||
}; |
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.
Please make each condition have a meaning, not only checking if the path exists.
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.
Each conditional branch will set net_cls_path to /sys/fs/cgroup/net_cls/net_cls.classid/test_network_cgroups
or /sys/fs/cgroup/net_cls,net_prio/net_cls.classid/test_network_cgroup
or /sys/fs/cgroup/net_prio,net_cls/net_cls.classid/network_cgroups
.
But looking at this alone, I too find this program confusing.
How can I write the same thing more neatly?
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 it would be simplest to just use sys/fs/cgroup/net_cls,net_prio/
, but looking at #39, do we still need to identify which directory it is mounted in and process it accordingly?
@@ -115,8 +116,12 @@ fn test_network_cgroups() -> TestResult { | |||
]; | |||
|
|||
for spec in cases.into_iter() { | |||
let test_result = test_outside_container(spec, &|data| { | |||
let test_result = test_outside_container(spec.clone(), &|data| { |
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.
Why is this change needed?
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.
In the case of spec
, ownership is passed to test_outside_container and I used spec.clone()
since I cannot use spec
on line 123.
let cgroup_name = "test_relative_network_cgroups"; | ||
|
||
let id = 255; | ||
let prio = 10; | ||
let if_name = "lo"; |
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.
Please use consts instead of normal values.
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.
For example, is it correct to write “const CGROUP_NAME: &str = ‘test_relative_network_cgroups’;`”?
|
||
// Gets the loopback interface if it exists | ||
fn get_loopback_interface() -> Option<String> { | ||
let interfaces = interfaces(); |
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 don't think this binding is needed.
fn create_spec(cgroup_name: &str, class_id: u32, prio: u32, if_name: &str) -> Result<Spec> { | ||
// Create the Linux Spec | ||
let linux_spec = LinuxBuilder::default() | ||
.cgroups_path(Path::new("testdir/runtime-test/container").join(cgroup_name)) |
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.
testdir/runtime-test/container
is duplicated with L66 in this file. How about passing cgroup path?
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 it is possible if I define it as a relative path (e.g. testdir/runtime-test/container/test_relative_network_cgroups
) in the cgroup_name variable.
However, looking at other existing test code, the cgroup path consists of /runtime
+ cgroup_name variable, and I wrote this to match.
Is there a cleaner way to write this?
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.
Thanks for your PR. I left some introductory comments. I'll return this week to review more details.
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.
Thanks for your PR. I left some introductory comments. I'll return this week to review more details.
For some reason, multiple copies were sent 😭 |
This implements the relative_network_cgroups validation in #361 .
I wrote it based on linux_cgroups_relative_network.go from
opencontainers/runtime-tools
and tests/cgroups/network.rs fromyouki-dev/youki
.