-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement nydusd and nydus-snapshotter to deliver config through the socket API #1379
Conversation
@DarkMountain-wyz , a new test job has been submitted. Please wait in patience. The test job url: https://tone.openanolis.cn/ws/nrh4nnio/test_result/85652 |
Codecov Report
@@ Coverage Diff @@
## master #1379 +/- ##
==========================================
- Coverage 46.29% 46.18% -0.12%
==========================================
Files 123 123
Lines 38872 38960 +88
Branches 38872 38960 +88
==========================================
- Hits 17997 17992 -5
- Misses 19906 19994 +88
- Partials 969 974 +5
|
@DarkMountain-wyz , The CI test is completed, please check result:
Congratulations, your test job passed! |
@DarkMountain-wyz , the code has been updated, so a new test job has been submitted. Please wait in patience. The test job url: https://tone.openanolis.cn/ws/nrh4nnio/test_result/87020 |
@DarkMountain-wyz , The CI test is completed, please check result:
Congratulations, your test job passed! |
src/bin/nydusd/main.rs
Outdated
@@ -418,7 +505,28 @@ fn process_fs_service( | |||
) | |||
} | |||
None => match args.value_of("config") { | |||
Some(v) => std::fs::read_to_string(v)?, | |||
Some(v) => { | |||
let socket_path = match args.value_of("config-source") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the option --config-source
should be conflict with --config
, right?
src/bin/nydusd/main.rs
Outdated
@@ -363,6 +373,83 @@ fn handle_rlimit_nofile_option(args: &ArgMatches, option_name: &str) -> Result<( | |||
Ok(()) | |||
} | |||
|
|||
fn send_unix_socket_request(socket_path: &str, method: &str, url: &str) -> Option<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about putting this into api/src/config.rs
, and naming it fn from_source(...)
.
src/bin/nydusd/main.rs
Outdated
fn send_unix_socket_request(socket_path: &str, method: &str, url: &str) -> Option<String> { | ||
let mut stream = match UnixStream::connect(socket_path).ok() { | ||
Some(stream) => stream, | ||
None => return None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd better return a Result
instead of an Option
, and handle the Result
outside.
src/bin/nydusd/main.rs
Outdated
None => return None, | ||
}; | ||
|
||
let request = format!("{} {} HTTP/1.1\r\nHost: localhost\r\n\r\n", method, url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about using the hyper::Client
crate directly, instead of implementing the HTTP over the unix domain socket client by self?
src/bin/nydusd/main.rs
Outdated
let mut total_read = 0; | ||
|
||
loop { | ||
match stream.read(&mut buffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it strange to actively read configuration from nydus-snapshotter. This means nydus daemon depends on nydus-snapshoter. But nydus-snapshotter is the manager of nydus daemon. So, I think nydus-snapshotter should update the configuration as needed instead of providing an API for the daemon.
@DarkMountain-wyz , the code has been updated, so a new test job has been submitted. Please wait in patience. The test job url: https://tone.openanolis.cn/ws/nrh4nnio/test_result/89250 |
@DarkMountain-wyz , The CI test is completed, please check result:
Congratulations, your test job passed! |
api/src/config.rs
Outdated
@@ -218,6 +220,32 @@ impl ConfigV2 { | |||
} | |||
} | |||
} | |||
|
|||
/// Fill backend config from nydus-snapshotter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not only for nydus snapshotter in the future.
api/src/config.rs
Outdated
let uri = Uri::new(sock, endpoint).into(); | ||
let response = client.get(uri).await?; | ||
let status_code = response.status().as_u16(); | ||
let buf = hyper::body::to_bytes(response).await?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should read the response body after the status code check.
api/src/config.rs
Outdated
let buf = hyper::body::to_bytes(response).await?; | ||
if status_code != 200 { | ||
return Err(anyhow::anyhow!( | ||
"Request failed with status code: {}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
failed to request backend config from source, status code: {}
api/src/config.rs
Outdated
@@ -245,6 +273,7 @@ impl FromStr for ConfigV2 { | |||
} | |||
} | |||
} | |||
info!("你到这了吗"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this.
src/bin/nydusd/main.rs
Outdated
.global(true), | ||
) | ||
.arg( | ||
Arg::new("credential-source") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about renaming it to backend-source
, and combining the url with systemsock
?
@DarkMountain-wyz Please refine the commits and add some commit messages to explain why & how to do this. |
|
@DarkMountain-wyz , the code has been updated, so a new test job has been submitted. Please wait in patience. The test job url: https://tone.openanolis.cn/ws/nrh4nnio/test_result/89600 |
@DarkMountain-wyz , The CI test is completed, please check result:
Congratulations, your test job passed! |
@DarkMountain-wyz , the code has been updated, so a new test job has been submitted. Please wait in patience. The test job url: https://tone.openanolis.cn/ws/nrh4nnio/test_result/89652 |
@DarkMountain-wyz , The CI test is completed, please check result:
Congratulations, your test job passed! |
@DarkMountain-wyz We'd better refresh the backend config when the registry auth expires. |
api/Cargo.toml
Outdated
@@ -13,6 +13,9 @@ libc = "0.2" | |||
log = "0.4.8" | |||
serde_json = "1.0.53" | |||
toml = "0.5" | |||
hyper = "0.14.11" | |||
hyperlocal = "0.8.0" | |||
anyhow = "1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use the exact version 1.0
here?
api/Cargo.toml
Outdated
@@ -21,9 +24,11 @@ lazy_static = { version = "1.4.0", optional = true } | |||
mio = { version = "0.8", features = ["os-poll", "os-ext"], optional = true } | |||
serde = { version = "1.0.110", features = ["rc", "serde_derive"] } | |||
url = { version = "2.1.1", optional = true } | |||
tokio = { version = "1.24", features = ["full"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the using of full
feature will import a large number of dependencies, can we only use the necessary feature?
storage/src/backend/registry.rs
Outdated
@@ -37,6 +39,7 @@ const REDIRECTED_STATUS_CODE: [StatusCode; 2] = [ | |||
]; | |||
|
|||
const REGISTRY_DEFAULT_TOKEN_EXPIRATION: u64 = 10 * 60; // in seconds | |||
const MAX_RETRIES: u32 = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is unnecessary to add the retry mechanism because the upper caller will retry if any error happens.
api/src/config.rs
Outdated
|
||
use serde::Deserialize; | ||
use serde_json::Value; | ||
|
||
lazy_static! { | ||
pub static ref BACKEND_SOURCE_PATH: Mutex<Option<String>> = Mutex::new(None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about putting this into BackendConfigV2
struct like this (as a private field, do not participate in Deserialize/Serialize):
pub struct BackendConfigV2 {
/// Type of storage backend.
#[serde(rename = "type")]
pub backend_type: String,
/// Source of storage backend configuration.
#[serde(skip_serializing, skip_deserializing)]
backend_source: Option<String>,
}
storage/src/backend/registry.rs
Outdated
|
||
if token_resp.status() == StatusCode::OK { | ||
return Ok(token_resp); | ||
} else if token_resp.status() == StatusCode::FORBIDDEN && retries < MAX_RETRIES { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be vec![StatusCode::UNAUTHORIZED, StatusCode::FORBIDDEN].contains(&token_resp.status())
.
storage/src/backend/registry.rs
Outdated
let registry_auth = trim(registry_config.auth.clone()); | ||
let (new_username, new_password) = | ||
Registry::get_authorization_info(®istry_auth)?; | ||
username = new_username; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.username
& self.password
should be updated.
src/bin/nydusd/main.rs
Outdated
@@ -276,6 +276,13 @@ fn prepare_commandline_options() -> Command { | |||
.required(false) | |||
.global(true), | |||
) | |||
.arg( | |||
Arg::new("backend-source") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smoke test is required. Please also update doc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR title mentions config delivery but it actually is only about auth right? We already support configurating nydusd backend (which including auth info) via API. It is just that we need to amend nydus-snapshotter to stopping passing config via local file but via API instead. @DarkMountain-wyz Are you planning to look at the nydus-snapshotter part as well?
src/bin/nydusd/main.rs
Outdated
@@ -425,7 +432,11 @@ fn process_fs_service( | |||
config.update_registry_auth_info(&auth); | |||
serde_json::to_string(&config)? | |||
} else { | |||
std::fs::read_to_string(v)? | |||
let mut config = ConfigV2::from_file(v)?; | |||
if let Some(source) = args.value_of("backend-source") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a backend-source
or an auth-source
? It looks like that we only use it to get auth info.
api/src/config.rs
Outdated
}) | ||
.ok()?; | ||
let backend_config_v2 = BackendConfigV2::try_from(&backend_config).ok()?; | ||
let mut backend_source = BACKEND_SOURCE_PATH.lock().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would deadlock as we call update_auth_from_source
after taking the BACKEND_SOURCE_PATH mutex when dealing with backend auth failures, which also indicates that the code path has not been tested.
BACKEND_SOURCE_PATH
should actually be only set when starting nydusd. There is no need to update it from time to time.
And where is the corresponding nydus-snapshotter part of the change? I assume we need a new API from snapshotter as well, no? |
The corresponding modification for the nydus-snapshotter can be found in the pull request here. The approach taken involves providing a domain socket API for nydusd to request and retrieve backend information. The decision to pass all backend information rather than just authentication details is to ensure flexibility in case new types of backends are added in the future, without needing to modify this interface. |
Relevant Issue (if applicable)
containerd/nydus-snapshotter#388
Details
Types of changes
What types of changes does your PullRequest introduce? Put an
x
in all the boxes that apply:Checklist
Go over all the following points, and put an
x
in all the boxes that apply.