diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 5aed5e4f1..ca2db149c 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -158,13 +158,14 @@ jobs:
- name: download-and-upload-tarball
env:
GITHUB_TOKEN: ${{ secrets.GIT_UPLOAD_TOKEN }}
+ GOPATH: ${HOME}/go
run: |
pushd $GITHUB_WORKSPACE
./ci/install_yq.sh
tag=$(echo $GITHUB_REF | cut -d/ -f3-)
versions_yaml="versions.yaml"
- version=$(yq read ${versions_yaml} "externals.libseccomp.version")
- repo_url=$(yq read ${versions_yaml} "externals.libseccomp.url")
+ version=$(${GOPATH}/bin/yq read ${versions_yaml} "externals.libseccomp.version")
+ repo_url=$(${GOPATH}/bin/yq read ${versions_yaml} "externals.libseccomp.url")
download_url="${repo_url}/releases/download/v${version}"
tarball="libseccomp-${version}.tar.gz"
asc="${tarball}.asc"
diff --git a/.github/workflows/static-checks.yaml b/.github/workflows/static-checks.yaml
index cb37e33b3..25618ff85 100644
--- a/.github/workflows/static-checks.yaml
+++ b/.github/workflows/static-checks.yaml
@@ -13,7 +13,7 @@ jobs:
test:
strategy:
matrix:
- go-version: [1.15.x, 1.16.x]
+ go-version: [1.16.x, 1.17.x]
os: [ubuntu-20.04]
runs-on: ${{ matrix.os }}
env:
diff --git a/docs/design/data/metrics.yaml b/docs/design/data/metrics.yaml
index 4ff801d88..51bcdb8cf 100644
--- a/docs/design/data/metrics.yaml
+++ b/docs/design/data/metrics.yaml
@@ -1825,12 +1825,8 @@ components:
desc: ""
- value: grpc.StartContainerRequest
desc: ""
- - value: grpc.StartTracingRequest
- desc: ""
- value: grpc.StatsContainerRequest
desc: ""
- - value: grpc.StopTracingRequest
- desc: ""
- value: grpc.TtyWinResizeRequest
desc: ""
- value: grpc.UpdateContainerRequest
diff --git a/docs/design/kata-2-0-metrics.md b/docs/design/kata-2-0-metrics.md
index 8adf3d9b5..8654fa507 100644
--- a/docs/design/kata-2-0-metrics.md
+++ b/docs/design/kata-2-0-metrics.md
@@ -207,7 +207,7 @@ Metrics for Firecracker vmm.
| `kata_firecracker_uart`:
Metrics specific to the UART device. | `GAUGE` | |
- `item`
- `error_count`
- `flush_count`
- `missed_read_count`
- `missed_write_count`
- `read_count`
- `write_count`
- `sandbox_id`
| 2.0.0 |
| `kata_firecracker_vcpu`:
Metrics specific to VCPUs' mode of functioning. | `GAUGE` | | - `item`
- `exit_io_in`
- `exit_io_out`
- `exit_mmio_read`
- `exit_mmio_write`
- `failures`
- `filter_cpuid`
- `sandbox_id`
| 2.0.0 |
| `kata_firecracker_vmm`:
Metrics specific to the machine manager as a whole. | `GAUGE` | | - `item`
- `device_events`
- `panic_count`
- `sandbox_id`
| 2.0.0 |
-| `kata_firecracker_vsock`:
Vsock-related metrics. | `GAUGE` | | - `item`
- `activate_fails`
- `cfg_fails`
- `conn_event_fails`
- `conns_added`
- `conns_killed`
- `conns_removed`
- `ev_queue_event_fails`
- `killq_resync`
- `muxer_event_fails`
- `rx_bytes_count`
- `rx_packets_count`
- `rx_queue_event_count`
- `rx_queue_event_fails`
- `rx_read_fails`
- `tx_bytes_count`
- `tx_flush_fails`
- `tx_packets_count`
- `tx_queue_event_count`
- `tx_queue_event_fails`
- `tx_write_fails`
- `sandbox_id`
| 2.0.0 |
+| `kata_firecracker_vsock`:
VSOCK-related metrics. | `GAUGE` | | - `item`
- `activate_fails`
- `cfg_fails`
- `conn_event_fails`
- `conns_added`
- `conns_killed`
- `conns_removed`
- `ev_queue_event_fails`
- `killq_resync`
- `muxer_event_fails`
- `rx_bytes_count`
- `rx_packets_count`
- `rx_queue_event_count`
- `rx_queue_event_fails`
- `rx_read_fails`
- `tx_bytes_count`
- `tx_flush_fails`
- `tx_packets_count`
- `tx_queue_event_count`
- `tx_queue_event_fails`
- `tx_write_fails`
- `sandbox_id`
| 2.0.0 |
### Kata guest OS metrics
@@ -288,7 +288,7 @@ Metrics about Kata containerd shim v2 process.
| Metric name | Type | Units | Labels | Introduced in Kata version |
|---|---|---|---|---|
-| `kata_shim_agent_rpc_durations_histogram_milliseconds`:
RPC latency distributions. | `HISTOGRAM` | `milliseconds` | - `action` (RPC actions of Kata agent)
- `grpc.CheckRequest`
- `grpc.CloseStdinRequest`
- `grpc.CopyFileRequest`
- `grpc.CreateContainerRequest`
- `grpc.CreateSandboxRequest`
- `grpc.DestroySandboxRequest`
- `grpc.ExecProcessRequest`
- `grpc.GetMetricsRequest`
- `grpc.GuestDetailsRequest`
- `grpc.ListInterfacesRequest`
- `grpc.ListProcessesRequest`
- `grpc.ListRoutesRequest`
- `grpc.MemHotplugByProbeRequest`
- `grpc.OnlineCPUMemRequest`
- `grpc.PauseContainerRequest`
- `grpc.RemoveContainerRequest`
- `grpc.ReseedRandomDevRequest`
- `grpc.ResumeContainerRequest`
- `grpc.SetGuestDateTimeRequest`
- `grpc.SignalProcessRequest`
- `grpc.StartContainerRequest`
- `grpc.StartTracingRequest`
- `grpc.StatsContainerRequest`
- `grpc.StopTracingRequest`
- `grpc.TtyWinResizeRequest`
- `grpc.UpdateContainerRequest`
- `grpc.UpdateInterfaceRequest`
- `grpc.UpdateRoutesRequest`
- `grpc.WaitProcessRequest`
- `grpc.WriteStreamRequest`
- `sandbox_id`
| 2.0.0 |
+| `kata_shim_agent_rpc_durations_histogram_milliseconds`:
RPC latency distributions. | `HISTOGRAM` | `milliseconds` | - `action` (RPC actions of Kata agent)
- `grpc.CheckRequest`
- `grpc.CloseStdinRequest`
- `grpc.CopyFileRequest`
- `grpc.CreateContainerRequest`
- `grpc.CreateSandboxRequest`
- `grpc.DestroySandboxRequest`
- `grpc.ExecProcessRequest`
- `grpc.GetMetricsRequest`
- `grpc.GuestDetailsRequest`
- `grpc.ListInterfacesRequest`
- `grpc.ListProcessesRequest`
- `grpc.ListRoutesRequest`
- `grpc.MemHotplugByProbeRequest`
- `grpc.OnlineCPUMemRequest`
- `grpc.PauseContainerRequest`
- `grpc.RemoveContainerRequest`
- `grpc.ReseedRandomDevRequest`
- `grpc.ResumeContainerRequest`
- `grpc.SetGuestDateTimeRequest`
- `grpc.SignalProcessRequest`
- `grpc.StartContainerRequest`
- `grpc.StatsContainerRequest`
- `grpc.TtyWinResizeRequest`
- `grpc.UpdateContainerRequest`
- `grpc.UpdateInterfaceRequest`
- `grpc.UpdateRoutesRequest`
- `grpc.WaitProcessRequest`
- `grpc.WriteStreamRequest`
- `sandbox_id`
| 2.0.0 |
| `kata_shim_fds`:
Kata containerd shim v2 open FDs. | `GAUGE` | | | 2.0.0 |
| `kata_shim_go_gc_duration_seconds`:
A summary of the pause duration of garbage collection cycles. | `SUMMARY` | `seconds` | | 2.0.0 |
| `kata_shim_go_goroutines`:
Number of goroutines that currently exist. | `GAUGE` | | | 2.0.0 |
diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock
index 2988b73b9..0b320adb2 100644
--- a/src/agent/Cargo.lock
+++ b/src/agent/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
-version = "0.15.1"
+version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03345e98af8f3d786b6d9f656ccfa6ac316d954e92bc4841f0bba20789d5fb5a"
+checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
dependencies = [
"gimli",
]
@@ -83,9 +83,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
-version = "0.3.59"
+version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4717cfcbfaa661a0fd48f8453951837ae7e8f81e481fbb136e3202d72805a744"
+checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01"
dependencies = [
"addr2line",
"cc",
@@ -414,15 +414,15 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.24.0"
+version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
+checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
[[package]]
name = "heck"
-version = "0.3.2"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
@@ -871,9 +871,12 @@ dependencies = [
[[package]]
name = "object"
-version = "0.24.0"
+version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170"
+checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
+dependencies = [
+ "memchr",
+]
[[package]]
name = "oci"
@@ -1138,6 +1141,10 @@ name = "protobuf"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485"
+dependencies = [
+ "serde",
+ "serde_derive",
+]
[[package]]
name = "protobuf-codegen"
@@ -1164,6 +1171,8 @@ version = "0.1.0"
dependencies = [
"async-trait",
"protobuf",
+ "serde",
+ "serde_json",
"ttrpc",
"ttrpc-codegen",
]
@@ -1304,9 +1313,9 @@ dependencies = [
[[package]]
name = "rustc-demangle"
-version = "0.1.19"
+version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
+checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustjail"
@@ -1364,18 +1373,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
-version = "1.0.129"
+version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1"
+checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.129"
+version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3"
+checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
dependencies = [
"proc-macro2 1.0.26",
"quote 1.0.9",
@@ -1384,9 +1393,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.64"
+version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
+checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
dependencies = [
"itoa",
"ryu",
@@ -1804,9 +1813,9 @@ dependencies = [
[[package]]
name = "unicode-segmentation"
-version = "1.7.1"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
+checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-xid"
diff --git a/src/agent/protocols/Cargo.toml b/src/agent/protocols/Cargo.toml
index 447393646..ae93e7fa1 100644
--- a/src/agent/protocols/Cargo.toml
+++ b/src/agent/protocols/Cargo.toml
@@ -4,10 +4,16 @@ version = "0.1.0"
authors = ["The Kata Containers community "]
edition = "2018"
+[features]
+default = []
+with-serde = [ "serde", "serde_json" ]
+
[dependencies]
ttrpc = { version = "0.5.0", features = ["async"] }
async-trait = "0.1.42"
-protobuf = "=2.14.0"
+protobuf = { version = "=2.14.0", features = ["with-serde"] }
+serde = { version = "1.0.130", features = ["derive"], optional = true }
+serde_json = { version = "1.0.68", optional = true }
[build-dependencies]
ttrpc-codegen = "0.2.0"
diff --git a/src/agent/protocols/build.rs b/src/agent/protocols/build.rs
index 03fd80b7d..d78f79f80 100644
--- a/src/agent/protocols/build.rs
+++ b/src/agent/protocols/build.rs
@@ -3,30 +3,149 @@
// SPDX-License-Identifier: Apache-2.0
//
-use std::fs;
-use ttrpc_codegen::{Codegen, Customize};
+use std::fs::File;
+use std::io::{BufRead, BufReader, Read, Write};
+use std::path::Path;
+use std::process::exit;
+use ttrpc_codegen::{Codegen, Customize, ProtobufCustomize};
+
+fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<(), std::io::Error> {
+ let mut src = File::open(file_name)?;
+ let mut contents = String::new();
+ src.read_to_string(&mut contents).unwrap();
+ drop(src);
+
+ let new_contents = contents.replace(from, to);
+
+ let mut dst = File::create(&file_name)?;
+ dst.write_all(new_contents.as_bytes())?;
+
+ Ok(())
+}
+
+fn use_serde(protos: &[&str], out_dir: &Path) -> Result<(), std::io::Error> {
+ protos
+ .iter()
+ .try_for_each(|f: &&str| -> Result<(), std::io::Error> {
+ let out_file = Path::new(f)
+ .file_name()
+ .and_then(|s| s.to_str())
+ .ok_or(format!("failed to get proto file name for {:?}", f))
+ .map(|s| {
+ let t = s.replace(".proto", ".rs");
+ out_dir.join(t)
+ })
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
+ .to_str()
+ .ok_or(format!("cannot convert {:?} path to string", f))
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
+ .to_string();
+
+ replace_text_in_file(
+ &out_file,
+ "derive(Serialize, Deserialize)",
+ "derive(serde::Serialize, serde::Deserialize)",
+ )
+ })
+}
+
+fn handle_file(autogen_comment: &str, rust_filename: &str) -> Result<(), std::io::Error> {
+ let mut new_contents = Vec::new();
+
+ let file = File::open(rust_filename)?;
+
+ let reader = BufReader::new(file);
+
+ // Guard the code since it is only needed for the agent-ctl tool,
+ // not the agent itself.
+ let serde_default_code = r#"#[cfg_attr(feature = "with-serde", serde(default))]"#;
+
+ for line in reader.lines() {
+ let line = line?;
+
+ new_contents.push(line.clone());
+
+ let pattern = "//! Generated file from";
+
+ if line.starts_with(&pattern) {
+ new_contents.push(autogen_comment.into());
+ }
+
+ let struct_pattern = "pub struct ";
+
+ // Although we've requested serde support via `Customize`, to
+ // allow the `kata-agent-ctl` tool to partially deserialise structures
+ // specified in JSON, we need this bit of additional magic.
+ if line.starts_with(&struct_pattern) {
+ new_contents.insert(new_contents.len() - 1, serde_default_code.trim().into());
+ }
+ }
+
+ let data = new_contents.join("\n");
+
+ let mut dst = File::create(&rust_filename)?;
+
+ dst.write_all(data.as_bytes())?;
+
+ Ok(())
+}
+
+fn real_main() -> Result<(), std::io::Error> {
+ let autogen_comment = format!("\n//! Generated by {:?} ({:?})", file!(), module_path!());
-fn main() {
let protos = vec![
- "protos/types.proto",
"protos/agent.proto",
- "protos/health.proto",
"protos/google/protobuf/empty.proto",
+ "protos/health.proto",
"protos/oci.proto",
+ "protos/types.proto",
"protos/image.proto",
];
+ // Tell Cargo that if the .proto files changed, to rerun this build script.
+ protos
+ .iter()
+ .for_each(|p| println!("cargo:rerun-if-changed={}", &p));
+
+ let ttrpc_options = Customize {
+ async_server: true,
+ ..Default::default()
+ };
+
+ let protobuf_options = ProtobufCustomize {
+ serde_derive: Some(true),
+ ..Default::default()
+ };
+
+ let out_dir = Path::new("src");
+
Codegen::new()
- .out_dir("src")
+ .out_dir(out_dir)
.inputs(&protos)
.include("protos")
+ .customize(ttrpc_options)
.rust_protobuf()
- .customize(Customize {
- async_server: true,
- ..Default::default()
- })
- .run()
- .expect("Gen codes failed.");
+ .rust_protobuf_customize(protobuf_options)
+ .run()?;
+
+ for file in protos.iter() {
+ let proto_filename = Path::new(file).file_name().unwrap();
+
+ let generated_file = proto_filename
+ .to_str()
+ .ok_or("failed")
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
+ .replace(".proto", ".rs");
+
+ let out_file = out_dir.join(generated_file);
+
+ let out_file_str = out_file
+ .to_str()
+ .ok_or("failed")
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
+
+ handle_file(&autogen_comment, out_file_str)?;
+ }
// There is a message named 'Box' in oci.proto
// so there is a struct named 'Box', we should replace Box to ::std::boxed::Box
@@ -35,11 +154,16 @@ fn main() {
"src/oci.rs",
"self: Box",
"self: ::std::boxed::Box",
- )
- .unwrap();
+ )?;
+
+ use_serde(&protos, out_dir)?;
+
+ Ok(())
}
-fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<(), std::io::Error> {
- let new_contents = fs::read_to_string(file_name)?.replace(from, to);
- fs::write(&file_name, new_contents.as_bytes())
+fn main() {
+ if let Err(e) = real_main() {
+ eprintln!("ERROR: {}", e);
+ exit(1);
+ }
}
diff --git a/src/agent/protocols/protos/agent.proto b/src/agent/protocols/protos/agent.proto
index c29ef7ebc..ede77ec0f 100644
--- a/src/agent/protocols/protos/agent.proto
+++ b/src/agent/protocols/protos/agent.proto
@@ -52,8 +52,6 @@ service AgentService {
rpc AddARPNeighbors(AddARPNeighborsRequest) returns (google.protobuf.Empty);
// observability
- rpc StartTracing(StartTracingRequest) returns (google.protobuf.Empty);
- rpc StopTracing(StopTracingRequest) returns (google.protobuf.Empty);
rpc GetMetrics(GetMetricsRequest) returns (Metrics);
// misc (TODO: some rpcs can be replaced by hyperstart-exec)
@@ -492,12 +490,6 @@ message CopyFileRequest {
bytes data = 8;
}
-message StartTracingRequest {
-}
-
-message StopTracingRequest {
-}
-
message GetOOMEventRequest {}
message OOMEvent {
diff --git a/src/agent/rustjail/src/container.rs b/src/agent/rustjail/src/container.rs
index 03ad66287..dce4c68ef 100644
--- a/src/agent/rustjail/src/container.rs
+++ b/src/agent/rustjail/src/container.rs
@@ -636,11 +636,10 @@ fn do_init_child(cwfd: RawFd) -> Result<()> {
// setup the envs
for e in env.iter() {
- let v: Vec<&str> = e.splitn(2, '=').collect();
- if v.len() != 2 {
- continue;
+ match valid_env(e) {
+ Some((key, value)) => env::set_var(key, value),
+ None => log_child!(cfd_log, "invalid env key-value: {:?}", e),
}
- env::set_var(v[0], v[1]);
}
// set the "HOME" env getting from "/etc/passwd", if
@@ -995,8 +994,6 @@ impl BaseContainer for LinuxContainer {
info!(logger, "entered namespaces!");
- self.created = SystemTime::now();
-
if p.init {
let spec = self.config.spec.as_mut().unwrap();
update_namespaces(&self.logger, spec, p.pid)?;
@@ -1565,6 +1562,30 @@ async fn execute_hook(logger: &Logger, h: &Hook, st: &OCIState) -> Result<()> {
}
}
+// valid environment variables according to https://doc.rust-lang.org/std/env/fn.set_var.html#panics
+fn valid_env(e: &str) -> Option<(&str, &str)> {
+ // wherther key or value will contain NULL char.
+ if e.as_bytes().contains(&b'\0') {
+ return None;
+ }
+
+ let v: Vec<&str> = e.splitn(2, '=').collect();
+
+ // key can't hold an `equal` sign, but value can
+ if v.len() != 2 {
+ return None;
+ }
+
+ let (key, value) = (v[0].trim(), v[1].trim());
+
+ // key can't be empty
+ if key.is_empty() {
+ return None;
+ }
+
+ Some((key, value))
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -1988,4 +2009,49 @@ mod tests {
let ret = do_init_child(std::io::stdin().as_raw_fd());
assert!(ret.is_err(), "Expecting Err, Got {:?}", ret);
}
+
+ #[test]
+ fn test_valid_env() {
+ let env = valid_env("a=b=c");
+ assert_eq!(Some(("a", "b=c")), env);
+
+ let env = valid_env("a=b");
+ assert_eq!(Some(("a", "b")), env);
+ let env = valid_env("a =b");
+ assert_eq!(Some(("a", "b")), env);
+
+ let env = valid_env(" a =b");
+ assert_eq!(Some(("a", "b")), env);
+
+ let env = valid_env("a= b");
+ assert_eq!(Some(("a", "b")), env);
+
+ let env = valid_env("a=b ");
+ assert_eq!(Some(("a", "b")), env);
+ let env = valid_env("a=b c ");
+ assert_eq!(Some(("a", "b c")), env);
+
+ let env = valid_env("=b");
+ assert_eq!(None, env);
+
+ let env = valid_env("a=");
+ assert_eq!(Some(("a", "")), env);
+
+ let env = valid_env("a==");
+ assert_eq!(Some(("a", "=")), env);
+
+ let env = valid_env("a");
+ assert_eq!(None, env);
+
+ let invalid_str = vec![97, b'\0', 98];
+ let invalid_string = std::str::from_utf8(&invalid_str).unwrap();
+
+ let invalid_env = format!("{}=value", invalid_string);
+ let env = valid_env(&invalid_env);
+ assert_eq!(None, env);
+
+ let invalid_env = format!("key={}", invalid_string);
+ let env = valid_env(&invalid_env);
+ assert_eq!(None, env);
+ }
}
diff --git a/src/agent/samples/configuration-all-endpoints.toml b/src/agent/samples/configuration-all-endpoints.toml
index 1ef6cac35..1c8b01367 100644
--- a/src/agent/samples/configuration-all-endpoints.toml
+++ b/src/agent/samples/configuration-all-endpoints.toml
@@ -29,9 +29,7 @@ allowed = [
"SetGuestDateTimeRequest",
"SignalProcessRequest",
"StartContainerRequest",
- "StartTracingRequest",
"StatsContainerRequest",
- "StopTracingRequest",
"TtyWinResizeRequest",
"UpdateContainerRequest",
"UpdateInterfaceRequest",
diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs
index abc41d0c0..5cbbaa0c9 100644
--- a/src/agent/src/rpc.rs
+++ b/src/agent/src/rpc.rs
@@ -943,25 +943,6 @@ impl protocols::agent_ttrpc::AgentService for AgentService {
})
}
- async fn start_tracing(
- &self,
- _ctx: &TtrpcContext,
- req: protocols::agent::StartTracingRequest,
- ) -> ttrpc::Result {
- info!(sl!(), "start_tracing {:?}", req);
- is_allowed!(req);
- Ok(Empty::new())
- }
-
- async fn stop_tracing(
- &self,
- _ctx: &TtrpcContext,
- req: protocols::agent::StopTracingRequest,
- ) -> ttrpc::Result {
- is_allowed!(req);
- Ok(Empty::new())
- }
-
async fn create_sandbox(
&self,
ctx: &TtrpcContext,
diff --git a/src/runtime/go.mod b/src/runtime/go.mod
index 97a6b6c31..198a101fb 100644
--- a/src/runtime/go.mod
+++ b/src/runtime/go.mod
@@ -9,6 +9,7 @@ require (
github.com/containerd/cgroups v1.0.1
github.com/containerd/console v1.0.2
github.com/containerd/containerd v1.5.7
+ github.com/containerd/cri-containerd v1.11.1-0.20190125013620-4dd6735020f5
github.com/containerd/fifo v1.0.0
github.com/containerd/ttrpc v1.0.2
github.com/containerd/typeurl v1.0.2
diff --git a/src/runtime/go.sum b/src/runtime/go.sum
index c8b123f99..14f90c917 100644
--- a/src/runtime/go.sum
+++ b/src/runtime/go.sum
@@ -111,6 +111,8 @@ github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8a
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
+github.com/containerd/cri-containerd v1.11.1-0.20190125013620-4dd6735020f5 h1:/srF029I+oDfm/qeltxCGJyJ8urmlqWGOQmQ7HvwrRc=
+github.com/containerd/cri-containerd v1.11.1-0.20190125013620-4dd6735020f5/go.mod h1:wxbGdReWGCalzGOEpifoHeYCK4xAgnj4o/4bVB+9voU=
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
diff --git a/src/runtime/pkg/containerd-shim-v2/create.go b/src/runtime/pkg/containerd-shim-v2/create.go
index ce0998126..3a0814e86 100644
--- a/src/runtime/pkg/containerd-shim-v2/create.go
+++ b/src/runtime/pkg/containerd-shim-v2/create.go
@@ -27,11 +27,10 @@ import (
"github.com/pkg/errors"
// only register the proto type
+ crioption "github.com/containerd/containerd/pkg/runtimeoptions/v1"
_ "github.com/containerd/containerd/runtime/linux/runctypes"
_ "github.com/containerd/containerd/runtime/v2/runc/options"
-
- crioption "github.com/containerd/containerd/pkg/runtimeoptions/v1"
- oldcrioption "github.com/containerd/containerd/pkg/runtimeoptions/v1"
+ oldcrioption "github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils/katatrace"
diff --git a/src/runtime/pkg/containerd-shim-v2/create_test.go b/src/runtime/pkg/containerd-shim-v2/create_test.go
index 294a191a7..5ad96f149 100644
--- a/src/runtime/pkg/containerd-shim-v2/create_test.go
+++ b/src/runtime/pkg/containerd-shim-v2/create_test.go
@@ -15,8 +15,8 @@ import (
"testing"
"github.com/containerd/containerd/namespaces"
- crioption "github.com/containerd/containerd/pkg/runtimeoptions/v1"
taskAPI "github.com/containerd/containerd/runtime/v2/task"
+ crioption "github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1"
"github.com/containerd/typeurl"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
diff --git a/src/runtime/vendor/github.com/containerd/containerd/pkg/cri/annotations/annotations.go b/src/runtime/vendor/github.com/containerd/containerd/pkg/cri/annotations/annotations.go
deleted file mode 100644
index 68a0f4837..000000000
--- a/src/runtime/vendor/github.com/containerd/containerd/pkg/cri/annotations/annotations.go
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Copyright The containerd Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-package annotations
-
-// ContainerType values
-// Following OCI annotations are used by katacontainers now.
-// We'll switch to standard secure pod API after it is defined in CRI.
-const (
- // ContainerTypeSandbox represents a pod sandbox container
- ContainerTypeSandbox = "sandbox"
-
- // ContainerTypeContainer represents a container running within a pod
- ContainerTypeContainer = "container"
-
- // ContainerType is the container type (sandbox or container) annotation
- ContainerType = "io.kubernetes.cri.container-type"
-
- // SandboxID is the sandbox ID annotation
- SandboxID = "io.kubernetes.cri.sandbox-id"
-
- // SandboxLogDir is the pod log directory annotation.
- // If the sandbox needs to generate any log, it will put it into this directory.
- // Kubelet will be responsible for:
- // 1) Monitoring the disk usage of the log, and including it as part of the pod
- // ephemeral storage usage.
- // 2) Cleaning up the logs when the pod is deleted.
- // NOTE: Kubelet is not responsible for rotating the logs.
- SandboxLogDir = "io.kubernetes.cri.sandbox-log-directory"
-
- // UntrustedWorkload is the sandbox annotation for untrusted workload. Untrusted
- // workload can only run on dedicated runtime for untrusted workload.
- UntrustedWorkload = "io.kubernetes.cri.untrusted-workload"
-
- // SandboxNamespace is the name of the namespace of the sandbox (pod)
- SandboxNamespace = "io.kubernetes.cri.sandbox-namespace"
-
- // SandboxName is the name of the sandbox (pod)
- SandboxName = "io.kubernetes.cri.sandbox-name"
-
- // ContainerName is the name of the container in the pod
- ContainerName = "io.kubernetes.cri.container-name"
-
- // ImageName is the name of the image used to create the container
- ImageName = "io.kubernetes.cri.image-name"
-
- // PodAnnotations are the annotations of the pod
- PodAnnotations = "io.kubernetes.cri.pod-annotations"
-)
diff --git a/src/runtime/vendor/github.com/containerd/cri-containerd/LICENSE b/src/runtime/vendor/github.com/containerd/cri-containerd/LICENSE
new file mode 100644
index 000000000..8dada3eda
--- /dev/null
+++ b/src/runtime/vendor/github.com/containerd/cri-containerd/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/annotations/annotations.go b/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/annotations/annotations.go
new file mode 100644
index 000000000..be63ba27a
--- /dev/null
+++ b/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/annotations/annotations.go
@@ -0,0 +1,38 @@
+/*
+Copyright 2018 The Containerd Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package annotations
+
+// ContainerType values
+// Following OCI annotations are used by katacontainers now.
+// We'll switch to standard secure pod API after it is defined in CRI.
+const (
+ // ContainerTypeSandbox represents a pod sandbox container
+ ContainerTypeSandbox = "sandbox"
+
+ // ContainerTypeContainer represents a container running within a pod
+ ContainerTypeContainer = "container"
+
+ // ContainerType is the container type (sandbox or container) annotation
+ ContainerType = "io.kubernetes.cri.container-type"
+
+ // SandboxID is the sandbox ID annotation
+ SandboxID = "io.kubernetes.cri.sandbox-id"
+
+ // UntrustedWorkload is the sandbox annotation for untrusted workload. Untrusted
+ // workload can only run on dedicated runtime for untrusted workload.
+ UntrustedWorkload = "io.kubernetes.cri.untrusted-workload"
+)
diff --git a/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1/api.pb.go b/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1/api.pb.go
new file mode 100644
index 000000000..71341ec78
--- /dev/null
+++ b/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1/api.pb.go
@@ -0,0 +1,394 @@
+/*
+Copyright 2019 The containerd Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: api.proto
+
+/*
+ Package cri_runtimeoptions_v1 is a generated protocol buffer package.
+
+ It is generated from these files:
+ api.proto
+
+ It has these top-level messages:
+ Options
+*/
+package cri_runtimeoptions_v1
+
+import proto "github.com/gogo/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import _ "github.com/gogo/protobuf/gogoproto"
+
+import strings "strings"
+import reflect "reflect"
+
+import io "io"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
+type Options struct {
+ // TypeUrl specifies the type of the content inside the config file.
+ TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
+ // ConfigPath specifies the filesystem location of the config file
+ // used by the runtime.
+ ConfigPath string `protobuf:"bytes,2,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"`
+}
+
+func (m *Options) Reset() { *m = Options{} }
+func (*Options) ProtoMessage() {}
+func (*Options) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} }
+
+func (m *Options) GetTypeUrl() string {
+ if m != nil {
+ return m.TypeUrl
+ }
+ return ""
+}
+
+func (m *Options) GetConfigPath() string {
+ if m != nil {
+ return m.ConfigPath
+ }
+ return ""
+}
+
+func init() {
+ proto.RegisterType((*Options)(nil), "cri.runtimeoptions.v1.Options")
+}
+func (m *Options) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalTo(dAtA)
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *Options) MarshalTo(dAtA []byte) (int, error) {
+ var i int
+ _ = i
+ var l int
+ _ = l
+ if len(m.TypeUrl) > 0 {
+ dAtA[i] = 0xa
+ i++
+ i = encodeVarintApi(dAtA, i, uint64(len(m.TypeUrl)))
+ i += copy(dAtA[i:], m.TypeUrl)
+ }
+ if len(m.ConfigPath) > 0 {
+ dAtA[i] = 0x12
+ i++
+ i = encodeVarintApi(dAtA, i, uint64(len(m.ConfigPath)))
+ i += copy(dAtA[i:], m.ConfigPath)
+ }
+ return i, nil
+}
+
+func encodeVarintApi(dAtA []byte, offset int, v uint64) int {
+ for v >= 1<<7 {
+ dAtA[offset] = uint8(v&0x7f | 0x80)
+ v >>= 7
+ offset++
+ }
+ dAtA[offset] = uint8(v)
+ return offset + 1
+}
+func (m *Options) Size() (n int) {
+ var l int
+ _ = l
+ l = len(m.TypeUrl)
+ if l > 0 {
+ n += 1 + l + sovApi(uint64(l))
+ }
+ l = len(m.ConfigPath)
+ if l > 0 {
+ n += 1 + l + sovApi(uint64(l))
+ }
+ return n
+}
+
+func sovApi(x uint64) (n int) {
+ for {
+ n++
+ x >>= 7
+ if x == 0 {
+ break
+ }
+ }
+ return n
+}
+func sozApi(x uint64) (n int) {
+ return sovApi(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+func (this *Options) String() string {
+ if this == nil {
+ return "nil"
+ }
+ s := strings.Join([]string{`&Options{`,
+ `TypeUrl:` + fmt.Sprintf("%v", this.TypeUrl) + `,`,
+ `ConfigPath:` + fmt.Sprintf("%v", this.ConfigPath) + `,`,
+ `}`,
+ }, "")
+ return s
+}
+func valueToStringApi(v interface{}) string {
+ rv := reflect.ValueOf(v)
+ if rv.IsNil() {
+ return "nil"
+ }
+ pv := reflect.Indirect(rv).Interface()
+ return fmt.Sprintf("*%v", pv)
+}
+func (m *Options) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: Options: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field TypeUrl", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthApi
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.TypeUrl = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field ConfigPath", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthApi
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.ConfigPath = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipApi(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if skippy < 0 {
+ return ErrInvalidLengthApi
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func skipApi(dAtA []byte) (n int, err error) {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ wireType := int(wire & 0x7)
+ switch wireType {
+ case 0:
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ iNdEx++
+ if dAtA[iNdEx-1] < 0x80 {
+ break
+ }
+ }
+ return iNdEx, nil
+ case 1:
+ iNdEx += 8
+ return iNdEx, nil
+ case 2:
+ var length int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ length |= (int(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ iNdEx += length
+ if length < 0 {
+ return 0, ErrInvalidLengthApi
+ }
+ return iNdEx, nil
+ case 3:
+ for {
+ var innerWire uint64
+ var start int = iNdEx
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return 0, ErrIntOverflowApi
+ }
+ if iNdEx >= l {
+ return 0, io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ innerWire |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ innerWireType := int(innerWire & 0x7)
+ if innerWireType == 4 {
+ break
+ }
+ next, err := skipApi(dAtA[start:])
+ if err != nil {
+ return 0, err
+ }
+ iNdEx = start + next
+ }
+ return iNdEx, nil
+ case 4:
+ return iNdEx, nil
+ case 5:
+ iNdEx += 4
+ return iNdEx, nil
+ default:
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
+ }
+ }
+ panic("unreachable")
+}
+
+var (
+ ErrInvalidLengthApi = fmt.Errorf("proto: negative length found during unmarshaling")
+ ErrIntOverflowApi = fmt.Errorf("proto: integer overflow")
+)
+
+func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
+
+var fileDescriptorApi = []byte{
+ // 183 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4,
+ 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4d, 0x2e, 0xca, 0xd4, 0x2b, 0x2a, 0xcd, 0x2b, 0xc9,
+ 0xcc, 0x4d, 0xcd, 0x2f, 0x28, 0xc9, 0xcc, 0xcf, 0x2b, 0xd6, 0x2b, 0x33, 0x94, 0xd2, 0x4d, 0xcf,
+ 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7, 0x07, 0xab,
+ 0x4e, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0x62, 0x8a, 0x92, 0x2b, 0x17, 0xbb, 0x3f,
+ 0x44, 0xb3, 0x90, 0x24, 0x17, 0x47, 0x49, 0x65, 0x41, 0x6a, 0x7c, 0x69, 0x51, 0x8e, 0x04, 0xa3,
+ 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24, 0xcf, 0xc5, 0x9d, 0x9c,
+ 0x9f, 0x97, 0x96, 0x99, 0x1e, 0x5f, 0x90, 0x58, 0x92, 0x21, 0xc1, 0x04, 0x96, 0xe5, 0x82, 0x08,
+ 0x05, 0x24, 0x96, 0x64, 0x38, 0xc9, 0x9c, 0x78, 0x28, 0xc7, 0x78, 0xe3, 0xa1, 0x1c, 0x43, 0xc3,
+ 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71,
+ 0xc2, 0x63, 0x39, 0x86, 0x24, 0x36, 0xb0, 0x5d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07,
+ 0x00, 0xf2, 0x18, 0xbe, 0x00, 0x00, 0x00,
+}
diff --git a/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1/api.proto b/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1/api.proto
new file mode 100644
index 000000000..f907d609c
--- /dev/null
+++ b/src/runtime/vendor/github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1/api.proto
@@ -0,0 +1,22 @@
+// To regenerate api.pb.go run `make proto`
+syntax = "proto3";
+
+package cri.runtimeoptions.v1;
+
+import "github.com/gogo/protobuf/gogoproto/gogo.proto";
+
+option (gogoproto.goproto_stringer_all) = false;
+option (gogoproto.stringer_all) = true;
+option (gogoproto.goproto_getters_all) = true;
+option (gogoproto.marshaler_all) = true;
+option (gogoproto.sizer_all) = true;
+option (gogoproto.unmarshaler_all) = true;
+option (gogoproto.goproto_unrecognized_all) = false;
+
+message Options {
+ // TypeUrl specifies the type of the content inside the config file.
+ string type_url = 1;
+ // ConfigPath specifies the filesystem location of the config file
+ // used by the runtime.
+ string config_path = 2;
+}
diff --git a/src/runtime/vendor/modules.txt b/src/runtime/vendor/modules.txt
index 6743e4f23..82938d500 100644
--- a/src/runtime/vendor/modules.txt
+++ b/src/runtime/vendor/modules.txt
@@ -64,7 +64,6 @@ github.com/containerd/containerd/identifiers
github.com/containerd/containerd/log
github.com/containerd/containerd/mount
github.com/containerd/containerd/namespaces
-github.com/containerd/containerd/pkg/cri/annotations
github.com/containerd/containerd/pkg/dialer
github.com/containerd/containerd/pkg/runtimeoptions/v1
github.com/containerd/containerd/pkg/ttrpcutil
@@ -77,6 +76,10 @@ github.com/containerd/containerd/runtime/v2/task
github.com/containerd/containerd/sys
github.com/containerd/containerd/sys/reaper
github.com/containerd/containerd/version
+# github.com/containerd/cri-containerd v1.11.1-0.20190125013620-4dd6735020f5
+## explicit
+github.com/containerd/cri-containerd/pkg/annotations
+github.com/containerd/cri-containerd/pkg/api/runtimeoptions/v1
# github.com/containerd/fifo v1.0.0
## explicit
github.com/containerd/fifo
diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go
index 8d61b9f0d..3366af7df 100644
--- a/src/runtime/virtcontainers/kata_agent.go
+++ b/src/runtime/virtcontainers/kata_agent.go
@@ -136,8 +136,6 @@ const (
grpcMemHotplugByProbeRequest = "grpc.MemHotplugByProbeRequest"
grpcCopyFileRequest = "grpc.CopyFileRequest"
grpcSetGuestDateTimeRequest = "grpc.SetGuestDateTimeRequest"
- grpcStartTracingRequest = "grpc.StartTracingRequest"
- grpcStopTracingRequest = "grpc.StopTracingRequest"
grpcGetOOMEventRequest = "grpc.GetOOMEventRequest"
grpcGetMetricsRequest = "grpc.GetMetricsRequest"
grpcAddSwapRequest = "grpc.AddSwapRequest"
@@ -246,9 +244,8 @@ type kataAgent struct {
dialTimout uint32
- keepConn bool
- dynamicTracing bool
- dead bool
+ keepConn bool
+ dead bool
}
func (k *kataAgent) Logger() *logrus.Entry {
@@ -823,13 +820,6 @@ func (k *kataAgent) startSandbox(ctx context.Context, sandbox *Sandbox) error {
return err
}
- if k.dynamicTracing {
- _, err = k.sendReq(ctx, &grpc.StartTracingRequest{})
- if err != nil {
- return err
- }
- }
-
return nil
}
@@ -929,13 +919,6 @@ func (k *kataAgent) stopSandbox(ctx context.Context, sandbox *Sandbox) error {
return err
}
- if k.dynamicTracing {
- _, err := k.sendReq(ctx, &grpc.StopTracingRequest{})
- if err != nil {
- return err
- }
- }
-
return nil
}
@@ -2031,12 +2014,6 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) {
k.reqHandlers[grpcSetGuestDateTimeRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
return k.client.AgentServiceClient.SetGuestDateTime(ctx, req.(*grpc.SetGuestDateTimeRequest))
}
- k.reqHandlers[grpcStartTracingRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
- return k.client.AgentServiceClient.StartTracing(ctx, req.(*grpc.StartTracingRequest))
- }
- k.reqHandlers[grpcStopTracingRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
- return k.client.AgentServiceClient.StopTracing(ctx, req.(*grpc.StopTracingRequest))
- }
k.reqHandlers[grpcGetOOMEventRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
return k.client.AgentServiceClient.GetOOMEvent(ctx, req.(*grpc.GetOOMEventRequest))
}
diff --git a/src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.pb.go b/src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.pb.go
index 2d60f94c7..b3681f650 100644
--- a/src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.pb.go
+++ b/src/runtime/virtcontainers/pkg/agent/protocols/grpc/agent.pb.go
@@ -2222,82 +2222,6 @@ func (m *CopyFileRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_CopyFileRequest proto.InternalMessageInfo
-type StartTracingRequest struct {
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *StartTracingRequest) Reset() { *m = StartTracingRequest{} }
-func (*StartTracingRequest) ProtoMessage() {}
-func (*StartTracingRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{51}
-}
-func (m *StartTracingRequest) XXX_Unmarshal(b []byte) error {
- return m.Unmarshal(b)
-}
-func (m *StartTracingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_StartTracingRequest.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
- }
-}
-func (m *StartTracingRequest) XXX_Merge(src proto.Message) {
- xxx_messageInfo_StartTracingRequest.Merge(m, src)
-}
-func (m *StartTracingRequest) XXX_Size() int {
- return m.Size()
-}
-func (m *StartTracingRequest) XXX_DiscardUnknown() {
- xxx_messageInfo_StartTracingRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StartTracingRequest proto.InternalMessageInfo
-
-type StopTracingRequest struct {
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *StopTracingRequest) Reset() { *m = StopTracingRequest{} }
-func (*StopTracingRequest) ProtoMessage() {}
-func (*StopTracingRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{52}
-}
-func (m *StopTracingRequest) XXX_Unmarshal(b []byte) error {
- return m.Unmarshal(b)
-}
-func (m *StopTracingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- if deterministic {
- return xxx_messageInfo_StopTracingRequest.Marshal(b, m, deterministic)
- } else {
- b = b[:cap(b)]
- n, err := m.MarshalToSizedBuffer(b)
- if err != nil {
- return nil, err
- }
- return b[:n], nil
- }
-}
-func (m *StopTracingRequest) XXX_Merge(src proto.Message) {
- xxx_messageInfo_StopTracingRequest.Merge(m, src)
-}
-func (m *StopTracingRequest) XXX_Size() int {
- return m.Size()
-}
-func (m *StopTracingRequest) XXX_DiscardUnknown() {
- xxx_messageInfo_StopTracingRequest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StopTracingRequest proto.InternalMessageInfo
-
type GetOOMEventRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@@ -2307,7 +2231,7 @@ type GetOOMEventRequest struct {
func (m *GetOOMEventRequest) Reset() { *m = GetOOMEventRequest{} }
func (*GetOOMEventRequest) ProtoMessage() {}
func (*GetOOMEventRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{53}
+ return fileDescriptor_c1460208c38ccf5e, []int{51}
}
func (m *GetOOMEventRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2346,7 +2270,7 @@ type OOMEvent struct {
func (m *OOMEvent) Reset() { *m = OOMEvent{} }
func (*OOMEvent) ProtoMessage() {}
func (*OOMEvent) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{54}
+ return fileDescriptor_c1460208c38ccf5e, []int{52}
}
func (m *OOMEvent) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2385,7 +2309,7 @@ type AddSwapRequest struct {
func (m *AddSwapRequest) Reset() { *m = AddSwapRequest{} }
func (*AddSwapRequest) ProtoMessage() {}
func (*AddSwapRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{55}
+ return fileDescriptor_c1460208c38ccf5e, []int{53}
}
func (m *AddSwapRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2423,7 +2347,7 @@ type GetMetricsRequest struct {
func (m *GetMetricsRequest) Reset() { *m = GetMetricsRequest{} }
func (*GetMetricsRequest) ProtoMessage() {}
func (*GetMetricsRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{56}
+ return fileDescriptor_c1460208c38ccf5e, []int{54}
}
func (m *GetMetricsRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2462,7 +2386,7 @@ type Metrics struct {
func (m *Metrics) Reset() { *m = Metrics{} }
func (*Metrics) ProtoMessage() {}
func (*Metrics) Descriptor() ([]byte, []int) {
- return fileDescriptor_c1460208c38ccf5e, []int{57}
+ return fileDescriptor_c1460208c38ccf5e, []int{55}
}
func (m *Metrics) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2545,8 +2469,6 @@ func init() {
proto.RegisterType((*Device)(nil), "grpc.Device")
proto.RegisterType((*StringUser)(nil), "grpc.StringUser")
proto.RegisterType((*CopyFileRequest)(nil), "grpc.CopyFileRequest")
- proto.RegisterType((*StartTracingRequest)(nil), "grpc.StartTracingRequest")
- proto.RegisterType((*StopTracingRequest)(nil), "grpc.StopTracingRequest")
proto.RegisterType((*GetOOMEventRequest)(nil), "grpc.GetOOMEventRequest")
proto.RegisterType((*OOMEvent)(nil), "grpc.OOMEvent")
proto.RegisterType((*AddSwapRequest)(nil), "grpc.AddSwapRequest")
@@ -2559,196 +2481,193 @@ func init() {
}
var fileDescriptor_c1460208c38ccf5e = []byte{
- // 3011 bytes of a gzipped FileDescriptorProto
+ // 2973 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x3a, 0x4b, 0x6f, 0x23, 0xc7,
0xd1, 0xe6, 0x43, 0x22, 0x59, 0x7c, 0x89, 0x23, 0xad, 0x96, 0x4b, 0xdb, 0xfa, 0xd6, 0xb3, 0xf6,
- 0x7a, 0x6d, 0x7f, 0xe6, 0xda, 0x6b, 0x23, 0xeb, 0x07, 0x9c, 0xc5, 0x4a, 0x2b, 0x4b, 0xb2, 0x2d,
- 0x2f, 0x3d, 0x5c, 0xc1, 0x41, 0x82, 0x64, 0x30, 0x9a, 0x69, 0x91, 0x6d, 0x71, 0xa6, 0xc7, 0x3d,
- 0x3d, 0x5a, 0xd1, 0x01, 0x82, 0x9c, 0x92, 0x5b, 0x8e, 0xb9, 0xe5, 0x0f, 0x04, 0xb9, 0xe5, 0x96,
- 0x5c, 0x73, 0x30, 0x72, 0xca, 0x31, 0xa7, 0x20, 0xde, 0x9f, 0x90, 0x5f, 0x10, 0xf4, 0x6b, 0x1e,
- 0x7c, 0xc8, 0x89, 0x20, 0x20, 0x17, 0x62, 0xaa, 0xba, 0xba, 0x5e, 0xdd, 0x55, 0x5d, 0xd5, 0x4d,
- 0xf8, 0x62, 0x84, 0xd9, 0x38, 0x3e, 0xee, 0xbb, 0xc4, 0xbf, 0x7b, 0xea, 0x30, 0xe7, 0x4d, 0x97,
- 0x04, 0xcc, 0xc1, 0x01, 0xa2, 0xd1, 0x1c, 0x1c, 0x51, 0xf7, 0xae, 0x33, 0x42, 0x01, 0xbb, 0x1b,
- 0x52, 0xc2, 0x88, 0x4b, 0x26, 0x91, 0xfc, 0x8a, 0x24, 0xba, 0x2f, 0x00, 0xa3, 0x3c, 0xa2, 0xa1,
- 0xdb, 0xab, 0x11, 0x17, 0x4b, 0x44, 0xaf, 0xce, 0xa6, 0x21, 0x8a, 0x14, 0xf0, 0xfc, 0x88, 0x90,
- 0xd1, 0x04, 0xc9, 0x89, 0xc7, 0xf1, 0xc9, 0x5d, 0xe4, 0x87, 0x6c, 0x2a, 0x07, 0xcd, 0xdf, 0x15,
- 0x61, 0x73, 0x87, 0x22, 0x87, 0xa1, 0x1d, 0x2d, 0xd6, 0x42, 0x5f, 0xc7, 0x28, 0x62, 0xc6, 0x4b,
- 0xd0, 0x48, 0x54, 0xb1, 0xb1, 0xd7, 0x2d, 0xdc, 0x2c, 0xdc, 0xa9, 0x59, 0xf5, 0x04, 0x77, 0xe0,
- 0x19, 0xd7, 0xa1, 0x82, 0xce, 0x91, 0xcb, 0x47, 0x8b, 0x62, 0x74, 0x95, 0x83, 0x07, 0x9e, 0xf1,
- 0x36, 0xd4, 0x23, 0x46, 0x71, 0x30, 0xb2, 0xe3, 0x08, 0xd1, 0x6e, 0xe9, 0x66, 0xe1, 0x4e, 0xfd,
- 0xde, 0x5a, 0x9f, 0xeb, 0xd9, 0x1f, 0x8a, 0x81, 0xa3, 0x08, 0x51, 0x0b, 0xa2, 0xe4, 0xdb, 0xb8,
- 0x0d, 0x15, 0x0f, 0x9d, 0x61, 0x17, 0x45, 0xdd, 0xf2, 0xcd, 0xd2, 0x9d, 0xfa, 0xbd, 0x86, 0x24,
- 0x7f, 0x24, 0x90, 0x96, 0x1e, 0x34, 0x5e, 0x83, 0x6a, 0xc4, 0x08, 0x75, 0x46, 0x28, 0xea, 0xae,
- 0x08, 0xc2, 0xa6, 0xe6, 0x2b, 0xb0, 0x56, 0x32, 0x6c, 0xbc, 0x00, 0xa5, 0xc7, 0x3b, 0x07, 0xdd,
- 0x55, 0x21, 0x1d, 0x14, 0x55, 0x88, 0x5c, 0x8b, 0xa3, 0x8d, 0x5b, 0xd0, 0x8c, 0x9c, 0xc0, 0x3b,
- 0x26, 0xe7, 0x76, 0x88, 0xbd, 0x20, 0xea, 0x56, 0x6e, 0x16, 0xee, 0x54, 0xad, 0x86, 0x42, 0x0e,
- 0x38, 0xce, 0xfc, 0x00, 0xae, 0x0d, 0x99, 0x43, 0xd9, 0x25, 0xbc, 0x63, 0x1e, 0xc1, 0xa6, 0x85,
- 0x7c, 0x72, 0x76, 0x29, 0xd7, 0x76, 0xa1, 0xc2, 0xb0, 0x8f, 0x48, 0xcc, 0x84, 0x6b, 0x9b, 0x96,
- 0x06, 0xcd, 0x3f, 0x14, 0xc0, 0xd8, 0x3d, 0x47, 0xee, 0x80, 0x12, 0x17, 0x45, 0xd1, 0xff, 0x68,
- 0xb9, 0x5e, 0x85, 0x4a, 0x28, 0x15, 0xe8, 0x96, 0x05, 0xb9, 0x5a, 0x05, 0xad, 0x95, 0x1e, 0x35,
- 0xbf, 0x82, 0x8d, 0x21, 0x1e, 0x05, 0xce, 0xe4, 0x0a, 0xf5, 0xdd, 0x84, 0xd5, 0x48, 0xf0, 0x14,
- 0xaa, 0x36, 0x2d, 0x05, 0x99, 0x03, 0x30, 0xbe, 0x74, 0x30, 0xbb, 0x3a, 0x49, 0xe6, 0x9b, 0xb0,
- 0x9e, 0xe3, 0x18, 0x85, 0x24, 0x88, 0x90, 0x50, 0x80, 0x39, 0x2c, 0x8e, 0x04, 0xb3, 0x15, 0x4b,
- 0x41, 0x26, 0x81, 0xcd, 0xa3, 0xd0, 0xbb, 0x64, 0x34, 0xdd, 0x83, 0x1a, 0x45, 0x11, 0x89, 0x29,
- 0x8f, 0x81, 0xa2, 0x70, 0xea, 0x86, 0x74, 0xea, 0x67, 0x38, 0x88, 0xcf, 0x2d, 0x3d, 0x66, 0xa5,
- 0x64, 0x6a, 0x7f, 0xb2, 0xe8, 0x32, 0xfb, 0xf3, 0x03, 0xb8, 0x36, 0x70, 0xe2, 0xe8, 0x32, 0xba,
- 0x9a, 0x1f, 0xf2, 0xbd, 0x1d, 0xc5, 0xfe, 0xa5, 0x26, 0xff, 0xbe, 0x00, 0xd5, 0x9d, 0x30, 0x3e,
- 0x8a, 0x9c, 0x11, 0x32, 0xfe, 0x0f, 0xea, 0x8c, 0x30, 0x67, 0x62, 0xc7, 0x1c, 0x14, 0xe4, 0x65,
- 0x0b, 0x04, 0x4a, 0x12, 0xbc, 0x04, 0x8d, 0x10, 0x51, 0x37, 0x8c, 0x15, 0x45, 0xf1, 0x66, 0xe9,
- 0x4e, 0xd9, 0xaa, 0x4b, 0x9c, 0x24, 0xe9, 0xc3, 0xba, 0x18, 0xb3, 0x71, 0x60, 0x9f, 0x22, 0x1a,
- 0xa0, 0x89, 0x4f, 0x3c, 0x24, 0x36, 0x47, 0xd9, 0xea, 0x88, 0xa1, 0x83, 0xe0, 0xd3, 0x64, 0xc0,
- 0x78, 0x1d, 0x3a, 0x09, 0x3d, 0xdf, 0xf1, 0x82, 0xba, 0x2c, 0xa8, 0xdb, 0x8a, 0xfa, 0x48, 0xa1,
- 0xcd, 0x5f, 0x40, 0xeb, 0xc9, 0x98, 0x12, 0xc6, 0x26, 0x38, 0x18, 0x3d, 0x72, 0x98, 0xc3, 0x43,
- 0x33, 0x44, 0x14, 0x13, 0x2f, 0x52, 0xda, 0x6a, 0xd0, 0x78, 0x03, 0x3a, 0x4c, 0xd2, 0x22, 0xcf,
- 0xd6, 0x34, 0x45, 0x41, 0xb3, 0x96, 0x0c, 0x0c, 0x14, 0xf1, 0x2b, 0xd0, 0x4a, 0x89, 0x79, 0x70,
- 0x2b, 0x7d, 0x9b, 0x09, 0xf6, 0x09, 0xf6, 0x91, 0x79, 0x26, 0x7c, 0x25, 0x16, 0xd9, 0x78, 0x03,
- 0x6a, 0xa9, 0x1f, 0x0a, 0x62, 0x87, 0xb4, 0xe4, 0x0e, 0xd1, 0xee, 0xb4, 0xaa, 0x89, 0x53, 0x3e,
- 0x82, 0x36, 0x4b, 0x14, 0xb7, 0x3d, 0x87, 0x39, 0xf9, 0x4d, 0x95, 0xb7, 0xca, 0x6a, 0xb1, 0x1c,
- 0x6c, 0x7e, 0x08, 0xb5, 0x01, 0xf6, 0x22, 0x29, 0xb8, 0x0b, 0x15, 0x37, 0xa6, 0x14, 0x05, 0x4c,
- 0x9b, 0xac, 0x40, 0x63, 0x03, 0x56, 0x26, 0xd8, 0xc7, 0x4c, 0x99, 0x29, 0x01, 0x93, 0x00, 0x1c,
- 0x22, 0x9f, 0xd0, 0xa9, 0x70, 0xd8, 0x06, 0xac, 0x64, 0x17, 0x57, 0x02, 0xc6, 0xf3, 0x50, 0xf3,
- 0x9d, 0xf3, 0x64, 0x51, 0xf9, 0x48, 0xd5, 0x77, 0xce, 0xa5, 0xf2, 0x5d, 0xa8, 0x9c, 0x38, 0x78,
- 0xe2, 0x06, 0x4c, 0x79, 0x45, 0x83, 0xa9, 0xc0, 0x72, 0x56, 0xe0, 0x5f, 0x8a, 0x50, 0x97, 0x12,
- 0xa5, 0xc2, 0x1b, 0xb0, 0xe2, 0x3a, 0xee, 0x38, 0x11, 0x29, 0x00, 0xe3, 0xb6, 0x56, 0xa4, 0x98,
- 0xcd, 0x70, 0xa9, 0xa6, 0x5a, 0xb5, 0xbb, 0x00, 0xd1, 0x53, 0x27, 0x54, 0xba, 0x95, 0x96, 0x10,
- 0xd7, 0x38, 0x8d, 0x54, 0xf7, 0x1d, 0x68, 0xc8, 0x7d, 0xa7, 0xa6, 0x94, 0x97, 0x4c, 0xa9, 0x4b,
- 0x2a, 0x39, 0xe9, 0x16, 0x34, 0xe3, 0x08, 0xd9, 0x63, 0x8c, 0xa8, 0x43, 0xdd, 0xf1, 0xb4, 0xbb,
- 0x22, 0x0f, 0xa0, 0x38, 0x42, 0xfb, 0x1a, 0x67, 0xdc, 0x83, 0x15, 0x9e, 0x5b, 0xa2, 0xee, 0xaa,
- 0x38, 0xeb, 0x5e, 0xc8, 0xb2, 0x14, 0xa6, 0xf6, 0xc5, 0xef, 0x6e, 0xc0, 0xe8, 0xd4, 0x92, 0xa4,
- 0xbd, 0xf7, 0x00, 0x52, 0xa4, 0xb1, 0x06, 0xa5, 0x53, 0x34, 0x55, 0x71, 0xc8, 0x3f, 0xb9, 0x73,
- 0xce, 0x9c, 0x49, 0xac, 0xbd, 0x2e, 0x81, 0x0f, 0x8a, 0xef, 0x15, 0x4c, 0x17, 0xda, 0xdb, 0x93,
- 0x53, 0x4c, 0x32, 0xd3, 0x37, 0x60, 0xc5, 0x77, 0xbe, 0x22, 0x54, 0x7b, 0x52, 0x00, 0x02, 0x8b,
- 0x03, 0x42, 0x35, 0x0b, 0x01, 0x18, 0x2d, 0x28, 0x92, 0x50, 0xf8, 0xab, 0x66, 0x15, 0x49, 0x98,
- 0x0a, 0x2a, 0x67, 0x04, 0x99, 0xff, 0x28, 0x03, 0xa4, 0x52, 0x0c, 0x0b, 0x7a, 0x98, 0xd8, 0x11,
- 0xa2, 0xfc, 0x7c, 0xb7, 0x8f, 0xa7, 0x0c, 0x45, 0x36, 0x45, 0x6e, 0x4c, 0x23, 0x7c, 0xc6, 0xd7,
- 0x8f, 0x9b, 0x7d, 0x4d, 0x9a, 0x3d, 0xa3, 0x9b, 0x75, 0x1d, 0x93, 0xa1, 0x9c, 0xb7, 0xcd, 0xa7,
- 0x59, 0x7a, 0x96, 0x71, 0x00, 0xd7, 0x52, 0x9e, 0x5e, 0x86, 0x5d, 0xf1, 0x22, 0x76, 0xeb, 0x09,
- 0x3b, 0x2f, 0x65, 0xb5, 0x0b, 0xeb, 0x98, 0xd8, 0x5f, 0xc7, 0x28, 0xce, 0x31, 0x2a, 0x5d, 0xc4,
- 0xa8, 0x83, 0xc9, 0x17, 0x62, 0x42, 0xca, 0x66, 0x00, 0x37, 0x32, 0x56, 0xf2, 0x70, 0xcf, 0x30,
- 0x2b, 0x5f, 0xc4, 0x6c, 0x33, 0xd1, 0x8a, 0xe7, 0x83, 0x94, 0xe3, 0x27, 0xb0, 0x89, 0x89, 0xfd,
- 0xd4, 0xc1, 0x6c, 0x96, 0xdd, 0xca, 0xf7, 0x18, 0xc9, 0x4f, 0xb4, 0x3c, 0x2f, 0x69, 0xa4, 0x8f,
- 0xe8, 0x28, 0x67, 0xe4, 0xea, 0xf7, 0x18, 0x79, 0x28, 0x26, 0xa4, 0x6c, 0x1e, 0x42, 0x07, 0x93,
- 0x59, 0x6d, 0x2a, 0x17, 0x31, 0x69, 0x63, 0x92, 0xd7, 0x64, 0x1b, 0x3a, 0x11, 0x72, 0x19, 0xa1,
- 0xd9, 0x4d, 0x50, 0xbd, 0x88, 0xc5, 0x9a, 0xa2, 0x4f, 0x78, 0x98, 0x3f, 0x81, 0xc6, 0x7e, 0x3c,
- 0x42, 0x6c, 0x72, 0x9c, 0x24, 0x83, 0x2b, 0xcb, 0x3f, 0xe6, 0xbf, 0x8a, 0x50, 0xdf, 0x19, 0x51,
- 0x12, 0x87, 0xb9, 0x9c, 0x2c, 0x83, 0x74, 0x36, 0x27, 0x0b, 0x12, 0x91, 0x93, 0x25, 0xf1, 0xbb,
- 0xd0, 0xf0, 0x45, 0xe8, 0x2a, 0x7a, 0x99, 0x87, 0x3a, 0x73, 0x41, 0x6d, 0xd5, 0xfd, 0x4c, 0x32,
- 0xeb, 0x03, 0x84, 0xd8, 0x8b, 0xd4, 0x1c, 0x99, 0x8e, 0xda, 0xaa, 0xdc, 0xd2, 0x29, 0xda, 0xaa,
- 0x85, 0x49, 0xb6, 0x7e, 0x1b, 0xea, 0xc7, 0xdc, 0x49, 0x6a, 0x42, 0x2e, 0x19, 0xa5, 0xde, 0xb3,
- 0xe0, 0x38, 0x0d, 0xc2, 0x7d, 0x68, 0x8e, 0xa5, 0xcb, 0xd4, 0x24, 0xb9, 0x87, 0x6e, 0x29, 0x4b,
- 0x52, 0x7b, 0xfb, 0x59, 0xcf, 0xca, 0x05, 0x68, 0x8c, 0x33, 0xa8, 0xde, 0x10, 0x3a, 0x73, 0x24,
- 0x0b, 0x72, 0xd0, 0x9d, 0x6c, 0x0e, 0xaa, 0xdf, 0x33, 0xa4, 0xa0, 0xec, 0xcc, 0x6c, 0x5e, 0xfa,
- 0x4d, 0x11, 0x1a, 0x9f, 0x23, 0xf6, 0x94, 0xd0, 0x53, 0xa9, 0xaf, 0x01, 0xe5, 0xc0, 0xf1, 0x91,
- 0xe2, 0x28, 0xbe, 0x8d, 0x1b, 0x50, 0xa5, 0xe7, 0x32, 0x81, 0xa8, 0xf5, 0xac, 0xd0, 0x73, 0x91,
- 0x18, 0x8c, 0x17, 0x01, 0xe8, 0xb9, 0x1d, 0x3a, 0xee, 0x29, 0x52, 0x1e, 0x2c, 0x5b, 0x35, 0x7a,
- 0x3e, 0x90, 0x08, 0xbe, 0x15, 0xe8, 0xb9, 0x8d, 0x28, 0x25, 0x34, 0x52, 0xb9, 0xaa, 0x4a, 0xcf,
- 0x77, 0x05, 0xac, 0xe6, 0x7a, 0x94, 0x84, 0x21, 0xf2, 0x44, 0x8e, 0x16, 0x73, 0x1f, 0x49, 0x04,
- 0x97, 0xca, 0xb4, 0xd4, 0x55, 0x29, 0x95, 0xa5, 0x52, 0x59, 0x2a, 0xb5, 0x22, 0x67, 0xb2, 0xac,
- 0x54, 0x96, 0x48, 0xad, 0x4a, 0xa9, 0x2c, 0x23, 0x95, 0xa5, 0x52, 0x6b, 0x7a, 0xae, 0x92, 0x6a,
- 0xfe, 0xba, 0x00, 0x9b, 0xb3, 0x85, 0x9f, 0xaa, 0x4d, 0xdf, 0x85, 0x86, 0x2b, 0xd6, 0x2b, 0xb7,
- 0x27, 0x3b, 0x73, 0x2b, 0x69, 0xd5, 0xdd, 0xcc, 0x36, 0xbe, 0x0f, 0xcd, 0x40, 0x3a, 0x38, 0xd9,
- 0x9a, 0xa5, 0x74, 0x5d, 0xb2, 0xbe, 0xb7, 0x1a, 0x41, 0x06, 0x32, 0x3d, 0x30, 0xbe, 0xa4, 0x98,
- 0xa1, 0x21, 0xa3, 0xc8, 0xf1, 0xaf, 0xa2, 0xba, 0x37, 0xa0, 0x2c, 0xaa, 0x15, 0xbe, 0x4c, 0x0d,
- 0x4b, 0x7c, 0x9b, 0xaf, 0xc2, 0x7a, 0x4e, 0x8a, 0xb2, 0x75, 0x0d, 0x4a, 0x13, 0x14, 0x08, 0xee,
- 0x4d, 0x8b, 0x7f, 0x9a, 0x0e, 0x74, 0x2c, 0xe4, 0x78, 0x57, 0xa7, 0x8d, 0x12, 0x51, 0x4a, 0x45,
- 0xdc, 0x01, 0x23, 0x2b, 0x42, 0xa9, 0xa2, 0xb5, 0x2e, 0x64, 0xb4, 0x7e, 0x0c, 0x9d, 0x9d, 0x09,
- 0x89, 0xd0, 0x90, 0x79, 0x38, 0xb8, 0x8a, 0x76, 0xe4, 0xe7, 0xb0, 0xfe, 0x84, 0x4d, 0xbf, 0xe4,
- 0xcc, 0x22, 0xfc, 0x0d, 0xba, 0x22, 0xfb, 0x28, 0x79, 0xaa, 0xed, 0xa3, 0xe4, 0x29, 0x6f, 0x6e,
- 0x5c, 0x32, 0x89, 0xfd, 0x40, 0x84, 0x42, 0xd3, 0x52, 0x90, 0xb9, 0x0d, 0x0d, 0x59, 0x43, 0x1f,
- 0x12, 0x2f, 0x9e, 0xa0, 0x85, 0x31, 0xb8, 0x05, 0x10, 0x3a, 0xd4, 0xf1, 0x11, 0x43, 0x54, 0xee,
- 0xa1, 0x9a, 0x95, 0xc1, 0x98, 0xbf, 0x2d, 0xc2, 0x86, 0xbc, 0x6f, 0x18, 0xca, 0x36, 0x5b, 0x9b,
- 0xd0, 0x83, 0xea, 0x98, 0x44, 0x2c, 0xc3, 0x30, 0x81, 0xb9, 0x8a, 0xbc, 0x3f, 0x97, 0xdc, 0xf8,
- 0x67, 0xee, 0x12, 0xa0, 0x74, 0xf1, 0x25, 0xc0, 0x5c, 0x9b, 0x5f, 0x9e, 0x6f, 0xf3, 0x79, 0xb4,
- 0x69, 0x22, 0x2c, 0x63, 0xbc, 0x66, 0xd5, 0x14, 0xe6, 0xc0, 0x33, 0x6e, 0x43, 0x7b, 0xc4, 0xb5,
- 0xb4, 0xc7, 0x84, 0x9c, 0xda, 0xa1, 0xc3, 0xc6, 0x22, 0xd4, 0x6b, 0x56, 0x53, 0xa0, 0xf7, 0x09,
- 0x39, 0x1d, 0x38, 0x6c, 0x6c, 0xbc, 0x0f, 0x2d, 0x55, 0x06, 0xfa, 0xc2, 0x45, 0x91, 0x3a, 0xfc,
- 0x54, 0x14, 0x65, 0xbd, 0x67, 0x35, 0x4f, 0x33, 0x50, 0x64, 0x5e, 0x87, 0x6b, 0x8f, 0x50, 0xc4,
- 0x28, 0x99, 0xe6, 0x1d, 0x63, 0xfe, 0x10, 0xe0, 0x20, 0x60, 0x88, 0x9e, 0x38, 0x2e, 0x8a, 0x8c,
- 0xb7, 0xb2, 0x90, 0x2a, 0x8e, 0xd6, 0xfa, 0xf2, 0xba, 0x27, 0x19, 0xb0, 0x32, 0x34, 0x66, 0x1f,
- 0x56, 0x2d, 0x12, 0xf3, 0x74, 0xf4, 0xb2, 0xfe, 0x52, 0xf3, 0x1a, 0x6a, 0x9e, 0x40, 0x5a, 0x6a,
- 0xcc, 0xdc, 0xd7, 0x2d, 0x6c, 0xca, 0x4e, 0x2d, 0x51, 0x1f, 0x6a, 0x58, 0xe3, 0x54, 0x56, 0x99,
- 0x17, 0x9d, 0x92, 0x98, 0x1f, 0xc2, 0xba, 0xe4, 0x24, 0x39, 0x6b, 0x36, 0x2f, 0xc3, 0x2a, 0xd5,
- 0x6a, 0x14, 0xd2, 0x7b, 0x1e, 0x45, 0xa4, 0xc6, 0xb8, 0x3f, 0x3e, 0xc3, 0x11, 0x4b, 0x0d, 0xd1,
- 0xfe, 0x58, 0x87, 0x0e, 0x1f, 0xc8, 0xf1, 0x34, 0x3f, 0x86, 0xc6, 0x43, 0x6b, 0xf0, 0x39, 0xc2,
- 0xa3, 0xf1, 0x31, 0xcf, 0x9e, 0x3f, 0xc8, 0xc3, 0xca, 0x60, 0x43, 0x69, 0x9b, 0x19, 0xb2, 0x72,
- 0x74, 0xe6, 0x27, 0xb0, 0xf9, 0xd0, 0xf3, 0xb2, 0x28, 0xad, 0xf5, 0x5b, 0x50, 0x0b, 0x32, 0xec,
- 0x32, 0x67, 0x56, 0x8e, 0x3a, 0x25, 0x32, 0x7f, 0x0a, 0xeb, 0x8f, 0x83, 0x09, 0x0e, 0xd0, 0xce,
- 0xe0, 0xe8, 0x10, 0x25, 0xb9, 0xc8, 0x80, 0x32, 0xaf, 0xd9, 0x04, 0x8f, 0xaa, 0x25, 0xbe, 0x79,
- 0x70, 0x06, 0xc7, 0xb6, 0x1b, 0xc6, 0x91, 0xba, 0xec, 0x59, 0x0d, 0x8e, 0x77, 0xc2, 0x38, 0xe2,
- 0x87, 0x0b, 0x2f, 0x2e, 0x48, 0x30, 0x99, 0x8a, 0x08, 0xad, 0x5a, 0x15, 0x37, 0x8c, 0x1f, 0x07,
- 0x93, 0xa9, 0xf9, 0xff, 0xa2, 0x03, 0x47, 0xc8, 0xb3, 0x9c, 0xc0, 0x23, 0xfe, 0x23, 0x74, 0x96,
- 0x91, 0x90, 0x74, 0x7b, 0x3a, 0x13, 0x7d, 0x5b, 0x80, 0xc6, 0xc3, 0x11, 0x0a, 0xd8, 0x23, 0xc4,
- 0x1c, 0x3c, 0x11, 0x1d, 0xdd, 0x19, 0xa2, 0x11, 0x26, 0x81, 0x0a, 0x37, 0x0d, 0xf2, 0x86, 0x1c,
- 0x07, 0x98, 0xd9, 0x9e, 0x83, 0x7c, 0x12, 0x08, 0x2e, 0x55, 0x0b, 0x38, 0xea, 0x91, 0xc0, 0x18,
- 0xaf, 0x42, 0x5b, 0x5e, 0xc6, 0xd9, 0x63, 0x27, 0xf0, 0x26, 0x3c, 0xd0, 0x4b, 0x22, 0x34, 0x5b,
- 0x12, 0xbd, 0xaf, 0xb0, 0xc6, 0x6b, 0xb0, 0xa6, 0xc2, 0x30, 0xa5, 0x2c, 0x0b, 0xca, 0xb6, 0xc2,
- 0xe7, 0x48, 0xe3, 0x30, 0x24, 0x94, 0x45, 0x76, 0x84, 0x5c, 0x97, 0xf8, 0xa1, 0x6a, 0x87, 0xda,
- 0x1a, 0x3f, 0x94, 0x68, 0x73, 0x04, 0xeb, 0x7b, 0xdc, 0x4e, 0x65, 0x49, 0xba, 0xad, 0x5a, 0x3e,
- 0xf2, 0xed, 0xe3, 0x09, 0x71, 0x4f, 0x6d, 0x9e, 0x1c, 0x95, 0x87, 0x79, 0xc1, 0xb5, 0xcd, 0x91,
- 0x43, 0xfc, 0x8d, 0xe8, 0xfc, 0x39, 0xd5, 0x98, 0xb0, 0x70, 0x12, 0x8f, 0xec, 0x90, 0x92, 0x63,
- 0xa4, 0x4c, 0x6c, 0xfb, 0xc8, 0xdf, 0x97, 0xf8, 0x01, 0x47, 0x9b, 0x7f, 0x2e, 0xc0, 0x46, 0x5e,
- 0x92, 0x4a, 0xf5, 0x77, 0x61, 0x23, 0x2f, 0x4a, 0x1d, 0xff, 0xb2, 0xbc, 0xec, 0x64, 0x05, 0xca,
- 0x42, 0xe0, 0x3e, 0x34, 0xc5, 0x7d, 0xad, 0xed, 0x49, 0x4e, 0xf9, 0xa2, 0x27, 0xbb, 0x2e, 0x56,
- 0xc3, 0xc9, 0xae, 0xd2, 0xfb, 0x70, 0x43, 0x99, 0x6f, 0xcf, 0xab, 0x2d, 0x37, 0xc4, 0xa6, 0x22,
- 0x38, 0x9c, 0xd1, 0xfe, 0x33, 0xe8, 0xa6, 0xa8, 0xed, 0xa9, 0x40, 0xa6, 0x9b, 0x79, 0x7d, 0xc6,
- 0xd8, 0x87, 0x9e, 0x47, 0x45, 0x94, 0x94, 0xad, 0x45, 0x43, 0xe6, 0x03, 0xb8, 0x3e, 0x44, 0x4c,
- 0x7a, 0xc3, 0x61, 0xaa, 0x13, 0x91, 0xcc, 0xd6, 0xa0, 0x34, 0x44, 0xae, 0x30, 0xbe, 0x64, 0xf1,
- 0x4f, 0xbe, 0x01, 0x8f, 0x22, 0xe4, 0x0a, 0x2b, 0x4b, 0x96, 0xf8, 0x36, 0xff, 0x58, 0x80, 0x8a,
- 0x4a, 0xce, 0xfc, 0x80, 0xf1, 0x28, 0x3e, 0x43, 0x54, 0x6d, 0x3d, 0x05, 0x19, 0xaf, 0x40, 0x4b,
- 0x7e, 0xd9, 0x24, 0x64, 0x98, 0x24, 0x29, 0xbf, 0x29, 0xb1, 0x8f, 0x25, 0x52, 0x5c, 0xbe, 0x89,
- 0xeb, 0x2f, 0xd5, 0x69, 0x2a, 0x88, 0xe3, 0x4f, 0x22, 0x1e, 0xe1, 0x22, 0xc5, 0xd7, 0x2c, 0x05,
- 0xf1, 0xad, 0xae, 0xf9, 0xad, 0x08, 0x7e, 0x1a, 0xe4, 0x5b, 0xdd, 0x27, 0x71, 0xc0, 0xec, 0x90,
- 0xe0, 0x80, 0xa9, 0x9c, 0x0e, 0x02, 0x35, 0xe0, 0x18, 0xf3, 0x57, 0x05, 0x58, 0x95, 0x17, 0xd0,
- 0xbc, 0xb7, 0x4d, 0x4e, 0xd6, 0x22, 0x16, 0x55, 0x8a, 0x90, 0x25, 0x4f, 0x53, 0xf1, 0xcd, 0xe3,
- 0xf8, 0xcc, 0x97, 0xe7, 0x83, 0x52, 0xed, 0xcc, 0x17, 0x07, 0xc3, 0x2b, 0xd0, 0x4a, 0x0f, 0x68,
- 0x31, 0x2e, 0x55, 0x6c, 0x26, 0x58, 0x41, 0xb6, 0x54, 0x53, 0xf3, 0x47, 0xbc, 0xa5, 0x4f, 0x2e,
- 0x5f, 0xd7, 0xa0, 0x14, 0x27, 0xca, 0xf0, 0x4f, 0x8e, 0x19, 0x25, 0x47, 0x3b, 0xff, 0x34, 0x6e,
- 0x43, 0xcb, 0xf1, 0x3c, 0xcc, 0xa7, 0x3b, 0x93, 0x3d, 0xec, 0x25, 0x41, 0x9a, 0xc7, 0x9a, 0x7f,
- 0x2d, 0x40, 0x7b, 0x87, 0x84, 0xd3, 0x8f, 0xf1, 0x04, 0x65, 0x32, 0x88, 0x50, 0x52, 0x9d, 0xec,
- 0xfc, 0x9b, 0x57, 0xab, 0x27, 0x78, 0x82, 0x64, 0x68, 0xc9, 0x95, 0xad, 0x72, 0x84, 0x08, 0x2b,
- 0x3d, 0x98, 0x5c, 0xbb, 0x35, 0xe5, 0xe0, 0x21, 0xf1, 0x44, 0x5d, 0xee, 0x61, 0x6a, 0x27, 0x97,
- 0x6c, 0x4d, 0xab, 0xe2, 0x61, 0x2a, 0x86, 0x94, 0x21, 0x2b, 0xe2, 0x12, 0x35, 0x6b, 0xc8, 0xaa,
- 0xc4, 0x70, 0x43, 0x36, 0x61, 0x95, 0x9c, 0x9c, 0x44, 0x88, 0x89, 0x0a, 0xba, 0x64, 0x29, 0x28,
- 0x49, 0x73, 0xd5, 0x4c, 0x9a, 0xbb, 0x06, 0xeb, 0xe2, 0xba, 0xfe, 0x09, 0x75, 0x5c, 0x1c, 0x8c,
- 0xf4, 0xf1, 0xb0, 0x01, 0xc6, 0x90, 0x91, 0x70, 0x1e, 0xbb, 0x87, 0xd8, 0xe3, 0xc7, 0x87, 0xbb,
- 0x67, 0x28, 0x60, 0x1a, 0xfb, 0x26, 0x54, 0x35, 0xea, 0x3f, 0xb9, 0xcb, 0x7c, 0x1d, 0x5a, 0x0f,
- 0x3d, 0x6f, 0xf8, 0xd4, 0x09, 0xb5, 0xf3, 0xba, 0x50, 0x19, 0xec, 0x1c, 0x0c, 0xa4, 0xff, 0x4a,
- 0xdc, 0x5a, 0x05, 0xf2, 0xa3, 0x6b, 0x0f, 0xb1, 0x43, 0xc4, 0x28, 0x76, 0x93, 0xa3, 0xeb, 0x16,
- 0x54, 0x14, 0x86, 0xcf, 0xf4, 0xe5, 0xa7, 0xce, 0xc9, 0x0a, 0xbc, 0xf7, 0xa7, 0x8e, 0x4a, 0xdf,
- 0xea, 0x26, 0xc0, 0xd8, 0x83, 0xf6, 0xcc, 0xb3, 0x8d, 0xa1, 0xae, 0x86, 0x16, 0xbf, 0xe6, 0xf4,
- 0x36, 0xfb, 0xf2, 0x19, 0xa8, 0xaf, 0x9f, 0x81, 0xfa, 0xbb, 0x7e, 0xc8, 0xa6, 0xc6, 0x2e, 0xb4,
- 0xf2, 0x0f, 0x1c, 0xc6, 0xf3, 0xba, 0x92, 0x5a, 0xf0, 0xec, 0xb1, 0x94, 0xcd, 0x1e, 0xb4, 0x67,
- 0xde, 0x3a, 0xb4, 0x3e, 0x8b, 0x9f, 0x40, 0x96, 0x32, 0x7a, 0x00, 0xf5, 0xcc, 0xe3, 0x86, 0xd1,
- 0x95, 0x4c, 0xe6, 0xdf, 0x3b, 0x96, 0x32, 0xd8, 0x81, 0x66, 0xee, 0xbd, 0xc1, 0xe8, 0x29, 0x7b,
- 0x16, 0x3c, 0x42, 0x2c, 0x65, 0xb2, 0x0d, 0xf5, 0xcc, 0xb5, 0xbf, 0xd6, 0x62, 0xfe, 0x6d, 0xa1,
- 0x77, 0x63, 0xc1, 0x88, 0x3a, 0x25, 0xf6, 0xa0, 0x3d, 0xf3, 0x16, 0xa0, 0x5d, 0xb2, 0xf8, 0x89,
- 0x60, 0xa9, 0x32, 0x9f, 0x8a, 0x25, 0xca, 0xb4, 0x7a, 0x99, 0x25, 0x9a, 0xbf, 0xf9, 0xef, 0xbd,
- 0xb0, 0x78, 0x50, 0x69, 0xb5, 0x0b, 0xad, 0xfc, 0xa5, 0xbf, 0x66, 0xb6, 0xf0, 0x29, 0xe0, 0xe2,
- 0xf5, 0xce, 0xdd, 0xff, 0xa7, 0xeb, 0xbd, 0xe8, 0x59, 0x60, 0x29, 0xa3, 0x87, 0x00, 0xaa, 0xb1,
- 0xf3, 0x70, 0x90, 0x38, 0x7a, 0xae, 0xa1, 0x4c, 0x1c, 0xbd, 0xa0, 0x09, 0x7c, 0x00, 0x20, 0xfb,
- 0x31, 0x8f, 0xc4, 0xcc, 0xb8, 0xae, 0xd5, 0x98, 0x69, 0x02, 0x7b, 0xdd, 0xf9, 0x81, 0x39, 0x06,
- 0x88, 0xd2, 0xcb, 0x30, 0xf8, 0x08, 0x20, 0xed, 0xf3, 0x34, 0x83, 0xb9, 0xce, 0xef, 0x02, 0x1f,
- 0x34, 0xb2, 0x5d, 0x9d, 0xa1, 0x6c, 0x5d, 0xd0, 0xe9, 0x5d, 0xc0, 0xa2, 0x3d, 0x53, 0xb5, 0xe7,
- 0x37, 0xdb, 0x6c, 0x31, 0xdf, 0x9b, 0xab, 0xdc, 0x8d, 0xfb, 0xd0, 0xc8, 0x96, 0xeb, 0x5a, 0x8b,
- 0x05, 0x25, 0x7c, 0x2f, 0x57, 0xb2, 0x1b, 0x0f, 0xa0, 0x95, 0x2f, 0xd5, 0xf5, 0x96, 0x5a, 0x58,
- 0xc0, 0xf7, 0xd4, 0x45, 0x54, 0x86, 0xfc, 0x1d, 0x80, 0xb4, 0xa4, 0xd7, 0xee, 0x9b, 0x2b, 0xf2,
- 0x67, 0xa4, 0xee, 0x41, 0x7b, 0xa6, 0x54, 0xd7, 0x16, 0x2f, 0xae, 0xe0, 0x2f, 0xf2, 0x7e, 0xf6,
- 0xcc, 0xd0, 0x76, 0x2f, 0x38, 0x47, 0x2e, 0x4a, 0x5a, 0x99, 0xf3, 0x45, 0xef, 0xe2, 0xf9, 0x23,
- 0x67, 0x29, 0x83, 0x77, 0x01, 0xd2, 0x93, 0x41, 0x7b, 0x60, 0xee, 0xac, 0xe8, 0x35, 0xf5, 0x45,
- 0xa1, 0xa4, 0xdb, 0x81, 0x66, 0xae, 0x97, 0xd6, 0xa9, 0x6e, 0x51, 0x83, 0x7d, 0xd1, 0x01, 0x90,
- 0x6f, 0x3c, 0xf5, 0xea, 0x2d, 0x6c, 0x47, 0x2f, 0xf2, 0x62, 0xb6, 0xdb, 0xd1, 0x5e, 0x5c, 0xd0,
- 0x01, 0x7d, 0x4f, 0x4e, 0xc9, 0x76, 0x34, 0x99, 0x9c, 0xb2, 0xa0, 0xd1, 0x59, 0xca, 0x68, 0x1f,
- 0xda, 0x7b, 0xba, 0x58, 0x55, 0x85, 0xb4, 0x52, 0x67, 0x41, 0xe3, 0xd0, 0xeb, 0x2d, 0x1a, 0x52,
- 0x81, 0xfd, 0x29, 0x74, 0xe6, 0x8a, 0x68, 0x63, 0x2b, 0xb9, 0xae, 0x5d, 0x58, 0x5d, 0x2f, 0x55,
- 0xeb, 0x00, 0xd6, 0x66, 0x6b, 0x68, 0xe3, 0x45, 0xb5, 0x55, 0x16, 0xd7, 0xd6, 0x4b, 0x59, 0xbd,
- 0x0f, 0x55, 0x5d, 0xb3, 0x19, 0xea, 0x5a, 0x7c, 0xa6, 0x86, 0x5b, 0x3a, 0xf5, 0x3e, 0xd4, 0x33,
- 0x55, 0x8f, 0xde, 0xab, 0xf3, 0x85, 0x50, 0x4f, 0xdd, 0x62, 0x27, 0x94, 0xf7, 0xa1, 0xa2, 0x2a,
- 0x1d, 0x63, 0x23, 0x09, 0xb4, 0x4c, 0xe1, 0xb3, 0x4c, 0xe2, 0xf6, 0xf9, 0xb7, 0xdf, 0x6d, 0x3d,
- 0xf7, 0xf7, 0xef, 0xb6, 0x9e, 0xfb, 0xe5, 0xb3, 0xad, 0xc2, 0xb7, 0xcf, 0xb6, 0x0a, 0x7f, 0x7b,
- 0xb6, 0x55, 0xf8, 0xe7, 0xb3, 0xad, 0xc2, 0x8f, 0x7f, 0xf6, 0x5f, 0xfe, 0x17, 0x86, 0xc6, 0x01,
- 0xc3, 0x3e, 0xba, 0x7b, 0x86, 0x29, 0xcb, 0x0c, 0x85, 0xa7, 0xa3, 0xb9, 0xbf, 0xc9, 0x70, 0x05,
- 0x8f, 0x57, 0x05, 0xfc, 0xce, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x43, 0x46, 0x6b, 0x3b, 0x74,
- 0x23, 0x00, 0x00,
+ 0x7a, 0x6d, 0x7f, 0xe6, 0xda, 0x6b, 0xe3, 0x5b, 0x3f, 0xe0, 0x6f, 0xa1, 0x97, 0x25, 0xd9, 0x96,
+ 0x45, 0x8f, 0x2c, 0xf8, 0xc3, 0x17, 0x24, 0x83, 0xd1, 0x4c, 0x8b, 0x6c, 0x8b, 0x33, 0x3d, 0xee,
+ 0xe9, 0xd1, 0x8a, 0x0e, 0x10, 0xe4, 0x94, 0xdc, 0x72, 0xcc, 0x2d, 0x7f, 0x20, 0xc8, 0x2d, 0x40,
+ 0x2e, 0xb9, 0xe6, 0x60, 0xe4, 0x94, 0x63, 0x4e, 0x41, 0xbc, 0x3f, 0x21, 0xbf, 0x20, 0xe8, 0xd7,
+ 0x3c, 0xf8, 0x90, 0x13, 0x41, 0x40, 0x2e, 0x44, 0x57, 0x75, 0x75, 0xbd, 0xba, 0xab, 0xba, 0xaa,
+ 0x87, 0xf0, 0xc5, 0x10, 0xb3, 0x51, 0x7c, 0xda, 0x77, 0x89, 0xff, 0xf0, 0xdc, 0x61, 0xce, 0x9b,
+ 0x2e, 0x09, 0x98, 0x83, 0x03, 0x44, 0xa3, 0x19, 0x38, 0xa2, 0xee, 0x43, 0x67, 0x88, 0x02, 0xf6,
+ 0x30, 0xa4, 0x84, 0x11, 0x97, 0x8c, 0x23, 0x39, 0x8a, 0x24, 0xba, 0x2f, 0x00, 0xa3, 0x3c, 0xa4,
+ 0xa1, 0xdb, 0xab, 0x11, 0x17, 0x4b, 0x44, 0xaf, 0xce, 0x26, 0x21, 0x8a, 0x14, 0xf0, 0xfc, 0x90,
+ 0x90, 0xe1, 0x18, 0xc9, 0x85, 0xa7, 0xf1, 0xd9, 0x43, 0xe4, 0x87, 0x6c, 0x22, 0x27, 0xcd, 0xdf,
+ 0x14, 0x61, 0x7d, 0x9b, 0x22, 0x87, 0xa1, 0x6d, 0x2d, 0xd6, 0x42, 0xdf, 0xc4, 0x28, 0x62, 0xc6,
+ 0x4b, 0xd0, 0x48, 0x54, 0xb1, 0xb1, 0xd7, 0x2d, 0xdc, 0x2d, 0x3c, 0xa8, 0x59, 0xf5, 0x04, 0x77,
+ 0xe0, 0x19, 0xb7, 0xa1, 0x82, 0x2e, 0x91, 0xcb, 0x67, 0x8b, 0x62, 0x76, 0x99, 0x83, 0x07, 0x9e,
+ 0xf1, 0x36, 0xd4, 0x23, 0x46, 0x71, 0x30, 0xb4, 0xe3, 0x08, 0xd1, 0x6e, 0xe9, 0x6e, 0xe1, 0x41,
+ 0xfd, 0xd1, 0x4a, 0x9f, 0xeb, 0xd9, 0x3f, 0x16, 0x13, 0x27, 0x11, 0xa2, 0x16, 0x44, 0xc9, 0xd8,
+ 0xb8, 0x0f, 0x15, 0x0f, 0x5d, 0x60, 0x17, 0x45, 0xdd, 0xf2, 0xdd, 0xd2, 0x83, 0xfa, 0xa3, 0x86,
+ 0x24, 0xdf, 0x11, 0x48, 0x4b, 0x4f, 0x1a, 0xaf, 0x41, 0x35, 0x62, 0x84, 0x3a, 0x43, 0x14, 0x75,
+ 0x97, 0x04, 0x61, 0x53, 0xf3, 0x15, 0x58, 0x2b, 0x99, 0x36, 0x5e, 0x80, 0xd2, 0xd1, 0xf6, 0x41,
+ 0x77, 0x59, 0x48, 0x07, 0x45, 0x15, 0x22, 0xd7, 0xe2, 0x68, 0xe3, 0x1e, 0x34, 0x23, 0x27, 0xf0,
+ 0x4e, 0xc9, 0xa5, 0x1d, 0x62, 0x2f, 0x88, 0xba, 0x95, 0xbb, 0x85, 0x07, 0x55, 0xab, 0xa1, 0x90,
+ 0x03, 0x8e, 0x33, 0x3f, 0x80, 0x5b, 0xc7, 0xcc, 0xa1, 0xec, 0x1a, 0xde, 0x31, 0x4f, 0x60, 0xdd,
+ 0x42, 0x3e, 0xb9, 0xb8, 0x96, 0x6b, 0xbb, 0x50, 0x61, 0xd8, 0x47, 0x24, 0x66, 0xc2, 0xb5, 0x4d,
+ 0x4b, 0x83, 0xe6, 0xef, 0x0a, 0x60, 0xec, 0x5e, 0x22, 0x77, 0x40, 0x89, 0x8b, 0xa2, 0xe8, 0x3f,
+ 0xb4, 0x5d, 0xaf, 0x42, 0x25, 0x94, 0x0a, 0x74, 0xcb, 0x82, 0x5c, 0xed, 0x82, 0xd6, 0x4a, 0xcf,
+ 0x9a, 0x5f, 0xc3, 0xda, 0x31, 0x1e, 0x06, 0xce, 0xf8, 0x06, 0xf5, 0x5d, 0x87, 0xe5, 0x48, 0xf0,
+ 0x14, 0xaa, 0x36, 0x2d, 0x05, 0x99, 0x03, 0x30, 0xbe, 0x72, 0x30, 0xbb, 0x39, 0x49, 0xe6, 0x9b,
+ 0xb0, 0x9a, 0xe3, 0x18, 0x85, 0x24, 0x88, 0x90, 0x50, 0x80, 0x39, 0x2c, 0x8e, 0x04, 0xb3, 0x25,
+ 0x4b, 0x41, 0x26, 0x81, 0xf5, 0x93, 0xd0, 0xbb, 0x66, 0x34, 0x3d, 0x82, 0x1a, 0x45, 0x11, 0x89,
+ 0x29, 0x8f, 0x81, 0xa2, 0x70, 0xea, 0x9a, 0x74, 0xea, 0x67, 0x38, 0x88, 0x2f, 0x2d, 0x3d, 0x67,
+ 0xa5, 0x64, 0xea, 0x7c, 0xb2, 0xe8, 0x3a, 0xe7, 0xf3, 0x03, 0xb8, 0x35, 0x70, 0xe2, 0xe8, 0x3a,
+ 0xba, 0x9a, 0x1f, 0xf2, 0xb3, 0x1d, 0xc5, 0xfe, 0xb5, 0x16, 0xff, 0xb6, 0x00, 0xd5, 0xed, 0x30,
+ 0x3e, 0x89, 0x9c, 0x21, 0x32, 0xfe, 0x0b, 0xea, 0x8c, 0x30, 0x67, 0x6c, 0xc7, 0x1c, 0x14, 0xe4,
+ 0x65, 0x0b, 0x04, 0x4a, 0x12, 0xbc, 0x04, 0x8d, 0x10, 0x51, 0x37, 0x8c, 0x15, 0x45, 0xf1, 0x6e,
+ 0xe9, 0x41, 0xd9, 0xaa, 0x4b, 0x9c, 0x24, 0xe9, 0xc3, 0xaa, 0x98, 0xb3, 0x71, 0x60, 0x9f, 0x23,
+ 0x1a, 0xa0, 0xb1, 0x4f, 0x3c, 0x24, 0x0e, 0x47, 0xd9, 0xea, 0x88, 0xa9, 0x83, 0xe0, 0xd3, 0x64,
+ 0xc2, 0x78, 0x1d, 0x3a, 0x09, 0x3d, 0x3f, 0xf1, 0x82, 0xba, 0x2c, 0xa8, 0xdb, 0x8a, 0xfa, 0x44,
+ 0xa1, 0xcd, 0x9f, 0x41, 0xeb, 0xcb, 0x11, 0x25, 0x8c, 0x8d, 0x71, 0x30, 0xdc, 0x71, 0x98, 0xc3,
+ 0x43, 0x33, 0x44, 0x14, 0x13, 0x2f, 0x52, 0xda, 0x6a, 0xd0, 0x78, 0x03, 0x3a, 0x4c, 0xd2, 0x22,
+ 0xcf, 0xd6, 0x34, 0x45, 0x41, 0xb3, 0x92, 0x4c, 0x0c, 0x14, 0xf1, 0x2b, 0xd0, 0x4a, 0x89, 0x79,
+ 0x70, 0x2b, 0x7d, 0x9b, 0x09, 0xf6, 0x4b, 0xec, 0x23, 0xf3, 0x42, 0xf8, 0x4a, 0x6c, 0xb2, 0xf1,
+ 0x06, 0xd4, 0x52, 0x3f, 0x14, 0xc4, 0x09, 0x69, 0xc9, 0x13, 0xa2, 0xdd, 0x69, 0x55, 0x13, 0xa7,
+ 0x7c, 0x04, 0x6d, 0x96, 0x28, 0x6e, 0x7b, 0x0e, 0x73, 0xf2, 0x87, 0x2a, 0x6f, 0x95, 0xd5, 0x62,
+ 0x39, 0xd8, 0xfc, 0x10, 0x6a, 0x03, 0xec, 0x45, 0x52, 0x70, 0x17, 0x2a, 0x6e, 0x4c, 0x29, 0x0a,
+ 0x98, 0x36, 0x59, 0x81, 0xc6, 0x1a, 0x2c, 0x8d, 0xb1, 0x8f, 0x99, 0x32, 0x53, 0x02, 0x26, 0x01,
+ 0x38, 0x44, 0x3e, 0xa1, 0x13, 0xe1, 0xb0, 0x35, 0x58, 0xca, 0x6e, 0xae, 0x04, 0x8c, 0xe7, 0xa1,
+ 0xe6, 0x3b, 0x97, 0xc9, 0xa6, 0xf2, 0x99, 0xaa, 0xef, 0x5c, 0x4a, 0xe5, 0xbb, 0x50, 0x39, 0x73,
+ 0xf0, 0xd8, 0x0d, 0x98, 0xf2, 0x8a, 0x06, 0x53, 0x81, 0xe5, 0xac, 0xc0, 0x3f, 0x15, 0xa1, 0x2e,
+ 0x25, 0x4a, 0x85, 0xd7, 0x60, 0xc9, 0x75, 0xdc, 0x51, 0x22, 0x52, 0x00, 0xc6, 0x7d, 0xad, 0x48,
+ 0x31, 0x9b, 0xe1, 0x52, 0x4d, 0xb5, 0x6a, 0x0f, 0x01, 0xa2, 0xa7, 0x4e, 0xa8, 0x74, 0x2b, 0x2d,
+ 0x20, 0xae, 0x71, 0x1a, 0xa9, 0xee, 0x3b, 0xd0, 0x90, 0xe7, 0x4e, 0x2d, 0x29, 0x2f, 0x58, 0x52,
+ 0x97, 0x54, 0x72, 0xd1, 0x3d, 0x68, 0xc6, 0x11, 0xb2, 0x47, 0x18, 0x51, 0x87, 0xba, 0xa3, 0x49,
+ 0x77, 0x49, 0x5e, 0x40, 0x71, 0x84, 0xf6, 0x35, 0xce, 0x78, 0x04, 0x4b, 0x3c, 0xb7, 0x44, 0xdd,
+ 0x65, 0x71, 0xd7, 0xbd, 0x90, 0x65, 0x29, 0x4c, 0xed, 0x8b, 0xdf, 0xdd, 0x80, 0xd1, 0x89, 0x25,
+ 0x49, 0x7b, 0xef, 0x01, 0xa4, 0x48, 0x63, 0x05, 0x4a, 0xe7, 0x68, 0xa2, 0xe2, 0x90, 0x0f, 0xb9,
+ 0x73, 0x2e, 0x9c, 0x71, 0xac, 0xbd, 0x2e, 0x81, 0x0f, 0x8a, 0xef, 0x15, 0x4c, 0x17, 0xda, 0x5b,
+ 0xe3, 0x73, 0x4c, 0x32, 0xcb, 0xd7, 0x60, 0xc9, 0x77, 0xbe, 0x26, 0x54, 0x7b, 0x52, 0x00, 0x02,
+ 0x8b, 0x03, 0x42, 0x35, 0x0b, 0x01, 0x18, 0x2d, 0x28, 0x92, 0x50, 0xf8, 0xab, 0x66, 0x15, 0x49,
+ 0x98, 0x0a, 0x2a, 0x67, 0x04, 0x99, 0x7f, 0x2b, 0x03, 0xa4, 0x52, 0x0c, 0x0b, 0x7a, 0x98, 0xd8,
+ 0x11, 0xa2, 0xfc, 0x7e, 0xb7, 0x4f, 0x27, 0x0c, 0x45, 0x36, 0x45, 0x6e, 0x4c, 0x23, 0x7c, 0xc1,
+ 0xf7, 0x8f, 0x9b, 0x7d, 0x4b, 0x9a, 0x3d, 0xa5, 0x9b, 0x75, 0x1b, 0x93, 0x63, 0xb9, 0x6e, 0x8b,
+ 0x2f, 0xb3, 0xf4, 0x2a, 0xe3, 0x00, 0x6e, 0xa5, 0x3c, 0xbd, 0x0c, 0xbb, 0xe2, 0x55, 0xec, 0x56,
+ 0x13, 0x76, 0x5e, 0xca, 0x6a, 0x17, 0x56, 0x31, 0xb1, 0xbf, 0x89, 0x51, 0x9c, 0x63, 0x54, 0xba,
+ 0x8a, 0x51, 0x07, 0x93, 0x2f, 0xc4, 0x82, 0x94, 0xcd, 0x00, 0xee, 0x64, 0xac, 0xe4, 0xe1, 0x9e,
+ 0x61, 0x56, 0xbe, 0x8a, 0xd9, 0x7a, 0xa2, 0x15, 0xcf, 0x07, 0x29, 0xc7, 0x4f, 0x60, 0x1d, 0x13,
+ 0xfb, 0xa9, 0x83, 0xd9, 0x34, 0xbb, 0xa5, 0x1f, 0x30, 0x92, 0xdf, 0x68, 0x79, 0x5e, 0xd2, 0x48,
+ 0x1f, 0xd1, 0x61, 0xce, 0xc8, 0xe5, 0x1f, 0x30, 0xf2, 0x50, 0x2c, 0x48, 0xd9, 0x6c, 0x42, 0x07,
+ 0x93, 0x69, 0x6d, 0x2a, 0x57, 0x31, 0x69, 0x63, 0x92, 0xd7, 0x64, 0x0b, 0x3a, 0x11, 0x72, 0x19,
+ 0xa1, 0xd9, 0x43, 0x50, 0xbd, 0x8a, 0xc5, 0x8a, 0xa2, 0x4f, 0x78, 0x98, 0x3f, 0x82, 0xc6, 0x7e,
+ 0x3c, 0x44, 0x6c, 0x7c, 0x9a, 0x24, 0x83, 0x1b, 0xcb, 0x3f, 0xe6, 0x3f, 0x8a, 0x50, 0xdf, 0x1e,
+ 0x52, 0x12, 0x87, 0xb9, 0x9c, 0x2c, 0x83, 0x74, 0x3a, 0x27, 0x0b, 0x12, 0x91, 0x93, 0x25, 0xf1,
+ 0xbb, 0xd0, 0xf0, 0x45, 0xe8, 0x2a, 0x7a, 0x99, 0x87, 0x3a, 0x33, 0x41, 0x6d, 0xd5, 0xfd, 0x4c,
+ 0x32, 0xeb, 0x03, 0x84, 0xd8, 0x8b, 0xd4, 0x1a, 0x99, 0x8e, 0xda, 0xaa, 0xdc, 0xd2, 0x29, 0xda,
+ 0xaa, 0x85, 0x49, 0xb6, 0x7e, 0x1b, 0xea, 0xa7, 0xdc, 0x49, 0x6a, 0x41, 0x2e, 0x19, 0xa5, 0xde,
+ 0xb3, 0xe0, 0x34, 0x0d, 0xc2, 0x7d, 0x68, 0x8e, 0xa4, 0xcb, 0xd4, 0x22, 0x79, 0x86, 0xee, 0x29,
+ 0x4b, 0x52, 0x7b, 0xfb, 0x59, 0xcf, 0xca, 0x0d, 0x68, 0x8c, 0x32, 0xa8, 0xde, 0x31, 0x74, 0x66,
+ 0x48, 0xe6, 0xe4, 0xa0, 0x07, 0xd9, 0x1c, 0x54, 0x7f, 0x64, 0x48, 0x41, 0xd9, 0x95, 0xd9, 0xbc,
+ 0xf4, 0xab, 0x22, 0x34, 0x3e, 0x47, 0xec, 0x29, 0xa1, 0xe7, 0x52, 0x5f, 0x03, 0xca, 0x81, 0xe3,
+ 0x23, 0xc5, 0x51, 0x8c, 0x8d, 0x3b, 0x50, 0xa5, 0x97, 0x32, 0x81, 0xa8, 0xfd, 0xac, 0xd0, 0x4b,
+ 0x91, 0x18, 0x8c, 0x17, 0x01, 0xe8, 0xa5, 0x1d, 0x3a, 0xee, 0x39, 0x52, 0x1e, 0x2c, 0x5b, 0x35,
+ 0x7a, 0x39, 0x90, 0x08, 0x7e, 0x14, 0xe8, 0xa5, 0x8d, 0x28, 0x25, 0x34, 0x52, 0xb9, 0xaa, 0x4a,
+ 0x2f, 0x77, 0x05, 0xac, 0xd6, 0x7a, 0x94, 0x84, 0x21, 0xf2, 0x44, 0x8e, 0x16, 0x6b, 0x77, 0x24,
+ 0x82, 0x4b, 0x65, 0x5a, 0xea, 0xb2, 0x94, 0xca, 0x52, 0xa9, 0x2c, 0x95, 0x5a, 0x91, 0x2b, 0x59,
+ 0x56, 0x2a, 0x4b, 0xa4, 0x56, 0xa5, 0x54, 0x96, 0x91, 0xca, 0x52, 0xa9, 0x35, 0xbd, 0x56, 0x49,
+ 0x35, 0x7f, 0x59, 0x80, 0xf5, 0xe9, 0xc2, 0x4f, 0xd5, 0xa6, 0xef, 0x42, 0xc3, 0x15, 0xfb, 0x95,
+ 0x3b, 0x93, 0x9d, 0x99, 0x9d, 0xb4, 0xea, 0x6e, 0xe6, 0x18, 0x3f, 0x86, 0x66, 0x20, 0x1d, 0x9c,
+ 0x1c, 0xcd, 0x52, 0xba, 0x2f, 0x59, 0xdf, 0x5b, 0x8d, 0x20, 0x03, 0x99, 0x1e, 0x18, 0x5f, 0x51,
+ 0xcc, 0xd0, 0x31, 0xa3, 0xc8, 0xf1, 0x6f, 0xa2, 0xba, 0x37, 0xa0, 0x2c, 0xaa, 0x15, 0xbe, 0x4d,
+ 0x0d, 0x4b, 0x8c, 0xcd, 0x57, 0x61, 0x35, 0x27, 0x45, 0xd9, 0xba, 0x02, 0xa5, 0x31, 0x0a, 0x04,
+ 0xf7, 0xa6, 0xc5, 0x87, 0xa6, 0x03, 0x1d, 0x0b, 0x39, 0xde, 0xcd, 0x69, 0xa3, 0x44, 0x94, 0x52,
+ 0x11, 0x0f, 0xc0, 0xc8, 0x8a, 0x50, 0xaa, 0x68, 0xad, 0x0b, 0x19, 0xad, 0x8f, 0xa0, 0xb3, 0x3d,
+ 0x26, 0x11, 0x3a, 0x66, 0x1e, 0x0e, 0x6e, 0xa2, 0x1d, 0xf9, 0x29, 0xac, 0x7e, 0xc9, 0x26, 0x5f,
+ 0x71, 0x66, 0x11, 0xfe, 0x16, 0xdd, 0x90, 0x7d, 0x94, 0x3c, 0xd5, 0xf6, 0x51, 0xf2, 0x94, 0x37,
+ 0x37, 0x2e, 0x19, 0xc7, 0x7e, 0x20, 0x42, 0xa1, 0x69, 0x29, 0xc8, 0xdc, 0x82, 0x86, 0xac, 0xa1,
+ 0x0f, 0x89, 0x17, 0x8f, 0xd1, 0xdc, 0x18, 0xdc, 0x00, 0x08, 0x1d, 0xea, 0xf8, 0x88, 0x21, 0x2a,
+ 0xcf, 0x50, 0xcd, 0xca, 0x60, 0xcc, 0x5f, 0x17, 0x61, 0x4d, 0xbe, 0x37, 0x1c, 0xcb, 0x36, 0x5b,
+ 0x9b, 0xd0, 0x83, 0xea, 0x88, 0x44, 0x2c, 0xc3, 0x30, 0x81, 0xb9, 0x8a, 0xbc, 0x3f, 0x97, 0xdc,
+ 0xf8, 0x30, 0xf7, 0x08, 0x50, 0xba, 0xfa, 0x11, 0x60, 0xa6, 0xcd, 0x2f, 0xcf, 0xb6, 0xf9, 0x3c,
+ 0xda, 0x34, 0x11, 0x96, 0x31, 0x5e, 0xb3, 0x6a, 0x0a, 0x73, 0xe0, 0x19, 0xf7, 0xa1, 0x3d, 0xe4,
+ 0x5a, 0xda, 0x23, 0x42, 0xce, 0xed, 0xd0, 0x61, 0x23, 0x11, 0xea, 0x35, 0xab, 0x29, 0xd0, 0xfb,
+ 0x84, 0x9c, 0x0f, 0x1c, 0x36, 0x32, 0xde, 0x87, 0x96, 0x2a, 0x03, 0x7d, 0xe1, 0xa2, 0x48, 0x5d,
+ 0x7e, 0x2a, 0x8a, 0xb2, 0xde, 0xb3, 0x9a, 0xe7, 0x19, 0x28, 0x32, 0x6f, 0xc3, 0xad, 0x1d, 0x14,
+ 0x31, 0x4a, 0x26, 0x79, 0xc7, 0x98, 0xff, 0x0b, 0x70, 0x10, 0x30, 0x44, 0xcf, 0x1c, 0x17, 0x45,
+ 0xc6, 0x5b, 0x59, 0x48, 0x15, 0x47, 0x2b, 0x7d, 0xf9, 0xdc, 0x93, 0x4c, 0x58, 0x19, 0x1a, 0xb3,
+ 0x0f, 0xcb, 0x16, 0x89, 0x79, 0x3a, 0x7a, 0x59, 0x8f, 0xd4, 0xba, 0x86, 0x5a, 0x27, 0x90, 0x96,
+ 0x9a, 0x33, 0xf7, 0x75, 0x0b, 0x9b, 0xb2, 0x53, 0x5b, 0xd4, 0x87, 0x1a, 0xd6, 0x38, 0x95, 0x55,
+ 0x66, 0x45, 0xa7, 0x24, 0xe6, 0x87, 0xb0, 0x2a, 0x39, 0x49, 0xce, 0x9a, 0xcd, 0xcb, 0xb0, 0x4c,
+ 0xb5, 0x1a, 0x85, 0xf4, 0x9d, 0x47, 0x11, 0xa9, 0x39, 0xee, 0x8f, 0xcf, 0x70, 0xc4, 0x52, 0x43,
+ 0xb4, 0x3f, 0x56, 0xa1, 0xc3, 0x27, 0x72, 0x3c, 0xcd, 0x8f, 0xa1, 0xb1, 0x69, 0x0d, 0x3e, 0x47,
+ 0x78, 0x38, 0x3a, 0xe5, 0xd9, 0xf3, 0x7f, 0xf2, 0xb0, 0x32, 0xd8, 0x50, 0xda, 0x66, 0xa6, 0xac,
+ 0x1c, 0x9d, 0xf9, 0x09, 0xac, 0x6f, 0x7a, 0x5e, 0x16, 0xa5, 0xb5, 0x7e, 0x0b, 0x6a, 0x41, 0x86,
+ 0x5d, 0xe6, 0xce, 0xca, 0x51, 0xa7, 0x44, 0xe6, 0x8f, 0x61, 0xf5, 0x28, 0x18, 0xe3, 0x00, 0x6d,
+ 0x0f, 0x4e, 0x0e, 0x51, 0x92, 0x8b, 0x0c, 0x28, 0xf3, 0x9a, 0x4d, 0xf0, 0xa8, 0x5a, 0x62, 0xcc,
+ 0x83, 0x33, 0x38, 0xb5, 0xdd, 0x30, 0x8e, 0xd4, 0x63, 0xcf, 0x72, 0x70, 0xba, 0x1d, 0xc6, 0x11,
+ 0xbf, 0x5c, 0x78, 0x71, 0x41, 0x82, 0xf1, 0x44, 0x44, 0x68, 0xd5, 0xaa, 0xb8, 0x61, 0x7c, 0x14,
+ 0x8c, 0x27, 0xe6, 0x7f, 0x8b, 0x0e, 0x1c, 0x21, 0xcf, 0x72, 0x02, 0x8f, 0xf8, 0x3b, 0xe8, 0x22,
+ 0x23, 0x21, 0xe9, 0xf6, 0x74, 0x26, 0xfa, 0xae, 0x00, 0x8d, 0xcd, 0x21, 0x0a, 0xd8, 0x0e, 0x62,
+ 0x0e, 0x1e, 0x8b, 0x8e, 0xee, 0x02, 0xd1, 0x08, 0x93, 0x40, 0x85, 0x9b, 0x06, 0x79, 0x43, 0x8e,
+ 0x03, 0xcc, 0x6c, 0xcf, 0x41, 0x3e, 0x09, 0x04, 0x97, 0xaa, 0x05, 0x1c, 0xb5, 0x23, 0x30, 0xc6,
+ 0xab, 0xd0, 0x96, 0x8f, 0x71, 0xf6, 0xc8, 0x09, 0xbc, 0x31, 0x0f, 0xf4, 0x92, 0x08, 0xcd, 0x96,
+ 0x44, 0xef, 0x2b, 0xac, 0xf1, 0x1a, 0xac, 0xa8, 0x30, 0x4c, 0x29, 0xcb, 0x82, 0xb2, 0xad, 0xf0,
+ 0x39, 0xd2, 0x38, 0x0c, 0x09, 0x65, 0x91, 0x1d, 0x21, 0xd7, 0x25, 0x7e, 0xa8, 0xda, 0xa1, 0xb6,
+ 0xc6, 0x1f, 0x4b, 0xb4, 0x39, 0x84, 0xd5, 0x3d, 0x6e, 0xa7, 0xb2, 0x24, 0x3d, 0x56, 0x2d, 0x1f,
+ 0xf9, 0xf6, 0xe9, 0x98, 0xb8, 0xe7, 0x36, 0x4f, 0x8e, 0xca, 0xc3, 0xbc, 0xe0, 0xda, 0xe2, 0xc8,
+ 0x63, 0xfc, 0xad, 0xe8, 0xfc, 0x39, 0xd5, 0x88, 0xb0, 0x70, 0x1c, 0x0f, 0xed, 0x90, 0x92, 0x53,
+ 0xa4, 0x4c, 0x6c, 0xfb, 0xc8, 0xdf, 0x97, 0xf8, 0x01, 0x47, 0x9b, 0x7f, 0x2c, 0xc0, 0x5a, 0x5e,
+ 0x92, 0x4a, 0xf5, 0x0f, 0x61, 0x2d, 0x2f, 0x4a, 0x5d, 0xff, 0xb2, 0xbc, 0xec, 0x64, 0x05, 0xca,
+ 0x42, 0xe0, 0x31, 0x34, 0xc5, 0x7b, 0xad, 0xed, 0x49, 0x4e, 0xf9, 0xa2, 0x27, 0xbb, 0x2f, 0x56,
+ 0xc3, 0xc9, 0xee, 0xd2, 0xfb, 0x70, 0x47, 0x99, 0x6f, 0xcf, 0xaa, 0x2d, 0x0f, 0xc4, 0xba, 0x22,
+ 0x38, 0x9c, 0xd2, 0xfe, 0x33, 0xe8, 0xa6, 0xa8, 0xad, 0x89, 0x40, 0xa6, 0x87, 0x79, 0x75, 0xca,
+ 0xd8, 0x4d, 0xcf, 0xa3, 0x22, 0x4a, 0xca, 0xd6, 0xbc, 0x29, 0xf3, 0x09, 0xdc, 0x3e, 0x46, 0x4c,
+ 0x7a, 0xc3, 0x61, 0xaa, 0x13, 0x91, 0xcc, 0x56, 0xa0, 0x74, 0x8c, 0x5c, 0x61, 0x7c, 0xc9, 0xe2,
+ 0x43, 0x7e, 0x00, 0x4f, 0x22, 0xe4, 0x0a, 0x2b, 0x4b, 0x96, 0x18, 0x9b, 0xbf, 0x2f, 0x40, 0x45,
+ 0x25, 0x67, 0x7e, 0xc1, 0x78, 0x14, 0x5f, 0x20, 0xaa, 0x8e, 0x9e, 0x82, 0x8c, 0x57, 0xa0, 0x25,
+ 0x47, 0x36, 0x09, 0x19, 0x26, 0x49, 0xca, 0x6f, 0x4a, 0xec, 0x91, 0x44, 0x8a, 0xc7, 0x37, 0xf1,
+ 0xfc, 0xa5, 0x3a, 0x4d, 0x05, 0x71, 0xfc, 0x59, 0xc4, 0x23, 0x5c, 0xa4, 0xf8, 0x9a, 0xa5, 0x20,
+ 0x7e, 0xd4, 0x35, 0xbf, 0x25, 0xc1, 0x4f, 0x83, 0xfc, 0xa8, 0xfb, 0x24, 0x0e, 0x98, 0x1d, 0x12,
+ 0x1c, 0x30, 0x95, 0xd3, 0x41, 0xa0, 0x06, 0x1c, 0x63, 0xfe, 0xa2, 0x00, 0xcb, 0xf2, 0x01, 0x9a,
+ 0xf7, 0xb6, 0xc9, 0xcd, 0x5a, 0xc4, 0xa2, 0x4a, 0x11, 0xb2, 0xe4, 0x6d, 0x2a, 0xc6, 0x3c, 0x8e,
+ 0x2f, 0x7c, 0x79, 0x3f, 0x28, 0xd5, 0x2e, 0x7c, 0x71, 0x31, 0xbc, 0x02, 0xad, 0xf4, 0x82, 0x16,
+ 0xf3, 0x52, 0xc5, 0x66, 0x82, 0x15, 0x64, 0x0b, 0x35, 0x35, 0xff, 0x8f, 0xb7, 0xf4, 0xc9, 0xe3,
+ 0xeb, 0x0a, 0x94, 0xe2, 0x44, 0x19, 0x3e, 0xe4, 0x98, 0x61, 0x72, 0xb5, 0xf3, 0xa1, 0x71, 0x1f,
+ 0x5a, 0x8e, 0xe7, 0x61, 0xbe, 0xdc, 0x19, 0xef, 0x61, 0x2f, 0x09, 0xd2, 0x3c, 0xd6, 0xfc, 0x73,
+ 0x01, 0xda, 0xdb, 0x24, 0x9c, 0x7c, 0x8c, 0xc7, 0x28, 0x93, 0x41, 0x84, 0x92, 0xea, 0x66, 0xe7,
+ 0x63, 0x5e, 0xad, 0x9e, 0xe1, 0x31, 0x92, 0xa1, 0x25, 0x77, 0xb6, 0xca, 0x11, 0x22, 0xac, 0xf4,
+ 0x64, 0xf2, 0xec, 0xd6, 0x94, 0x93, 0x87, 0xc4, 0x13, 0x75, 0xb9, 0x87, 0xa9, 0x9d, 0x3c, 0xb2,
+ 0x35, 0xad, 0x8a, 0x87, 0xa9, 0x98, 0x52, 0x86, 0x2c, 0x89, 0x47, 0xd4, 0xac, 0x21, 0xcb, 0x12,
+ 0xc3, 0x0d, 0x59, 0x87, 0x65, 0x72, 0x76, 0x16, 0x21, 0x26, 0x2a, 0xe8, 0x92, 0xa5, 0xa0, 0x24,
+ 0xcd, 0x55, 0x33, 0x69, 0x6e, 0x0d, 0x8c, 0x3d, 0xc4, 0x8e, 0x8e, 0x0e, 0x77, 0x2f, 0x50, 0xc0,
+ 0xf4, 0xed, 0xf0, 0x26, 0x54, 0x35, 0xea, 0x5f, 0x79, 0x9e, 0x7c, 0x1d, 0x5a, 0x9b, 0x9e, 0x77,
+ 0xfc, 0xd4, 0x09, 0xb5, 0x3f, 0xba, 0x50, 0x19, 0x6c, 0x1f, 0x0c, 0xa4, 0x4b, 0x4a, 0xdc, 0x00,
+ 0x05, 0xf2, 0xdb, 0x68, 0x0f, 0xb1, 0x43, 0xc4, 0x28, 0x76, 0x93, 0xdb, 0xe8, 0x1e, 0x54, 0x14,
+ 0x86, 0xaf, 0xf4, 0xe5, 0x50, 0xa7, 0x59, 0x05, 0x3e, 0xfa, 0xc3, 0x8a, 0xca, 0xc8, 0xaa, 0xb9,
+ 0x37, 0xf6, 0xa0, 0x3d, 0xf5, 0x25, 0xc6, 0x50, 0xaf, 0x3d, 0xf3, 0x3f, 0xd0, 0xf4, 0xd6, 0xfb,
+ 0xf2, 0xcb, 0x4e, 0x5f, 0x7f, 0xd9, 0xe9, 0xef, 0xfa, 0x21, 0x9b, 0x18, 0xbb, 0xd0, 0xca, 0x7f,
+ 0xb3, 0x30, 0x9e, 0xd7, 0xc5, 0xd1, 0x9c, 0x2f, 0x19, 0x0b, 0xd9, 0xec, 0x41, 0x7b, 0xea, 0xf3,
+ 0x85, 0xd6, 0x67, 0xfe, 0x57, 0x8d, 0x85, 0x8c, 0x9e, 0x40, 0x3d, 0xf3, 0xbd, 0xc2, 0xe8, 0x4a,
+ 0x26, 0xb3, 0x9f, 0x30, 0x16, 0x32, 0xd8, 0x86, 0x66, 0xee, 0x13, 0x82, 0xd1, 0x53, 0xf6, 0xcc,
+ 0xf9, 0xae, 0xb0, 0x90, 0xc9, 0x16, 0xd4, 0x33, 0x2f, 0xf9, 0x5a, 0x8b, 0xd9, 0xcf, 0x05, 0xbd,
+ 0x3b, 0x73, 0x66, 0x54, 0xe2, 0xdf, 0x83, 0xf6, 0xd4, 0xf3, 0xbe, 0x76, 0xc9, 0xfc, 0x57, 0xff,
+ 0x85, 0xca, 0x7c, 0x2a, 0xb6, 0x28, 0xd3, 0xbd, 0x65, 0xb6, 0x68, 0xf6, 0x31, 0xbf, 0xf7, 0xc2,
+ 0xfc, 0x49, 0xa5, 0xd5, 0x2e, 0xb4, 0xf2, 0xef, 0xf8, 0x9a, 0xd9, 0xdc, 0xd7, 0xfd, 0xab, 0xf7,
+ 0x3b, 0xf7, 0xa4, 0x9f, 0xee, 0xf7, 0xbc, 0x97, 0xfe, 0x85, 0x8c, 0x36, 0x01, 0x54, 0xaf, 0xe6,
+ 0xe1, 0x20, 0x71, 0xf4, 0x4c, 0x8f, 0x98, 0x38, 0x7a, 0x4e, 0x5f, 0xf7, 0x04, 0x40, 0xb6, 0x58,
+ 0x1e, 0x89, 0x99, 0x71, 0x5b, 0xab, 0x31, 0xd5, 0xd7, 0xf5, 0xba, 0xb3, 0x13, 0x33, 0x0c, 0x10,
+ 0xa5, 0xd7, 0x61, 0xf0, 0x11, 0x40, 0xda, 0xba, 0x69, 0x06, 0x33, 0xcd, 0xdc, 0x15, 0x3e, 0x68,
+ 0x64, 0x1b, 0x35, 0x43, 0xd9, 0x3a, 0xa7, 0x79, 0xbb, 0x82, 0x45, 0x7b, 0xaa, 0x10, 0xcf, 0x1f,
+ 0xb6, 0xe9, 0xfa, 0xbc, 0x37, 0x53, 0x8c, 0x1b, 0x8f, 0xa1, 0x91, 0xad, 0xc0, 0xb5, 0x16, 0x73,
+ 0xaa, 0xf2, 0x5e, 0xae, 0x0a, 0x37, 0x9e, 0x40, 0x2b, 0x5f, 0x7d, 0xeb, 0x23, 0x35, 0xb7, 0x26,
+ 0xef, 0xa9, 0xb7, 0xa5, 0x0c, 0xf9, 0x3b, 0x00, 0x69, 0x95, 0xae, 0xdd, 0x37, 0x53, 0xb7, 0x4f,
+ 0x49, 0xdd, 0x83, 0xf6, 0x54, 0xf5, 0xad, 0x2d, 0x9e, 0x5f, 0x94, 0x2f, 0x74, 0xdd, 0xbb, 0x00,
+ 0x69, 0x56, 0xd6, 0xd2, 0x67, 0xf2, 0x74, 0xaf, 0xa9, 0xdf, 0xdd, 0x24, 0xdd, 0x36, 0x34, 0x73,
+ 0xad, 0xa9, 0x4e, 0x33, 0xf3, 0xfa, 0xd5, 0xab, 0x92, 0x6f, 0xbe, 0x8f, 0xd3, 0x9e, 0x9b, 0xdb,
+ 0xdd, 0x5d, 0x75, 0x7e, 0xb2, 0xcd, 0x83, 0xde, 0xb9, 0x39, 0x0d, 0xc5, 0x0f, 0xc4, 0x73, 0xb6,
+ 0x41, 0xc8, 0xc4, 0xf3, 0x9c, 0xbe, 0x61, 0x21, 0xa3, 0x7d, 0x68, 0xef, 0xe9, 0xda, 0x4f, 0xd5,
+ 0xa5, 0x4a, 0x9d, 0x39, 0x75, 0x78, 0xaf, 0x37, 0x6f, 0x4a, 0x05, 0xd5, 0xa7, 0xd0, 0x99, 0xa9,
+ 0x49, 0x8d, 0x8d, 0xe4, 0xf5, 0x73, 0x6e, 0xb1, 0xba, 0x50, 0xad, 0x03, 0x58, 0x99, 0x2e, 0x49,
+ 0x8d, 0x17, 0x55, 0xa2, 0x9c, 0x5f, 0xaa, 0x2e, 0x64, 0xf5, 0x3e, 0x54, 0x75, 0x09, 0x64, 0xa8,
+ 0x57, 0xe6, 0xa9, 0x92, 0x68, 0xe1, 0xd2, 0xc7, 0x50, 0xcf, 0x54, 0x1c, 0x3a, 0xdb, 0xcd, 0x16,
+ 0x21, 0x3d, 0xf5, 0x28, 0x9c, 0x50, 0x3e, 0x86, 0x8a, 0xaa, 0x32, 0x8c, 0xb5, 0xe4, 0x90, 0x67,
+ 0x8a, 0x8e, 0x45, 0x12, 0xb7, 0x2e, 0xbf, 0xfb, 0x7e, 0xe3, 0xb9, 0xbf, 0x7e, 0xbf, 0xf1, 0xdc,
+ 0xcf, 0x9f, 0x6d, 0x14, 0xbe, 0x7b, 0xb6, 0x51, 0xf8, 0xcb, 0xb3, 0x8d, 0xc2, 0xdf, 0x9f, 0x6d,
+ 0x14, 0xfe, 0xff, 0x27, 0xff, 0xe6, 0x5f, 0x4b, 0x68, 0x1c, 0x30, 0xec, 0xa3, 0x87, 0x17, 0x98,
+ 0xb2, 0xcc, 0x54, 0x78, 0x3e, 0x9c, 0xf9, 0xd7, 0x09, 0x57, 0xf0, 0x74, 0x59, 0xc0, 0xef, 0xfc,
+ 0x33, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x41, 0xae, 0xa1, 0xc3, 0x22, 0x00, 0x00,
}
func (m *CreateContainerRequest) Marshal() (dAtA []byte, err error) {
@@ -5359,60 +5278,6 @@ func (m *CopyFileRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
-func (m *StartTracingRequest) Marshal() (dAtA []byte, err error) {
- size := m.Size()
- dAtA = make([]byte, size)
- n, err := m.MarshalToSizedBuffer(dAtA[:size])
- if err != nil {
- return nil, err
- }
- return dAtA[:n], nil
-}
-
-func (m *StartTracingRequest) MarshalTo(dAtA []byte) (int, error) {
- size := m.Size()
- return m.MarshalToSizedBuffer(dAtA[:size])
-}
-
-func (m *StartTracingRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
- i := len(dAtA)
- _ = i
- var l int
- _ = l
- if m.XXX_unrecognized != nil {
- i -= len(m.XXX_unrecognized)
- copy(dAtA[i:], m.XXX_unrecognized)
- }
- return len(dAtA) - i, nil
-}
-
-func (m *StopTracingRequest) Marshal() (dAtA []byte, err error) {
- size := m.Size()
- dAtA = make([]byte, size)
- n, err := m.MarshalToSizedBuffer(dAtA[:size])
- if err != nil {
- return nil, err
- }
- return dAtA[:n], nil
-}
-
-func (m *StopTracingRequest) MarshalTo(dAtA []byte) (int, error) {
- size := m.Size()
- return m.MarshalToSizedBuffer(dAtA[:size])
-}
-
-func (m *StopTracingRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
- i := len(dAtA)
- _ = i
- var l int
- _ = l
- if m.XXX_unrecognized != nil {
- i -= len(m.XXX_unrecognized)
- copy(dAtA[i:], m.XXX_unrecognized)
- }
- return len(dAtA) - i, nil
-}
-
func (m *GetOOMEventRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -6796,30 +6661,6 @@ func (m *CopyFileRequest) Size() (n int) {
return n
}
-func (m *StartTracingRequest) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- if m.XXX_unrecognized != nil {
- n += len(m.XXX_unrecognized)
- }
- return n
-}
-
-func (m *StopTracingRequest) Size() (n int) {
- if m == nil {
- return 0
- }
- var l int
- _ = l
- if m.XXX_unrecognized != nil {
- n += len(m.XXX_unrecognized)
- }
- return n
-}
-
func (m *GetOOMEventRequest) Size() (n int) {
if m == nil {
return 0
@@ -7656,26 +7497,6 @@ func (this *CopyFileRequest) String() string {
}, "")
return s
}
-func (this *StartTracingRequest) String() string {
- if this == nil {
- return "nil"
- }
- s := strings.Join([]string{`&StartTracingRequest{`,
- `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *StopTracingRequest) String() string {
- if this == nil {
- return "nil"
- }
- s := strings.Join([]string{`&StopTracingRequest{`,
- `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
- `}`,
- }, "")
- return s
-}
func (this *GetOOMEventRequest) String() string {
if this == nil {
return "nil"
@@ -7759,8 +7580,6 @@ type AgentServiceService interface {
ListInterfaces(ctx context.Context, req *ListInterfacesRequest) (*Interfaces, error)
ListRoutes(ctx context.Context, req *ListRoutesRequest) (*Routes, error)
AddARPNeighbors(ctx context.Context, req *AddARPNeighborsRequest) (*types.Empty, error)
- StartTracing(ctx context.Context, req *StartTracingRequest) (*types.Empty, error)
- StopTracing(ctx context.Context, req *StopTracingRequest) (*types.Empty, error)
GetMetrics(ctx context.Context, req *GetMetricsRequest) (*Metrics, error)
CreateSandbox(ctx context.Context, req *CreateSandboxRequest) (*types.Empty, error)
DestroySandbox(ctx context.Context, req *DestroySandboxRequest) (*types.Empty, error)
@@ -7916,20 +7735,6 @@ func RegisterAgentServiceService(srv *github_com_containerd_ttrpc.Server, svc Ag
}
return svc.AddARPNeighbors(ctx, &req)
},
- "StartTracing": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
- var req StartTracingRequest
- if err := unmarshal(&req); err != nil {
- return nil, err
- }
- return svc.StartTracing(ctx, &req)
- },
- "StopTracing": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
- var req StopTracingRequest
- if err := unmarshal(&req); err != nil {
- return nil, err
- }
- return svc.StopTracing(ctx, &req)
- },
"GetMetrics": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req GetMetricsRequest
if err := unmarshal(&req); err != nil {
@@ -8180,22 +7985,6 @@ func (c *agentServiceClient) AddARPNeighbors(ctx context.Context, req *AddARPNei
return &resp, nil
}
-func (c *agentServiceClient) StartTracing(ctx context.Context, req *StartTracingRequest) (*types.Empty, error) {
- var resp types.Empty
- if err := c.client.Call(ctx, "grpc.AgentService", "StartTracing", req, &resp); err != nil {
- return nil, err
- }
- return &resp, nil
-}
-
-func (c *agentServiceClient) StopTracing(ctx context.Context, req *StopTracingRequest) (*types.Empty, error) {
- var resp types.Empty
- if err := c.client.Call(ctx, "grpc.AgentService", "StopTracing", req, &resp); err != nil {
- return nil, err
- }
- return &resp, nil
-}
-
func (c *agentServiceClient) GetMetrics(ctx context.Context, req *GetMetricsRequest) (*Metrics, error) {
var resp Metrics
if err := c.client.Call(ctx, "grpc.AgentService", "GetMetrics", req, &resp); err != nil {
@@ -15214,108 +15003,6 @@ func (m *CopyFileRequest) Unmarshal(dAtA []byte) error {
}
return nil
}
-func (m *StartTracingRequest) Unmarshal(dAtA []byte) error {
- l := len(dAtA)
- iNdEx := 0
- for iNdEx < l {
- preIndex := iNdEx
- var wire uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowAgent
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- wire |= uint64(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- fieldNum := int32(wire >> 3)
- wireType := int(wire & 0x7)
- if wireType == 4 {
- return fmt.Errorf("proto: StartTracingRequest: wiretype end group for non-group")
- }
- if fieldNum <= 0 {
- return fmt.Errorf("proto: StartTracingRequest: illegal tag %d (wire type %d)", fieldNum, wire)
- }
- switch fieldNum {
- default:
- iNdEx = preIndex
- skippy, err := skipAgent(dAtA[iNdEx:])
- if err != nil {
- return err
- }
- if (skippy < 0) || (iNdEx+skippy) < 0 {
- return ErrInvalidLengthAgent
- }
- if (iNdEx + skippy) > l {
- return io.ErrUnexpectedEOF
- }
- m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
- iNdEx += skippy
- }
- }
-
- if iNdEx > l {
- return io.ErrUnexpectedEOF
- }
- return nil
-}
-func (m *StopTracingRequest) Unmarshal(dAtA []byte) error {
- l := len(dAtA)
- iNdEx := 0
- for iNdEx < l {
- preIndex := iNdEx
- var wire uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowAgent
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- wire |= uint64(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- fieldNum := int32(wire >> 3)
- wireType := int(wire & 0x7)
- if wireType == 4 {
- return fmt.Errorf("proto: StopTracingRequest: wiretype end group for non-group")
- }
- if fieldNum <= 0 {
- return fmt.Errorf("proto: StopTracingRequest: illegal tag %d (wire type %d)", fieldNum, wire)
- }
- switch fieldNum {
- default:
- iNdEx = preIndex
- skippy, err := skipAgent(dAtA[iNdEx:])
- if err != nil {
- return err
- }
- if (skippy < 0) || (iNdEx+skippy) < 0 {
- return ErrInvalidLengthAgent
- }
- if (iNdEx + skippy) > l {
- return io.ErrUnexpectedEOF
- }
- m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
- iNdEx += skippy
- }
- }
-
- if iNdEx > l {
- return io.ErrUnexpectedEOF
- }
- return nil
-}
func (m *GetOOMEventRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
diff --git a/src/runtime/virtcontainers/pkg/mock/mock.go b/src/runtime/virtcontainers/pkg/mock/mock.go
index fae69d8ba..53e2a5259 100644
--- a/src/runtime/virtcontainers/pkg/mock/mock.go
+++ b/src/runtime/virtcontainers/pkg/mock/mock.go
@@ -203,14 +203,6 @@ func (p *HybridVSockTTRPCMockImp) CopyFile(ctx context.Context, req *pb.CopyFile
return &gpb.Empty{}, nil
}
-func (p *HybridVSockTTRPCMockImp) StartTracing(ctx context.Context, req *pb.StartTracingRequest) (*gpb.Empty, error) {
- return &gpb.Empty{}, nil
-}
-
-func (p *HybridVSockTTRPCMockImp) StopTracing(ctx context.Context, req *pb.StopTracingRequest) (*gpb.Empty, error) {
- return &gpb.Empty{}, nil
-}
-
func (p *HybridVSockTTRPCMockImp) MemHotplugByProbe(ctx context.Context, req *pb.MemHotplugByProbeRequest) (*gpb.Empty, error) {
return &gpb.Empty{}, nil
}
diff --git a/src/runtime/virtcontainers/pkg/oci/utils.go b/src/runtime/virtcontainers/pkg/oci/utils.go
index d6fc10d8d..c4413ec03 100644
--- a/src/runtime/virtcontainers/pkg/oci/utils.go
+++ b/src/runtime/virtcontainers/pkg/oci/utils.go
@@ -17,7 +17,7 @@ import (
"strings"
"syscall"
- criContainerdAnnotations "github.com/containerd/containerd/pkg/cri/annotations"
+ criContainerdAnnotations "github.com/containerd/cri-containerd/pkg/annotations"
crioAnnotations "github.com/cri-o/cri-o/pkg/annotations"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
diff --git a/src/runtime/virtcontainers/qemu_arch_base.go b/src/runtime/virtcontainers/qemu_arch_base.go
index fb3a8876c..deec2b817 100644
--- a/src/runtime/virtcontainers/qemu_arch_base.go
+++ b/src/runtime/virtcontainers/qemu_arch_base.go
@@ -159,22 +159,22 @@ const (
//Intel Trust Domain Extensions
//https://software.intel.com/content/www/us/en/develop/articles/intel-trust-domain-extensions.html
// Exclude from lint checking for it won't be used on arm64 code
- tdxProtection //nolint
+ tdxProtection
// AMD Secure Encrypted Virtualization
// https://developer.amd.com/sev/
// Exclude from lint checking for it won't be used on arm64 code
- sevProtection //nolint
+ sevProtection
// IBM POWER 9 Protected Execution Facility
// https://www.kernel.org/doc/html/latest/powerpc/ultravisor.html
// Exclude from lint checking for it won't be used on arm64 code
- pefProtection //nolint
+ pefProtection
// IBM Secure Execution (IBM Z & LinuxONE)
// https://www.kernel.org/doc/html/latest/virt/kvm/s390-pv.html
// Exclude from lint checking for it won't be used on arm64 code
- seProtection //nolint
+ seProtection
)
var guestProtectionStr = [...]string{
diff --git a/src/runtime/virtcontainers/qemu_arm64_test.go b/src/runtime/virtcontainers/qemu_arm64_test.go
index 56fe5deb7..bb03204b9 100644
--- a/src/runtime/virtcontainers/qemu_arm64_test.go
+++ b/src/runtime/virtcontainers/qemu_arm64_test.go
@@ -170,3 +170,46 @@ func TestQemuArm64WithInitrd(t *testing.T) {
assert.NotContains(arm64.machine().Options, qemuNvdimmOption)
}
+
+func TestQemuArm64AppendProtectionDevice(t *testing.T) {
+ assert := assert.New(t)
+ arm64 := newTestQemu(assert, QemuVirt)
+
+ var devices []govmmQemu.Device
+ var bios, firmware string
+ var err error
+
+ // no protection
+ devices, bios, err = arm64.appendProtectionDevice(devices, firmware)
+ assert.Empty(devices)
+ assert.Empty(bios)
+ assert.NoError(err)
+
+ // PEF protection
+ arm64.(*qemuArm64).protection = pefProtection
+ devices, bios, err = arm64.appendProtectionDevice(devices, firmware)
+ assert.Empty(devices)
+ assert.Empty(bios)
+ assert.NoError(err)
+
+ // Secure Execution protection
+ arm64.(*qemuArm64).protection = seProtection
+ devices, bios, err = arm64.appendProtectionDevice(devices, firmware)
+ assert.Empty(devices)
+ assert.Empty(bios)
+ assert.NoError(err)
+
+ // SEV protection
+ arm64.(*qemuArm64).protection = sevProtection
+ devices, bios, err = arm64.appendProtectionDevice(devices, firmware)
+ assert.Empty(devices)
+ assert.Empty(bios)
+ assert.NoError(err)
+
+ // TDX protection
+ arm64.(*qemuArm64).protection = tdxProtection
+ devices, bios, err = arm64.appendProtectionDevice(devices, firmware)
+ assert.Empty(devices)
+ assert.Empty(bios)
+ assert.NoError(err)
+}
diff --git a/tools/agent-ctl/Cargo.lock b/tools/agent-ctl/Cargo.lock
index 4bcca80f9..922d48626 100644
--- a/tools/agent-ctl/Cargo.lock
+++ b/tools/agent-ctl/Cargo.lock
@@ -818,6 +818,10 @@ name = "protobuf"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485"
+dependencies = [
+ "serde",
+ "serde_derive",
+]
[[package]]
name = "protobuf-codegen"
@@ -844,6 +848,8 @@ version = "0.1.0"
dependencies = [
"async-trait",
"protobuf",
+ "serde",
+ "serde_json",
"ttrpc",
"ttrpc-codegen",
]
@@ -1050,18 +1056,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
-version = "1.0.126"
+version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
+checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.126"
+version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
+checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
dependencies = [
"proc-macro2 1.0.26",
"quote 1.0.9",
@@ -1070,9 +1076,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.64"
+version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
+checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
dependencies = [
"itoa",
"ryu",
diff --git a/tools/agent-ctl/Cargo.toml b/tools/agent-ctl/Cargo.toml
index 95e640edd..e6bd1727a 100644
--- a/tools/agent-ctl/Cargo.toml
+++ b/tools/agent-ctl/Cargo.toml
@@ -10,7 +10,7 @@ authors = ["The Kata Containers community "]
edition = "2018"
[dependencies]
-protocols = { path = "../../src/agent/protocols" }
+protocols = { path = "../../src/agent/protocols", features = ["with-serde"] }
rustjail = { path = "../../src/agent/rustjail" }
oci = { path = "../../src/agent/oci" }
@@ -20,6 +20,8 @@ anyhow = "1.0.31"
hex = "0.4.2"
byteorder = "1.3.4"
+# Note: this crate sets the slog 'max_*' features which allows the log level
+# to be modified at runtime.
logging = { path = "../../pkg/logging" }
slog = "2.5.2"
slog-scope = "4.3.0"
@@ -35,5 +37,5 @@ ttrpc = { version = "0.5.0" }
humantime = "2.0.0"
# For Options (state passing)
-serde = { version = "1.0.110", features = ["derive"] }
-serde_json = "1.0.53"
+serde = { version = "1.0.130", features = ["derive"] }
+serde_json = "1.0.68"
diff --git a/tools/agent-ctl/README.md b/tools/agent-ctl/README.md
index f4c42e508..fa2caf99d 100644
--- a/tools/agent-ctl/README.md
+++ b/tools/agent-ctl/README.md
@@ -60,6 +60,49 @@ $ mkdir -p "$rootfs_dir" && (cd "$bundle_dir" && runc spec)
$ sudo docker export $(sudo docker create "$image") | tar -C "$rootfs_dir" -xvf -
```
+
+### Specify API commands to run
+
+The tool allows one or more API commands to be specified using the `-c` or
+`--cmd` command-line options. At their simplest, these are just the name of
+the API commands, which will make the API command using default values
+(generally blank or empty) where possible. However, some API calls require
+some basic value to be specified such as a sandbox ID or container ID. For
+these calls, the tool will generate a value by default unless told not to.
+
+If the user wishes to, they may specify these values as part of the command
+using `name=value` syntax.
+
+In addition to this, it is possible to specify either a complete or partial
+set of values for the API call using JSON syntax, either directly on the
+command-line or via a file URI.
+
+The table below summarises the possible ways of specifying an API call to
+make.
+
+| CLI values | API Query |
+|-|-|
+| `-c 'SomeAPIName' -n` | Calls the API using the default values for all request options |
+| `-c 'SomeAPIName'` | Calls the API specifying some values automatically if possible |
+| `-c 'SomeAPIName foo=bar baz="hello world" x=3 y="a cat"'` | Calls the API specifying various values in name/value form |
+| `-c 'SomeAPIName json://{}' -n` | Calls the API specifying empty values via an empty JSON document |
+| `-c 'SomeAPIName json://{"foo": true, "bar": "hello world"}' -n` | Calls the API specifying _some_ values in JSON syntax |
+| `-c 'SomeAPIName file:///foo.json' -n` | Calls the API passing the JSON values from the specified file |
+
+#### JSON Example
+
+An example showing how to specify the messages fields for an API call
+(`GetGuestDetails`):
+
+```sh
+$ cargo run -- -l debug connect --server-address "unix://@/tmp/foo.socket" --bundle-dir "$bundle_dir" -c Check -c 'GetGuestDetails json://{"mem_block_size": true, "mem_hotplug_probe": true}'
+```
+
+> **Note:**
+>
+> For details of the names of the APIs to call and the available fields
+> in each API, see the [Code Summary](#code-summary) section.
+
### Connect to a real Kata Container
The method used to connect to Kata Containers agent depends on the configured
diff --git a/tools/agent-ctl/src/client.rs b/tools/agent-ctl/src/client.rs
index 771906ada..551bf9c46 100644
--- a/tools/agent-ctl/src/client.rs
+++ b/tools/agent-ctl/src/client.rs
@@ -27,6 +27,23 @@ use std::time::Duration;
use ttrpc;
use ttrpc::context::Context;
+// Run the specified closure to set an automatic value if the ttRPC Context
+// does not contain the special values requesting automatic values be
+// suppressed.
+macro_rules! run_if_auto_values {
+ ($ctx:expr, $closure:expr) => {{
+ let cfg = $ctx.metadata.get(METADATA_CFG_NS);
+
+ if let Some(v) = cfg {
+ if v.contains(&NO_AUTO_VALUES_CFG_NAME.to_string()) {
+ debug!(sl!(), "Running closure to generate values");
+
+ $closure()?;
+ }
+ }
+ }};
+}
+
// Hack until the actual Context type supports this.
fn clone_context(ctx: &Context) -> Context {
Context {
@@ -86,6 +103,13 @@ const DEFAULT_PROC_SIGNAL: &'static str = "SIGKILL";
const ERR_API_FAILED: &str = "API failed";
+// Value used as a "namespace" in the ttRPC Context's metadata.
+const METADATA_CFG_NS: &str = "agent-ctl-cfg";
+
+// Special value which if found means do not generate any values
+// automatically.
+const NO_AUTO_VALUES_CFG_NAME: &str = "no-auto-values";
+
static AGENT_CMDS: &'static [AgentCmd] = &[
AgentCmd {
name: "AddARPNeighbors",
@@ -217,21 +241,11 @@ static AGENT_CMDS: &'static [AgentCmd] = &[
st: ServiceType::Agent,
fp: agent_cmd_container_start,
},
- AgentCmd {
- name: "StartTracing",
- st: ServiceType::Agent,
- fp: agent_cmd_sandbox_tracing_start,
- },
AgentCmd {
name: "StatsContainer",
st: ServiceType::Agent,
fp: agent_cmd_container_stats,
},
- AgentCmd {
- name: "StopTracing",
- st: ServiceType::Agent,
- fp: agent_cmd_sandbox_tracing_stop,
- },
AgentCmd {
name: "TtyWinResize",
st: ServiceType::Agent,
@@ -331,7 +345,7 @@ fn get_agent_cmd_details() -> Vec {
fn get_agent_cmd_func(name: &str) -> Result {
for cmd in AGENT_CMDS {
- if cmd.name == name {
+ if cmd.name.eq(name) {
return Ok(cmd.fp);
}
}
@@ -359,7 +373,7 @@ fn get_all_cmd_details() -> Vec {
fn get_builtin_cmd_func(name: &str) -> Result {
for cmd in BUILTIN_CMDS {
- if cmd.name == name {
+ if cmd.name.eq(name) {
return Ok(cmd.fp);
}
}
@@ -436,7 +450,7 @@ fn create_ttrpc_client(
hybrid_vsock_port: u64,
hybrid_vsock: bool,
) -> Result {
- if server_address == "" {
+ if server_address.is_empty() {
return Err(anyhow!("server address cannot be blank"));
}
@@ -583,7 +597,7 @@ fn announce(cfg: &Config) {
}
pub fn client(cfg: &Config, commands: Vec<&str>) -> Result<()> {
- if commands.len() == 1 && commands[0] == "list" {
+ if commands.len() == 1 && commands[0].eq("list") {
println!("Built-in commands:\n");
let mut builtin_cmds = get_builtin_cmd_details();
@@ -626,7 +640,16 @@ pub fn client(cfg: &Config, commands: Vec<&str>) -> Result<()> {
let mut options = Options::new();
- let ttrpc_ctx = ttrpc::context::with_timeout(cfg.timeout_nano);
+ let mut ttrpc_ctx = ttrpc::context::with_timeout(cfg.timeout_nano);
+
+ // Allow the commands to change their behaviour based on the value
+ // of this option.
+
+ if !cfg.no_auto_values {
+ ttrpc_ctx.add(METADATA_CFG_NS.into(), NO_AUTO_VALUES_CFG_NAME.to_string());
+
+ debug!(sl!(), "Automatic value generation disabled");
+ }
// Special-case loading the OCI config file so it is accessible
// to all commands.
@@ -691,7 +714,7 @@ fn handle_cmd(
let cmd = fields[0];
- if cmd == "" {
+ if cmd.is_empty() {
// Ignore empty commands
return (Ok(()), false);
}
@@ -792,7 +815,7 @@ fn handle_agent_cmd(
return (result, false);
}
- let shutdown = cmd == SHUTDOWN_CMD;
+ let shutdown = cmd.eq(SHUTDOWN_CMD);
(Ok(()), shutdown)
}
@@ -816,7 +839,7 @@ fn interactive_client_loop(
let cmdline =
readline("Enter command").map_err(|e| anyhow!(e).context("failed to read line"))?;
- if cmdline == "" {
+ if cmdline.is_empty() {
continue;
}
@@ -873,15 +896,12 @@ fn agent_cmd_health_check(
health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let mut req = CheckRequest::default();
+ let req: CheckRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- // value unused
- req.set_service("".to_string());
-
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
let reply = health
@@ -900,16 +920,13 @@ fn agent_cmd_health_version(
health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
// XXX: Yes, the API is actually broken!
- let mut req = CheckRequest::default();
+ let req: CheckRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- // value unused
- req.set_service("".to_string());
-
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
let reply = health
@@ -930,12 +947,16 @@ fn agent_cmd_sandbox_create(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = CreateSandboxRequest::default();
+ let mut req: CreateSandboxRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let sid = utils::get_option("sid", options, args);
- req.set_sandbox_id(sid);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let sid = utils::get_option("sid", options, args)?;
+ req.set_sandbox_id(sid);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -955,9 +976,9 @@ fn agent_cmd_sandbox_destroy(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = DestroySandboxRequest::default();
+ let req: DestroySandboxRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -981,20 +1002,23 @@ fn agent_cmd_container_create(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = CreateContainerRequest::default();
+ let mut req: CreateContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
-
// FIXME: container create: add back "spec=file:///" support
- let ttrpc_spec = utils::get_ttrpc_spec(options, &cid).map_err(|e| anyhow!(e))?;
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
+ let ttrpc_spec = utils::get_ttrpc_spec(options, &cid).map_err(|e| anyhow!(e))?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
- req.set_OCI(ttrpc_spec);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
+ req.set_OCI(ttrpc_spec);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1016,13 +1040,15 @@ fn agent_cmd_container_remove(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = RemoveContainerRequest::default();
-
- let cid = utils::get_option("cid", options, args);
+ let mut req: RemoveContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- req.set_container_id(cid);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ req.set_container_id(cid);
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1044,32 +1070,36 @@ fn agent_cmd_container_exec(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = ExecProcessRequest::default();
+ let mut req: ExecProcessRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- let ttrpc_spec = utils::get_ttrpc_spec(options, &cid).map_err(|e| anyhow!(e))?;
+ let ttrpc_spec = utils::get_ttrpc_spec(options, &cid).map_err(|e| anyhow!(e))?;
- let bundle_dir = options
- .get("bundle-dir")
- .ok_or("BUG: bundle-dir missing")
- .map_err(|e| anyhow!(e))?;
+ let bundle_dir = options
+ .get("bundle-dir")
+ .ok_or("BUG: bundle-dir missing")
+ .map_err(|e| anyhow!(e))?;
- let process = ttrpc_spec
- .Process
- .into_option()
- .ok_or(format!(
- "failed to get process from OCI spec: {}",
- bundle_dir,
- ))
- .map_err(|e| anyhow!(e))?;
+ let process = ttrpc_spec
+ .Process
+ .into_option()
+ .ok_or(format!(
+ "failed to get process from OCI spec: {}",
+ bundle_dir,
+ ))
+ .map_err(|e| anyhow!(e))?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
- req.set_process(process);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
+ req.set_process(process);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1091,13 +1121,16 @@ fn agent_cmd_container_stats(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = StatsContainerRequest::default();
+ let mut req: StatsContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
- req.set_container_id(cid);
+ req.set_container_id(cid);
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1119,13 +1152,16 @@ fn agent_cmd_container_pause(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = PauseContainerRequest::default();
+ let mut req: PauseContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
- req.set_container_id(cid);
+ req.set_container_id(cid);
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1147,13 +1183,16 @@ fn agent_cmd_container_resume(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = ResumeContainerRequest::default();
-
- let cid = utils::get_option("cid", options, args);
+ let mut req: ResumeContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- req.set_container_id(cid);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+
+ req.set_container_id(cid);
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1175,13 +1214,16 @@ fn agent_cmd_container_start(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = StartContainerRequest::default();
+ let mut req: StartContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
- req.set_container_id(cid);
+ req.set_container_id(cid);
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1201,13 +1243,18 @@ fn agent_cmd_sandbox_get_guest_details(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let mut req = GuestDetailsRequest::default();
+ let mut req: GuestDetailsRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- req.set_mem_block_size(true);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ req.set_mem_block_size(true);
+ req.set_mem_hotplug_probe(true);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1229,15 +1276,19 @@ fn agent_cmd_container_wait_process(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = WaitProcessRequest::default();
+ let mut req: WaitProcessRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1259,25 +1310,29 @@ fn agent_cmd_container_signal_process(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = SignalProcessRequest::default();
+ let mut req: SignalProcessRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- let mut sigstr = utils::get_option("signal", options, args);
+ let mut sigstr = utils::get_option("signal", options, args)?;
- // Convert to a numeric
- if sigstr == "" {
- sigstr = DEFAULT_PROC_SIGNAL.to_string();
- }
+ // Convert to a numeric
+ if sigstr.is_empty() {
+ sigstr = DEFAULT_PROC_SIGNAL.to_string();
+ }
- let signum = utils::signame_to_signum(&sigstr).map_err(|e| anyhow!(e))?;
+ let signum = utils::signame_to_signum(&sigstr).map_err(|e| anyhow!(e))?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
- req.set_signal(signum as u32);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
+ req.set_signal(signum as u32);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1291,63 +1346,15 @@ fn agent_cmd_container_signal_process(
Ok(())
}
-fn agent_cmd_sandbox_tracing_start(
- ctx: &Context,
- client: &AgentServiceClient,
- _health: &HealthClient,
- _image: &ImageClient,
- _options: &mut Options,
- _args: &str,
-) -> Result<()> {
- let req = StartTracingRequest::default();
-
- let ctx = clone_context(ctx);
-
- debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
-
- let reply = client
- .start_tracing(ctx, &req)
- .map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
-
- info!(sl!(), "response received";
- "response" => format!("{:?}", reply));
-
- Ok(())
-}
-
-fn agent_cmd_sandbox_tracing_stop(
- ctx: &Context,
- client: &AgentServiceClient,
- _health: &HealthClient,
- _image: &ImageClient,
- _options: &mut Options,
- _args: &str,
-) -> Result<()> {
- let req = StopTracingRequest::default();
-
- let ctx = clone_context(ctx);
-
- debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
-
- let reply = client
- .stop_tracing(ctx, &req)
- .map_err(|e| anyhow!("{:?}", e).context(ERR_API_FAILED))?;
-
- info!(sl!(), "response received";
- "response" => format!("{:?}", reply));
-
- Ok(())
-}
-
fn agent_cmd_sandbox_update_interface(
ctx: &Context,
client: &AgentServiceClient,
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = UpdateInterfaceRequest::default();
+ let req: UpdateInterfaceRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1371,9 +1378,9 @@ fn agent_cmd_sandbox_update_routes(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = UpdateRoutesRequest::default();
+ let req: UpdateRoutesRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1398,9 +1405,9 @@ fn agent_cmd_sandbox_list_interfaces(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = ListInterfacesRequest::default();
+ let req: ListInterfacesRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1422,9 +1429,9 @@ fn agent_cmd_sandbox_list_routes(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = ListRoutesRequest::default();
+ let req: ListRoutesRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1448,34 +1455,38 @@ fn agent_cmd_container_tty_win_resize(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = TtyWinResizeRequest::default();
+ let mut req: TtyWinResizeRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
- let rows_str = utils::get_option("row", options, args);
+ let rows_str = utils::get_option("row", options, args)?;
- if rows_str != "" {
- let rows = rows_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid row size"))?;
- req.set_row(rows);
- }
+ if rows_str != "" {
+ let rows = rows_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid row size"))?;
+ req.set_row(rows);
+ }
- let cols_str = utils::get_option("column", options, args);
+ let cols_str = utils::get_option("column", options, args)?;
- if cols_str != "" {
- let cols = cols_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid column size"))?;
+ if cols_str != "" {
+ let cols = cols_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid column size"))?;
- req.set_column(cols);
- }
+ req.set_column(cols);
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1497,15 +1508,19 @@ fn agent_cmd_container_close_stdin(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = CloseStdinRequest::default();
+ let mut req: CloseStdinRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1527,24 +1542,28 @@ fn agent_cmd_container_read_stdout(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = ReadStreamRequest::default();
+ let mut req: ReadStreamRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
- let length_str = utils::get_option("len", options, args);
+ let length_str = utils::get_option("len", options, args)?;
- if length_str != "" {
- let length = length_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid length"))?;
- req.set_len(length);
- }
+ if length_str != "" {
+ let length = length_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid length"))?;
+ req.set_len(length);
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1566,24 +1585,28 @@ fn agent_cmd_container_read_stderr(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = ReadStreamRequest::default();
+ let mut req: ReadStreamRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
- let length_str = utils::get_option("len", options, args);
+ let length_str = utils::get_option("len", options, args)?;
- if length_str != "" {
- let length = length_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid length"))?;
- req.set_len(length);
- }
+ if length_str != "" {
+ let length = length_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid length"))?;
+ req.set_len(length);
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1605,19 +1628,23 @@ fn agent_cmd_container_write_stdin(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = WriteStreamRequest::default();
+ let mut req: WriteStreamRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
- let exec_id = utils::get_option("exec_id", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
+ let exec_id = utils::get_option("exec_id", options, args)?;
- let str_data = utils::get_option("data", options, args);
- let data = utils::str_to_bytes(&str_data)?;
+ let str_data = utils::get_option("data", options, args)?;
+ let data = utils::str_to_bytes(&str_data)?;
- req.set_container_id(cid);
- req.set_exec_id(exec_id);
- req.set_data(data.to_vec());
+ req.set_container_id(cid);
+ req.set_exec_id(exec_id);
+ req.set_data(data.to_vec());
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1637,9 +1664,9 @@ fn agent_cmd_sandbox_get_metrics(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = GetMetricsRequest::default();
+ let req: GetMetricsRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1661,9 +1688,9 @@ fn agent_cmd_sandbox_get_oom_event(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = GetOOMEventRequest::default();
+ let req: GetOOMEventRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1687,78 +1714,82 @@ fn agent_cmd_sandbox_copy_file(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = CopyFileRequest::default();
+ let mut req: CopyFileRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let path = utils::get_option("path", options, args);
- if path != "" {
- req.set_path(path);
- }
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let path = utils::get_option("path", options, args)?;
+ if path != "" {
+ req.set_path(path);
+ }
- let file_size_str = utils::get_option("file_size", options, args);
+ let file_size_str = utils::get_option("file_size", options, args)?;
- if file_size_str != "" {
- let file_size = file_size_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid file_size"))?;
+ if file_size_str != "" {
+ let file_size = file_size_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid file_size"))?;
- req.set_file_size(file_size);
- }
+ req.set_file_size(file_size);
+ }
- let file_mode_str = utils::get_option("file_mode", options, args);
+ let file_mode_str = utils::get_option("file_mode", options, args)?;
- if file_mode_str != "" {
- let file_mode = file_mode_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid file_mode"))?;
+ if file_mode_str != "" {
+ let file_mode = file_mode_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid file_mode"))?;
- req.set_file_mode(file_mode);
- }
+ req.set_file_mode(file_mode);
+ }
- let dir_mode_str = utils::get_option("dir_mode", options, args);
+ let dir_mode_str = utils::get_option("dir_mode", options, args)?;
- if dir_mode_str != "" {
- let dir_mode = dir_mode_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid dir_mode"))?;
+ if dir_mode_str != "" {
+ let dir_mode = dir_mode_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid dir_mode"))?;
- req.set_dir_mode(dir_mode);
- }
+ req.set_dir_mode(dir_mode);
+ }
- let uid_str = utils::get_option("uid", options, args);
+ let uid_str = utils::get_option("uid", options, args)?;
- if uid_str != "" {
- let uid = uid_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid uid"))?;
+ if uid_str != "" {
+ let uid = uid_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid uid"))?;
- req.set_uid(uid);
- }
+ req.set_uid(uid);
+ }
- let gid_str = utils::get_option("gid", options, args);
+ let gid_str = utils::get_option("gid", options, args)?;
- if gid_str != "" {
- let gid = gid_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid gid"))?;
- req.set_gid(gid);
- }
+ if gid_str != "" {
+ let gid = gid_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid gid"))?;
+ req.set_gid(gid);
+ }
- let offset_str = utils::get_option("offset", options, args);
+ let offset_str = utils::get_option("offset", options, args)?;
- if offset_str != "" {
- let offset = offset_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid offset"))?;
- req.set_offset(offset);
- }
+ if offset_str != "" {
+ let offset = offset_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid offset"))?;
+ req.set_offset(offset);
+ }
- let data_str = utils::get_option("data", options, args);
- if data_str != "" {
- let data = utils::str_to_bytes(&data_str)?;
- req.set_data(data.to_vec());
- }
+ let data_str = utils::get_option("data", options, args)?;
+ if data_str != "" {
+ let data = utils::str_to_bytes(&data_str)?;
+ req.set_data(data.to_vec());
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1780,14 +1811,18 @@ fn agent_cmd_sandbox_reseed_random_dev(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = ReseedRandomDevRequest::default();
+ let mut req: ReseedRandomDevRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let str_data = utils::get_option("data", options, args);
- let data = utils::str_to_bytes(&str_data)?;
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let str_data = utils::get_option("data", options, args)?;
+ let data = utils::str_to_bytes(&str_data)?;
- req.set_data(data.to_vec());
+ req.set_data(data.to_vec());
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1809,39 +1844,43 @@ fn agent_cmd_sandbox_online_cpu_mem(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = OnlineCPUMemRequest::default();
+ let mut req: OnlineCPUMemRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let wait_str = utils::get_option("wait", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let wait_str = utils::get_option("wait", options, args)?;
- if wait_str != "" {
- let wait = wait_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid wait bool"))?;
+ if wait_str != "" {
+ let wait = wait_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid wait bool"))?;
- req.set_wait(wait);
- }
+ req.set_wait(wait);
+ }
- let nb_cpus_str = utils::get_option("nb_cpus", options, args);
+ let nb_cpus_str = utils::get_option("nb_cpus", options, args)?;
- if nb_cpus_str != "" {
- let nb_cpus = nb_cpus_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid nb_cpus value"))?;
+ if nb_cpus_str != "" {
+ let nb_cpus = nb_cpus_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid nb_cpus value"))?;
- req.set_nb_cpus(nb_cpus);
- }
+ req.set_nb_cpus(nb_cpus);
+ }
- let cpu_only_str = utils::get_option("cpu_only", options, args);
+ let cpu_only_str = utils::get_option("cpu_only", options, args)?;
- if cpu_only_str != "" {
- let cpu_only = cpu_only_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid cpu_only bool"))?;
+ if cpu_only_str != "" {
+ let cpu_only = cpu_only_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid cpu_only bool"))?;
- req.set_cpu_only(cpu_only);
- }
+ req.set_cpu_only(cpu_only);
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1863,29 +1902,33 @@ fn agent_cmd_sandbox_set_guest_date_time(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = SetGuestDateTimeRequest::default();
+ let mut req: SetGuestDateTimeRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let secs_str = utils::get_option("sec", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let secs_str = utils::get_option("sec", options, args)?;
- if secs_str != "" {
- let secs = secs_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid seconds"))?;
+ if secs_str != "" {
+ let secs = secs_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid seconds"))?;
- req.set_Sec(secs);
- }
+ req.set_Sec(secs);
+ }
- let usecs_str = utils::get_option("usec", options, args);
+ let usecs_str = utils::get_option("usec", options, args)?;
- if usecs_str != "" {
- let usecs = usecs_str
- .parse::()
- .map_err(|e| anyhow!(e).context("invalid useconds"))?;
+ if usecs_str != "" {
+ let usecs = usecs_str
+ .parse::()
+ .map_err(|e| anyhow!(e).context("invalid useconds"))?;
- req.set_Usec(usecs);
- }
+ req.set_Usec(usecs);
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
@@ -1905,9 +1948,9 @@ fn agent_cmd_sandbox_add_arp_neighbors(
_health: &HealthClient,
_image: &ImageClient,
_options: &mut Options,
- _args: &str,
+ args: &str,
) -> Result<()> {
- let req = AddARPNeighborsRequest::default();
+ let req: AddARPNeighborsRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
@@ -1934,13 +1977,17 @@ fn agent_cmd_sandbox_update_container(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = UpdateContainerRequest::default();
+ let mut req: UpdateContainerRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
- let cid = utils::get_option("cid", options, args);
+ run_if_auto_values!(ctx, || -> Result<()> {
+ let cid = utils::get_option("cid", options, args)?;
- req.set_container_id(cid);
+ req.set_container_id(cid);
+
+ Ok(())
+ });
// FIXME: Implement fully
eprintln!("FIXME: 'UpdateContainer' not fully implemented");
@@ -1965,32 +2012,36 @@ fn agent_cmd_sandbox_mem_hotplug_by_probe(
options: &mut Options,
args: &str,
) -> Result<()> {
- let mut req = MemHotplugByProbeRequest::default();
+ let mut req: MemHotplugByProbeRequest = utils::make_request(args)?;
let ctx = clone_context(ctx);
// Expected to be a comma separated list of hex addresses
- let addr_list = utils::get_option("memHotplugProbeAddr", options, args);
+ let addr_list = utils::get_option("memHotplugProbeAddr", options, args)?;
- if addr_list != "" {
- let addrs: Vec = addr_list
- // Convert into a list of string values.
- .split(",")
- // Convert each string element into a u8 array of bytes, ignoring
- // those elements that fail the conversion.
- .filter_map(|s| hex::decode(s.trim_start_matches("0x")).ok())
- // "Stretch" the u8 byte slice into one of length 8
- // (to allow each 8 byte chunk to be converted into a u64).
- .map(|mut v| -> Vec {
- v.resize(8, 0x0);
- v
- })
- // Convert the slice of u8 bytes into a u64
- .map(|b| byteorder::LittleEndian::read_u64(&b))
- .collect();
+ run_if_auto_values!(ctx, || -> Result<()> {
+ if !addr_list.is_empty() {
+ let addrs: Vec = addr_list
+ // Convert into a list of string values.
+ .split(",")
+ // Convert each string element into a u8 array of bytes, ignoring
+ // those elements that fail the conversion.
+ .filter_map(|s| hex::decode(s.trim_start_matches("0x")).ok())
+ // "Stretch" the u8 byte slice into one of length 8
+ // (to allow each 8 byte chunk to be converted into a u64).
+ .map(|mut v| -> Vec {
+ v.resize(8, 0x0);
+ v
+ })
+ // Convert the slice of u8 bytes into a u64
+ .map(|b| byteorder::LittleEndian::read_u64(&b))
+ .collect();
- req.set_memHotplugProbeAddr(addrs);
- }
+ req.set_memHotplugProbeAddr(addrs);
+ }
+
+ Ok(())
+ });
debug!(sl!(), "sending request"; "request" => format!("{:?}", req));
diff --git a/tools/agent-ctl/src/main.rs b/tools/agent-ctl/src/main.rs
index ab4a90e45..00519c932 100644
--- a/tools/agent-ctl/src/main.rs
+++ b/tools/agent-ctl/src/main.rs
@@ -96,6 +96,15 @@ fn make_examples_text(program_name: &str) -> String {
$ {program} connect --server-address "{vsock_server_address}" --repeat -1 --cmd GetGuestDetails
+- Query guest details, asking for full details by specifying the API request object in JSON format:
+
+ $ {program} connect --server-address "{vsock_server_address}" -c 'GetGuestDetails json://{{"mem_block_size": true, "mem_hotplug_probe": true}}'
+
+- Query guest details, asking for extra detail by partially specifying the API request object in JSON format from a file:
+
+ $ echo '{{"mem_block_size": true}}' > /tmp/api.json
+ $ {program} connect --server-address "{vsock_server_address}" -c 'GetGuestDetails file:///tmp/api.json'
+
- Send a 'SIGUSR1' signal to a container process:
$ {program} connect --server-address "{vsock_server_address}" --cmd 'SignalProcess signal=usr1 sid={sandbox_id} cid={container_id}'
@@ -169,6 +178,7 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
let bundle_dir = args.value_of("bundle-dir").unwrap_or("").to_string();
let hybrid_vsock = args.is_present("hybrid-vsock");
+ let no_auto_values = args.is_present("no-auto-values");
let cfg = Config {
server_address,
@@ -178,6 +188,7 @@ fn connect(name: &str, global_args: clap::ArgMatches) -> Result<()> {
timeout_nano,
hybrid_vsock_port,
hybrid_vsock,
+ no_auto_values,
};
let result = rpc::run(&logger, &cfg, commands);
@@ -255,6 +266,12 @@ fn real_main() -> Result<()> {
.long("interactive")
.help("Allow interactive client"),
)
+ .arg(
+ Arg::with_name("no-auto-values")
+ .short("n")
+ .long("no-auto-values")
+ .help("Disable automatic generation of values for sandbox ID, container ID, etc"),
+ )
.arg(
Arg::with_name("server-address")
.long("server-address")
diff --git a/tools/agent-ctl/src/types.rs b/tools/agent-ctl/src/types.rs
index b5d8f31a5..300ebe170 100644
--- a/tools/agent-ctl/src/types.rs
+++ b/tools/agent-ctl/src/types.rs
@@ -18,4 +18,5 @@ pub struct Config {
pub interactive: bool,
pub hybrid_vsock: bool,
pub ignore_errors: bool,
+ pub no_auto_values: bool,
}
diff --git a/tools/agent-ctl/src/utils.rs b/tools/agent-ctl/src/utils.rs
index 15761cdea..41235494c 100644
--- a/tools/agent-ctl/src/utils.rs
+++ b/tools/agent-ctl/src/utils.rs
@@ -23,8 +23,10 @@ use protocols::oci::{
User as ttrpcUser,
};
use rand::Rng;
+use serde::de::DeserializeOwned;
use slog::{debug, warn};
use std::collections::HashMap;
+use std::fs::File;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
@@ -86,7 +88,7 @@ lazy_static! {
}
pub fn signame_to_signum(name: &str) -> Result {
- if name == "" {
+ if name.is_empty() {
return Err(anyhow!("invalid signal"));
}
@@ -121,7 +123,7 @@ pub fn signame_to_signum(name: &str) -> Result {
// Convert a human time fornat (like "2s") into the equivalent number
// of nano seconds.
pub fn human_time_to_ns(human_time: &str) -> Result {
- if human_time == "" || human_time == "0" {
+ if human_time.is_empty() || human_time.eq("0") {
return Ok(0);
}
@@ -143,17 +145,17 @@ pub fn human_time_to_ns(human_time: &str) -> Result {
// - All other options values default to an empty string.
// - All options are saved in the global hash before being returned for future
// use.
-pub fn get_option(name: &str, options: &mut Options, args: &str) -> String {
+pub fn get_option(name: &str, options: &mut Options, args: &str) -> Result {
let words: Vec<&str> = args.split_whitespace().collect();
for word in words {
- let fields: Vec = word.split("=").map(|s| s.to_string()).collect();
+ let fields: Vec = word.split('=').map(|s| s.to_string()).collect();
if fields.len() < 2 {
continue;
}
- if fields[0] == "" {
+ if fields[0].is_empty() {
continue;
}
@@ -162,17 +164,10 @@ pub fn get_option(name: &str, options: &mut Options, args: &str) -> String {
let mut value = fields[1..].join("=");
// Expand "spec=file:///some/where/config.json"
- if key == "spec" && value.starts_with(FILE_URI) {
- let spec_file = match uri_to_filename(&value) {
- Ok(file) => file,
- Err(e) => {
- warn!(sl!(), "failed to handle spec file URI: {:}", e);
+ if key.eq("spec") && value.starts_with(FILE_URI) {
+ let (_, spec_file) = split_uri(&value)?;
- "".to_string()
- }
- };
-
- if spec_file != "" {
+ if !spec_file.is_empty() {
value = match spec_file_to_string(spec_file) {
Ok(s) => s,
Err(e) => {
@@ -197,7 +192,7 @@ pub fn get_option(name: &str, options: &mut Options, args: &str) -> String {
if let Some(value) = options.get(name) {
debug!(sl!(), "using option {:?}={:?} ({})", name, value, msg);
- return value.to_string();
+ return Ok(value.into());
}
msg = "generated";
@@ -210,14 +205,14 @@ pub fn get_option(name: &str, options: &mut Options, args: &str) -> String {
// Default to CID
"exec_id" => {
msg = "derived";
- //derived = true;
match options.get("cid") {
- Some(value) => value.to_string(),
- None => "".to_string(),
+ Some(value) => value,
+ None => "",
}
+ .into()
}
- _ => "".to_string(),
+ _ => "".into(),
};
debug!(sl!(), "using option {:?}={:?} ({})", name, value, msg);
@@ -225,7 +220,7 @@ pub fn get_option(name: &str, options: &mut Options, args: &str) -> String {
// Store auto-generated value
options.insert(name.to_string(), value.to_string());
- value
+ Ok(value)
}
pub fn generate_random_hex_string(len: u32) -> String {
@@ -252,7 +247,7 @@ pub fn random_container_id() -> String {
}
fn config_file_from_bundle_dir(bundle_dir: &str) -> Result {
- if bundle_dir == "" {
+ if bundle_dir.is_empty() {
return Err(anyhow!("missing bundle directory"));
}
@@ -739,18 +734,20 @@ fn oci_to_ttrpc(bundle_dir: &str, cid: &str, oci: &ociSpec) -> Result
Ok(ttrpc_spec)
}
-fn uri_to_filename(uri: &str) -> Result {
- if !uri.starts_with(FILE_URI) {
- return Err(anyhow!(format!("invalid URI: {:?}", uri)));
- }
+// Split a URI and return a tuple comprising the scheme and the data.
+//
+// Note that we have to use our own parsing since "json://" is not
+// an official schema ;(
+fn split_uri(uri: &str) -> Result<(String, String)> {
+ const URI_DELIMITER: &str = "://";
- let fields: Vec<&str> = uri.split(FILE_URI).collect();
+ let fields: Vec<&str> = uri.split(URI_DELIMITER).collect();
if fields.len() != 2 {
- return Err(anyhow!(format!("invalid URI: {:?}", uri)));
+ return Err(anyhow!("invalid URI: {:?}", uri));
}
- Ok(fields[1].to_string())
+ Ok((fields[0].into(), fields[1].into()))
}
pub fn spec_file_to_string(spec_file: String) -> Result {
@@ -766,9 +763,9 @@ pub fn get_oci_spec_json(cfg: &Config) -> Result {
}
pub fn get_ttrpc_spec(options: &mut Options, cid: &str) -> Result {
- let bundle_dir = get_option("bundle-dir", options, "");
+ let bundle_dir = get_option("bundle-dir", options, "")?;
- let json_spec = get_option("spec", options, "");
+ let json_spec = get_option("spec", options, "")?;
assert_ne!(json_spec, "");
let oci_spec: ociSpec = serde_json::from_str(&json_spec).map_err(|e| anyhow!(e))?;
@@ -789,3 +786,67 @@ pub fn str_to_bytes(s: &str) -> Result> {
Ok(s.as_bytes().to_vec())
}
}
+
+// Returns a request object of the type requested.
+//
+// Call as:
+//
+// ```rust
+// let req1: SomeType = make_request(args)?;
+// let req2: AnotherType = make_request(args)?;
+// ```
+//
+// The args string can take a number of forms:
+//
+// - A file URI:
+//
+// The string is expected to start with 'file://' with the full path to
+// a local file containing a complete or partial JSON document.
+//
+// Example: 'file:///some/where/foo.json'
+//
+// - A JSON URI:
+//
+// This invented 'json://{ ...}' URI allows either a complete JSON document
+// or a partial JSON fragment to be specified. The JSON takes the form of
+// the JSON serialised protocol buffers files that specify the Kata Agent
+// API.
+//
+// - If the complete document for the specified type is provided, the values
+// specified are deserialised into the returned
+// type.
+//
+// - If a partial document is provided, the values specified are
+// deserialised into the returned type and all remaining elements take their
+// default values.
+//
+// - If no values are specified, all returned type will be created as
+// if TypeName::default() had been specified instead.
+//
+// Example 1 (Complete and valid empty JSON document): 'json://{}'
+// Example 2 (Valid partial JSON document): 'json://{"foo": true, "bar": "hello"}'
+// Example 3 (GetGuestDetails API example):
+//
+// let args = r#"json://{"mem_block_size": true, "mem_hotplug_probe": true}"#;
+//
+// let req: GetGuestDetailsRequest = make_request(args)?;
+//
+pub fn make_request(args: &str) -> Result {
+ if args.is_empty() {
+ return Ok(Default::default());
+ }
+
+ let (scheme, data) = split_uri(args)?;
+
+ match scheme.as_str() {
+ "json" => Ok(serde_json::from_str(&data)?),
+ "file" => {
+ let file = File::open(data)?;
+
+ Ok(serde_json::from_reader(file)?)
+ }
+ // Don't error since the args may contain key=value pairs which
+ // are not handled by this functionz.
+ _ => Ok(Default::default()),
+ }
+}
diff --git a/tools/packaging/kernel/configs/fragments/powerpc/vfio.conf b/tools/packaging/kernel/configs/fragments/powerpc/vfio.conf
new file mode 100644
index 000000000..249315e1e
--- /dev/null
+++ b/tools/packaging/kernel/configs/fragments/powerpc/vfio.conf
@@ -0,0 +1,3 @@
+CONFIG_IOMMU_API=y
+CONFIG_SPAPR_TCE_IOMMU=y
+
diff --git a/versions.yaml b/versions.yaml
index a2deb2a60..95e9e1b40 100644
--- a/versions.yaml
+++ b/versions.yaml
@@ -271,7 +271,7 @@ languages:
description: |
'newest-version' is the latest version known to work when
building Kata
- newest-version: "1.16.5"
+ newest-version: "1.17.3"
rust:
description: "Rust language"