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 capnp map for tracing metadata #1498

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 26 additions & 8 deletions conmon-rs/common/proto/conmon.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ interface Conmon {
# Version
struct VersionRequest {
verbose @0 :Bool;
metadata @1 :Data;
metadataOld @1 :Data; # deprecated
mgjm marked this conversation as resolved.
Show resolved Hide resolved
metadata @2 :Metadata; # Standard metadata to carry.
}

struct VersionResponse {
Expand All @@ -18,7 +19,7 @@ interface Conmon {
rustVersion @6 :Text;
cargoVersion @7 :Text;
cargoTree @8 :Text;
metadata @9 :Data;
metadata @9 :Data; # deprecated (never used, remove in next major release)
}

version @0 (request: VersionRequest) -> (response: VersionResponse);
Expand All @@ -36,7 +37,8 @@ interface Conmon {
cleanupCmd @7 :List(Text);
globalArgs @8 :List(Text);
commandArgs @9 :List(Text);
metadata @10 :Data;
metadataOld @10 :Data; # deprecated
metadata @11 :Metadata; # Standard metadata to carry.
}

struct LogDriver {
Expand Down Expand Up @@ -68,7 +70,8 @@ interface Conmon {
timeoutSec @1 :UInt64;
command @2 :List(Text);
terminal @3 :Bool;
metadata @4 :Data;
metadataOld @4 :Data; # deprecated
metadata @5 :Metadata; # Standard metadata to carry.
}

struct ExecSyncContainerResponse {
Expand All @@ -87,7 +90,8 @@ interface Conmon {
socketPath @1 :Text;
execSessionId @2 :Text;
stopAfterStdinEof @3 :Bool;
metadata @4 :Data;
metadataOld @4 :Data; # deprecated
metadata @5 :Metadata; # Standard metadata to carry.
}

struct AttachResponse {
Expand All @@ -99,7 +103,8 @@ interface Conmon {
# ReopenLog
struct ReopenLogRequest {
id @0 :Text;
metadata @1 :Data;
metadataOld @1 :Data; # deprecated
metadata @2 :Metadata; # Standard metadata to carry.
}

struct ReopenLogResponse {
Expand All @@ -113,7 +118,9 @@ interface Conmon {
id @0 :Text; # container identifier
width @1 :UInt16; # columns in characters
height @2 :UInt16; # rows in characters
metadata @3 :Data;
metadataOld @3 :Data; # deprecated
metadata @4 :Metadata; # Standard metadata to carry.

}

struct SetWindowSizeResponse {
Expand All @@ -124,12 +131,13 @@ interface Conmon {
###############################################
# CreateNamespaces
struct CreateNamespacesRequest {
metadata @0 :Data; # Standard metadata to carry.
metadataOld @0 :Data; # deprecated
namespaces @1 :List(Namespace); # The list of namespaces to unshare.
uidMappings @2 :List(Text); # User ID mappings when unsharing the user namespace.
gidMappings @3 :List(Text); # Group ID mappings when unsharing the user namespace.
basePath @4 :Text; # The root path for storing the namespaces.
podId @5 :Text; # The pod identifier.
metadata @6 :Metadata; # Standard metadata to carry.
}

enum Namespace {
Expand All @@ -151,4 +159,14 @@ interface Conmon {
}

createNamespaces @6 (request: CreateNamespacesRequest) -> (response: CreateNamespacesResponse);

###############################################
# Helper types

using Metadata = TextTextMap;
using TextTextMap = List(TextTextMapEntry);
struct TextTextMapEntry {
key @0 :Text;
value @1 :Text;
}
}
1 change: 0 additions & 1 deletion conmon-rs/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ prctl = "1.0.0"
regex = "1.9.1"
sendfd = { version = "0.4.3", features = ["tokio"] }
serde = { version = "1.0.171", features = ["derive"] }
serde_json = "1.0.102"
shadow-rs = "=0.23.0"
signal-hook = "0.3.16"
strum = { version = "0.25.0", features = ["derive"] }
Expand Down
81 changes: 81 additions & 0 deletions conmon-rs/server/src/capnp_util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
pub(crate) use map_entry::into_map;

#[allow(unused)]
pub(crate) use map_entry::set_map;

/// Helper functions to convert between capnp maps (List's of MapEntries) and rust maps
mod map_entry {
use capnp::{
struct_list::{Builder, Reader},
traits::OwnedStruct,
};
use conmon_common::conmon_capnp::conmon;

/// Convert from a MapEntry capnp struct to a (key, value) tuple.
pub(crate) trait IntoKeyValue<'a, K, V>: OwnedStruct {
fn into_key_value(entry: Self::Reader<'a>) -> capnp::Result<(K, V)>;
}

/// Set the key and value properties of a MapEntry capnp struct.
pub(crate) trait SetKeyValue<K, V>: OwnedStruct {
fn set_key_value(entry: Self::Builder<'_>, key: K, value: V);
}

impl<'a, K, V> IntoKeyValue<'a, K, V> for conmon::text_text_map_entry::Owned
where
K: From<&'a str>,
V: From<&'a str>,
{
fn into_key_value(entry: Self::Reader<'a>) -> capnp::Result<(K, V)> {
Ok((entry.get_key()?.into(), entry.get_value()?.into()))
}
}

impl<K, V> SetKeyValue<K, V> for conmon::text_text_map_entry::Owned
where
K: AsRef<str>,
V: AsRef<str>,
{
fn set_key_value(mut entry: Self::Builder<'_>, key: K, value: V) {
entry.set_key(key.as_ref());
entry.set_value(value.as_ref());
}
}

/// Convert a capnp map reader (`struct_list::Reader`) into a rust map (`impl FromIterator<(K, V)>`).
pub(crate) fn into_map<'a, K, V, E, T>(reader: Reader<'a, E>) -> capnp::Result<T>
where
E: IntoKeyValue<'a, K, V>,
T: FromIterator<(K, V)>,
{
reader.into_iter().map(E::into_key_value).collect()
}

/// Set a capnp map property from a rust map (`impl IntoIterator<Item=(K, V)>`).
///
/// The `init` function is used to allocate a `struct_list::Builder`.
///
/// ## Example
/// Set the `exampleMap` property in the response capnp builder to the rust map `data`
/// ```ignore
/// set_from_map(data, |size| response.init_example_map(size));
/// ```
pub(crate) fn set_map<'a, K, V, E, T>(data: T, init: impl FnOnce(u32) -> Builder<'a, E>)
where
T: IntoIterator<Item = (K, V)>,
T::IntoIter: ExactSizeIterator,
E: SetKeyValue<K, V>,
{
let data = data.into_iter();
let size = if let Ok(size) = data.len().try_into() {
size
} else {
panic!("map with more then u32::MAX entries")
};
let mut list = init(size);
for (i, (key, value)) in data.enumerate() {
let entry = list.reborrow().get(i as u32);
E::set_key_value(entry, key, value);
}
}
}
1 change: 1 addition & 0 deletions conmon-rs/server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub use server::Server;
pub use version::Version;

mod attach;
mod capnp_util;
mod child;
mod child_reaper;
mod config;
Expand Down
9 changes: 6 additions & 3 deletions conmon-rs/server/src/telemetry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/// Open Telemetry related source code.
use crate::capnp_util;
use anyhow::{Context, Result};
use capnp::struct_list::Reader;
use clap::crate_name;
use conmon_common::conmon_capnp::conmon;
use nix::unistd::gethostname;
use opentelemetry::{
global,
Expand Down Expand Up @@ -63,13 +66,13 @@ impl Telemetry {
}

/// Set a new parent context from the provided slice data.
pub fn set_parent_context(slice: &'_ [u8]) -> Result<()> {
if slice.is_empty() {
pub fn set_parent_context(reader: Reader<conmon::text_text_map_entry::Owned>) -> Result<()> {
if reader.is_empty() {
// Make it a noop if no data is provided.
return Ok(());
}

let metadata = Metadata(serde_json::from_slice(slice).context("parse slice as JSON")?);
let metadata = Metadata(capnp_util::into_map(reader)?);
let ctx = global::get_text_map_propagator(|prop| prop.extract(&metadata));
Span::current().set_parent(ctx);

Expand Down
Loading
Loading