rda-python-dsarch 3.0.16__tar.gz → 3.0.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rda_python_dsarch-3.0.16/src/rda_python_dsarch.egg-info → rda_python_dsarch-3.0.18}/PKG-INFO +2 -2
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/pyproject.toml +2 -2
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/dsarch.py +292 -246
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/dsarch.usg +22 -8
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/pg_arch.py +29 -3
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18/src/rda_python_dsarch.egg-info}/PKG-INFO +2 -2
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/requires.txt +1 -1
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/LICENSE +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/MANIFEST.in +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/README.md +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/setup.cfg +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/PgArch.py +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/PgMeta.py +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/__init__.py +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/ds_arch.py +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch/pg_meta.py +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/SOURCES.txt +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/dependency_links.txt +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/entry_points.txt +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/top_level.txt +0 -0
- {rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/tests/test_dsarch.py +0 -0
{rda_python_dsarch-3.0.16/src/rda_python_dsarch.egg-info → rda_python_dsarch-3.0.18}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_dsarch
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.18
|
|
4
4
|
Summary: RDA Python package for utility program dsarch archive RDA data
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-dsarch
|
|
@@ -11,7 +11,7 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
11
11
|
Requires-Python: >=3.7
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
-
Requires-Dist: rda_python_common
|
|
14
|
+
Requires-Dist: rda_python_common>=3.0.31
|
|
15
15
|
Requires-Dist: rda_python_setuid
|
|
16
16
|
Requires-Dist: rda_python_miscs
|
|
17
17
|
Dynamic: license-file
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rda_python_dsarch"
|
|
7
|
-
version = "3.0.
|
|
7
|
+
version = "3.0.18"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Zaihua Ji", email="zji@ucar.edu" },
|
|
10
10
|
]
|
|
@@ -18,7 +18,7 @@ classifiers = [
|
|
|
18
18
|
"Development Status :: 5 - Production/Stable",
|
|
19
19
|
]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"rda_python_common",
|
|
21
|
+
"rda_python_common>=3.0.31",
|
|
22
22
|
"rda_python_setuid",
|
|
23
23
|
"rda_python_miscs",
|
|
24
24
|
]
|
|
@@ -119,7 +119,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
119
119
|
elif 'XM' in self.params:
|
|
120
120
|
self.crosscopy_help_files('Move')
|
|
121
121
|
else:
|
|
122
|
-
self.archive_help_files
|
|
122
|
+
self.archive_in_passes(self.archive_help_files)
|
|
123
123
|
if 'CL' in self.params: self.delete_local_files()
|
|
124
124
|
elif self.PGOPT['ACTS'] == self.OPTS['AQ'][0]:
|
|
125
125
|
if 'XC' in self.params:
|
|
@@ -130,7 +130,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
130
130
|
elif self.PGOPT['ACTS'] == self.OPTS['AS'][0]:
|
|
131
131
|
self.ALLCNT = len(self.params['SF']) if 'SF' in self.params else len(self.params['LF'])
|
|
132
132
|
self.cache_group_info(self.ALLCNT)
|
|
133
|
-
self.archive_saved_files
|
|
133
|
+
self.archive_in_passes(self.archive_saved_files)
|
|
134
134
|
if 'CL' in self.params: self.delete_local_files()
|
|
135
135
|
elif self.PGOPT['ACTS'] == self.OPTS['AW'][0]:
|
|
136
136
|
self.ALLCNT = len(self.params['WF']) if 'WF' in self.params else len(self.params['LF'])
|
|
@@ -141,8 +141,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
141
141
|
elif 'XM' in self.params:
|
|
142
142
|
self.crosscopy_web_files('Move')
|
|
143
143
|
else:
|
|
144
|
-
self.archive_web_files
|
|
145
|
-
if self.PGSIG['BPROC'] > 1: self.set_webfile_info()
|
|
144
|
+
self.archive_in_passes(self.archive_web_files)
|
|
146
145
|
if 'CL' in self.params: self.delete_local_files()
|
|
147
146
|
elif self.PGOPT['ACTS'] & self.OPTS['CG'][0]:
|
|
148
147
|
self.ALLCNT = len(self.params['GI'])
|
|
@@ -355,7 +354,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
355
354
|
else:
|
|
356
355
|
self.cmdlog()
|
|
357
356
|
|
|
358
|
-
def archive_web_files(self):
|
|
357
|
+
def archive_web_files(self, cpass=0):
|
|
359
358
|
"""
|
|
360
359
|
Archive local files as web files on GLADE and/or the object store.
|
|
361
360
|
|
|
@@ -369,6 +368,11 @@ class DsArch(PgArch, PgMeta):
|
|
|
369
368
|
|
|
370
369
|
Retries the whole batch if transient errors occur, stopping when the
|
|
371
370
|
error count stabilises. Sets self.RETSTAT on unresolved failures.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
cpass -- 0 for a single pass; with -AL N, archive_in_passes() calls 1 for the
|
|
374
|
+
copy pass (copies in up to N child processes, no records) and then 2
|
|
375
|
+
for the record pass (see archive_in_passes())
|
|
372
376
|
"""
|
|
373
377
|
tname = 'wfile'
|
|
374
378
|
dftloc = None
|
|
@@ -379,7 +383,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
379
383
|
dslocflags = set()
|
|
380
384
|
dflags = {}
|
|
381
385
|
self.pglog("Archive {} Web file{} of {} ...".format(self.ALLCNT, s, dsid), self.WARNLG)
|
|
382
|
-
if 'ZD' in self.params or 'UZ' in self.params:
|
|
386
|
+
if cpass != 2 and ('ZD' in self.params or 'UZ' in self.params):
|
|
383
387
|
self.compress_localfile_list(self.PGOPT['CACT'], self.ALLCNT)
|
|
384
388
|
if 'QF' in self.params: self.params['QF'] = self.get_bid_numbers(self.params['QF'])
|
|
385
389
|
self.validate_multiple_values(tname, self.ALLCNT)
|
|
@@ -406,19 +410,15 @@ class DsArch(PgArch, PgMeta):
|
|
|
406
410
|
self.params['SZ'] = [0]*self.ALLCNT
|
|
407
411
|
self.OPTS['SZ'][2] |= 2
|
|
408
412
|
if 'MC' not in self.params: self.params['MC'] = [None]*self.ALLCNT
|
|
409
|
-
reorder = errcnt = metatotal = metacnt = self.ADDCNT = self.MODCNT =
|
|
413
|
+
reorder = errcnt = metatotal = metacnt = self.ADDCNT = self.MODCNT = acnt = ocnt = 0
|
|
410
414
|
perrcnt = self.ALLCNT
|
|
411
415
|
efiles = [1]*self.ALLCNT
|
|
412
|
-
if self.PGSIG['BPROC'] > 1:
|
|
413
|
-
afiles = [None]*self.ALLCNT
|
|
414
|
-
lfiles = [None]*self.ALLCNT
|
|
415
|
-
ofiles = [None]*self.ALLCNT
|
|
416
416
|
fnames = None
|
|
417
417
|
override = self.OVERRIDE
|
|
418
418
|
if not override and 'GF' in self.params: override = self.OVRIDE
|
|
419
419
|
while True:
|
|
420
420
|
for i in range(bidx, self.ALLCNT):
|
|
421
|
-
if
|
|
421
|
+
if cpass != 1 and i > bidx and ((i-bidx)%20) == 0:
|
|
422
422
|
if metacnt >= self.PGOPT['RSMAX']:
|
|
423
423
|
metatotal += self.process_metadata("W", metacnt, self.PGOPT['emerol'])
|
|
424
424
|
metacnt = 0
|
|
@@ -470,14 +470,20 @@ class DsArch(PgArch, PgMeta):
|
|
|
470
470
|
if warch and locfile == afile: warch = 0
|
|
471
471
|
vsnctl = 1 if pgrec and pgrec['vindex'] and pgrec['data_size'] else 0
|
|
472
472
|
chksum = self.params['MC'][i]
|
|
473
|
+
gdone = odone = 0
|
|
474
|
+
if cpass == 2 and i in self.CPFILES: # copied in the -AL copy pass; recopy only what failed
|
|
475
|
+
(gdone, odone) = self.check_pass_copies(i, wfile, afile if warch else None, ofile if oarch else None, bucket, lsize)
|
|
476
|
+
if gdone: warch = 0; acnt += 1
|
|
477
|
+
if odone: oarch = 0; ocnt += 1
|
|
478
|
+
if self.PGLOG['DSCHECK'] and (gdone or odone) and not (warch or oarch): chksize += lsize
|
|
473
479
|
if warch and (vsnctl or not override):
|
|
474
480
|
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE)
|
|
475
481
|
if info:
|
|
476
482
|
if pgrec and chksum and pgrec['checksum'] and pgrec['checksum'] == chksum:
|
|
477
|
-
self.pglog("Web-{}: Same-Checksum ARCHIVED at {}:{}".format(winfo, info['date_modified'], info['time_modified']), self.PGOPT['emllog'])
|
|
483
|
+
self.pglog("Web-{}: Same-Checksum ARCHIVED at {}:{}".format(winfo, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['emllog']))
|
|
478
484
|
warch = 0
|
|
479
|
-
elif info['data_size'] == lsize:
|
|
480
|
-
self.pglog("Web-{}: Same-Size ARCHIVED at {}:{}".format(winfo, info['date_modified'], info['time_modified']), self.PGOPT['wrnlog'])
|
|
485
|
+
elif not override and info['data_size'] == lsize:
|
|
486
|
+
self.pglog("Web-{}: Same-Size ARCHIVED at {}:{}".format(winfo, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['wrnlog']))
|
|
481
487
|
warch = 0
|
|
482
488
|
elif vsnctl and not override:
|
|
483
489
|
self.pglog("Web-{}: Cannot rearchive version controlled file".format(winfo), self.PGOPT['extlog'])
|
|
@@ -493,10 +499,10 @@ class DsArch(PgArch, PgMeta):
|
|
|
493
499
|
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
494
500
|
if info:
|
|
495
501
|
if pgrec and chksum and pgrec['checksum'] and pgrec['checksum'] == chksum:
|
|
496
|
-
self.pglog("Object-{}-{}: Same-Checksum ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), self.PGOPT['emllog'])
|
|
502
|
+
self.pglog("Object-{}-{}: Same-Checksum ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['emllog']))
|
|
497
503
|
oarch = 0
|
|
498
|
-
elif info['data_size'] == lsize:
|
|
499
|
-
self.pglog("Object-{}-{}: Same-Size ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), self.PGOPT['wrnlog'])
|
|
504
|
+
elif not override and info['data_size'] == lsize:
|
|
505
|
+
self.pglog("Object-{}-{}: Same-Size ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['wrnlog']))
|
|
500
506
|
oarch = 0
|
|
501
507
|
elif vsnctl and not override:
|
|
502
508
|
self.pglog("Object-{}-{}: Cannot rearchive version controlled file".format(bucket, ofile), self.PGOPT['extlog'])
|
|
@@ -510,6 +516,10 @@ class DsArch(PgArch, PgMeta):
|
|
|
510
516
|
dflags['O'] = bucket
|
|
511
517
|
continue
|
|
512
518
|
if (warch + oarch) > 0:
|
|
519
|
+
if cpass == 1: # -AL copy pass: copy in a child process; the record pass sets the record
|
|
520
|
+
self.run_copy(i, self.copy_archive_file, afile if warch else None, ofile if oarch else None,
|
|
521
|
+
lfile, bucket, (replace if oarch else 0), self.PGOPT['emerol']|override)
|
|
522
|
+
continue
|
|
513
523
|
if warch:
|
|
514
524
|
if not self.local_copy_local(afile, lfile, self.PGOPT['emerol']|override):
|
|
515
525
|
errcnt += 1
|
|
@@ -526,40 +536,41 @@ class DsArch(PgArch, PgMeta):
|
|
|
526
536
|
continue
|
|
527
537
|
ocnt += 1
|
|
528
538
|
if self.PGLOG['DSCHECK']: chksize += lsize
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
if
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
self.
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if gindex != pgrec['gindex'] and (gindex or (self.OPTS['GI'][2]&2) == 0):
|
|
558
|
-
metacnt += self.record_meta_summary('W', dsid, gindex, pgrec['gindex'])
|
|
559
|
-
if errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
539
|
+
if cpass == 1: continue # the record pass sets the record, also for a file not copied
|
|
540
|
+
if gdone: warch = 1 # as if copied in this pass, for the file info below
|
|
541
|
+
if odone: oarch = 1
|
|
542
|
+
if not fnames: fnames = self.get_field_keys(tname, None, "G") # get setting fields if not yet
|
|
543
|
+
info = None
|
|
544
|
+
if afile: # also when already in place, so a directory gets its real total size
|
|
545
|
+
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE)
|
|
546
|
+
elif oarch:
|
|
547
|
+
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
548
|
+
elif pgrec:
|
|
549
|
+
info = self.get_file_origin_info(wfile, pgrec)
|
|
550
|
+
elif locflag == 'O':
|
|
551
|
+
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
552
|
+
wid = self.set_one_webfile(i, pgrec, wfile, fnames, type, info)
|
|
553
|
+
if not wid:
|
|
554
|
+
self.params['LF'][i] = self.params['WF'][i] = None
|
|
555
|
+
continue
|
|
556
|
+
if 'GX' in self.params and self.PGOPT['GXTYP'].find(type) > -1:
|
|
557
|
+
metacnt += self.record_meta_gather('W', dsid, wfile, self.params['DF'][i])
|
|
558
|
+
self.cache_meta_tindex(dsid, wid, 'W')
|
|
559
|
+
if pgrec and pgrec['meta_link'] and pgrec['meta_link'] != 'N':
|
|
560
|
+
if 'DX' in self.params or self.PGOPT['GXTYP'].find(type) < 0 and self.PGOPT['GXTYP'].find(pgrec['type']) > -1:
|
|
561
|
+
metacnt += self.record_meta_delete('W', dsid, wfile)
|
|
562
|
+
elif 'GI' in self.params:
|
|
563
|
+
gindex = self.params['GI'][i]
|
|
564
|
+
if gindex != pgrec['gindex'] and (gindex or (self.OPTS['GI'][2]&2) == 0):
|
|
565
|
+
metacnt += self.record_meta_summary('W', dsid, gindex, pgrec['gindex'])
|
|
566
|
+
if cpass == 1 or errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
560
567
|
perrcnt = errcnt
|
|
561
|
-
self.pglog("Rearchive failed {}/{} Web file{} for {}".format(errcnt, self.ALLCNT
|
|
568
|
+
self.pglog("Rearchive failed {}/{} Web file{} for {}".format(errcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
562
569
|
errcnt = self.reset_errmsg(0)
|
|
570
|
+
if cpass == 1: # the record pass checks the copies, retries failed ones and sets the records
|
|
571
|
+
self.wait_copy_children()
|
|
572
|
+
self.reset_errmsg(0) # the record pass finds and counts any error again
|
|
573
|
+
return
|
|
563
574
|
if errcnt:
|
|
564
575
|
if 'CL' in self.params: del self.params['CL']
|
|
565
576
|
self.RETSTAT = self.reset_errmsg(errcnt)
|
|
@@ -567,13 +578,6 @@ class DsArch(PgArch, PgMeta):
|
|
|
567
578
|
if efiles[i]: self.params['WF'][i] = ''
|
|
568
579
|
if self.PGLOG['DSCHECK']:
|
|
569
580
|
self.check_storage_dflags(dflags, self.PGLOG['DSCHECK'], self.PGOPT['emerol'])
|
|
570
|
-
if bgcnt:
|
|
571
|
-
self.check_background(None, 0, self.LOGWRN, 1)
|
|
572
|
-
for i in range(self.ALLCNT):
|
|
573
|
-
if afiles[i]:
|
|
574
|
-
self.validate_gladearch(afiles[i], lfiles[i], i)
|
|
575
|
-
if ofiles[i]:
|
|
576
|
-
self.validate_objectarch(ofiles[i], lfiles[i], bucket, i)
|
|
577
581
|
if acnt > 0:
|
|
578
582
|
self.pglog("{} of {} Web file{} archived for {}".format(acnt, self.ALLCNT, s, self.params['DS']), self.PGOPT['emllog'])
|
|
579
583
|
if ocnt > 0:
|
|
@@ -590,7 +594,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
590
594
|
if 'EM' in self.params: self.PGLOG['PRGMSG'] = ""
|
|
591
595
|
if dslocflags: self.set_dataset_locflag(dsid, dslocflags.pop())
|
|
592
596
|
|
|
593
|
-
def archive_help_files(self):
|
|
597
|
+
def archive_help_files(self, cpass=0):
|
|
594
598
|
"""
|
|
595
599
|
Archive local files as dataset help/documentation files on GLADE/object store.
|
|
596
600
|
|
|
@@ -598,6 +602,11 @@ class DsArch(PgArch, PgMeta):
|
|
|
598
602
|
file path (RTPATH['H<type>']) and registering records in the hfile table.
|
|
599
603
|
Handles both GLADE (warch) and object-store (oarch) destinations based on
|
|
600
604
|
the file's location flag. Sets self.RETSTAT on unresolved failures.
|
|
605
|
+
|
|
606
|
+
Args:
|
|
607
|
+
cpass -- 0 for a single pass; with -AL N, archive_in_passes() calls 1 for the
|
|
608
|
+
copy pass (copies in up to N child processes, no records) and then 2
|
|
609
|
+
for the record pass (see archive_in_passes())
|
|
601
610
|
"""
|
|
602
611
|
tname = 'hfile'
|
|
603
612
|
dsid = self.params['DS']
|
|
@@ -631,18 +640,14 @@ class DsArch(PgArch, PgMeta):
|
|
|
631
640
|
self.params['SZ'] = [0]*self.ALLCNT
|
|
632
641
|
self.OPTS['SZ'][2] |= 2
|
|
633
642
|
if 'MC' not in self.params: self.params['MC'] = [None]*self.ALLCNT
|
|
634
|
-
reorder = errcnt = self.ADDCNT = self.MODCNT =
|
|
643
|
+
reorder = errcnt = self.ADDCNT = self.MODCNT = acnt = ocnt = 0
|
|
635
644
|
perrcnt = self.ALLCNT
|
|
636
645
|
efiles = [1]*self.ALLCNT
|
|
637
|
-
if self.PGSIG['BPROC'] > 1:
|
|
638
|
-
afiles = [None]*self.ALLCNT
|
|
639
|
-
lfiles = [None]*self.ALLCNT
|
|
640
|
-
ofiles = [None]*self.ALLCNT
|
|
641
646
|
override = self.OVERRIDE
|
|
642
647
|
fnames = None
|
|
643
648
|
while True:
|
|
644
649
|
for i in range(bidx, self.ALLCNT):
|
|
645
|
-
if
|
|
650
|
+
if cpass != 1 and i > bidx and ((i-bidx)%20) == 0:
|
|
646
651
|
if self.PGLOG['DSCHECK']:
|
|
647
652
|
self.set_dscheck_dcount(i, chksize, self.PGOPT['extlog'])
|
|
648
653
|
if 'EM' in self.params:
|
|
@@ -694,14 +699,20 @@ class DsArch(PgArch, PgMeta):
|
|
|
694
699
|
self.pglog("{}: Archive Help file from {} ...".format(hfile, locfile), self.WARNLG)
|
|
695
700
|
if harch and locfile == afile: harch = 0
|
|
696
701
|
chksum = self.params['MC'][i]
|
|
702
|
+
gdone = odone = 0
|
|
703
|
+
if cpass == 2 and i in self.CPFILES: # copied in the -AL copy pass; recopy only what failed
|
|
704
|
+
(gdone, odone) = self.check_pass_copies(i, hfile, afile if harch else None, ofile if oarch else None, bucket, lsize)
|
|
705
|
+
if gdone: harch = 0; acnt += 1
|
|
706
|
+
if odone: oarch = 0; ocnt += 1
|
|
707
|
+
if self.PGLOG['DSCHECK'] and (gdone or odone) and not (harch or oarch): chksize += lsize
|
|
697
708
|
if harch and not self.OVERRIDE:
|
|
698
709
|
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE)
|
|
699
710
|
if info:
|
|
700
711
|
if pgrec and chksum and pgrec['checksum'] and pgrec['checksum'] == chksum:
|
|
701
|
-
self.pglog("Help-{}: Same-Checksum ARCHIVED at {}:{}".format(hinfo, info['date_modified'], info['time_modified']), self.PGOPT['emllog'])
|
|
712
|
+
self.pglog("Help-{}: Same-Checksum ARCHIVED at {}:{}".format(hinfo, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['emllog']))
|
|
702
713
|
harch = 0
|
|
703
714
|
elif info['data_size'] == lsize:
|
|
704
|
-
self.pglog("Help-{}: Same-Size ARCHIVED at {}:{}".format(hinfo, info['date_modified'], info['time_modified']), self.PGOPT['wrnlog'])
|
|
715
|
+
self.pglog("Help-{}: Same-Size ARCHIVED at {}:{}".format(hinfo, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['wrnlog']))
|
|
705
716
|
harch = 0
|
|
706
717
|
elif info is not None:
|
|
707
718
|
errcnt += 1
|
|
@@ -712,10 +723,10 @@ class DsArch(PgArch, PgMeta):
|
|
|
712
723
|
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
713
724
|
if info:
|
|
714
725
|
if pgrec and chksum and pgrec['checksum'] and pgrec['checksum'] == chksum:
|
|
715
|
-
self.pglog("Object-{}-{}: Same-Checksum ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), self.PGOPT['emllog'])
|
|
726
|
+
self.pglog("Object-{}-{}: Same-Checksum ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['emllog']))
|
|
716
727
|
oarch = 0
|
|
717
|
-
elif info['data_size'] == lsize:
|
|
718
|
-
self.pglog("Object-{}-{}: Same-Size ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), self.PGOPT['wrnlog'])
|
|
728
|
+
elif not override and info['data_size'] == lsize:
|
|
729
|
+
self.pglog("Object-{}-{}: Same-Size ARCHIVED at {}:{}".format(bucket, ofile, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['wrnlog']))
|
|
719
730
|
oarch = 0
|
|
720
731
|
else:
|
|
721
732
|
replace = 1
|
|
@@ -725,6 +736,10 @@ class DsArch(PgArch, PgMeta):
|
|
|
725
736
|
dflags['O'] = bucket
|
|
726
737
|
continue
|
|
727
738
|
if (harch + oarch) > 0:
|
|
739
|
+
if cpass == 1: # -AL copy pass: copy in a child process; the record pass sets the record
|
|
740
|
+
self.run_copy(i, self.copy_archive_file, afile if harch else None, ofile if oarch else None,
|
|
741
|
+
lfile, bucket, (replace if oarch else 0), self.PGOPT['emerol']|override)
|
|
742
|
+
continue
|
|
728
743
|
if harch:
|
|
729
744
|
if not self.local_copy_local(afile, lfile, self.PGOPT['emerol']|override):
|
|
730
745
|
errcnt += 1
|
|
@@ -740,30 +755,31 @@ class DsArch(PgArch, PgMeta):
|
|
|
740
755
|
continue
|
|
741
756
|
ocnt += 1
|
|
742
757
|
if self.PGLOG['DSCHECK']: chksize += lsize
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
if
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
self.params['LF'][i] = self.params['WF'][i] = None
|
|
762
|
-
continue
|
|
763
|
-
if errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
758
|
+
if cpass == 1: continue # the record pass sets the record, also for a file not copied
|
|
759
|
+
if gdone: harch = 1 # as if copied in this pass, for the file info below
|
|
760
|
+
if odone: oarch = 1
|
|
761
|
+
if not fnames: fnames = self.get_field_keys(tname, None, "G") # get setting fields if not yet
|
|
762
|
+
info = None
|
|
763
|
+
if harch:
|
|
764
|
+
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE)
|
|
765
|
+
elif oarch:
|
|
766
|
+
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
767
|
+
elif pgrec:
|
|
768
|
+
info = self.get_file_origin_info(hfile, pgrec)
|
|
769
|
+
elif locflag == 'O':
|
|
770
|
+
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
771
|
+
hid = self.set_one_helpfile(i, pgrec, hfile, fnames, type, info)
|
|
772
|
+
if not hid:
|
|
773
|
+
self.params['LF'][i] = self.params['WF'][i] = None
|
|
774
|
+
continue
|
|
775
|
+
if cpass == 1 or errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
764
776
|
perrcnt = errcnt
|
|
765
|
-
self.pglog("Rearchive failed {}/{} Help file{} for {}".format(errcnt, self.ALLCNT
|
|
777
|
+
self.pglog("Rearchive failed {}/{} Help file{} for {}".format(errcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
766
778
|
errcnt = self.reset_errmsg(0)
|
|
779
|
+
if cpass == 1: # the record pass checks the copies, retries failed ones and sets the records
|
|
780
|
+
self.wait_copy_children()
|
|
781
|
+
self.reset_errmsg(0) # the record pass finds and counts any error again
|
|
782
|
+
return
|
|
767
783
|
if errcnt:
|
|
768
784
|
if 'CL' in self.params: del self.params['CL']
|
|
769
785
|
self.RETSTAT = self.reset_errmsg(errcnt)
|
|
@@ -771,13 +787,6 @@ class DsArch(PgArch, PgMeta):
|
|
|
771
787
|
if efiles[i]: self.params['HF'][i] = ''
|
|
772
788
|
if self.PGLOG['DSCHECK']:
|
|
773
789
|
self.check_storage_dflags(dflags, self.PGLOG['DSCHECK'], self.PGOPT['emerol'])
|
|
774
|
-
if bgcnt:
|
|
775
|
-
self.check_background(None, 0, self.LOGWRN, 1)
|
|
776
|
-
for i in range(self.ALLCNT):
|
|
777
|
-
if afiles[i]:
|
|
778
|
-
self.validate_gladearch(afiles[i], lfiles[i], i)
|
|
779
|
-
if ofiles[i]:
|
|
780
|
-
self.validate_objectarch(ofiles[i], lfiles[i], bucket, i)
|
|
781
790
|
if acnt > 0:
|
|
782
791
|
self.pglog("{} of {} Help file{} archived for {}".format(acnt, self.ALLCNT, s, self.params['DS']), self.PGOPT['emllog'])
|
|
783
792
|
if ocnt > 0:
|
|
@@ -791,7 +800,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
791
800
|
self.reset_rdadb_version(dsid)
|
|
792
801
|
if 'EM' in self.params: self.PGLOG['PRGMSG'] = ""
|
|
793
802
|
|
|
794
|
-
def archive_saved_files(self):
|
|
803
|
+
def archive_saved_files(self, cpass=0):
|
|
795
804
|
"""
|
|
796
805
|
Archive local files as dataset saved files on GLADE.
|
|
797
806
|
|
|
@@ -799,6 +808,11 @@ class DsArch(PgArch, PgMeta):
|
|
|
799
808
|
type constraints, handles version control checks, and registers or updates
|
|
800
809
|
the saved file record in RDADB via set_one_savedfile(). Retries on
|
|
801
810
|
transient copy failures. Sets self.RETSTAT on unresolved failures.
|
|
811
|
+
|
|
812
|
+
Args:
|
|
813
|
+
cpass -- 0 for a single pass; with -AL N, archive_in_passes() calls 1 for the
|
|
814
|
+
copy pass (copies in up to N child processes, no records) and then 2
|
|
815
|
+
for the record pass (see archive_in_passes())
|
|
802
816
|
"""
|
|
803
817
|
tname = 'sfile'
|
|
804
818
|
dftloc = 'G'
|
|
@@ -808,7 +822,7 @@ class DsArch(PgArch, PgMeta):
|
|
|
808
822
|
bidx = chksize = 0
|
|
809
823
|
dflags = {}
|
|
810
824
|
self.pglog("Archive {} Saved file{} of {} ...".format(self.ALLCNT, s, dsid), self.WARNLG)
|
|
811
|
-
if 'ZD' in self.params or 'UZ' in self.params:
|
|
825
|
+
if cpass != 2 and ('ZD' in self.params or 'UZ' in self.params):
|
|
812
826
|
self.compress_localfile_list(self.PGOPT['CACT'], self.ALLCNT)
|
|
813
827
|
if 'QF' in self.params: self.params['QF'] = self.get_bid_numbers(self.params['QF'])
|
|
814
828
|
self.validate_multiple_values(tname, self.ALLCNT)
|
|
@@ -832,18 +846,15 @@ class DsArch(PgArch, PgMeta):
|
|
|
832
846
|
self.params['SZ'] = [0]*self.ALLCNT
|
|
833
847
|
self.OPTS['SZ'][2] |= 2
|
|
834
848
|
if 'MC' not in self.params: self.params['MC'] = [None]*self.ALLCNT
|
|
835
|
-
reorder = errcnt = self.ADDCNT = self.MODCNT =
|
|
849
|
+
reorder = errcnt = self.ADDCNT = self.MODCNT = acnt = 0
|
|
836
850
|
perrcnt = self.ALLCNT
|
|
837
851
|
efiles = [1]*self.ALLCNT
|
|
838
|
-
if self.PGSIG['BPROC'] > 1:
|
|
839
|
-
afiles = [None]*self.ALLCNT
|
|
840
|
-
lfiles = [None]*self.ALLCNT
|
|
841
852
|
fnames = None
|
|
842
853
|
override = self.OVERRIDE
|
|
843
854
|
if not override and 'GF' in self.params: override = self.OVRIDE
|
|
844
855
|
while True:
|
|
845
856
|
for i in range(bidx, self.ALLCNT):
|
|
846
|
-
if
|
|
857
|
+
if cpass != 1 and i > bidx and ((i-bidx)%20) == 0:
|
|
847
858
|
if self.PGLOG['DSCHECK']:
|
|
848
859
|
self.set_dscheck_dcount(i, chksize, self.PGOPT['extlog'])
|
|
849
860
|
if 'EM' in self.params:
|
|
@@ -895,14 +906,20 @@ class DsArch(PgArch, PgMeta):
|
|
|
895
906
|
self.pglog("{}: Archive Saved file from {} ...".format(sinfo, locfile), self.WARNLG)
|
|
896
907
|
vsnctl = 1 if pgrec and pgrec['vindex'] and pgrec['data_size'] else 0
|
|
897
908
|
chksum = self.params['MC'][i]
|
|
909
|
+
if cpass == 2 and i in self.CPFILES: # copied in the -AL copy pass; recopy only if it failed
|
|
910
|
+
(gdone, odone) = self.check_pass_copies(i, sfile, afile if sarch else None, None, None, lsize)
|
|
911
|
+
if gdone:
|
|
912
|
+
sarch = 0
|
|
913
|
+
acnt += 1
|
|
914
|
+
if self.PGLOG['DSCHECK']: chksize += lsize
|
|
898
915
|
if sarch and (vsnctl or not override):
|
|
899
916
|
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE)
|
|
900
917
|
if info:
|
|
901
918
|
if pgrec and chksum and pgrec['checksum'] and pgrec['checksum'] == chksum:
|
|
902
|
-
self.pglog("Saved-{}: Same-Checksum ARCHIVED at {}:{}".format(sinfo, info['date_modified'], info['time_modified']), self.PGOPT['emllog'])
|
|
919
|
+
self.pglog("Saved-{}: Same-Checksum ARCHIVED at {}:{}".format(sinfo, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['emllog']))
|
|
903
920
|
sarch = 0
|
|
904
|
-
elif info['data_size'] == lsize:
|
|
905
|
-
self.pglog("Saved-{}: Same-Size ARCHIVED at {}:{}".format(sinfo, info['date_modified'], info['time_modified']), self.PGOPT['wrnlog'])
|
|
921
|
+
elif not override and info['data_size'] == lsize:
|
|
922
|
+
self.pglog("Saved-{}: Same-Size ARCHIVED at {}:{}".format(sinfo, info['date_modified'], info['time_modified']), (0 if cpass == 1 else self.PGOPT['wrnlog']))
|
|
906
923
|
sarch = 0
|
|
907
924
|
elif vsnctl and not override:
|
|
908
925
|
self.pglog("Saved-{}: Cannot rearchive version controlled file".format(sinfo), self.PGOPT['extlog'])
|
|
@@ -914,29 +931,32 @@ class DsArch(PgArch, PgMeta):
|
|
|
914
931
|
dflags['G'] = self.PGLOG['DECSHOME']
|
|
915
932
|
continue
|
|
916
933
|
if sarch:
|
|
934
|
+
if cpass == 1: # -AL copy pass: copy in a child process; the record pass sets the record
|
|
935
|
+
self.run_copy(i, self.copy_archive_file, afile, None, lfile, None, 0, self.PGOPT['emerol']|override)
|
|
936
|
+
continue
|
|
917
937
|
if not self.local_copy_local(afile, lfile, self.PGOPT['emerol']|override):
|
|
918
938
|
errcnt += 1
|
|
919
939
|
efiles[i] = 1
|
|
920
940
|
continue
|
|
921
941
|
acnt += 1
|
|
922
942
|
if self.PGLOG['DSCHECK']: chksize += lsize
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
if not sid:
|
|
934
|
-
self.params['LF'][i] = self.params['SF'][i] = None
|
|
935
|
-
continue
|
|
936
|
-
if errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
943
|
+
if cpass == 1: continue # the record pass sets the record, also for a file not copied
|
|
944
|
+
if not fnames: fnames = self.get_field_keys(tname, None, "G") # get setting fields if not yet
|
|
945
|
+
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE) # also when already in place
|
|
946
|
+
if not info and pgrec:
|
|
947
|
+
info = self.get_file_origin_info(sfile, pgrec)
|
|
948
|
+
sid = self.set_one_savedfile(i, pgrec, sfile, fnames, type, info)
|
|
949
|
+
if not sid:
|
|
950
|
+
self.params['LF'][i] = self.params['SF'][i] = None
|
|
951
|
+
continue
|
|
952
|
+
if cpass == 1 or errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
937
953
|
perrcnt = errcnt
|
|
938
954
|
self.pglog("Rearchive failed {}/{} Saved file{} for {}!".format(errcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
939
955
|
errcnt = self.reset_errmsg(0)
|
|
956
|
+
if cpass == 1: # the record pass checks the copies, retries failed ones and sets the records
|
|
957
|
+
self.wait_copy_children()
|
|
958
|
+
self.reset_errmsg(0) # the record pass finds and counts any error again
|
|
959
|
+
return
|
|
940
960
|
if errcnt:
|
|
941
961
|
if 'CL' in self.params: del self.params['CL']
|
|
942
962
|
self.RETSTAT = self.reset_errmsg(errcnt)
|
|
@@ -944,10 +964,6 @@ class DsArch(PgArch, PgMeta):
|
|
|
944
964
|
if efiles[i]: self.params['SF'][i] = ''
|
|
945
965
|
if self.PGLOG['DSCHECK']:
|
|
946
966
|
self.check_storage_dflags(dflags, self.PGLOG['DSCHECK'], self.PGOPT['emerol'])
|
|
947
|
-
if bgcnt:
|
|
948
|
-
self.check_background(None, 0, self.LOGWRN, 1)
|
|
949
|
-
for i in range(self.ALLCNT):
|
|
950
|
-
if afiles[i]: self.validate_gladearch(afiles[i], lfiles[i], i)
|
|
951
967
|
if acnt > 0:
|
|
952
968
|
self.pglog("{} of {} Saved file{} archived for {}".format(acnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
953
969
|
if self.PGLOG['DSCHECK']:
|
|
@@ -981,18 +997,14 @@ class DsArch(PgArch, PgMeta):
|
|
|
981
997
|
if bidx == self.ALLCNT: return
|
|
982
998
|
self.set_rearchive_filenumber(dsid, bidx, self.ALLCNT, 4)
|
|
983
999
|
chksize = self.PGLOG['DSCHECK']['size']
|
|
984
|
-
reorder = errcnt = metatotal = metacnt = self.MODCNT =
|
|
1000
|
+
reorder = errcnt = metatotal = metacnt = self.MODCNT = acnt = ocnt = 0
|
|
985
1001
|
perrcnt = self.ALLCNT
|
|
986
1002
|
efiles = [1]*self.ALLCNT
|
|
987
1003
|
self.params['LC'] = ['B']*self.ALLCNT
|
|
988
|
-
if self.PGSIG['BPROC'] > 1:
|
|
989
|
-
afiles = [None]*self.ALLCNT
|
|
990
|
-
ofiles = [None]*self.ALLCNT
|
|
991
|
-
warchs = [None]*self.ALLCNT
|
|
992
1004
|
fnames = None
|
|
993
1005
|
while True:
|
|
994
1006
|
for i in range(bidx, self.ALLCNT):
|
|
995
|
-
if
|
|
1007
|
+
if i > bidx and ((i-bidx)%20) == 0:
|
|
996
1008
|
if self.PGLOG['DSCHECK']:
|
|
997
1009
|
self.set_dscheck_dcount(i, chksize, self.PGOPT['extlog'])
|
|
998
1010
|
if metacnt >= self.PGOPT['RSMAX']:
|
|
@@ -1058,29 +1070,23 @@ class DsArch(PgArch, PgMeta):
|
|
|
1058
1070
|
self.params['LC'][i] = 'O'
|
|
1059
1071
|
self.delete_local_file(afile, self.PGOPT['extlog'])
|
|
1060
1072
|
ocnt += 1
|
|
1061
|
-
if self.PGSIG['BPROC'] > 1:
|
|
1062
|
-
afiles[i] = afile
|
|
1063
|
-
ofiles[i] = ofile
|
|
1064
|
-
warchs[i] = warch
|
|
1065
|
-
bgcnt += 1
|
|
1066
1073
|
if self.PGLOG['DSCHECK']: chksize += pgrec['data_size']
|
|
1067
|
-
if self.
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
if '
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
if
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
metacnt += self.record_meta_summary('W', dsid, gindex, pgrec['gindex'])
|
|
1074
|
+
if not fnames: fnames = self.get_field_keys(tname, None, "G") # get setting fields if not yet
|
|
1075
|
+
info = self.get_file_origin_info(wfile, pgrec)
|
|
1076
|
+
wid = self.set_one_webfile(i, pgrec, wfile, fnames, type, info)
|
|
1077
|
+
if not wid:
|
|
1078
|
+
self.params['WF'][i] = None
|
|
1079
|
+
continue
|
|
1080
|
+
if 'GX' in self.params and self.PGOPT['GXTYP'].find(type) > -1:
|
|
1081
|
+
metacnt += self.record_meta_gather('W', dsid, wfile, self.params['DF'][i] if 'DF' in self.params else pgrec['data_format'])
|
|
1082
|
+
self.cache_meta_tindex(dsid, wid, 'W')
|
|
1083
|
+
if pgrec['meta_link'] and pgrec['meta_link'] != 'N':
|
|
1084
|
+
if 'DX' in self.params or self.PGOPT['GXTYP'].find(type) < 0 and self.PGOPT['GXTYP'].find(pgrec['type']) > -1:
|
|
1085
|
+
metacnt += self.record_meta_delete('W', dsid, wfile)
|
|
1086
|
+
elif 'GI' in self.params:
|
|
1087
|
+
gindex = self.params['GI'][i]
|
|
1088
|
+
if gindex != pgrec['gindex'] and (gindex or (self.OPTS['GI'][2]&2) == 0):
|
|
1089
|
+
metacnt += self.record_meta_summary('W', dsid, gindex, pgrec['gindex'])
|
|
1084
1090
|
if errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
1085
1091
|
perrcnt = errcnt
|
|
1086
1092
|
self.pglog("Recopy failed {}/{} Web file{} for {}".format(errcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
@@ -1091,13 +1097,6 @@ class DsArch(PgArch, PgMeta):
|
|
|
1091
1097
|
if efiles[i]: self.params['WF'][i] = ''
|
|
1092
1098
|
if self.PGLOG['DSCHECK']:
|
|
1093
1099
|
self.check_storage_dflags(dflags, self.PGLOG['DSCHECK'], self.PGOPT['emerol'])
|
|
1094
|
-
if bgcnt:
|
|
1095
|
-
self.check_background(None, 0, self.LOGWRN, 1)
|
|
1096
|
-
for i in range(self.ALLCNT):
|
|
1097
|
-
if warchs[i]:
|
|
1098
|
-
self.validate_gladearch(afiles[i], "{}-{}".format(bucket, ofiles[i]), i)
|
|
1099
|
-
elif ofiles[i]:
|
|
1100
|
-
self.validate_objectarch(ofiles[i], afiles[i], bucket, i)
|
|
1101
1100
|
astr = 'Moved' if aname == 'Move' else 'Copied'
|
|
1102
1101
|
if acnt > 0: self.pglog("{} of {} Web file{} Cross {} for {}".format(acnt, self.ALLCNT, s, astr, dsid), self.PGOPT['emllog'])
|
|
1103
1102
|
if ocnt > 0: self.pglog("{} of {} Object file{} Cross {} for {}".format(ocnt, self.ALLCNT, s, astr, dsid), self.PGOPT['emllog'])
|
|
@@ -1135,18 +1134,14 @@ class DsArch(PgArch, PgMeta):
|
|
|
1135
1134
|
if bidx == self.ALLCNT: return
|
|
1136
1135
|
self.set_rearchive_filenumber(dsid, bidx, self.ALLCNT, 4)
|
|
1137
1136
|
chksize = self.PGLOG['DSCHECK']['size']
|
|
1138
|
-
reorder = errcnt = self.MODCNT =
|
|
1137
|
+
reorder = errcnt = self.MODCNT = acnt = ocnt = 0
|
|
1139
1138
|
perrcnt = self.ALLCNT
|
|
1140
1139
|
efiles = [1]*self.ALLCNT
|
|
1141
1140
|
self.params['LC'] = ['B']*self.ALLCNT
|
|
1142
|
-
if self.PGSIG['BPROC'] > 1:
|
|
1143
|
-
afiles = [None]*self.ALLCNT
|
|
1144
|
-
ofiles = [None]*self.ALLCNT
|
|
1145
|
-
harchs = [None]*self.ALLCNT
|
|
1146
1141
|
fnames = None
|
|
1147
1142
|
while True:
|
|
1148
1143
|
for i in range(bidx, self.ALLCNT):
|
|
1149
|
-
if
|
|
1144
|
+
if i > bidx and ((i-bidx)%20) == 0:
|
|
1150
1145
|
if self.PGLOG['DSCHECK']:
|
|
1151
1146
|
self.set_dscheck_dcount(i, chksize, self.PGOPT['extlog'])
|
|
1152
1147
|
if 'EM' in self.params:
|
|
@@ -1222,19 +1217,13 @@ class DsArch(PgArch, PgMeta):
|
|
|
1222
1217
|
self.params['LC'][i] = 'O'
|
|
1223
1218
|
self.delete_local_file(afile, self.PGOPT['extlog'])
|
|
1224
1219
|
ocnt += 1
|
|
1225
|
-
if self.PGSIG['BPROC'] > 1:
|
|
1226
|
-
afiles[i] = afile
|
|
1227
|
-
ofiles[i] = ofile
|
|
1228
|
-
harchs[i] = harch
|
|
1229
|
-
bgcnt += 1
|
|
1230
1220
|
if self.PGLOG['DSCHECK']: chksize += pgrec['data_size']
|
|
1231
|
-
if self.
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
continue
|
|
1221
|
+
if not fnames: fnames = self.get_field_keys(tname, None, "G") # get setting fields if not yet
|
|
1222
|
+
info = self.get_file_origin_info(hfile, pgrec)
|
|
1223
|
+
hid = self.set_one_helpfile(i, pgrec, hfile, fnames, type, info)
|
|
1224
|
+
if not hid:
|
|
1225
|
+
self.params['HF'][i] = None
|
|
1226
|
+
continue
|
|
1238
1227
|
if errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
1239
1228
|
perrcnt = errcnt
|
|
1240
1229
|
self.pglog("Re{} {} Help file{} for {}".format(aname, errcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
@@ -1245,13 +1234,6 @@ class DsArch(PgArch, PgMeta):
|
|
|
1245
1234
|
if efiles[i]: self.params['SF'][i] = ''
|
|
1246
1235
|
if self.PGLOG['DSCHECK']:
|
|
1247
1236
|
self.check_storage_dflags(dflags, self.PGLOG['DSCHECK'], self.PGOPT['emerol'])
|
|
1248
|
-
if bgcnt:
|
|
1249
|
-
self.check_background(None, 0, self.LOGWRN, 1)
|
|
1250
|
-
for i in range(self.ALLCNT):
|
|
1251
|
-
if harchs[i]:
|
|
1252
|
-
self.validate_gladearch(afiles[i], "{}-{}".format(bucket, ofiles[i]), i)
|
|
1253
|
-
elif ofiles[i]:
|
|
1254
|
-
self.validate_objectarch(ofiles[i], afiles[i], bucket, i)
|
|
1255
1237
|
astr = 'Moved' if aname == 'Move' else 'Copied'
|
|
1256
1238
|
if acnt > 0: self.pglog("{} of {} Help file{} Cross {} for {}".format(acnt, self.ALLCNT, s, astr, dsid), self.PGOPT['emllog'])
|
|
1257
1239
|
if ocnt > 0: self.pglog("{} of {} Object file{} Cross {} for {}".format(ocnt, self.ALLCNT, s, astr, dsid), self.PGOPT['emllog'])
|
|
@@ -1864,16 +1846,13 @@ class DsArch(PgArch, PgMeta):
|
|
|
1864
1846
|
if bidx == self.ALLCNT: return
|
|
1865
1847
|
self.set_rearchive_filenumber(dsid, bidx, self.ALLCNT, 4)
|
|
1866
1848
|
chksize = self.PGLOG['DSCHECK']['size']
|
|
1867
|
-
reorder = errcnt = self.MODCNT =
|
|
1849
|
+
reorder = errcnt = self.MODCNT = bcnt = dcnt = 0
|
|
1868
1850
|
perrcnt = self.ALLCNT
|
|
1869
1851
|
efiles = [1]*self.ALLCNT
|
|
1870
|
-
if self.PGSIG['BPROC'] > 1:
|
|
1871
|
-
qfiles = [None]*self.ALLCNT
|
|
1872
|
-
barchs = [None]*self.ALLCNT
|
|
1873
1852
|
fnames = None
|
|
1874
1853
|
while True:
|
|
1875
1854
|
for i in range(bidx, self.ALLCNT):
|
|
1876
|
-
if
|
|
1855
|
+
if i > bidx and ((i-bidx)%20) == 0:
|
|
1877
1856
|
if self.PGLOG['DSCHECK']:
|
|
1878
1857
|
self.set_dscheck_dcount(i, chksize, self.PGOPT['extlog'])
|
|
1879
1858
|
if 'EM' in self.params:
|
|
@@ -1930,17 +1909,12 @@ class DsArch(PgArch, PgMeta):
|
|
|
1930
1909
|
dflags['D'] = dpoint
|
|
1931
1910
|
continue
|
|
1932
1911
|
dcnt += 1
|
|
1933
|
-
if self.PGSIG['BPROC'] > 1:
|
|
1934
|
-
qfiles[i] = qfile
|
|
1935
|
-
barchs[i] = barch
|
|
1936
|
-
bgcnt += 1
|
|
1937
1912
|
if self.PGLOG['DSCHECK']: chksize += pgrec['data_size']
|
|
1938
|
-
if self.
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
continue
|
|
1913
|
+
if not fnames: fnames = self.get_field_keys(tname) # get setting fields if not yet
|
|
1914
|
+
bid = self.set_one_backfile(i, pgrec, bfile, fnames, qtype)
|
|
1915
|
+
if not bid:
|
|
1916
|
+
self.params['QF'][i] = None
|
|
1917
|
+
continue
|
|
1944
1918
|
if errcnt == 0 or errcnt >= perrcnt or self.PGLOG['DSCHECK']: break
|
|
1945
1919
|
perrcnt = errcnt
|
|
1946
1920
|
self.pglog("Recopy {} Quasar file{} for {}".format(errcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
@@ -1951,13 +1925,6 @@ class DsArch(PgArch, PgMeta):
|
|
|
1951
1925
|
if efiles[i]: self.params['QF'][i] = ''
|
|
1952
1926
|
if self.PGLOG['DSCHECK']:
|
|
1953
1927
|
self.check_storage_dflags(dflags, self.PGLOG['DSCHECK'], self.PGOPT['emerol'])
|
|
1954
|
-
if bgcnt:
|
|
1955
|
-
self.check_background(None, 0, self.LOGWRN, 1)
|
|
1956
|
-
for i in range(self.ALLCNT):
|
|
1957
|
-
if barchs[i]:
|
|
1958
|
-
self.validate_backarch(qfiles[i], "{}-{}".format(dpoint, qfiles[i]), bpoint, i)
|
|
1959
|
-
elif qfiles[i]:
|
|
1960
|
-
self.validate_backarch(qfiles[i], "{}-{}".format(bpoint, qfiles[i]), dpoint, i)
|
|
1961
1928
|
if bcnt > 0: self.pglog("{} of {} Backup file{} Cross Copied for {}".format(bcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
1962
1929
|
if dcnt > 0: self.pglog("{} of {} Drdata file{} Cross Copied for {}".format(dcnt, self.ALLCNT, s, dsid), self.PGOPT['emllog'])
|
|
1963
1930
|
if self.PGLOG['DSCHECK']:
|
|
@@ -1968,57 +1935,136 @@ class DsArch(PgArch, PgMeta):
|
|
|
1968
1935
|
self.reset_rdadb_version(dsid)
|
|
1969
1936
|
if 'EM' in self.params: self.PGLOG['PRGMSG'] = ""
|
|
1970
1937
|
|
|
1971
|
-
def
|
|
1938
|
+
def archive_in_passes(self, archfunc):
|
|
1972
1939
|
"""
|
|
1973
|
-
|
|
1940
|
+
Run an archive action (archive_web/help/saved_files) once, or in two passes for -AL.
|
|
1974
1941
|
|
|
1975
|
-
|
|
1976
|
-
|
|
1942
|
+
With -AL N (N > 1, so PGSIG['MPROC'] > 1) the action runs twice:
|
|
1943
|
+
1. copy pass -- the usual checks, then each file that needs a copy is copied
|
|
1944
|
+
in one of up to N child processes (run_copy()); no records are set;
|
|
1945
|
+
2. record pass -- the usual single process loop; a file the copy pass copied
|
|
1946
|
+
is checked (check_pass_copies()) instead of copied again, and copied again
|
|
1947
|
+
only if its child copy failed; records, dscheck progress and metadata are
|
|
1948
|
+
all set here exactly as without -AL.
|
|
1977
1949
|
|
|
1978
1950
|
Args:
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
elif self.OPTS['SZ'][2]&2 and self.params['SZ'] and info['data_size'] != self.params['SZ'][i]:
|
|
1987
|
-
self.pglog("Wrong Sizes: ({}){}/({}){}".format(file, info['data_size'], ofile, self.params['SZ'][i]), self.LGEREX)
|
|
1988
|
-
else:
|
|
1989
|
-
self.set_local_mode(file, 1, self.PGLOG['FILEMODE'], info['mode'], info['logname'], self.PGOPT['errlog'])
|
|
1951
|
+
archfunc -- bound archive method taking the pass number (0, 1 or 2)
|
|
1952
|
+
"""
|
|
1953
|
+
if self.PGSIG['MPROC'] < 2: return archfunc()
|
|
1954
|
+
self.CPFILES = {}
|
|
1955
|
+
archfunc(1)
|
|
1956
|
+
archfunc(2)
|
|
1957
|
+
self.CPFILES = {}
|
|
1990
1958
|
|
|
1991
|
-
def
|
|
1959
|
+
def run_copy(self, i, copyfunc, *args):
|
|
1992
1960
|
"""
|
|
1993
|
-
|
|
1961
|
+
Run the copy of file *i* in a child process for the -AL copy pass.
|
|
1962
|
+
|
|
1963
|
+
Waits for a free child slot (up to PGSIG['MPROC'] running), forks, and runs
|
|
1964
|
+
copyfunc(*args) in the child, which then leaves with os._exit(): it skips the
|
|
1965
|
+
parent's exit handling, so it cannot close the parent's database connection,
|
|
1966
|
+
send email or end the run; NOQUIT also keeps an EXITLG error in the copy from
|
|
1967
|
+
exiting early. The parent records the child's process name in
|
|
1968
|
+
self.CPFILES[i] (its exit code then shows up in self.CEXITS) and returns at
|
|
1969
|
+
once. If no child can be started, the copy runs in the parent and
|
|
1970
|
+
self.CPFILES[i] is 1 or 0 for its result.
|
|
1994
1971
|
|
|
1995
1972
|
Args:
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
1973
|
+
i -- file index
|
|
1974
|
+
copyfunc -- function doing the copy; returns true on success
|
|
1975
|
+
args -- arguments of copyfunc
|
|
1976
|
+
"""
|
|
1977
|
+
for fh in (sys.stdout, sys.stderr): # nothing buffered is written twice by the child
|
|
1978
|
+
try:
|
|
1979
|
+
fh.flush()
|
|
1980
|
+
except Exception:
|
|
1981
|
+
pass
|
|
1982
|
+
pname = "dsarch_copy_{}".format(i)
|
|
1983
|
+
self.CEXITS.pop(pname, None)
|
|
1984
|
+
stat = self.start_child(pname, self.LOGWRN, 1)
|
|
1985
|
+
if stat <= 0: # cannot fork, copy in the parent
|
|
1986
|
+
self.CPFILES[i] = 1 if copyfunc(*args) else 0
|
|
1987
|
+
return self.CPFILES[i]
|
|
1988
|
+
if self.PGSIG['PPID'] > 1: # in the child process
|
|
1989
|
+
self.PGLOG['NOQUIT'] = 1
|
|
1990
|
+
ret = 0
|
|
1991
|
+
try:
|
|
1992
|
+
ret = copyfunc(*args)
|
|
1993
|
+
except BaseException as e:
|
|
1994
|
+
self.pglog("Copy {}: {}".format(i, str(e)), self.LOGERR)
|
|
1995
|
+
for fh in (sys.stdout, sys.stderr):
|
|
1996
|
+
try:
|
|
1997
|
+
fh.flush()
|
|
1998
|
+
except Exception:
|
|
1999
|
+
pass
|
|
2000
|
+
os._exit(0 if ret else 1)
|
|
2001
|
+
self.CPFILES[i] = pname # the child's exit code shows up in self.CEXITS[pname]
|
|
2002
|
+
return 1
|
|
2003
|
+
|
|
2004
|
+
def wait_copy_children(self):
|
|
2005
|
+
"""Wait until all child processes of the -AL copy pass are done."""
|
|
2006
|
+
if self.PGSIG['MPROC'] > 1: self.check_child(None, 0, self.LOGWRN, 1)
|
|
2007
|
+
|
|
2008
|
+
def copy_archive_file(self, afile, ofile, lfile, bucket, replace, logact):
|
|
2009
|
+
"""
|
|
2010
|
+
Copy one local file to GLADE and/or the object store; run in a copy pass child.
|
|
2011
|
+
|
|
2012
|
+
Args:
|
|
2013
|
+
afile -- absolute GLADE target path, or None for no GLADE copy
|
|
2014
|
+
ofile -- object store key, or None for no object copy
|
|
2015
|
+
lfile -- local source file
|
|
2016
|
+
bucket -- object store bucket
|
|
2017
|
+
replace -- true to delete the existing object first
|
|
2018
|
+
logact -- logging flags for the copies
|
|
2019
|
+
|
|
2020
|
+
Returns:
|
|
2021
|
+
1 if all copies succeeded, 0 otherwise
|
|
2000
2022
|
"""
|
|
2001
|
-
|
|
2002
|
-
if
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2023
|
+
if afile and not self.local_copy_local(afile, lfile, logact): return 0
|
|
2024
|
+
if ofile:
|
|
2025
|
+
if replace: self.delete_object_file(ofile, bucket)
|
|
2026
|
+
if not self.local_copy_object(ofile, lfile, bucket, None, logact): return 0
|
|
2027
|
+
return 1
|
|
2006
2028
|
|
|
2007
|
-
def
|
|
2029
|
+
def check_pass_copies(self, i, fname, afile, ofile, bucket, lsize):
|
|
2008
2030
|
"""
|
|
2009
|
-
|
|
2031
|
+
Check the targets the -AL copy pass copied a file to, for the record pass.
|
|
2032
|
+
|
|
2033
|
+
A copy whose child exited with an error counts as failed even when the
|
|
2034
|
+
target holds an older file of the same size (as with -OE); when the exit
|
|
2035
|
+
code is unknown, a target of size *lsize* counts as copied.
|
|
2010
2036
|
|
|
2011
2037
|
Args:
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2038
|
+
i -- file index, the key of self.CPFILES
|
|
2039
|
+
fname -- archived file name, for the message
|
|
2040
|
+
afile -- GLADE target path the copy pass copied to, or None
|
|
2041
|
+
ofile -- object store key the copy pass copied to, or None
|
|
2042
|
+
bucket -- object store bucket
|
|
2043
|
+
lsize -- size of the local source file
|
|
2044
|
+
|
|
2045
|
+
Returns:
|
|
2046
|
+
(gdone, odone) -- 1 for each target that holds the file with size *lsize*;
|
|
2047
|
+
a 0 for a target given means its copy failed and is to be copied again
|
|
2048
|
+
"""
|
|
2049
|
+
gdone = odone = 0
|
|
2050
|
+
cstat = self.CPFILES.get(i)
|
|
2051
|
+
if isinstance(cstat, str): # copied in a child: failed if it exited with an error
|
|
2052
|
+
ecode = self.CEXITS.get(cstat)
|
|
2053
|
+
failed = ecode is not None and ecode != 0
|
|
2054
|
+
else: # copied in the parent: 1 or 0
|
|
2055
|
+
failed = cstat == 0
|
|
2056
|
+
if failed:
|
|
2057
|
+
self.pglog("{}: copy in child process failed, copy again".format(fname), self.PGOPT['wrnlog'])
|
|
2058
|
+
return (0, 0)
|
|
2059
|
+
if afile:
|
|
2060
|
+
info = self.check_local_file(afile, 1, self.PGOPT['emerol']|self.PFSIZE)
|
|
2061
|
+
if info and info['data_size'] == lsize: gdone = 1
|
|
2062
|
+
if ofile:
|
|
2063
|
+
info = self.check_object_file(ofile, bucket, 1, self.PGOPT['emerol'])
|
|
2064
|
+
if info and info['data_size'] == lsize: odone = 1
|
|
2065
|
+
if afile and not gdone or ofile and not odone:
|
|
2066
|
+
self.pglog("{}: copy in child process failed, copy again".format(fname), self.PGOPT['wrnlog'])
|
|
2067
|
+
return (gdone, odone)
|
|
2022
2068
|
|
|
2023
2069
|
def get_dataset_info(self):
|
|
2024
2070
|
"""
|
|
@@ -1249,7 +1249,8 @@ IMMA_2.4_2007.tar<:>37<:>IMMA<:>Z.TAR<:>D<:>656820224<:>
|
|
|
1249
1249
|
-(NE|NoEmail) - suppresses email notification on failure
|
|
1250
1250
|
-(NT|NoTrim) - skips trimming of spaces and comments from input
|
|
1251
1251
|
values, speeding up input file processing
|
|
1252
|
-
-(OE|OverrideExist) - overwrites existing Saved files
|
|
1252
|
+
-(OE|OverrideExist) - overwrites existing Saved files, even ones of the
|
|
1253
|
+
same size
|
|
1253
1254
|
-(RO|ResetOrder) - resets display order indices to match the order
|
|
1254
1255
|
files are given per -SF. Alternatively, use -ON
|
|
1255
1256
|
(-OrderNames) to reorder all files in the dataset
|
|
@@ -1347,7 +1348,8 @@ IMMA_2.4_2007.tar<:>37<:>IMMA<:>Z.TAR<:>D<:>656820224<:>
|
|
|
1347
1348
|
-(NE|NoEmail) - suppresses email notification on failure
|
|
1348
1349
|
-(NT|NoTrim) - skips trimming of spaces and comments from input
|
|
1349
1350
|
values, speeding up input file processing
|
|
1350
|
-
-(OE|OverrideExist) - overwrites existing Web files
|
|
1351
|
+
-(OE|OverrideExist) - overwrites existing Web files, even ones of the
|
|
1352
|
+
same size
|
|
1351
1353
|
-(RO|ResetOrder) - resets display order indices to match the order
|
|
1352
1354
|
files are given per -WF. Alternatively, use -ON
|
|
1353
1355
|
(-OrderNames) to reorder all files in the dataset
|
|
@@ -1438,7 +1440,8 @@ IMMA_2.4_2007.tar<:>37<:>IMMA<:>Z.TAR<:>D<:>656820224<:>
|
|
|
1438
1440
|
-(NE|NoEmail) - suppresses email notification on failure
|
|
1439
1441
|
-(NT|NoTrim) - skips trimming of spaces and comments from input
|
|
1440
1442
|
values, speeding up input file processing
|
|
1441
|
-
-(OE|OverrideExist) - overwrites existing Help files
|
|
1443
|
+
-(OE|OverrideExist) - overwrites existing Help files, even ones of the
|
|
1444
|
+
same size
|
|
1442
1445
|
-(RO|ResetOrder) - resets display order indices to match the order
|
|
1443
1446
|
files are given per -HF. Alternatively, use -ON
|
|
1444
1447
|
(-OrderNames) to reorder all files in the dataset
|
|
@@ -1988,9 +1991,16 @@ They come in two forms:
|
|
|
1988
1991
|
A single-value Info option accepts exactly one value. Providing no
|
|
1989
1992
|
value or more than one causes an error.
|
|
1990
1993
|
|
|
1991
|
-
-AL or -AsyncLimit (Alias: -AsynchronousLimit),
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
+
-AL or -AsyncLimit (Alias: -AsynchronousLimit), the number of
|
|
1995
|
+
processes that run at the same time. For -AW, -AH and -AS (not with
|
|
1996
|
+
-XC/-XM), up to this many child processes copy the files in a first
|
|
1997
|
+
pass; a second pass then checks each copy, copies again any that
|
|
1998
|
+
failed, and sets the file records as usual. It also caps the
|
|
1999
|
+
'gatherxml' and 'dcm' calls run in the background. Cross copies
|
|
2000
|
+
(-XC/-XM) and -AQ run one file at a time. Works with -BP (-d) too:
|
|
2001
|
+
the PBS batch job then gets one cpu and 1gb of memory per process
|
|
2002
|
+
(select=1:ncpus=N:mem=Ngb) unless -QS already requests select,
|
|
2003
|
+
ncpus or mem.
|
|
1994
2004
|
|
|
1995
2005
|
-AO or -ActOption (Alias: -ActionOption), the token that marks
|
|
1996
2006
|
Action and Mode options in input files. Defaults to '<!>'. Change
|
|
@@ -2063,7 +2073,9 @@ They come in two forms:
|
|
|
2063
2073
|
|
|
2064
2074
|
-QS or -QsubOptions (Alias: -PBSOptions), passes options to qsub
|
|
2065
2075
|
when running 'dsarch' as a PBS batch job. Quote the value on the
|
|
2066
|
-
command line, e.g., -QS '-l walltime=12:00:00'.
|
|
2076
|
+
command line, e.g., -QS '-l walltime=12:00:00'. With -AL N (N > 1),
|
|
2077
|
+
'select=1:ncpus=N:mem=Ngb' is added to these options unless they
|
|
2078
|
+
already request select, ncpus or mem.
|
|
2067
2079
|
|
|
2068
2080
|
-VS or -ValidSize, the minimum acceptable file size (in bytes) for
|
|
2069
2081
|
archiving. Files smaller than this threshold are rejected.
|
|
@@ -2111,7 +2123,9 @@ They come in two forms:
|
|
|
2111
2123
|
exclude specific hosts (e.g., '-d PBS' to use PBS batch hosts).
|
|
2112
2124
|
An optional retry limit (1-99) can also be specified, e.g.,
|
|
2113
2125
|
'-d 5'; defaults to 2. Archive actions (-AS, -AW, -AH, -AQ) retry
|
|
2114
|
-
automatically after storage system outage.
|
|
2126
|
+
automatically after storage system outage. Add -AL N to run the
|
|
2127
|
+
batch job with N parallel copies and a matching PBS cpu/memory
|
|
2128
|
+
request, e.g., '-d -AL 4'.
|
|
2115
2129
|
|
|
2116
2130
|
-BS or -BackupStatus, the current Quasar backup state for a file:
|
|
2117
2131
|
'A' - archived to Quasar (complete)
|
|
@@ -694,16 +694,19 @@ class PgArch(PgOPT, PgCMD, PgSplit):
|
|
|
694
694
|
self.PGLOG['LOGMASK'] &= ~self.EMLALL # turn off all email acts
|
|
695
695
|
if 'EM' in self.params: del self.params['EM']
|
|
696
696
|
if 'BP' in self.params:
|
|
697
|
-
if 'AL' in self.params: self.params['AL'] = 0
|
|
698
697
|
if 'EM' not in self.params: self.PGLOG['LOGMASK'] &= ~self.EMLALL # turn off email if not yet
|
|
699
698
|
self.PGOPT['emerol'] |= self.EXITLG
|
|
700
699
|
# set command line Batch options
|
|
701
700
|
self.set_qsub_walltime()
|
|
702
701
|
self.set_batch_options(self.params, 1)
|
|
702
|
+
self.set_qsub_resources() # after -QS, so a user resource request is kept
|
|
703
703
|
self.init_dscheck(0, '', "dsarch", self.params['DS'], cact, self.PGLOG['CURDIR'], self.params['LN'],
|
|
704
704
|
self.params['BP'], self.PGOPT['emerol'])
|
|
705
705
|
if 'EM' in self.params: self.PGOPT['emlerr'] = self.LOGERR|self.EMEROL
|
|
706
|
-
|
|
706
|
+
# -AL N: up to N child processes copy files in the copy pass of -AW/-AH/-AS (see
|
|
707
|
+
# DsArch.archive_in_passes()) and up to N background processes run gatherxml/dcm
|
|
708
|
+
pcnt = self.params['AL'] if self.params['AL'] and self.params['AL'] > 1 else 1
|
|
709
|
+
self.start_none_daemon('dsarch', self.PGOPT['CACT'], self.params['LN'], pcnt, self.params['WI'], 1, pcnt)
|
|
707
710
|
|
|
708
711
|
def set_qsub_walltime(self):
|
|
709
712
|
"""
|
|
@@ -734,7 +737,30 @@ class PgArch(PgOPT, PgCMD, PgSplit):
|
|
|
734
737
|
hr = 24
|
|
735
738
|
self.set_one_boption('qoptions', '-l walltime={}:00:00'.format(hr), 1)
|
|
736
739
|
return
|
|
737
|
-
|
|
740
|
+
|
|
741
|
+
def set_qsub_resources(self):
|
|
742
|
+
"""
|
|
743
|
+
Request PBS cpus and memory for the -AL background processes of a -d batch job.
|
|
744
|
+
|
|
745
|
+
With -AL N (N > 1) the batch job runs up to N background copies at once,
|
|
746
|
+
so its PBS chunk gets select=1:ncpus=N:mem=Ngb (1gb per process), added
|
|
747
|
+
to the existing '-l' list of the qsub options (after any walltime) or as
|
|
748
|
+
a new '-l'. Leaves the qsub options alone when -AL is under 2, when they
|
|
749
|
+
already request select/ncpus/mem (a -QS from the user wins), or when they
|
|
750
|
+
are dynamic options starting with '!'.
|
|
751
|
+
"""
|
|
752
|
+
pcnt = self.params['AL'] if 'AL' in self.params else 0
|
|
753
|
+
if not pcnt or pcnt < 2: return
|
|
754
|
+
qopts = self.BOPTIONS['qoptions'] or ''
|
|
755
|
+
if qopts.startswith('!') or re.search(r'(select|ncpus|mem)=', qopts): return
|
|
756
|
+
res = "select=1:ncpus={0}:mem={0}gb".format(pcnt)
|
|
757
|
+
ms = re.search(r'-l\s+(\S+)', qopts)
|
|
758
|
+
if ms:
|
|
759
|
+
qopts = qopts[:ms.end(1)] + ',' + res + qopts[ms.end(1):]
|
|
760
|
+
else:
|
|
761
|
+
qopts = (qopts + ' ' if qopts else '') + '-l ' + res
|
|
762
|
+
self.set_one_boption('qoptions', qopts, 1)
|
|
763
|
+
|
|
738
764
|
def build_localfile_list(self, cact, dir):
|
|
739
765
|
"""
|
|
740
766
|
Populate params['LF'] from all files found under a local directory.
|
{rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18/src/rda_python_dsarch.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_dsarch
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.18
|
|
4
4
|
Summary: RDA Python package for utility program dsarch archive RDA data
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-dsarch
|
|
@@ -11,7 +11,7 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
11
11
|
Requires-Python: >=3.7
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
-
Requires-Dist: rda_python_common
|
|
14
|
+
Requires-Dist: rda_python_common>=3.0.31
|
|
15
15
|
Requires-Dist: rda_python_setuid
|
|
16
16
|
Requires-Dist: rda_python_miscs
|
|
17
17
|
Dynamic: license-file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_dsarch-3.0.16 → rda_python_dsarch-3.0.18}/src/rda_python_dsarch.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|