@@ -29,6 +29,8 @@ pub struct ConfigV2 {
29
29
pub cache : Option < CacheConfigV2 > ,
30
30
/// Configuration information for RAFS filesystem.
31
31
pub rafs : Option < RafsConfigV2 > ,
32
+ /// Configuration information for image deduplication.
33
+ pub dedup : Option < DeduplicationConfigV2 > ,
32
34
/// Internal runtime configuration.
33
35
#[ serde( skip) ]
34
36
pub internal : ConfigV2Internal ,
@@ -42,6 +44,7 @@ impl Default for ConfigV2 {
42
44
backend : None ,
43
45
cache : None ,
44
46
rafs : None ,
47
+ dedup : None ,
45
48
internal : ConfigV2Internal :: default ( ) ,
46
49
}
47
50
}
@@ -56,6 +59,7 @@ impl ConfigV2 {
56
59
backend : None ,
57
60
cache : None ,
58
61
rafs : None ,
62
+ dedup : None ,
59
63
internal : ConfigV2Internal :: default ( ) ,
60
64
}
61
65
}
@@ -126,6 +130,16 @@ impl ConfigV2 {
126
130
} )
127
131
}
128
132
133
+ /// Get configuration information for image deduplication.
134
+ pub fn get_dedup_config ( & self ) -> Result < & DeduplicationConfigV2 > {
135
+ self . dedup . as_ref ( ) . ok_or_else ( || {
136
+ Error :: new (
137
+ ErrorKind :: InvalidInput ,
138
+ "no configuration information for deduplication" ,
139
+ )
140
+ } )
141
+ }
142
+
129
143
/// Get configuration information for cache subsystem.
130
144
pub fn get_cache_config ( & self ) -> Result < & CacheConfigV2 > {
131
145
self . cache . as_ref ( ) . ok_or_else ( || {
@@ -962,6 +976,9 @@ pub struct BlobCacheEntryConfigV2 {
962
976
/// Configuration information for local cache system.
963
977
#[ serde( default ) ]
964
978
pub cache : CacheConfigV2 ,
979
+ /// Configuration information for chunk deduplication.
980
+ #[ serde( default ) ]
981
+ pub dedup : Option < DeduplicationConfigV2 > ,
965
982
/// Optional file path for metadata blob.
966
983
#[ serde( default ) ]
967
984
pub metadata_path : Option < String > ,
@@ -1024,11 +1041,59 @@ impl From<&BlobCacheEntryConfigV2> for ConfigV2 {
1024
1041
backend : Some ( c. backend . clone ( ) ) ,
1025
1042
cache : Some ( c. cache . clone ( ) ) ,
1026
1043
rafs : None ,
1044
+ dedup : c. dedup . clone ( ) ,
1027
1045
internal : ConfigV2Internal :: default ( ) ,
1028
1046
}
1029
1047
}
1030
1048
}
1031
1049
1050
+ /// Configuration information for image deduplication.
1051
+ #[ derive( Clone , Debug , Default , Deserialize , Eq , PartialEq , Serialize ) ]
1052
+ pub struct DeduplicationConfigV2 {
1053
+ #[ serde( default ) ]
1054
+ pub enable : bool ,
1055
+ #[ serde( default ) ]
1056
+ pub work_dir : String ,
1057
+ }
1058
+
1059
+ impl DeduplicationConfigV2 {
1060
+ /// Validate image deduplication configuration.
1061
+ pub fn validate ( & self ) -> bool {
1062
+ true
1063
+ }
1064
+
1065
+ pub fn get_enable ( & self ) -> bool {
1066
+ self . enable
1067
+ }
1068
+ pub fn get_work_dir ( & self ) -> Result < & str > {
1069
+ let path = fs:: metadata ( & self . work_dir )
1070
+ . or_else ( |_| {
1071
+ fs:: create_dir_all ( & self . work_dir ) ?;
1072
+ fs:: metadata ( & self . work_dir )
1073
+ } )
1074
+ . map_err ( |e| {
1075
+ log:: error!(
1076
+ "fail to stat deduplication work_dir {}: {}" ,
1077
+ self . work_dir,
1078
+ e
1079
+ ) ;
1080
+ e
1081
+ } ) ?;
1082
+
1083
+ if path. is_dir ( ) {
1084
+ Ok ( & self . work_dir )
1085
+ } else {
1086
+ Err ( Error :: new (
1087
+ ErrorKind :: NotFound ,
1088
+ format ! (
1089
+ "deduplication work_dir {} is not a directory" ,
1090
+ self . work_dir
1091
+ ) ,
1092
+ ) )
1093
+ }
1094
+ }
1095
+ }
1096
+
1032
1097
/// Internal runtime configuration.
1033
1098
#[ derive( Clone , Debug ) ]
1034
1099
pub struct ConfigV2Internal {
@@ -1070,7 +1135,7 @@ pub const BLOB_CACHE_TYPE_META_BLOB: &str = "bootstrap";
1070
1135
pub const BLOB_CACHE_TYPE_DATA_BLOB : & str = "datablob" ;
1071
1136
1072
1137
/// Configuration information for a cached blob.
1073
- #[ derive( Debug , Deserialize , Serialize ) ]
1138
+ #[ derive( Debug , Deserialize , Serialize , Clone ) ]
1074
1139
pub struct BlobCacheEntry {
1075
1140
/// Type of blob object, bootstrap or data blob.
1076
1141
#[ serde( rename = "type" ) ]
@@ -1325,6 +1390,28 @@ impl TryFrom<&CacheConfig> for CacheConfigV2 {
1325
1390
}
1326
1391
}
1327
1392
1393
+ /// Configuration information for image deduplication.
1394
+ #[ derive( Clone , Debug , Default , Deserialize , Eq , PartialEq , Serialize ) ]
1395
+ struct DeduplicationConfig {
1396
+ /// Whether to enable image dedup
1397
+ #[ serde( default ) ]
1398
+ pub enable : bool ,
1399
+ /// Work fir for image dedup
1400
+ #[ serde( default ) ]
1401
+ pub work_dir : String ,
1402
+ }
1403
+
1404
+ impl TryFrom < & DeduplicationConfig > for DeduplicationConfigV2 {
1405
+ type Error = std:: io:: Error ;
1406
+
1407
+ fn try_from ( v : & DeduplicationConfig ) -> std:: result:: Result < Self , Self :: Error > {
1408
+ Ok ( DeduplicationConfigV2 {
1409
+ enable : v. enable ,
1410
+ work_dir : v. work_dir . clone ( ) ,
1411
+ } )
1412
+ }
1413
+ }
1414
+
1328
1415
/// Configuration information to create blob cache manager.
1329
1416
#[ derive( Clone , Debug , Default , Deserialize , Eq , PartialEq , Serialize ) ]
1330
1417
struct FactoryConfig {
@@ -1336,6 +1423,9 @@ struct FactoryConfig {
1336
1423
/// Configuration for blob cache manager.
1337
1424
#[ serde( default ) ]
1338
1425
pub cache : CacheConfig ,
1426
+ /// Configuration information for image deduplication.
1427
+ #[ serde( default ) ]
1428
+ pub dedup : Option < DeduplicationConfig > ,
1339
1429
}
1340
1430
1341
1431
/// Rafs storage backend configuration information.
@@ -1374,6 +1464,14 @@ impl TryFrom<RafsConfig> for ConfigV2 {
1374
1464
fn try_from ( v : RafsConfig ) -> std:: result:: Result < Self , Self :: Error > {
1375
1465
let backend: BackendConfigV2 = ( & v. device . backend ) . try_into ( ) ?;
1376
1466
let mut cache: CacheConfigV2 = ( & v. device . cache ) . try_into ( ) ?;
1467
+ let dedup: Option < DeduplicationConfigV2 > = match & v. device . dedup {
1468
+ Some ( dedup) => {
1469
+ let dedup_v2: DeduplicationConfigV2 = dedup. try_into ( ) ?;
1470
+ Some ( dedup_v2)
1471
+ }
1472
+ None => None ,
1473
+ } ;
1474
+ // (&v.device.dedup).try_into()?;
1377
1475
let rafs = RafsConfigV2 {
1378
1476
mode : v. mode ,
1379
1477
batch_size : v. amplify_io ,
@@ -1394,6 +1492,7 @@ impl TryFrom<RafsConfig> for ConfigV2 {
1394
1492
backend : Some ( backend) ,
1395
1493
cache : Some ( cache) ,
1396
1494
rafs : Some ( rafs) ,
1495
+ dedup,
1397
1496
internal : ConfigV2Internal :: default ( ) ,
1398
1497
} )
1399
1498
}
@@ -1487,6 +1586,8 @@ pub(crate) struct BlobCacheEntryConfig {
1487
1586
///
1488
1587
/// Possible value: `FileCacheConfig`, `FsCacheConfig`.
1489
1588
cache_config : Value ,
1589
+ /// Configuration for chunk deduplication
1590
+ dedup_config : Option < DeduplicationConfig > ,
1490
1591
/// Configuration for data prefetch.
1491
1592
#[ serde( default ) ]
1492
1593
prefetch_config : BlobPrefetchConfig ,
@@ -1510,11 +1611,19 @@ impl TryFrom<&BlobCacheEntryConfig> for BlobCacheEntryConfigV2 {
1510
1611
cache_validate : false ,
1511
1612
prefetch_config : v. prefetch_config . clone ( ) ,
1512
1613
} ;
1614
+ let dedup_config = match & v. dedup_config {
1615
+ Some ( cfg) => {
1616
+ let cfg_v2: DeduplicationConfigV2 = cfg. try_into ( ) ?;
1617
+ Some ( cfg_v2)
1618
+ }
1619
+ None => None ,
1620
+ } ;
1513
1621
Ok ( BlobCacheEntryConfigV2 {
1514
1622
version : 2 ,
1515
1623
id : v. id . clone ( ) ,
1516
1624
backend : ( & backend_config) . try_into ( ) ?,
1517
1625
cache : ( & cache_config) . try_into ( ) ?,
1626
+ dedup : dedup_config,
1518
1627
metadata_path : v. metadata_path . clone ( ) ,
1519
1628
} )
1520
1629
}
0 commit comments