@@ -8,10 +8,9 @@ use axum_macros::debug_handler;
8
8
use std:: {
9
9
collections:: HashMap ,
10
10
fs,
11
+ path:: PathBuf ,
11
12
sync:: { mpsc, Arc } ,
12
13
} ;
13
- use tokio:: io;
14
- use walkdir:: WalkDir ;
15
14
16
15
use bollard:: auth:: DockerCredentials ;
17
16
use serde:: { Deserialize , Serialize } ;
@@ -25,10 +24,7 @@ use crate::{
25
24
response:: { FileInfo , ResponseError , ResponseResult } ,
26
25
serve_flists:: visit_dir_one_level,
27
26
} ;
28
- use rfs:: {
29
- cache,
30
- fungi:: { Reader , Writer } ,
31
- } ;
27
+ use rfs:: fungi:: { Reader , Writer } ;
32
28
use utoipa:: { OpenApi , ToSchema } ;
33
29
use uuid:: Uuid ;
34
30
@@ -58,7 +54,7 @@ pub struct FlistBody {
58
54
59
55
#[ derive( Debug , Deserialize , Serialize , Clone , ToSchema ) ]
60
56
pub struct PreviewResponse {
61
- pub content : Vec < String > ,
57
+ pub content : Vec < PathBuf > ,
62
58
pub metadata : String ,
63
59
pub checksum : String ,
64
60
}
@@ -124,37 +120,28 @@ pub async fn create_flist_handler(
124
120
}
125
121
126
122
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) ;
128
125
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 ( ) ) ) ;
139
128
}
140
129
141
130
let created = fs:: create_dir_all ( & username_dir) ;
142
131
if created. is_err ( ) {
143
132
log:: error!(
144
- "failed to create user flist directory `{}` with error {:?}" ,
133
+ "failed to create user flist directory `{:? }` with error {:?}" ,
145
134
& username_dir,
146
135
created. err( )
147
136
) ;
148
137
return Err ( ResponseError :: InternalServerError ) ;
149
138
}
150
139
151
- let fl_path: String = format ! ( "{}/{}" , username_dir, fl_name) ;
152
-
153
140
let meta = match Writer :: new ( & fl_path) . await {
154
141
Ok ( writer) => writer,
155
142
Err ( err) => {
156
143
log:: error!(
157
- "failed to create a new writer for flist `{}` with error {}" ,
144
+ "failed to create a new writer for flist `{:? }` with error {}" ,
158
145
fl_path,
159
146
err
160
147
) ;
@@ -257,7 +244,7 @@ pub async fn create_flist_handler(
257
244
state. jobs_state . lock ( ) . unwrap ( ) . insert (
258
245
job. id . clone ( ) ,
259
246
FlistState :: Created ( format ! (
260
- "flist {}:{}/{} is created successfully" ,
247
+ "flist {}:{}/{:? } is created successfully" ,
261
248
cfg. host, cfg. port, fl_path
262
249
) ) ,
263
250
) ;
@@ -397,7 +384,7 @@ pub async fn preview_flist_handler(
397
384
Err ( err) => return Err ( ResponseError :: BadRequest ( err. to_string ( ) ) ) ,
398
385
} ;
399
386
400
- let content = match unpack_flist ( & fl_path) . await {
387
+ let content = match get_flist_content ( & fl_path) . await {
401
388
Ok ( paths) => paths,
402
389
Err ( _) => return Err ( ResponseError :: InternalServerError ) ,
403
390
} ;
@@ -421,20 +408,6 @@ pub async fn preview_flist_handler(
421
408
} ) )
422
409
}
423
410
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
-
438
411
async fn validate_flist_path (
439
412
users : Vec < User > ,
440
413
flist_dir : & String ,
@@ -466,7 +439,7 @@ async fn validate_flist_path(
466
439
}
467
440
468
441
// validate username
469
- match get_user_by_username ( users, parts[ 1 ] ) {
442
+ match get_user_by_username ( & users, parts[ 1 ] ) {
470
443
Some ( _) => ( ) ,
471
444
None => {
472
445
return Err ( anyhow:: anyhow!(
@@ -493,23 +466,20 @@ async fn validate_flist_path(
493
466
}
494
467
495
468
// 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) ) ;
507
475
}
508
476
509
477
Ok ( ( ) )
510
478
}
511
479
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
+
513
483
let meta = match Reader :: new ( & fl_path) . await {
514
484
Ok ( reader) => reader,
515
485
Err ( err) => {
@@ -522,43 +492,38 @@ async fn unpack_flist(fl_path: &String) -> Result<Vec<std::string::String>, Erro
522
492
}
523
493
} ;
524
494
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 ( ) ) ,
536
497
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
+ ) ;
538
503
return Err ( anyhow:: anyhow!( "Internal server error" ) ) ;
539
504
}
540
505
} ;
541
- let tmp_target_path = tmp_target . path ( ) . to_owned ( ) ;
506
+ }
542
507
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
+ }
550
512
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
561
516
}
517
+ }
562
518
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
+ }
564
529
}
0 commit comments