rda-python-dsquasar 3.0.21__tar.gz → 3.0.22__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_dsquasar-3.0.21/src/rda_python_dsquasar.egg-info → rda_python_dsquasar-3.0.22}/PKG-INFO +1 -1
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/pyproject.toml +1 -1
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/dsquasar.py +39 -8
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/dsquasar.usg +17 -2
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22/src/rda_python_dsquasar.egg-info}/PKG-INFO +1 -1
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/LICENSE +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/MANIFEST.in +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/README.md +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/setup.cfg +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/__init__.py +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/ds_quasar.py +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/dstacc.py +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/taccrec.py +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/tacctar.py +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar.egg-info/SOURCES.txt +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar.egg-info/dependency_links.txt +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar.egg-info/entry_points.txt +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar.egg-info/requires.txt +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar.egg-info/top_level.txt +0 -0
- {rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/test/test_dsquasar.py +0 -0
{rda_python_dsquasar-3.0.21/src/rda_python_dsquasar.egg-info → rda_python_dsquasar-3.0.22}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_dsquasar
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.22
|
|
4
4
|
Summary: RDA Python package to backup and recover RDA data archives to and from GLOBUS Quasar backup server
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-dsquasar
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/dsquasar.py
RENAMED
|
@@ -123,6 +123,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
123
123
|
'maxcnt' : 10,
|
|
124
124
|
'dolock' : 1,
|
|
125
125
|
'doemail' : 0,
|
|
126
|
+
'locflag' : None, # -L, limit the datasets gathered to one dataset.locflag
|
|
126
127
|
'starttime' : 0, # wall-clock start of the run, for the PBS walltime guard
|
|
127
128
|
'einfo' : 0, # set once a progress report is cached into dscheck.einfo
|
|
128
129
|
'eretry' : 0, # earliest retry time after a progress report failed to cache
|
|
@@ -144,7 +145,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
144
145
|
argv = sys.argv[1:]
|
|
145
146
|
for arg in argv:
|
|
146
147
|
if re.match(r'^-(h|-help)$', arg, re.I): self.show_usage('dsquasar')
|
|
147
|
-
ms = re.match(r'^-(a|b|c|d|e|E|l|m|n|t|u|w|A|B|D|W)$', arg)
|
|
148
|
+
ms = re.match(r'^-(a|b|c|d|e|E|l|m|n|t|u|w|A|B|D|L|W)$', arg)
|
|
148
149
|
if ms:
|
|
149
150
|
arg = ms.group(1)
|
|
150
151
|
if arg == 'b':
|
|
@@ -152,7 +153,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
152
153
|
elif arg in self.sopts:
|
|
153
154
|
self.sopts[arg] = 1
|
|
154
155
|
option = None
|
|
155
|
-
elif '
|
|
156
|
+
elif 'AcdLlmtwW'.find(arg) > -1:
|
|
156
157
|
option = arg
|
|
157
158
|
if arg == 'd': self.bopts = []
|
|
158
159
|
elif 'BD'.find(arg) > -1:
|
|
@@ -179,6 +180,10 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
179
180
|
if not (arg == 'Y' or arg == 'N'): self.pglog(arg +": Lock Flag(-l) must be Y or N", self.LGWNEX)
|
|
180
181
|
self.PGBACK['dolock'] = 1 if arg == 'Y' else 0
|
|
181
182
|
option = None
|
|
183
|
+
elif option == 'L':
|
|
184
|
+
if not (arg == 'G' or arg == 'O'): self.pglog(arg +": Location Flag(-L) must be G or O", self.LGWNEX)
|
|
185
|
+
self.PGBACK['locflag'] = arg
|
|
186
|
+
option = None
|
|
182
187
|
elif option == 'W':
|
|
183
188
|
self.PGBACK['maxworkers'] = int(arg)
|
|
184
189
|
if self.PGBACK['maxworkers'] < 1: self.pglog(arg +": Maximum Workers(-W) must be > 0", self.LGWNEX)
|
|
@@ -918,9 +923,10 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
918
923
|
# even if PBS kills the job at the walltime. the final report follows and drops the
|
|
919
924
|
# parked one if the run does finish in time. the live email buffers are saved and put
|
|
920
925
|
# back, so the final report still carries everything logged before the cutoff.
|
|
921
|
-
#
|
|
922
|
-
#
|
|
923
|
-
#
|
|
926
|
+
# batch_term_report covers the kill itself, but only the seconds of it: SIGKILL cannot be
|
|
927
|
+
# caught, and a process stuck in uninterruptible I/O may never run the handler. this parked
|
|
928
|
+
# report is what stands between a killed job and a run that is never heard from, so it is
|
|
929
|
+
# kept as the first line of defence. every action submitted to PBS is guarded, not just the
|
|
924
930
|
# tar and transfer ones: -A 16 and the hidden -A 128 are submitted with the same 24 hour
|
|
925
931
|
# walltime and used to be excluded, so they died silently.
|
|
926
932
|
# the tar queue depths are only reported for the actions they describe. both depths are
|
|
@@ -1468,13 +1474,29 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
1468
1474
|
fcnt = 0
|
|
1469
1475
|
# warn per named dataset with no files; stay silent when scanning all datasets
|
|
1470
1476
|
logact = self.LOGWRN if self.dsids else 0
|
|
1477
|
+
flds = "dsid, backflag, pid, lockhost"
|
|
1478
|
+
# -L splits the work by where the data sits: an Object(O) dataset has to be staged
|
|
1479
|
+
# down from the object store and checksummed before it can be tarred, while a Glade(G)
|
|
1480
|
+
# one is only stat'ed, so the two classes run at wildly different rates and are better
|
|
1481
|
+
# off in separate runs than sharing one walltime.
|
|
1482
|
+
# G is matched as "not O" rather than "= G" on purpose: dataset.locflag is only a
|
|
1483
|
+
# summary of the per-file flags (set_dataset_locflag writes it only when every public
|
|
1484
|
+
# web file agrees, and leaves the old value otherwise), so it can hold a stale value.
|
|
1485
|
+
# as "not O" the two halves stay exhaustive and no dataset falls through both runs
|
|
1486
|
+
lcnd = ''
|
|
1487
|
+
if self.PGBACK['locflag'] == 'O':
|
|
1488
|
+
lcnd = "locflag = 'O'"
|
|
1489
|
+
elif self.PGBACK['locflag']:
|
|
1490
|
+
lcnd = "locflag <> 'O'"
|
|
1471
1491
|
if self.dsids:
|
|
1472
1492
|
pgrecs = []
|
|
1473
1493
|
for dsid in self.dsids:
|
|
1474
|
-
|
|
1494
|
+
dcnd = "dsid = '{}'".format(dsid)
|
|
1495
|
+
if lcnd: dcnd += " AND " + lcnd
|
|
1496
|
+
pgrec = self.pgget("dataset", flds, dcnd, self.LGWNEX)
|
|
1475
1497
|
if pgrec: pgrecs.append(pgrec)
|
|
1476
1498
|
else:
|
|
1477
|
-
mrecs = self.pgmget("dataset",
|
|
1499
|
+
mrecs = self.pgmget("dataset", flds, (lcnd + self.dsid_order()).strip(), self.LGWNEX)
|
|
1478
1500
|
dcnt = len(mrecs['dsid']) if mrecs else 0
|
|
1479
1501
|
pgrecs = [self.onerecord(mrecs, i) for i in range(dcnt)]
|
|
1480
1502
|
for pgrec in pgrecs:
|
|
@@ -1487,7 +1509,16 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
1487
1509
|
# main runs take new files (bid = 0), so it shares no record with the worker holding
|
|
1488
1510
|
# the lock and must not skip the dataset for it
|
|
1489
1511
|
if unlock and pgrec['pid'] and not self.PGBACK['chgdays']:
|
|
1490
|
-
|
|
1512
|
+
# quiet unlock: a live holder is the normal case for a second worker, and the
|
|
1513
|
+
# library wording for it ("Cannot Unlock") reads like a failure. report the skip
|
|
1514
|
+
# here instead, in terms of the worker that is still on the dataset
|
|
1515
|
+
lstat = self.lock_dataset(dsid, 0, 0)
|
|
1516
|
+
if lstat < 1:
|
|
1517
|
+
# -1 is the live holder; 0 means the record went away or the db errored,
|
|
1518
|
+
# which lock_dataset has already logged as an error
|
|
1519
|
+
if lstat < 0:
|
|
1520
|
+
self.pglog("{}: skipped, still in use by {}/{}".format(dsid, pgrec['pid'], pgrec['lockhost']), self.LOGACT)
|
|
1521
|
+
continue
|
|
1491
1522
|
fcnt += self.get_dataset_files(dsid, dsfiles, pgrec['backflag'], logact, sizes)
|
|
1492
1523
|
if dsfiles:
|
|
1493
1524
|
s = 's' if fcnt > 1 else ''
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/dsquasar.usg
RENAMED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
file tarring and transferring is performed through the utility program dsarch.
|
|
9
9
|
|
|
10
10
|
Usage: dsquasar [-b] [(-a | -t DatasetIDs)] [-c ChangeDays] [-(e|E)] \
|
|
11
|
-
[-(B|D)] [-A ActionBits] [-l (Y|N)]
|
|
12
|
-
[-n] [-u] [-d [HostName] [TryCount]] [-h]
|
|
11
|
+
[-(B|D)] [-L (G|O)] [-A ActionBits] [-l (Y|N)] \
|
|
12
|
+
[-m ProcessCount] [-n] [-u] [-d [HostName] [TryCount]] [-h]
|
|
13
13
|
|
|
14
14
|
Either -a or -t must be given (usage is displayed otherwise). dsquasar runs
|
|
15
15
|
from the Quasar backup work directory; it changes there automatically.
|
|
@@ -24,6 +24,21 @@
|
|
|
24
24
|
'%' is allowed and is expanded against the dataset table. Ignored,
|
|
25
25
|
with a warning, when -a is also given.
|
|
26
26
|
|
|
27
|
+
-L (G|O)
|
|
28
|
+
Limit the run by dataset.locflag: O takes the datasets on the object
|
|
29
|
+
store, G takes everything else. Applies to -a and to -t alike. The
|
|
30
|
+
two classes back up at very different rates: an O dataset has every
|
|
31
|
+
file staged down from the object store and checksummed before it can
|
|
32
|
+
be tarred, while a G dataset is only stat'ed. Running them in one job
|
|
33
|
+
lets the slow class eat the whole walltime, so give them separate
|
|
34
|
+
runs, e.g. one submit with -L G and another with -L O. Defaults to
|
|
35
|
+
all datasets.
|
|
36
|
+
|
|
37
|
+
-L G and -L O together always cover every dataset, so a pair of runs
|
|
38
|
+
loses nothing. The split is by dataset, though, and dataset.locflag
|
|
39
|
+
is only a summary of the per-file flags, so a dataset holding files of
|
|
40
|
+
both kinds is backed up entirely by whichever run claims it.
|
|
41
|
+
|
|
27
42
|
|
|
28
43
|
BACKUP SCOPE
|
|
29
44
|
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22/src/rda_python_dsquasar.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_dsquasar
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.22
|
|
4
4
|
Summary: RDA Python package to backup and recover RDA data archives to and from GLOBUS Quasar backup server
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-dsquasar
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/__init__.py
RENAMED
|
File without changes
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/ds_quasar.py
RENAMED
|
File without changes
|
|
File without changes
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/taccrec.py
RENAMED
|
File without changes
|
{rda_python_dsquasar-3.0.21 → rda_python_dsquasar-3.0.22}/src/rda_python_dsquasar/tacctar.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|