Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,363 changes: 1,593 additions & 770 deletions edgelet/Cargo.lock

Large diffs are not rendered by default.

103 changes: 103 additions & 0 deletions edgelet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,118 @@ members = [
"edgelet-http-workload",
"edgelet-image-cleanup",
"edgelet-settings",
"edgelet-test-utils",
"edgelet-utils",
"iotedge",
"support-bundle",
]
resolver = "2"


[workspace.dependencies]
anyhow = "1"
async-trait = "0.1"
atty = "0.2"

base64 = "0.22"
byte-unit = "5"
bytes = "1"

chrono = { version = "0.4.7", features = ["serde"] }
chrono-humanize = "0.2"

clap = { version = "4", features = ["cargo", "env", "string"] }
config = { version = "0.15", default-features = false }

erased-serde = "0.4"

futures-util = "0.3"

hex = "0.4"
http = "1"
http-body = "1"
http-body-util = "0.1"
humantime = "2"
humantime-serde = "1"
hyper = { version = "1", features = ["client", "http1", "server"] }
hyper-util = { version = "0.1", features = [
"client",
"client-legacy",
"http1",
"service",
"tokio",
] }
hyper-openssl = { version = "0.10.1", features = ["tokio"] }

libc = "0.2"
log = { version = "0.4", features = ["std"] }

nix = "0.31"
num_cpus = "1.8"

openssl = "0.10"

percent-encoding = "2"

regex = "1"

semver = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serial_test = "3"
sha2 = "0.11"
sysinfo = "0.39"

tabwriter = "1"
termcolor = "1"
test-case = "3"
thiserror = "2"
tokio = { version = "1", features = [
"macros",
"parking_lot",
"process",
"rt",
"rt-multi-thread",
"signal",
"sync",
"time",
] }
toml = "1"
tower-service = "0.3"

url = { version = "2", features = ["serde"] }

yaml-rust = "0.4"

zip = { version = "8", features = ["deflate"], default-features = false }

aziot-cert-client-async = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-cert-common-http = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-certd-config = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-identity-client-async = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-identity-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-identity-common-http = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-identityd-config = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-key-client = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-key-client-async = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-key-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-key-common-http = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-key-openssl-engine = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-keyd-config = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-keys-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziot-tpmd-config = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
aziotctl-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
cert-renewal = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
config-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
http-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
logger = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
test-common = { git = "https://github.com/arsing/iot-identity-service", branch = "rustup" }
Comment on lines +97 to +117
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

TODO: Switch back to Azure/i-i-s:main when Azure/iot-identity-service#664 is merged.



[profile.dev]
panic = 'abort'


[profile.release]
panic = 'abort'
# Release builds will have full symbols. The packaging phase will strip symbols from binaries and
Expand Down
35 changes: 17 additions & 18 deletions edgelet/aziot-edged/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@
name = "aziot-edged"
version = "0.1.0"
authors = ["Azure IoT Edge Devs"]
edition = "2024"
publish = false
edition = "2021"
description = "The aziot-edged is the main binary for the IoT edge daemon."
homepage = "https://aka.ms/iotedge"
license = "MIT"


[dependencies]
base64 = "0.21"
chrono = "0.4"
clap = { version = "4", features = ["cargo", "string"] }
futures-util = "0.3"
log = "0.4"
serde_json = "1"
sha2 = "0.10"
serde = "1"
tokio = { version = "1", features = ["macros", "parking_lot", "rt-multi-thread", "signal", "sync", "time"] }
url = "2"
base64 = { workspace = true }
clap = { workspace = true }
futures-util = { workspace = true }
log = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
tokio = { workspace = true }
url = { workspace = true }

aziot-identity-client-async = { workspace = true }
aziot-identity-common = { workspace = true }
aziot-identity-common-http = { workspace = true }
http-common = { workspace = true }
logger = { workspace = true }

edgelet-core = { path = "../edgelet-core" }
edgelet-docker = { path = "../edgelet-docker" }
Expand All @@ -27,10 +33,3 @@ edgelet-http-mgmt = { path = "../edgelet-http-mgmt" }
edgelet-http-workload = { path = "../edgelet-http-workload" }
edgelet-image-cleanup = { path = "../edgelet-image-cleanup" }
edgelet-settings = { path = "../edgelet-settings", features = ["settings-docker"] }

aziot-identity-client-async = { git = "https://github.com/Azure/iot-identity-service", branch = "main" }
aziot-identity-common = { git = "https://github.com/Azure/iot-identity-service", branch = "main" }
aziot-identity-common-http = { git = "https://github.com/Azure/iot-identity-service", branch = "main" }

http-common = { git = "https://github.com/Azure/iot-identity-service", branch = "main" }
logger = { git = "https://github.com/Azure/iot-identity-service", branch = "main" }
2 changes: 1 addition & 1 deletion edgelet/aziot-edged/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod workload_manager;

use std::sync::atomic;

use edgelet_core::{module::ModuleAction, ModuleRuntime, WatchdogAction};
use edgelet_core::{ModuleRuntime, WatchdogAction, module::ModuleAction};
use edgelet_docker::{ImagePruneData, MakeModuleRuntime};
use edgelet_image_cleanup::image_gc;
use edgelet_settings::RuntimeSettings;
Expand Down
7 changes: 5 additions & 2 deletions edgelet/aziot-edged/src/workload_manager.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;

use edgelet_core::{module::ModuleAction, Error, UrlExt};
use edgelet_core::{Error, UrlExt, module::ModuleAction};
use edgelet_settings::uri::Listen;

use crate::error::Error as EdgedError;
Expand Down Expand Up @@ -250,7 +250,10 @@ where
M::Config: serde::Serialize,
{
if let Err(err) = shutdown_rx.await {
return Err(EdgedError::from_err("Could wait on the stop signal, workload manager will continue but not shutdown properly", err));
return Err(EdgedError::from_err(
"Could wait on the stop signal, workload manager will continue but not shutdown properly",
err,
));
}

let module_list = runtime
Expand Down
26 changes: 15 additions & 11 deletions edgelet/docker-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
[package]
authors = ["Azure IoT Edge Devs"]
edition = "2021"
name = "docker"
publish = false
version = "0.1.0"
authors = ["Azure IoT Edge Devs"]
edition = "2024"
publish = false


[dependencies]
anyhow = "1"
hyper = { version = "0.14", features = ["client", "http1"] }
serde = "1"
serde_derive = "1"
serde_json = "1"
tokio = { version = "1", features = ["time"] }
url = "2"
anyhow = { workspace = true }
bytes = { workspace = true }
http-body-util = { workspace = true }
hyper = { workspace = true }
hyper-util = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
url = { workspace = true }


[dev-dependencies]
tokio = { version = "1", features = ["macros", "rt"] }
tokio = { workspace = true }

edgelet-test-utils = { path = "../edgelet-test-utils" }
47 changes: 29 additions & 18 deletions edgelet/docker-rs/src/apis/client.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
use std::convert::Infallible;

use bytes::Bytes;
use http_body_util::{BodyExt as _, combinators::BoxBody};
use hyper::body::Incoming;
use hyper_util::{
client::legacy::{Client, connect::Connect},
rt::TokioExecutor,
};
use serde::Deserialize;

use super::configuration::Configuration;
Expand All @@ -6,7 +15,7 @@ use crate::models;
type BoxFutureResult<'a, T> =
std::pin::Pin<Box<dyn std::future::Future<Output = anyhow::Result<T>> + Send + 'a>>;

#[derive(Debug, serde_derive::Deserialize)]
#[derive(Debug, serde::Deserialize)]
#[cfg_attr(test, derive(PartialEq))]
pub struct ApiError {
#[serde(deserialize_with = "try_from_u16")]
Expand All @@ -31,9 +40,9 @@ where
}

impl ApiError {
async fn try_from_response(value: hyper::Response<hyper::Body>) -> anyhow::Result<Self> {
async fn try_from_response(value: hyper::Response<Incoming>) -> anyhow::Result<Self> {
let (parts, body) = value.into_parts();
let error_bytes = hyper::body::to_bytes(body).await?;
let error_bytes = body.collect().await?.to_bytes();
let error_str = String::from_utf8(error_bytes.to_vec())?;
Ok(Self {
code: parts.status,
Expand All @@ -54,17 +63,17 @@ impl ApiError {

#[derive(Clone)]
pub struct DockerApiClient<C> {
client: hyper::Client<C>,
client: Client<C, BoxBody<Bytes, Infallible>>,
configuration: std::sync::Arc<Configuration>,
}

impl<C> DockerApiClient<C>
where
C: Clone + hyper::client::connect::Connect + Send + Sync + 'static,
C: Clone + Connect + Send + Sync + 'static,
{
pub fn new(connector: C) -> Self {
Self {
client: hyper::Client::builder().build(connector),
client: Client::builder(TokioExecutor::new()).build(connector),
configuration: std::sync::Arc::new(Configuration::default()),
}
}
Expand Down Expand Up @@ -159,7 +168,7 @@ pub trait DockerApi {
until: Option<i32>,
timestamps: bool,
tail: &'a str,
) -> BoxFutureResult<'a, hyper::Body>;
) -> BoxFutureResult<'a, Incoming>;

fn network_create(
&self,
Expand All @@ -183,19 +192,19 @@ macro_rules! api_call {
.contains("application/json"),
"expected JSON Content-Type"
);
let response_bytes = ::hyper::body::to_bytes(body).await?;
let response_bytes = http_body_util::BodyExt::collect(body).await?.to_bytes();
Ok(::serde_json::from_slice::<$output>(&response_bytes)?)
}};
(@inner maybe_output $response:ident => $transfer:ident $blk:block ; $($_output:ty)?) => {{
let $transfer = $response;
$blk
}};

(@inner build_request $builder:ident) => { $builder.body(::hyper::Body::empty()) };
(@inner build_request $builder:ident) => { $builder.body(http_body_util::combinators::BoxBody::new(http_body_util::Empty::new())) };
(@inner build_request $builder:ident $body:ident $_:ty) => {
$builder
.header(::hyper::header::CONTENT_TYPE, "application/json")
.body(::hyper::Body::from(::serde_json::to_string(&$body)?))
.header(hyper::header::CONTENT_TYPE, "application/json")
.body(http_body_util::combinators::BoxBody::new(http_body_util::Full::new(serde_json::to_string(&$body)?.into())))
};

(@inner query $param:ident &$($_:lifetime)? str) => { $param };
Expand Down Expand Up @@ -266,7 +275,7 @@ macro_rules! api_call {

impl<C> DockerApi for DockerApiClient<C>
where
C: Clone + hyper::client::connect::Connect + Send + Sync + 'static,
C: Clone + Connect + Send + Sync + 'static,
{
api_call! {
system_info : get "/info" -> models::SystemInfo ;
Expand Down Expand Up @@ -390,7 +399,7 @@ where
"expected JSON Content-Type"
);

let response_bytes = hyper::body::to_bytes(body).await?;
let response_bytes = body.collect().await?.to_bytes();
let mut last = serde_json::Deserializer::from_slice(&response_bytes)
.into_iter::<serde_json::Map<String, serde_json::Value>>()
.last()
Expand All @@ -414,7 +423,7 @@ where
}

api_call! {
container_logs : get "/containers/{id}/logs" -> hyper::Body ;
container_logs : get "/containers/{id}/logs" -> Incoming ;
path : [ id: &'a str ] ;
query : [
"follow" = (follow: bool),
Expand Down Expand Up @@ -444,10 +453,12 @@ mod tests {
serde_json::to_string(&serde_json::json!({"status":"STATUS"})).unwrap(),
);
let client = DockerApiClient::new(JsonConnector::ok(&payload));
assert!(client
.image_create("", "", "", "", "", "", "")
.await
.is_ok());
assert!(
client
.image_create("", "", "", "", "", "", "")
.await
.is_ok()
);
}

#[tokio::test]
Expand Down
12 changes: 2 additions & 10 deletions edgelet/docker-rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
// Copyright (c) Microsoft. All rights reserved.

#![deny(rust_2018_idioms, warnings)]
#![allow(
dead_code,
non_snake_case,
renamed_and_removed_lints,
unused_imports,
unused_mut
)]
#![allow(clippy::all, clippy::pedantic)]
#![cfg(not(tarpaulin_include))]
pub mod apis;

#[expect(non_snake_case)]
pub mod models;

pub use apis::{DockerApi, DockerApiClient};
2 changes: 1 addition & 1 deletion edgelet/docker-rs/src/models/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#[allow(unused_imports)]
use serde_json::Value;

#[derive(Debug, serde_derive::Serialize, serde_derive::Deserialize)]
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Address {
/// IP address.
#[serde(rename = "Addr", skip_serializing_if = "Option::is_none")]
Expand Down
Loading
Loading