@@ -180,7 +180,7 @@ def __init__(self):
180
180
# Last timestamp we checked for an updated
181
181
self .update_check_timestamp = config .get (
182
182
'UPDATE' , 'timestamp' , fallback = None )
183
-
183
+
184
184
# Shared configuration
185
185
self .is_shared = config .getboolean (
186
186
'SHARED' , 'is_shared' , fallback = False )
@@ -1210,6 +1210,9 @@ def check_update(self):
1210
1210
1211
1211
if hasattr (self , 'update_check_timestamp' ) and self .update_check_timestamp is not None :
1212
1212
# Check if last day was less than 86400 * 7 = (1 day) * 7 = 1 week
1213
+ print (timestamp )
1214
+ print (self .update_check_timestamp )
1215
+ print (timestamp - self .update_check_timestamp )
1213
1216
if timestamp - self .update_check_timestamp < (86400 * 7 ):
1214
1217
# Less than a week since last check
1215
1218
return False
@@ -3241,7 +3244,7 @@ def _index_locally(self, folder):
3241
3244
except Exception :
3242
3245
print_error ()
3243
3246
3244
- def _slurm_cmd (self , folders , cmd_type ):
3247
+ def _slurm_cmd (self , folders , cmd_type , scheduled ):
3245
3248
'''Execute the current command using SLURM'''
3246
3249
3247
3250
try :
@@ -3262,7 +3265,8 @@ def _slurm_cmd(self, folders, cmd_type):
3262
3265
se .submit_job (cmd = cmd ,
3263
3266
cmd_type = cmd_type ,
3264
3267
label = label ,
3265
- shortlabel = shortlabel )
3268
+ shortlabel = shortlabel ,
3269
+ scheduled = scheduled )
3266
3270
3267
3271
except Exception :
3268
3272
print_error ()
@@ -4458,41 +4462,50 @@ def restore(self, folders, aws: AWSBoto):
4458
4462
f' froster archive --permissions "/your/folder/to/archive"\n ' , file = sys .stderr )
4459
4463
return
4460
4464
4461
- if use_slurm (self .args .noslurm ):
4462
- self ._slurm_cmd (folders = folders , cmd_type = 'restore' )
4463
4465
4464
- else :
4465
- # Archive locally all folders. If recursive flag set, archive all subfolders too.
4466
- for folder in folders :
4467
- for root , dirs , files in self ._walker (folder ):
4466
+ # Archive locally all folders. If recursive flag set, archive all subfolders too.
4467
+ for folder in folders :
4468
+ for root , dirs , files in self ._walker (folder ):
4468
4469
4469
- # Break in case of non-recursive restore
4470
- if not is_recursive and root != folder :
4471
- break
4470
+ # Break in case of non-recursive restore
4471
+ if not is_recursive and root != folder :
4472
+ break
4472
4473
4473
- archived_folder_info = self .froster_archives_get_entry (
4474
- root )
4474
+ archived_folder_info = self .froster_archives_get_entry (
4475
+ root )
4475
4476
4476
- if archived_folder_info is None :
4477
- print (f'\n Folder { root } is not archived' )
4478
- print (f'No entry found in froster-archives.json\n ' )
4479
- continue
4477
+ if archived_folder_info is None :
4478
+ print (f'\n Folder { root } is not archived' )
4479
+ print (f'No entry found in froster-archives.json\n ' )
4480
+ continue
4480
4481
4481
- if not self ._contains_non_froster_files (root ):
4482
- print (f'\n WARNING: Folder { root } contains non-froster metadata files' )
4483
- print ('Has this folder been deleted using "froster delete" command?.' )
4484
- print ('Please empty the folder before restoring.\n ' )
4485
- continue
4482
+ if not self ._contains_non_froster_files (root ):
4483
+ print (
4484
+ f'\n WARNING: Folder { root } contains non-froster metadata files' )
4485
+ print (
4486
+ 'Has this folder been deleted using "froster delete" command?.' )
4487
+ print ('Please empty the folder before restoring.\n ' )
4488
+ continue
4486
4489
4487
- if self ._restore_locally (root , aws ):
4490
+ if self ._restore_locally (root , aws ):
4491
+ # Already restored
4488
4492
4489
- # If nodownload flag is set we are done
4490
- if self .args .nodownload :
4491
- print (
4492
- f'\n Folder restored but not downloaded (--no-download flag set)\n ' )
4493
- return
4494
- else :
4493
+ # If nodownload flag is set we are done
4494
+ if self .args .nodownload :
4495
+ print (
4496
+ f'\n Folder restored but not downloaded (--no-download flag set)\n ' )
4497
+ return
4498
+ else :
4495
4499
self ._download (root )
4500
+ else :
4501
+ # Restore ongoing
4502
+ # In this case the slurm will only be used for downloading. AWS has taken care of the restore
4503
+ if is_slurm_installed () and not self .args .noslurm :
4504
+ # schedule execution in 12 hours
4505
+ self ._slurm_cmd (
4506
+ folders = folders , cmd_type = 'restore' , scheduled = 12 )
4507
+
4508
+
4496
4509
4497
4510
except Exception :
4498
4511
print_error ()
@@ -4518,7 +4531,8 @@ def _restore_verify(self, source, target):
4518
4531
return
4519
4532
4520
4533
# Get the path to the hashfile
4521
- hashfile = os .path .join (restpath , self .md5sum_restored_filename )
4534
+ hashfile = os .path .join (
4535
+ restpath , self .md5sum_restored_filename )
4522
4536
4523
4537
# Create the Rclone object
4524
4538
rclone = Rclone (self .args , self .cfg )
@@ -4539,7 +4553,8 @@ def _restore_verify(self, source, target):
4539
4553
os .remove (tar_path )
4540
4554
print (' ...done\n ' )
4541
4555
4542
- where_did_file_go_full_path = os .path .join (target , self .where_did_the_files_go_filename )
4556
+ where_did_file_go_full_path = os .path .join (
4557
+ target , self .where_did_the_files_go_filename )
4543
4558
if os .path .exists (where_did_file_go_full_path ):
4544
4559
os .remove (where_did_file_go_full_path )
4545
4560
@@ -5581,7 +5596,7 @@ def _reorder_sbatch_lines(self, script_buffer):
5581
5596
except Exception :
5582
5597
print_error ()
5583
5598
5584
- def submit_job (self , cmd , cmd_type , label , shortlabel ):
5599
+ def submit_job (self , cmd , cmd_type , label , shortlabel , scheduled = None ):
5585
5600
'''Submit a Slurm job'''
5586
5601
5587
5602
try :
@@ -5594,6 +5609,9 @@ def submit_job(self, cmd, cmd_type, label, shortlabel):
5594
5609
f'#SBATCH --job-name=froster:{ cmd_type } :{ shortlabel } ' )
5595
5610
self .add_line (f'#SBATCH --cpus-per-task={ self .args .cores } ' )
5596
5611
self .add_line (f'#SBATCH --mem={ self .args .memory } ' )
5612
+ if scheduled :
5613
+ self .add_line (f'#SBATCH --begin={ scheduled } ' )
5614
+ self .add_line (f'#SBATCH --requeue' )
5597
5615
self .add_line (f'#SBATCH --output={ output_dir } -%J.out' )
5598
5616
self .add_line (f'#SBATCH --mail-type=FAIL,REQUEUE,END' )
5599
5617
self .add_line (f'#SBATCH --mail-user={ self .cfg .email } ' )
@@ -6201,7 +6219,8 @@ def subcmd_archive(self, arch: Archiver, aws: AWSBoto):
6201
6219
return
6202
6220
6203
6221
if not aws .check_credentials ():
6204
- print ('\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6222
+ print (
6223
+ '\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6205
6224
sys .exit (1 )
6206
6225
6207
6226
# Check if the user provided the hotspots argument
@@ -6231,7 +6250,8 @@ def subcmd_restore(self, arch: Archiver, aws: AWSBoto):
6231
6250
6232
6251
try :
6233
6252
if not aws .check_credentials ():
6234
- print ('\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6253
+ print (
6254
+ '\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6235
6255
sys .exit (1 )
6236
6256
6237
6257
if self .args .monitor :
@@ -6274,9 +6294,10 @@ def subcmd_delete(self, arch: Archiver, aws: AWSBoto):
6274
6294
6275
6295
try :
6276
6296
if not aws .check_credentials ():
6277
- print ('\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6297
+ print (
6298
+ '\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6278
6299
sys .exit (1 )
6279
-
6300
+
6280
6301
if not self .args .folders :
6281
6302
6282
6303
# Get the list of folders from the archive
@@ -6311,9 +6332,10 @@ def subcmd_mount(self, arch: Archiver, aws: AWSBoto):
6311
6332
6312
6333
try :
6313
6334
if not aws .check_credentials ():
6314
- print ('\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6335
+ print (
6336
+ '\n Error: invalid credentials. Check the AWS configuration with "froster config --aws"\n ' )
6315
6337
sys .exit (1 )
6316
-
6338
+
6317
6339
if self .args .list :
6318
6340
arch .print_current_mounts ()
6319
6341
return
@@ -6454,19 +6476,20 @@ def subcmd_credentials(self, cfg: ConfigManager, aws: AWSBoto):
6454
6476
print (' ...AWS credentials are NOT valid\n ' )
6455
6477
return False
6456
6478
6457
- def subcmd_update (self ):
6479
+ def subcmd_update (self , mute_no_update ):
6458
6480
'''Check if an update is available'''
6459
6481
try :
6460
6482
6461
- cmd = "curl -s https://api.github.com/repos/dirkpetersen /froster/releases"
6462
-
6483
+ cmd = "curl -s https://api.github.com/repos/hpcnow /froster/releases"
6484
+
6463
6485
result = subprocess .run (cmd , shell = True , text = True ,
6464
6486
stdout = subprocess .PIPE , stderr = subprocess .PIPE )
6465
-
6487
+
6466
6488
if result .returncode != 0 :
6467
- print (f"Error checking if froster update available. Command run: { cmd } : { result .stderr .strip ()} " )
6489
+ print (
6490
+ f"Error checking if froster update available. Command run: { cmd } : { result .stderr .strip ()} " )
6468
6491
return False
6469
-
6492
+
6470
6493
def compare_versions (version1 , version2 ):
6471
6494
v1 = [int (v ) for v in version1 .split ("." )]
6472
6495
v2 = [int (v ) for v in version2 .split ("." )]
@@ -6477,7 +6500,7 @@ def compare_versions(version1, version2):
6477
6500
if v1_part != v2_part :
6478
6501
return v1_part - v2_part
6479
6502
return 0
6480
-
6503
+
6481
6504
releases = json .loads (result .stdout )
6482
6505
if not releases :
6483
6506
print ('Note: Could not check for updates' )
@@ -6488,10 +6511,12 @@ def compare_versions(version1, version2):
6488
6511
6489
6512
if compare_versions (latest , current ) > 0 :
6490
6513
print (f'\n A froster update is available: froster v{ latest } ' )
6491
- print (f'You can update froster using the command:' )
6492
- print (f' curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?$(date +%s) | bash\n ' )
6514
+ print (f'\n You can update froster using the command:' )
6515
+ print (
6516
+ f' curl -s https://raw.githubusercontent.com/dirkpetersen/froster/main/install.sh?$(date +%s) | bash\n ' )
6493
6517
else :
6494
- print (f'\n Froster is up to date: froster v{ current } \n ' )
6518
+ if not mute_no_update :
6519
+ print (f'\n Froster is up to date: froster v{ current } \n ' )
6495
6520
6496
6521
except Exception :
6497
6522
print_error ()
@@ -6710,19 +6735,18 @@ def parse_arguments(self):
6710
6735
parser_restore .add_argument ('folders' , action = 'store' , default = [], nargs = '*' ,
6711
6736
help = 'folders you would like to to restore (separated by space)' )
6712
6737
6713
-
6714
6738
parser_restore .add_argument ('-a' , '--aws' , dest = 'aws' , action = 'store_true' ,
6715
6739
help = "Restore folder on new AWS EC2 instance instead of local machine" )
6716
-
6740
+
6717
6741
parser_restore .add_argument ('-d' , '--days' , dest = 'days' , action = 'store' , default = 30 ,
6718
6742
help = 'Number of days to keep data in S3 One Zone-IA storage at $10/TiB/month (default: 30)' )
6719
-
6743
+
6720
6744
parser_restore .add_argument ('-i' , '--instance-type' , dest = 'instancetype' , action = 'store' , default = "" ,
6721
6745
help = 'The EC2 instance type is auto-selected, but you can pick any other type here' )
6722
6746
6723
6747
parser_restore .add_argument ('-l' , '--no-download' , dest = 'nodownload' , action = 'store_true' ,
6724
6748
help = "skip download to local storage after retrieval from Glacier" )
6725
-
6749
+
6726
6750
parser_restore .add_argument ('-m' , '--monitor' , dest = 'monitor' , action = 'store_true' ,
6727
6751
help = "Monitor EC2 server for cost and idle time." )
6728
6752
@@ -6945,13 +6969,13 @@ def main():
6945
6969
elif args .subcmd in ['credentials' , 'crd' ]:
6946
6970
cmd .subcmd_credentials (cfg , aws )
6947
6971
elif args .subcmd in ['update' , 'upd' ]:
6948
- cmd .subcmd_update ()
6972
+ cmd .subcmd_update (mute_no_update = False )
6949
6973
else :
6950
6974
cmd .print_help ()
6951
6975
6952
6976
# Check if there are updates on froster every X days
6953
- if cfg .check_update ():
6954
- cmd .subcmd_update ()
6977
+ if cfg .check_update () and args . subcmd not in [ 'update' , 'upd' ] :
6978
+ cmd .subcmd_update (mute_no_update = True )
6955
6979
6956
6980
# Close the AWS session
6957
6981
aws .close_session ()
0 commit comments