Skip to content
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

Use Aya in the userspace #142

Merged
merged 7 commits into from
Jan 26, 2022
Merged

Conversation

vadorovsky
Copy link
Member

@vadorovsky vadorovsky commented Jan 17, 2022

This change replaces libbpf-rs with Aya as a loader of eBPF programs in
the userspace part in lockc.

eBPF programs still remain written in C and are going to be rewritten in
Rust in separate changes.

Another change is change of logging library to tracing.

Fixes: #135
Fixes: #106
Signed-off-by: Michal Rostecki mrostecki@opensuse.org

@vadorovsky
Copy link
Member Author

vadorovsky commented Jan 17, 2022

I would say it's ready for review, since the code on lockc side is most likely not going to radically change.

Why I keep it as a draft? The problem is that we discovered some bugs in Aya, which has some troubles with loading lockc eBPF programs. For now we are using partial fixes from Dave Tucker's branch, not upstreamed yet:

https://github.com/dave-tucker/aya/tree/lockc

We are also discussing those problems every day on Aya Discord server (https://discord.gg/xHW2cb2N6G)

@vadorovsky vadorovsky changed the title Use Aya in the userspac Use Aya in the userspace Jan 17, 2022
@vadorovsky vadorovsky force-pushed the aya-userspace branch 4 times, most recently from 17cc60f to ed35f8f Compare January 18, 2022 23:23
@vadorovsky
Copy link
Member Author

It fully works and is ready for review! 🎉

So far it uses the following fork and branch of Aya:
https://github.com/dave-tucker/aya/tree/lockc

But all those fixes should land in the main branch soon.

@vadorovsky vadorovsky marked this pull request as ready for review January 18, 2022 23:29
@vadorovsky vadorovsky force-pushed the aya-userspace branch 3 times, most recently from 8eade52 to c50679d Compare January 19, 2022 17:33
Copy link
Collaborator

@flavio flavio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot comment about the BPF-related parts. As for the others, I left some comments.

Sorry for being pedantic about structured logging, I think it's super important to have it and it's something that must be enforced always while writing code

lockc/src/main.rs Outdated Show resolved Hide resolved
lockc/src/main.rs Outdated Show resolved Hide resolved
lockc/src/main.rs Outdated Show resolved Hide resolved
Comment on lines 122 to 193
let log_level = match env::var("LOCKC_DEBUG") {
Ok(_) => LevelFilter::Debug,
Err(_) => LevelFilter::Info,
};
Copy link
Collaborator

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 nice to handle all of that via clap, which allows both cli and env variables to be set. Plus it does many kind of checks and generates a nice help output.

This is something I would not do as part of this PR, but I would file an issue and work on that later on if I were you

Comment on lines 126 to 133
TermLogger::init(
LevelFilter::Debug,
ConfigBuilder::new()
.set_target_level(log_level)
.set_location_level(log_level)
.build(),
TerminalMode::Mixed,
ColorChoice::Auto,
)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another issue that could be filed for future work: it's pretty easy to use a JSON formatter that prints logs in a "machine-friendly" way.

I would offer the user a choice between two console output format: pretty/human and json. If you look into kubewarden/policy-server you can find the code to deal with that :)

.build()?
.block_on(self.add_container(container_id, pid, policy_level))?;

Ok(())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

lockc/src/runc.rs Outdated Show resolved Hide resolved
lockc/src/runc.rs Outdated Show resolved Hide resolved
lockc/src/sysutils.rs Show resolved Hide resolved
lockc/src/utils.rs Outdated Show resolved Hide resolved
@vadorovsky vadorovsky force-pushed the aya-userspace branch 2 times, most recently from 666f986 to 025fae4 Compare January 21, 2022 16:19
let mut id_b = CString::new(id)?.into_bytes_with_nul();
id_b.resize(CONTAINER_ID_LIMIT as usize, 0);
Ok(container_id {
id: id_b.try_into().unwrap(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not unwrap here, rather bubble up the error. This function already returns a Result

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason why I did unwrap here is that I didn't find any way to successfully convert TryInto errors into anything which can be listed in thiserror::Error enums. But it seems that the cleanest way to handle that will be converting TryInto error into some custom error with map_err. At least that's how this StackOverflow topic concludes:

https://stackoverflow.com/questions/66508331/cast-error-from-try-into-to-custom-error

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is what I would do. Eventually define a new error type with thiserror and then rely onmap_err to do the conversion

lockc/src/main.rs Show resolved Hide resolved
lockc/src/maps.rs Show resolved Hide resolved
lockc/src/maps.rs Show resolved Hide resolved
lockc/src/runc.rs Show resolved Hide resolved
lockc/src/runc.rs Outdated Show resolved Hide resolved
lockc/src/runc.rs Show resolved Hide resolved
lockc/src/runc.rs Outdated Show resolved Hide resolved
lockc/src/runc.rs Outdated Show resolved Hide resolved
@vadorovsky vadorovsky force-pushed the aya-userspace branch 6 times, most recently from 4c46033 to 7b8e79f Compare January 24, 2022 17:15
@vadorovsky
Copy link
Member Author

@flavio PTAL

To sum it up:

  • I changed the logging library to tracing, handled all levels and json/text formatter as clippy options
  • made log messages structured

What I didn't to was removal of Ok(()) lines. In the most of cases, changing foo()? to foo() as the last line of a method/function, the underlying error doesn't get converted to a thiserror::Error enum instance. To make it work, I would rather have to convert foo()? into foo().map_err(|e| MyErrorEnum::from(e))?. That seems uglier for me than just using foo()?; and Ok(()).

@vadorovsky vadorovsky force-pushed the aya-userspace branch 3 times, most recently from 92f3472 to eac6ed3 Compare January 25, 2022 15:16
Since we are dropping the usage of libbpf-rs, we are going to keep only
C source files (to be built directly with Clang).

Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
Follow up changes are goinng to handle container add/delete operations
in the userspace.

Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
We are going to dron the usage of libbpf-rs at all. The first step is to
remove libbpf-cargo dependency from our build. This change replaces it
with direct usage of clang and libbpf headers copied from libbpf-sys.

Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
BTF maps defined in SEC(".maps") are still bonkers in Aya. Let's switch
to SEC("maps/...") temporarily.

Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
@vadorovsky vadorovsky force-pushed the aya-userspace branch 2 times, most recently from 2ce4a93 to 204d92a Compare January 26, 2022 14:02
Comment on lines 106 to 107
bundle = bundle_path.display().to_string().as_str(),
config = config_path.display().to_string().as_str(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracing handles that in a nice way, there's no need to call display()...:

debug!(
  bundle = %bundle_path,
  config = ?config_path,
  "bundle uses display, while config uses debug");

This is documented here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Collaborator

@flavio flavio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good to me. There are some minor improvements that can be done, see the latest comment I left

This change replaces libbpf-rs with Aya as a loader of eBPF programs in
the userspace part in lockc.

eBPF programs still remain written in C and are going to be rewritten in
Rust in separate changes.

Another change is change of logging library to tracing.

Fixes: lockc-project#135
Fixes: lockc-project#106
Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
@vadorovsky vadorovsky merged commit c82d824 into lockc-project:main Jan 26, 2022
@vadorovsky vadorovsky deleted the aya-userspace branch January 26, 2022 16:33
vadorovsky added a commit to vadorovsky/lockc that referenced this pull request Jan 26, 2022
In pull request lockc-project#142 we made a mistake of converting lockc into full
binary crate, therefore renaming lockcd to lockc and removing a
possibility of creating multiple binaries (if there will be a need -
i.e. for some CLI tool).

This change fixes that by creating a bin/ directory with binaries again.

Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
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.

Try to use aya only in userspce (as the 1st step) use tracing for logging
2 participants