@@ -18,6 +18,7 @@ const { throw_cli_error, get_service_status, NOOBAA_SERVICE_NAME,
18
18
is_desired_time, record_current_time } = require ( './manage_nsfs_cli_utils' ) ;
19
19
const SensitiveString = require ( '../util/sensitive_string' ) ;
20
20
const { CONFIG_TYPES } = require ( '../sdk/config_fs' ) ;
21
+ const lifecycle_utils = require ( '../util/lifecycle_utils' ) ;
21
22
22
23
// TODO:
23
24
// implement
@@ -53,11 +54,12 @@ const TIMED_OPS = Object.freeze({
53
54
* run_lifecycle_under_lock runs the lifecycle workflow under a file system lock
54
55
* lifecycle workflow is being locked to prevent multiple instances from running the lifecycle workflow
55
56
* @param {import('../sdk/config_fs').ConfigFS } config_fs
56
- * @param {{disable_service_validation?: boolean, disable_runtime_validation?: boolean, short_status?: boolean} } flags
57
+ * @param {{disable_service_validation?: boolean, disable_runtime_validation?: boolean, short_status?: boolean, should_continue_last_run?: boolean } } flags
57
58
* @returns {Promise<{should_run: Boolean, lifecycle_run_status: Object}> }
58
59
*/
59
60
async function run_lifecycle_under_lock ( config_fs , flags ) {
60
- const { disable_service_validation = false , disable_runtime_validation = false , short_status = false } = flags ;
61
+ const { disable_service_validation = false , disable_runtime_validation = false , short_status = false ,
62
+ should_continue_last_run = false } = flags ;
61
63
return_short_status = short_status ;
62
64
const fs_context = config_fs . fs_context ;
63
65
const lifecyle_logs_dir_path = config . NC_LIFECYCLE_LOGS_DIR ;
@@ -76,7 +78,7 @@ async function run_lifecycle_under_lock(config_fs, flags) {
76
78
try {
77
79
dbg . log0 ( 'run_lifecycle_under_lock acquired lock - start lifecycle' ) ;
78
80
new NoobaaEvent ( NoobaaEvent . LIFECYCLE_STARTED ) . create_event ( ) ;
79
- await run_lifecycle_or_timeout ( config_fs , disable_service_validation ) ;
81
+ await run_lifecycle_or_timeout ( config_fs , disable_service_validation , should_continue_last_run ) ;
80
82
} catch ( err ) {
81
83
dbg . error ( 'run_lifecycle_under_lock failed with error' , err , err . code , err . message ) ;
82
84
throw err ;
@@ -96,13 +98,13 @@ async function run_lifecycle_under_lock(config_fs, flags) {
96
98
* @param {boolean } disable_service_validation
97
99
* @returns {Promise<Void> }
98
100
*/
99
- async function run_lifecycle_or_timeout ( config_fs , disable_service_validation ) {
101
+ async function run_lifecycle_or_timeout ( config_fs , disable_service_validation , should_continue_last_run ) {
100
102
await _call_op_and_update_status ( {
101
103
op_name : TIMED_OPS . RUN_LIFECYLE ,
102
104
op_func : async ( ) => {
103
105
await P . timeout (
104
106
config . NC_LIFECYCLE_TIMEOUT_MS ,
105
- run_lifecycle ( config_fs , disable_service_validation ) ,
107
+ run_lifecycle ( config_fs , disable_service_validation , should_continue_last_run ) ,
106
108
( ) => ManageCLIError . LifecycleWorkerReachedTimeout
107
109
) ;
108
110
}
@@ -115,7 +117,7 @@ async function run_lifecycle_or_timeout(config_fs, disable_service_validation) {
115
117
* @param {boolean } disable_service_validation
116
118
* @returns {Promise<Void> }
117
119
*/
118
- async function run_lifecycle ( config_fs , disable_service_validation ) {
120
+ async function run_lifecycle ( config_fs , disable_service_validation , should_continue_last_run ) {
119
121
const system_json = await config_fs . get_system_config_file ( config_fs_options ) ;
120
122
if ( ! disable_service_validation ) await throw_if_noobaa_not_active ( config_fs , system_json ) ;
121
123
@@ -124,6 +126,10 @@ async function run_lifecycle(config_fs, disable_service_validation) {
124
126
op_func : async ( ) => config_fs . list_buckets ( )
125
127
} ) ;
126
128
129
+ if ( should_continue_last_run ) {
130
+ await load_previous_run_state ( bucket_names , config_fs ) ;
131
+ }
132
+
127
133
await _call_op_and_update_status ( {
128
134
op_name : TIMED_OPS . PROCESS_BUCKETS ,
129
135
op_func : async ( ) => process_buckets ( config_fs , bucket_names , system_json )
@@ -735,6 +741,32 @@ async function _call_op_and_update_status({ bucket_name = undefined, rule_id = u
735
741
}
736
742
}
737
743
744
+ /**
745
+ * init the bucket status object statuses if they don't exist
746
+ * @param {string } bucket_name
747
+ * @returns {Object } created or existing bucket status
748
+ */
749
+ function init_bucket_status ( bucket_name ) {
750
+ lifecycle_run_status . buckets_statuses [ bucket_name ] ??= { } ;
751
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses ??= { } ;
752
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . bucket_process_times = { } ;
753
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . bucket_stats = { } ;
754
+ return lifecycle_run_status . buckets_statuses [ bucket_name ] ;
755
+ }
756
+
757
+ /**
758
+ * init the rule status object statuses if they don't exist
759
+ * @param {string } bucket_name
760
+ * @param {string } rule_id
761
+ * @returns {Object } created or existing rule status
762
+ */
763
+ function init_rule_status ( bucket_name , rule_id ) {
764
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] ??= { } ;
765
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . rule_process_times = { } ;
766
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . rule_stats = { } ;
767
+ return lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] ;
768
+ }
769
+
738
770
/**
739
771
* update_status updates rule/bucket/global based on the given parameters
740
772
* 1. initalize statuses/times/stats per level
@@ -755,9 +787,9 @@ function update_status({ bucket_name, rule_id, op_name, op_times, reply = [], er
755
787
// TODO - check errors
756
788
if ( op_times . start_time ) {
757
789
if ( op_name === TIMED_OPS . PROCESS_RULE ) {
758
- lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] = { rule_process_times : { } , rule_stats : { } } ;
790
+ init_rule_status ( bucket_name , rule_id ) ;
759
791
} else if ( op_name === TIMED_OPS . PROCESS_BUCKET ) {
760
- lifecycle_run_status . buckets_statuses [ bucket_name ] = { bucket_process_times : { } , bucket_stats : { } , rules_statuses : { } } ;
792
+ init_bucket_status ( bucket_name ) ;
761
793
}
762
794
}
763
795
_update_times_on_status ( { op_name, op_times, bucket_name, rule_id } ) ;
@@ -882,6 +914,26 @@ async function write_lifecycle_log_file(fs_context, lifecyle_logs_dir_path) {
882
914
) ;
883
915
}
884
916
917
+ async function load_previous_run_state ( buckets , config_fs ) {
918
+ const previous_run = await lifecycle_utils . get_latest_nc_lifecycle_run_status ( config_fs , { silent_if_missing : true } ) ;
919
+ if ( previous_run ) {
920
+ lifecycle_run_status . state = previous_run . state ;
921
+ for ( const [ bucket_name , prev_bucket_status ] of Object . entries ( previous_run . buckets_statuses ) ) {
922
+ if ( ! buckets . includes ( bucket_name ) ) continue ;
923
+ const bucket_json = await config_fs . get_bucket_by_name ( bucket_name , config_fs_options ) ;
924
+ if ( ! bucket_json . lifecycle_configuration_rules ) continue ;
925
+ const bucket_status = init_bucket_status ( bucket_name ) ;
926
+ bucket_status . state = prev_bucket_status . state ;
927
+ const bucket_rules = bucket_json . lifecycle_configuration_rules . map ( rule => rule . id ) ;
928
+ for ( const [ rule_id , prev_rule_status ] of Object . entries ( prev_bucket_status . rules_statuses ) ) {
929
+ if ( ! bucket_rules . includes ( rule_id ) ) return ;
930
+ const rule_status = init_rule_status ( bucket_name , rule_id ) ;
931
+ rule_status . state = prev_rule_status . state ;
932
+ }
933
+ }
934
+ }
935
+ }
936
+
885
937
// EXPORTS
886
938
exports . run_lifecycle_under_lock = run_lifecycle_under_lock ;
887
939
0 commit comments