@@ -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 )
@@ -185,7 +191,6 @@ async function process_bucket(config_fs, bucket_name, system_json) {
185
191
*/
186
192
async function process_rules ( config_fs , bucket_json , object_sdk , should_notify ) {
187
193
try {
188
- lifecycle_run_status . buckets_statuses [ bucket_json . name ] . state ??= { } ;
189
194
const bucket_state = lifecycle_run_status . buckets_statuses [ bucket_json . name ] . state ;
190
195
bucket_state . num_processed_objects = 0 ;
191
196
while ( ! bucket_state . is_finished && bucket_state . num_processed_objects < config . NC_LIFECYCLE_BUCKET_BATCH_SIZE ) {
@@ -409,7 +414,7 @@ async function throw_if_noobaa_not_active(config_fs, system_json) {
409
414
*/
410
415
async function get_candidates ( bucket_json , lifecycle_rule , object_sdk , fs_context ) {
411
416
const candidates = { abort_mpu_candidates : [ ] , delete_candidates : [ ] } ;
412
- const rule_state = lifecycle_run_status . buckets_statuses [ bucket_json . name ] . rules_statuses [ lifecycle_rule . id ] ? .state || { } ;
417
+ const rule_state = lifecycle_run_status . buckets_statuses [ bucket_json . name ] . rules_statuses [ lifecycle_rule . id ] . state ;
413
418
if ( lifecycle_rule . expiration ) {
414
419
candidates . delete_candidates = await get_candidates_by_expiration_rule ( lifecycle_rule , bucket_json , object_sdk , rule_state ) ;
415
420
if ( lifecycle_rule . expiration . days || lifecycle_rule . expiration . expired_object_delete_marker ) {
@@ -755,9 +760,9 @@ function update_status({ bucket_name, rule_id, op_name, op_times, reply = [], er
755
760
// TODO - check errors
756
761
if ( op_times . start_time ) {
757
762
if ( op_name === TIMED_OPS . PROCESS_RULE ) {
758
- lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] = { rule_process_times : { } , rule_stats : { } } ;
763
+ init_rule_status ( bucket_name , rule_id ) ;
759
764
} else if ( op_name === TIMED_OPS . PROCESS_BUCKET ) {
760
- lifecycle_run_status . buckets_statuses [ bucket_name ] = { bucket_process_times : { } , bucket_stats : { } , rules_statuses : { } } ;
765
+ init_bucket_status ( bucket_name ) ;
761
766
}
762
767
}
763
768
_update_times_on_status ( { op_name, op_times, bucket_name, rule_id } ) ;
@@ -882,6 +887,60 @@ async function write_lifecycle_log_file(fs_context, lifecyle_logs_dir_path) {
882
887
) ;
883
888
}
884
889
890
+ /**
891
+ * init the bucket status object statuses if they don't exist
892
+ * @param {string } bucket_name
893
+ * @returns {Object } created or existing bucket status
894
+ */
895
+ function init_bucket_status ( bucket_name ) {
896
+ lifecycle_run_status . buckets_statuses [ bucket_name ] ??= { } ;
897
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses ??= { } ;
898
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . state ??= { } ;
899
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . bucket_process_times = { } ;
900
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . bucket_stats = { } ;
901
+ return lifecycle_run_status . buckets_statuses [ bucket_name ] ;
902
+ }
903
+
904
+ /**
905
+ * init the rule status object statuses if they don't exist
906
+ * @param {string } bucket_name
907
+ * @param {string } rule_id
908
+ * @returns {Object } created or existing rule status
909
+ */
910
+ function init_rule_status ( bucket_name , rule_id ) {
911
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] ??= { } ;
912
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . state ??= { } ;
913
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . rule_process_times = { } ;
914
+ lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] . rule_stats = { } ;
915
+ return lifecycle_run_status . buckets_statuses [ bucket_name ] . rules_statuses [ rule_id ] ;
916
+ }
917
+
918
+ /**
919
+ *
920
+ * @param {Object[] } buckets
921
+ * @param {Object } config_fs
922
+ * @returns
923
+ */
924
+ async function load_previous_run_state ( buckets , config_fs ) {
925
+ const previous_run = await lifecycle_utils . get_latest_nc_lifecycle_run_status ( config_fs , { silent_if_missing : true } ) ;
926
+ if ( previous_run ) {
927
+ lifecycle_run_status . state = previous_run . state ;
928
+ for ( const [ bucket_name , prev_bucket_status ] of Object . entries ( previous_run . buckets_statuses ) ) {
929
+ if ( ! buckets . includes ( bucket_name ) ) continue ;
930
+ const bucket_json = await config_fs . get_bucket_by_name ( bucket_name , config_fs_options ) ;
931
+ if ( ! bucket_json . lifecycle_configuration_rules ) continue ;
932
+ const bucket_status = init_bucket_status ( bucket_name ) ;
933
+ bucket_status . state = prev_bucket_status . state ;
934
+ const bucket_rules = bucket_json . lifecycle_configuration_rules . map ( rule => rule . id ) ;
935
+ for ( const [ rule_id , prev_rule_status ] of Object . entries ( prev_bucket_status . rules_statuses ) ) {
936
+ if ( ! bucket_rules . includes ( rule_id ) ) return ;
937
+ const rule_status = init_rule_status ( bucket_name , rule_id ) ;
938
+ rule_status . state = prev_rule_status . state ;
939
+ }
940
+ }
941
+ }
942
+ }
943
+
885
944
// EXPORTS
886
945
exports . run_lifecycle_under_lock = run_lifecycle_under_lock ;
887
946
0 commit comments