rda-python-dbms 2.0.8__py3-none-any.whl → 3.0.0__py3-none-any.whl
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_dbms/pgchksum.py +52 -5
- rda_python_dbms/tables/dssdb/dsgroup.json +1 -1
- {rda_python_dbms-2.0.8.dist-info → rda_python_dbms-3.0.0.dist-info}/METADATA +1 -1
- {rda_python_dbms-2.0.8.dist-info → rda_python_dbms-3.0.0.dist-info}/RECORD +8 -8
- {rda_python_dbms-2.0.8.dist-info → rda_python_dbms-3.0.0.dist-info}/WHEEL +1 -1
- {rda_python_dbms-2.0.8.dist-info → rda_python_dbms-3.0.0.dist-info}/entry_points.txt +0 -0
- {rda_python_dbms-2.0.8.dist-info → rda_python_dbms-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {rda_python_dbms-2.0.8.dist-info → rda_python_dbms-3.0.0.dist-info}/top_level.txt +0 -0
rda_python_dbms/pgchksum.py
CHANGED
|
@@ -22,6 +22,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
22
22
|
super().__init__() # initialize parent class
|
|
23
23
|
self.PGSUM = {
|
|
24
24
|
'd' : [], # delay mode option, value array
|
|
25
|
+
'e' : 0, # 1 for emailing dataset owners the list of their missing files
|
|
25
26
|
's' : [], # specialist login name array for email notice, default to none
|
|
26
27
|
'f' : [], # file name array, default to none
|
|
27
28
|
'i' : [], # dataset id array, default for all
|
|
@@ -46,6 +47,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
46
47
|
'begin' : 0,
|
|
47
48
|
'end' : 0
|
|
48
49
|
}
|
|
50
|
+
self.MISSING = {} # dsid => list of missing file names with their location
|
|
49
51
|
self.pgname = "pgchksum"
|
|
50
52
|
self.pgcmd = None
|
|
51
53
|
|
|
@@ -61,7 +63,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
61
63
|
self.PGLOG['BCKGRND'] = 1 # processing in backgroup mode
|
|
62
64
|
option = None
|
|
63
65
|
elif option in self.PGSUM:
|
|
64
|
-
if option in ['m', 'n', 'x']:
|
|
66
|
+
if option in ['e', 'm', 'n', 'x']:
|
|
65
67
|
self.PGSUM[option] = 1
|
|
66
68
|
option = None
|
|
67
69
|
else:
|
|
@@ -80,12 +82,13 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
80
82
|
else:
|
|
81
83
|
self.pglog(arg + ": value passed without leading Option", self.LGEREX)
|
|
82
84
|
if not self.PGSUM['t']:
|
|
83
|
-
print("Usage: pgchksum -t (W|S|Q) [-b] [-m] [-n] [-x] [-c FileCount] \\")
|
|
85
|
+
print("Usage: pgchksum -t (W|S|Q) [-b] [-e] [-m] [-n] [-x] [-c FileCount] \\")
|
|
84
86
|
print(" [-d [Hostnames] [RerunCount]] [-f FileNames] [-i DatasetIDs] \\")
|
|
85
87
|
print(" [-k SkipCount] [-o r|s] [-s Specialists]")
|
|
86
88
|
print(" -b - background process and no screen output")
|
|
87
89
|
print(" -c - File count to re-evaluate checksum; for all gathered files if not specified")
|
|
88
90
|
print(" -d - delayed mode background/batch processes on RDA machines/DAV PBS nodes")
|
|
91
|
+
print(" -e - email the primary owner of each dataset a reminder listing its missing files")
|
|
89
92
|
print(" -f - Re-evaluate the specify File names only")
|
|
90
93
|
print(" -i - Dataset IDs the files belong; for all files if not specified")
|
|
91
94
|
print(" -k - skip the given file count to re-evaluate checksum")
|
|
@@ -100,6 +103,8 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
100
103
|
self.pgexit(0)
|
|
101
104
|
elif self.PGSUM['t'] not in 'QSW':
|
|
102
105
|
self.pglog(self.PGSUM['t'] + ": Unknown File Type, must be one of 'QSW'", self.LGEREX)
|
|
106
|
+
if self.PGSUM['e'] and self.PGSUM['n']:
|
|
107
|
+
self.pglog("Option -e (email owners) cannot work with -n (no email)", self.LGEREX)
|
|
103
108
|
# set different log file
|
|
104
109
|
self.PGLOG['LOGFILE'] = self.pgname + '.log'
|
|
105
110
|
self.set_suid(self.PGLOG['EUID'])
|
|
@@ -151,6 +156,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
151
156
|
self.evaluate_backfile_checksum(fcnt, pgrecs, cnts)
|
|
152
157
|
self.dump_progress(fcnt, fcnt, cnts, self.PVALS['emlsum'])
|
|
153
158
|
self.PVALS['end'] = int(time.time())
|
|
159
|
+
if self.PGSUM['e'] and self.MISSING: self.send_owner_emails()
|
|
154
160
|
if not self.PGSUM['n']: self.send_check_email(cnts['cnt'], fcnt)
|
|
155
161
|
if self.PGLOG['DSCHECK']:
|
|
156
162
|
if self.PGLOG['ERRMSG']:
|
|
@@ -173,6 +179,43 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
173
179
|
else:
|
|
174
180
|
self.pglog(subject, self.LOGWRN|self.SNDEML)
|
|
175
181
|
|
|
182
|
+
# email the primary owner(s) of each dataset the list of its missing files
|
|
183
|
+
def send_owner_emails(self):
|
|
184
|
+
for dsid in sorted(self.MISSING):
|
|
185
|
+
files = self.MISSING[dsid]
|
|
186
|
+
fcnt = len(files)
|
|
187
|
+
s = 's' if fcnt > 1 else ''
|
|
188
|
+
tjoin = "dsowner LEFT JOIN dssgrp ON specialist = logname"
|
|
189
|
+
pgrecs = self.pgmget(tjoin, "specialist, fstname",
|
|
190
|
+
"dsid = '{}' AND priority = 1 ORDER BY specialist".format(dsid), self.PVALS['emlerr'])
|
|
191
|
+
if not pgrecs or not pgrecs['specialist']:
|
|
192
|
+
self.pglog("{}: No primary owner found in dsowner to email {} missing {} file{}".format(dsid, fcnt, self.PVALS['TYPE'], s), self.PVALS['emllog'])
|
|
193
|
+
continue
|
|
194
|
+
owners = []
|
|
195
|
+
names = []
|
|
196
|
+
for i in range(len(pgrecs['specialist'])):
|
|
197
|
+
owners.append(pgrecs['specialist'][i])
|
|
198
|
+
names.append(pgrecs['fstname'][i] if pgrecs['fstname'][i] else pgrecs['specialist'][i])
|
|
199
|
+
subject = "PGCHKSUM: {} {} File{} Missing for {}".format(fcnt, self.PVALS['TYPE'], s, dsid)
|
|
200
|
+
msg = "Dear {},\n\n".format(' and '.join(names))
|
|
201
|
+
msg += ("Checking {} files of dataset {}, {} found the following {} file{} recorded in RDADB " +
|
|
202
|
+
"but missing from the archive location{}. Please restore the file{}, or remove/update " +
|
|
203
|
+
"the file record{} via dsarch if no longer needed:\n\n").format(
|
|
204
|
+
self.PVALS['TYPE'], dsid, self.pgname, fcnt, s, s, s, s)
|
|
205
|
+
for i in range(fcnt):
|
|
206
|
+
msg += "{}. {}\n".format(i+1, files[i])
|
|
207
|
+
msg += "\n{} on {}\n".format(self.pgcmd, self.PGLOG['HOSTNAME'])
|
|
208
|
+
receiver = ', '.join(o if o.find('@') > -1 else o + "@ucar.edu" for o in owners)
|
|
209
|
+
if self.send_python_email(subject, receiver, msg, None, '', self.PVALS['emlerr']):
|
|
210
|
+
self.pglog("{}: emailed {} about {} missing {} file{}".format(dsid, receiver, fcnt, self.PVALS['TYPE'], s), self.PVALS['emllog'])
|
|
211
|
+
|
|
212
|
+
# record a missing file for the dataset owner email
|
|
213
|
+
def add_missing_file(self, fname, pgrec, location):
|
|
214
|
+
if not self.PGSUM['e']: return
|
|
215
|
+
dsid = pgrec['dsid']
|
|
216
|
+
if dsid not in self.MISSING: self.MISSING[dsid] = []
|
|
217
|
+
self.MISSING[dsid].append("{} (Type {}, {})".format(fname, pgrec['type'], location))
|
|
218
|
+
|
|
176
219
|
# get the checksum filelist for wfile
|
|
177
220
|
def get_checksum_wfilelist(self):
|
|
178
221
|
self.PVALS['TYPE'] = "Web"
|
|
@@ -197,7 +240,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
197
240
|
if self.PGLOG['DSCHECK']: self.set_dscheck_attribute("dsid", dsid, self.PVALS['emlerr'])
|
|
198
241
|
if self.PGSUM['m']: self.PVALS['CND'] += "(checksum IS NULL OR checksum < ' ') "
|
|
199
242
|
elif dscnt > 1:
|
|
200
|
-
self.PVALS['CND'] = "dsid IN ({}) ".format(','.join(self.PGSUM['i']))
|
|
243
|
+
self.PVALS['CND'] = "dsid IN ('{}') ".format("','".join(self.PGSUM['i']))
|
|
201
244
|
if self.PGSUM['o']: self.PVALS['CND'] += "ORDER BY {} ".format('wid' if self.PGSUM['o'] == 's' else "RANDOM()")
|
|
202
245
|
if fcnt: self.PVALS['CND'] += "LIMIT {} ".format(fcnt)
|
|
203
246
|
if self.PGSUM['k']:
|
|
@@ -206,6 +249,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
206
249
|
if dscnt == 1:
|
|
207
250
|
wfrecs = self.pgmget_wfile(dsid, flds, self.PVALS['CND'])
|
|
208
251
|
cnt = len(wfrecs['wid']) if wfrecs else 0
|
|
252
|
+
if cnt > 0: wfrecs['dsid'] = [dsid]*cnt # wfile_{dsid} has no dsid column
|
|
209
253
|
else:
|
|
210
254
|
pgrecs = self.pgmget('wfile', 'wid, dsid', self.PVALS['CND'])
|
|
211
255
|
cnt = len(pgrecs['wid']) if pgrecs else 0
|
|
@@ -245,7 +289,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
245
289
|
self.PVALS['CND'] = "dsid = '{}'".format(dsid)
|
|
246
290
|
if self.PGLOG['DSCHECK']: self.set_dscheck_attribute("dsid", dsid, self.PVALS['emlerr'])
|
|
247
291
|
elif cnt > 1:
|
|
248
|
-
self.PVALS['CND'] = "dsid IN ({})".format(','.join(self.PGSUM['i']))
|
|
292
|
+
self.PVALS['CND'] = "dsid IN ('{}')".format("','".join(self.PGSUM['i']))
|
|
249
293
|
if self.PGSUM['m']:
|
|
250
294
|
if self.PVALS['CND']: self.PVALS['CND'] += " AND "
|
|
251
295
|
self.PVALS['CND'] += "(checksum IS NULL OR checksum < ' ')"
|
|
@@ -279,7 +323,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
279
323
|
self.PVALS['CND'] = "dsid = '{}' AND ".format(dsid)
|
|
280
324
|
if self.PGLOG['DSCHECK']: self.set_dscheck_attribute("dsid", dsid, self.PVALS['emlerr'])
|
|
281
325
|
elif cnt > 1:
|
|
282
|
-
self.PVALS['CND'] = "dsid IN ({}) AND ".format(','.join(self.PGSUM['i']))
|
|
326
|
+
self.PVALS['CND'] = "dsid IN ('{}') AND ".format("','".join(self.PGSUM['i']))
|
|
283
327
|
if self.PGSUM['m']:
|
|
284
328
|
self.PVALS['CND'] += "(checksum IS NULL OR checksum < ' ') AND "
|
|
285
329
|
self.PVALS['CND'] += "status = 'A'"
|
|
@@ -376,6 +420,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
376
420
|
self.evaluate_file_status('DSK', fname, pgrec, info, cnts)
|
|
377
421
|
else:
|
|
378
422
|
self.pglog("{}: Type {} {} file is missing on Disk".format(fname, pgrec['type'], self.PVALS['TYPE']), self.PVALS['emllog'])
|
|
423
|
+
self.add_missing_file(fname, pgrec, 'on Disk')
|
|
379
424
|
cnts['ecnt'] += 1
|
|
380
425
|
|
|
381
426
|
# evaluate an object file
|
|
@@ -385,6 +430,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
385
430
|
self.evaluate_file_status('OBS', "{}-{}".format(bucket, fname), pgrec, info, cnts)
|
|
386
431
|
else:
|
|
387
432
|
self.pglog("{}: Type {} {} file is missing in Object Store".format(fname, pgrec['type'], self.PVALS['TYPE']), self.PVALS['emllog'])
|
|
433
|
+
self.add_missing_file("{}-{}".format(bucket, fname), pgrec, 'in Object Store')
|
|
388
434
|
cnts['ecnt'] += 1
|
|
389
435
|
|
|
390
436
|
# evaluate a quasar file
|
|
@@ -394,6 +440,7 @@ class PgChksum(PgCMD, PgSplit):
|
|
|
394
440
|
self.evaluate_file_status('QSR', "{}-{}".format(endpoint, fname), pgrec, info, cnts)
|
|
395
441
|
else:
|
|
396
442
|
self.pglog("{}: Type {} {} file is missing on Quasar".format(fname, pgrec['type'], self.PVALS['TYPE']), self.PVALS['emllog'])
|
|
443
|
+
self.add_missing_file("{}-{}".format(endpoint, fname), pgrec, 'on Quasar')
|
|
397
444
|
cnts['ecnt'] += 1
|
|
398
445
|
|
|
399
446
|
# evaluate a file status
|
|
@@ -10,7 +10,7 @@ rda_python_dbms/pg_ddllib.py,sha256=-zawllfUCe7QZNvza-u5TAYKP4yilC9K6TetHhoGenU,
|
|
|
10
10
|
rda_python_dbms/pg_schema.py,sha256=Vsf5fKENYIOgMKE3yS0TkXhg-aeHZ2nYzpvltFAcdFY,5520
|
|
11
11
|
rda_python_dbms/pg_seq.py,sha256=wNxqsyIjcTplJErPirZ-VkZ8HS4mgQUwPz8Xwd12kYA,4914
|
|
12
12
|
rda_python_dbms/pgbackup.py,sha256=IuP3nQEEVR86YlSZuGyqsdz1-O9rgET76FnWB7iL3xk,4249
|
|
13
|
-
rda_python_dbms/pgchksum.py,sha256=
|
|
13
|
+
rda_python_dbms/pgchksum.py,sha256=ePHdh2MQ3q8102Nm7znXPg8ToI-ohGnyg3f-ipIYWu8,24921
|
|
14
14
|
rda_python_dbms/pgcmptables.py,sha256=LQ4KK4JuQs2z3nBdINWYgyiGu2MF9RZjS5_cAktbs6k,47123
|
|
15
15
|
rda_python_dbms/pgdbdump.py,sha256=8d-1z16Y2DyJnQqex2wFu5svChKgncPnzdQ-iUftHg8,3831
|
|
16
16
|
rda_python_dbms/pgdbrestore.py,sha256=d12hl1r6usK1oGIFAPVWUB_KkIH04PPlugxVSnLOX1g,3110
|
|
@@ -61,7 +61,7 @@ rda_python_dbms/tables/dssdb/dscart.json,sha256=ggVt5SVi1EbNc9bEA7dCRRF4l7pOZIHm
|
|
|
61
61
|
rda_python_dbms/tables/dssdb/dscheck.json,sha256=ZL6VNerF2PGcP0yPFUXhq7dzJDc5g5xX64eURAghGNY,6426
|
|
62
62
|
rda_python_dbms/tables/dssdb/dschkhist.json,sha256=UeTjTsIpBGGscPNajL1tl7uflQWbYe3ILkyBcDBb9Mc,2880
|
|
63
63
|
rda_python_dbms/tables/dssdb/dsdaemon.json,sha256=Ua0TktcZ5RPEQbwEblnNjWRBjDp-xcuunsaCAIaXsx0,1859
|
|
64
|
-
rda_python_dbms/tables/dssdb/dsgroup.json,sha256=
|
|
64
|
+
rda_python_dbms/tables/dssdb/dsgroup.json,sha256=aZ7RtRWnRcIruQesdsbUglHxvb8tROfNoWMNP0Bfzdk,5389
|
|
65
65
|
rda_python_dbms/tables/dssdb/dshist.json,sha256=EEpCLLwS0vfV9OwMWgrRmvHP81gMybG8NOTxtDeHR1Y,1396
|
|
66
66
|
rda_python_dbms/tables/dssdb/dslimit.json,sha256=hdpRAC4Bg0ZUCwVVDCCHVwYJcDLotXFB2e30G7ByzKg,758
|
|
67
67
|
rda_python_dbms/tables/dssdb/dsokeys.json,sha256=4c_AsQgxBApawhnkKTzXflxL-603J19z8poimxe_sXw,746
|
|
@@ -954,9 +954,9 @@ rda_python_dbms/tables/obsua/wind_5v2_0.json,sha256=NehMFE-GMNlD5Bh_fiacfSOmZWkr
|
|
|
954
954
|
rda_python_dbms/tables/obsua/wind_60v2_0.json,sha256=jOyQgD5ph7YBMuQfvYz1Ln6X_-_Vdhl36HBexOHZ1dA,1067
|
|
955
955
|
rda_python_dbms/tables/obsua/wind_8v2_0.json,sha256=5wtCThmFeOyiAGH_Qv3_jrXjhjo9b87ehlpI9QQY2SM,1064
|
|
956
956
|
rda_python_dbms/tables/obsua/wind_9v2_0.json,sha256=7OKFUicOn15LL_WuF1VE_L8DjxsHmRP4uBnopuMIeTg,1064
|
|
957
|
-
rda_python_dbms-
|
|
958
|
-
rda_python_dbms-
|
|
959
|
-
rda_python_dbms-
|
|
960
|
-
rda_python_dbms-
|
|
961
|
-
rda_python_dbms-
|
|
962
|
-
rda_python_dbms-
|
|
957
|
+
rda_python_dbms-3.0.0.dist-info/licenses/LICENSE,sha256=Uky6fiiVw7cakFVRtVpzg-mvqOQ-WcA_H8lHqhPRg58,1101
|
|
958
|
+
rda_python_dbms-3.0.0.dist-info/METADATA,sha256=B9DrL7R_MmsAlJg1nRTq0jUBKjhPMFfITFGqlX5kqIE,617
|
|
959
|
+
rda_python_dbms-3.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
960
|
+
rda_python_dbms-3.0.0.dist-info/entry_points.txt,sha256=iti6iZS2OEeBqO5aHlWeMFcbuwN_2assidP0qeSkQ6E,346
|
|
961
|
+
rda_python_dbms-3.0.0.dist-info/top_level.txt,sha256=4T1ShNUMyiqmwDIuDL7pDOm_S-6zWWW3Vy6OdAzYA4c,16
|
|
962
|
+
rda_python_dbms-3.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|