@@ -341,6 +341,8 @@ impl Configurator {
341
341
///
342
342
/// This function will return an error if the underlying resource fails.
343
343
pub fn invoke_get ( & mut self ) -> Result < ConfigurationGetResult , DscError > {
344
+ self . unroll_copy_loops ( ) ?;
345
+
344
346
let mut result = ConfigurationGetResult :: new ( ) ;
345
347
let resources = get_resource_invocation_order ( & self . config , & mut self . statement_parser , & self . context ) ?;
346
348
let mut progress = ProgressBar :: new ( resources. len ( ) as u64 , self . progress_format ) ?;
@@ -421,6 +423,8 @@ impl Configurator {
421
423
/// This function will return an error if the underlying resource fails.
422
424
#[ allow( clippy:: too_many_lines) ]
423
425
pub fn invoke_set ( & mut self , skip_test : bool ) -> Result < ConfigurationSetResult , DscError > {
426
+ self . unroll_copy_loops ( ) ?;
427
+
424
428
let mut result = ConfigurationSetResult :: new ( ) ;
425
429
let resources = get_resource_invocation_order ( & self . config , & mut self . statement_parser , & self . context ) ?;
426
430
let mut progress = ProgressBar :: new ( resources. len ( ) as u64 , self . progress_format ) ?;
@@ -575,6 +579,8 @@ impl Configurator {
575
579
///
576
580
/// This function will return an error if the underlying resource fails.
577
581
pub fn invoke_test ( & mut self ) -> Result < ConfigurationTestResult , DscError > {
582
+ self . unroll_copy_loops ( ) ?;
583
+
578
584
let mut result = ConfigurationTestResult :: new ( ) ;
579
585
let resources = get_resource_invocation_order ( & self . config , & mut self . statement_parser , & self . context ) ?;
580
586
let mut progress = ProgressBar :: new ( resources. len ( ) as u64 , self . progress_format ) ?;
@@ -651,6 +657,8 @@ impl Configurator {
651
657
///
652
658
/// This function will return an error if the underlying resource fails.
653
659
pub fn invoke_export ( & mut self ) -> Result < ConfigurationExportResult , DscError > {
660
+ self . unroll_copy_loops ( ) ?;
661
+
654
662
let mut result = ConfigurationExportResult :: new ( ) ;
655
663
let mut conf = config_doc:: Configuration :: new ( ) ;
656
664
conf. metadata . clone_from ( & self . config . metadata ) ;
@@ -874,7 +882,7 @@ impl Configurator {
874
882
}
875
883
876
884
fn validate_config ( & mut self ) -> Result < ( ) , DscError > {
877
- let mut config: Configuration = serde_json:: from_str ( self . json . as_str ( ) ) ?;
885
+ let config: Configuration = serde_json:: from_str ( self . json . as_str ( ) ) ?;
878
886
check_security_context ( config. metadata . as_ref ( ) ) ?;
879
887
880
888
// Perform discovery of resources used in config
@@ -886,15 +894,33 @@ impl Configurator {
886
894
if !discovery_filter. contains ( & filter) {
887
895
discovery_filter. push ( filter) ;
888
896
}
889
- // if the resource contains `Copy`, we need to unroll
897
+ // defer actual unrolling until parameters are available
890
898
if let Some ( copy) = & resource. copy {
891
- debug ! ( "{}" , t!( "configure.mod.unrollingCopy " , name = & copy. name, count = copy. count) ) ;
899
+ debug ! ( "{}" , t!( "configure.mod.validateCopy " , name = & copy. name, count = copy. count) ) ;
892
900
if copy. mode . is_some ( ) {
893
901
return Err ( DscError :: Validation ( t ! ( "configure.mod.copyModeNotSupported" ) . to_string ( ) ) ) ;
894
902
}
895
903
if copy. batch_size . is_some ( ) {
896
904
return Err ( DscError :: Validation ( t ! ( "configure.mod.copyBatchSizeNotSupported" ) . to_string ( ) ) ) ;
897
905
}
906
+ }
907
+ }
908
+
909
+ self . discovery . find_resources ( & discovery_filter, self . progress_format ) ;
910
+ self . config = config;
911
+ Ok ( ( ) )
912
+ }
913
+
914
+ /// Unroll copy loops in the configuration.
915
+ /// This method should be called after parameters have been set in the context.
916
+ fn unroll_copy_loops ( & mut self ) -> Result < ( ) , DscError > {
917
+ let mut config = self . config . clone ( ) ;
918
+ let config_copy = config. clone ( ) ;
919
+
920
+ for resource in config_copy. resources {
921
+ // if the resource contains `Copy`, unroll it
922
+ if let Some ( copy) = & resource. copy {
923
+ debug ! ( "{}" , t!( "configure.mod.unrollingCopy" , name = & copy. name, count = copy. count) ) ;
898
924
self . context . process_mode = ProcessMode :: Copy ;
899
925
self . context . copy_current_loop_name . clone_from ( & copy. name ) ;
900
926
let mut copy_resources = Vec :: < Resource > :: new ( ) ;
@@ -905,6 +931,7 @@ impl Configurator {
905
931
return Err ( DscError :: Parser ( t ! ( "configure.mod.copyNameResultNotString" ) . to_string ( ) ) )
906
932
} ;
907
933
new_resource. name = new_name. to_string ( ) ;
934
+
908
935
new_resource. copy = None ;
909
936
copy_resources. push ( new_resource) ;
910
937
}
@@ -914,8 +941,7 @@ impl Configurator {
914
941
config. resources . extend ( copy_resources) ;
915
942
}
916
943
}
917
-
918
- self . discovery . find_resources ( & discovery_filter, self . progress_format ) ;
944
+
919
945
self . config = config;
920
946
Ok ( ( ) )
921
947
}
0 commit comments