Skip to content

Commit d56b5af

Browse files
committed
add a new visitor instead of using unpack function
1 parent edac067 commit d56b5af

File tree

6 files changed

+58
-95
lines changed

6 files changed

+58
-95
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fl-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ thiserror = "1.0.63"
4949
hostname-validator = "1.1.1"
5050
walkdir = "2.5.0"
5151
sha256 = "1.5.0"
52+
async-trait = "0.1.53"

fl-server/src/auth.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub async fn sign_in_handler(
5555
Extension(cfg): Extension<config::Config>,
5656
Json(user_data): Json<SignInBody>,
5757
) -> impl IntoResponse {
58-
let user = match get_user_by_username(cfg.users, &user_data.username) {
58+
let user = match get_user_by_username(&cfg.users, &user_data.username) {
5959
Some(user) => user,
6060
None => {
6161
return Err(ResponseError::Unauthorized(
@@ -70,17 +70,17 @@ pub async fn sign_in_handler(
7070
));
7171
}
7272

73-
let token = encode_jwt(user.username, cfg.jwt_secret, cfg.jwt_expire_hours)
73+
let token = encode_jwt(user.username.clone(), cfg.jwt_secret, cfg.jwt_expire_hours)
7474
.map_err(|_| ResponseError::InternalServerError)?;
7575

7676
Ok(ResponseResult::SignedIn(SignInResponse {
7777
access_token: token,
7878
}))
7979
}
8080

81-
pub fn get_user_by_username(users: Vec<User>, username: &str) -> Option<User> {
81+
pub fn get_user_by_username<'a>(users: &'a [User], username: &str) -> Option<&'a User> {
8282
let user = users.iter().find(|u| u.username == username)?;
83-
Some(user.clone())
83+
Some(user)
8484
}
8585

8686
pub fn encode_jwt(
@@ -138,7 +138,7 @@ pub async fn authorize(
138138
}
139139
};
140140

141-
let current_user = match get_user_by_username(cfg.users, &token_data.claims.username) {
141+
let current_user = match get_user_by_username(&cfg.users, &token_data.claims.username) {
142142
Some(user) => user,
143143
None => {
144144
return Err(ResponseError::Unauthorized(
@@ -147,6 +147,6 @@ pub async fn authorize(
147147
}
148148
};
149149

150-
req.extensions_mut().insert(current_user.username);
150+
req.extensions_mut().insert(current_user.username.clone());
151151
Ok(next.run(req).await)
152152
}

fl-server/src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use anyhow::{Context, Result};
22
use serde::{Deserialize, Serialize};
3-
use std::{collections::HashMap, fs, sync::Mutex};
3+
use std::{collections::HashMap, fs, path::PathBuf, sync::Mutex};
44
use utoipa::ToSchema;
55

66
use crate::{auth, handlers};
@@ -13,7 +13,7 @@ pub struct Job {
1313
#[derive(Debug, ToSchema)]
1414
pub struct AppState {
1515
pub jobs_state: Mutex<HashMap<String, handlers::FlistState>>,
16-
pub flists_progress: Mutex<HashMap<String, f32>>,
16+
pub flists_progress: Mutex<HashMap<PathBuf, f32>>,
1717
}
1818

1919
#[derive(Debug, Default, Clone, Deserialize)]

fl-server/src/handlers.rs

Lines changed: 47 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ use axum_macros::debug_handler;
88
use std::{
99
collections::HashMap,
1010
fs,
11+
path::PathBuf,
1112
sync::{mpsc, Arc},
1213
};
13-
use tokio::io;
14-
use walkdir::WalkDir;
1514

1615
use bollard::auth::DockerCredentials;
1716
use serde::{Deserialize, Serialize};
@@ -25,10 +24,7 @@ use crate::{
2524
response::{FileInfo, ResponseError, ResponseResult},
2625
serve_flists::visit_dir_one_level,
2726
};
28-
use rfs::{
29-
cache,
30-
fungi::{Reader, Writer},
31-
};
27+
use rfs::fungi::{Reader, Writer};
3228
use utoipa::{OpenApi, ToSchema};
3329
use uuid::Uuid;
3430

@@ -58,7 +54,7 @@ pub struct FlistBody {
5854

5955
#[derive(Debug, Deserialize, Serialize, Clone, ToSchema)]
6056
pub struct PreviewResponse {
61-
pub content: Vec<String>,
57+
pub content: Vec<PathBuf>,
6258
pub metadata: String,
6359
pub checksum: String,
6460
}
@@ -124,37 +120,28 @@ pub async fn create_flist_handler(
124120
}
125121

126122
let fl_name = docker_image.replace([':', '/'], "-") + ".fl";
127-
let username_dir = format!("{}/{}", cfg.flist_dir, username);
123+
let username_dir = std::path::Path::new(&cfg.flist_dir).join(username);
124+
let fl_path = username_dir.join(&fl_name);
128125

129-
match flist_exists(std::path::Path::new(&username_dir), &fl_name).await {
130-
Ok(exists) => {
131-
if exists {
132-
return Err(ResponseError::Conflict("flist already exists".to_string()));
133-
}
134-
}
135-
Err(e) => {
136-
log::error!("failed to check flist existence with error {:?}", e);
137-
return Err(ResponseError::InternalServerError);
138-
}
126+
if fl_path.exists() {
127+
return Err(ResponseError::Conflict("flist already exists".to_string()));
139128
}
140129

141130
let created = fs::create_dir_all(&username_dir);
142131
if created.is_err() {
143132
log::error!(
144-
"failed to create user flist directory `{}` with error {:?}",
133+
"failed to create user flist directory `{:?}` with error {:?}",
145134
&username_dir,
146135
created.err()
147136
);
148137
return Err(ResponseError::InternalServerError);
149138
}
150139

151-
let fl_path: String = format!("{}/{}", username_dir, fl_name);
152-
153140
let meta = match Writer::new(&fl_path).await {
154141
Ok(writer) => writer,
155142
Err(err) => {
156143
log::error!(
157-
"failed to create a new writer for flist `{}` with error {}",
144+
"failed to create a new writer for flist `{:?}` with error {}",
158145
fl_path,
159146
err
160147
);
@@ -257,7 +244,7 @@ pub async fn create_flist_handler(
257244
state.jobs_state.lock().unwrap().insert(
258245
job.id.clone(),
259246
FlistState::Created(format!(
260-
"flist {}:{}/{} is created successfully",
247+
"flist {}:{}/{:?} is created successfully",
261248
cfg.host, cfg.port, fl_path
262249
)),
263250
);
@@ -397,7 +384,7 @@ pub async fn preview_flist_handler(
397384
Err(err) => return Err(ResponseError::BadRequest(err.to_string())),
398385
};
399386

400-
let content = match unpack_flist(&fl_path).await {
387+
let content = match get_flist_content(&fl_path).await {
401388
Ok(paths) => paths,
402389
Err(_) => return Err(ResponseError::InternalServerError),
403390
};
@@ -421,20 +408,6 @@ pub async fn preview_flist_handler(
421408
}))
422409
}
423410

424-
async fn flist_exists(dir_path: &std::path::Path, flist_name: &String) -> io::Result<bool> {
425-
let mut dir = tokio::fs::read_dir(dir_path).await?;
426-
427-
while let Some(child) = dir.next_entry().await? {
428-
let file_name = child.file_name().to_string_lossy().to_string();
429-
430-
if file_name.eq(flist_name) {
431-
return Ok(true);
432-
}
433-
}
434-
435-
Ok(false)
436-
}
437-
438411
async fn validate_flist_path(
439412
users: Vec<User>,
440413
flist_dir: &String,
@@ -466,7 +439,7 @@ async fn validate_flist_path(
466439
}
467440

468441
// validate username
469-
match get_user_by_username(users, parts[1]) {
442+
match get_user_by_username(&users, parts[1]) {
470443
Some(_) => (),
471444
None => {
472445
return Err(anyhow::anyhow!(
@@ -493,23 +466,20 @@ async fn validate_flist_path(
493466
}
494467

495468
// validate flist existence
496-
let username_dir = format!("{}/{}", parts[0], parts[1]);
497-
match flist_exists(std::path::Path::new(&username_dir), &fl_name).await {
498-
Ok(exists) => {
499-
if !exists {
500-
return Err(anyhow::anyhow!("flist '{}' doesn't exist", fl_path));
501-
}
502-
}
503-
Err(e) => {
504-
log::error!("failed to check flist existence with error {:?}", e);
505-
return Err(anyhow::anyhow!("Internal server error"));
506-
}
469+
if !std::path::Path::new(parts[0])
470+
.join(parts[1])
471+
.join(&fl_name)
472+
.exists()
473+
{
474+
return Err(anyhow::anyhow!("flist '{}' doesn't exist", fl_path));
507475
}
508476

509477
Ok(())
510478
}
511479

512-
async fn unpack_flist(fl_path: &String) -> Result<Vec<std::string::String>, Error> {
480+
async fn get_flist_content(fl_path: &String) -> Result<Vec<PathBuf>, Error> {
481+
let mut visitor = ReadVisitor::default();
482+
513483
let meta = match Reader::new(&fl_path).await {
514484
Ok(reader) => reader,
515485
Err(err) => {
@@ -522,43 +492,38 @@ async fn unpack_flist(fl_path: &String) -> Result<Vec<std::string::String>, Erro
522492
}
523493
};
524494

525-
let router = match rfs::store::get_router(&meta).await {
526-
Ok(r) => r,
527-
Err(err) => {
528-
log::error!("failed to get router with error {}", err);
529-
return Err(anyhow::anyhow!("Internal server error"));
530-
}
531-
};
532-
533-
let cache = cache::Cache::new(String::from("/tmp/cache"), router);
534-
let tmp_target = match tempdir::TempDir::new("target") {
535-
Ok(dir) => dir,
495+
match meta.walk(&mut visitor).await {
496+
Ok(()) => return Ok(visitor.into_inner()),
536497
Err(err) => {
537-
log::error!("failed to create tmp dir with error {}", err);
498+
log::error!(
499+
"failed to walk through metadata for flist `{}` with error {}",
500+
fl_path,
501+
err
502+
);
538503
return Err(anyhow::anyhow!("Internal server error"));
539504
}
540505
};
541-
let tmp_target_path = tmp_target.path().to_owned();
506+
}
542507

543-
match rfs::unpack(&meta, &cache, &tmp_target_path, false).await {
544-
Ok(_) => (),
545-
Err(err) => {
546-
log::error!("failed to unpack flist {} with error {}", fl_path, err);
547-
return Err(anyhow::anyhow!("Internal server error"));
548-
}
549-
};
508+
#[derive(Default)]
509+
struct ReadVisitor {
510+
inner: Vec<PathBuf>,
511+
}
550512

551-
let mut paths = Vec::new();
552-
for file in WalkDir::new(tmp_target_path.clone())
553-
.into_iter()
554-
.filter_map(|file| file.ok())
555-
{
556-
let path = file.path().to_string_lossy().to_string();
557-
match path.strip_prefix(&tmp_target_path.to_string_lossy().to_string()) {
558-
Some(p) => paths.push(p.to_string()),
559-
None => return Err(anyhow::anyhow!("Internal server error")),
560-
};
513+
impl ReadVisitor {
514+
pub fn into_inner(self) -> Vec<PathBuf> {
515+
self.inner
561516
}
517+
}
562518

563-
Ok(paths)
519+
#[async_trait::async_trait]
520+
impl rfs::fungi::meta::WalkVisitor for ReadVisitor {
521+
async fn visit(
522+
&mut self,
523+
path: &std::path::Path,
524+
_node: &rfs::fungi::meta::Inode,
525+
) -> rfs::fungi::meta::Result<rfs::fungi::meta::Walk> {
526+
self.inner.push(path.to_path_buf());
527+
Ok(rfs::fungi::meta::Walk::Continue)
528+
}
564529
}

fl-server/src/serve_flists.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ pub async fn visit_dir_one_level(
9898

9999
let mut progress = 0.0;
100100
if is_file {
101-
match state.flists_progress.lock().unwrap().get(&format!(
102-
"{}/{}",
103-
path.to_string_lossy().to_string(),
104-
name
105-
)) {
101+
match state.flists_progress.lock().unwrap().get(&path.join(&name)) {
106102
Some(p) => progress = p.to_owned(),
107103
None => progress = 100.0,
108104
}

0 commit comments

Comments
 (0)