rda-python-miscs 3.0.7__tar.gz → 3.0.8__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.
Files changed (63) hide show
  1. {rda_python_miscs-3.0.7/src/rda_python_miscs.egg-info → rda_python_miscs-3.0.8}/PKG-INFO +7 -1
  2. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/README.md +6 -0
  3. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/pyproject.toml +1 -1
  4. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexdrop.py +30 -0
  5. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexdrop.usg +10 -1
  6. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8/src/rda_python_miscs.egg-info}/PKG-INFO +7 -1
  7. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/LICENSE +0 -0
  8. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/MANIFEST.in +0 -0
  9. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/setup.cfg +0 -0
  10. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/__init__.py +0 -0
  11. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/bash_qsub.py +0 -0
  12. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/bashqsub.py +0 -0
  13. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/bashqsub.usg +0 -0
  14. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/decsdata_restore.py +0 -0
  15. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/decsdata_restore.usg +0 -0
  16. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/decsdata_storage.py +0 -0
  17. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/decsdata_storage.usg +0 -0
  18. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdex_ls.py +0 -0
  19. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexcp.py +0 -0
  20. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexcp.usg +0 -0
  21. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexdrop_standalone.py +0 -0
  22. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexkill.py +0 -0
  23. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexkill.usg +0 -0
  24. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexls.py +0 -0
  25. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexls.usg +0 -0
  26. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexls_standalone.py +0 -0
  27. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexmod.py +0 -0
  28. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexmod.usg +0 -0
  29. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexown.py +0 -0
  30. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexown.usg +0 -0
  31. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexps.py +0 -0
  32. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexps.usg +0 -0
  33. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexsub.py +0 -0
  34. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexsub.usg +0 -0
  35. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexzip.py +0 -0
  36. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/gdexzip.usg +0 -0
  37. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/pg_docs.py +0 -0
  38. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/pg_rst.py +0 -0
  39. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/pg_rst.usg +0 -0
  40. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/pg_wget.py +0 -0
  41. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/pgwget.py +0 -0
  42. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/pgwget.usg +0 -0
  43. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_cp.py +0 -0
  44. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_kill.py +0 -0
  45. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_mod.py +0 -0
  46. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_own.py +0 -0
  47. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_ps.py +0 -0
  48. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_sub.py +0 -0
  49. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rda_zip.py +0 -0
  50. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rdals.py +0 -0
  51. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rdals.usg +0 -0
  52. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rst_templates/appendix.rst.temp +0 -0
  53. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rst_templates/index.rst.temp +0 -0
  54. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/rst_templates/section.rst.temp +0 -0
  55. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/tcsh_qsub.py +0 -0
  56. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/tcshqsub.py +0 -0
  57. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs/tcshqsub.usg +0 -0
  58. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs.egg-info/SOURCES.txt +0 -0
  59. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs.egg-info/dependency_links.txt +0 -0
  60. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs.egg-info/entry_points.txt +0 -0
  61. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs.egg-info/requires.txt +0 -0
  62. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/src/rda_python_miscs.egg-info/top_level.txt +0 -0
  63. {rda_python_miscs-3.0.7 → rda_python_miscs-3.0.8}/tests/test_miscs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_miscs
3
- Version: 3.0.7
3
+ Version: 3.0.8
4
4
  Summary: RDA Python package to hold RDA miscellaneous utility programs
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs
@@ -172,6 +172,12 @@ deliberately narrow alternative to `gdexcp`: the destination is always
172
172
  directory is rejected, and every source must be readable by the calling user
173
173
  rather than only by `gdexdata`.
174
174
 
175
+ An absolute `-t` under `/tmp/` names any sub-path of `/tmp` instead of a sub-path
176
+ of the dataset directory, so that a drop can be tried out without touching the
177
+ dataset tree. The dataset of `-ds` is still checked against the access list, and
178
+ because `/tmp` is world writable — unlike a dataset directory — the part of the
179
+ path that already exists must belong to the calling user or to `gdexdata`.
180
+
175
181
  Everything dropped, including sub-directories created for `-t`, is also set to the
176
182
  GDEX group `PGLOG['GDEXGRP']`. The setuid wrapper switches only the user to
177
183
  `gdexdata`, not the group, so without that step a dropped file would stay in the
@@ -155,6 +155,12 @@ deliberately narrow alternative to `gdexcp`: the destination is always
155
155
  directory is rejected, and every source must be readable by the calling user
156
156
  rather than only by `gdexdata`.
157
157
 
158
+ An absolute `-t` under `/tmp/` names any sub-path of `/tmp` instead of a sub-path
159
+ of the dataset directory, so that a drop can be tried out without touching the
160
+ dataset tree. The dataset of `-ds` is still checked against the access list, and
161
+ because `/tmp` is world writable — unlike a dataset directory — the part of the
162
+ path that already exists must belong to the calling user or to `gdexdata`.
163
+
158
164
  Everything dropped, including sub-directories created for `-t`, is also set to the
159
165
  GDEX group `PGLOG['GDEXGRP']`. The setuid wrapper switches only the user to
160
166
  `gdexdata`, not the group, so without that step a dropped file would stay in the
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "rda_python_miscs"
9
- version = "3.0.7"
9
+ version = "3.0.8"
10
10
  authors = [
11
11
  { name="Zaihua Ji", email="zji@ucar.edu" },
12
12
  ]
@@ -24,6 +24,7 @@ DROPROOT = "/glade/campaign/collections/gdex/data" # dataset data root path
24
24
  DROPCONF = "/glade/u/home/gdexdata/config/gdexdrop.conf" # access list
25
25
  DROPLOG = "/glade/u/home/gdexdata/dssdb/log" # log path
26
26
  DROPUSER = "gdexdata" # owner of dropped files
27
+ DROPTMP = "/tmp" # alternate root, for testing
27
28
 
28
29
  class GdexDrop(PgFile):
29
30
  """Copy local files and directories into a GDEX dataset directory as 'gdexdata'.
@@ -187,18 +188,47 @@ class GdexDrop(PgFile):
187
188
  real path of the dataset directory, so that neither a '..' component in -t
188
189
  nor an existing symbolic link can move the drop outside the dataset.
189
190
 
191
+ An absolute -t under DROPTMP names any sub-path of that directory instead,
192
+ for trying a drop out without touching the dataset tree. The dataset of
193
+ -ds is still validated against the access list.
194
+
190
195
  Returns:
191
196
  str: Resolved absolute target directory.
192
197
  """
193
198
  dsid = self.DROP['ds']
194
199
  if not re.match(r'^[a-z]\d{6}$', dsid):
195
200
  self.pglog(dsid + ": Invalid Dataset ID of -ds, expecting the form d123456", self.LGEREX)
201
+ if self.DROP['t'] and re.match(r'^{}/'.format(DROPTMP), self.DROP['t']):
202
+ return self.tmp_target()
196
203
  dsroot = op.realpath(op.join(DROPROOT, dsid))
197
204
  if not op.isdir(dsroot):
198
205
  self.pglog("{}: Dataset directory NOT exists under {}".format(dsid, DROPROOT), self.LGEREX)
199
206
  target = self.confine_path(op.join(dsroot, self.DROP['t']) if self.DROP['t'] else dsroot, dsroot)
200
207
  return target
201
208
 
209
+ # resolve a target of -t that names a sub-path of DROPTMP
210
+ def tmp_target(self):
211
+ """Return the resolved -t path under DROPTMP, exiting if it may not be used.
212
+
213
+ DROPTMP is world writable, unlike a dataset directory, so a path there can
214
+ be replaced by another user between this check and the copy, and may well
215
+ belong to somebody else already. The existing part of the path is therefore
216
+ required to belong to the caller or to DROPUSER, so that a drop cannot be
217
+ aimed at a directory a third user controls.
218
+
219
+ Returns:
220
+ str: Resolved absolute target directory under DROPTMP.
221
+ """
222
+ tmproot = op.realpath(DROPTMP)
223
+ target = self.confine_path(self.DROP['t'], tmproot)
224
+ dir = target
225
+ while not op.isdir(dir): dir = op.dirname(dir)
226
+ if dir == tmproot: return target # nothing of the path exists yet
227
+ info = self.check_local_file(dir, 2, self.LOGWRN)
228
+ if info and info['logname'] not in (self.PGLOG['CURUID'], DROPUSER):
229
+ self.pglog("{}: Target path under {} is owned by {}".format(dir, DROPTMP, info['logname']), self.LGEREX)
230
+ return target
231
+
202
232
  # make sure a path stays inside the dataset directory
203
233
  def confine_path(self, path, dsroot):
204
234
  """Return the resolved path, exiting if it falls outside the dataset directory.
@@ -17,7 +17,12 @@
17
17
  files into. Missing sub-directories are created. The path must stay
18
18
  inside the dataset directory; '..' components and symbolic links
19
19
  leading out of it are rejected. Defaults to the dataset directory
20
- itself;
20
+ itself.
21
+ An absolute path under /tmp/ names any sub-path of /tmp instead, for
22
+ trying a drop out without touching the dataset tree. The dataset of
23
+ -ds is still checked against the access list, and because /tmp is
24
+ world writable, the existing part of the path must belong to the
25
+ calling user or to 'gdexdata';
21
26
 
22
27
  - Option -f File/Directory List is the default option, so the source paths
23
28
  may be given without it and in any position. Relative paths are
@@ -77,3 +82,7 @@
77
82
  4. Drop a long list of files named in a file, with group-writable modes:
78
83
 
79
84
  gdexdrop -ds d123456 -i filelist.txt -F 664 -D 775
85
+
86
+ 5. Try a drop out under /tmp, leaving the dataset directory alone:
87
+
88
+ gdexdrop -ds d123456 -t /tmp/mydrop hourly.2026*.nc
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_miscs
3
- Version: 3.0.7
3
+ Version: 3.0.8
4
4
  Summary: RDA Python package to hold RDA miscellaneous utility programs
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-miscs
@@ -172,6 +172,12 @@ deliberately narrow alternative to `gdexcp`: the destination is always
172
172
  directory is rejected, and every source must be readable by the calling user
173
173
  rather than only by `gdexdata`.
174
174
 
175
+ An absolute `-t` under `/tmp/` names any sub-path of `/tmp` instead of a sub-path
176
+ of the dataset directory, so that a drop can be tried out without touching the
177
+ dataset tree. The dataset of `-ds` is still checked against the access list, and
178
+ because `/tmp` is world writable — unlike a dataset directory — the part of the
179
+ path that already exists must belong to the calling user or to `gdexdata`.
180
+
175
181
  Everything dropped, including sub-directories created for `-t`, is also set to the
176
182
  GDEX group `PGLOG['GDEXGRP']`. The setuid wrapper switches only the user to
177
183
  `gdexdata`, not the group, so without that step a dropped file would stay in the